2011-05-09 22:00:00 +02:00
/*
gl_vidnt . c - NT GL vid component
Copyright ( C ) 2010 Uncle Mike
This program 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 3 of the License , or
( at your option ) any later version .
This program 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 .
*/
2010-11-28 22:00:00 +01:00
# include "common.h"
# include "client.h"
# include "gl_local.h"
2011-04-06 22:00:00 +02:00
# include "mod_local.h"
2010-11-28 22:00:00 +01:00
# include "input.h"
2010-12-21 22:00:00 +01:00
# define VID_DEFAULTMODE "1"
2010-11-28 22:00:00 +01:00
# define num_vidmodes ((int)(sizeof(vidmode) / sizeof(vidmode[0])) - 1)
# define WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_SYSMENU|WS_CAPTION|WS_VISIBLE)
# define WINDOW_EX_STYLE (0)
2011-02-05 22:00:00 +01:00
# define WINDOW_NAME "Xash Window" // Half-Life
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
convar_t * renderinfo ;
2010-11-28 22:00:00 +01:00
convar_t * gl_allow_software ;
convar_t * gl_extensions ;
2010-12-11 22:00:00 +01:00
convar_t * gl_alphabits ;
2010-11-28 22:00:00 +01:00
convar_t * gl_stencilbits ;
convar_t * gl_ignorehwgamma ;
convar_t * gl_texture_anisotropy ;
2010-11-29 22:00:00 +01:00
convar_t * gl_compress_textures ;
2011-07-07 22:00:00 +02:00
convar_t * gl_luminance_textures ;
2014-04-01 22:00:00 +02:00
convar_t * gl_compensate_gamma_screenshots ;
2012-12-23 21:00:00 +01:00
convar_t * gl_keeptjunctions ;
2010-11-28 22:00:00 +01:00
convar_t * gl_texture_lodbias ;
2010-11-29 22:00:00 +01:00
convar_t * gl_showtextures ;
2013-12-01 21:00:00 +01:00
convar_t * gl_detailscale ;
2010-11-28 22:00:00 +01:00
convar_t * gl_swapInterval ;
convar_t * gl_check_errors ;
2011-01-08 22:00:00 +01:00
convar_t * gl_allow_static ;
2011-10-06 22:00:00 +02:00
convar_t * gl_allow_mirrors ;
2010-11-28 22:00:00 +01:00
convar_t * gl_texturemode ;
2011-04-15 22:00:00 +02:00
convar_t * gl_wireframe ;
2010-11-28 22:00:00 +01:00
convar_t * gl_round_down ;
2011-08-21 22:00:00 +02:00
convar_t * gl_overview ;
2011-01-03 22:00:00 +01:00
convar_t * gl_max_size ;
2010-11-28 22:00:00 +01:00
convar_t * gl_picmip ;
2010-11-29 22:00:00 +01:00
convar_t * gl_skymip ;
convar_t * gl_finish ;
2012-12-28 21:00:00 +01:00
convar_t * gl_nosort ;
2010-11-29 22:00:00 +01:00
convar_t * gl_clear ;
2010-12-13 22:00:00 +01:00
convar_t * gl_test ;
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
convar_t * r_xpos ;
convar_t * r_ypos ;
2010-11-28 22:00:00 +01:00
convar_t * r_width ;
convar_t * r_height ;
2010-12-02 22:00:00 +01:00
convar_t * r_speeds ;
2010-12-03 22:00:00 +01:00
convar_t * r_fullbright ;
2010-12-06 22:00:00 +01:00
convar_t * r_norefresh ;
2011-02-25 22:00:00 +01:00
convar_t * r_lighting_extended ;
2010-12-06 22:00:00 +01:00
convar_t * r_lighting_modulate ;
2010-12-16 22:00:00 +01:00
convar_t * r_lighting_ambient ;
2011-07-07 22:00:00 +02:00
convar_t * r_detailtextures ;
2010-12-14 22:00:00 +01:00
convar_t * r_faceplanecull ;
2010-12-11 22:00:00 +01:00
convar_t * r_drawentities ;
2010-12-06 22:00:00 +01:00
convar_t * r_adjust_fov ;
2011-04-10 22:00:00 +02:00
convar_t * r_flaresize ;
2010-12-17 22:00:00 +01:00
convar_t * r_lefthand ;
2010-12-23 22:00:00 +01:00
convar_t * r_decals ;
2010-12-06 22:00:00 +01:00
convar_t * r_novis ;
convar_t * r_nocull ;
convar_t * r_lockpvs ;
2010-12-12 22:00:00 +01:00
convar_t * r_lockcull ;
2010-12-06 22:00:00 +01:00
convar_t * r_dynamic ;
convar_t * r_lightmap ;
convar_t * r_fastsky ;
2010-11-28 22:00:00 +01:00
convar_t * vid_displayfrequency ;
convar_t * vid_fullscreen ;
convar_t * vid_gamma ;
2011-10-06 22:00:00 +02:00
convar_t * vid_texgamma ;
2010-11-28 22:00:00 +01:00
convar_t * vid_mode ;
2011-04-10 22:00:00 +02:00
byte * r_temppool ;
2010-11-28 22:00:00 +01:00
ref_globals_t tr ;
glconfig_t glConfig ;
glstate_t glState ;
glwstate_t glw_state ;
2013-02-24 21:00:00 +01:00
uint num_instances ;
2010-11-28 22:00:00 +01:00
typedef enum
{
rserr_ok ,
rserr_invalid_fullscreen ,
rserr_invalid_mode ,
rserr_unknown
} rserr_t ;
typedef struct vidmode_s
{
const char * desc ;
int width ;
int height ;
qboolean wideScreen ;
} vidmode_t ;
vidmode_t vidmode [ ] =
{
2010-12-21 22:00:00 +01:00
{ " Mode 0: 4x3 " , 640 , 480 , false } ,
{ " Mode 1: 4x3 " , 800 , 600 , false } ,
{ " Mode 2: 4x3 " , 960 , 720 , false } ,
{ " Mode 3: 4x3 " , 1024 , 768 , false } ,
{ " Mode 4: 4x3 " , 1152 , 864 , false } ,
{ " Mode 5: 4x3 " , 1280 , 800 , false } ,
{ " Mode 6: 4x3 " , 1280 , 960 , false } ,
{ " Mode 7: 4x3 " , 1280 , 1024 , false } ,
{ " Mode 8: 4x3 " , 1600 , 1200 , false } ,
{ " Mode 9: 4x3 " , 2048 , 1536 , false } ,
2011-04-18 22:00:00 +02:00
{ " Mode 10: 16x9 " , 800 , 480 , true } ,
{ " Mode 11: 16x9 " , 856 , 480 , true } ,
2011-11-13 21:00:00 +01:00
{ " Mode 12: 16x9 " , 960 , 540 , true } ,
{ " Mode 13: 16x9 " , 1024 , 576 , true } ,
{ " Mode 14: 16x9 " , 1024 , 600 , true } ,
{ " Mode 15: 16x9 " , 1280 , 720 , true } ,
{ " Mode 16: 16x9 " , 1360 , 768 , true } ,
{ " Mode 17: 16x9 " , 1366 , 768 , true } ,
{ " Mode 18: 16x9 " , 1440 , 900 , true } ,
{ " Mode 19: 16x9 " , 1680 , 1050 , true } ,
{ " Mode 20: 16x9 " , 1920 , 1080 , true } ,
{ " Mode 21: 16x9 " , 1920 , 1200 , true } ,
{ " Mode 22: 16x9 " , 2560 , 1600 , true } ,
2010-11-28 22:00:00 +01:00
{ NULL , 0 , 0 , 0 } ,
} ;
static dllfunc_t opengl_110funcs [ ] =
{
{ " glClearColor " , ( void * * ) & pglClearColor } ,
{ " glClear " , ( void * * ) & pglClear } ,
{ " glAlphaFunc " , ( void * * ) & pglAlphaFunc } ,
{ " glBlendFunc " , ( void * * ) & pglBlendFunc } ,
{ " glCullFace " , ( void * * ) & pglCullFace } ,
{ " glDrawBuffer " , ( void * * ) & pglDrawBuffer } ,
{ " glReadBuffer " , ( void * * ) & pglReadBuffer } ,
{ " glEnable " , ( void * * ) & pglEnable } ,
{ " glDisable " , ( void * * ) & pglDisable } ,
{ " glEnableClientState " , ( void * * ) & pglEnableClientState } ,
{ " glDisableClientState " , ( void * * ) & pglDisableClientState } ,
{ " glGetBooleanv " , ( void * * ) & pglGetBooleanv } ,
{ " glGetDoublev " , ( void * * ) & pglGetDoublev } ,
{ " glGetFloatv " , ( void * * ) & pglGetFloatv } ,
{ " glGetIntegerv " , ( void * * ) & pglGetIntegerv } ,
{ " glGetError " , ( void * * ) & pglGetError } ,
{ " glGetString " , ( void * * ) & pglGetString } ,
{ " glFinish " , ( void * * ) & pglFinish } ,
{ " glFlush " , ( void * * ) & pglFlush } ,
{ " glClearDepth " , ( void * * ) & pglClearDepth } ,
{ " glDepthFunc " , ( void * * ) & pglDepthFunc } ,
{ " glDepthMask " , ( void * * ) & pglDepthMask } ,
{ " glDepthRange " , ( void * * ) & pglDepthRange } ,
{ " glFrontFace " , ( void * * ) & pglFrontFace } ,
{ " glDrawElements " , ( void * * ) & pglDrawElements } ,
{ " glColorMask " , ( void * * ) & pglColorMask } ,
{ " glIndexPointer " , ( void * * ) & pglIndexPointer } ,
{ " glVertexPointer " , ( void * * ) & pglVertexPointer } ,
{ " glNormalPointer " , ( void * * ) & pglNormalPointer } ,
{ " glColorPointer " , ( void * * ) & pglColorPointer } ,
{ " glTexCoordPointer " , ( void * * ) & pglTexCoordPointer } ,
{ " glArrayElement " , ( void * * ) & pglArrayElement } ,
{ " glColor3f " , ( void * * ) & pglColor3f } ,
{ " glColor3fv " , ( void * * ) & pglColor3fv } ,
{ " glColor4f " , ( void * * ) & pglColor4f } ,
{ " glColor4fv " , ( void * * ) & pglColor4fv } ,
2010-12-14 22:00:00 +01:00
{ " glColor3ub " , ( void * * ) & pglColor3ub } ,
2010-11-28 22:00:00 +01:00
{ " glColor4ub " , ( void * * ) & pglColor4ub } ,
{ " glColor4ubv " , ( void * * ) & pglColor4ubv } ,
{ " glTexCoord1f " , ( void * * ) & pglTexCoord1f } ,
{ " glTexCoord2f " , ( void * * ) & pglTexCoord2f } ,
{ " glTexCoord3f " , ( void * * ) & pglTexCoord3f } ,
{ " glTexCoord4f " , ( void * * ) & pglTexCoord4f } ,
{ " glTexGenf " , ( void * * ) & pglTexGenf } ,
{ " glTexGenfv " , ( void * * ) & pglTexGenfv } ,
{ " glTexGeni " , ( void * * ) & pglTexGeni } ,
{ " glVertex2f " , ( void * * ) & pglVertex2f } ,
{ " glVertex3f " , ( void * * ) & pglVertex3f } ,
{ " glVertex3fv " , ( void * * ) & pglVertex3fv } ,
{ " glNormal3f " , ( void * * ) & pglNormal3f } ,
{ " glNormal3fv " , ( void * * ) & pglNormal3fv } ,
{ " glBegin " , ( void * * ) & pglBegin } ,
{ " glEnd " , ( void * * ) & pglEnd } ,
{ " glLineWidth " , ( void * * ) & pglLineWidth } ,
{ " glPointSize " , ( void * * ) & pglPointSize } ,
{ " glMatrixMode " , ( void * * ) & pglMatrixMode } ,
{ " glOrtho " , ( void * * ) & pglOrtho } ,
2012-12-23 21:00:00 +01:00
{ " glRasterPos2f " , ( void * * ) & pglRasterPos2f } ,
2010-11-28 22:00:00 +01:00
{ " glFrustum " , ( void * * ) & pglFrustum } ,
{ " glViewport " , ( void * * ) & pglViewport } ,
{ " glPushMatrix " , ( void * * ) & pglPushMatrix } ,
{ " glPopMatrix " , ( void * * ) & pglPopMatrix } ,
2011-03-07 22:00:00 +01:00
{ " glPushAttrib " , ( void * * ) & pglPushAttrib } ,
{ " glPopAttrib " , ( void * * ) & pglPopAttrib } ,
2010-11-28 22:00:00 +01:00
{ " glLoadIdentity " , ( void * * ) & pglLoadIdentity } ,
{ " glLoadMatrixd " , ( void * * ) & pglLoadMatrixd } ,
{ " glLoadMatrixf " , ( void * * ) & pglLoadMatrixf } ,
{ " glMultMatrixd " , ( void * * ) & pglMultMatrixd } ,
{ " glMultMatrixf " , ( void * * ) & pglMultMatrixf } ,
{ " glRotated " , ( void * * ) & pglRotated } ,
{ " glRotatef " , ( void * * ) & pglRotatef } ,
{ " glScaled " , ( void * * ) & pglScaled } ,
{ " glScalef " , ( void * * ) & pglScalef } ,
{ " glTranslated " , ( void * * ) & pglTranslated } ,
{ " glTranslatef " , ( void * * ) & pglTranslatef } ,
{ " glReadPixels " , ( void * * ) & pglReadPixels } ,
{ " glDrawPixels " , ( void * * ) & pglDrawPixels } ,
{ " glStencilFunc " , ( void * * ) & pglStencilFunc } ,
{ " glStencilMask " , ( void * * ) & pglStencilMask } ,
{ " glStencilOp " , ( void * * ) & pglStencilOp } ,
{ " glClearStencil " , ( void * * ) & pglClearStencil } ,
2012-01-27 21:00:00 +01:00
{ " glIsEnabled " , ( void * * ) & pglIsEnabled } ,
{ " glIsList " , ( void * * ) & pglIsList } ,
{ " glIsTexture " , ( void * * ) & pglIsTexture } ,
2010-11-28 22:00:00 +01:00
{ " glTexEnvf " , ( void * * ) & pglTexEnvf } ,
{ " glTexEnvfv " , ( void * * ) & pglTexEnvfv } ,
{ " glTexEnvi " , ( void * * ) & pglTexEnvi } ,
{ " glTexParameterf " , ( void * * ) & pglTexParameterf } ,
{ " glTexParameterfv " , ( void * * ) & pglTexParameterfv } ,
{ " glTexParameteri " , ( void * * ) & pglTexParameteri } ,
{ " glHint " , ( void * * ) & pglHint } ,
{ " glPixelStoref " , ( void * * ) & pglPixelStoref } ,
{ " glPixelStorei " , ( void * * ) & pglPixelStorei } ,
{ " glGenTextures " , ( void * * ) & pglGenTextures } ,
{ " glDeleteTextures " , ( void * * ) & pglDeleteTextures } ,
{ " glBindTexture " , ( void * * ) & pglBindTexture } ,
{ " glTexImage1D " , ( void * * ) & pglTexImage1D } ,
{ " glTexImage2D " , ( void * * ) & pglTexImage2D } ,
{ " glTexSubImage1D " , ( void * * ) & pglTexSubImage1D } ,
{ " glTexSubImage2D " , ( void * * ) & pglTexSubImage2D } ,
{ " glCopyTexImage1D " , ( void * * ) & pglCopyTexImage1D } ,
{ " glCopyTexImage2D " , ( void * * ) & pglCopyTexImage2D } ,
{ " glCopyTexSubImage1D " , ( void * * ) & pglCopyTexSubImage1D } ,
{ " glCopyTexSubImage2D " , ( void * * ) & pglCopyTexSubImage2D } ,
2010-12-14 22:00:00 +01:00
{ " glScissor " , ( void * * ) & pglScissor } ,
{ " glGetTexEnviv " , ( void * * ) & pglGetTexEnviv } ,
2010-11-28 22:00:00 +01:00
{ " glPolygonOffset " , ( void * * ) & pglPolygonOffset } ,
{ " glPolygonMode " , ( void * * ) & pglPolygonMode } ,
{ " glPolygonStipple " , ( void * * ) & pglPolygonStipple } ,
{ " glClipPlane " , ( void * * ) & pglClipPlane } ,
{ " glGetClipPlane " , ( void * * ) & pglGetClipPlane } ,
{ " glShadeModel " , ( void * * ) & pglShadeModel } ,
{ " glFogfv " , ( void * * ) & pglFogfv } ,
{ " glFogf " , ( void * * ) & pglFogf } ,
{ " glFogi " , ( void * * ) & pglFogi } ,
{ NULL , NULL }
} ;
static dllfunc_t pointparametersfunc [ ] =
{
{ " glPointParameterfEXT " , ( void * * ) & pglPointParameterfEXT } ,
{ " glPointParameterfvEXT " , ( void * * ) & pglPointParameterfvEXT } ,
{ NULL , NULL }
} ;
static dllfunc_t drawrangeelementsfuncs [ ] =
{
{ " glDrawRangeElements " , ( void * * ) & pglDrawRangeElements } ,
{ NULL , NULL }
} ;
static dllfunc_t drawrangeelementsextfuncs [ ] =
{
{ " glDrawRangeElementsEXT " , ( void * * ) & pglDrawRangeElementsEXT } ,
{ NULL , NULL }
} ;
static dllfunc_t sgis_multitexturefuncs [ ] =
{
{ " glSelectTextureSGIS " , ( void * * ) & pglSelectTextureSGIS } ,
{ " glMTexCoord2fSGIS " , ( void * * ) & pglMTexCoord2fSGIS } ,
{ NULL , NULL }
} ;
static dllfunc_t multitexturefuncs [ ] =
{
{ " glMultiTexCoord1fARB " , ( void * * ) & pglMultiTexCoord1f } ,
{ " glMultiTexCoord2fARB " , ( void * * ) & pglMultiTexCoord2f } ,
{ " glMultiTexCoord3fARB " , ( void * * ) & pglMultiTexCoord3f } ,
{ " glMultiTexCoord4fARB " , ( void * * ) & pglMultiTexCoord4f } ,
{ " glActiveTextureARB " , ( void * * ) & pglActiveTextureARB } ,
{ " glClientActiveTextureARB " , ( void * * ) & pglClientActiveTexture } ,
{ " glClientActiveTextureARB " , ( void * * ) & pglClientActiveTextureARB } ,
{ NULL , NULL }
} ;
static dllfunc_t compiledvertexarrayfuncs [ ] =
{
{ " glLockArraysEXT " , ( void * * ) & pglLockArraysEXT } ,
{ " glUnlockArraysEXT " , ( void * * ) & pglUnlockArraysEXT } ,
{ " glDrawArrays " , ( void * * ) & pglDrawArrays } ,
{ NULL , NULL }
} ;
static dllfunc_t texture3dextfuncs [ ] =
{
{ " glTexImage3DEXT " , ( void * * ) & pglTexImage3D } ,
{ " glTexSubImage3DEXT " , ( void * * ) & pglTexSubImage3D } ,
{ " glCopyTexSubImage3DEXT " , ( void * * ) & pglCopyTexSubImage3D } ,
{ NULL , NULL }
} ;
static dllfunc_t atiseparatestencilfuncs [ ] =
{
{ " glStencilOpSeparateATI " , ( void * * ) & pglStencilOpSeparate } ,
{ " glStencilFuncSeparateATI " , ( void * * ) & pglStencilFuncSeparate } ,
{ NULL , NULL }
} ;
static dllfunc_t gl2separatestencilfuncs [ ] =
{
{ " glStencilOpSeparate " , ( void * * ) & pglStencilOpSeparate } ,
{ " glStencilFuncSeparate " , ( void * * ) & pglStencilFuncSeparate } ,
{ NULL , NULL }
} ;
static dllfunc_t stenciltwosidefuncs [ ] =
{
{ " glActiveStencilFaceEXT " , ( void * * ) & pglActiveStencilFaceEXT } ,
{ NULL , NULL }
} ;
static dllfunc_t blendequationfuncs [ ] =
{
{ " glBlendEquationEXT " , ( void * * ) & pglBlendEquationEXT } ,
{ NULL , NULL }
} ;
static dllfunc_t shaderobjectsfuncs [ ] =
{
{ " glDeleteObjectARB " , ( void * * ) & pglDeleteObjectARB } ,
{ " glGetHandleARB " , ( void * * ) & pglGetHandleARB } ,
{ " glDetachObjectARB " , ( void * * ) & pglDetachObjectARB } ,
{ " glCreateShaderObjectARB " , ( void * * ) & pglCreateShaderObjectARB } ,
{ " glShaderSourceARB " , ( void * * ) & pglShaderSourceARB } ,
{ " glCompileShaderARB " , ( void * * ) & pglCompileShaderARB } ,
{ " glCreateProgramObjectARB " , ( void * * ) & pglCreateProgramObjectARB } ,
{ " glAttachObjectARB " , ( void * * ) & pglAttachObjectARB } ,
{ " glLinkProgramARB " , ( void * * ) & pglLinkProgramARB } ,
{ " glUseProgramObjectARB " , ( void * * ) & pglUseProgramObjectARB } ,
{ " glValidateProgramARB " , ( void * * ) & pglValidateProgramARB } ,
{ " glUniform1fARB " , ( void * * ) & pglUniform1fARB } ,
{ " glUniform2fARB " , ( void * * ) & pglUniform2fARB } ,
{ " glUniform3fARB " , ( void * * ) & pglUniform3fARB } ,
{ " glUniform4fARB " , ( void * * ) & pglUniform4fARB } ,
{ " glUniform1iARB " , ( void * * ) & pglUniform1iARB } ,
{ " glUniform2iARB " , ( void * * ) & pglUniform2iARB } ,
{ " glUniform3iARB " , ( void * * ) & pglUniform3iARB } ,
{ " glUniform4iARB " , ( void * * ) & pglUniform4iARB } ,
{ " glUniform1fvARB " , ( void * * ) & pglUniform1fvARB } ,
{ " glUniform2fvARB " , ( void * * ) & pglUniform2fvARB } ,
{ " glUniform3fvARB " , ( void * * ) & pglUniform3fvARB } ,
{ " glUniform4fvARB " , ( void * * ) & pglUniform4fvARB } ,
{ " glUniform1ivARB " , ( void * * ) & pglUniform1ivARB } ,
{ " glUniform2ivARB " , ( void * * ) & pglUniform2ivARB } ,
{ " glUniform3ivARB " , ( void * * ) & pglUniform3ivARB } ,
{ " glUniform4ivARB " , ( void * * ) & pglUniform4ivARB } ,
{ " glUniformMatrix2fvARB " , ( void * * ) & pglUniformMatrix2fvARB } ,
{ " glUniformMatrix3fvARB " , ( void * * ) & pglUniformMatrix3fvARB } ,
{ " glUniformMatrix4fvARB " , ( void * * ) & pglUniformMatrix4fvARB } ,
{ " glGetObjectParameterfvARB " , ( void * * ) & pglGetObjectParameterfvARB } ,
{ " glGetObjectParameterivARB " , ( void * * ) & pglGetObjectParameterivARB } ,
{ " glGetInfoLogARB " , ( void * * ) & pglGetInfoLogARB } ,
{ " glGetAttachedObjectsARB " , ( void * * ) & pglGetAttachedObjectsARB } ,
{ " glGetUniformLocationARB " , ( void * * ) & pglGetUniformLocationARB } ,
2012-12-23 21:00:00 +01:00
{ " glGetActiveUniformARB " , ( void * * ) & pglGetActiveUniformARB } ,
2010-11-28 22:00:00 +01:00
{ " glGetUniformfvARB " , ( void * * ) & pglGetUniformfvARB } ,
{ " glGetUniformivARB " , ( void * * ) & pglGetUniformivARB } ,
{ " glGetShaderSourceARB " , ( void * * ) & pglGetShaderSourceARB } ,
{ " glVertexAttribPointerARB " , ( void * * ) & pglVertexAttribPointerARB } ,
{ " glEnableVertexAttribArrayARB " , ( void * * ) & pglEnableVertexAttribArrayARB } ,
{ " glDisableVertexAttribArrayARB " , ( void * * ) & pglDisableVertexAttribArrayARB } ,
{ " glBindAttribLocationARB " , ( void * * ) & pglBindAttribLocationARB } ,
{ " glGetActiveAttribARB " , ( void * * ) & pglGetActiveAttribARB } ,
{ " glGetAttribLocationARB " , ( void * * ) & pglGetAttribLocationARB } ,
{ NULL , NULL }
} ;
static dllfunc_t vertexshaderfuncs [ ] =
{
{ " glVertexAttribPointerARB " , ( void * * ) & pglVertexAttribPointerARB } ,
{ " glEnableVertexAttribArrayARB " , ( void * * ) & pglEnableVertexAttribArrayARB } ,
{ " glDisableVertexAttribArrayARB " , ( void * * ) & pglDisableVertexAttribArrayARB } ,
{ " glBindAttribLocationARB " , ( void * * ) & pglBindAttribLocationARB } ,
{ " glGetActiveAttribARB " , ( void * * ) & pglGetActiveAttribARB } ,
{ " glGetAttribLocationARB " , ( void * * ) & pglGetAttribLocationARB } ,
{ NULL , NULL }
} ;
static dllfunc_t vbofuncs [ ] =
{
{ " glBindBufferARB " , ( void * * ) & pglBindBufferARB } ,
{ " glDeleteBuffersARB " , ( void * * ) & pglDeleteBuffersARB } ,
{ " glGenBuffersARB " , ( void * * ) & pglGenBuffersARB } ,
{ " glIsBufferARB " , ( void * * ) & pglIsBufferARB } ,
{ " glMapBufferARB " , ( void * * ) & pglMapBufferARB } ,
{ " glUnmapBufferARB " , ( void * * ) & pglUnmapBufferARB } ,
{ " glBufferDataARB " , ( void * * ) & pglBufferDataARB } ,
{ " glBufferSubDataARB " , ( void * * ) & pglBufferSubDataARB } ,
{ NULL , NULL }
} ;
static dllfunc_t occlusionfunc [ ] =
{
{ " glGenQueriesARB " , ( void * * ) & pglGenQueriesARB } ,
{ " glDeleteQueriesARB " , ( void * * ) & pglDeleteQueriesARB } ,
{ " glIsQueryARB " , ( void * * ) & pglIsQueryARB } ,
{ " glBeginQueryARB " , ( void * * ) & pglBeginQueryARB } ,
{ " glEndQueryARB " , ( void * * ) & pglEndQueryARB } ,
{ " glGetQueryivARB " , ( void * * ) & pglGetQueryivARB } ,
{ " glGetQueryObjectivARB " , ( void * * ) & pglGetQueryObjectivARB } ,
{ " glGetQueryObjectuivARB " , ( void * * ) & pglGetQueryObjectuivARB } ,
{ NULL , NULL }
} ;
static dllfunc_t texturecompressionfuncs [ ] =
{
{ " glCompressedTexImage3DARB " , ( void * * ) & pglCompressedTexImage3DARB } ,
{ " glCompressedTexImage2DARB " , ( void * * ) & pglCompressedTexImage2DARB } ,
{ " glCompressedTexImage1DARB " , ( void * * ) & pglCompressedTexImage1DARB } ,
{ " glCompressedTexSubImage3DARB " , ( void * * ) & pglCompressedTexSubImage3DARB } ,
{ " glCompressedTexSubImage2DARB " , ( void * * ) & pglCompressedTexSubImage2DARB } ,
{ " glCompressedTexSubImage1DARB " , ( void * * ) & pglCompressedTexSubImage1DARB } ,
{ " glGetCompressedTexImageARB " , ( void * * ) & pglGetCompressedTexImage } ,
{ NULL , NULL }
} ;
static dllfunc_t wgl_funcs [ ] =
{
{ " wglSwapBuffers " , ( void * * ) & pwglSwapBuffers } ,
{ " wglCreateContext " , ( void * * ) & pwglCreateContext } ,
{ " wglDeleteContext " , ( void * * ) & pwglDeleteContext } ,
{ " wglMakeCurrent " , ( void * * ) & pwglMakeCurrent } ,
{ " wglGetCurrentContext " , ( void * * ) & pwglGetCurrentContext } ,
{ NULL , NULL }
} ;
2011-07-07 22:00:00 +02:00
static dllfunc_t wglproc_funcs [ ] =
{
{ " wglGetProcAddress " , ( void * * ) & pwglGetProcAddress } ,
{ NULL , NULL }
} ;
2010-11-28 22:00:00 +01:00
static dllfunc_t wglswapintervalfuncs [ ] =
{
{ " wglSwapIntervalEXT " , ( void * * ) & pwglSwapIntervalEXT } ,
{ NULL , NULL }
} ;
2011-03-11 22:00:00 +01:00
dll_info_t opengl_dll = { " opengl32.dll " , wgl_funcs , true } ;
2010-11-28 22:00:00 +01:00
/*
= = = = = = = = = = = = = = = = =
GL_SetExtension
= = = = = = = = = = = = = = = = =
*/
void GL_SetExtension ( int r_ext , int enable )
{
if ( r_ext > = 0 & & r_ext < GL_EXTCOUNT )
glConfig . extension [ r_ext ] = enable ? GL_TRUE : GL_FALSE ;
else MsgDev ( D_ERROR , " GL_SetExtension: invalid extension %d \n " , r_ext ) ;
}
/*
= = = = = = = = = = = = = = = = =
GL_Support
= = = = = = = = = = = = = = = = =
*/
qboolean GL_Support ( int r_ext )
{
if ( r_ext > = 0 & & r_ext < GL_EXTCOUNT )
return glConfig . extension [ r_ext ] ? true : false ;
MsgDev ( D_ERROR , " GL_Support: invalid extension %d \n " , r_ext ) ;
2012-12-23 21:00:00 +01:00
2010-11-28 22:00:00 +01:00
return false ;
}
2013-12-01 21:00:00 +01:00
/*
= = = = = = = = = = = = = = = = =
GL_MaxTextureUnits
= = = = = = = = = = = = = = = = =
*/
int GL_MaxTextureUnits ( void )
{
if ( GL_Support ( GL_SHADER_GLSL100_EXT ) )
return max ( min ( glConfig . max_texture_coords , glConfig . max_teximage_units ) , MAX_TEXTURE_UNITS ) ;
return glConfig . max_texture_units ;
}
2010-11-28 22:00:00 +01:00
/*
= = = = = = = = = = = = = = = = =
GL_GetProcAddress
= = = = = = = = = = = = = = = = =
*/
void * GL_GetProcAddress ( const char * name )
{
void * p = NULL ;
if ( pwglGetProcAddress ! = NULL )
p = ( void * ) pwglGetProcAddress ( name ) ;
if ( ! p ) p = ( void * ) Sys_GetProcAddress ( & opengl_dll , name ) ;
return p ;
}
/*
= = = = = = = = = = = = = = = = =
GL_CheckExtension
= = = = = = = = = = = = = = = = =
*/
void GL_CheckExtension ( const char * name , const dllfunc_t * funcs , const char * cvarname , int r_ext )
{
const dllfunc_t * func ;
convar_t * parm ;
MsgDev ( D_NOTE , " GL_CheckExtension: %s " , name ) ;
if ( cvarname )
{
// system config disable extensions
2010-12-27 22:00:00 +01:00
parm = Cvar_Get ( cvarname , " 1 " , CVAR_GLCONFIG , va ( " enable or disable %s " , name ) ) ;
if ( parm - > integer = = 0 | | ( gl_extensions - > integer = = 0 & & r_ext ! = GL_OPENGL_110 ) )
2010-11-28 22:00:00 +01:00
{
2010-12-06 22:00:00 +01:00
MsgDev ( D_NOTE , " - disabled \n " ) ;
2010-12-27 22:00:00 +01:00
GL_SetExtension ( r_ext , 0 ) ;
2010-11-28 22:00:00 +01:00
return ; // nothing to process at
}
2010-12-27 22:00:00 +01:00
GL_SetExtension ( r_ext , 1 ) ;
2010-11-28 22:00:00 +01:00
}
2011-03-09 22:00:00 +01:00
if ( ( name [ 2 ] = = ' _ ' | | name [ 3 ] = = ' _ ' ) & & ! Q_strstr ( glConfig . extensions_string , name ) )
2010-11-28 22:00:00 +01:00
{
GL_SetExtension ( r_ext , false ) ; // update render info
2011-07-07 22:00:00 +02:00
MsgDev ( D_NOTE , " - ^1failed \n " ) ;
2010-11-28 22:00:00 +01:00
return ;
}
// clear exports
for ( func = funcs ; func & & func - > name ; func + + )
* func - > func = NULL ;
GL_SetExtension ( r_ext , true ) ; // predict extension state
for ( func = funcs ; func & & func - > name ! = NULL ; func + + )
{
// functions are cleared before all the extensions are evaluated
if ( ! ( * func - > func = ( void * ) GL_GetProcAddress ( func - > name ) ) )
GL_SetExtension ( r_ext , false ) ; // one or more functions are invalid, extension will be disabled
}
if ( GL_Support ( r_ext ) )
2011-07-07 22:00:00 +02:00
MsgDev ( D_NOTE , " - ^2enabled \n " ) ;
2012-08-03 22:00:00 +02:00
else MsgDev ( D_NOTE , " - ^1failed \n " ) ;
2010-11-28 22:00:00 +01:00
}
/*
= = = = = = = = = = = = = = =
GL_BuildGammaTable
= = = = = = = = = = = = = = =
*/
void GL_BuildGammaTable ( void )
{
int i , v ;
double invGamma , div ;
2011-10-06 22:00:00 +02:00
invGamma = 1.0 / bound ( 0.5 , vid_gamma - > value , 2.3 ) ;
2010-11-28 22:00:00 +01:00
div = ( double ) 1.0 / 255.5 ;
2011-03-10 22:00:00 +01:00
Q_memcpy ( glState . gammaRamp , glState . stateRamp , sizeof ( glState . gammaRamp ) ) ;
2010-11-28 22:00:00 +01:00
for ( i = 0 ; i < 256 ; i + + )
{
v = ( int ) ( 65535.0 * pow ( ( ( double ) i + 0.5 ) * div , invGamma ) + 0.5 ) ;
glState . gammaRamp [ i + 0 ] = ( ( word ) bound ( 0 , v , 65535 ) ) ;
glState . gammaRamp [ i + 256 ] = ( ( word ) bound ( 0 , v , 65535 ) ) ;
glState . gammaRamp [ i + 512 ] = ( ( word ) bound ( 0 , v , 65535 ) ) ;
}
}
/*
= = = = = = = = = = = = = = =
GL_UpdateGammaRamp
= = = = = = = = = = = = = = =
*/
void GL_UpdateGammaRamp ( void )
{
if ( ! glConfig . deviceSupportsGamma ) return ;
GL_BuildGammaTable ( ) ;
2011-09-19 22:00:00 +02:00
SetDeviceGammaRamp ( glw_state . hDC , glState . gammaRamp ) ;
2010-11-28 22:00:00 +01:00
}
/*
= = = = = = = = = = = = = = =
GL_UpdateSwapInterval
= = = = = = = = = = = = = = =
*/
void GL_UpdateSwapInterval ( void )
{
if ( gl_swapInterval - > modified )
{
gl_swapInterval - > modified = false ;
if ( pwglSwapIntervalEXT )
pwglSwapIntervalEXT ( gl_swapInterval - > integer ) ;
}
}
/*
= = = = = = = = = = = = = = =
GL_SetDefaultTexState
= = = = = = = = = = = = = = =
*/
static void GL_SetDefaultTexState ( void )
{
2012-12-23 21:00:00 +01:00
int i ;
2012-01-27 21:00:00 +01:00
2011-03-10 22:00:00 +01:00
Q_memset ( glState . currentTextures , - 1 , MAX_TEXTURE_UNITS * sizeof ( * glState . currentTextures ) ) ;
2013-12-07 21:00:00 +01:00
Q_memset ( glState . texCoordArrayMode , 0 , MAX_TEXTURE_UNITS * sizeof ( * glState . texCoordArrayMode ) ) ;
2011-03-10 22:00:00 +01:00
Q_memset ( glState . genSTEnabled , 0 , MAX_TEXTURE_UNITS * sizeof ( * glState . genSTEnabled ) ) ;
2012-01-27 21:00:00 +01:00
for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i + + )
{
2012-07-18 22:00:00 +02:00
glState . currentTextureTargets [ i ] = GL_NONE ;
2012-01-27 21:00:00 +01:00
glState . texIdentityMatrix [ i ] = true ;
}
2010-11-28 22:00:00 +01:00
}
/*
= = = = = = = = = = = = = = =
GL_SetDefaultState
= = = = = = = = = = = = = = =
*/
static void GL_SetDefaultState ( void )
{
2011-03-10 22:00:00 +01:00
Q_memset ( & glState , 0 , sizeof ( glState ) ) ;
2010-11-28 22:00:00 +01:00
GL_SetDefaultTexState ( ) ;
}
2010-12-21 22:00:00 +01:00
/*
= = = = = = = = = = = = = = = = =
GL_CreateContext
= = = = = = = = = = = = = = = = =
*/
qboolean GL_CreateContext ( void )
{
if ( ! ( glw_state . hGLRC = pwglCreateContext ( glw_state . hDC ) ) )
return GL_DeleteContext ( ) ;
if ( ! ( pwglMakeCurrent ( glw_state . hDC , glw_state . hGLRC ) ) )
return GL_DeleteContext ( ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = = =
GL_UpdateContext
= = = = = = = = = = = = = = = = =
*/
qboolean GL_UpdateContext ( void )
{
if ( ! ( pwglMakeCurrent ( glw_state . hDC , glw_state . hGLRC ) ) )
return GL_DeleteContext ( ) ;
return true ;
}
2010-11-28 22:00:00 +01:00
/*
= = = = = = = = = = = = = = = = =
GL_DeleteContext
= = = = = = = = = = = = = = = = =
*/
qboolean GL_DeleteContext ( void )
{
2010-12-21 22:00:00 +01:00
if ( pwglMakeCurrent )
pwglMakeCurrent ( NULL , NULL ) ;
2010-11-28 22:00:00 +01:00
if ( glw_state . hGLRC )
{
2010-12-21 22:00:00 +01:00
if ( pwglDeleteContext )
pwglDeleteContext ( glw_state . hGLRC ) ;
2010-11-28 22:00:00 +01:00
glw_state . hGLRC = NULL ;
}
if ( glw_state . hDC )
{
ReleaseDC ( host . hWnd , glw_state . hDC ) ;
glw_state . hDC = NULL ;
}
return false ;
}
/*
= = = = = = = = = = = = = = = = =
2010-12-21 22:00:00 +01:00
VID_ChoosePFD
2010-11-28 22:00:00 +01:00
= = = = = = = = = = = = = = = = =
*/
2010-12-27 22:00:00 +01:00
static int VID_ChoosePFD ( PIXELFORMATDESCRIPTOR * pfd , int colorBits , int alphaBits , int depthBits , int stencilBits )
2010-11-28 22:00:00 +01:00
{
2010-12-27 22:00:00 +01:00
int pixelFormat = 0 ;
2010-11-28 22:00:00 +01:00
2010-12-21 22:00:00 +01:00
MsgDev ( D_NOTE , " VID_ChoosePFD( color %i, alpha %i, depth %i, stencil %i ) \n " , colorBits , alphaBits , depthBits , stencilBits ) ;
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
// Fill out the PFD
pfd - > nSize = sizeof ( PIXELFORMATDESCRIPTOR ) ;
pfd - > nVersion = 1 ;
pfd - > dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ;
pfd - > iPixelType = PFD_TYPE_RGBA ;
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
pfd - > cColorBits = colorBits ;
pfd - > cRedBits = 0 ;
pfd - > cRedShift = 0 ;
pfd - > cGreenBits = 0 ;
pfd - > cGreenShift = 0 ;
pfd - > cBlueBits = 0 ;
pfd - > cBlueShift = 0 ; // wow! Blue Shift %)
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
pfd - > cAlphaBits = alphaBits ;
pfd - > cAlphaShift = 0 ;
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
pfd - > cAccumBits = 0 ;
pfd - > cAccumRedBits = 0 ;
pfd - > cAccumGreenBits = 0 ;
pfd - > cAccumBlueBits = 0 ;
pfd - > cAccumAlphaBits = 0 ;
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
pfd - > cDepthBits = depthBits ;
pfd - > cStencilBits = stencilBits ;
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
pfd - > cAuxBuffers = 0 ;
pfd - > iLayerType = PFD_MAIN_PLANE ;
pfd - > bReserved = 0 ;
2010-12-11 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
pfd - > dwLayerMask = 0 ;
pfd - > dwVisibleMask = 0 ;
pfd - > dwDamageMask = 0 ;
2010-11-28 22:00:00 +01:00
2011-02-20 22:00:00 +01:00
// count PFDs
2011-09-19 22:00:00 +02:00
pixelFormat = ChoosePixelFormat ( glw_state . hDC , pfd ) ;
2010-11-28 22:00:00 +01:00
if ( ! pixelFormat )
{
2010-12-27 22:00:00 +01:00
MsgDev ( D_ERROR , " VID_ChoosePFD failed \n " ) ;
2010-11-28 22:00:00 +01:00
return 0 ;
}
return pixelFormat ;
}
2013-02-24 21:00:00 +01:00
BOOL CALLBACK pfnEnumWnd ( HWND hwnd , LPARAM lParam )
{
string wndname ;
if ( GetClassName ( hwnd , wndname , sizeof ( wndname ) - 1 ) )
{
if ( ! Q_strcmp ( wndname , WINDOW_NAME ) )
num_instances + + ;
}
return true ;
}
uint VID_EnumerateInstances ( void )
{
num_instances = 0 ;
if ( EnumWindows ( & pfnEnumWnd , 0 ) )
return num_instances ;
return 1 ;
}
2010-12-21 22:00:00 +01:00
void VID_StartupGamma ( void )
2010-11-28 22:00:00 +01:00
{
2010-12-21 22:00:00 +01:00
size_t gamma_size ;
byte * savedGamma ;
2010-11-28 22:00:00 +01:00
2011-11-14 21:00:00 +01:00
// init gamma ramp
Q_memset ( glState . stateRamp , 0 , sizeof ( glState . stateRamp ) ) ;
2011-10-06 22:00:00 +02:00
glConfig . deviceSupportsGamma = GetDeviceGammaRamp ( glw_state . hDC , glState . stateRamp ) ;
if ( ! glConfig . deviceSupportsGamma )
{
// force to set cvar
Cvar_FullSet ( " gl_ignorehwgamma " , " 1 " , CVAR_GLCONFIG ) ;
}
if ( gl_ignorehwgamma - > integer )
{
glConfig . deviceSupportsGamma = false ; // even if supported!
BuildGammaTable ( vid_gamma - > value , vid_texgamma - > value ) ;
MsgDev ( D_NOTE , " VID_StartupGamma: software gamma initialized \n " ) ;
return ;
}
2010-11-28 22:00:00 +01:00
// share this extension so engine can grab them
GL_SetExtension ( GL_HARDWARE_GAMMA_CONTROL , glConfig . deviceSupportsGamma ) ;
2011-03-08 22:00:00 +01:00
savedGamma = FS_LoadFile ( " gamma.dat " , & gamma_size , false ) ;
2010-12-21 22:00:00 +01:00
2010-11-28 22:00:00 +01:00
if ( ! savedGamma | | gamma_size ! = sizeof ( glState . stateRamp ) )
{
// saved gamma not found or corrupted file
2010-12-21 22:00:00 +01:00
FS_WriteFile ( " gamma.dat " , glState . stateRamp , sizeof ( glState . stateRamp ) ) ;
MsgDev ( D_NOTE , " VID_StartupGamma: gamma.dat initialized \n " ) ;
2010-11-28 22:00:00 +01:00
if ( savedGamma ) Mem_Free ( savedGamma ) ;
}
else
{
GL_BuildGammaTable ( ) ;
// validate base gamma
2012-12-21 21:00:00 +01:00
if ( ! Q_memcmp ( savedGamma , glState . stateRamp , sizeof ( glState . stateRamp ) ) )
2010-11-28 22:00:00 +01:00
{
// all ok, previous gamma is valid
2010-12-21 22:00:00 +01:00
MsgDev ( D_NOTE , " VID_StartupGamma: validate screen gamma - ok \n " ) ;
2010-11-28 22:00:00 +01:00
}
2012-12-21 21:00:00 +01:00
else if ( ! Q_memcmp ( glState . gammaRamp , glState . stateRamp , sizeof ( glState . stateRamp ) ) )
2010-11-28 22:00:00 +01:00
{
// screen gamma is equal to render gamma (probably previous instance crashed)
2010-12-21 22:00:00 +01:00
// run additional check to make sure for it
2012-12-21 21:00:00 +01:00
if ( Q_memcmp ( savedGamma , glState . stateRamp , sizeof ( glState . stateRamp ) ) )
2010-11-28 22:00:00 +01:00
{
// yes, current gamma it's totally wrong, restore it from gamma.dat
2010-12-21 22:00:00 +01:00
MsgDev ( D_NOTE , " VID_StartupGamma: restore original gamma after crash \n " ) ;
2011-03-10 22:00:00 +01:00
Q_memcpy ( glState . stateRamp , savedGamma , sizeof ( glState . gammaRamp ) ) ;
2010-11-28 22:00:00 +01:00
}
else
{
// oops, savedGamma == glState.stateRamp == glState.gammaRamp
// probably r_gamma set as default
2010-12-21 22:00:00 +01:00
MsgDev ( D_NOTE , " VID_StartupGamma: validate screen gamma - disabled \n " ) ;
2010-11-28 22:00:00 +01:00
}
}
2012-12-21 21:00:00 +01:00
else if ( ! Q_memcmp ( glState . gammaRamp , savedGamma , sizeof ( glState . stateRamp ) ) )
2010-11-28 22:00:00 +01:00
{
2010-12-21 22:00:00 +01:00
// saved gamma is equal render gamma, probably gamma.dat wroted after crash
2010-11-28 22:00:00 +01:00
// run additional check to make sure it
2012-12-21 21:00:00 +01:00
if ( Q_memcmp ( savedGamma , glState . stateRamp , sizeof ( glState . stateRamp ) ) )
2010-11-28 22:00:00 +01:00
{
// yes, saved gamma it's totally wrong, get origianl gamma from screen
2010-12-21 22:00:00 +01:00
MsgDev ( D_NOTE , " VID_StartupGamma: merge gamma.dat after crash \n " ) ;
2010-11-28 22:00:00 +01:00
FS_WriteFile ( " gamma.dat " , glState . stateRamp , sizeof ( glState . stateRamp ) ) ;
}
else
{
// oops, savedGamma == glState.stateRamp == glState.gammaRamp
// probably r_gamma set as default
2010-12-21 22:00:00 +01:00
MsgDev ( D_NOTE , " VID_StartupGamma: validate screen gamma - disabled \n " ) ;
2010-11-28 22:00:00 +01:00
}
}
else
{
2010-12-21 22:00:00 +01:00
// current gamma unset by other application, so we can restore it here
MsgDev ( D_NOTE , " VID_StartupGamma: restore original gamma after crash \n " ) ;
2011-03-10 22:00:00 +01:00
Q_memcpy ( glState . stateRamp , savedGamma , sizeof ( glState . gammaRamp ) ) ;
2010-11-28 22:00:00 +01:00
}
2012-12-23 21:00:00 +01:00
2010-11-28 22:00:00 +01:00
Mem_Free ( savedGamma ) ;
}
2012-12-23 21:00:00 +01:00
2010-11-28 22:00:00 +01:00
vid_gamma - > modified = true ;
}
2010-11-29 22:00:00 +01:00
void VID_RestoreGamma ( void )
2010-11-28 22:00:00 +01:00
{
2013-02-24 21:00:00 +01:00
if ( ! glw_state . hDC | | ! glConfig . deviceSupportsGamma )
return ;
// don't touch gamma if multiple instances was running
if ( VID_EnumerateInstances ( ) > 1 ) return ;
2010-11-28 22:00:00 +01:00
SetDeviceGammaRamp ( glw_state . hDC , glState . stateRamp ) ;
}
2010-12-21 22:00:00 +01:00
/*
= = = = = = = = = = = = = = = = =
GL_SetPixelformat
= = = = = = = = = = = = = = = = =
*/
qboolean GL_SetPixelformat ( void )
2010-11-28 22:00:00 +01:00
{
2010-12-21 22:00:00 +01:00
PIXELFORMATDESCRIPTOR PFD ;
2010-12-27 22:00:00 +01:00
int alphaBits ;
int stencilBits ;
2010-12-21 22:00:00 +01:00
int pixelFormat ;
2010-11-28 22:00:00 +01:00
2011-09-19 22:00:00 +02:00
if ( ( glw_state . hDC = GetDC ( host . hWnd ) ) = = NULL )
return false ;
2010-11-28 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
// set alpha/stencil
alphaBits = bound ( 0 , gl_alphabits - > integer , 8 ) ;
stencilBits = bound ( 0 , gl_stencilbits - > integer , 8 ) ;
2010-12-21 22:00:00 +01:00
2011-09-19 22:00:00 +02:00
if ( glw_state . desktopBitsPixel < 32 )
{
// clear alphabits in case we in 16-bit mode
alphaBits = 0 ;
}
2010-12-21 22:00:00 +01:00
// choose a pixel format
2011-09-19 22:00:00 +02:00
pixelFormat = VID_ChoosePFD ( & PFD , 24 , alphaBits , 32 , stencilBits ) ;
2010-12-21 22:00:00 +01:00
if ( ! pixelFormat )
2010-11-28 22:00:00 +01:00
{
2010-12-21 22:00:00 +01:00
// try again with default color/depth/stencil
2011-09-19 22:00:00 +02:00
pixelFormat = VID_ChoosePFD ( & PFD , 24 , 0 , 32 , 0 ) ;
2010-12-21 22:00:00 +01:00
if ( ! pixelFormat )
{
MsgDev ( D_ERROR , " GL_SetPixelformat: failed to find an appropriate PIXELFORMAT \n " ) ;
return false ;
}
2010-11-28 22:00:00 +01:00
}
2010-12-21 22:00:00 +01:00
// set the pixel format
2011-09-19 22:00:00 +02:00
if ( ! SetPixelFormat ( glw_state . hDC , pixelFormat , & PFD ) )
2010-12-21 22:00:00 +01:00
{
2011-09-19 22:00:00 +02:00
MsgDev ( D_ERROR , " GL_SetPixelformat: failed \n " ) ;
return false ;
2010-12-21 22:00:00 +01:00
}
2010-12-27 22:00:00 +01:00
2011-09-19 22:00:00 +02:00
DescribePixelFormat ( glw_state . hDC , pixelFormat , sizeof ( PIXELFORMATDESCRIPTOR ) , & PFD ) ;
2010-12-27 22:00:00 +01:00
if ( PFD . dwFlags & PFD_GENERIC_FORMAT )
{
if ( PFD . dwFlags & PFD_GENERIC_ACCELERATED )
{
2012-12-23 21:00:00 +01:00
MsgDev ( D_NOTE , " VID_ChoosePFD: using Generic MCD acceleration \n " ) ;
2010-12-27 22:00:00 +01:00
glw_state . software = false ;
}
else if ( gl_allow_software - > integer )
{
MsgDev ( D_NOTE , " VID_ChoosePFD: using software emulation \n " ) ;
glw_state . software = true ;
}
else
{
MsgDev ( D_ERROR , " GL_SetPixelformat: no hardware acceleration found \n " ) ;
return false ;
}
}
else
{
MsgDev ( D_NOTE , " VID_ChoosePFD: using hardware acceleration \n " ) ;
glw_state . software = false ;
2010-11-28 22:00:00 +01:00
}
2010-12-21 22:00:00 +01:00
glConfig . color_bits = PFD . cColorBits ;
glConfig . alpha_bits = PFD . cAlphaBits ;
glConfig . depth_bits = PFD . cDepthBits ;
glConfig . stencil_bits = PFD . cStencilBits ;
2010-11-28 22:00:00 +01:00
2010-12-21 22:00:00 +01:00
if ( PFD . cStencilBits ! = 0 )
glState . stencilEnabled = true ;
else glState . stencilEnabled = false ;
// print out PFD specifics
MsgDev ( D_NOTE , " GL PFD: color( %d-bits ) alpha( %d-bits ) Z( %d-bit ) \n " , PFD . cColorBits , PFD . cAlphaBits , PFD . cDepthBits ) ;
return true ;
2010-11-28 22:00:00 +01:00
}
void R_SaveVideoMode ( int vid_mode )
{
int mode = bound ( 0 , vid_mode , num_vidmodes ) ; // check range
glState . width = vidmode [ mode ] . width ;
glState . height = vidmode [ mode ] . height ;
glState . wideScreen = vidmode [ mode ] . wideScreen ;
Cvar_FullSet ( " width " , va ( " %i " , vidmode [ mode ] . width ) , CVAR_READ_ONLY ) ;
Cvar_FullSet ( " height " , va ( " %i " , vidmode [ mode ] . height ) , CVAR_READ_ONLY ) ;
2010-12-21 22:00:00 +01:00
Cvar_SetFloat ( " vid_mode " , mode ) ; // merge if it out of bounds
2010-11-28 22:00:00 +01:00
MsgDev ( D_NOTE , " Set: %s [%dx%d] \n " , vidmode [ mode ] . desc , vidmode [ mode ] . width , vidmode [ mode ] . height ) ;
}
2011-03-20 22:00:00 +01:00
qboolean R_DescribeVIDMode ( int width , int height )
{
int i ;
for ( i = 0 ; i < sizeof ( vidmode ) / sizeof ( vidmode [ 0 ] ) ; i + + )
{
if ( vidmode [ i ] . width = = width & & vidmode [ i ] . height = = height )
{
// found specified mode
Cvar_SetFloat ( " vid_mode " , i ) ;
return true ;
}
}
2012-12-23 21:00:00 +01:00
2011-03-20 22:00:00 +01:00
return false ;
}
2010-11-28 22:00:00 +01:00
qboolean VID_CreateWindow ( int width , int height , qboolean fullscreen )
{
WNDCLASS wc ;
RECT rect ;
int x = 0 , y = 0 , w , h ;
int stylebits = WINDOW_STYLE ;
int exstyle = WINDOW_EX_STYLE ;
static string wndname ;
2011-09-19 22:00:00 +02:00
HWND window ;
2010-11-28 22:00:00 +01:00
2012-12-23 21:00:00 +01:00
Q_strncpy ( wndname , GI - > title , sizeof ( wndname ) ) ;
2010-11-28 22:00:00 +01:00
// register the frame class
wc . style = CS_OWNDC | CS_NOCLOSE ;
wc . lpfnWndProc = ( WNDPROC ) IN_WndProc ;
wc . cbClsExtra = 0 ;
wc . cbWndExtra = 0 ;
wc . hInstance = host . hInst ;
wc . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
wc . hbrBackground = ( void * ) COLOR_3DSHADOW ;
2011-02-05 22:00:00 +01:00
wc . lpszClassName = WINDOW_NAME ;
2010-11-28 22:00:00 +01:00
wc . lpszMenuName = 0 ;
// find the icon file in the filesystem
2011-10-01 22:00:00 +02:00
if ( FS_FileExists ( GI - > iconpath , true ) )
2010-11-28 22:00:00 +01:00
{
char localPath [ MAX_PATH ] ;
2011-10-01 22:00:00 +02:00
Q_snprintf ( localPath , sizeof ( localPath ) , " %s/%s " , GI - > gamedir , GI - > iconpath ) ;
2010-11-28 22:00:00 +01:00
wc . hIcon = LoadImage ( NULL , localPath , IMAGE_ICON , 0 , 0 , LR_LOADFROMFILE | LR_DEFAULTSIZE ) ;
2010-12-21 22:00:00 +01:00
2010-11-28 22:00:00 +01:00
if ( ! wc . hIcon )
{
2011-10-01 22:00:00 +02:00
MsgDev ( D_INFO , " Extract %s from pak if you want to see it. \n " , GI - > iconpath ) ;
2010-11-28 22:00:00 +01:00
wc . hIcon = LoadIcon ( host . hInst , MAKEINTRESOURCE ( 101 ) ) ;
}
}
else wc . hIcon = LoadIcon ( host . hInst , MAKEINTRESOURCE ( 101 ) ) ;
if ( ! RegisterClass ( & wc ) )
{
2011-02-05 22:00:00 +01:00
MsgDev ( D_ERROR , " VID_CreateWindow: couldn't register window class %s \n " WINDOW_NAME ) ;
2010-11-28 22:00:00 +01:00
return false ;
}
if ( fullscreen )
{
stylebits = WS_POPUP | WS_VISIBLE ;
exstyle = WS_EX_TOPMOST ;
}
rect . left = 0 ;
rect . top = 0 ;
rect . right = width ;
rect . bottom = height ;
AdjustWindowRect ( & rect , stylebits , FALSE ) ;
w = rect . right - rect . left ;
h = rect . bottom - rect . top ;
if ( ! fullscreen )
{
x = r_xpos - > integer ;
y = r_ypos - > integer ;
// adjust window coordinates if necessary
// so that the window is completely on screen
if ( x < 0 ) x = 0 ;
if ( y < 0 ) y = 0 ;
if ( Cvar_VariableInteger ( " vid_mode " ) ! = glConfig . prev_mode )
{
2010-12-21 22:00:00 +01:00
// adjust window in the screen size
2010-11-28 22:00:00 +01:00
if ( ( x + w > glw_state . desktopWidth ) | | ( y + h > glw_state . desktopHeight ) )
{
x = ( glw_state . desktopWidth - w ) / 2 ;
y = ( glw_state . desktopHeight - h ) / 2 ;
}
}
}
2011-09-19 22:00:00 +02:00
window = CreateWindowEx ( exstyle , WINDOW_NAME , wndname , stylebits , x , y , w , h , NULL , NULL , host . hInst , NULL ) ;
if ( host . hWnd ! = window )
{
// probably never happens
MsgDev ( D_WARN , " VID_CreateWindow: bad hWnd for '%s' \n " , wndname ) ;
}
2010-11-28 22:00:00 +01:00
2011-04-10 22:00:00 +02:00
// host.hWnd must be filled in IN_WndProc
2010-11-28 22:00:00 +01:00
if ( ! host . hWnd )
{
MsgDev ( D_ERROR , " VID_CreateWindow: couldn't create '%s' \n " , wndname ) ;
return false ;
}
2010-12-27 22:00:00 +01:00
2010-11-28 22:00:00 +01:00
ShowWindow ( host . hWnd , SW_SHOW ) ;
UpdateWindow ( host . hWnd ) ;
// init all the gl stuff for the window
if ( ! GL_SetPixelformat ( ) )
{
ShowWindow ( host . hWnd , SW_HIDE ) ;
DestroyWindow ( host . hWnd ) ;
host . hWnd = NULL ;
2011-02-05 22:00:00 +01:00
UnregisterClass ( WINDOW_NAME , host . hInst ) ;
2010-11-28 22:00:00 +01:00
MsgDev ( D_ERROR , " OpenGL driver not installed \n " ) ;
2012-12-23 21:00:00 +01:00
2010-11-28 22:00:00 +01:00
return false ;
}
2010-12-21 22:00:00 +01:00
if ( ! glw_state . initialized )
{
if ( ! GL_CreateContext ( ) )
return false ;
VID_StartupGamma ( ) ;
}
else
{
if ( ! GL_UpdateContext ( ) )
return false ;
}
2010-11-28 22:00:00 +01:00
SetForegroundWindow ( host . hWnd ) ;
SetFocus ( host . hWnd ) ;
return true ;
}
2010-12-21 22:00:00 +01:00
void VID_DestroyWindow ( void )
{
if ( pwglMakeCurrent )
pwglMakeCurrent ( NULL , NULL ) ;
if ( glw_state . hDC )
{
ReleaseDC ( host . hWnd , glw_state . hDC ) ;
glw_state . hDC = NULL ;
}
if ( host . hWnd )
{
DestroyWindow ( host . hWnd ) ;
host . hWnd = NULL ;
}
2011-02-05 22:00:00 +01:00
UnregisterClass ( WINDOW_NAME , host . hInst ) ;
2010-12-21 22:00:00 +01:00
if ( glState . fullScreen )
{
ChangeDisplaySettings ( 0 , 0 ) ;
glState . fullScreen = false ;
}
}
2010-11-28 22:00:00 +01:00
rserr_t R_ChangeDisplaySettings ( int vid_mode , qboolean fullscreen )
{
int width , height ;
HDC hDC ;
R_SaveVideoMode ( vid_mode ) ;
width = r_width - > integer ;
height = r_height - > integer ;
// check our desktop attributes
hDC = GetDC ( GetDesktopWindow ( ) ) ;
glw_state . desktopBitsPixel = GetDeviceCaps ( hDC , BITSPIXEL ) ;
glw_state . desktopWidth = GetDeviceCaps ( hDC , HORZRES ) ;
glw_state . desktopHeight = GetDeviceCaps ( hDC , VERTRES ) ;
ReleaseDC ( GetDesktopWindow ( ) , hDC ) ;
// destroy the existing window
2010-12-21 22:00:00 +01:00
if ( host . hWnd ) VID_DestroyWindow ( ) ;
2010-11-28 22:00:00 +01:00
// do a CDS if needed
if ( fullscreen )
{
DEVMODE dm ;
2011-03-10 22:00:00 +01:00
Q_memset ( & dm , 0 , sizeof ( dm ) ) ;
2010-11-28 22:00:00 +01:00
dm . dmSize = sizeof ( dm ) ;
dm . dmPelsWidth = width ;
dm . dmPelsHeight = height ;
dm . dmFields = DM_PELSWIDTH | DM_PELSHEIGHT ;
if ( vid_displayfrequency - > integer > 0 )
{
2010-12-27 22:00:00 +01:00
if ( vid_displayfrequency - > integer < 60 ) Cvar_SetFloat ( " vid_displayfrequency " , 60 ) ;
if ( vid_displayfrequency - > integer > 100 ) Cvar_SetFloat ( " vid_displayfrequency " , 100 ) ;
2010-11-28 22:00:00 +01:00
dm . dmFields | = DM_DISPLAYFREQUENCY ;
dm . dmDisplayFrequency = vid_displayfrequency - > integer ;
}
if ( ChangeDisplaySettings ( & dm , CDS_FULLSCREEN ) = = DISP_CHANGE_SUCCESSFUL )
{
glState . fullScreen = true ;
if ( ! VID_CreateWindow ( width , height , true ) )
return rserr_invalid_mode ;
return rserr_ok ;
}
else
{
dm . dmPelsWidth = width * 2 ;
dm . dmPelsHeight = height ;
dm . dmFields = DM_PELSWIDTH | DM_PELSHEIGHT ;
2010-12-27 22:00:00 +01:00
dm . dmBitsPerPel = 24 ;
dm . dmFields | = DM_BITSPERPEL ;
2010-11-28 22:00:00 +01:00
// our first CDS failed, so maybe we're running on some weird dual monitor system
if ( ChangeDisplaySettings ( & dm , CDS_FULLSCREEN ) ! = DISP_CHANGE_SUCCESSFUL )
{
ChangeDisplaySettings ( 0 , 0 ) ;
glState . fullScreen = false ;
if ( ! VID_CreateWindow ( width , height , false ) )
return rserr_invalid_mode ;
return rserr_invalid_fullscreen ;
}
else
{
if ( ! VID_CreateWindow ( width , height , true ) )
return rserr_invalid_mode ;
glState . fullScreen = true ;
return rserr_ok ;
}
}
}
else
{
ChangeDisplaySettings ( 0 , 0 ) ;
glState . fullScreen = false ;
if ( ! VID_CreateWindow ( width , height , false ) )
return rserr_invalid_mode ;
}
return rserr_ok ;
}
/*
= = = = = = = = = = = = = = = = = =
2010-12-21 22:00:00 +01:00
VID_SetMode
Set the described video mode
2010-11-28 22:00:00 +01:00
= = = = = = = = = = = = = = = = = =
*/
2010-12-21 22:00:00 +01:00
qboolean VID_SetMode ( void )
2010-11-28 22:00:00 +01:00
{
qboolean fullscreen ;
2012-12-23 21:00:00 +01:00
rserr_t err ;
2010-11-28 22:00:00 +01:00
fullscreen = vid_fullscreen - > integer ;
2011-12-04 21:00:00 +01:00
gl_swapInterval - > modified = true ;
2010-11-28 22:00:00 +01:00
if ( ( err = R_ChangeDisplaySettings ( vid_mode - > integer , fullscreen ) ) = = rserr_ok )
{
glConfig . prev_mode = vid_mode - > integer ;
}
else
{
if ( err = = rserr_invalid_fullscreen )
{
Cvar_SetFloat ( " fullscreen " , 0 ) ;
2010-12-21 22:00:00 +01:00
MsgDev ( D_ERROR , " VID_SetMode: fullscreen unavailable in this mode \n " ) ;
2010-11-28 22:00:00 +01:00
if ( ( err = R_ChangeDisplaySettings ( vid_mode - > integer , false ) ) = = rserr_ok )
return true ;
}
else if ( err = = rserr_invalid_mode )
{
Cvar_SetFloat ( " vid_mode " , glConfig . prev_mode ) ;
2010-12-21 22:00:00 +01:00
MsgDev ( D_ERROR , " VID_SetMode: invalid mode \n " ) ;
2010-11-28 22:00:00 +01:00
}
// try setting it back to something safe
if ( ( err = R_ChangeDisplaySettings ( glConfig . prev_mode , false ) ) ! = rserr_ok )
{
2010-12-21 22:00:00 +01:00
MsgDev ( D_ERROR , " VID_SetMode: could not revert to safe mode \n " ) ;
2010-11-28 22:00:00 +01:00
return false ;
}
}
2012-12-23 21:00:00 +01:00
2010-11-28 22:00:00 +01:00
return true ;
}
2010-12-21 22:00:00 +01:00
/*
= = = = = = = = = = = = = = = = = =
VID_CheckChanges
check vid modes and fullscreen
= = = = = = = = = = = = = = = = = =
*/
void VID_CheckChanges ( void )
{
2011-09-03 22:00:00 +02:00
if ( cl_allow_levelshots - > modified )
{
GL_FreeTexture ( cls . loadingBar ) ;
2012-12-23 21:00:00 +01:00
SCR_RegisterTextures ( ) ; // reload 'lambda' image
2011-09-03 22:00:00 +02:00
cl_allow_levelshots - > modified = false ;
}
2010-12-27 22:00:00 +01:00
if ( renderinfo - > modified )
2010-12-21 22:00:00 +01:00
{
if ( ! VID_SetMode ( ) )
{
// can't initialize video subsystem
2011-03-12 22:00:00 +01:00
Host_NewInstance ( va ( " #%s " , GI - > gamefolder ) , " fallback to dedicated mode \n " ) ;
2010-12-21 22:00:00 +01:00
}
else
{
2010-12-27 22:00:00 +01:00
renderinfo - > modified = false ;
2010-12-21 22:00:00 +01:00
SCR_VidInit ( ) ; // tell the client.dll what vid_mode has changed
}
}
}
/*
= = = = = = = = = = = = = = = = = =
R_Init_OpenGL
= = = = = = = = = = = = = = = = = =
*/
qboolean R_Init_OpenGL ( void )
{
2011-03-11 22:00:00 +01:00
Sys_LoadLibrary ( & opengl_dll ) ; // load opengl32.dll
2010-12-21 22:00:00 +01:00
2011-09-19 22:00:00 +02:00
if ( ! opengl_dll . link )
return false ;
2010-12-21 22:00:00 +01:00
return VID_SetMode ( ) ;
}
/*
= = = = = = = = = = = = = = = = = =
R_Free_OpenGL
= = = = = = = = = = = = = = = = = =
*/
void R_Free_OpenGL ( void )
{
VID_RestoreGamma ( ) ;
2012-06-25 22:00:00 +02:00
GL_DeleteContext ( ) ;
2010-12-21 22:00:00 +01:00
VID_DestroyWindow ( ) ;
Sys_FreeLibrary ( & opengl_dll ) ;
// now all extensions are disabled
2011-03-10 22:00:00 +01:00
Q_memset ( glConfig . extension , 0 , sizeof ( glConfig . extension [ 0 ] ) * GL_EXTCOUNT ) ;
2010-12-21 22:00:00 +01:00
glw_state . initialized = false ;
}
2010-11-28 22:00:00 +01:00
/*
= = = = = = = = = = = = = = =
GL_SetDefaults
= = = = = = = = = = = = = = =
*/
static void GL_SetDefaults ( void )
{
int i ;
pglFinish ( ) ;
2010-12-22 22:00:00 +01:00
pglClearColor ( 0.5f , 0.5f , 0.5f , 1.0f ) ;
2010-11-28 22:00:00 +01:00
2011-02-25 22:00:00 +01:00
pglDisable ( GL_DEPTH_TEST ) ;
2010-11-28 22:00:00 +01:00
pglDisable ( GL_CULL_FACE ) ;
pglEnable ( GL_SCISSOR_TEST ) ;
pglDepthFunc ( GL_LEQUAL ) ;
pglDepthMask ( GL_FALSE ) ;
2012-12-23 21:00:00 +01:00
pglColor4f ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
2010-11-28 22:00:00 +01:00
if ( glState . stencilEnabled )
{
pglDisable ( GL_STENCIL_TEST ) ;
pglStencilMask ( ( GLuint ) ~ 0 ) ;
2011-08-14 22:00:00 +02:00
pglStencilFunc ( GL_EQUAL , 0 , ~ 0 ) ;
pglStencilOp ( GL_KEEP , GL_INCR , GL_INCR ) ;
2010-11-28 22:00:00 +01:00
}
pglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
2012-12-23 21:00:00 +01:00
pglPolygonOffset ( - 1.0f , - 2.0f ) ;
2010-11-28 22:00:00 +01:00
// properly disable multitexturing at startup
2013-12-01 21:00:00 +01:00
for ( i = ( MAX_TEXTURE_UNITS - 1 ) ; i > 0 ; i - - )
2010-11-28 22:00:00 +01:00
{
2013-12-01 21:00:00 +01:00
if ( i > = GL_MaxTextureUnits ( ) )
continue ;
2010-11-28 22:00:00 +01:00
GL_SelectTexture ( i ) ;
2011-02-25 22:00:00 +01:00
pglTexEnvi ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
2010-11-28 22:00:00 +01:00
pglDisable ( GL_BLEND ) ;
pglDisable ( GL_TEXTURE_2D ) ;
}
GL_SelectTexture ( 0 ) ;
pglDisable ( GL_BLEND ) ;
pglDisable ( GL_ALPHA_TEST ) ;
pglDisable ( GL_POLYGON_OFFSET_FILL ) ;
2011-03-23 22:00:00 +01:00
pglAlphaFunc ( GL_GREATER , 0.0f ) ;
2010-11-28 22:00:00 +01:00
pglEnable ( GL_TEXTURE_2D ) ;
2011-02-25 22:00:00 +01:00
pglShadeModel ( GL_FLAT ) ;
2010-11-28 22:00:00 +01:00
2012-06-25 22:00:00 +02:00
pglPointSize ( 1.2f ) ;
pglLineWidth ( 1.2f ) ;
2010-11-28 22:00:00 +01:00
GL_Cull ( 0 ) ;
GL_FrontFace ( 0 ) ;
2010-12-02 22:00:00 +01:00
R_SetTextureParameters ( ) ;
2010-11-28 22:00:00 +01:00
pglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_LINEAR ) ;
pglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
pglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_REPEAT ) ;
pglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_REPEAT ) ;
}
/*
= = = = = = = = = = = = = = = = =
R_RenderInfo_f
= = = = = = = = = = = = = = = = =
*/
void R_RenderInfo_f ( void )
{
Msg ( " \n " ) ;
Msg ( " GL_VENDOR: %s \n " , glConfig . vendor_string ) ;
Msg ( " GL_RENDERER: %s \n " , glConfig . renderer_string ) ;
Msg ( " GL_VERSION: %s \n " , glConfig . version_string ) ;
Msg ( " GL_EXTENSIONS: %s \n " , glConfig . extensions_string ) ;
Msg ( " GL_MAX_TEXTURE_SIZE: %i \n " , glConfig . max_2d_texture_size ) ;
if ( GL_Support ( GL_ARB_MULTITEXTURE ) )
Msg ( " GL_MAX_TEXTURE_UNITS_ARB: %i \n " , glConfig . max_texture_units ) ;
if ( GL_Support ( GL_TEXTURECUBEMAP_EXT ) )
2010-11-29 22:00:00 +01:00
Msg ( " GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: %i \n " , glConfig . max_cubemap_size ) ;
2010-11-28 22:00:00 +01:00
if ( GL_Support ( GL_ANISOTROPY_EXT ) )
Msg ( " GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: %.1f \n " , glConfig . max_texture_anisotropy ) ;
if ( glConfig . texRectangle )
Msg ( " GL_MAX_RECTANGLE_TEXTURE_SIZE_NV: %i \n " , glConfig . max_2d_rectangle_size ) ;
2013-12-01 21:00:00 +01:00
if ( GL_Support ( GL_SHADER_GLSL100_EXT ) )
{
Msg ( " GL_MAX_TEXTURE_COORDS_ARB: %i \n " , glConfig . max_texture_coords ) ;
Msg ( " GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %i \n " , glConfig . max_teximage_units ) ;
}
2010-11-28 22:00:00 +01:00
Msg ( " \n " ) ;
Msg ( " MODE: %i, %i x %i %s \n " , vid_mode - > integer , r_width - > integer , r_height - > integer ) ;
Msg ( " GAMMA: %s \n " , ( glConfig . deviceSupportsGamma ) ? " hardware " : " software " ) ;
Msg ( " \n " ) ;
Msg ( " PICMIP: %i \n " , gl_picmip - > integer ) ;
2010-11-29 22:00:00 +01:00
Msg ( " SKYMIP: %i \n " , gl_skymip - > integer ) ;
2010-11-28 22:00:00 +01:00
Msg ( " TEXTUREMODE: %s \n " , gl_texturemode - > string ) ;
Msg ( " VERTICAL SYNC: %s \n " , gl_swapInterval - > integer ? " enabled " : " disabled " ) ;
2010-12-11 22:00:00 +01:00
Msg ( " Color %d bits, Alpha %d bits, Depth %d bits, Stencil %d bits \n " , glConfig . color_bits ,
glConfig . alpha_bits , glConfig . depth_bits , glConfig . stencil_bits ) ;
2010-11-28 22:00:00 +01:00
}
//=======================================================================
void GL_InitCommands ( void )
{
Cbuf_AddText ( " vidlatch \n " ) ;
Cbuf_Execute ( ) ;
// system screen width and height (don't suppose for change from console at all)
r_width = Cvar_Get ( " width " , " 640 " , CVAR_READ_ONLY , " screen width " ) ;
r_height = Cvar_Get ( " height " , " 480 " , CVAR_READ_ONLY , " screen height " ) ;
2010-12-27 22:00:00 +01:00
renderinfo = Cvar_Get ( " @renderinfo " , " 0 " , CVAR_READ_ONLY , " " ) ; // use ->modified value only
2010-12-02 22:00:00 +01:00
r_speeds = Cvar_Get ( " r_speeds " , " 0 " , CVAR_ARCHIVE , " shows renderer speeds " ) ;
2010-12-03 22:00:00 +01:00
r_fullbright = Cvar_Get ( " r_fullbright " , " 0 " , CVAR_CHEAT , " disable lightmaps, get fullbright for entities " ) ;
2010-12-06 22:00:00 +01:00
r_norefresh = Cvar_Get ( " r_norefresh " , " 0 " , 0 , " disable 3D rendering (use with caution) " ) ;
2011-07-07 22:00:00 +02:00
r_lighting_extended = Cvar_Get ( " r_lighting_extended " , " 1 " , CVAR_ARCHIVE , " allow to get lighting from world and bmodels " ) ;
2010-12-11 22:00:00 +01:00
r_lighting_modulate = Cvar_Get ( " r_lighting_modulate " , " 0.6 " , CVAR_ARCHIVE , " lightstyles modulate scale " ) ;
2011-03-03 22:00:00 +01:00
r_lighting_ambient = Cvar_Get ( " r_lighting_ambient " , " 0.3 " , 0 , " map ambient lighting scale " ) ;
2010-12-06 22:00:00 +01:00
r_adjust_fov = Cvar_Get ( " r_adjust_fov " , " 1 " , CVAR_ARCHIVE , " making FOV adjustment for wide-screens " ) ;
r_novis = Cvar_Get ( " r_novis " , " 0 " , 0 , " ignore vis information (perfomance test) " ) ;
r_nocull = Cvar_Get ( " r_nocull " , " 0 " , 0 , " ignore frustrum culling (perfomance test) " ) ;
2010-12-14 22:00:00 +01:00
r_faceplanecull = Cvar_Get ( " r_faceplanecull " , " 1 " , 0 , " ignore face plane culling (perfomance test) " ) ;
2011-07-07 22:00:00 +02:00
r_detailtextures = Cvar_Get ( " r_detailtextures " , " 1 " , CVAR_ARCHIVE , " enable detail textures support, use \" 2 \" for auto-generate mapname_detail.txt " ) ;
2010-12-06 22:00:00 +01:00
r_lockpvs = Cvar_Get ( " r_lockpvs " , " 0 " , CVAR_CHEAT , " lockpvs area at current point (pvs test) " ) ;
2010-12-12 22:00:00 +01:00
r_lockcull = Cvar_Get ( " r_lockcull " , " 0 " , CVAR_CHEAT , " lock frustrum area at current point (cull test) " ) ;
2010-12-06 22:00:00 +01:00
r_dynamic = Cvar_Get ( " r_dynamic " , " 1 " , CVAR_ARCHIVE , " allow dynamic lighting (dlights, lightstyles) " ) ;
r_lightmap = Cvar_Get ( " r_lightmap " , " 0 " , CVAR_CHEAT , " lightmap debugging tool " ) ;
r_fastsky = Cvar_Get ( " r_fastsky " , " 0 " , CVAR_ARCHIVE , " enable algorhytm fo fast sky rendering (for old machines) " ) ;
2010-12-11 22:00:00 +01:00
r_drawentities = Cvar_Get ( " r_drawentities " , " 1 " , CVAR_CHEAT | CVAR_ARCHIVE , " render entities " ) ;
2011-04-10 22:00:00 +02:00
r_flaresize = Cvar_Get ( " r_flaresize " , " 200 " , CVAR_ARCHIVE , " set flares size " ) ;
2010-12-17 22:00:00 +01:00
r_lefthand = Cvar_Get ( " hand " , " 0 " , CVAR_ARCHIVE , " viewmodel handedness " ) ;
2010-12-23 22:00:00 +01:00
r_decals = Cvar_Get ( " r_decals " , " 4096 " , CVAR_ARCHIVE , " sets the maximum number of decals " ) ;
2010-12-27 22:00:00 +01:00
r_xpos = Cvar_Get ( " r_xpos " , " 130 " , CVAR_GLCONFIG , " window position by horizontal " ) ;
r_ypos = Cvar_Get ( " r_ypos " , " 48 " , CVAR_GLCONFIG , " window position by vertical " ) ;
gl_picmip = Cvar_Get ( " gl_picmip " , " 0 " , CVAR_GLCONFIG , " reduces resolution of textures by powers of 2 " ) ;
gl_skymip = Cvar_Get ( " gl_skymip " , " 0 " , CVAR_GLCONFIG , " reduces resolution of skybox textures by powers of 2 " ) ;
2011-10-06 22:00:00 +02:00
gl_ignorehwgamma = Cvar_Get ( " gl_ignorehwgamma " , " 0 " , CVAR_GLCONFIG , " ignore hardware gamma " ) ;
2010-11-28 22:00:00 +01:00
gl_allow_software = Cvar_Get ( " gl_allow_software " , " 0 " , CVAR_ARCHIVE , " allow OpenGL software emulation " ) ;
2010-12-27 22:00:00 +01:00
gl_alphabits = Cvar_Get ( " gl_alphabits " , " 8 " , CVAR_GLCONFIG , " pixelformat alpha bits (0 - auto) " ) ;
2010-11-28 22:00:00 +01:00
gl_texturemode = Cvar_Get ( " gl_texturemode " , " GL_LINEAR_MIPMAP_LINEAR " , CVAR_ARCHIVE , " texture filter " ) ;
2010-12-27 22:00:00 +01:00
gl_round_down = Cvar_Get ( " gl_round_down " , " 0 " , CVAR_GLCONFIG , " down size non-power of two textures " ) ;
2011-01-03 22:00:00 +01:00
gl_max_size = Cvar_Get ( " gl_max_size " , " 512 " , CVAR_ARCHIVE , " no effect in Xash3D just a legacy " ) ;
2010-12-27 22:00:00 +01:00
gl_stencilbits = Cvar_Get ( " gl_stencilbits " , " 8 " , CVAR_GLCONFIG , " pixelformat stencil bits (0 - auto) " ) ;
2010-11-28 22:00:00 +01:00
gl_check_errors = Cvar_Get ( " gl_check_errors " , " 1 " , CVAR_ARCHIVE , " ignore video engine errors " ) ;
gl_swapInterval = Cvar_Get ( " gl_swapInterval " , " 0 " , CVAR_ARCHIVE , " time beetween frames (in msec) " ) ;
2010-12-27 22:00:00 +01:00
gl_extensions = Cvar_Get ( " gl_extensions " , " 1 " , CVAR_GLCONFIG , " allow gl_extensions " ) ;
2013-12-01 21:00:00 +01:00
gl_detailscale = Cvar_Get ( " gl_detailscale " , " 4.0 " , CVAR_ARCHIVE , " default scale applies while auto-generate list of detail textures " ) ;
2013-01-11 21:00:00 +01:00
gl_texture_anisotropy = Cvar_Get ( " gl_anisotropy " , " 2.0 " , CVAR_ARCHIVE , " textures anisotropic filter " ) ;
2010-11-28 22:00:00 +01:00
gl_texture_lodbias = Cvar_Get ( " gl_texture_lodbias " , " 0.0 " , CVAR_ARCHIVE , " LOD bias for mipmapped textures " ) ;
2011-07-07 22:00:00 +02:00
gl_compress_textures = Cvar_Get ( " gl_compress_textures " , " 0 " , CVAR_GLCONFIG , " compress textures to safe video memory " ) ;
gl_luminance_textures = Cvar_Get ( " gl_luminance_textures " , " 0 " , CVAR_GLCONFIG , " force all textures to luminance " ) ;
2014-04-01 22:00:00 +02:00
gl_compensate_gamma_screenshots = Cvar_Get ( " gl_compensate_gamma_screenshots " , " 0 " , CVAR_ARCHIVE , " allow to apply gamma value for screenshots and snapshots " ) ;
2012-12-23 21:00:00 +01:00
gl_keeptjunctions = Cvar_Get ( " gl_keeptjunctions " , " 1 " , CVAR_ARCHIVE , " disable to reduce vertexes count but removing tjuncs causes blinking pixels " ) ;
2012-06-25 22:00:00 +02:00
gl_allow_static = Cvar_Get ( " gl_allow_static " , " 0 " , CVAR_ARCHIVE , " force to drawing non-moveable brushes as part of world (save FPS) " ) ;
2011-10-06 22:00:00 +02:00
gl_allow_mirrors = Cvar_Get ( " gl_allow_mirrors " , " 1 " , CVAR_ARCHIVE , " allow to draw mirror surfaces " ) ;
2011-12-09 21:00:00 +01:00
gl_showtextures = Cvar_Get ( " r_showtextures " , " 0 " , CVAR_CHEAT , " show all uploaded textures (type values from 1 to 13) " ) ;
2010-11-29 22:00:00 +01:00
gl_finish = Cvar_Get ( " gl_finish " , " 0 " , CVAR_ARCHIVE , " use glFinish instead of glFlush " ) ;
2012-12-28 21:00:00 +01:00
gl_nosort = Cvar_Get ( " gl_nosort " , " 0 " , CVAR_ARCHIVE , " disable sorting of translucent surfaces " ) ;
2010-11-29 22:00:00 +01:00
gl_clear = Cvar_Get ( " gl_clear " , " 0 " , CVAR_ARCHIVE , " clearing screen after each frame " ) ;
2010-12-13 22:00:00 +01:00
gl_test = Cvar_Get ( " gl_test " , " 0 " , 0 , " engine developer cvar for quick testing new features " ) ;
2011-04-15 22:00:00 +02:00
gl_wireframe = Cvar_Get ( " gl_wireframe " , " 0 " , 0 , " show wireframe overlay " ) ;
2011-08-21 22:00:00 +02:00
gl_overview = Cvar_Get ( " dev_overview " , " 0 " , 0 , " show level overview " ) ;
2011-04-09 22:00:00 +02:00
// these cvar not used by engine but some mods requires this
Cvar_Get ( " gl_polyoffset " , " -0.1 " , 0 , " polygon offset for decals " ) ;
2010-12-13 22:00:00 +01:00
2010-11-28 22:00:00 +01:00
// make sure r_swapinterval is checked after vid_restart
gl_swapInterval - > modified = true ;
2011-09-19 22:00:00 +02:00
vid_gamma = Cvar_Get ( " gamma " , " 1.0 " , CVAR_ARCHIVE , " gamma amount " ) ;
2011-10-06 22:00:00 +02:00
vid_texgamma = Cvar_Get ( " texgamma " , " 2.2 " , CVAR_GLCONFIG , " texgamma amount (default Half-Life artwork gamma) " ) ;
2010-12-27 22:00:00 +01:00
vid_mode = Cvar_Get ( " vid_mode " , VID_DEFAULTMODE , CVAR_RENDERINFO , " display resolution mode " ) ;
2010-12-21 22:00:00 +01:00
vid_fullscreen = Cvar_Get ( " fullscreen " , " 0 " , CVAR_RENDERINFO , " set in 1 to enable fullscreen mode " ) ;
2010-12-27 22:00:00 +01:00
vid_displayfrequency = Cvar_Get ( " vid_displayfrequency " , " 0 " , CVAR_RENDERINFO , " fullscreen refresh rate " ) ;
2010-11-28 22:00:00 +01:00
2010-11-29 22:00:00 +01:00
Cmd_AddCommand ( " r_info " , R_RenderInfo_f , " display renderer info " ) ;
2010-12-02 22:00:00 +01:00
Cmd_AddCommand ( " texturelist " , R_TextureList_f , " display loaded textures list " ) ;
2010-11-28 22:00:00 +01:00
}
void GL_RemoveCommands ( void )
{
Cmd_RemoveCommand ( " r_info " ) ;
2010-12-02 22:00:00 +01:00
Cmd_RemoveCommand ( " texturelist " ) ;
2010-11-28 22:00:00 +01:00
}
void GL_InitExtensions ( void )
{
2010-12-02 22:00:00 +01:00
// initialize gl extensions
GL_CheckExtension ( " OpenGL 1.1.0 " , opengl_110funcs , NULL , GL_OPENGL_110 ) ;
// get our various GL strings
glConfig . vendor_string = pglGetString ( GL_VENDOR ) ;
glConfig . renderer_string = pglGetString ( GL_RENDERER ) ;
glConfig . version_string = pglGetString ( GL_VERSION ) ;
glConfig . extensions_string = pglGetString ( GL_EXTENSIONS ) ;
MsgDev ( D_INFO , " Video: %s \n " , glConfig . renderer_string ) ;
2011-07-07 22:00:00 +02:00
// initalize until base opengl functions loaded
GL_CheckExtension ( " OpenGL Internal ProcAddress " , wglproc_funcs , NULL , GL_WGL_PROCADDRESS ) ;
2010-11-28 22:00:00 +01:00
GL_CheckExtension ( " WGL_EXT_swap_control " , wglswapintervalfuncs , NULL , GL_WGL_SWAPCONTROL ) ;
2011-07-07 22:00:00 +02:00
2010-11-28 22:00:00 +01:00
GL_CheckExtension ( " glDrawRangeElements " , drawrangeelementsfuncs , " gl_drawrangeelments " , GL_DRAW_RANGEELEMENTS_EXT ) ;
if ( ! GL_Support ( GL_DRAW_RANGEELEMENTS_EXT ) )
2010-12-02 22:00:00 +01:00
GL_CheckExtension ( " GL_EXT_draw_range_elements " , drawrangeelementsextfuncs , " gl_drawrangeelments " , GL_DRAW_RANGEELEMENTS_EXT ) ;
2010-11-28 22:00:00 +01:00
// multitexture
2013-12-01 21:00:00 +01:00
glConfig . max_texture_units = glConfig . max_texture_coords = glConfig . max_teximage_units = 1 ;
2010-11-28 22:00:00 +01:00
GL_CheckExtension ( " GL_ARB_multitexture " , multitexturefuncs , " gl_arb_multitexture " , GL_ARB_MULTITEXTURE ) ;
if ( GL_Support ( GL_ARB_MULTITEXTURE ) )
{
pglGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & glConfig . max_texture_units ) ;
GL_CheckExtension ( " GL_ARB_texture_env_combine " , NULL , " gl_texture_env_combine " , GL_ENV_COMBINE_EXT ) ;
if ( ! GL_Support ( GL_ENV_COMBINE_EXT ) )
GL_CheckExtension ( " GL_EXT_texture_env_combine " , NULL , " gl_texture_env_combine " , GL_ENV_COMBINE_EXT ) ;
if ( GL_Support ( GL_ENV_COMBINE_EXT ) )
GL_CheckExtension ( " GL_ARB_texture_env_dot3 " , NULL , " gl_texture_env_dot3 " , GL_DOT3_ARB_EXT ) ;
}
else
{
GL_CheckExtension ( " GL_SGIS_multitexture " , sgis_multitexturefuncs , " gl_sgis_multitexture " , GL_ARB_MULTITEXTURE ) ;
if ( GL_Support ( GL_ARB_MULTITEXTURE ) ) glConfig . max_texture_units = 2 ;
}
if ( glConfig . max_texture_units = = 1 )
GL_SetExtension ( GL_ARB_MULTITEXTURE , false ) ;
// 3d texture support
GL_CheckExtension ( " GL_EXT_texture3D " , texture3dextfuncs , " gl_texture_3d " , GL_TEXTURE_3D_EXT ) ;
if ( GL_Support ( GL_TEXTURE_3D_EXT ) )
{
pglGetIntegerv ( GL_MAX_3D_TEXTURE_SIZE , & glConfig . max_3d_texture_size ) ;
if ( glConfig . max_3d_texture_size < 32 )
{
GL_SetExtension ( GL_TEXTURE_3D_EXT , false ) ;
MsgDev ( D_ERROR , " GL_EXT_texture3D reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled \n " ) ;
}
}
GL_CheckExtension ( " GL_SGIS_generate_mipmap " , NULL , " gl_sgis_generate_mipmaps " , GL_SGIS_MIPMAPS_EXT ) ;
// hardware cubemaps
GL_CheckExtension ( " GL_ARB_texture_cube_map " , NULL , " gl_texture_cubemap " , GL_TEXTURECUBEMAP_EXT ) ;
if ( GL_Support ( GL_TEXTURECUBEMAP_EXT ) )
2010-11-29 22:00:00 +01:00
pglGetIntegerv ( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB , & glConfig . max_cubemap_size ) ;
2010-11-28 22:00:00 +01:00
// point particles extension
GL_CheckExtension ( " GL_EXT_point_parameters " , pointparametersfunc , NULL , GL_EXT_POINTPARAMETERS ) ;
GL_CheckExtension ( " GL_ARB_texture_non_power_of_two " , NULL , " gl_texture_npot " , GL_ARB_TEXTURE_NPOT_EXT ) ;
GL_CheckExtension ( " GL_ARB_texture_compression " , texturecompressionfuncs , " gl_dds_hardware_support " , GL_TEXTURE_COMPRESSION_EXT ) ;
GL_CheckExtension ( " GL_EXT_compiled_vertex_array " , compiledvertexarrayfuncs , " gl_cva_support " , GL_CUSTOM_VERTEX_ARRAY_EXT ) ;
if ( ! GL_Support ( GL_CUSTOM_VERTEX_ARRAY_EXT ) )
2011-11-14 21:00:00 +01:00
GL_CheckExtension ( " GL_SGI_compiled_vertex_array " , compiledvertexarrayfuncs , " gl_cva_support " , GL_CUSTOM_VERTEX_ARRAY_EXT ) ;
2010-11-28 22:00:00 +01:00
GL_CheckExtension ( " GL_EXT_texture_edge_clamp " , NULL , " gl_clamp_to_edge " , GL_CLAMPTOEDGE_EXT ) ;
if ( ! GL_Support ( GL_CLAMPTOEDGE_EXT ) )
GL_CheckExtension ( " GL_SGIS_texture_edge_clamp " , NULL , " gl_clamp_to_edge " , GL_CLAMPTOEDGE_EXT ) ;
glConfig . max_texture_anisotropy = 0.0f ;
GL_CheckExtension ( " GL_EXT_texture_filter_anisotropic " , NULL , " gl_ext_anisotropic_filter " , GL_ANISOTROPY_EXT ) ;
if ( GL_Support ( GL_ANISOTROPY_EXT ) )
pglGetFloatv ( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT , & glConfig . max_texture_anisotropy ) ;
GL_CheckExtension ( " GL_EXT_texture_lod_bias " , NULL , " gl_ext_texture_lodbias " , GL_TEXTURE_LODBIAS ) ;
if ( GL_Support ( GL_TEXTURE_LODBIAS ) )
pglGetFloatv ( GL_MAX_TEXTURE_LOD_BIAS_EXT , & glConfig . max_texture_lodbias ) ;
GL_CheckExtension ( " GL_ARB_texture_border_clamp " , NULL , " gl_ext_texborder_clamp " , GL_CLAMP_TEXBORDER_EXT ) ;
GL_CheckExtension ( " GL_EXT_blend_minmax " , blendequationfuncs , " gl_ext_customblend " , GL_BLEND_MINMAX_EXT ) ;
GL_CheckExtension ( " GL_EXT_blend_subtract " , blendequationfuncs , " gl_ext_customblend " , GL_BLEND_SUBTRACT_EXT ) ;
GL_CheckExtension ( " glStencilOpSeparate " , gl2separatestencilfuncs , " gl_separate_stencil " , GL_SEPARATESTENCIL_EXT ) ;
2013-12-01 21:00:00 +01:00
2010-11-28 22:00:00 +01:00
if ( ! GL_Support ( GL_SEPARATESTENCIL_EXT ) )
GL_CheckExtension ( " GL_ATI_separate_stencil " , atiseparatestencilfuncs , " gl_separate_stencil " , GL_SEPARATESTENCIL_EXT ) ;
GL_CheckExtension ( " GL_EXT_stencil_two_side " , stenciltwosidefuncs , " gl_stenciltwoside " , GL_STENCILTWOSIDE_EXT ) ;
GL_CheckExtension ( " GL_ARB_vertex_buffer_object " , vbofuncs , " gl_vertex_buffer_object " , GL_ARB_VERTEX_BUFFER_OBJECT_EXT ) ;
// we don't care if it's an extension or not, they are identical functions, so keep it simple in the rendering code
if ( pglDrawRangeElementsEXT = = NULL ) pglDrawRangeElementsEXT = pglDrawRangeElements ;
GL_CheckExtension ( " GL_ARB_texture_env_add " , NULL , " gl_texture_env_add " , GL_TEXTURE_ENV_ADD_EXT ) ;
// vp and fp shaders
GL_CheckExtension ( " GL_ARB_shader_objects " , shaderobjectsfuncs , " gl_shaderobjects " , GL_SHADER_OBJECTS_EXT ) ;
GL_CheckExtension ( " GL_ARB_shading_language_100 " , NULL , " gl_glslprogram " , GL_SHADER_GLSL100_EXT ) ;
GL_CheckExtension ( " GL_ARB_vertex_shader " , vertexshaderfuncs , " gl_vertexshader " , GL_VERTEX_SHADER_EXT ) ;
GL_CheckExtension ( " GL_ARB_fragment_shader " , NULL , " gl_pixelshader " , GL_FRAGMENT_SHADER_EXT ) ;
GL_CheckExtension ( " GL_ARB_depth_texture " , NULL , " gl_depthtexture " , GL_DEPTH_TEXTURE ) ;
GL_CheckExtension ( " GL_ARB_shadow " , NULL , " gl_arb_shadow " , GL_SHADOW_EXT ) ;
2014-04-01 22:00:00 +02:00
GL_CheckExtension ( " GL_ARB_texture_float " , NULL , " gl_arb_texture_float " , GL_ARB_TEXTURE_FLOAT_EXT ) ;
2010-11-28 22:00:00 +01:00
// occlusion queries
GL_CheckExtension ( " GL_ARB_occlusion_query " , occlusionfunc , " gl_occlusion_queries " , GL_OCCLUSION_QUERIES_EXT ) ;
2013-12-01 21:00:00 +01:00
if ( GL_Support ( GL_SHADER_GLSL100_EXT ) )
{
pglGetIntegerv ( GL_MAX_TEXTURE_COORDS_ARB , & glConfig . max_texture_coords ) ;
pglGetIntegerv ( GL_MAX_TEXTURE_IMAGE_UNITS_ARB , & glConfig . max_teximage_units ) ;
}
else
{
// just get from multitexturing
glConfig . max_texture_coords = glConfig . max_teximage_units = glConfig . max_texture_units ;
}
2010-11-28 22:00:00 +01:00
// rectangle textures support
2011-03-09 22:00:00 +01:00
if ( Q_strstr ( glConfig . extensions_string , " GL_NV_texture_rectangle " ) )
2010-11-28 22:00:00 +01:00
{
glConfig . texRectangle = GL_TEXTURE_RECTANGLE_NV ;
pglGetIntegerv ( GL_MAX_RECTANGLE_TEXTURE_SIZE_NV , & glConfig . max_2d_rectangle_size ) ;
}
2011-03-09 22:00:00 +01:00
else if ( Q_strstr ( glConfig . extensions_string , " GL_EXT_texture_rectangle " ) )
2010-11-28 22:00:00 +01:00
{
glConfig . texRectangle = GL_TEXTURE_RECTANGLE_EXT ;
pglGetIntegerv ( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT , & glConfig . max_2d_rectangle_size ) ;
}
else glConfig . texRectangle = glConfig . max_2d_rectangle_size = 0 ; // no rectangle
glConfig . max_2d_texture_size = 0 ;
pglGetIntegerv ( GL_MAX_TEXTURE_SIZE , & glConfig . max_2d_texture_size ) ;
if ( glConfig . max_2d_texture_size < = 0 ) glConfig . max_2d_texture_size = 256 ;
Cvar_Get ( " gl_max_texture_size " , " 0 " , CVAR_INIT , " opengl texture max dims " ) ;
Cvar_Set ( " gl_max_texture_size " , va ( " %i " , glConfig . max_2d_texture_size ) ) ;
// MCD has buffering issues
2011-03-09 22:00:00 +01:00
if ( Q_strstr ( glConfig . renderer_string , " gdi " ) )
2010-11-28 22:00:00 +01:00
Cvar_SetFloat ( " gl_finish " , 1 ) ;
Cvar_Set ( " gl_anisotropy " , va ( " %f " , bound ( 0 , gl_texture_anisotropy - > value , glConfig . max_texture_anisotropy ) ) ) ;
// software mipmap generator does wrong result with NPOT textures ...
if ( ! GL_Support ( GL_SGIS_MIPMAPS_EXT ) )
GL_SetExtension ( GL_ARB_TEXTURE_NPOT_EXT , false ) ;
glw_state . initialized = true ;
2010-12-21 22:00:00 +01:00
tr . framecount = tr . visframecount = 1 ;
2010-11-28 22:00:00 +01:00
}
/*
= = = = = = = = = = = = = = =
R_Init
= = = = = = = = = = = = = = =
*/
qboolean R_Init ( void )
{
2010-12-21 22:00:00 +01:00
if ( glw_state . initialized )
return true ;
2012-12-23 21:00:00 +01:00
// give initial OpenGL configuration
2010-12-21 22:00:00 +01:00
Cbuf_AddText ( " exec opengl.cfg \n " ) ;
2010-11-28 22:00:00 +01:00
GL_InitCommands ( ) ;
GL_SetDefaultState ( ) ;
// create the window and set up the context
2010-12-02 22:00:00 +01:00
if ( ! R_Init_OpenGL ( ) )
2010-11-28 22:00:00 +01:00
{
2010-12-02 22:00:00 +01:00
GL_RemoveCommands ( ) ;
2010-11-28 22:00:00 +01:00
R_Free_OpenGL ( ) ;
2010-12-21 22:00:00 +01:00
// can't initialize video subsystem
2011-03-12 22:00:00 +01:00
Host_NewInstance ( va ( " #%s " , GI - > gamefolder ) , " fallback to dedicated mode \n " ) ;
2010-11-28 22:00:00 +01:00
return false ;
}
2010-12-27 22:00:00 +01:00
renderinfo - > modified = false ;
2010-12-02 22:00:00 +01:00
r_temppool = Mem_AllocPool ( " Render Zone " ) ;
2010-11-28 22:00:00 +01:00
GL_InitExtensions ( ) ;
GL_SetDefaults ( ) ;
2010-11-29 22:00:00 +01:00
R_InitImages ( ) ;
2010-12-15 22:00:00 +01:00
R_SpriteInit ( ) ;
2010-12-16 22:00:00 +01:00
R_StudioInit ( ) ;
2011-10-09 22:00:00 +02:00
R_ClearDecals ( ) ;
2010-11-28 22:00:00 +01:00
R_ClearScene ( ) ;
2010-12-21 22:00:00 +01:00
// initialize screen
SCR_Init ( ) ;
2010-11-28 22:00:00 +01:00
return true ;
}
/*
= = = = = = = = = = = = = = =
R_Shutdown
= = = = = = = = = = = = = = =
*/
void R_Shutdown ( void )
{
2010-12-21 22:00:00 +01:00
int i ;
2010-12-02 22:00:00 +01:00
if ( ! glw_state . initialized )
return ;
2010-12-21 22:00:00 +01:00
// release SpriteTextures
for ( i = 1 ; i < MAX_IMAGES ; i + + )
{
if ( ! clgame . sprites [ i ] . name [ 0 ] ) continue ;
Mod_UnloadSpriteModel ( & clgame . sprites [ i ] ) ;
}
2011-03-10 22:00:00 +01:00
Q_memset ( clgame . sprites , 0 , sizeof ( clgame . sprites ) ) ;
2010-12-21 22:00:00 +01:00
2010-11-28 22:00:00 +01:00
GL_RemoveCommands ( ) ;
2010-11-29 22:00:00 +01:00
R_ShutdownImages ( ) ;
2010-11-28 22:00:00 +01:00
Mem_FreePool ( & r_temppool ) ;
// shut down OS specific OpenGL stuff like contexts, etc.
R_Free_OpenGL ( ) ;
}
/*
= = = = = = = = = = = = = = = = =
GL_CheckForErrors
= = = = = = = = = = = = = = = = =
*/
void GL_CheckForErrors_ ( const char * filename , const int fileline )
{
int err ;
char * str ;
if ( ! gl_check_errors - > integer )
return ;
if ( ( err = pglGetError ( ) ) = = GL_NO_ERROR )
return ;
switch ( err )
{
case GL_STACK_OVERFLOW :
str = " GL_STACK_OVERFLOW " ;
break ;
case GL_STACK_UNDERFLOW :
str = " GL_STACK_UNDERFLOW " ;
break ;
case GL_INVALID_ENUM :
str = " GL_INVALID_ENUM " ;
break ;
case GL_INVALID_VALUE :
str = " GL_INVALID_VALUE " ;
break ;
case GL_INVALID_OPERATION :
str = " GL_INVALID_OPERATION " ;
break ;
case GL_OUT_OF_MEMORY :
str = " GL_OUT_OF_MEMORY " ;
break ;
default :
str = " UNKNOWN ERROR " ;
break ;
}
Host_Error ( " GL_CheckForErrors: %s (called at %s:%i) \n " , str , filename , fileline ) ;
}