Asked by:
C++ Windows API: Is there any alternative of the SetDIBits for device-dependent Bitmap?

Question
-
I am trying to make a graphics engine for a Windows API window (something like a game, I've not decided yet), and I do this because I want to practice my math skills and I want to learn more about how this stuff works.
I wanted just a fast-enough function to put a pixel on it. Setpixel, as you may know, is very slow when used to fill a screen, even without calculations. So I've been searching for a long time, until I found this function (SetDIBits) which puts an array of pixel data (I use 24-bit because it has many colors and it's simple) into a HBITMAP class, device-independently (I don't know what this really means), but there says that device-dependent bitmaps work faster. ("Probably the biggest limitation of DIBs is that they are slower than device-dependent bitmaps.")
Here is the address: http://msdn.microsoft.com/en-us/library/ms969901.aspx .
I have some questions:
1. Is the time difference big, I mean, for making animations?
2. Does it help me if I use device-dependent instead of device-independent, as far as I work only on one window?
3. I have a small problem: I am trying to make a blue screen, and it works for some weight and height values, such as 100 x 100, 600 x 100, but for 150 x 150 bitmap, there appear some red lines, green lines, and I don't know exactly why. I think this may be because I use this index (width * bottom + left) * 3, so the image would have a size of (width * height * 3) bytes, and in the page, it says biSizeImage = ((((biWidth * biBitCount) + 31) & ~31) >> 3) * biHeight. I don't understand this, but I think that here is the problem. If I put at the end of the for(i = 0; i < height; i++) this: data += 2, it works correctly for the 150x150 example, but not for the rest, so there may be some bytes in the end of a scan (line), but I don't know how many (it's variable, because it's different from a case to another: for 100x100 it's 0, for 150x150 it's 2). I don't know if this helps. What do you think?
(Here is my code:http://pastebin.com/Skdv7KGS (function is called between BeginPaint() and EndPaint()), and here is a screenshot: http://imageshack.us/content_round.php?page=done&l=img843/5690/screenshothc.png&via=mupload&newlp=1# )
I use Code::Bocks MinGW GCC compiler (http://www.codeblocks.org/).
Thank you!
Sunday, September 25, 2011 8:44 AM
All replies
-
For the ones wondering the same things:
1. I haven't found anything else, but still I think it's faster with the device-dependent ones.
2. I don't know.
3. I've replaced the SetDIBits with SetBitmapBits, which works great, but, if you'll use this too, remember RGBQUAD has 4 bytes of data: rgbRed,rgbGreen,rgbBlue and rgbReserved, so take it into consideration when making the data array:
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
index = (width * i + j) * 4;
data[index] = (j * 256 / width) % 255; //blue
data[index + 1] = 0; //green
data[index + 2] = 0; //red
data[index + 3] = 0; //protected
}
}
Thank you for reading all this stuff.
Best wishes,
Cristi
Sunday, September 25, 2011 12:16 PM -
DirectDraw for ancient cards, Direct2D for new ones
There are some comparison of these technologies in http://msdn.microsoft.com/en-us/magazine/ee819134.aspx
The following is signature, not part of post
Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
Visual C++ MVPSunday, September 25, 2011 4:37 PM -
cristipiticul wrote:>>1. Is the time difference big, I mean, for making animations?For animations, you will usually be drawing onto an offscreen surface,which is then "flipped" to become visible.>2. Does it help me if I use device-dependent instead of>device-independent, as far as I work only on one window?The difference is insignificant, more than swamped by the time it takes tocopy the bitmap to the frame buffer.>3. I have a small problem: I am trying to make a blue screen, and it works>for some weight and height values, such as 100 x 100, 600 x 100, but for>150 x 150 bitmap, there appear some red lines, green lines, and I don't>know exactly why.In a DIB, each scanline is always a multiple of 4 bytes. In a 24-bit DIB,that means you will have extra padding bytes unless the width is a multipleof 4.For a 150x150 DIB, each scanline is 452 bytes long -- 450 bytes of pixels,plus 2 bytes of padding.That's comomonly called the stride. You should compute the address of eachscanline using Stride x Y, then write the data for that stanline.--Tim Roberts, timr@probo.comProvidenza & Boekelheide, Inc.
Tim Roberts, DDK MVP Providenza & Boekelheide, Inc.Monday, September 26, 2011 5:32 AM -
Thank you for your answers. I moved to SetBitmapBits function (device-dependent). I din't know about this padding... interesting. I'll think about using Direct2D later, for now I'll use bitmap stuff :D. Thanks again and have a nice... life!Wednesday, September 28, 2011 6:09 PM