summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/win_glimp.c149
-rw-r--r--src/win_glimp.h5
-rw-r--r--src/win_wgl.c107
-rw-r--r--src/win_wgl.h37
4 files changed, 171 insertions, 127 deletions
diff --git a/src/win_glimp.c b/src/win_glimp.c
index 7df65a8..d7c2069 100644
--- a/src/win_glimp.c
+++ b/src/win_glimp.c
@@ -66,6 +66,9 @@ void VID_Shutdown( void ) {
if( gl_swapinterval ) {
gl_swapinterval->changed = NULL;
}
+ if( gl_drawbuffer ) {
+ gl_drawbuffer->changed = NULL;
+ }
memset( &glw, 0, sizeof( glw ) );
}
@@ -92,84 +95,101 @@ static qboolean InitGL( void ) {
0, 0, 0 // layer masks ignored
};
int pixelformat;
- const char *renderer;
+ const char *what;
// figure out if we're running on a minidriver or not
if( !Q_stristr( gl_driver->string, "opengl32" ) ) {
Com_Printf( "...running a minidriver: %s\n", gl_driver->string );
glw.minidriver = qtrue;
+ } else {
+ glw.minidriver = qfalse;
}
// load OpenGL library
- Com_DPrintf( "...initializing WGL: " );
if( !WGL_Init( gl_driver->string ) ) {
+ what = "WGL_Init";
goto fail1;
}
- Com_DPrintf( "ok\n" );
- Com_DPrintf( "...setting pixel format: " );
+ // set pixel format
if( glw.minidriver ) {
+ // check if certain entry points are present if using a minidriver
+ if( !qwglChoosePixelFormat || !qwglSetPixelFormat ||
+ !qwglDescribePixelFormat || !qwglSwapBuffers )
+ {
+ Com_EPrintf( "Required MCD entry points are missing\n" );
+ goto fail2;
+ }
+
if ( ( pixelformat = qwglChoosePixelFormat( win.dc, &pfd ) ) == 0 ) {
+ what = "wglChoosePixelFormat";
goto fail1;
}
+
if( qwglSetPixelFormat( win.dc, pixelformat, &pfd ) == FALSE ) {
+ what = "wglSetPixelFormat";
goto fail1;
}
+
qwglDescribePixelFormat( win.dc, pixelformat, sizeof( pfd ), &pfd );
} else {
if( ( pixelformat = ChoosePixelFormat( win.dc, &pfd ) ) == 0 ) {
+ what = "ChoosePixelFormat";
goto fail1;
}
+
if( SetPixelFormat( win.dc, pixelformat, &pfd ) == FALSE ) {
+ what = "SetPixelFormat";
goto fail1;
}
+
DescribePixelFormat( win.dc, pixelformat, sizeof( pfd ), &pfd );
}
- Com_DPrintf( "ok\n" );
+
+ // check for software emulation
+ if( pfd.dwFlags & PFD_GENERIC_FORMAT ) {
+ if( !gl_allow_software->integer ) {
+ Com_EPrintf( "No hardware OpenGL acceleration detected\n" );
+ goto fail2;
+ }
+ Com_WPrintf( "...using software emulation\n" );
+ } else if( pfd.dwFlags & PFD_GENERIC_ACCELERATED ) {
+ Com_DPrintf( "...MCD acceleration found\n" );
+ win.flags |= QVF_ACCELERATED;
+ } else {
+ Com_DPrintf( "...ICD acceleration found\n" );
+ win.flags |= QVF_ACCELERATED;
+ }
// startup the OpenGL subsystem by creating a context and making it current
- Com_DPrintf( "...creating OpenGL context: " );
if( ( glw.hGLRC = qwglCreateContext( win.dc ) ) == NULL ) {
+ what = "wglCreateContext";
goto fail1;
}
- Com_DPrintf( "ok\n" );
- Com_DPrintf( "...making context current: " );
if( !qwglMakeCurrent( win.dc, glw.hGLRC ) ) {
+ what = "wglMakeCurrent";
goto fail1;
}
- Com_DPrintf( "ok\n" );
-
- renderer = ( const char * )qglGetString( GL_RENDERER );
-
- if( pfd.dwFlags & PFD_GENERIC_ACCELERATED ) {
- win.flags |= QVF_ACCELERATED;
- } else if( !renderer || !renderer[0] || !Q_stricmp( renderer, "gdi generic" ) ) {
- Com_EPrintf( "No hardware OpenGL acceleration detected.\n" );
- if( !gl_allow_software->integer ) {
- goto fail2;
- }
- }
// print out PFD specifics
- Com_Printf( "GL_VENDOR: %s\n", qglGetString( GL_VENDOR ) );
- Com_Printf( "GL_RENDERER: %s\n", renderer );
- Com_Printf( "GL_PFD: color(%d-bits: %d,%d,%d,%d) Z(%d-bit) stencil(%d-bit)\n",
+ Com_DPrintf( "GL_VENDOR: %s\n", qwglGetString( GL_VENDOR ) );
+ Com_DPrintf( "GL_RENDERER: %s\n", qwglGetString( GL_RENDERER ) );
+ Com_DPrintf( "GL_PFD: color(%d-bits: %d,%d,%d,%d) Z(%d-bit) stencil(%d-bit)\n",
pfd.cColorBits, pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits,
pfd.cAlphaBits, pfd.cDepthBits, pfd.cStencilBits );
return qtrue;
fail1:
- Com_DPrintf( "failed with error %#lx\n", GetLastError() );
-fail2:
+ Com_EPrintf( "%s failed with error %#lx\n", what, GetLastError() );
if( glw.hGLRC && qwglDeleteContext ) {
qwglDeleteContext( glw.hGLRC );
glw.hGLRC = NULL;
}
+fail2:
WGL_Shutdown();
-
return qfalse;
}
@@ -179,6 +199,19 @@ static void gl_swapinterval_changed( cvar_t *self ) {
}
}
+static void gl_drawbuffer_changed( cvar_t *self ) {
+ if( !Q_stricmp( self->string, "GL_FRONT" ) ) {
+ glw.drawbuffer = GL_FRONT;
+ } else if( !Q_stricmp( self->string, "GL_BACK" ) ) {
+ glw.drawbuffer = GL_BACK;
+ } else {
+ Cvar_Reset( self );
+ glw.drawbuffer = GL_BACK;
+ }
+
+ qwglDrawBuffer( glw.drawbuffer );
+}
+
/*
GLimp_Init
@@ -188,45 +221,54 @@ doing the wgl interface stuff.
*/
qboolean VID_Init( void ) {
const char *extensions;
+ unsigned mask;
- gl_driver = Cvar_Get( "gl_driver", "opengl32", CVAR_ARCHIVE|CVAR_REFRESH );
+ gl_driver = Cvar_Get( "gl_driver", DEFAULT_OPENGL_DRIVER, CVAR_ARCHIVE|CVAR_REFRESH );
gl_drawbuffer = Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 );
gl_swapinterval = Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE );
gl_allow_software = Cvar_Get( "gl_allow_software", "0", 0 );
- // create the window
- Win_Init();
+ while( 1 ) {
+ // create the window
+ Win_Init();
+
+ // initialize OpenGL context
+ if( InitGL() ) {
+ break;
+ }
+
+ // it failed, clean up
+ Win_Shutdown();
- // initialize OpenGL context
- if( !InitGL() ) {
+ // see if this was a minidriver
if( !glw.minidriver ) {
- goto fail;
+ return qfalse;
}
+
+ // attempt to recover
Com_Printf( "...attempting to load opengl32\n" );
- Cvar_Set( "gl_driver","opengl32" );
- if( !InitGL() ) {
- goto fail;
- }
+ Cvar_Set( "gl_driver", "opengl32" );
}
// initialize WGL extensions
- extensions = ( const char * )qglGetString( GL_EXTENSIONS );
- if( extensions && strstr( extensions, "WGL_EXT_swap_control" ) ) {
+ extensions = ( const char * )qwglGetString( GL_EXTENSIONS );
+ mask = WGL_ParseExtensionString( extensions );
+
+ if( mask & QWGL_EXT_swap_control ) {
Com_Printf( "...enabling WGL_EXT_swap_control\n" );
- qwglSwapIntervalEXT = ( PFNWGLSWAPINTERWALEXTPROC )qwglGetProcAddress( "wglSwapIntervalEXT" );
+ WGL_InitExtensions( QWGL_EXT_swap_control );
gl_swapinterval->changed = gl_swapinterval_changed;
gl_swapinterval_changed( gl_swapinterval );
} else {
Com_Printf( "WGL_EXT_swap_control not found\n" );
}
+ gl_drawbuffer->changed = gl_drawbuffer_changed;
+ gl_drawbuffer_changed( gl_drawbuffer );
+
VID_SetMode();
return qtrue;
-
-fail:
- Win_Shutdown();
- return qfalse;
}
void VID_VideoWait( void ) {
@@ -247,11 +289,26 @@ as yet to be determined. Probably better not to make this a GLimp
function and instead do a call to GLimp_SwapBuffers.
*/
void VID_EndFrame( void ) {
- if( !qwglSwapBuffers( win.dc ) ) {
- int error = GetLastError();
+ BOOL ret;
+
+ // don't flip if drawing to front buffer
+ if( glw.drawbuffer == GL_FRONT ) {
+ return;
+ }
+
+ if( glw.minidriver ) {
+ ret = qwglSwapBuffers( win.dc );
+ } else {
+ ret = SwapBuffers( win.dc );
+ }
+
+ if( !ret ) {
+ DWORD error = GetLastError();
+ // this happens sometimes when the window is iconified
if( !IsIconic( win.wnd ) ) {
- Com_Error( ERR_FATAL, "wglSwapBuffers failed with error %#x", error );
+ Com_Error( ERR_FATAL, "%s failed with error %#lx",
+ glw.minidriver ? "wglSwapBuffers" : "SwapBuffers", error );
}
}
}
diff --git a/src/win_glimp.h b/src/win_glimp.h
index c82cb18..34f363d 100644
--- a/src/win_glimp.h
+++ b/src/win_glimp.h
@@ -26,9 +26,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <GL/glu.h>
typedef struct {
- HGLRC hGLRC; // handle to GL rendering context
+ HGLRC hGLRC; // handle to GL rendering context
HINSTANCE hinstOpenGL; // handle to GL library
- qboolean minidriver;
+ qboolean minidriver;
+ GLenum drawbuffer;
} glwstate_t;
extern glwstate_t glw;
diff --git a/src/win_wgl.c b/src/win_wgl.c
index 410199d..f165350 100644
--- a/src/win_wgl.c
+++ b/src/win_wgl.c
@@ -21,26 +21,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "win_glimp.h"
#include "win_wgl.h"
-//void ( APIENTRY * qglDrawBuffer )(GLenum mode);
-const GLubyte * ( APIENTRY * qglGetString )(GLenum name);
+void ( APIENTRY * qwglDrawBuffer )(GLenum mode);
+const GLubyte * ( APIENTRY * qwglGetString )(GLenum name);
int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *);
-int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
-//int ( WINAPI * qwglGetPixelFormat)(HDC);
-BOOL ( WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
-BOOL ( WINAPI * qwglSwapBuffers)(HDC);
+int ( WINAPI * qwglDescribePixelFormat )(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
+BOOL ( WINAPI * qwglSetPixelFormat )(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
+BOOL ( WINAPI * qwglSwapBuffers )(HDC);
-//BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT);
-HGLRC ( WINAPI * qwglCreateContext)(HDC);
-BOOL ( WINAPI * qwglDeleteContext)(HGLRC);
-//HGLRC ( WINAPI * qwglGetCurrentContext)(VOID);
-//HDC ( WINAPI * qwglGetCurrentDC)(VOID);
-PROC ( WINAPI * qwglGetProcAddress)(LPCSTR);
-BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC);
+HGLRC ( WINAPI * qwglCreateContext )(HDC);
+BOOL ( WINAPI * qwglDeleteContext )(HGLRC);
+PROC ( WINAPI * qwglGetProcAddress )(LPCSTR);
+BOOL ( WINAPI * qwglMakeCurrent )(HDC, HGLRC);
-BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval );
-//BOOL ( WINAPI * qwglGetDeviceGammaRampEXT)( unsigned char *, unsigned char *, unsigned char * );
-//BOOL ( WINAPI * qwglSetDeviceGammaRampEXT)( const unsigned char *, const unsigned char *, const unsigned char * );
+BOOL ( WINAPI * qwglSwapIntervalEXT )(int interval);
void WGL_Shutdown( void ) {
if( glw.hinstOpenGL ) {
@@ -48,73 +42,70 @@ void WGL_Shutdown( void ) {
glw.hinstOpenGL = NULL;
}
- //qglDrawBuffer = NULL;
- qglGetString = NULL;
+ qwglDrawBuffer = NULL;
+ qwglGetString = NULL;
qwglChoosePixelFormat = NULL;
qwglDescribePixelFormat = NULL;
- //qwglGetPixelFormat = NULL;
qwglSetPixelFormat = NULL;
qwglSwapBuffers = NULL;
- //qwglCopyContext = NULL;
qwglCreateContext = NULL;
qwglDeleteContext = NULL;
- //qwglGetCurrentContext = NULL;
- //qwglGetCurrentDC = NULL;
qwglGetProcAddress = NULL;
qwglMakeCurrent = NULL;
- qwglSwapIntervalEXT = NULL;
- //qwglGetDeviceGammaRampEXT = NULL;
- //qwglSetDeviceGammaRampEXT = NULL;
+ WGL_ShutdownExtensions( ~0 );
}
-
-#define GPA( x ) do { \
- q ## x = ( void * )GetProcAddress( glw.hinstOpenGL, #x ); \
- if( !q ## x ) { \
- Com_DPrintf( " %s ", #x ); \
- return qfalse; \
- } \
- } while( 0 )
+#define GPA( x ) ( void * )GetProcAddress( glw.hinstOpenGL, x );
qboolean WGL_Init( const char *dllname ) {
if( ( glw.hinstOpenGL = LoadLibrary( dllname ) ) == NULL ) {
return qfalse;
}
- //GPA( glDrawBuffer );
- GPA( glGetString );
-
- //GPA( wglCopyContext );
- GPA( wglCreateContext );
- //GPA( wglCreateLayerContext );
- GPA( wglDeleteContext );
- //GPA( wglDescribeLayerPlane );
- //GPA( wglGetCurrentContext );
- //GPA( wglGetCurrentDC );
- //GPA( wglGetLayerPaletteEntries );
- GPA( wglGetProcAddress );
- GPA( wglMakeCurrent );
- //GPA( wglRealizeLayerPalette );
- //GPA( wglSetLayerPaletteEntries );
- //GPA( wglShareLists );
- //GPA( wglSwapLayerBuffers );
+ qwglDrawBuffer = GPA( "glDrawBuffer" );
+ qwglGetString = GPA( "glGetString" );
- GPA( wglChoosePixelFormat );
- GPA( wglDescribePixelFormat );
- //GPA( wglGetPixelFormat );
- GPA( wglSetPixelFormat );
- GPA( wglSwapBuffers );
+ qwglChoosePixelFormat = GPA( "wglChoosePixelFormat" );
+ qwglDescribePixelFormat = GPA( "wglDescribePixelFormat" );
+ qwglSetPixelFormat = GPA( "wglSetPixelFormat" );
+ qwglSwapBuffers = GPA( "wglSwapBuffers" );
- qwglSwapIntervalEXT = NULL;
- //qwglGetDeviceGammaRampEXT = NULL;
- //qwglSetDeviceGammaRampEXT = NULL;
+ qwglCreateContext = GPA( "wglCreateContext" );
+ qwglDeleteContext = GPA( "wglDeleteContext" );
+ qwglGetProcAddress = GPA( "wglGetProcAddress" );
+ qwglMakeCurrent = GPA( "wglMakeCurrent" );
return qtrue;
}
+#undef GPA
+
+void WGL_ShutdownExtensions( unsigned mask ) {
+ if( mask & QWGL_EXT_swap_control ) {
+ qwglSwapIntervalEXT = NULL;
+ }
+}
+
+#define GPA( x ) ( void * )qwglGetProcAddress( x )
+
+void WGL_InitExtensions( unsigned mask ) {
+ if( mask & QWGL_EXT_swap_control ) {
+ qwglSwapIntervalEXT = GPA( "wglSwapIntervalEXT" );
+ }
+}
#undef GPA
+unsigned WGL_ParseExtensionString( const char *s ) {
+ // must match defines in win_wgl.h!
+ static const char *const extnames[] = {
+ "WGL_EXT_swap_control",
+ NULL
+ };
+
+ return Com_ParseExtensionString( s, extnames );
+}
+
diff --git a/src/win_wgl.h b/src/win_wgl.h
index b69f8be..dc639d9 100644
--- a/src/win_wgl.h
+++ b/src/win_wgl.h
@@ -22,31 +22,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// win_wgl.h
//
+#define QWGL_EXT_swap_control (1<<0)
+
qboolean WGL_Init( const char *dllname );
void WGL_Shutdown( void );
-void *WGL_GetProcAddress( const char *symbol );
-
-//extern void ( APIENTRY * qglDrawBuffer )(GLenum mode);
-extern const GLubyte * ( APIENTRY * qglGetString )(GLenum name);
-
-extern int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *);
-extern int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
-//extern int ( WINAPI * qwglGetPixelFormat)(HDC);
-extern BOOL ( WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
-extern BOOL ( WINAPI * qwglSwapBuffers)(HDC);
+void WGL_InitExtensions( unsigned mask );
+void WGL_ShutdownExtensions( unsigned mask );
+unsigned WGL_ParseExtensionString( const char *s );
-//extern BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT);
-extern HGLRC ( WINAPI * qwglCreateContext)(HDC);
-extern BOOL ( WINAPI * qwglDeleteContext)(HGLRC);
-//extern HGLRC ( WINAPI * qwglGetCurrentContext)(VOID);
-//extern HDC ( WINAPI * qwglGetCurrentDC)(VOID);
-extern PROC ( WINAPI * qwglGetProcAddress)(LPCSTR);
-extern BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC);
+extern void ( APIENTRY * qwglDrawBuffer )(GLenum mode);
+extern const GLubyte * ( APIENTRY * qwglGetString )(GLenum name);
-typedef BOOL ( WINAPI * PFNWGLSWAPINTERWALEXTPROC )( int );
-extern BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval );
+extern int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *);
+extern int ( WINAPI * qwglDescribePixelFormat ) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
+extern BOOL ( WINAPI * qwglSetPixelFormat )(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
+extern BOOL ( WINAPI * qwglSwapBuffers )(HDC);
-//extern BOOL ( WINAPI * qwglGetDeviceGammaRampEXT ) ( unsigned char *pRed, unsigned char *pGreen, unsigned char *pBlue );
-//extern BOOL ( WINAPI * qwglSetDeviceGammaRampEXT ) ( const unsigned char *pRed, const unsigned char *pGreen, const unsigned char *pBlue );
+extern HGLRC ( WINAPI * qwglCreateContext )(HDC);
+extern BOOL ( WINAPI * qwglDeleteContext )(HGLRC);
+extern PROC ( WINAPI * qwglGetProcAddress )(LPCSTR);
+extern BOOL ( WINAPI * qwglMakeCurrent )(HDC, HGLRC);
+extern BOOL ( WINAPI * qwglSwapIntervalEXT )(int interval);