Jump to content
Tuts 4 You

SetDIBitsToDevice parameters


Killboy

Recommended Posts

Posted

I got a question for all you GDI pros out there

Following scenario:

I have a bitmap for which I get the pixels using GetDIBits for every single line (I do this because I have a seperate buffer for every line in order to have a 2-dimensional array so I can easily access pixels using buffer[y][x])

bmiHeader.biHeight is set to the negative bitmap height so I can use top-to-bottom bitmap data, this is easier to use with client coordinates etc.

I periodically change pixels in the buffer and then write its content into a compatible bitmap using SetDIBits, again line by line. The compatible bitmap is selected into a compatible DC for rendering and on WM_PAINT I just BitBlt from the renderDC to the window DC.

Now, this works all fine and dandy but I found SetDIBitsToDevice which seems to do the same thing without having to create an additional bitmap for drawing, also only writing to the bitmap when I actually need to paint is probably better than every time I modify pixels in the buffer.

Anyway, this is the code giving me trouble:


for(int i = y; i < y+ysize; i++)
{
SetDIBitsToDevice(hdc, x, i, xsize, 1, x, 0, 0, 1, this->DIBitsRender[i], &this->stBmpInfo, DIB_RGB_COLORS);
}

where x, y, xsize, ysize define the region that needs updating, this->DIBitsRender holds bitmap data for line i

My problem is that it paints the whole thing bottom-up, although the bitmap height in stBmpInfo is negative which should tell it to draw top to bottom. I fiddled with the xSrc and ySrc params, but any other value leads to wrong parts of the pictures drawn to the rectangle.

What am I missing? The MSDN docs are very vague about the parameters and their meaning, google didn't help either.

Posted

Some more observations:

Calling it like this:

SetDIBitsToDevice(hdc, x, y, xsize, ysize, x, 0, i, 1, this->DIBitsRender[i], &this->stBmpInfo, DIB_RGB_COLORS);

it kinda works but I can see blur when I move another window over it.

I modified the code from earlier to use bitmap rows starting at the bottom:

SetDIBitsToDevice(hdc, x, i, xsize, 1, x, 0, 0, 1, this->DIBitsRender[this->bmpHeight-i-1], &this->stBmpInfo, DIB_RGB_COLORS);

which for some reason removes the blur and lagging when another window invalidates it but I still would like to know what is happening here :wacko:

Posted

Fixed it, in case anyone cares what was going wrong:

I called GetDIBits for every row, but as it turns out the scan line index maps to the physical line in the bmp file, thus bottom-to-top. When you supply it a buffer for all lines it automatically mirrors the lines for a top-to-bottom DIB. With one scan line though it ignores the negative height in the bmpinfo header. So yeah, the solution is to request scan line bmpHeight-i-1 for buffer or the other way around.

The devil is in the detail :wacko:

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
×
×
  • Create New...