Archived

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

TempusElf

Making a custom BitBlt?

Recommended Posts

I have read many people claiming that BitBlt is "way to slow" and that they opt to instead make their own Blitting functions. I can''t seem to figure out how to do this with GDI. I''ve been trying to get access to the HBITMAP''s bits but GetObject won''t do that and GetDIBits (from what I understand from reading MSDN) only gives you a copy of them. So how would I go about creating an "optimized" Blitting function for GDI Device Contexts? Is there a way to get at and change the bits of an HBITMAP or am I just misunderstanding this whole concept?

Share this post


Link to post
Share on other sites
I think you can get an offset of a BITMAP pointer and access the bits that way. It is either BITMAP, BITMAPHEADER or BITMAPINFOHEADER. I would check before using though.

eg.

  
BITMAP* pBmp;
BYTE* pixels;
pixels = pBmp + sizeof(BITMAP);


something like that anyway.

I think maybe your biggest problem will be getting it on the screen without using BitBlt.

Could you please email me at aholland@tasmail.com if you get something working? I am interested in doing something similar.


''Your theory of a donut shaped universe is intriguing Homer'' - Stephen Hawking

Share this post


Link to post
Share on other sites
Basicly...you will end up useing something like bitblt to show the image onscreen...but this is only for your final image.

The most basic approch is to create a GDI friendly off screen BITMAP buffer in system memory (not video memory)...use your own blitting fuctions to change the pixel colors of this surface, then use GDI to transfer it to the screen (course you could also write your own routines to do this also...but then you start to get into writeing for video card drivers and the different standards they have)

the reason why you do this in system memory is because the transfer bus between the system and video card can be very, very slow...one transfer of the whole screen image can take a lot less time then transfering each tile and sprite one at a time (and telling the video card where and how to ''render'' each).

Share this post


Link to post
Share on other sites
Actually, I had a look at this and you can actually get a pointer to the bits from the BITMAP structure. Try something like this:


  
BYTE* GetBits(HBITMAP hsrc){
BITMAP bmp;
GetObject(hsrc, sizeof(bmp), &bmp);
return bmp.biBits;
}


Too easy
Of course, the bitmap will be device dependant so you would need to do your own coding to deal with the bits. The easiest way to do this is insist that everybody use 24 or 32 bit colour mode...




''Your theory of a donut shaped universe is intriguing Homer'' - Stephen Hawking

Share this post


Link to post
Share on other sites
quote:
Original post by Sailorstick
Too easy



Thanks for your response but GetObject will only give you a BITMAP structure that has everything except the biBits member. This was actually the first thing that I tried.

I've come to the conclusion that GDI doesn't let you get direct access to device dependent bitmaps. However I have found ways to get access to the bits of DIB's. (Specifically, by creating them with CreateDIBSection) So, I figure that I'll just do all my operations on device independent bitmaps and then use BitBlt to put the back buffer on to the screen like what MSW was talking about.

EDIT: oh wait... I'm dumb... Sailorstick, I just tried your function and it works just fine but only if the bitmap is device independent... which is all good since I've decided to just use all DIBs

[edited by - TempusElf on January 23, 2003 5:13:53 PM]

Share this post


Link to post
Share on other sites

      
HDC my_DC = GetDC(ghWnd);
if(my_DC == NULL)
{
return;
}
HDC bmapDC = CreateCompatibleDC(my_DC);
if(bmapDC == NULL)
{
DeleteDC(my_DC);
return;
}
HBITMAP h_bmap = CreateCompatibleBitmap(my_DC,X,Y);
if(h_bmap == NULL)
{
DeleteDC(my_DC);
DeleteDC(bmapDC);
return;
}
SelectObject ( bmapDC, h_bmap );

.
.
.
// DRAW TO BITMAP IN MEMORY

.
.
.
// NOW DRAW TO SCREEN

BitBlt(my_DC,0,0,X,Y,bmapDC,0,0,SRCCOPY);
DeleteObject(h_bmap);
DeleteDC(bmapDC);
DeleteDC(my_DC);


This is from a 2d GDI tetris I made a while back. I generalized it some (hope i didnt introduce any errors). Adapt as needed. Good Luck.

[edited by - jplocster on January 23, 2003 3:36:09 PM]

[edited by - jplocster on January 23, 2003 3:36:29 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
What about different bitmap formats? Do you have to cater for every possible format - in which case, how many are there?

Share this post


Link to post
Share on other sites
You do need your own BitBlit for converting color formats.

This is how it works:
- Get the start of a scanline for both images (iY*lPicth basically)
- Copy a pixel
- Increment src and dest pointers
- Loop next pixel (X)
- Loop next scanline (Y)

its easy, you just have to exparament

Share this post


Link to post
Share on other sites