diff --git a/code/renderercommon/qgl.h b/code/renderercommon/qgl.h index d490f3ff..29fee3e4 100644 --- a/code/renderercommon/qgl.h +++ b/code/renderercommon/qgl.h @@ -305,4 +305,7 @@ QGL_ARB_vertex_array_object_PROCS; QGL_EXT_direct_state_access_PROCS; #undef GLE +extern int qglMajorVersion, qglMinorVersion; +#define QGL_VERSION_ATLEAST( major, minor ) ( qglMajorVersion > major || ( qglMajorVersion == major && qglMinorVersion >= minor ) ) + #endif diff --git a/code/renderergl1/tr_init.c b/code/renderergl1/tr_init.c index 11278df7..62b590e2 100644 --- a/code/renderergl1/tr_init.c +++ b/code/renderergl1/tr_init.c @@ -920,7 +920,21 @@ void GfxInfo_f( void ) ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string ); ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string ); ri.Printf( PRINT_ALL, "GL_EXTENSIONS: " ); - R_PrintLongString( glConfig.extensions_string ); + if ( qglGetStringi ) + { + GLint numExtensions; + int i; + + qglGetIntegerv( GL_NUM_EXTENSIONS, &numExtensions ); + for ( i = 0; i < numExtensions; i++ ) + { + ri.Printf( PRINT_ALL, "%s ", qglGetStringi( GL_EXTENSIONS, i ) ); + } + } + else + { + R_PrintLongString( glConfig.extensions_string ); + } ri.Printf( PRINT_ALL, "\n" ); ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize ); ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.numTextureUnits ); diff --git a/code/renderergl2/tr_extensions.c b/code/renderergl2/tr_extensions.c index e90f5189..59cfab53 100644 --- a/code/renderergl2/tr_extensions.c +++ b/code/renderergl2/tr_extensions.c @@ -34,7 +34,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA QGL_1_3_PROCS; QGL_1_5_PROCS; QGL_2_0_PROCS; -QGL_3_0_PROCS; QGL_ARB_framebuffer_object_PROCS; QGL_ARB_vertex_array_object_PROCS; QGL_EXT_direct_state_access_PROCS; @@ -48,13 +47,12 @@ void GLimp_InitExtraExtensions() qboolean q_gl_version_at_least_3_2; // Check OpenGL version - sscanf(glConfig.version_string, "%d.%d", &glRefConfig.openglMajorVersion, &glRefConfig.openglMinorVersion); - if (glRefConfig.openglMajorVersion < 2) + if ( !QGL_VERSION_ATLEAST( 2, 0 ) ) ri.Error(ERR_FATAL, "OpenGL 2.0 required!"); ri.Printf(PRINT_ALL, "...using OpenGL %s\n", glConfig.version_string); - q_gl_version_at_least_3_0 = (glRefConfig.openglMajorVersion >= 3); - q_gl_version_at_least_3_2 = (glRefConfig.openglMajorVersion > 3 || (glRefConfig.openglMajorVersion == 3 && glRefConfig.openglMinorVersion > 2)); + q_gl_version_at_least_3_0 = QGL_VERSION_ATLEAST( 3, 0 ); + q_gl_version_at_least_3_2 = QGL_VERSION_ATLEAST( 3, 2 ); // Check if we need Intel graphics specific fixes. glRefConfig.intelGraphics = qfalse; @@ -79,13 +77,6 @@ void GLimp_InitExtraExtensions() // OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader QGL_2_0_PROCS; - // OpenGL 3.0 - no matching extension - // QGL_*_PROCS becomes several functions, do not remove {} - if (q_gl_version_at_least_3_0) - { - QGL_3_0_PROCS; - } - // OpenGL 3.0 - GL_ARB_framebuffer_object extension = "GL_ARB_framebuffer_object"; glRefConfig.framebufferObject = qfalse; diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index 212cacb1..ea315e66 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -1031,15 +1031,15 @@ void GfxInfo_f( void ) ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string ); ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string ); ri.Printf( PRINT_ALL, "GL_EXTENSIONS: " ); - if (glRefConfig.openglMajorVersion >= 3) + if ( qglGetStringi ) { GLint numExtensions; int i; - qglGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); - for (i = 0; i < numExtensions; i++) + qglGetIntegerv( GL_NUM_EXTENSIONS, &numExtensions ); + for ( i = 0; i < numExtensions; i++ ) { - ri.Printf(PRINT_ALL, "%s ", qglGetStringi(GL_EXTENSIONS, i)); + ri.Printf( PRINT_ALL, "%s ", qglGetStringi( GL_EXTENSIONS, i ) ); } } else diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 4926149f..f5f4b79e 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1336,9 +1336,6 @@ typedef enum { // We can't change glConfig_t without breaking DLL/vms compatibility, so // store extensions we have here. typedef struct { - int openglMajorVersion; - int openglMinorVersion; - qboolean intelGraphics; qboolean occlusionQuery; diff --git a/code/sdl/sdl_glimp.c b/code/sdl/sdl_glimp.c index c81d38b0..b52da430 100644 --- a/code/sdl/sdl_glimp.c +++ b/code/sdl/sdl_glimp.c @@ -53,6 +53,8 @@ cvar_t *r_allowResize; // make window resizable cvar_t *r_centerWindow; cvar_t *r_sdlDriver; +int qglMajorVersion, qglMinorVersion; + void (APIENTRYP qglActiveTextureARB) (GLenum texture); void (APIENTRYP qglClientActiveTextureARB) (GLenum texture); void (APIENTRYP qglMultiTexCoord2fARB) (GLenum target, GLfloat s, GLfloat t); @@ -63,6 +65,7 @@ void (APIENTRYP qglUnlockArraysEXT) (void); #define GLE(ret, name, ...) name##proc * qgl##name; QGL_1_0_PROCS; QGL_1_1_PROCS; +QGL_3_0_PROCS; #undef GLE /* @@ -224,6 +227,7 @@ Get addresses for OpenGL functions. */ static qboolean GLimp_GetProcAddresses( void ) { qboolean success = qtrue; + const char *version; #ifdef __SDL_NOGETPROCADDR__ #define GLE( ret, name, ... ) qgl##name = gl#name; @@ -235,8 +239,32 @@ static qboolean GLimp_GetProcAddresses( void ) { } #endif - QGL_1_0_PROCS; - QGL_1_1_PROCS; + // OpenGL 1.0 + GLE(const GLubyte *, GetString, GLenum name) + + if ( !qglGetString ) { + Com_Error( ERR_FATAL, "glGetString is NULL" ); + } + + version = (const char *)qglGetString( GL_VERSION ); + + if ( !version ) { + Com_Error( ERR_FATAL, "GL_VERSION is NULL\n" ); + } + + sscanf( version, "%d.%d", &qglMajorVersion, &qglMinorVersion ); + + // require OpenGL 1.1 + if ( QGL_VERSION_ATLEAST( 1, 1 ) ) { + QGL_1_0_PROCS; + QGL_1_1_PROCS; + } else { + Com_Error( ERR_FATAL, "Unsupported OpenGL Version: %s\n", version ); + } + + if ( QGL_VERSION_ATLEAST( 3, 0 ) ) { + QGL_3_0_PROCS; + } #undef GLE @@ -253,8 +281,12 @@ Clear addresses for OpenGL functions. static void GLimp_ClearProcAddresses( void ) { #define GLE( ret, name, ... ) qgl##name = NULL; + qglMajorVersion = 0; + qglMinorVersion = 0; + QGL_1_0_PROCS; QGL_1_1_PROCS; + QGL_3_0_PROCS; #undef GLE } @@ -921,10 +953,37 @@ success: if (*glConfig.renderer_string && glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] == '\n') glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] = 0; Q_strncpyz( glConfig.version_string, (char *) qglGetString (GL_VERSION), sizeof( glConfig.version_string ) ); - if (qglGetString(GL_EXTENSIONS)) - Q_strncpyz( glConfig.extensions_string, (char *) qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) ); + + // manually create extension list if using OpenGL 3 + if ( qglGetStringi ) + { + int i, numExtensions, extensionLength, listLength; + const char *extension; + + qglGetIntegerv( GL_NUM_EXTENSIONS, &numExtensions ); + listLength = 0; + + for ( i = 0; i < numExtensions; i++ ) + { + extension = (char *) qglGetStringi( GL_EXTENSIONS, i ); + extensionLength = strlen( extension ); + + if ( ( listLength + extensionLength + 1 ) >= sizeof( glConfig.extensions_string ) ) + break; + + if ( i > 0 ) { + Q_strcat( glConfig.extensions_string, sizeof( glConfig.extensions_string ), " " ); + listLength++; + } + + Q_strcat( glConfig.extensions_string, sizeof( glConfig.extensions_string ), extension ); + listLength += extensionLength; + } + } else - Q_strncpyz( glConfig.extensions_string, "Not available (core context, fixme)", sizeof( glConfig.extensions_string ) ); + { + Q_strncpyz( glConfig.extensions_string, (char *) qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) ); + } // initialize extensions GLimp_InitExtensions( );