Sign in to follow this  

DDraw 7: I Can't Get Back Buffers to Work

This topic is 4860 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am a newbie to the world of DirectX. Using the following initialization code, I can't seem to be able to draw to the back buffer Note: Thise is only the initialization for DirectDraw.
//Here are my globals
//DirectX stuff
LPDIRECTDRAW7        lpdd;            // The DirectDraw7 object
LPDIRECTDRAWSURFACE7 lpddsprimary;    // The primary surface
LPDIRECTDRAWSURFACE7 lpddsback;       // The back buffer
LPDIRECTDRAWCLIPPER  lpddclipper;     // DD clipper for back surface
DDSURFACEDESC2       ddsd;            // A direct draw surface description struct
DDSCAPS2             ddscaps;         // A direct draw surface capabilities struct
int                  dd_pixel_format; // Keep track of the 5.5.5 or 5.6.5 pixel format

//InitDDraw() - Initializes DDraw to 16 bit fullscreen mode, 640x480
//	Returns true if succeseful and false otherwise
bool App::InitDDraw(HWND hWnd)
{
	if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
	{	
		AddError("Could not create the DirectDraw interface");
		return false;
	}
	// set cooperation level to fullscreen mode 
	if(FAILED(lpdd->SetCooperativeLevel(hWnd, DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT | DDSCL_MULTITHREADED )))
	{
		AddError("Could not set the proper cooperation level");
		return false;
	}

	// set the display mode
	if (FAILED(lpdd->SetDisplayMode(640, 480, 16, 0, 0)))
	{
		AddError("Could not set the display mode.");
		return false;
	}

	//Create the primary surface
	memset(&ddsd, 0, sizeof(ddsd));                                                 //clear the surface description
	ddsd.dwSize  = sizeof(ddsd);                                                    //set the size to the size of the DDSD struct
	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;                                //tell directX what counts and what doesn't
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;  //set the surface capabilities
	ddsd.dwBackBufferCount = 1;                                                     //tell directX how many backbuffers to have
	// Officialy create the primary surface
	lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL);

	// get the pixel format of the primary surface
	DDPIXELFORMAT ddpf; // used to get pixel format

	// initialize structure
	DDRAW_INIT_STRUCT(ddpf);

	// query the format from primary surface
	lpddsprimary->GetPixelFormat(&ddpf);

	// based on masks determine if system is 5.6.5 or 5.5.5

	// use number of bits, better method
	dd_pixel_format = ddpf.dwRGBBitCount;

	// set up conversion macros, so you don't have to test which one to use
	if (dd_pixel_format == DD_PIXEL_FORMAT555)
		RGB16Bit = RGB16Bit555;
	else
		RGB16Bit = RGB16Bit565;

	// query for the backbuffer i.e the secondary surface
	memset(&ddscaps, 0, sizeof(ddscaps));
	ddscaps.dwCaps = DDSCAPS_BACKBUFFER;

	if(FAILED(lpddsprimary->GetAttachedSurface(&ddscaps, &lpddsback)))
	{
		AddError("Could not create the back buffer.");
		return false;
	}

	RECT screen_rect = {0, 0, 640, 480};

	//create the clipper
	if(FAILED(lpdd->CreateClipper(0, &lpddclipper, NULL)))
	{
		AddError("Could not create clipper");
		return false;
	}
	LPRGNDATA rgndata; //Create the region data used to define the clipped region
	rgndata = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+sizeof(RECT)); //allocate enough memory to hold everything
	memcpy(rgndata->Buffer, &screen_rect, sizeof(RECT)); //copy the rectangle into buffer
	//set the rgndata's header feilds
	rgndata->rdh.dwSize   = sizeof(RGNDATAHEADER);
	rgndata->rdh.iType    = RDH_RECTANGLES;
	rgndata->rdh.nCount   = 1;
	rgndata->rdh.nRgnSize = sizeof(RECT);

	rgndata->rdh.rcBound.left    =  64000;
	rgndata->rdh.rcBound.top     =  64000;
	rgndata->rdh.rcBound.right   = -64000;
	rgndata->rdh.rcBound.bottom  = -64000;

	if(FAILED(lpddclipper->SetClipList(rgndata, 0)))
	{
		free(rgndata);
		AddError("Could not set the clipper clip list");
		return false;
	}
	if(FAILED(lpddsback->SetClipper(lpddclipper)))
	{
		free(rgndata);
		AddError("Could not attach the clipper to the surface.");
		return false;
	}
	free(rgndata);

	return true;
}

Edited by Coder: Use source tags for large blocks of code. Check GDNet Forums FAQ [Edited by - Coder on August 22, 2004 7:11:26 AM]

Share this post


Link to post
Share on other sites
We need more information, where the problem occurs, what line it crashes on, or if it doesn't crash, etc. It would also be nice to see the portion of code that draws to the back buffer.

Chris

Share this post


Link to post
Share on other sites
The program doesn't accually crash. It's wierd. if I do a color fill like so:

RECT screen_rect = {5, 5, 55, 55};

//Clear the surfaces
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
DDRAW_INIT_STRUCT(ddbltfx); // clear out the structure and set the size field
ddbltfx.dwFillColor = color; // set the dwfillcolor field to the desired color

// blt blank to surfaces
lpddsback->Blt(&screen_rect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);


It should make a red rectangle at {5,5,55,55}, instead it fills the whole screen with red. If I do the samething, but blt to the primary surface, it works. Also, if I blt another surface to the back buffer like so:

//"picture" is the other surface. It is 160x120
RECT pic_rect = {0, 0, 159, 119}; //Make the source rectangle with the pictures dimensions
RECT dest_rect= {x, y, x+159, y+119}; //Make the destination rectangle with the pictures dimensions starting on where the user wants to draw it.

lpddsback->Blt(&dest_rect, _picture, NULL, (DDBLT_WAIT | DDBLT_KEYSRC), NULL);


I don't see anything. But if I do the same thing but blt to the primary surface, it works, but the picture is all flickery.

P.S. I am flipping the surfaces.

Share this post


Link to post
Share on other sites

This topic is 4860 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this