• Advertisement
Sign in to follow this  

Copying DC content to the backbuffer

This topic is 2321 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is the main part of the code, it doesn't seem to do a thing so I suspect I don't really understand how to copy the pixels.



HDC DDC;
HBITMAP hbm;
HDC rdC;
BITMAPINFO bi;
RGBA *badger = (RGBA*)malloc(SCREEN_WIDTH * 4 * SCREEN_HEIGHT);


DDC = GetDC(GetDesktopWindow());
hbm = CreateCompatibleBitmap(DDC,SCREEN_WIDTH,SCREEN_HEIGHT);
rdC = CreateCompatibleDC(DDC);
SelectObject(rdC, hbm);



bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = SCREEN_WIDTH;
bi.bmiHeader.biHeight = SCREEN_HEIGHT;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = SCREEN_WIDTH * 4 * SCREEN_HEIGHT;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;


LockableRect.left = 0;
LockableRect.right = bi.bmiHeader.biWidth;
LockableRect.top = 0;
LockableRect.bottom = bi.bmiHeader.biHeight;


SelectObject(rdC,hbm);
GetDIBits(rdC,hbm,0,500,badger,&bi,DIB_RGB_COLORS);

D3DLOCKED_RECT lockedRect;

backbuffer->LockRect(&lockedRect,&LockableRect,D3DLOCK_DISCARD);

for(unsigned n=0; n<(sizeof(badger)/sizeof(RGBA));n++)
{memcpy((&lockedRect.pBits)[n] ,&badger[n],sizeof(badger[0]));}
backbuffer->UnlockRect();



Thank you in advance,
Adar.

Share this post


Link to post
Share on other sites
Advertisement
for(unsigned n=0; n<(sizeof(badger)/sizeof(RGBA));n++)
{memcpy((&lockedRect.pBits)[n] ,&badger[n],sizeof(badger[0]));}
backbuffer->UnlockRect();
[/quote]
This looks incorrect, in many ways. Try something like this:

char *backBuffer = (char*)lockedRect.pBits;
for(int row=0; row<SCREEN_HEIGHT; ++row) {
RGBA *dest = (RGBA*)(backBuffer + row * lockedRect.Pitch);
RGBA *src = (badger + row * SCREEN_WIDTH);

memcpy(dest, src, SCREEN_WIDTH * 4);
}

Share this post


Link to post
Share on other sites
Thanks mate, I can see pixels change now.cool.gif
can you please explain these lines to me?
;lines;
[code[color="#1C2837"][font="CourierNew, monospace"][color="#000000"] RGBA [color="#666600"]*[color="#000000"]dest [color="#666600"]= [color="#666600"]([color="#000000"]RGBA[color="#666600"]*)([color="#000000"]backBuffer [color="#666600"]+[color="#000000"] row [color="#666600"]*[color="#000000"] lockedRect[color="#666600"].[color="#660066"]Pitch[color="#666600"]);[/font]
[font="CourierNew, monospace"] RGBA [color="#666600"]*[color="#000000"]src [color="#666600"]= [color="#666600"]([color="#000000"]badger [color="#666600"]+[color="#000000"] row [color="#666600"]*[color="#000000"] SCREEN_WIDTH[color="#666600"]);[/font]]
If I get it right, the pitch is the pointer to the number of bytes in a row of pixels, but I don't quite understand what the arithmatics in these line yield.huh.gif

Share this post


Link to post
Share on other sites
RGBA *dest = (RGBA*)(backBuffer + row * lockedRect.Pitch);
backBuffer is a char pointer to the start of the back-buffer memory, top left corner first pixel.
row is the row-number, where the top row is 0 and the bottom is SCREEN_HEIGHT-1.
Pitch is the number of bytes per row.

row * Pitch = the number of bytes from the start of the back-buffer to the start of the row with number 'row'
Since backBuffer is a char-pointer and char size = 1 byte, adding to it yields a pointer exactly that many bytes from the start. So dest is the start of the row we currently want to fill in the back-buffer.

RGBA *src = (badger + row * SCREEN_WIDTH);
badger is the start of the source image, and it's type is a pointer to an RGBA which is 4 bytes in size (32-bit color)
The source memory is always SCREEN_WIDTH * 4 bytes per row. However, since badger is an RGBA pointer each addition is in RGBA units (4 bytes), so badger + row * SCREEN_WIDTH is the start of the source row to copy into the back-buffer.

The memcpy simply copies the whole row (memcpy takes the number of 1-byte units to copy).

Share this post


Link to post
Share on other sites
haven't been home for a while, and read the reply.
now I have only got one windows-oriented question, am I getting the HBITMAP the wrong way?

HBITMAP hbm;
hbm = CreateCompatibleBitmap(DDC,SCREEN_WIDTH,SCREEN_HEIGHT);


because using stretchBlt with DDC, I get an actual desktop pic, but while trying to memcpy the pixels by the method above, they all turn black.(even when the d3d-device's clear color, or the window's brush color isn't black- it just repeats 0,0,0,0 (A,R,G,B) for all pixels).
Think I might be getting the hbm wrong.

Share this post


Link to post
Share on other sites
GDI, forgot to blit context to the new HDC....

rdC = CreateCompatibleDC(DDC);
hbm = CreateCompatibleBitmap(DDC,SCREEN_WIDTH,SCREEN_HEIGHT);

SelectObject(rdC,hbm);

BitBlt(rdC,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,DDC,0,0,SRCCOPY);





Now, does anyone know how I can make my DC hidden to the desktop(display) DC?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement