Search code examples
c++windowsopenglpixelformat

Black screen in OpenGL on some machines (PIXELFORMATDESCRIPTOR/SwapBuffer?)


I've written an OpenGL application which will crash on some machines (on my own test machines it runs: Windows 8, Windows 7, Windows Vista (x86) - but on some client machines with Windows Vista (x86) it crashes) - I don't know yet why exactly, but I downgraded the application to an empty skeleton, which will just do glClear(). Then the application runs at least without crash (OpenGL context could be created, glew could be loaded), but the screen is not cleared in the specified glClearColor color. I suspect some issue in either my PIXELFORMATDESCRIPTOR or SwapBuffer doesn't work as expected there.

My code (I left out the windows creation and main() for simplicity):

hdc = GetDC(hWnd);
int   pf;
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize  = sizeof(pfd);
pfd.nVersion  = 1;
pfd.dwFlags   = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
pfd.iPixelType   = PFD_TYPE_RGBA;
pfd.cColorBits   = 32;

pf = ChoosePixelFormat(hdc, &pfd);
if (pf == 0) {
  MessageBox(NULL, "ChoosePixelFormat() failed:  "
 "Cannot find a suitable pixel format.", "Error", MB_OK); 
} 
if (SetPixelFormat(hdc, pf, &pfd) == FALSE) {
  MessageBox(NULL, "SetPixelFormat() failed:  "
 "Cannot set format specified.", "Error", MB_OK);
} 
DescribePixelFormat(hdc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
hglrc = wglCreateContext(hdc);
if(!wglMakeCurrent(hdc, hglrc)){
  MessageBox(NULL, "wglMakeCurrent() failed:  "
 "Cannot make context current.", "Error", MB_OK); 
}
GLenum err = glewInit();
if (GLEW_OK != err){
  /* Problem: glewInit failed, something is seriously wrong. */
  fprintf(stdout, "Error: %s\n", glewGetErrorString(err));
}
fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));

This code outputs: "Status: Using GLEW 1.10.0" My main loop then:

while(true){
  timeDuration = std::chrono::duration_cast<std::chrono::duration<double> >(std::chrono::high_resolution_clock::now() - lastTime);
  lastTime = std::chrono::high_resolution_clock::now();
  time += timeDuration.count();
  glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  SwapBuffers(hdc);
  while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
} 

On my own machine I receive an gray screen (as expected) - but on the machines where my original program crashed, the screen is just black (but none of the MessageBoxes appear and the output is also: "Status: Using GLEW 1.10.0"). So I can't see any evidence for an error - but the output is different and glClearColor() seems to be ignored.

Any ideas on how I could hunt down this issue further?


Solution

  • Well, I'm still not sure why exactly it did run on my machine before, but the issue was the line:

    pfd.dwFlags   = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
    

    after changing it to:

    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    

    it did run anywhere. I didn't specified double buffering in the PIXELFORMATDESCRIPTOR and that seemed to bring strange issues with it (worked on my machine for some reason - but not on others).