From 4cd544217c277156cd04b18bdb34dc7ef5358333 Mon Sep 17 00:00:00 2001 From: myT Date: Fri, 3 Nov 2017 19:33:54 +0100 Subject: [PATCH] platform layer GL interface cleanup renamed and documented the core GLimp functions moved the memset calls out of GLimp_Shutdown dealing with anisotropic filtering properly and fixed the cvar's range and help platform extension loading is done through Sys_GL_LoadExtensions throwing fatal errors is done by the renderer exclusively removed QGL_Init and QGL_Shutdown cleaned up glconfig_t filling up the unused glConfig fields in the renderer for old mods --- code/linux/linux_local.h | 2 + code/linux/linux_qgl.c | 76 ++++---- code/linux/sdl_glimp.cpp | 52 +---- code/qcommon/tr_types.h | 54 +++--- code/renderer/qgl.h | 125 ++++-------- code/renderer/qgl_linked.h | 357 ----------------------------------- code/renderer/tr_backend.cpp | 2 +- code/renderer/tr_gl2.cpp | 2 +- code/renderer/tr_help.h | 7 +- code/renderer/tr_image.cpp | 4 +- code/renderer/tr_init.cpp | 75 ++++++-- code/renderer/tr_local.h | 34 +++- code/win32/win_glimp.cpp | 100 +--------- code/win32/win_local.h | 24 ++- code/win32/win_qgl.c | 125 ++++++------ 15 files changed, 289 insertions(+), 750 deletions(-) delete mode 100644 code/renderer/qgl_linked.h diff --git a/code/linux/linux_local.h b/code/linux/linux_local.h index 55e6def..53e8bf3 100644 --- a/code/linux/linux_local.h +++ b/code/linux/linux_local.h @@ -35,6 +35,8 @@ void Lin_QueEvent( int time, sysEventType_t type, int value, int value2, int pt void Lin_ConsoleInputInit(); void Lin_ConsoleInputShutdown(); const char* Lin_ConsoleInput(); +qbool Lin_LoadGL(); +void Lin_UnloadGL(); qbool tty_Enabled(); void tty_Hide(); diff --git a/code/linux/linux_qgl.c b/code/linux/linux_qgl.c index 459a945..bdd052b 100644 --- a/code/linux/linux_qgl.c +++ b/code/linux/linux_qgl.c @@ -738,12 +738,7 @@ static void ( APIENTRY * dllVertexPointer )(GLint size, GLenum type, GLsizei str static void ( APIENTRY * dllViewport )(GLint x, GLint y, GLsizei width, GLsizei height); -/* -** QGL_Shutdown -** -** Unloads the specified DLL then nulls out all the proc pointers. -*/ -void QGL_Shutdown( void ) +void Lin_UnloadGL() { qglAccum = NULL; qglAlphaFunc = NULL; @@ -1092,32 +1087,12 @@ void QGL_Shutdown( void ) qglXSwapIntervalEXT = NULL; qglXSwapIntervalMESA = NULL; qglXSwapIntervalSGI = NULL; -} // QGL_Shutdown +} -/* -** GPA -** -** This'll setup a wrapper around calling GetProcAddress for all our -** GL to QGL bindings, hopefully making them less cumbersome to setup -** -*/ - #define GPA( a ) SDL_GL_GetProcAddress( a ) - -/* -** QGL_Init -** -** This is responsible for binding our qgl function pointers to -** the appropriate GL stuff. In Windows this means doing a -** LoadLibrary and a bunch of calls to GetProcAddress. On other -** operating systems we need to do the right thing, whatever that -** might be. -** -*/ - -qbool QGL_Init( const char * ) +qbool Lin_LoadGL() { qglXGetProcAddress = (void* (*)( const char *symbol ))GPA( "glXGetProcAddress" ); qglAccum = dllAccum =(void (*)(GLenum, GLfloat))GPA( "glAccum" ); @@ -1485,8 +1460,19 @@ qbool QGL_Init( const char * ) } -#define QGL_EXT(fn, type) q##fn = (type)GPA( #fn ); \ - if (!q##fn) Com_Error( ERR_FATAL, "QGL_EXT: "#fn" not found" ); +// +// Linux-specific OpenGL extensions +// + +static qbool LIN_InitPlatformGL( const char** ) +{ + return qtrue; +} + + +// +// OpenGL 2 +// PFNGLCREATESHADERPROC qglCreateShader; PFNGLSHADERSOURCEPROC qglShaderSource; @@ -1533,13 +1519,13 @@ PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC qglGetFramebufferAttachmentParamete PFNGLGENERATEMIPMAPPROC qglGenerateMipmap; PFNGLBLITFRAMEBUFFERPROC qglBlitFramebuffer; +#define QGL_EXT(fn, type) q##fn = (type)GPA( #fn ); \ + do { if (!q##fn) { *extension = #fn; return qfalse; } } while(0) -qbool GLW_InitGL2() +static qbool LIN_InitGL2( const char** extension ) { if (atof((const char*)qglGetString(GL_VERSION)) < 2.0f) - { return qfalse; - } QGL_EXT( glCreateShader, PFNGLCREATESHADERPROC ); QGL_EXT( glShaderSource, PFNGLSHADERSOURCEPROC ); @@ -1589,11 +1575,13 @@ qbool GLW_InitGL2() return qtrue; } - #undef QGL_EXT -#define QGL_EXT(fn, type) q##fn = (type)GPA( #fn ) +// +// OpenGL 3+ +// + typedef void ( APIENTRY * PFNGLTEXIMAGE2DMULTISAMPLE )(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean); // 3.0 @@ -1602,19 +1590,29 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC qglRenderbufferStorageMultisample; // 3.2 PFNGLTEXIMAGE2DMULTISAMPLE qglTexImage2DMultisample; +#define QGL_EXT(fn, type) q##fn = (type)GPA( #fn ) -qbool GLW_InitGL3() +static void LIN_InitGL3() { if (atof((const char*)qglGetString(GL_VERSION)) < 3.0f) - { - return qfalse; - } + return; // 3.0 QGL_EXT( glRenderbufferStorageMultisample, PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC ); // 3.2 QGL_EXT( glTexImage2DMultisample, PFNGLTEXIMAGE2DMULTISAMPLE ); +} + +#undef QGL_EXT + + +qbool Sys_GL_LoadExtensions( const char** extension ) +{ + if (!LIN_InitPlatformGL(extension) || !LIN_InitGL2(extension)) + return qfalse; + + LIN_InitGL3(); return qtrue; } diff --git a/code/linux/sdl_glimp.cpp b/code/linux/sdl_glimp.cpp index 86b1fc6..1c39b1f 100644 --- a/code/linux/sdl_glimp.cpp +++ b/code/linux/sdl_glimp.cpp @@ -137,32 +137,7 @@ static void sdl_PrintMonitorList() } -// @TODO: this should be handled by the renderer, not the platform layer! -static void GLW_InitExtensions() -{ - ri.Printf(PRINT_ALL, "Initializing OpenGL extensions\n"); - - int maxAnisotropy = 0; - if (strstr(glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic")) { - if (r_ext_max_anisotropy->integer > 1) { - qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); - if (maxAnisotropy <= 0) { - ri.Printf(PRINT_DEVELOPER, "...GL_EXT_texture_filter_anisotropic not properly supported!\n"); - maxAnisotropy = 0; - } else { - ri.Printf(PRINT_DEVELOPER, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", maxAnisotropy); - } - } else { - ri.Printf(PRINT_DEVELOPER, "...ignoring GL_EXT_texture_filter_anisotropic\n"); - } - } else { - ri.Printf(PRINT_DEVELOPER, "...GL_EXT_texture_filter_anisotropic not found\n"); - } - Cvar_Set("r_ext_max_anisotropy", va("%i", maxAnisotropy)); -} - - -void GLimp_Init() +void Sys_GL_Init() { if (glimp.window != NULL) return; @@ -220,26 +195,12 @@ void GLimp_Init() if (SDL_GL_MakeCurrent(glimp.window, glimp.glContext) < 0) ri.Error(ERR_FATAL, "GLimp_Init - SDL_GL_MakeCurrent failed: %s\n", SDL_GetError()); - if (!QGL_Init(NULL)) + if (!Lin_LoadGL()) ri.Error(ERR_FATAL, "GLimp_Init - failed to initialize core OpenGL\n"); - - GLW_InitExtensions(); - - if (!GLW_InitGL2()) - ri.Error(ERR_FATAL, "GLimp_Init - could not find or initialize a suitable OpenGL 2+ subsystem\n"); - - GLW_InitGL3(); - - if (!QGL_InitGL2()) - ri.Error(ERR_FATAL, "GLimp_Init - could not initialize OpenGL 2 objects\n"); - - SDL_GL_SetSwapInterval(r_swapInterval->integer); - - ri.Printf(PRINT_ALL, "Loaded OpenGL %s\n", (const char*)qglGetString(GL_VERSION)); } -void GLimp_Shutdown() +void Sys_GL_Shutdown() { if (glimp.glContext != NULL) { SDL_GL_DeleteContext(glimp.glContext); @@ -252,14 +213,11 @@ void GLimp_Shutdown() } SDL_GL_UnloadLibrary(); - QGL_Shutdown(); - - memset(&glConfig, 0, sizeof(glConfig)); - memset(&glState, 0, sizeof(glState)); + Lin_UnloadGL(); } -void GLimp_EndFrame() +void Sys_GL_EndFrame() { if (r_swapInterval->modified) { r_swapInterval->modified = qfalse; diff --git a/code/qcommon/tr_types.h b/code/qcommon/tr_types.h index 0946ee5..c6324ea 100644 --- a/code/qcommon/tr_types.h +++ b/code/qcommon/tr_types.h @@ -135,49 +135,57 @@ typedef enum { STEREO_RIGHT } stereoFrame_t; - /* -there are two "glconfig" types: this one is exposed to vm's, client, etc, -and is immutable because the layout has to match what cgame and ui expect +glconfig_t -the "real" one is correctly local to the renderer -*/ +Contains variables specific to the OpenGL configuration +being run right now. These are constant once the OpenGL +subsystem is initialized. -/* -** glconfig_t -** -** Contains variables specific to the OpenGL configuration -** being run right now. These are constant once the OpenGL -** subsystem is initialized. +This type is exposed to VMs and the client. It is immutable because +the layout has to match what the cgame and ui VMs expect. + +There is an equivalent to this that is local to the renderer. + +Fields prefixed with "unused_" are unused _by the engine_, +but might still be read by mods other than CPMA. */ typedef struct { + // filled by the renderer char renderer_string[MAX_STRING_CHARS]; char vendor_string[MAX_STRING_CHARS]; char version_string[MAX_STRING_CHARS]; char extensions_string[BIG_INFO_STRING]; - int unused1, unused2; + int unused_maxTextureSize; + int unused_maxActiveTextures; - int colorBits, depthBits, stencilBits; + // filled by the platform layer + int colorBits; // 32 + int depthBits; // 24 + int stencilBits; // 8 - int unused3, unused4; + int unused_driverType; // 0 for ICD + int unused_hardwareType; // 0 for generic - int unused10; // gamma + qbool unused_deviceSupportsGamma; // qtrue - int unused5, unused6; + int unused_textureCompression; // 0 for none + qbool unused_textureEnvAddAvailable; // qtrue - int vidWidth, vidHeight; - // aspect is the screen's physical width / height, which may be different + // windowAspect is the screen's physical width / height, which may be different // than scrWidth / scrHeight if the pixels are non-square // normal screens should be 4/3, but wide aspect monitors may be 16/9 + + // filled by the platform layer + int vidWidth, vidHeight; float windowAspect; - int unused7, unused8; - - qbool unused11; // stereo - - int unused9; + int unused_displayFrequency; // 0 + qbool unused_isFullscreen; // r_fullscreen->integer + qbool unused_stereoEnabled; // qfalse + qbool unused_smpActive; // qfalse } glconfig_t; diff --git a/code/renderer/qgl.h b/code/renderer/qgl.h index 9f41717..cd18624 100644 --- a/code/renderer/qgl.h +++ b/code/renderer/qgl.h @@ -19,57 +19,27 @@ along with Quake III Arena source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ -/* -** QGL.H -*/ +#pragma once -#ifndef __QGL_H__ -#define __QGL_H__ -#if defined( __LINT__ ) - -#include - -#elif defined( _WIN32 ) +#if defined( _WIN32 ) #include "../win32/windows.h" #include #include "../win32/glext.h" -#elif defined(MACOS_X) +#elif defined( __linux__ ) -#include -#include -#include -#ifndef GL_EXT_abgr -#include -#endif - -// This can be defined to use the CGLMacro.h support which avoids looking up -// the current context. -//#define USE_CGLMACROS - -#ifdef USE_CGLMACROS -#include "macosx_local.h" -#define cgl_ctx glw_state._cgl_ctx -#include -#endif - -#elif defined( __linux__ ) || defined(__FreeBSD__) - -#include -#include - -#elif defined( __sun ) #include #include #else -#include +#error "Unsupported platform" #endif + #ifndef APIENTRY #define APIENTRY #endif @@ -77,34 +47,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define WINAPI #endif -/////////////////////////////////////////////////////////////// extern "C" { -qbool QGL_Init( const char* dllname ); -void QGL_Shutdown(); - -// extensions will be function pointers on all platforms - -extern void ( APIENTRY * qglActiveTextureARB )( GLenum texture ); -extern void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture ); - -extern PFNGLLOCKARRAYSEXTPROC qglLockArraysEXT; -extern PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT; - - -// non-dlopening systems will just redefine qgl* to gl* -#if !defined( _WIN32 ) && !defined(MACOS_X) && !defined( __linux__ ) && !defined( __FreeBSD__ ) && !defined(__sun) // rb010123 - -#include "qgl_linked.h" - -#elif (defined(MACOS_X) && !defined(USE_SDL_VIDEO)) -// This includes #ifdefs for optional logging and GL error checking after every GL call as well as #defines to prevent incorrect usage of the non-'qgl' versions of the GL API. -#include "macosx_qgl.h" - -#else - -// windows systems use a function pointer for each call so we can load minidrivers +// +// OpenGL 1.X functions +// extern void ( APIENTRY * qglAccum )(GLenum op, GLfloat value); extern void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref); @@ -443,8 +391,23 @@ extern void ( APIENTRY * qglVertex4sv )(const GLshort *v); extern void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height); + +// +// mandatory (and really old) OpenGL extensions +// + +extern void (APIENTRY * qglActiveTextureARB)(GLenum texture); +extern void (APIENTRY * qglClientActiveTextureARB)(GLenum texture); +extern PFNGLLOCKARRAYSEXTPROC qglLockArraysEXT; +extern PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT; + + #if defined( _WIN32 ) +// +// Windows extensions +// + extern int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *); extern int ( WINAPI * qwglChoosePixelFormatARB )(HDC, const int*, const FLOAT*, UINT, int*, UINT*); extern int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); @@ -470,30 +433,22 @@ extern BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT); extern BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval ); -#endif // _WIN32 - -}; +#endif -#if ( (defined __linux__ ) || (defined __FreeBSD__ ) || (defined __sun) ) - -//GLX Functions -extern XVisualInfo * (*qglXChooseVisual)( Display *dpy, int screen, int *attribList ); -extern GLXContext (*qglXCreateContext)( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct ); -extern void (*qglXDestroyContext)( Display *dpy, GLXContext ctx ); -extern Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx); -extern void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask ); -extern void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable ); - -#endif // __linux__ || __FreeBSD__ || __sun // rb010123 +// Sys_GL_LoadExtensions rules: +// - OpenGL 2 extensions are mandatory +// - OpenGL 3+ extensions are optional +// - platform-specific extensions are not mandatory, +// but the implementation is free to return qfalse if one is missing +// - when returning qfalse, set *extension to point to the name of the missing extension +// the string should either be a string literal or returned by va() +qbool Sys_GL_LoadExtensions( const char** extension ); -#endif // _WIN32 && __linux__ - - -extern "C" { - -qbool GLW_InitGL2(); +// +// OpenGL 2.X functions +// extern PFNGLCREATESHADERPROC qglCreateShader; extern PFNGLSHADERSOURCEPROC qglShaderSource; @@ -540,14 +495,12 @@ extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC qglGetFramebufferAttachmentP extern PFNGLGENERATEMIPMAPPROC qglGenerateMipmap; extern PFNGLBLITFRAMEBUFFERPROC qglBlitFramebuffer; -qbool GLW_InitGL3(); + +// +// OpenGL 3+ functions +// extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC qglRenderbufferStorageMultisample; extern void (APIENTRY* qglTexImage2DMultisample)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean); }; - -qbool QGL_InitGL2(); - - -#endif diff --git a/code/renderer/qgl_linked.h b/code/renderer/qgl_linked.h deleted file mode 100644 index 3d11f4a..0000000 --- a/code/renderer/qgl_linked.h +++ /dev/null @@ -1,357 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -#define qglAccum glAccum -#define qglAlphaFunc glAlphaFunc -#define qglAreTexturesResident glAreTexturesResident -#define qglArrayElement glArrayElement -#define qglBegin glBegin -#define qglBindTexture glBindTexture -#define qglBitmap glBitmap -#define qglBlendFunc glBlendFunc -#define qglCallList glCallList -#define qglCallLists glCallLists -#define qglClear glClear -#define qglClearAccum glClearAccum -#define qglClearColor glClearColor -#define qglClearDepth glClearDepth -#define qglClearIndex glClearIndex -#define qglClearStencil glClearStencil -#define qglClipPlane glClipPlane -#define qglColor3b glColor3b -#define qglColor3bv glColor3bv -#define qglColor3d glColor3d -#define qglColor3dv glColor3dv -#define qglColor3f glColor3f -#define qglColor3fv glColor3fv -#define qglColor3i glColor3i -#define qglColor3iv glColor3iv -#define qglColor3s glColor3s -#define qglColor3sv glColor3sv -#define qglColor3ub glColor3ub -#define qglColor3ubv glColor3ubv -#define qglColor3ui glColor3ui -#define qglColor3uiv glColor3uiv -#define qglColor3us glColor3us -#define qglColor3usv glColor3usv -#define qglColor4b glColor4b -#define qglColor4bv glColor4bv -#define qglColor4d glColor4d -#define qglColor4dv glColor4dv -#define qglColor4f glColor4f -#define qglColor4fv glColor4fv -#define qglColor4i glColor4i -#define qglColor4iv glColor4iv -#define qglColor4s glColor4s -#define qglColor4sv glColor4sv -#define qglColor4ub glColor4ub -#define qglColor4ubv glColor4ubv -#define qglColor4ui glColor4ui -#define qglColor4uiv glColor4uiv -#define qglColor4us glColor4us -#define qglColor4usv glColor4usv -#define qglColorMask glColorMask -#define qglColorMaterial glColorMaterial -#define qglColorPointer glColorPointer -#define qglCopyPixels glCopyPixels -#define qglCopyTexImage1D glCopyTexImage1D -#define qglCopyTexImage2D glCopyTexImage2D -#define qglCopyTexSubImage1D glCopyTexSubImage1D -#define qglCopyTexSubImage2D glCopyTexSubImage2D -#define qglCullFace glCullFace -#define qglDeleteLists glDeleteLists -#define qglDeleteTextures glDeleteTextures -#define qglDepthFunc glDepthFunc -#define qglDepthMask glDepthMask -#define qglDepthRange glDepthRange -#define qglDisable glDisable -#define qglDisableClientState glDisableClientState -#define qglDrawArrays glDrawArrays -#define qglDrawBuffer glDrawBuffer -#define qglDrawElements glDrawElements -#define qglDrawPixels glDrawPixels -#define qglEdgeFlag glEdgeFlag -#define qglEdgeFlagPointer glEdgeFlagPointer -#define qglEdgeFlagv glEdgeFlagv -#define qglEnable glEnable -#define qglEnableClientState glEnableClientState -#define qglEnd glEnd -#define qglEndList glEndList -#define qglEvalCoord1d glEvalCoord1d -#define qglEvalCoord1dv glEvalCoord1dv -#define qglEvalCoord1f glEvalCoord1f -#define qglEvalCoord1fv glEvalCoord1fv -#define qglEvalCoord2d glEvalCoord2d -#define qglEvalCoord2dv glEvalCoord2dv -#define qglEvalCoord2f glEvalCoord2f -#define qglEvalCoord2fv glEvalCoord2fv -#define qglEvalMesh1 glEvalMesh1 -#define qglEvalMesh2 glEvalMesh2 -#define qglEvalPoint1 glEvalPoint1 -#define qglEvalPoint2 glEvalPoint2 -#define qglFeedbackBuffer glFeedbackBuffer -#define qglFinish glFinish -#define qglFlush glFlush -#define qglFogf glFogf -#define qglFogfv glFogfv -#define qglFogi glFogi -#define qglFogiv glFogiv -#define qglFrontFace glFrontFace -#define qglFrustum glFrustum -#define qglGenLists glGenLists -#define qglGenTextures glGenTextures -#define qglGetBooleanv glGetBooleanv -#define qglGetClipPlane glGetClipPlane -#define qglGetDoublev glGetDoublev -#define qglGetError glGetError -#define qglGetFloatv glGetFloatv -#define qglGetIntegerv glGetIntegerv -#define qglGetLightfv glGetLightfv -#define qglGetLightiv glGetLightiv -#define qglGetMapdv glGetMapdv -#define qglGetMapfv glGetMapfv -#define qglGetMapiv glGetMapiv -#define qglGetMaterialfv glGetMaterialfv -#define qglGetMaterialiv glGetMaterialiv -#define qglGetPixelMapfv glGetPixelMapfv -#define qglGetPixelMapuiv glGetPixelMapuiv -#define qglGetPixelMapusv glGetPixelMapusv -#define qglGetPointerv glGetPointerv -#define qglGetPolygonStipple glGetPolygonStipple -#define qglGetString glGetString -#define qglGetTexGendv glGetTexGendv -#define qglGetTexGenfv glGetTexGenfv -#define qglGetTexGeniv glGetTexGeniv -#define qglGetTexImage glGetTexImage -#define qglGetTexLevelParameterfv glGetTexLevelParameterfv -#define qglGetTexLevelParameteriv glGetTexLevelParameteriv -#define qglGetTexParameterfv glGetTexParameterfv -#define qglGetTexParameteriv glGetTexParameteriv -#define qglHint glHint -#define qglIndexMask glIndexMask -#define qglIndexPointer glIndexPointer -#define qglIndexd glIndexd -#define qglIndexdv glIndexdv -#define qglIndexf glIndexf -#define qglIndexfv glIndexfv -#define qglIndexi glIndexi -#define qglIndexiv glIndexiv -#define qglIndexs glIndexs -#define qglIndexsv glIndexsv -#define qglIndexub glIndexub -#define qglIndexubv glIndexubv -#define qglInitNames glInitNames -#define qglInterleavedArrays glInterleavedArrays -#define qglIsEnabled glIsEnabled -#define qglIsList glIsList -#define qglIsTexture glIsTexture -#define qglLightModelf glLightModelf -#define qglLightModelfv glLightModelfv -#define qglLightModeli glLightModeli -#define qglLightModeliv glLightModeliv -#define qglLightf glLightf -#define qglLightfv glLightfv -#define qglLighti glLighti -#define qglLightiv glLightiv -#define qglLineStipple glLineStipple -#define qglLineWidth glLineWidth -#define qglListBase glListBase -#define qglLoadIdentity glLoadIdentity -#define qglLoadMatrixd glLoadMatrixd -#define qglLoadMatrixf glLoadMatrixf -#define qglLoadName glLoadName -#define qglLogicOp glLogicOp -#define qglMap1d glMap1d -#define qglMap1f glMap1f -#define qglMap2d glMap2d -#define qglMap2f glMap2f -#define qglMapGrid1d glMapGrid1d -#define qglMapGrid1f glMapGrid1f -#define qglMapGrid2d glMapGrid2d -#define qglMapGrid2f glMapGrid2f -#define qglMaterialf glMaterialf -#define qglMaterialfv glMaterialfv -#define qglMateriali glMateriali -#define qglMaterialiv glMaterialiv -#define qglMatrixMode glMatrixMode -#define qglMultMatrixd glMultMatrixd -#define qglMultMatrixf glMultMatrixf -#define qglNewList glNewList -#define qglNormal3b glNormal3b -#define qglNormal3bv glNormal3bv -#define qglNormal3d glNormal3d -#define qglNormal3dv glNormal3dv -#define qglNormal3f glNormal3f -#define qglNormal3fv glNormal3fv -#define qglNormal3i glNormal3i -#define qglNormal3iv glNormal3iv -#define qglNormal3s glNormal3s -#define qglNormal3sv glNormal3sv -#define qglNormalPointer glNormalPointer -#define qglOrtho glOrtho -#define qglPassThrough glPassThrough -#define qglPixelMapfv glPixelMapfv -#define qglPixelMapuiv glPixelMapuiv -#define qglPixelMapusv glPixelMapusv -#define qglPixelStoref glPixelStoref -#define qglPixelStorei glPixelStorei -#define qglPixelTransferf glPixelTransferf -#define qglPixelTransferi glPixelTransferi -#define qglPixelZoom glPixelZoom -#define qglPointSize glPointSize -#define qglPolygonMode glPolygonMode -#define qglPolygonOffset glPolygonOffset -#define qglPolygonStipple glPolygonStipple -#define qglPopAttrib glPopAttrib -#define qglPopClientAttrib glPopClientAttrib -#define qglPopMatrix glPopMatrix -#define qglPopName glPopName -#define qglPrioritizeTextures glPrioritizeTextures -#define qglPushAttrib glPushAttrib -#define qglPushClientAttrib glPushClientAttrib -#define qglPushMatrix glPushMatrix -#define qglPushName glPushName -#define qglRasterPos2d glRasterPos2d -#define qglRasterPos2dv glRasterPos2dv -#define qglRasterPos2f glRasterPos2f -#define qglRasterPos2fv glRasterPos2fv -#define qglRasterPos2i glRasterPos2i -#define qglRasterPos2iv glRasterPos2iv -#define qglRasterPos2s glRasterPos2s -#define qglRasterPos2sv glRasterPos2sv -#define qglRasterPos3d glRasterPos3d -#define qglRasterPos3dv glRasterPos3dv -#define qglRasterPos3f glRasterPos3f -#define qglRasterPos3fv glRasterPos3fv -#define qglRasterPos3i glRasterPos3i -#define qglRasterPos3iv glRasterPos3iv -#define qglRasterPos3s glRasterPos3s -#define qglRasterPos3sv glRasterPos3sv -#define qglRasterPos4d glRasterPos4d -#define qglRasterPos4dv glRasterPos4dv -#define qglRasterPos4f glRasterPos4f -#define qglRasterPos4fv glRasterPos4fv -#define qglRasterPos4i glRasterPos4i -#define qglRasterPos4iv glRasterPos4iv -#define qglRasterPos4s glRasterPos4s -#define qglRasterPos4sv glRasterPos4sv -#define qglReadBuffer glReadBuffer -#define qglReadPixels glReadPixels -#define qglRectd glRectd -#define qglRectdv glRectdv -#define qglRectf glRectf -#define qglRectfv glRectfv -#define qglRecti glRecti -#define qglRectiv glRectiv -#define qglRects glRects -#define qglRectsv glRectsv -#define qglRenderMode glRenderMode -#define qglRotated glRotated -#define qglRotatef glRotatef -#define qglScaled glScaled -#define qglScalef glScalef -#define qglScissor glScissor -#define qglSelectBuffer glSelectBuffer -#define qglShadeModel glShadeModel -#define qglStencilFunc glStencilFunc -#define qglStencilMask glStencilMask -#define qglStencilOp glStencilOp -#define qglTexCoord1d glTexCoord1d -#define qglTexCoord1dv glTexCoord1dv -#define qglTexCoord1f glTexCoord1f -#define qglTexCoord1fv glTexCoord1fv -#define qglTexCoord1i glTexCoord1i -#define qglTexCoord1iv glTexCoord1iv -#define qglTexCoord1s glTexCoord1s -#define qglTexCoord1sv glTexCoord1sv -#define qglTexCoord2d glTexCoord2d -#define qglTexCoord2dv glTexCoord2dv -#define qglTexCoord2f glTexCoord2f -#define qglTexCoord2fv glTexCoord2fv -#define qglTexCoord2i glTexCoord2i -#define qglTexCoord2iv glTexCoord2iv -#define qglTexCoord2s glTexCoord2s -#define qglTexCoord2sv glTexCoord2sv -#define qglTexCoord3d glTexCoord3d -#define qglTexCoord3dv glTexCoord3dv -#define qglTexCoord3f glTexCoord3f -#define qglTexCoord3fv glTexCoord3fv -#define qglTexCoord3i glTexCoord3i -#define qglTexCoord3iv glTexCoord3iv -#define qglTexCoord3s glTexCoord3s -#define qglTexCoord3sv glTexCoord3sv -#define qglTexCoord4d glTexCoord4d -#define qglTexCoord4dv glTexCoord4dv -#define qglTexCoord4f glTexCoord4f -#define qglTexCoord4fv glTexCoord4fv -#define qglTexCoord4i glTexCoord4i -#define qglTexCoord4iv glTexCoord4iv -#define qglTexCoord4s glTexCoord4s -#define qglTexCoord4sv glTexCoord4sv -#define qglTexCoordPointer glTexCoordPointer -#define qglTexEnvf glTexEnvf -#define qglTexEnvfv glTexEnvfv -#define qglTexEnvi glTexEnvi -#define qglTexEnviv glTexEnviv -#define qglTexGend glTexGend -#define qglTexGendv glTexGendv -#define qglTexGenf glTexGenf -#define qglTexGenfv glTexGenfv -#define qglTexGeni glTexGeni -#define qglTexGeniv glTexGeniv -#define qglTexImage1D glTexImage1D -#define qglTexImage2D glTexImage2D -#define qglTexParameterf glTexParameterf -#define qglTexParameterfv glTexParameterfv -#define qglTexParameteri glTexParameteri -#define qglTexParameteriv glTexParameteriv -#define qglTexSubImage1D glTexSubImage1D -#define qglTexSubImage2D glTexSubImage2D -#define qglTranslated glTranslated -#define qglTranslatef glTranslatef -#define qglVertex2d glVertex2d -#define qglVertex2dv glVertex2dv -#define qglVertex2f glVertex2f -#define qglVertex2fv glVertex2fv -#define qglVertex2i glVertex2i -#define qglVertex2iv glVertex2iv -#define qglVertex2s glVertex2s -#define qglVertex2sv glVertex2sv -#define qglVertex3d glVertex3d -#define qglVertex3dv glVertex3dv -#define qglVertex3f glVertex3f -#define qglVertex3fv glVertex3fv -#define qglVertex3i glVertex3i -#define qglVertex3iv glVertex3iv -#define qglVertex3s glVertex3s -#define qglVertex3sv glVertex3sv -#define qglVertex4d glVertex4d -#define qglVertex4dv glVertex4dv -#define qglVertex4f glVertex4f -#define qglVertex4fv glVertex4fv -#define qglVertex4i glVertex4i -#define qglVertex4iv glVertex4iv -#define qglVertex4s glVertex4s -#define qglVertex4sv glVertex4sv -#define qglVertexPointer glVertexPointer -#define qglViewport glViewport - diff --git a/code/renderer/tr_backend.cpp b/code/renderer/tr_backend.cpp index 9df397d..6efc55a 100644 --- a/code/renderer/tr_backend.cpp +++ b/code/renderer/tr_backend.cpp @@ -1032,7 +1032,7 @@ static const void* RB_SwapBuffers( const void* data ) qglFinish(); } - GLimp_EndFrame(); + Sys_GL_EndFrame(); backEnd.projection2D = qfalse; backEnd.pc = backEnd.pc3D; diff --git a/code/renderer/tr_gl2.cpp b/code/renderer/tr_gl2.cpp index d01cf1b..e3824d8 100644 --- a/code/renderer/tr_gl2.cpp +++ b/code/renderer/tr_gl2.cpp @@ -728,7 +728,7 @@ static const char* greyscaleFS = ""; -qbool QGL_InitGL2() +qbool GL2_Init() { if ( !GL2_FBO_Init() ) { Com_Printf( "ERROR: failed to create framebuffer objects\n" ); diff --git a/code/renderer/tr_help.h b/code/renderer/tr_help.h index f48e57e..b099ffa 100644 --- a/code/renderer/tr_help.h +++ b/code/renderer/tr_help.h @@ -1,9 +1,10 @@ #define help_r_ext_max_anisotropy \ "max. allowed anisotropy ratio\n" \ "For anisotropic filtering to be enabled, this needs to be 2 or higher.\n" \ -" 2 = 8-16 tap filtering\n" \ -" 4 = 16-32 tap filtering\n" \ -" 8 = 32-64 tap filtering" +" 2 = 8- 16 tap filtering\n" \ +" 4 = 16- 32 tap filtering\n" \ +" 8 = 32- 64 tap filtering\n" \ +" 16 = 64-128 tap filtering" #define help_r_picmip \ "lowest allowed mip level\n" \ diff --git a/code/renderer/tr_image.cpp b/code/renderer/tr_image.cpp index 9917ad2..1a3b225 100644 --- a/code/renderer/tr_image.cpp +++ b/code/renderer/tr_image.cpp @@ -407,8 +407,8 @@ done: qglGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&image->format ); - if (r_ext_max_anisotropy->integer > 1) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, r_ext_max_anisotropy->integer ); + if ( glInfo.maxAnisotropy >= 2 && r_ext_max_anisotropy->integer >= 2 ) + qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, min( r_ext_max_anisotropy->integer, glInfo.maxAnisotropy ) ); if ( image->flags & IMG_NOMIPMAP ) { qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); diff --git a/code/renderer/tr_init.cpp b/code/renderer/tr_init.cpp index 1a8b6bf..8129ed3 100644 --- a/code/renderer/tr_init.cpp +++ b/code/renderer/tr_init.cpp @@ -171,6 +171,50 @@ static void GL_SetDefaultState() } +static void GL_InitGLConfig() +{ + Q_strncpyz( glConfig.vendor_string, (const char*)qglGetString( GL_VENDOR ), sizeof( glConfig.vendor_string ) ); + Q_strncpyz( glConfig.renderer_string, (const char*)qglGetString( GL_RENDERER ), sizeof( glConfig.renderer_string ) ); + Q_strncpyz( glConfig.version_string, (const char*)qglGetString( GL_VERSION ), sizeof( glConfig.version_string ) ); + Q_strncpyz( glConfig.extensions_string, (const char*)qglGetString( GL_EXTENSIONS ), sizeof( glConfig.extensions_string ) ); + qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.unused_maxTextureSize ); + glConfig.unused_maxActiveTextures = 0; + glConfig.unused_driverType = 0; // ICD + glConfig.unused_hardwareType = 0; // generic + glConfig.unused_deviceSupportsGamma = qtrue; + glConfig.unused_textureCompression = 0; // no compression + glConfig.unused_textureEnvAddAvailable = qtrue; + glConfig.unused_displayFrequency = 0; + glConfig.unused_isFullscreen = !!r_fullscreen->integer; + glConfig.unused_stereoEnabled = qfalse; + glConfig.unused_smpActive = qfalse; +} + + +static void GL_InitGLInfo() +{ + qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glInfo.maxTextureSize ); + qglGetIntegerv( GL_MAX_ELEMENTS_INDICES, &glInfo.maxDrawElementsI ); + qglGetIntegerv( GL_MAX_ELEMENTS_VERTICES, &glInfo.maxDrawElementsV ); + + if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) ) + qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glInfo.maxAnisotropy ); + else + glInfo.maxAnisotropy = 0; +} + + +static void GL_InitExtensions() +{ + const char* missingExtension = NULL; + if ( !Sys_GL_LoadExtensions( &missingExtension ) ) + ri.Error( ERR_FATAL, "GL_InitExtensions() - failed to load %s\n", missingExtension ? missingExtension : "a required extension" ); + + if ( !GL2_Init() ) + ri.Error( ERR_FATAL, "GL_InitExtensions() - failed to create GL2 objects\n" ); +} + + /* ** InitOpenGL ** @@ -181,25 +225,20 @@ static void GL_SetDefaultState() */ static void InitOpenGL() { - // - // initialize OS specific portions of the renderer - // - // GLimp_Init directly or indirectly references the following cvars: - // - r_fullscreen - // - r_mode - // - r_(color|depth|stencil)bits - // - r_ignorehwgamma - // - r_gamma - // + // Sys_GL_Init initializes OS-specific portions of the renderer + // it directly or indirectly references the following cvars: + // r_fullscreen, r_mode, r_width, r_height if ( glConfig.vidWidth == 0 ) { - GLimp_Init(); + // the order of these calls can not be changed + Sys_GL_Init(); + GL_InitGLConfig(); + GL_InitGLInfo(); + GL_InitExtensions(); - qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glInfo.maxTextureSize ); - - qglGetIntegerv( GL_MAX_ELEMENTS_INDICES, &glInfo.maxDrawElementsI ); - qglGetIntegerv( GL_MAX_ELEMENTS_VERTICES, &glInfo.maxDrawElementsV ); + // apply the current V-Sync option after the first rendered frame + r_swapInterval->modified = qtrue; } // init command buffers and SMP @@ -448,7 +487,7 @@ static const cvarTableItem_t r_cvars[] = // // latched and archived variables // - { &r_ext_max_anisotropy, "r_ext_max_anisotropy", "4", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", "4", help_r_ext_max_anisotropy }, + { &r_ext_max_anisotropy, "r_ext_max_anisotropy", "16", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", "16", help_r_ext_max_anisotropy }, { &r_msaa, "r_msaa", "4", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", "16", "anti-aliasing sample count, 0=off" }, { &r_picmip, "r_picmip", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_INTEGER, "0", "16", help_r_picmip }, { &r_roundImagesDown, "r_roundImagesDown", "0", CVAR_ARCHIVE | CVAR_LATCH, CVART_BOOL, NULL, NULL, help_r_roundImagesDown }, @@ -631,7 +670,9 @@ static void RE_Shutdown( qbool destroyWindow ) // shut down platform specific OpenGL stuff if ( destroyWindow ) { - GLimp_Shutdown(); + Sys_GL_Shutdown(); + memset( &glConfig, 0, sizeof( glConfig ) ); + memset( &glState, 0, sizeof( glState ) ); } tr.registered = qfalse; diff --git a/code/renderer/tr_local.h b/code/renderer/tr_local.h index 0942e36..e189dfd 100644 --- a/code/renderer/tr_local.h +++ b/code/renderer/tr_local.h @@ -1141,10 +1141,24 @@ IMPLEMENTATION SPECIFIC FUNCTIONS ==================================================================== */ -void GLimp_Init(); -void GLimp_Shutdown(); -void GLimp_EndFrame(); +// OpenGL initialization: +// - loading OpenGL and getting core function pointers +// - creating a window and changing video mode if needed, +// respecting r_fullscreen, r_mode, r_width, r_height +// - creating a valid OpenGL context and making it current +// - filling up the right glconfig fields (see glconfig_t definition) +void Sys_GL_Init(); +// OpenGL shutdown: +// - unloading OpenGL and zeroing the core function pointers +// - destroying the GL context, window and other associated resources +// - resetting the proper video mode if necessary +void Sys_GL_Shutdown(); + +// Swaps buffers and applies r_swapInterval. +void Sys_GL_EndFrame(); + +// SMP qbool GLimp_SpawnRenderThread( void (*function)( void ) ); void* GLimp_RendererSleep( void ); void GLimp_FrontEndSleep( void ); @@ -1498,14 +1512,18 @@ extern glconfig_t glConfig; // the "private" glconfig: implementation specifics for the renderer struct glinfo_t { + // used by platform layer qbool isFullscreen; int displayFrequency; + // used by platform layer and renderer qbool smpActive; + // used by renderer GLint maxTextureSize; GLint maxDrawElementsI; GLint maxDrawElementsV; + GLint maxAnisotropy; }; extern glinfo_t glInfo; @@ -1529,10 +1547,12 @@ private: }; -extern void GL2_DynLights_SetupLight(); -extern void GL2_DynLights_StageIterator(); -extern void GL2_BeginFrame(); -extern void GL2_EndFrame(); +// tr_gl2.cpp +qbool GL2_Init(); +void GL2_DynLights_SetupLight(); +void GL2_DynLights_StageIterator(); +void GL2_BeginFrame(); +void GL2_EndFrame(); extern int re_cameraMatrixTime; diff --git a/code/win32/win_glimp.cpp b/code/win32/win_glimp.cpp index 9562277..c809bc7 100644 --- a/code/win32/win_glimp.cpp +++ b/code/win32/win_glimp.cpp @@ -602,80 +602,24 @@ static qbool GLW_SetMode( qbool cdsFullscreen ) } -static void GLW_InitExtensions() -{ - ri.Printf( PRINT_DEVELOPER, "Initializing OpenGL extensions\n" ); - -#define QGL_EXT(T, fn) q##fn = (T)qwglGetProcAddress( #fn ); \ - if (!q##fn) Com_Error( ERR_FATAL, "QGL_EXT: required extension "#fn" not found" ); - - QGL_EXT( PFNGLLOCKARRAYSEXTPROC, glLockArraysEXT ); - QGL_EXT( PFNGLUNLOCKARRAYSEXTPROC, glUnlockArraysEXT ); - QGL_EXT( PFNGLACTIVETEXTUREARBPROC, glActiveTextureARB ); - QGL_EXT( PFNGLCLIENTACTIVETEXTUREARBPROC, glClientActiveTextureARB ); - -#undef QGL_EXT - - // WGL_EXT_swap_control - qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" ); - if ( qwglSwapIntervalEXT ) - { - ri.Printf( PRINT_DEVELOPER, "...using WGL_EXT_swap_control\n" ); - r_swapInterval->modified = qtrue; // force a set next frame - } - else - { - ri.Printf( PRINT_DEVELOPER, "...WGL_EXT_swap_control not found\n" ); - } - - int maxAnisotropy = 0; - if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) ) - { - if (r_ext_max_anisotropy->integer > 1) { - qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy ); - if ( maxAnisotropy <= 0 ) { - ri.Printf( PRINT_DEVELOPER, "...GL_EXT_texture_filter_anisotropic not properly supported!\n" ); - maxAnisotropy = 0; - } - else - { - ri.Printf( PRINT_DEVELOPER, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", maxAnisotropy ); - } - } - else - { - ri.Printf( PRINT_DEVELOPER, "...ignoring GL_EXT_texture_filter_anisotropic\n" ); - } - } - else - { - ri.Printf( PRINT_DEVELOPER, "...GL_EXT_texture_filter_anisotropic not found\n" ); - } - Cvar_Set( "r_ext_max_anisotropy", va("%i", maxAnisotropy) ); - -} - - static qbool GLW_LoadOpenGL() { // only real GL implementations are acceptable - const char* OPENGL_DRIVER_NAME = "opengl32"; - // load the driver and bind our function pointers to it - if ( QGL_Init( OPENGL_DRIVER_NAME ) ) { + if ( WIN_LoadGL( "opengl32" ) ) { // create the window and set up the context if ( GLW_SetMode( (qbool)!!r_fullscreen->integer ) ) { return qtrue; } } - QGL_Shutdown(); + WIN_UnloadGL(); return qfalse; } -void GLimp_EndFrame() +void Sys_GL_EndFrame() { if ( r_swapInterval->modified ) { r_swapInterval->modified = qfalse; @@ -692,15 +636,7 @@ void GLimp_EndFrame() /////////////////////////////////////////////////////////////// -/* -This is the platform specific OpenGL initialization function. -It is responsible for loading OpenGL, initializing it, setting -extensions, creating a window of the appropriate size, doing -fullscreen manipulations, etc. Its overall responsibility is -to make sure that a functional OpenGL subsystem is operating -when it returns to the ref. -*/ -void GLimp_Init() +void Sys_GL_Init() { ri.Printf( PRINT_DEVELOPER, "Initializing OpenGL subsystem\n" ); @@ -711,29 +647,10 @@ void GLimp_Init() // load appropriate DLL and initialize subsystem if (!GLW_LoadOpenGL()) ri.Error( ERR_FATAL, "GLimp_Init() - could not load OpenGL subsystem\n" ); - - // get our config strings - Q_strncpyz( glConfig.vendor_string, (const char*)qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) ); - Q_strncpyz( glConfig.renderer_string, (const char*)qglGetString (GL_RENDERER), sizeof( glConfig.renderer_string ) ); - Q_strncpyz( glConfig.version_string, (const char*)qglGetString (GL_VERSION), sizeof( glConfig.version_string ) ); - Q_strncpyz( glConfig.extensions_string, (const char*)qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) ); - - GLW_InitExtensions(); - - if (!GLW_InitGL2()) - ri.Error( ERR_FATAL, "GLimp_Init() - could not find OpenGL 2 extensions\n" ); - - // GL2 is mandatory, GL3+ isn't - GLW_InitGL3(); - - if (!QGL_InitGL2()) - ri.Error( ERR_FATAL, "GLimp_Init() - could not initialize OpenGL 2 objects\n" ); } -// do all OS specific shutdown procedures for the OpenGL subsystem - -void GLimp_Shutdown() +void Sys_GL_Shutdown() { const char* success[] = { "failed", "success" }; int retVal; @@ -787,11 +704,8 @@ void GLimp_Shutdown() GLW_ResetDisplaySettings( qtrue ); } - // shutdown QGL subsystem - QGL_Shutdown(); - - memset( &glConfig, 0, sizeof( glConfig ) ); - memset( &glState, 0, sizeof( glState ) ); + // shutdown OpenGL subsystem + WIN_UnloadGL(); } diff --git a/code/win32/win_local.h b/code/win32/win_local.h index 63921d8..fc0333b 100644 --- a/code/win32/win_local.h +++ b/code/win32/win_local.h @@ -26,10 +26,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ); -void Sys_CreateConsole( void ); -void Sys_DestroyConsole( void ); -const char* Sys_ConsoleInput(); -void Conbuf_AppendText( const char *msg ); +void Sys_CreateConsole( void ); +void Sys_DestroyConsole( void ); +const char* Sys_ConsoleInput(); + +void Conbuf_AppendText( const char *msg ); void IN_Activate( qbool active ); qbool IN_ProcessMessage( UINT msg, WPARAM wParam, LPARAM lParam ); // returns true if the event was handled @@ -48,14 +49,19 @@ void SNDDMA_Activate(); LRESULT CALLBACK MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); // crash handling -LONG CALLBACK WIN_HandleException( EXCEPTION_POINTERS* ep ); -void WIN_HandleExit(); -void WIN_EndTimePeriod(); +LONG CALLBACK WIN_HandleException( EXCEPTION_POINTERS* ep ); +void WIN_HandleExit(); +void WIN_EndTimePeriod(); + +// opening OpenGL and loading core functions +extern "C" { + qbool WIN_LoadGL( const char* dllName ); + void WIN_UnloadGL(); +} #define MAX_MONITOR_COUNT 16 -typedef struct -{ +typedef struct { HWND hWnd; HINSTANCE hInstance; qbool activeApp; diff --git a/code/win32/win_qgl.c b/code/win32/win_qgl.c index 7735411..1ffe31e 100644 --- a/code/win32/win_qgl.c +++ b/code/win32/win_qgl.c @@ -19,26 +19,14 @@ along with Quake III Arena source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ -/* -** QGL_WIN.C -** -** This file implements the operating system binding of GL to QGL function -** pointers. When doing a port of Quake3 you must implement the following -** two functions: -** -** QGL_Init() - loads libraries, assigns function pointers, etc. -** QGL_Shutdown() - unloads libraries, NULLs function pointers -*/ - #include "../qcommon/q_shared.h" - #define WIN32_LEAN_AND_MEAN #include "../win32/windows.h" #include #include "glext.h" - #include "glw_win.h" + int ( WINAPI * qwglSwapIntervalEXT)( int interval ); int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *); @@ -411,21 +399,10 @@ PFNGLLOCKARRAYSEXTPROC qglLockArraysEXT; PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT; -/* -** QGL_Shutdown -** -** Unloads the specified DLL then nulls out all the proc pointers. This -** is only called during a hard shutdown of the OGL subsystem (e.g. vid_restart). -*/ -void QGL_Shutdown() +void WIN_UnloadGL() { - //ri.Printf( PRINT_ALL, "...shutting down QGL\n" ); - if ( glw_state.hinstOpenGL ) - { - //ri.Printf( PRINT_ALL, "...unloading OpenGL DLL\n" ); FreeLibrary( glw_state.hinstOpenGL ); - } glw_state.hinstOpenGL = NULL; @@ -795,20 +772,16 @@ void QGL_Shutdown() #pragma warning( disable : 4047 4133 ) // various WINGDIAPI/FARPROC mismatches #endif + +// +// core OpenGL functions +// + #define QGL_GPA(fn) q##fn = GetProcAddress( glw_state.hinstOpenGL, #fn ) -/* -** QGL_Init -** -** This is responsible for binding our qgl function pointers to -** the appropriate GL stuff. In Windows this means doing a -** LoadLibrary and a bunch of calls to GetProcAddress. On other -** operating systems we need to do the right thing, whatever that -** might be. -*/ -qbool QGL_Init( const char* dllname ) +qbool WIN_LoadGL( const char* dllName ) { - if ( ( glw_state.hinstOpenGL = LoadLibrary( dllname ) ) == 0 ) + if ( ( glw_state.hinstOpenGL = LoadLibrary( dllName ) ) == 0 ) return qfalse; QGL_GPA( glAccum ); @@ -1169,36 +1142,43 @@ qbool QGL_Init( const char* dllname ) QGL_GPA( wglSetPixelFormat ); QGL_GPA( wglSwapBuffers ); - // required extensions - qglLockArraysEXT = 0; - qglUnlockArraysEXT = 0; - qglActiveTextureARB = 0; - qglClientActiveTextureARB = 0; - - // optional extensions - qwglSwapIntervalEXT = 0; - qwglChoosePixelFormatARB = 0; - return qtrue; }; #undef QGL_GPA -#ifdef _MSC_VER -#pragma warning( default : 4047 4133 ) -#endif - - -/////////////////////////////////////////////////////////////// - -// the logfile system is obsolete - use GLIntercept - -// note that all GL2 functions have to be retrieved by wglGPA -// which means they can't be set up until AFTER there's a current context +// +// platform-specific OpenGL extensions +// +#define QGL_EXT_OPT(fn) q##fn = qwglGetProcAddress( #fn ) #define QGL_EXT(fn) q##fn = qwglGetProcAddress( #fn ); \ - if (!q##fn) Com_Error( ERR_FATAL, "QGL_EXT: "#fn" not found" ); + do { if (!q##fn) { *extension = #fn; return qfalse; } } while(0) + +static qbool WIN_InitPlatformGL( const char** extension ) +{ + // required extensions + QGL_EXT( glLockArraysEXT ); + QGL_EXT( glUnlockArraysEXT ); + QGL_EXT( glActiveTextureARB ); + QGL_EXT( glClientActiveTextureARB ); + + // optional extensions + QGL_EXT_OPT( wglSwapIntervalEXT ); + QGL_EXT_OPT( wglChoosePixelFormatARB ); + QGL_EXT_OPT( wglSwapIntervalEXT ); + + return qtrue; +} + +#undef QGL_EXT +#undef QGL_EXT_OPT + + +// +// OpenGL 2 +// PFNGLCREATESHADERPROC qglCreateShader; PFNGLSHADERSOURCEPROC qglShaderSource; @@ -1245,8 +1225,10 @@ PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC qglGetFramebufferAttachmentParamete PFNGLGENERATEMIPMAPPROC qglGenerateMipmap; PFNGLBLITFRAMEBUFFERPROC qglBlitFramebuffer; +#define QGL_EXT(fn) q##fn = qwglGetProcAddress( #fn ); \ + do { if (!q##fn) { *extension = #fn; return qfalse; } } while(0) -qbool GLW_InitGL2() +static qbool WIN_InitGL2( const char** extension ) { if (atof((const char*)qglGetString(GL_VERSION)) < 2.0f) return qfalse; @@ -1299,23 +1281,36 @@ qbool GLW_InitGL2() return qtrue; } +#undef QGL_EXT + + +// +// OpenGL 3+ +// PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC qglRenderbufferStorageMultisample; void (APIENTRY* qglTexImage2DMultisample)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean); - -#undef QGL_EXT #define QGL_EXT(fn) q##fn = qwglGetProcAddress( #fn ) - -qbool GLW_InitGL3() +static void WIN_InitGL3() { if (atof((const char*)qglGetString(GL_VERSION)) < 3.2f) - return qfalse; + return; QGL_EXT( glRenderbufferStorageMultisample ); QGL_EXT( glTexImage2DMultisample ); +} + +#undef QGL_EXT + + +qbool Sys_GL_LoadExtensions( const char** extension ) +{ + if ( !WIN_InitPlatformGL(extension) || !WIN_InitGL2(extension) ) + return qfalse; + + WIN_InitGL3(); return qtrue; } -