Bah... page flipping problem

Started by
6 comments, last by Stibmit 22 years, 8 months ago
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
If you keep on dividing (man) you end up as a collection of monkeys throwing nuts at each other out of separate trees." - Merlyn, The Once and Future King (T.H. White)
Advertisement
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.


  Downloads:  ZeroOne Realm

  Downloads:  ZeroOne Realm


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?
If you keep on dividing (man) you end up as a collection of monkeys throwing nuts at each other out of separate trees." - Merlyn, The Once and Future King (T.H. White)
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
If you keep on dividing (man) you end up as a collection of monkeys throwing nuts at each other out of separate trees." - Merlyn, The Once and Future King (T.H. White)
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)));  



  Downloads:  ZeroOne Realm

  Downloads:  ZeroOne Realm

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);  
If you keep on dividing (man) you end up as a collection of monkeys throwing nuts at each other out of separate trees." - Merlyn, The Once and Future King (T.H. White)
Yep

  Downloads:  ZeroOne Realm

  Downloads:  ZeroOne Realm

Heh, thanks for your help
If you keep on dividing (man) you end up as a collection of monkeys throwing nuts at each other out of separate trees." - Merlyn, The Once and Future King (T.H. White)

This topic is closed to new replies.

Advertisement