StretchBlt only works when nHeightDest is negative

I’m trying to use StretchBlt in order to copy pixels from a memory hdc to the window hdc.
The memory hdc gets the image from an invisible window which renders a stream using openGL.

Here’s my code:

BITMAPINFOHEADER createBitmapHeader(int width, int height) {
    BITMAPINFOHEADER header;
    header.biSize = sizeof(BITMAPINFOHEADER);
    header.biWidth = width;
    header.biHeight = height;
    header.biPlanes = 1;
    header.biBitCount = 32;
    header.biCompression = BI_RGB;
    header.biSizeImage = 0;
    header.biXPelsPerMeter = 0;
    header.biYPelsPerMeter = 0;
    header.biClrUsed = 0;
    header.biClrImportant = 0;

    return header;
}

...

HDC memoryHdc = CreateCompatibleDC(windowHdc);
BITMAPINFO bitmapInfo;
bitmapInfo.bmiHeader = createBitmapHeader(targetDimensions.width, targetDimensions.height);
HBITMAP bitmap = CreateDIBitmap(windowHdc, &bitmapInfo.bmiHeader, CBM_INIT, offscreenBuffer, &bitmapInfo, DIB_RGB_COLORS);
SelectObject(memoryHdc, bitmap);
DeleteObject(bitmap);

SetStretchBltMode(windowHdc, COLORONCOLOR);
StretchBlt(windowHdc,
    targetDimensions.x, targetDimensions.y,
    targetDimensions.width, -targetDimensions.height,
    memoryHdc,
    sourceDimensions.x, sourceDimensions.y,
    sourceDimensions.width, sourceDimensions.height,
    SRCCOPY);

DeleteDC(memoryHdc);

Where windowHdc is the hdc of the window to which I want the StretchBlt to copy the pixels to, and offscreenBuffer is a void* to the pixels copied from the offscreen window in which the openGL is rendering.

This code works great, except that the image is upside down and I want it vertically flipped.
I know that this happens because:

If nHeightSrc and nHeightDest have different signs, the function
creates a mirror image of the bitmap along the y-axis

But when I remove the minus sign and both target and source heights are the same then I see no image in the window.
Just to check, I tried to put the minus on the sourceDimensions.height but that also results in no image, and the same if I try to negate the widths (both target and source).

Any idea why?
Thanks.


Source: windows

Leave a Reply