I am having trouble drawing a bitmap. I already know that the (two) bitmaps were successfully loaded, my only problem is my double buffer system. I used BitBlt to make a successful double buffer, but my first call to BitBlt (inside 'body') I think is conflicting. Everything compiles fine, but when I run the app all I get is a white screen (instead of a white screen with a bitmap on it)
Also, this function is called very frequently (in a game) so the double buffer is necessary.
my draw function
// In global scope
HBITMAP left, right;
HPALETTE left_p, right_p;
void draw() { // note: outside of the brackets marked 'body' is premade code creating a double buffer, which works with MoveToEx(), LineTo(), etc. (for clarification)
HDC hDC = GetDC(hwnd);
HDC memDC = CreateCompatibleDC(hDC); // my buffer
HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, width, height); // this is the only call to this function in my whole source (is this a problem?)
HBITMAP hOldBmp = (HBITMAP) SelectObject(memDC, hMemBmp);
HPEN white_pen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
HPEN old_pen = (HPEN) SelectObject(memDC, white_pen);
HBRUSH white_brush = CreateSolidBrush(RGB(255, 255, 255));
HBRUSH old_brush = (HBRUSH) SelectObject(memDC, white_brush);
Rectangle(memDC, 0, 0, width, height);
SelectObject(memDC, old_pen);
SelectObject(memDC, old_brush);
DeleteObject(white_pen);
DeleteObject(white_brush);
BitBlt(hDC, 0, 0, width, height, memDC, 0, 0, SRCCOPY); // write buffer to main DC
SelectObject(memDC, hOldBmp);
DeleteObject(hMemBmp);
DeleteDC(memDC);
ReleaseDC(hwnd, hDC);
}
ProgramArtist
July 1st, 2008, 10:51 AM
Hi,
Also, this function is called very frequently (in a game) so the double buffer is necessary.
(1)
If this is so: Is it necessary to call getObject so often? You're using it only for getting the size of the bmp. Is this size changing so often (without any notification to you)?
BTW: I don't understand why double buffering is needed because you call the function frequently. The purpose for double buffering is a flicker-free drawing (I thought).
(2) Possible failure:
The bitblt function where you expect the error blits the loaded bitmap into the normal hdc (of the window). Then (after the closing bracket } ) you blit your double-buffer (bitmap) into the same hdc. Of course you will see a white screen then.
Solution: You should blit the bitmap into your (double) buffer instead into the screen.
For double buffered bitmap blitting you'll need two mem DC's: One for holding the bitmap as a source, one as the double buffer. Both can be created the same way via CreateCompatibleDC.
As the last step you have to blit the double buffer onto the screen (which is working as you wrote for other GDI functions).
Psedo-Code:
// create a memDC to hold the bitmap
HDC hMemDC_Bitmap = CreateCompitibleDC(hdcScreen);
// select the bitmap into this:
HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemDC_Bitmap, hTheBitmap);
// create the memDC for the double-buffer-bitmap:
hMemDC_Buffer = CreateCompatibleDC(hdcScreen);
// now blit the bitmap into the buffer:
BitBlt(hMemDC_Buffer, 0, 0, width, height, hMemDC_Bitmap, 0, 0, SRCCOPY);
SelectObject(hMemDC_Bitmap, hOldBitmap);
DeleteDC(hMemDC_Bitmap);
// now call your existing code to draw the double buffer:
// (including deleting the hMemDC_Buffer
...
If this doesn't help you:
Can you make a compilable test program? It will make it much easier to help you then.
With regards
Programartist
Ingo Bochmann
Bluefox815
July 1st, 2008, 12:38 PM
Thank you, your post helps me a very great deal. The reason I had the double buffer is because it does stop existant flickering.
Are the first integer arguments in BitBlt coordinates? I know the third and fourth are, but are the first and second x y?
example: BitBlt(dst, x, y, width, height, src, 0, 0, SRCCOPY);
This may be causing problems as well if I am not correct, and if I am, are the width and height relative to xy, or relative to the screen?
Also, I have already made a test program without writing to the double buffer. I got my bitmap in the top left of the screen, but it flickered a lot.
What I did was I used BitBlt to get my bitmap on the screen, but I wrote it to the main DC, not my buffer.
...
Just now I paused to try writing to the buffer instead with my test prog (which had a different layout in drawing the bitmap) and it worked perfectly! But it disappeared after about 3 seconds, which is odd. Here is my semi-working code.
In my experience, when you get problems like this, it's often cause by a resource leak. You should make sure you've closed all of the GDI handles. An easy way to tell if this is the problem is to use the Windows Task Manager. Open the Processes tab, the select "Select Columns..." from the View menu, and check GDI Objects. If the number of GDI objects keep increasing, then that's the problem.
Kelly
DreamShore
July 3rd, 2008, 02:44 AM
BitBlt actually copy a portion of the source to the destination. It's not always the (0, 0) when you are copying the entire source.
LoKi_79
July 3rd, 2008, 08:51 AM
I'm not sure about all your double/tripple buffering? Are you planning to draw additional things onto the bitmap? Currently you draw a rectangle onto a memDC, then you crate another memDC and put a bitmap on it, then you copy the bitmap onto the blank one, and copy the result onto the screen... Can you post more of your code, i expect the flickering is to do with either how you invalidate the region or how you handle the erase background message.
Bluefox815
July 5th, 2008, 03:13 PM
in my latest posted code the buffer worked but I found I do have a resource leak.
I've used the same buffer in other programs and it worked perfectly, but it involved only 2 DC's and one call to BitBlt. (instead of bitmaps I used MoveToEx() and LineTo(), Rectangle(), etc.; drawing to memDC, which when finished was drawn to hDC)
I now have two questions.
- How would I fix my resource leak?
- What are all the arguments in BitBlt and how are they used/what do they do?
(In case it helps, I tried to use BitBlt similarly to how you would draw an Image object onto an Applet, which is in Java)
MrViggy
July 7th, 2008, 05:55 PM
- What are all the arguments in BitBlt and how are they used/what do they do?
The MSDN (http://msdn.microsoft.com/en-us/library/ms532278.aspx) is your friend! :D
Viggy
codeguru.com
Copyright 2007 Jupitermedia Corporation All Rights Reserved.