Clipping

Started by
12 comments, last by Archi 19 years, 5 months ago
Could anyone point me to a tutorial about how to set up the DirectDraw clipper? I have some code, but it doesn't work. At all. What so ever. :) When I try it, the first image blt works, but from then on, the blts fail, so I assume that my clipper set up is whacked. Cheers SIgma | | | \ / posted in the wrong form: [edit] whoops: Posted this in Game programming, not DX. Damn. Ok, I'll post over there, but don't freak for a double post ok! :)
Advertisement
      LPDIRECTDRAWCLIPPER      lpClipper=NULL;//DirectDrawClipper       result = lpDD->SetDisplayMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, 0, 0);      result = lpDD->CreateSurface( &ddsd, &lpFront, NULL );      result = lpDD->CreateSurface(&ddsd, &lpBack, NULL);      // Create a clipper (used in IDirectDrawSurface::Blt call)	result = lpDD->CreateClipper(0, &lpClipper, NULL);	if( result!=DD_OK )	{		return false;	}	result = lpClipper->SetHWnd(0, g_hWindow);		//Client area of the window	if( result!=DD_OK )	{		return false;	}	result = lpBack->SetClipper(lpClipper);	if( result!=DD_OK )	{		return false;	}


NOTE: Don't try BltFast() with clipper - only Blt() or Flip()

PS: That's quick cut out of the working app - hope it helps
Well, i got my code to work. I was attaching the clipper BEFORE I initialized the surface! Oopps...

You seem to be doing the attaching in WAY less code than me tho....I'll try your method. thx man
Actually it doesn't work 100% If I move off the screen at a diagonal angle, it crashes. Any idea what could cause this?
Common...anyone?
first question: is it fullscreen app or windowed?
second question: do you attach clipper to front surface or to the back one?
Full screen. Back surface
You'd better post some code of yours, where are
- Clipper creation and attachment
- Blitting/Flipping Back to Front surfaces
- Viewport movement
clipping creation

LPDIRECTDRAWCLIPPER MercuryEngine::DDCrClipper(LPDIRECTDRAWSURFACE7 lpdds,                                 int num_rects,                                 LPRECT clip_list){        int index; //loop var        LPDIRECTDRAWCLIPPER DDclipper; // our clipper        LPRGNDATA region_data; //contains clip list        if(FAILED(lpdd->CreateClipper(0,&DDclipper,NULL)))                return(NULL);        //creat clip list from data sent        region_data = (LPRGNDATA)malloc((sizeof(RGNDATAHEADER) + num_rects * sizeof(RECT)));        //copy rects into region data        memcpy(region_data->Buffer, clip_list , sizeof(RECT)*num_rects);        //set up fields        region_data->rdh.dwSize   = sizeof(RGNDATAHEADER);        region_data->rdh.iType    = RDH_RECTANGLES;        region_data->rdh.nCount   = num_rects;        region_data->rdh.nRgnSize = num_rects * sizeof(RECT);        region_data->rdh.rcBound.left   = 64000;        region_data->rdh.rcBound.top    = 64000;        region_data->rdh.rcBound.right  = -64000;        region_data->rdh.rcBound.bottom = -64000;        //find bounds for clipping        for(index = 0; index < num_rects; ++index)        {                //test if the next rectangle union with the current bound is alrger                if (clip_list[index].left < region_data->rdh.rcBound.left)                        region_data->rdh.rcBound.left = clip_list[index].left;                if (clip_list[index].right < region_data->rdh.rcBound.right)                        region_data->rdh.rcBound.right = clip_list[index].right;                if (clip_list[index].top < region_data->rdh.rcBound.top)                        region_data->rdh.rcBound.top = clip_list[index].top;                if (clip_list[index].bottom < region_data->rdh.rcBound.bottom)                        region_data->rdh.rcBound.bottom = clip_list[index].bottom;        }        //now we have computedthe bounding rectangle region and set up the data        //now we deal with the clipping list        if(FAILED(DDclipper->SetClipList(region_data,0)));        {                delete(region_data);                //return(NULL);        }        if(FAILED(lpdds->SetClipper(DDclipper)));        {                delete(region_data);                //return(NULL);        }        //and now we are done        delete(region_data);        return(DDclipper);}


Attach then Blt source
RECT clipper_rect[1] = {0,0,799,599}; //fullscreen clipping area...//attach a clipper to the backsurface        DDclipper = GameEngine.DDCrClipper(DDback,1,clipper_rect);BLT HERE//draw the back ground image        if(FAILED(DDback->Blt(&dest_rect,DDback_sprite,&src_rect,DDBLT_WAIT, NULL)))        {                Application->MessageBoxA("Error","Boom",MB_OK);                Application->Terminate();        }        //draw the BOB sprite        if(FAILED(DDback->Blt(&bob.dest_rect,bob.DDBOB,&bob.src_rect ,(DDBLT_WAIT | DDBLT_KEYSRC),NULL)))        {                //nail any errors that get through                hr = DDback->Blt(&bob.dest_rect,bob.DDBOB,&bob.src_rect ,DDBLT_WAIT,NULL);                //display said error                Application->MessageBoxA(buf,"Boom",MB_OK);                Application->Terminate();        } //flip        while(FAILED(DDprimary->Flip(NULL,DDFLIP_WAIT))); 


I had once tried to use windows regions with clipper, but that failed, too (strange, perhaps it's a windows bug), so I've clipped to hWnd and Back surface and
lpClipper->SetHWnd(0, g_hWindow);lpBack->SetClipper(lpClipper);

works fine for me in fullscreen and windowed modes

EDIT: Damn that tags!

This topic is closed to new replies.

Advertisement