Fixed setting OpenGL mode multiple times on Windows
authorSam Lantinga <slouken@libsdl.org>
Sun, 19 May 2002 22:27:42 +0000
changeset 373 c638fde8a824
parent 372 7e9e5a51c5f9
child 374 3fc4e71f7714
Fixed setting OpenGL mode multiple times on Windows
docs.html
src/video/wincommon/SDL_wingl.c
--- a/docs.html	Sun May 19 21:40:25 2002 +0000
+++ b/docs.html	Sun May 19 22:27:42 2002 +0000
@@ -16,6 +16,7 @@
 Major changes since SDL 1.0.0:
 </H2>
 <UL>
+	<LI> 1.2.5: Fixed setting OpenGL mode multiple times on Windows
 	<LI> 1.2.5: Added support for Qtopia on embedded systems (thanks David!)
 	<LI> 1.2.4: Added initial support for Atari (thanks Patrice!)
 	<LI> 1.2.4: Added support for building SDL for EPOC/SymbianOS 6.0
--- a/src/video/wincommon/SDL_wingl.c	Sun May 19 21:40:25 2002 +0000
+++ b/src/video/wincommon/SDL_wingl.c	Sun May 19 22:27:42 2002 +0000
@@ -36,11 +36,50 @@
 #define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
 #endif
 
+/* If setting the HDC fails, we may need to recreate the window (MSDN) */
+static int WIN_GL_ResetWindow(_THIS)
+{
+	int status = 0;
+	int can_reset = 1;
+
+	/* If we were passed a window, then we can't create a new one */
+	if ( SDL_windowid ) {
+		can_reset = 0;
+	}
+#ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */
+	if ( can_reset ) {
+		/* Save the existing window attributes */
+		LONG style;
+		RECT rect = { 0, 0, 0, 0 };
+		style = GetWindowLong(SDL_Window, GWL_STYLE);
+		GetWindowRect(SDL_Window, &rect);
+		DestroyWindow(SDL_Window);
+		SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
+		                          style,
+					  rect.left, rect.top,
+                                          (rect.right-rect.left)+1,
+                                          (rect.top-rect.bottom)+1,
+		                          NULL, NULL, SDL_Instance, NULL);
+		if ( SDL_Window ) {
+			this->SetCaption(this, this->wm_title, this->wm_icon);
+		} else {
+			SDL_SetError("Couldn't create window");
+			status = -1;
+		}
+	} else
+#endif /* !_WIN32_WCE */
+	{
+		SDL_SetError("Unable to reset window for OpenGL context");
+		status = -1;
+	}
+	return(status);
+}
 
 int WIN_GL_SetupWindow(_THIS)
 {
 	int retval;
 #ifdef HAVE_OPENGL
+	int i;
 	int pixel_format;
 
 	/* load the gl driver from a default path */
@@ -51,46 +90,57 @@
 		}
 	}
 
-	/* Get the window device context for our OpenGL drawing */
-	GL_hdc = GetDC(SDL_Window);
-	if ( GL_hdc == NULL ) {
-		SDL_SetError("Unable to get DC for SDL_Window");
-		return(-1);
-	}
+	for ( i=0; ; ++i ) {
+		/* Get the window device context for our OpenGL drawing */
+		GL_hdc = GetDC(SDL_Window);
+		if ( GL_hdc == NULL ) {
+			SDL_SetError("Unable to get DC for SDL_Window");
+			return(-1);
+		}
 
-	/* Set up the pixel format descriptor with our needed format */
-	memset(&GL_pfd, 0, sizeof(GL_pfd));
-	GL_pfd.nSize = sizeof(GL_pfd);
-	GL_pfd.nVersion = 1;
-	GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
-	if ( this->gl_config.double_buffer ) {
-		GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
-	}
-	GL_pfd.iPixelType = PFD_TYPE_RGBA;
-	GL_pfd.cColorBits = this->gl_config.buffer_size;
-	GL_pfd.cRedBits = this->gl_config.red_size;
-	GL_pfd.cGreenBits = this->gl_config.green_size;
-	GL_pfd.cBlueBits = this->gl_config.blue_size;
-	GL_pfd.cAlphaBits = this->gl_config.alpha_size;
-	GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
-	GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
-	GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
-	GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
-	GL_pfd.cAccumBits =
-		(GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
-		 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
-	GL_pfd.cDepthBits = this->gl_config.depth_size;
-	GL_pfd.cStencilBits = this->gl_config.stencil_size;
+		/* Set up the pixel format descriptor with our needed format */
+		memset(&GL_pfd, 0, sizeof(GL_pfd));
+		GL_pfd.nSize = sizeof(GL_pfd);
+		GL_pfd.nVersion = 1;
+		GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
+		if ( this->gl_config.double_buffer ) {
+			GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
+		}
+		GL_pfd.iPixelType = PFD_TYPE_RGBA;
+		GL_pfd.cColorBits = this->gl_config.buffer_size;
+		GL_pfd.cRedBits = this->gl_config.red_size;
+		GL_pfd.cGreenBits = this->gl_config.green_size;
+		GL_pfd.cBlueBits = this->gl_config.blue_size;
+		GL_pfd.cAlphaBits = this->gl_config.alpha_size;
+		GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
+		GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
+		GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
+		GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
+		GL_pfd.cAccumBits =
+			(GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
+			 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
+		GL_pfd.cDepthBits = this->gl_config.depth_size;
+		GL_pfd.cStencilBits = this->gl_config.stencil_size;
 
-	/* Choose and set the closest available pixel format */
-	pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
-	if ( !pixel_format ) {
-		SDL_SetError("No matching GL pixel format available");
-		return(-1);
-	}
-	if( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
-		SDL_SetError("Unable to set HDC pixel format");
-		return(-1);
+		/* Choose and set the closest available pixel format */
+		pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
+		if ( !pixel_format ) {
+			SDL_SetError("No matching GL pixel format available");
+			return(-1);
+		}
+		if( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
+			if ( i == 0 ) {
+				/* First time through, try resetting the window */
+				if ( WIN_GL_ResetWindow(this) < 0 ) {
+					return(-1);
+				}
+				continue;
+			}
+			SDL_SetError("Unable to set HDC pixel format");
+			return(-1);
+		}
+		/* We either succeeded or failed by this point */
+		break;
 	}
 	DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);