PDA

View Full Version : Screen resolution change troubles/Windows



Pa3PyX
03-24-2003, 09:00 AM
Help make sense of what's going on here...

When I try to change screen resolution (or just destroy and recreate the window) in Windows after OpenGL has been running for some time, and set it up to use OpenGL, it works only so long as I use no texturing. Attempting to use textures after such procedure crashes the app. The crash occurs with hardware accelerated drivers (both 3Dfx Voodoo3, latest ICD, and latest MiniGL), but it works fine with Microsoft's generic ICD, and WickedGL. Here's the sequence of calls:

//Clean all OpenGL textures
glDeleteTextures(...)
//Make GL rendering context non-current
wglMakeCurrent(NULL, NULL);
//Delete GL rendering context
wglDeleteContext(hRC);
//Release device context
ReleaseDC(hWnd, hDC);
//Close old window
DestroyWindow(hWnd);
//Unregister its class
UnregisterClass(<classname>, hInstance);

//Register window class
wc.style = CS_OWNDC;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = global_hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = "GLSample";
RegisterClass(wc);
//Make a new window
hWnd = CreateWindow("GLSample", "OpenGL Sample", WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, global_hInstance, NULL);
//Get device context
hDC = GetDC(hWnd);
//Set up pixel format
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, format, &pfd);
//Create OpenGL rendering context
hRC = wglCreateContext(hDC);
//Make it current
wglMakeCurrent(hDC, hRC);

Much of this code is a cut and paste from Blaine Hodge's GLSample. Now it works so long as there was no OpenGL window before it is executed, but no longer works after there was one. Adding return result checks does not work -- none of the functions above actually fail, they all return success. Only the first call to glTexCoord2f() results in a nasty crash.

Now it could be attributed to a device driver bug, except for one thing. It works fine with other games that use OpenGL and have change resolution support. Works fine with Quake 2 and Quake 3, for instance.

Now Quake 2, practically, does the following. It links run-time (LoadLibrary/GetProcAddress) to all functions in the OpenGL library that it uses. It executes all the cleanup calls above, then unloads the OpenGL32.dll library. Then it reloads the library and executes all the setup calls above.

Is that the only "right way" of doing it? That would be unfavorable, since I have a pretty big and nasty OpenGL app here that links statically to OpenGL32.dll. It would be a big mess to make OpenGL32.dll load dynamically here. Or can there be any other reason for that behavior? Microsoft's GDI docs say that SetPixelFormat can only be called on a window once after the window has been created; however, I destroy the old window and create a new one here, so that should not be the problem.

Pa3PyX
03-24-2003, 11:23 AM
Nevermind, figured it out. Was nothing but my own crook-handedness. First, I was forgetting to NULL the function pointers remaining from the previous OpenGL instance's wglGetProcAddress (which may no longer be valid if you choose a different PFD); secondly, I was using palettized textures but forgetting to re-upload the shared texture palette after mode change.

[This message has been edited by Pa3PyX (edited 03-24-2003).]