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
This commit is contained in:
myT 2017-11-03 19:33:54 +01:00
parent 31167156ac
commit 4cd544217c
15 changed files with 289 additions and 750 deletions

View file

@ -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();

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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 <GL/gl.h>
#elif defined( _WIN32 )
#if defined( _WIN32 )
#include "../win32/windows.h"
#include <GL/gl.h>
#include "../win32/glext.h"
#elif defined(MACOS_X)
#elif defined( __linux__ )
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#ifndef GL_EXT_abgr
#include <OpenGL/glext.h>
#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 <OpenGL/CGLMacro.h>
#endif
#elif defined( __linux__ ) || defined(__FreeBSD__)
#include <GL/gl.h>
#include <GL/glx.h>
#elif defined( __sun )
#include <GL/gl.h>
#include <GL/glx.h>
#else
#include <gl.h>
#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

View file

@ -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

View file

@ -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;

View file

@ -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" );

View file

@ -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" \

View file

@ -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 );

View file

@ -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;

View file

@ -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;

View file

@ -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();
}

View file

@ -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;

View file

@ -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 <GL/gl.h>
#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;
}