🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

directx clippers

Started by
8 comments, last by xSuiCidEx 24 years, 8 months ago
Assuming lpDD is your DirectDraw7 interface, primarySurface is your primary display surface, and hwnd is your window handle:

LPDIRECTDRAWCLIPPER mainClipper;

lpDD->CreateClipper(0, mainClipper, NULL);
mainClipper->SetHWnd(0, hwnd);
primarySurface->SetClipper(mainClipper);


That should create a new clipper, set it to update it's clipping according to your window, and then set's it as the clipper for your primary surface.

- Splat

Advertisement
the above discussion should point you in the right direction, but it leaves out a very important part of the puzzle for getting your clipper to work correctly.

when u create and attach a clipper to a directdraw surface it will clip everything that you try to draw to that surface(it does this by default). this is the case with the above code snippet. it will compile and run, but you will just get a blank screen because the clipper clipped everything.

you have to explicity tell the clipper what area of the screen you want to be a valid drawing area. the following code shows you how to setup the clipper that will clip to the edges of the screen (you can clip any area(s) of the screen of course, but that code is a little more tedious). here's the basic approach for a 640x480 surface:

where lpddsbuffer is the dd surface u want clipped, and lpdd is your dd object...

// local variables
LPDIRECTDRAWCLIPPER lpddclipper;
LPRGNDATA cliplist;
RECT screen_rect = {0,0,640,480};

// we need to allocate some memory
cliplist = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) + sizeof(RECT));

//copy to the buffer
memcpy(cliplist->Buffer,&screen_rect,sizeof(RECT));

// set the data fields
cliplist->rdh.dwSize = sizeof(RGNDATAHEADER);
cliplist->rdh.iType = RDH_RECTANGLES;
cliplist->rdh.nCount = 1;
cliplist->rdh.nRgnSize = sizeof(RECT);
cliplist->rdh.rcBound.left= 0;
cliplist->rdh.rcBound.top = 0;
cliplist->rdh.rcBound.right = 640;
cliplist->rdh.rcBound.bottom = 480;

//now create,set,and clip!
if(lpdd->CreateClipper(NULL,&lpddclipper,NULL)!=DD_OK)
return(FALSE); // failed
if(lpddclipper->SetClipList(cliplist,0)!=DD_OK)
return(FALSE); // failed
if(lpddsbuffer->SetClipper(lpddclipper)!=DD_OK)
return(FALSE); // failed

free(cliplist);
return(TRUE); // success

as you can see, you have to declare and fill out the data fields of a RGNDATA structure and then pass it to the SetClipList() function in order to get the clipper to do what u want.
it's a pain at first, but after that it's not so bad. also, i'd put all this stuff in a sub-routine to hide all the grusome details. hence the return statements.

good luck,
don


www.ChippedDagger.com"They that can give up essential liberty to obtain temporary safety deserve neither." -- Benjamin Franklin"If opportunity doesn't knock, build a door." -- Milton Berle
Does anyone have any idea on the performance of DD clippers? I've always written my own, since it's so bloody simple, and I can't really think of any reason why the DD implementation should be faster. After all, it's nothing more than a few compares per blit.

/Niels

<b>/NJ</b>
Note: After calling SetClipper the reference-count of the clipper will be incremented so when you release it, it's still in the memory. After you call SetClipper call Release one time on the clipper and at the end of your program make a second call to release the clipper once and for all.

VirtualNext

Well, with DirectX 5, the clipper slowed by code down about 4 frames as compared with my own clipping. So I vowed not to touch it again, though I'm not sure if there is any speed improvement with DX 7
That's what I figured. After all; How much, really, can you optimize 4 compares if you have to live with the penalties of COM? Even if you had hardware support the speed improvement would be VERY limited.

/Niels

<b>/NJ</b>
a question for Neils:

i use the LPDIRECTDRAWSURFACE3::Blt() function for all my blitting needs, so how could i write my own clipper without writing my own blitter? is this what you do, write your own blitter?

-DeltaRho

no, you don't write your own blitter, you just make a function or something to clip the source rect and dest rect so that they don't cover off screen areas. then you call this before you call blit.
i was wondering how to set up a clipper or something to allow me to not worry about drawing pictures from a bmp with directx half on the screen and half off without getting errors etc., any help is appreciated...thanx

brad

---===xxxx===---
----THE END----
---===xxxx===---
FWIW, there's a rumor going around that the clippers don't perform very well on RIVA-based cards.

Keep in mind that clippers do more than just clip against the edges of the screen. I can give the clipper an arbitrary number of rectangles that I want masked out, and it will correctly clip the blts to *all* of them.

This is a more general purpose solution than just clipping against the edges of the screen, so of course it will be slower.

Mason McCuskey
Spin Studios
www.spin-studios.com

Founder, Cuttlefish Industries
The Cuttlefish Engine lets anyone develop great games for iPad, iPhone, Android, WP7, the web, and more!

This topic is closed to new replies.

Advertisement