• Announcements

Archived

This topic is now archived and is closed to further replies.

Bah... page flipping problem

Recommended Posts

Stibmit    122
Using half of Andre''s book and half of the Direct X SDK, I''ve been learning some Directdraw the past while. It''s been going smoothly except for this; page flipping is giving me weird problems. As you can tell from the code below, I''m first setting up a primary surface and then a secondary surface. I plot some random pixels, and try to do so using the backbuffer then flipping. However, every other flip, instead of the random pixels I get some crappy garbage all over the screen. Maybe one of you can find something that I''m doing wrong? Any assistance would be very much appreciated NOTE: lpddprimary is the primary surface. +lpddback is the backbuffer. +ddsd is the surface descriptor +DdErrorCheck() is a function which checks the result of HRESULT, as well as displays an error message if the hresult isn''t successful. +
  /* PRIMARY SURFACE- in the initialization portion of the program*/ //create the primary surface memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; hresult = lpdd->CreateSurface(&ddsd, &lpddprimary, NULL); DdErrorCheck(hresult, "lpdd->CreateSurface(&ddsd, &lpddprimary) FAILED"); //back buffer (from the primary) ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; hresult = lpddprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddback); DdErrorCheck(hresult, "lpddprimary->GetAttachedSurface(lpddback) FAILED"); /* THE MAIN LOOP- where the balls are */ memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); hresult = lpddback->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); DdErrorCheck(hresult, "lpddback->Lock() FAILED"); UCHAR *buffer = (UCHAR *)ddsd.lpSurface; //make a plotting loop for(int index=0; index<1000; index++) { int x = rand()%RES_WIDTH; int y = rand()%RES_HEIGHT; UCHAR color = rand()%256; buffer[x + y*ddsd.lPitch] = color; } //end for //unlock the surface; we''re done with it for now hresult = lpddback->Unlock(NULL); DdErrorCheck(hresult, "lpddback->Unlock() FAILED"); //flip that sucka while(FAILED(lpddprimary->Flip(NULL, DDFLIP_WAIT))); 
Well... that''s the bulk of it, leaving out all the other crap (of which might be useful... eh.). If you can give me any help it would be very helpful! Thanks

Share on other sites
SikCiv    122
Before u use your DdErrorCheck() function you should check the return value using ''if(FAILED(hr)) return;'' to avoid continuing and writing to an invalid pointer.

Also u dont need to use ''while'' here:
while(FAILED(lpddprimary->Flip(NULL, DDFLIP_WAIT)));
The DDFlip_Wait flag does this internally, maybe this is the problem?

Are u clearing the backbuffer after every flip? Use Blt() on your backbuffer and specify the ''clear'' flag.

Share on other sites
Stibmit    122

Hmm, I''ll try that...

in the DdErrorCheck() function it tests if hresult failed, and if it did, what the hell happened (which will also allow the error message to be displayed), so I already have that step, unless I misunderstood you. This is what I have:
  if(hs != DD_OK) { //the programmer can type in a nasty message as well //as get feedback from Directdraw MessageBox(hwnd, errormessage, "DD Error", MB_OK);switch(hs)case ...

And then comes the long list of all the possible return values under DirectDraw.

While I have this window open I''ll try what you said; No, I haven''t been clearing the backbuffer after every flip simply because I''m not too sure how to.

Hmm... I tried DDBLT_CLEAR, but that doesn''t seem to work, so I went into the SDK and couldn''t find anything related to a "clear" flag. Colorfill comes closest to that, but I doubt that would do the correct job. Am I missing something?

Share on other sites
Stibmit    122
Alllllrighty. At the beginning of the main loop I cleared out the backbuffer using the dwColorFill variable and setting it to 0 as well as using the DDBLT_COLORFILL flag then I rendered some crap onto the backbuffer. I'm not even sure if this is the proper way to clean out the backbuffer... I tried using memset() but that made the application freeze up for some weird reason. Am I on the right track? My programs are a little different than those found in Andre LaMothe's book, as his pixels and simple things that he renders on the screen STAY on screen, and mine don't, but that makes perfect sense, while at the same time makes me wonder who's doing something wrong: him or me.

Edited by - Stibmit on July 29, 2001 9:32:46 PM

Share on other sites
SikCiv    122
Use Blt() to clear - this is the quickest way since the video card does this in hardware. Using memset is slower.

Calling DdErrorCheck does not stop the routine which will cause a crash. Use "if(FAILED(hresult)) return false;" to stop the routine.

  // CLEAR BACKBUFFERmemset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd);hresult = lpddback->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); DdErrorCheck(hresult, "lpddback->Lock() FAILED");if(FAILED(hresult)) return false; // SafetyUCHAR *buffer = (UCHAR *)ddsd.lpSurface;//make a plotting loopfor(int index=0; index<1000; index++) { int x = rand()%RES_WIDTH; int y = rand()%RES_HEIGHT; UCHAR color = rand()%256; buffer[x + y*ddsd.lPitch] = color; } //end for //unlock the surface; we''re done with it for now hresult = lpddback->Unlock(NULL); DdErrorCheck(hresult, "lpddback->Unlock() FAILED");//flip that suckawhile(FAILED(lpddprimary->Flip(NULL, DDFLIP_WAIT)));

Share on other sites
Stibmit    122
so.... do this to clean out the surface?

  //clean out the back buffer memset(&bltfx, 0, sizeof(bltfx)); bltfx.dwSize = sizeof(bltfx); bltfx.dwFillColor = 0; lpddback->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx);

SikCiv    122
Yep

Stibmit    122