Skip to main content
GameDev.net gamedev.net
🔒 Locked

Monochrome DC??? (Win32)

Started by kirkd Aug 28, 2006 at 4:38 PM 5 replies 3.2k views
Original Post
kirkd
kirkd
I'm working on a simple console clone - see if you can guess what it is. 8^) I'm working with simple Win32 API - no DirectX here. Here's a basic idea of what I have: Map Object: This contains a maze map that will be drawn to the screen. The map is a text file that defines where the walls are. There is a Draw function that takes an HDC as its parameter. When Draw(HDC dc) is called, I walk through the map and draw a green square to the target DC where there is supposed to be a portion of a wall. Here's the code that does that:

long x, y;  //loop indices
long TileID; //which tile to draw?

HBRUSH NewBrush = CreateSolidBrush(RGB(25, 250, 5));
HBRUSH OldBrush = (HBRUSH)SelectObject(TargetDC,NewBrush);

//parse through the map and blit the appropriate picture to the targetDC
for (x=0; x<m_Model->Width(); x++)
{
	for (y=0; y<m_Model->Height(); y++)
	{
		TileID = m_Model->GetPosition(x,y);
		if (TileID != 0)
		{
			Rectangle(TargetDC, x*m_TileHeight, y*m_TileWidth,
					x*m_TileHeight+16, y*m_TileWidth+16);		}
	}
}

SelectObject(TargetDC,OldBrush);
DeleteObject(NewBrush);






World Object: Contains a Map Object. It also has its own DC used as a back buffer. I create the back buffer DC like this:

m_hBackBuffer = CreateCompatibleDC(NULL);  
m_hBitmap = CreateCompatibleBitmap(m_hBackBuffer, m_PixelWidth, m_PixelHeight);
m_hOldBitmap = (HBITMAP) SelectObject(m_hBackBuffer, m_hBitmap);





The World Object also has a draw function that takes an HDC parameter:

//tell the map to draw to the backbuffer
m_MazeController.Draw(m_hBackBuffer);
	
//draw the backbuffer to the target
BitBlt( TargetDC,
	0,0,
	m_PixelWidth, m_PixelHeight,
	m_hBackBuffer,
	0,0,
	SRCCOPY);






The general flow is this: When WM_PAINT is called, I call the World::Draw function with the window DC as a paramter. Inside World::Draw I call the Map::Draw function using the BackBuffer as a parameter. The Map::Draw function parses the text file and draws green squares in the appropriate locations on the BackBuffer. Back insed World::Draw, after calling Map::Draw, I BitBlt the BackBuffer to the window DC. The assumption is that I'll have green walls drawn to form my maze, but I get this: Image Hosted by ImageShack.us It appears that somewhere along the way, I'm getting a monochrome image. I've done a number of tests and found that if I draw to the BackBuffer directly in the Wolrd::Draw function and then BitBlt, I get the monochrome situation. But, if I draw directly to the window DC in World::Draw, I get the correct colors. Any ideas??? -Kirk
Anon Mike
Anon Mike
Change:
m_hBackBuffer = CreateCompatibleDC(NULL);  m_hBitmap = CreateCompatibleBitmap(m_hBackBuffer, m_PixelWidth, m_PixelHeight);

to
HDC screen = GetDC(NULL);m_hBackBuffer = CreateCompatibleDC(screen);m_hBitmap = CreateCompatibleBitmap(screen, m_PixelWidth, m_PixelHeight);ReleaseDC(NULL, screen);


When you create a bitmap it comes with a 1x1x1bpp bitmap selected into it. You code then goes on to create new bitmap compatible with that. What you need instead is a bitmap compatible with the screen.
-Mike
kirkd
kirkd
That did the trick!

Now, instead of the ugly monochrome, I get this:

Image Hosted by ImageShack.us


Or, even better yet, I've extended your suggestion deeper into my code and gotten my actual goal:

Free Image Hosting at www.ImageShack.us


I'm still confused by the documentation for CreateCompatibleDC:


Quote:

HDC CreateCompatibleDC(
HDC hdc // handle to the device context
);

Parameters
hdc
Handle to an existing device context. If this handle is NULL, the function creates a memory device context compatible with the application's current screen.



It sounds to be like if hdc is NULL, the resulting DC should be compatible with the screen, no??

Thanks for you help!!!

-Kirk


edit: And - the beauty of object oriented design - I add one line of code and get this:

Free Image Hosting at www.ImageShack.us

Anon Mike
Anon Mike
Quote:
Original post by kirkd
I'm still confused by the documentation for CreateCompatibleDC:
...
It sounds to be like if hdc is NULL, the resulting DC should be compatible with the screen, no??

The DC is compatible. The default bitmap in the DC is the stock 1x1x1 bitmap as I described. These are two completely different things. A DC actually doesn't need to have a bitmap at all (think plotters for example).
-Mike
kirkd
kirkd
I guess therein lies my confusion. My original code was:

m_hBackBuffer = CreateCompatibleDC(NULL);
m_hBitmap = CreateCompatibleBitmap(m_hBackBuffer, m_PixelWidth, m_PixelHeight);
m_hOldBitmap = (HBITMAP) SelectObject(m_hBackBuffer, m_hBitmap);


My take on this was:

Create a screen compatible DC.
Create a bitmap compatible with the DC, which is then compatible with the screen.
Load the bitmap into the DC and replace the 1x1x1 stock bitmap.


I assume that in the second line I was actually creating another monochrome bitmap.

Thanks again for you help.


Anon Mike
Anon Mike
One DC being compatible with another basically means they front the same device or there is some trivial translation between them. e.g. two display DC's are compatible. A display DC and a memory DC based off a display DC are compatible. A display DC and a printer DC are not.

You're not alone, many, many people confuse DC's with the bitmap selected into it. They really are completely different things. If they were the same thing you wouldn't even be able to do something like select a different bitmap in.
-Mike
kirkd
kirkd
I guess I just need to keep reading Petzold. Lots of pages.... 8^)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.