BitBlt, OpenGL et Vista Aero.
Le problème exposé ci-dessous n'apparaît que sous Vista avec l'interface Aero active. Sous XP, ou sans l'interface Aero, ou si un logiciel comme PaintShopPro change le jeu des couleurs, tout va bien.
Je cherche à capturer le contenu d'une fenêtre OpenGL dans une bitmap.
(DisplayWnd est le HWND de ma fenêtre OpenGL)...
Code:
1 2 3 4 5 6 7
| HDC dc = ::GetDC(DisplayWnd);
HDC hdc = CreateCompatibleDC(dc);
HBITMAP hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void **)&bufferbgr, NULL, 0);
HBITMAP oldBitmap = (HBITMAP)SelectObject(hdc, hBitmap);
BitBlt(hdc, 0, 0, WdWidth, WdHeight, dc, 0, 0, SRCCOPY); |
J'obtiens ce qu'il y a en dessous de ma fenêtre OpenGL, comme si la fenêtre OpenGL était complètement transparente. J'ai essayé avec du StretchBlt et du transparentBlt avec le même résultat.:cry:
Any good idea?
glReadPixels est la réponse...
Bon, j'ai la réponse à ma propre question...:yaisse2:
Code:
1 2 3 4 5 6 7 8 9 10
| UCHAR* CPlot3DWnd::GetScreenImage()
{
UCHAR *Buffer = new UCHAR[m_Cx*m_Cy*4];
CDC *pDC = GetDC();
wglMakeCurrent(pDC->GetSafeHdc(), m_hRC);
glReadPixels(0, 0, m_Cx, m_Cy, GL_RGBA, GL_UNSIGNED_BYTE, Buffer);
int Err = GetLastError();
wglMakeCurrent(NULL, NULL);
return Buffer;
} |
Attention le buffer obtenu est constitué de blocs de 4 octets RGBA, il faudra le traiter par quelque chose comme:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| bufferbgr = GETPLOT3DVIEW->GetScreenImage();
*Buffer = new unsigned char [WdWidth*WdHeight*BitPerPixel];
unsigned char * ptmp = *Buffer;
unsigned char * pbuffer = bufferbgr;
for (int j=0; j<WdHeight; j++)
{
for (int i=0;i<WdWidth; i++)
{
*ptmp++ = *pbuffer++;
*ptmp++ = *pbuffer++;
*ptmp++ = *pbuffer++;
pbuffer++;
}
}
delete [] bufferbgr; |
Je ne ferme pas tout de suite la question au cas où quelqu'un ait une meilleure idée... 8O
De plus j'ai contourné le problème... je sais toujours pas pourquoi le bitblt ne marche pas sous Aero...