I have some code written to do an openGL render into a DIBSection, and it is working fine for the RGB channels, but is not generating the alpha pixels - they all get set to zero on any pixel that is drawn, regardless of alpha, so when I save to PNG file, it is completely black. Other file types work fine (JPG, GIF, BMP), and if I programmatically set all the alpha pixels to 255 just before saving, the PNG also works.
I’ve tried clearing the alpha bits before the OpenGL rendering, and any pixels that are not touched by OpenGL will retain their original alpha channel, but any pixels rendered by openGL (regardless of alpha channel) will set the DIBSection alpha channel to zero.
I’m guess it’s got to be something in the pixel format descriptor for the DIB, right? Here’s the code for setting up the DIB prior to rendering…
//-------------------------------------
// Create the memory DC for the OpenGL context
//-------------------------------------
m_hDC = ::CreateCompatibleDC(NULL);
// Create the DIB to render into
memset(&m_bmi, 0, sizeof(BITMAPINFO));
m_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_bmi.bmiHeader.biWidth = m_iWidth;
m_bmi.bmiHeader.biHeight = m_iHeight;
m_bmi.bmiHeader.biPlanes = 1;
m_bmi.bmiHeader.biBitCount = 32;
m_bmi.bmiHeader.biCompression = BI_RGB;
m_bmi.bmiHeader.biSizeImage = m_iWidth * m_iHeight * 4;
m_hBitmap = ::CreateDIBSection(m_hDC/*hWindowDC*/, &m_bmi, DIB_RGB_COLORS, &m_bmpBits, NULL, (DWORD)0);
::SelectObject(m_hDC, m_hBitmap);
// direct method of pixel format setting
//-------------------------------------
// Select a software-rendering pixel format that supports drawing to a bitmap
// (Must be 32-bit color because the bitmap is 32-bit color)
//-------------------------------------
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */
1, /* version num */
PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP,/* support OpenGL */
PFD_TYPE_RGBA, /* pixel type */
32, /* 8-bit color depth */
8, 24, 8, 16, 8, 8, /* color bits (ignored) */
8, 0, /* alpha bits */
0, /* no accumulation buffer */
0, 0, 0, 0, /* accum bits (ignored) */
16, /* depth buffer */
0, /* no stencil buffer */
0, /* no auxiliary buffers */
PFD_MAIN_PLANE, /* main layer */
0, /* reserved */
0, 0, 0 /* no layer, visible, damage masks */
};
int SelectedPixelFormat;
BOOL retVal;
SelectedPixelFormat = ::ChoosePixelFormat(m_hDC, &pfd);
if (SelectedPixelFormat == 0) {
AfxMessageBox("Failed to find acceptable pixel format.", MB_ICONERROR | MB_OK);
return EXIT_FAILURE;
}
// just to double check, read out the pfd and check it in the debugger...
DescribePixelFormat(m_hDC, SelectedPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
retVal = SetPixelFormat(m_hDC, SelectedPixelFormat, &pfd);
if (retVal != TRUE) {
AfxMessageBox("Failed to set pixel format.", MB_ICONERROR | MB_OK);
return EXIT_FAILURE;
}
//-------------------------------------
// Initialize the OpenGL context
//-------------------------------------
m_hGLRC = wglCreateContext(m_hDC);
m_hOldDC = wglGetCurrentDC();
m_hOldGLRC = wglGetCurrentContext();
wglMakeCurrent(m_hDC, m_hGLRC);
// Setup the OGL viewport
glViewport(0, 0, m_iWidth, m_iHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, m_iWidth, m_iHeight, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
After that, I call my existing OGL DrawScene() function. Everything seems to work fine, except the alpha channel. Immediately after calling DrawScene(), any pixel touched by OpenGL has alpha = 0. I can overwrite all the alpha pixels with 255 before saving, then I can see the saved PNG file perfectly. If I overwrite with 128, then I can see a half-transparent image. I just need to get the OpenGL alpha channel coming out into the DIB correctly!
Any ideas?