2019-02-23 21:49:46 +03:00
# include "gl_local.h"
2021-10-31 20:59:20 +06:00
# if XASH_GL4ES
# include "gl4es/include/gl4esinit.h"
# include "gl4es/include/gl4eshint.h"
# endif // XASH_GL4ES
2019-02-23 21:49:46 +03:00
2023-05-20 20:27:15 +03:00
CVAR_DEFINE ( gl_extensions , " gl_allow_extensions " , " 1 " , FCVAR_GLCONFIG | FCVAR_READ_ONLY , " allow gl_extensions " ) ;
CVAR_DEFINE ( gl_texture_anisotropy , " gl_anisotropy " , " 8 " , FCVAR_GLCONFIG , " textures anisotropic filter " ) ;
CVAR_DEFINE_AUTO ( gl_texture_lodbias , " 0.0 " , FCVAR_GLCONFIG , " LOD bias for mipmapped textures (perfomance|quality) " ) ;
CVAR_DEFINE_AUTO ( gl_texture_nearest , " 0 " , FCVAR_GLCONFIG , " disable texture filter " ) ;
CVAR_DEFINE_AUTO ( gl_lightmap_nearest , " 0 " , FCVAR_GLCONFIG , " disable lightmap filter " ) ;
CVAR_DEFINE_AUTO ( gl_keeptjunctions , " 1 " , FCVAR_GLCONFIG , " removing tjuncs causes blinking pixels " ) ;
CVAR_DEFINE_AUTO ( gl_check_errors , " 1 " , FCVAR_GLCONFIG , " ignore video engine errors " ) ;
CVAR_DEFINE_AUTO ( gl_polyoffset , " 2.0 " , FCVAR_GLCONFIG , " polygon offset for decals " ) ;
CVAR_DEFINE_AUTO ( gl_wireframe , " 0 " , FCVAR_GLCONFIG | FCVAR_SPONLY , " show wireframe overlay " ) ;
CVAR_DEFINE_AUTO ( gl_finish , " 0 " , FCVAR_GLCONFIG , " use glFinish instead of glFlush " ) ;
CVAR_DEFINE_AUTO ( gl_nosort , " 0 " , FCVAR_GLCONFIG , " disable sorting of translucent surfaces " ) ;
CVAR_DEFINE_AUTO ( gl_test , " 0 " , 0 , " engine developer cvar for quick testing new features " ) ;
CVAR_DEFINE_AUTO ( gl_msaa , " 1 " , FCVAR_GLCONFIG , " enable or disable multisample anti-aliasing " ) ;
CVAR_DEFINE_AUTO ( gl_stencilbits , " 8 " , FCVAR_GLCONFIG | FCVAR_READ_ONLY , " pixelformat stencil bits (0 - auto) " ) ;
2024-01-06 19:35:49 +03:00
CVAR_DEFINE_AUTO ( gl_overbright , " 1 " , FCVAR_GLCONFIG , " overbrights " ) ;
2024-11-21 23:17:30 +04:00
CVAR_DEFINE_AUTO ( gl_fog , " 1 " , FCVAR_GLCONFIG , " allow for rendering fog using built-in OpenGL fog implementation " ) ;
2023-05-20 20:27:15 +03:00
CVAR_DEFINE_AUTO ( r_lighting_extended , " 1 " , FCVAR_GLCONFIG , " allow to get lighting from world and bmodels " ) ;
CVAR_DEFINE_AUTO ( r_lighting_ambient , " 0.3 " , FCVAR_GLCONFIG , " map ambient lighting scale " ) ;
2024-10-24 23:31:16 +03:00
CVAR_DEFINE_AUTO ( r_detailtextures , " 1 " , FCVAR_GLCONFIG , " enable detail textures support " ) ;
2023-05-20 20:27:15 +03:00
CVAR_DEFINE_AUTO ( r_novis , " 0 " , 0 , " ignore vis information (perfomance test) " ) ;
CVAR_DEFINE_AUTO ( r_nocull , " 0 " , 0 , " ignore frustrum culling (perfomance test) " ) ;
CVAR_DEFINE_AUTO ( r_lockpvs , " 0 " , FCVAR_CHEAT , " lockpvs area at current point (pvs test) " ) ;
CVAR_DEFINE_AUTO ( r_lockfrustum , " 0 " , FCVAR_CHEAT , " lock frustrum area at current point (cull test) " ) ;
2023-10-26 04:59:01 +03:00
CVAR_DEFINE_AUTO ( r_traceglow , " 0 " , FCVAR_GLCONFIG , " cull flares behind models " ) ;
2023-05-20 20:27:15 +03:00
CVAR_DEFINE_AUTO ( gl_round_down , " 2 " , FCVAR_GLCONFIG | FCVAR_READ_ONLY , " round texture sizes to nearest POT value " ) ;
2024-10-24 23:31:16 +03:00
CVAR_DEFINE ( r_vbo , " gl_vbo " , " 0 " , FCVAR_GLCONFIG , " draw world using VBO (known to be glitchy) " ) ;
CVAR_DEFINE ( r_vbo_detail , " gl_vbo_detail " , " 0 " , FCVAR_GLCONFIG , " detail vbo mode (0: disable, 1: multipass, 2: singlepass, broken decal dlights) " ) ;
CVAR_DEFINE ( r_vbo_dlightmode , " gl_vbo_dlightmode " , " 1 " , FCVAR_GLCONFIG , " vbo dlight rendering mode (0-1) " ) ;
CVAR_DEFINE ( r_vbo_overbrightmode , " gl_vbo_overbrightmode " , " 0 " , FCVAR_GLCONFIG , " vbo overbright rendering mode (0-1) " ) ;
2023-10-30 06:25:28 +03:00
CVAR_DEFINE_AUTO ( r_ripple , " 0 " , FCVAR_GLCONFIG , " enable software-like water texture ripple simulation " ) ;
CVAR_DEFINE_AUTO ( r_ripple_updatetime , " 0.05 " , FCVAR_GLCONFIG , " how fast ripple simulation is " ) ;
CVAR_DEFINE_AUTO ( r_ripple_spawntime , " 0.1 " , FCVAR_GLCONFIG , " how fast new ripples spawn " ) ;
2025-02-05 13:02:37 +03:00
CVAR_DEFINE_AUTO ( r_large_lightmaps , " 0 " , FCVAR_GLCONFIG | FCVAR_LATCH , " enable larger lightmap atlas textures (might break custom renderer mods) " ) ;
2025-02-07 22:05:54 +03:00
CVAR_DEFINE_AUTO ( r_dlight_virtual_radius , " 3 " , FCVAR_GLCONFIG , " increase dlight radius virtually by this amount, should help against ugly cut off dlights on highly scaled textures " ) ;
2023-10-30 06:25:28 +03:00
2021-12-06 04:57:32 +03:00
DEFINE_ENGINE_SHARED_CVAR_LIST ( )
2021-06-01 19:28:52 +03:00
poolhandle_t r_temppool ;
2019-02-23 21:49:46 +03:00
gl_globals_t tr ;
glconfig_t glConfig ;
glstate_t glState ;
glwstate_t glw_state ;
2024-10-09 02:01:10 +03:00
# if XASH_GL_STATIC
# define GL_CALL( x ) #x, NULL
2019-03-30 03:07:52 +03:00
# else
2024-10-09 02:01:10 +03:00
# define GL_CALL( x ) #x, (void**)&p##x
2019-03-30 03:07:52 +03:00
# endif
2024-10-09 02:01:10 +03:00
2024-12-22 07:11:28 +03:00
static const dllfunc_t opengl_110funcs [ ] =
2019-02-24 18:45:27 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glClearColor ) } ,
{ GL_CALL ( glClear ) } ,
{ GL_CALL ( glAlphaFunc ) } ,
{ GL_CALL ( glBlendFunc ) } ,
{ GL_CALL ( glCullFace ) } ,
{ GL_CALL ( glDrawBuffer ) } ,
{ GL_CALL ( glReadBuffer ) } ,
{ GL_CALL ( glAccum ) } ,
{ GL_CALL ( glEnable ) } ,
{ GL_CALL ( glDisable ) } ,
{ GL_CALL ( glEnableClientState ) } ,
{ GL_CALL ( glDisableClientState ) } ,
{ GL_CALL ( glGetBooleanv ) } ,
{ GL_CALL ( glGetDoublev ) } ,
{ GL_CALL ( glGetFloatv ) } ,
{ GL_CALL ( glGetIntegerv ) } ,
{ GL_CALL ( glGetError ) } ,
{ GL_CALL ( glGetString ) } ,
{ GL_CALL ( glFinish ) } ,
{ GL_CALL ( glFlush ) } ,
{ GL_CALL ( glClearDepth ) } ,
{ GL_CALL ( glDepthFunc ) } ,
{ GL_CALL ( glDepthMask ) } ,
{ GL_CALL ( glDepthRange ) } ,
{ GL_CALL ( glFrontFace ) } ,
{ GL_CALL ( glDrawElements ) } ,
{ GL_CALL ( glDrawArrays ) } ,
{ GL_CALL ( glColorMask ) } ,
{ GL_CALL ( glIndexPointer ) } ,
{ GL_CALL ( glVertexPointer ) } ,
{ GL_CALL ( glNormalPointer ) } ,
{ GL_CALL ( glColorPointer ) } ,
{ GL_CALL ( glTexCoordPointer ) } ,
{ GL_CALL ( glArrayElement ) } ,
{ GL_CALL ( glColor3f ) } ,
{ GL_CALL ( glColor3fv ) } ,
{ GL_CALL ( glColor4f ) } ,
{ GL_CALL ( glColor4fv ) } ,
{ GL_CALL ( glColor3ub ) } ,
{ GL_CALL ( glColor4ub ) } ,
{ GL_CALL ( glColor4ubv ) } ,
{ GL_CALL ( glTexCoord1f ) } ,
{ GL_CALL ( glTexCoord2f ) } ,
{ GL_CALL ( glTexCoord3f ) } ,
{ GL_CALL ( glTexCoord4f ) } ,
{ GL_CALL ( glTexCoord1fv ) } ,
{ GL_CALL ( glTexCoord2fv ) } ,
{ GL_CALL ( glTexCoord3fv ) } ,
{ GL_CALL ( glTexCoord4fv ) } ,
{ GL_CALL ( glTexGenf ) } ,
{ GL_CALL ( glTexGenfv ) } ,
{ GL_CALL ( glTexGeni ) } ,
{ GL_CALL ( glVertex2f ) } ,
{ GL_CALL ( glVertex3f ) } ,
{ GL_CALL ( glVertex3fv ) } ,
{ GL_CALL ( glNormal3f ) } ,
{ GL_CALL ( glNormal3fv ) } ,
{ GL_CALL ( glBegin ) } ,
{ GL_CALL ( glEnd ) } ,
{ GL_CALL ( glLineWidth ) } ,
{ GL_CALL ( glPointSize ) } ,
{ GL_CALL ( glMatrixMode ) } ,
{ GL_CALL ( glOrtho ) } ,
{ GL_CALL ( glRasterPos2f ) } ,
{ GL_CALL ( glFrustum ) } ,
{ GL_CALL ( glViewport ) } ,
{ GL_CALL ( glPushMatrix ) } ,
{ GL_CALL ( glPopMatrix ) } ,
{ GL_CALL ( glPushAttrib ) } ,
{ GL_CALL ( glPopAttrib ) } ,
{ GL_CALL ( glLoadIdentity ) } ,
{ GL_CALL ( glLoadMatrixd ) } ,
{ GL_CALL ( glLoadMatrixf ) } ,
{ GL_CALL ( glMultMatrixd ) } ,
{ GL_CALL ( glMultMatrixf ) } ,
{ GL_CALL ( glRotated ) } ,
{ GL_CALL ( glRotatef ) } ,
{ GL_CALL ( glScaled ) } ,
{ GL_CALL ( glScalef ) } ,
{ GL_CALL ( glTranslated ) } ,
{ GL_CALL ( glTranslatef ) } ,
{ GL_CALL ( glReadPixels ) } ,
{ GL_CALL ( glDrawPixels ) } ,
{ GL_CALL ( glStencilFunc ) } ,
{ GL_CALL ( glStencilMask ) } ,
{ GL_CALL ( glStencilOp ) } ,
{ GL_CALL ( glClearStencil ) } ,
{ GL_CALL ( glIsEnabled ) } ,
{ GL_CALL ( glIsList ) } ,
{ GL_CALL ( glIsTexture ) } ,
{ GL_CALL ( glTexEnvf ) } ,
{ GL_CALL ( glTexEnvfv ) } ,
{ GL_CALL ( glTexEnvi ) } ,
{ GL_CALL ( glTexParameterf ) } ,
{ GL_CALL ( glTexParameterfv ) } ,
{ GL_CALL ( glTexParameteri ) } ,
{ GL_CALL ( glHint ) } ,
{ GL_CALL ( glPixelStoref ) } ,
{ GL_CALL ( glPixelStorei ) } ,
{ GL_CALL ( glGenTextures ) } ,
{ GL_CALL ( glDeleteTextures ) } ,
{ GL_CALL ( glBindTexture ) } ,
{ GL_CALL ( glTexImage1D ) } ,
{ GL_CALL ( glTexImage2D ) } ,
{ GL_CALL ( glTexSubImage1D ) } ,
{ GL_CALL ( glTexSubImage2D ) } ,
{ GL_CALL ( glCopyTexImage1D ) } ,
{ GL_CALL ( glCopyTexImage2D ) } ,
{ GL_CALL ( glCopyTexSubImage1D ) } ,
{ GL_CALL ( glCopyTexSubImage2D ) } ,
{ GL_CALL ( glScissor ) } ,
{ GL_CALL ( glGetTexImage ) } ,
{ GL_CALL ( glGetTexEnviv ) } ,
{ GL_CALL ( glPolygonOffset ) } ,
{ GL_CALL ( glPolygonMode ) } ,
{ GL_CALL ( glPolygonStipple ) } ,
{ GL_CALL ( glClipPlane ) } ,
{ GL_CALL ( glGetClipPlane ) } ,
{ GL_CALL ( glShadeModel ) } ,
{ GL_CALL ( glGetTexLevelParameteriv ) } ,
{ GL_CALL ( glGetTexLevelParameterfv ) } ,
{ GL_CALL ( glFogfv ) } ,
{ GL_CALL ( glFogf ) } ,
{ GL_CALL ( glFogi ) } ,
2019-02-24 18:45:27 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t debugoutputfuncs [ ] =
2019-02-24 18:45:27 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glDebugMessageControlARB ) } ,
{ GL_CALL ( glDebugMessageInsertARB ) } ,
{ GL_CALL ( glDebugMessageCallbackARB ) } ,
{ GL_CALL ( glGetDebugMessageLogARB ) } ,
2019-02-24 18:45:27 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t multitexturefuncs [ ] =
2019-02-24 18:45:27 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glMultiTexCoord1f ) } ,
{ GL_CALL ( glMultiTexCoord2f ) } ,
{ GL_CALL ( glMultiTexCoord3f ) } ,
{ GL_CALL ( glMultiTexCoord4f ) } ,
{ GL_CALL ( glActiveTexture ) } ,
{ GL_CALL ( glActiveTextureARB ) } ,
{ GL_CALL ( glClientActiveTexture ) } ,
{ GL_CALL ( glClientActiveTextureARB ) } ,
2019-02-24 18:45:27 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t texture3dextfuncs [ ] =
2019-02-24 18:45:27 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glTexImage3D ) } ,
{ GL_CALL ( glTexSubImage3D ) } ,
{ GL_CALL ( glCopyTexSubImage3D ) } ,
2019-02-24 18:45:27 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t texturecompressionfuncs [ ] =
2019-02-24 18:45:27 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glCompressedTexImage3DARB ) } ,
{ GL_CALL ( glCompressedTexImage2DARB ) } ,
{ GL_CALL ( glCompressedTexImage1DARB ) } ,
{ GL_CALL ( glCompressedTexSubImage3DARB ) } ,
{ GL_CALL ( glCompressedTexSubImage2DARB ) } ,
{ GL_CALL ( glCompressedTexSubImage1DARB ) } ,
{ GL_CALL ( glGetCompressedTexImage ) } ,
2019-02-24 18:45:27 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t vbofuncs [ ] =
2019-02-24 18:45:27 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glBindBufferARB ) } ,
{ GL_CALL ( glDeleteBuffersARB ) } ,
{ GL_CALL ( glGenBuffersARB ) } ,
{ GL_CALL ( glIsBufferARB ) } ,
2024-10-09 02:01:10 +03:00
# if !XASH_GLES
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glMapBufferARB ) } ,
{ GL_CALL ( glUnmapBufferARB ) } ,
2023-10-13 22:10:01 +03:00
# endif
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glBufferDataARB ) } ,
{ GL_CALL ( glBufferSubDataARB ) } ,
2019-11-17 18:51:03 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t multisampletexfuncs [ ] =
2021-11-22 13:48:39 +04:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glTexImage2DMultisample ) } ,
2021-11-22 13:48:39 +04:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t drawrangeelementsfuncs [ ] =
2019-11-17 18:51:03 +03:00
{
{ GL_CALL ( glDrawRangeElements ) } ,
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t drawrangeelementsextfuncs [ ] =
2019-11-17 18:51:03 +03:00
{
{ GL_CALL ( glDrawRangeElementsEXT ) } ,
2019-02-24 18:45:27 +03:00
} ;
2023-10-13 00:11:39 +03:00
// mangling in gl2shim???
// still need resolve some ext dynamicly, and mangling beginend wrappers will help only with LTO
// anyway this will not work with gl-wes/nanogl, we do not link to libGLESv2, so skip this now
2024-10-09 02:01:10 +03:00
# if !XASH_GL_STATIC
2024-12-22 07:11:28 +03:00
static const dllfunc_t mapbufferrangefuncs [ ] =
2023-10-13 00:11:39 +03:00
{
{ GL_CALL ( glMapBufferRange ) } ,
{ GL_CALL ( glFlushMappedBufferRange ) } ,
2024-10-09 02:01:10 +03:00
# if XASH_GLES
2023-10-13 22:10:01 +03:00
{ GL_CALL ( glUnmapBufferARB ) } ,
# endif
2023-10-13 00:11:39 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t drawrangeelementsbasevertexfuncs [ ] =
2023-10-13 00:11:39 +03:00
{
{ GL_CALL ( glDrawRangeElementsBaseVertex ) } ,
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t bufferstoragefuncs [ ] =
2023-10-13 00:11:39 +03:00
{
{ GL_CALL ( glBufferStorage ) } ,
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t shaderobjectsfuncs [ ] =
2023-10-04 18:29:29 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glDeleteObjectARB ) } ,
{ GL_CALL ( glGetHandleARB ) } ,
{ GL_CALL ( glDetachObjectARB ) } ,
{ GL_CALL ( glCreateShaderObjectARB ) } ,
{ GL_CALL ( glShaderSourceARB ) } ,
{ GL_CALL ( glCompileShaderARB ) } ,
{ GL_CALL ( glCreateProgramObjectARB ) } ,
{ GL_CALL ( glAttachObjectARB ) } ,
{ GL_CALL ( glLinkProgramARB ) } ,
{ GL_CALL ( glUseProgramObjectARB ) } ,
{ GL_CALL ( glValidateProgramARB ) } ,
{ GL_CALL ( glUniform1fARB ) } ,
{ GL_CALL ( glUniform2fARB ) } ,
{ GL_CALL ( glUniform3fARB ) } ,
{ GL_CALL ( glUniform4fARB ) } ,
{ GL_CALL ( glUniform1iARB ) } ,
{ GL_CALL ( glUniform2iARB ) } ,
{ GL_CALL ( glUniform3iARB ) } ,
{ GL_CALL ( glUniform4iARB ) } ,
{ GL_CALL ( glUniform1fvARB ) } ,
{ GL_CALL ( glUniform2fvARB ) } ,
{ GL_CALL ( glUniform3fvARB ) } ,
{ GL_CALL ( glUniform4fvARB ) } ,
{ GL_CALL ( glUniform1ivARB ) } ,
{ GL_CALL ( glUniform2ivARB ) } ,
{ GL_CALL ( glUniform3ivARB ) } ,
{ GL_CALL ( glUniform4ivARB ) } ,
{ GL_CALL ( glUniformMatrix2fvARB ) } ,
{ GL_CALL ( glUniformMatrix3fvARB ) } ,
{ GL_CALL ( glUniformMatrix4fvARB ) } ,
{ GL_CALL ( glGetObjectParameterfvARB ) } ,
{ GL_CALL ( glGetObjectParameterivARB ) } ,
{ GL_CALL ( glGetInfoLogARB ) } ,
{ GL_CALL ( glGetAttachedObjectsARB ) } ,
{ GL_CALL ( glGetUniformLocationARB ) } ,
{ GL_CALL ( glGetActiveUniformARB ) } ,
{ GL_CALL ( glGetUniformfvARB ) } ,
{ GL_CALL ( glGetUniformivARB ) } ,
{ GL_CALL ( glGetShaderSourceARB ) } ,
{ GL_CALL ( glVertexAttribPointerARB ) } ,
{ GL_CALL ( glEnableVertexAttribArrayARB ) } ,
{ GL_CALL ( glDisableVertexAttribArrayARB ) } ,
{ GL_CALL ( glBindAttribLocationARB ) } ,
{ GL_CALL ( glGetActiveAttribARB ) } ,
{ GL_CALL ( glGetAttribLocationARB ) } ,
{ GL_CALL ( glVertexAttrib2fARB ) } ,
{ GL_CALL ( glVertexAttrib2fvARB ) } ,
//{ GL_CALL( glVertexAttrib3fv ) },
//{ GL_CALL( glVertexAttrib4f ) },
//{ GL_CALL( glVertexAttrib4fv ) },
//{ GL_CALL( glVertexAttrib4ubv ) },
2023-10-04 18:29:29 +03:00
} ;
2023-10-15 04:30:18 +03:00
/*
= = = = = = = = = = = = = = = = = =
Even if * ARB functions may work in GL driver in Core context ,
renderdoc completely ignores this calls , so we cannot workaround this
by removing ARB suffix after failed function resolve
I desided not to remove ARB suffix from function declarations because
it historicaly related to ARB_shader_object extension , not GL2 + functions
and all shader code from XashXT / ancient xash3d uses it too
Commented out lines left there intentionally to prevent usage on core / gles
= = = = = = = = = = = = = = = = = =
*/
2024-12-22 07:11:28 +03:00
static const dllfunc_t shaderobjectsfuncs_gles [ ] =
2023-10-05 00:24:40 +03:00
{
2024-12-22 07:11:28 +03:00
{ " glDeleteShader " , ( void * * ) & pglDeleteObjectARB } ,
//{ "glGetHandleARB" , (void **)&pglGetHandleARB },
{ " glDetachShader " , ( void * * ) & pglDetachObjectARB } ,
{ " glCreateShader " , ( void * * ) & pglCreateShaderObjectARB } ,
{ " glShaderSource " , ( void * * ) & pglShaderSourceARB } ,
{ " glCompileShader " , ( void * * ) & pglCompileShaderARB } ,
{ " glCreateProgram " , ( void * * ) & pglCreateProgramObjectARB } ,
{ " glAttachShader " , ( void * * ) & pglAttachObjectARB } ,
{ " glLinkProgram " , ( void * * ) & pglLinkProgramARB } ,
{ " glUseProgram " , ( void * * ) & pglUseProgramObjectARB } ,
{ " glValidateProgram " , ( void * * ) & pglValidateProgramARB } ,
{ " glUniform1f " , ( void * * ) & pglUniform1fARB } ,
{ " glUniform2f " , ( void * * ) & pglUniform2fARB } ,
{ " glUniform3f " , ( void * * ) & pglUniform3fARB } ,
{ " glUniform4f " , ( void * * ) & pglUniform4fARB } ,
{ " glUniform1i " , ( void * * ) & pglUniform1iARB } ,
{ " glUniform2i " , ( void * * ) & pglUniform2iARB } ,
{ " glUniform3i " , ( void * * ) & pglUniform3iARB } ,
{ " glUniform4i " , ( void * * ) & pglUniform4iARB } ,
{ " glUniform1f " , ( void * * ) & pglUniform1fvARB } ,
{ " glUniform2fv " , ( void * * ) & pglUniform2fvARB } ,
{ " glUniform3fv " , ( void * * ) & pglUniform3fvARB } ,
{ " glUniform4fv " , ( void * * ) & pglUniform4fvARB } ,
{ " glUniform1iv " , ( void * * ) & pglUniform1ivARB } ,
{ " glUniform2iv " , ( void * * ) & pglUniform2ivARB } ,
{ " glUniform3iv " , ( void * * ) & pglUniform3ivARB } ,
{ " glUniform4iv " , ( void * * ) & pglUniform4ivARB } ,
{ " glUniformMatrix2fv " , ( void * * ) & pglUniformMatrix2fvARB } ,
{ " glUniformMatrix3fv " , ( void * * ) & pglUniformMatrix3fvARB } ,
{ " glUniformMatrix4fv " , ( void * * ) & pglUniformMatrix4fvARB } ,
//{ "glGetShaderfv" , (void **)&pglGetObjectParameterfvARB }, // missing in ES2?
{ " glGetShaderiv " , ( void * * ) & pglGetObjectParameterivARB } ,
{ " glGetShaderInfoLog " , ( void * * ) & pglGetInfoLogARB } ,
//{ "glGetAttachedObjects" , (void **)&pglGetAttachedObjectsARB }, // missing in ES2?
{ " glGetUniformLocation " , ( void * * ) & pglGetUniformLocationARB } ,
{ " glGetActiveUniform " , ( void * * ) & pglGetActiveUniformARB } ,
{ " glGetUniformfv " , ( void * * ) & pglGetUniformfvARB } ,
{ " glGetUniformiv " , ( void * * ) & pglGetUniformivARB } ,
{ " glGetShaderSource " , ( void * * ) & pglGetShaderSourceARB } ,
{ " glVertexAttribPointer " , ( void * * ) & pglVertexAttribPointerARB } ,
{ " glEnableVertexAttribArray " , ( void * * ) & pglEnableVertexAttribArrayARB } ,
{ " glDisableVertexAttribArray " , ( void * * ) & pglDisableVertexAttribArrayARB } ,
{ " glBindAttribLocation " , ( void * * ) & pglBindAttribLocationARB } ,
{ " glGetActiveAttrib " , ( void * * ) & pglGetActiveAttribARB } ,
{ " glGetAttribLocation " , ( void * * ) & pglGetAttribLocationARB } ,
{ " glVertexAttrib2f " , ( void * * ) & pglVertexAttrib2fARB } ,
{ " glVertexAttrib2fv " , ( void * * ) & pglVertexAttrib2fvARB } ,
{ " glVertexAttrib3fv " , ( void * * ) & pglVertexAttrib3fvARB } ,
// Core/GLES only
{ GL_CALL ( glGetProgramiv ) } ,
{ GL_CALL ( glDeleteProgram ) } ,
{ GL_CALL ( glGetProgramInfoLog ) } ,
//{ "glVertexAttrib4f" , (void **)&pglVertexAttrib4fARB },
//{ "glVertexAttrib4fv" , (void **)&pglVertexAttrib4fvARB },
//{ "glVertexAttrib4ubv" , (void **)&pglVertexAttrib4ubvARB },
2023-10-05 00:24:40 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t vaofuncs [ ] =
2023-10-05 03:32:02 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glBindVertexArray ) } ,
{ GL_CALL ( glDeleteVertexArrays ) } ,
{ GL_CALL ( glGenVertexArrays ) } ,
{ GL_CALL ( glIsVertexArray ) } ,
2023-10-05 03:32:02 +03:00
} ;
2023-10-13 22:10:01 +03:00
2024-12-22 07:11:28 +03:00
static const dllfunc_t multitexturefuncs_es [ ] =
2023-10-13 22:10:01 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glActiveTexture ) } ,
{ GL_CALL ( glActiveTextureARB ) } ,
{ GL_CALL ( glClientActiveTexture ) } ,
{ GL_CALL ( glClientActiveTextureARB ) } ,
2023-10-13 22:10:01 +03:00
} ;
2024-12-22 07:11:28 +03:00
static const dllfunc_t multitexturefuncs_es2 [ ] =
2023-10-13 22:10:01 +03:00
{
2024-12-22 07:11:28 +03:00
{ GL_CALL ( glActiveTexture ) } ,
{ GL_CALL ( glActiveTextureARB ) } ,
2023-10-13 22:10:01 +03:00
} ;
2024-10-09 02:01:10 +03:00
# endif // !XASH_GL_STATIC
2023-10-05 03:32:02 +03:00
2019-02-24 18:45:27 +03:00
/*
= = = = = = = = = = = = = = = = = = = = = = = =
DebugCallback
For ARB_debug_output
= = = = = = = = = = = = = = = = = = = = = = = =
*/
static void APIENTRY GL_DebugOutput ( GLuint source , GLuint type , GLuint id , GLuint severity , GLint length , const GLcharARB * message , GLvoid * userParam )
{
switch ( type )
{
case GL_DEBUG_TYPE_ERROR_ARB :
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( S_OPENGL_ERROR " %s \n " , message ) ;
2019-02-24 18:45:27 +03:00
break ;
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB :
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB :
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( S_OPENGL_WARN " %s \n " , message ) ;
2019-02-24 18:45:27 +03:00
break ;
case GL_DEBUG_TYPE_PORTABILITY_ARB :
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Reportf ( S_OPENGL_WARN " %s \n " , message ) ;
2019-02-24 18:45:27 +03:00
break ;
case GL_DEBUG_TYPE_PERFORMANCE_ARB :
case GL_DEBUG_TYPE_OTHER_ARB :
2019-03-06 16:23:33 +03:00
default :
gEngfuncs . Con_Printf ( S_OPENGL_NOTE " %s \n " , message ) ;
2019-02-24 18:45:27 +03:00
break ;
}
}
2019-02-23 21:49:46 +03:00
/*
= = = = = = = = = = = = = = = = =
GL_SetExtension
= = = = = = = = = = = = = = = = =
*/
2024-12-22 07:11:28 +03:00
static void GL_SetExtension ( int r_ext , int enable )
2019-02-23 21:49:46 +03:00
{
if ( r_ext > = 0 & & r_ext < GL_EXTCOUNT )
glConfig . extension [ r_ext ] = enable ? GL_TRUE : GL_FALSE ;
2024-06-19 06:46:08 +03:00
else gEngfuncs . Con_Printf ( S_ERROR " %s: invalid extension %d \n " , __func__ , r_ext ) ;
2019-02-23 21:49:46 +03:00
}
/*
= = = = = = = = = = = = = = = = =
GL_CheckExtension
= = = = = = = = = = = = = = = = =
*/
2024-12-22 07:11:28 +03:00
static qboolean GL_CheckExtension ( const char * name , const dllfunc_t * funcs , size_t num_funcs , const char * cvarname , int r_ext , float minver )
2019-02-23 21:49:46 +03:00
{
2024-12-22 07:11:28 +03:00
size_t i ;
cvar_t * parm = NULL ;
const char * extensions_string ;
char desc [ MAX_VA_STRING ] ;
2023-10-12 21:46:08 +03:00
float glver = ( float ) glConfig . version_major + glConfig . version_minor / 10.0f ;
2019-02-23 21:49:46 +03:00
2024-06-19 06:46:08 +03:00
gEngfuncs . Con_Reportf ( " %s: %s " , __func__ , name ) ;
2019-02-23 21:49:46 +03:00
GL_SetExtension ( r_ext , true ) ;
if ( cvarname )
{
// system config disable extensions
2022-12-18 22:55:53 +05:00
Q_snprintf ( desc , sizeof ( desc ) , CVAR_GLCONFIG_DESCRIPTION , name ) ;
parm = gEngfuncs . Cvar_Get ( cvarname , " 1 " , FCVAR_GLCONFIG | FCVAR_READ_ONLY , desc ) ;
2019-02-23 21:49:46 +03:00
}
2023-05-20 20:27:15 +03:00
if ( ( parm & & ! parm - > value ) | | ( ! gl_extensions . value & & r_ext ! = GL_OPENGL_110 ) )
2019-02-23 21:49:46 +03:00
{
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Reportf ( " - disabled \n " ) ;
2019-02-23 21:49:46 +03:00
GL_SetExtension ( r_ext , false ) ;
2019-08-08 05:52:36 +03:00
return false ; // nothing to process at
2019-02-23 21:49:46 +03:00
}
extensions_string = glConfig . extensions_string ;
2023-10-12 21:46:08 +03:00
if ( ( name [ 2 ] = = ' _ ' | | name [ 3 ] = = ' _ ' ) & & ! Q_strstr ( extensions_string , name ) & & ( glver < minver | | ! minver | | ! glver ) )
2019-02-23 21:49:46 +03:00
{
GL_SetExtension ( r_ext , false ) ; // update render info
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Reportf ( " - ^1failed \n " ) ;
2019-08-08 05:52:36 +03:00
return false ;
2019-02-23 21:49:46 +03:00
}
2024-10-09 02:01:10 +03:00
# if !XASH_GL_STATIC
2019-02-23 21:49:46 +03:00
// clear exports
2024-12-23 04:43:15 +03:00
ClearExports ( funcs , num_funcs ) ;
2019-02-23 21:49:46 +03:00
2024-12-22 07:11:28 +03:00
for ( i = 0 ; i < num_funcs ; i + + )
2019-02-23 21:49:46 +03:00
{
// functions are cleared before all the extensions are evaluated
2024-12-22 07:11:28 +03:00
if ( ( * ( funcs [ i ] . func ) = ( void * ) gEngfuncs . GL_GetProcAddress ( funcs [ i ] . name ) ) = = NULL )
2023-02-17 23:46:38 +01:00
{
2023-10-21 20:11:58 +03:00
string name ;
2023-10-22 19:16:16 +03:00
char * end ;
2024-12-22 07:11:28 +03:00
size_t j = 0 ;
2024-10-09 02:01:10 +03:00
# if XASH_GLES
2023-10-22 19:16:16 +03:00
const char * suffixes [ ] = { " " , " EXT " , " OES " } ;
# else
const char * suffixes [ ] = { " " , " EXT " } ;
# endif
2023-10-21 20:11:58 +03:00
2023-10-13 22:10:01 +03:00
// HACK: fix ARB names
2024-12-22 07:11:28 +03:00
Q_strncpy ( name , funcs [ i ] . name , sizeof ( name ) ) ;
2023-10-22 19:16:16 +03:00
if ( ( end = Q_strstr ( name , " ARB " ) ) )
2023-10-21 20:11:58 +03:00
{
2023-10-22 19:16:16 +03:00
* end = ' \0 ' ;
2023-10-21 20:11:58 +03:00
}
2023-10-22 19:16:16 +03:00
else // I need Q_strstrnul
2023-10-21 20:11:58 +03:00
{
2023-10-22 19:16:16 +03:00
end = name + Q_strlen ( name ) ;
2024-12-22 07:11:28 +03:00
j + + ; // skip empty suffix
2023-10-21 20:11:58 +03:00
}
2024-12-22 07:11:28 +03:00
for ( ; j < sizeof ( suffixes ) / sizeof ( suffixes [ 0 ] ) ; j + + )
2023-10-21 20:11:58 +03:00
{
2023-10-22 19:16:16 +03:00
void * f ;
2024-12-22 07:11:28 +03:00
Q_strncat ( name , suffixes [ j ] , sizeof ( name ) ) ;
2023-10-22 19:16:16 +03:00
if ( ( f = gEngfuncs . GL_GetProcAddress ( name ) ) )
{
// GL_GetProcAddress prints errors about missing functions, so tell user that we found it with different name
gEngfuncs . Con_Printf ( S_NOTE " found %s \n " , name ) ;
2024-12-22 07:11:28 +03:00
* ( funcs [ i ] . func ) = f ;
2023-10-22 19:16:16 +03:00
break ;
}
else
{
* end = ' \0 ' ; // cut suffix, try next
}
2023-10-21 20:11:58 +03:00
}
2023-10-15 04:30:18 +03:00
2023-10-22 19:16:16 +03:00
// not found...
2024-12-22 07:11:28 +03:00
if ( j = = sizeof ( suffixes ) / sizeof ( suffixes [ 0 ] ) )
2023-10-21 20:11:58 +03:00
{
2023-10-13 22:10:01 +03:00
GL_SetExtension ( r_ext , false ) ;
2023-10-22 19:16:16 +03:00
}
2023-02-17 23:46:38 +01:00
}
2019-02-23 21:49:46 +03:00
}
2019-03-30 03:07:52 +03:00
# endif
2019-02-23 21:49:46 +03:00
if ( GL_Support ( r_ext ) )
2019-08-08 05:52:36 +03:00
{
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Reportf ( " - ^2enabled \n " ) ;
2019-08-08 05:52:36 +03:00
return true ;
}
gEngfuncs . Con_Reportf ( " - ^1failed \n " ) ;
return false ;
2019-02-23 21:49:46 +03:00
}
2019-05-12 03:04:26 +03:00
/*
= = = = = = = = = = = = = =
GL_GetProcAddress
defined just for nanogl / glwes , so it don ' t link to SDL2 directly , nor use dlsym
= = = = = = = = = = = = = =
*/
2024-01-27 20:18:05 +03:00
void GAME_EXPORT * GL_GetProcAddress ( const char * name ) ; // keep defined for nanogl/wes
2019-05-12 03:04:26 +03:00
void GAME_EXPORT * GL_GetProcAddress ( const char * name )
{
return gEngfuncs . GL_GetProcAddress ( name ) ;
}
2019-02-23 21:49:46 +03:00
/*
= = = = = = = = = = = = = = =
GL_SetDefaultTexState
= = = = = = = = = = = = = = =
*/
static void GL_SetDefaultTexState ( void )
{
int i ;
memset ( glState . currentTextures , - 1 , MAX_TEXTURE_UNITS * sizeof ( * glState . currentTextures ) ) ;
memset ( glState . texCoordArrayMode , 0 , MAX_TEXTURE_UNITS * sizeof ( * glState . texCoordArrayMode ) ) ;
memset ( glState . genSTEnabled , 0 , MAX_TEXTURE_UNITS * sizeof ( * glState . genSTEnabled ) ) ;
for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i + + )
{
glState . currentTextureTargets [ i ] = GL_NONE ;
glState . texIdentityMatrix [ i ] = true ;
}
}
/*
= = = = = = = = = = = = = = =
GL_SetDefaultState
= = = = = = = = = = = = = = =
*/
static void GL_SetDefaultState ( void )
{
memset ( & glState , 0 , sizeof ( glState ) ) ;
GL_SetDefaultTexState ( ) ;
// init draw stack
tr . draw_list = & tr . draw_stack [ 0 ] ;
tr . draw_stack_pos = 0 ;
}
/*
= = = = = = = = = = = = = = =
GL_SetDefaults
= = = = = = = = = = = = = = =
*/
static void GL_SetDefaults ( void )
{
pglFinish ( ) ;
pglClearColor ( 0.5f , 0.5f , 0.5f , 1.0f ) ;
pglDisable ( GL_DEPTH_TEST ) ;
pglDisable ( GL_CULL_FACE ) ;
pglDisable ( GL_SCISSOR_TEST ) ;
pglDepthFunc ( GL_LEQUAL ) ;
pglColor4f ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
2019-03-06 16:23:33 +03:00
if ( glState . stencilEnabled )
2019-02-23 21:49:46 +03:00
{
pglDisable ( GL_STENCIL_TEST ) ;
pglStencilMask ( ( GLuint ) ~ 0 ) ;
pglStencilFunc ( GL_EQUAL , 0 , ~ 0 ) ;
pglStencilOp ( GL_KEEP , GL_INCR , GL_INCR ) ;
}
pglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
pglPolygonOffset ( - 1.0f , - 2.0f ) ;
GL_CleanupAllTextureUnits ( ) ;
pglDisable ( GL_BLEND ) ;
pglDisable ( GL_ALPHA_TEST ) ;
pglDisable ( GL_POLYGON_OFFSET_FILL ) ;
pglAlphaFunc ( GL_GREATER , DEFAULT_ALPHATEST ) ;
pglEnable ( GL_TEXTURE_2D ) ;
pglShadeModel ( GL_SMOOTH ) ;
pglFrontFace ( GL_CCW ) ;
pglPointSize ( 1.2f ) ;
pglLineWidth ( 1.2f ) ;
GL_Cull ( GL_NONE ) ;
}
/*
= = = = = = = = = = = = = = = = =
R_RenderInfo_f
= = = = = = = = = = = = = = = = =
*/
2024-01-27 20:18:05 +03:00
static void R_RenderInfo_f ( void )
2019-02-23 21:49:46 +03:00
{
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " \n " ) ;
gEngfuncs . Con_Printf ( " GL_VENDOR: %s \n " , glConfig . vendor_string ) ;
gEngfuncs . Con_Printf ( " GL_RENDERER: %s \n " , glConfig . renderer_string ) ;
gEngfuncs . Con_Printf ( " GL_VERSION: %s \n " , glConfig . version_string ) ;
2019-02-23 21:49:46 +03:00
// don't spam about extensions
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Reportf ( " GL_EXTENSIONS: %s \n " , glConfig . extensions_string ) ;
2019-02-23 21:49:46 +03:00
2020-02-25 12:58:36 +07:00
if ( glConfig . wrapper = = GLES_WRAPPER_GL4ES )
{
2022-05-29 04:00:19 +03:00
const char * vendor = ( const char * ) pglGetString ( GL_VENDOR | 0x10000 ) ;
const char * renderer = ( const char * ) pglGetString ( GL_RENDERER | 0x10000 ) ;
const char * version = ( const char * ) pglGetString ( GL_VERSION | 0x10000 ) ;
const char * extensions = ( const char * ) pglGetString ( GL_EXTENSIONS | 0x10000 ) ;
2020-02-25 12:58:36 +07:00
if ( vendor )
gEngfuncs . Con_Printf ( " GL4ES_VENDOR: %s \n " , vendor ) ;
if ( renderer )
gEngfuncs . Con_Printf ( " GL4ES_RENDERER: %s \n " , renderer ) ;
if ( version )
gEngfuncs . Con_Printf ( " GL4ES_VERSION: %s \n " , version ) ;
if ( extensions )
gEngfuncs . Con_Reportf ( " GL4ES_EXTENSIONS: %s \n " , extensions ) ;
}
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " GL_MAX_TEXTURE_SIZE: %i \n " , glConfig . max_2d_texture_size ) ;
2019-02-23 21:49:46 +03:00
if ( GL_Support ( GL_ARB_MULTITEXTURE ) )
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " GL_MAX_TEXTURE_UNITS_ARB: %i \n " , glConfig . max_texture_units ) ;
2019-02-23 21:49:46 +03:00
if ( GL_Support ( GL_TEXTURE_CUBEMAP_EXT ) )
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: %i \n " , glConfig . max_cubemap_size ) ;
2019-02-23 21:49:46 +03:00
if ( GL_Support ( GL_ANISOTROPY_EXT ) )
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: %.1f \n " , glConfig . max_texture_anisotropy ) ;
2019-02-23 21:49:46 +03:00
if ( GL_Support ( GL_TEXTURE_2D_RECT_EXT ) )
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " GL_MAX_RECTANGLE_TEXTURE_SIZE: %i \n " , glConfig . max_2d_rectangle_size ) ;
2019-02-23 21:49:46 +03:00
if ( GL_Support ( GL_TEXTURE_ARRAY_EXT ) )
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " GL_MAX_ARRAY_TEXTURE_LAYERS_EXT: %i \n " , glConfig . max_2d_texture_layers ) ;
2019-02-23 21:49:46 +03:00
if ( GL_Support ( GL_SHADER_GLSL100_EXT ) )
{
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " GL_MAX_TEXTURE_COORDS_ARB: %i \n " , glConfig . max_texture_coords ) ;
gEngfuncs . Con_Printf ( " GL_MAX_TEXTURE_IMAGE_UNITS_ARB: %i \n " , glConfig . max_teximage_units ) ;
gEngfuncs . Con_Printf ( " GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: %i \n " , glConfig . max_vertex_uniforms ) ;
gEngfuncs . Con_Printf ( " GL_MAX_VERTEX_ATTRIBS_ARB: %i \n " , glConfig . max_vertex_attribs ) ;
2019-02-23 21:49:46 +03:00
}
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " \n " ) ;
2019-03-06 17:14:25 +03:00
gEngfuncs . Con_Printf ( " MODE: %ix%i \n " , gpGlobals - > width , gpGlobals - > height ) ;
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( " \n " ) ;
gEngfuncs . Con_Printf ( " VERTICAL SYNC: %s \n " , gl_vsync - > value ? " enabled " : " disabled " ) ;
gEngfuncs . Con_Printf ( " Color %d bits, Alpha %d bits, Depth %d bits, Stencil %d bits \n " , glConfig . color_bits ,
2019-02-23 21:49:46 +03:00
glConfig . alpha_bits , glConfig . depth_bits , glConfig . stencil_bits ) ;
}
2024-10-09 02:01:10 +03:00
# if XASH_GLES
2024-01-27 20:18:05 +03:00
static void GL_InitExtensionsGLES ( void )
2019-02-24 18:45:27 +03:00
{
2019-04-05 01:37:22 +03:00
int extid ;
2019-02-24 18:45:27 +03:00
// intialize wrapper type
2024-10-09 02:01:10 +03:00
# if XASH_NANOGL
2019-02-24 18:45:27 +03:00
glConfig . context = CONTEXT_TYPE_GLES_1_X ;
glConfig . wrapper = GLES_WRAPPER_NANOGL ;
2024-10-09 02:01:10 +03:00
# elif XASH_WES
2019-02-24 18:45:27 +03:00
glConfig . context = CONTEXT_TYPE_GLES_2_X ;
glConfig . wrapper = GLES_WRAPPER_WES ;
2024-10-09 02:01:10 +03:00
# elif XASH_GLES3COMPAT
2023-10-05 00:24:40 +03:00
glConfig . context = CONTEXT_TYPE_GLES_2_X ;
glConfig . wrapper = GLES_WRAPPER_NONE ;
2019-08-08 05:52:36 +03:00
# else
2024-10-09 02:01:10 +03:00
# error "unknown gles wrapper"
2019-02-24 18:45:27 +03:00
# endif
glConfig . hardware_type = GLHW_GENERIC ;
2019-08-08 05:52:36 +03:00
for ( extid = GL_OPENGL_110 + 1 ; extid < GL_EXTCOUNT ; extid + + )
2019-04-05 01:37:22 +03:00
{
switch ( extid )
{
2019-08-08 05:52:36 +03:00
case GL_ARB_VERTEX_BUFFER_OBJECT_EXT :
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " vertex_buffer_object " , vbofuncs , ARRAYSIZE ( vbofuncs ) , " gl_vertex_buffer_object " , extid , 1.0 ) ;
2019-08-08 05:52:36 +03:00
break ;
2019-04-05 01:37:22 +03:00
case GL_ARB_MULTITEXTURE :
2024-12-22 07:11:28 +03:00
if ( ! GL_CheckExtension ( " multitexture " , multitexturefuncs , ARRAYSIZE ( multitexturefuncs ) , " gl_arb_multitexture " , GL_ARB_MULTITEXTURE , 1.0 ) & & glConfig . wrapper = = GLES_WRAPPER_NONE )
2023-10-15 04:30:18 +03:00
{
2024-10-09 02:01:10 +03:00
# if !XASH_GL_STATIC
2024-12-22 07:11:28 +03:00
if ( ! GL_CheckExtension ( " multitexture_es1 " , multitexturefuncs_es , ARRAYSIZE ( multitexturefuncs_es ) , " gl_arb_multitexture " , GL_ARB_MULTITEXTURE , 1.0 )
& & ! GL_CheckExtension ( " multitexture_es2 " , multitexturefuncs_es2 , ARRAYSIZE ( multitexturefuncs_es2 ) , " gl_arb_multitexture " , GL_ARB_MULTITEXTURE , 2.0 ) )
2023-10-15 04:30:18 +03:00
break ;
2023-10-13 22:54:40 +03:00
# endif
2023-10-15 04:30:18 +03:00
}
GL_SetExtension ( extid , true ) ; // required to be supported by wrapper
2019-08-08 05:52:36 +03:00
pglGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & glConfig . max_texture_units ) ;
2023-10-06 01:46:17 +03:00
if ( glConfig . max_texture_units < = 1 )
pglGetIntegerv ( GL_MAX_TEXTURE_IMAGE_UNITS_ARB , & glConfig . max_texture_units ) ;
2019-09-28 21:13:38 +07:00
if ( glConfig . max_texture_units < = 1 )
{
2019-08-08 05:52:36 +03:00
GL_SetExtension ( extid , false ) ;
2019-09-28 21:13:38 +07:00
glConfig . max_texture_units = 1 ;
}
2019-08-08 05:52:36 +03:00
glConfig . max_texture_coords = glConfig . max_teximage_units = glConfig . max_texture_units ;
2019-04-05 01:37:22 +03:00
break ;
case GL_TEXTURE_CUBEMAP_EXT :
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_OES_texture_cube_map " , NULL , 0 , " gl_texture_cubemap " , extid , 0 ) )
2019-04-05 01:37:22 +03:00
pglGetIntegerv ( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB , & glConfig . max_cubemap_size ) ;
break ;
case GL_ANISOTROPY_EXT :
glConfig . max_texture_anisotropy = 0.0f ;
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_EXT_texture_filter_anisotropic " , NULL , 0 , " gl_ext_anisotropic_filter " , extid , 0 ) )
2019-04-05 01:37:22 +03:00
pglGetFloatv ( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT , & glConfig . max_texture_anisotropy ) ;
break ;
case GL_TEXTURE_LOD_BIAS :
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_EXT_texture_lod_bias " , NULL , 0 , " gl_texture_mipmap_biasing " , extid , 0 ) )
2019-04-05 01:37:22 +03:00
pglGetFloatv ( GL_MAX_TEXTURE_LOD_BIAS_EXT , & glConfig . max_texture_lod_bias ) ;
break ;
2019-08-08 05:52:36 +03:00
case GL_ARB_TEXTURE_NPOT_EXT :
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_OES_texture_npot " , NULL , 0 , " gl_texture_npot " , extid , 0 ) ;
2019-08-08 05:52:36 +03:00
break ;
2024-10-09 02:01:10 +03:00
# if !XASH_GL_STATIC
2023-10-05 00:24:40 +03:00
case GL_SHADER_OBJECTS_EXT :
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " ES2 Shaders " , shaderobjectsfuncs_gles , ARRAYSIZE ( shaderobjectsfuncs_gles ) , " gl_shaderobjects " , extid , 2.0 ) ;
2023-10-05 00:24:40 +03:00
break ;
2023-10-05 03:32:02 +03:00
case GL_ARB_VERTEX_ARRAY_OBJECT_EXT :
2024-12-22 07:11:28 +03:00
if ( ! GL_CheckExtension ( " GL_OES_vertex_array_object " , vaofuncs , ARRAYSIZE ( vaofuncs ) , " gl_vertex_array_object " , extid , 3.0 ) )
GL_CheckExtension ( " GL_EXT_vertex_array_object " , vaofuncs , ARRAYSIZE ( vaofuncs ) , " gl_vertex_array_object " , extid , 3.0 ) ;
2023-10-05 03:32:02 +03:00
break ;
2023-10-06 01:14:48 +03:00
case GL_DRAW_RANGEELEMENTS_EXT :
2024-12-22 07:11:28 +03:00
if ( ! GL_CheckExtension ( " GL_EXT_draw_range_elements " , drawrangeelementsfuncs , ARRAYSIZE ( drawrangeelementsfuncs ) , " gl_drawrangeelements " , extid , 3.0 ) )
GL_CheckExtension ( " GL_OES_draw_range_elements " , drawrangeelementsfuncs , ARRAYSIZE ( drawrangeelementsfuncs ) , " gl_drawrangeelements " , extid , 3.0 ) ;
2023-10-06 01:14:48 +03:00
break ;
2023-10-13 00:11:39 +03:00
case GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX_EXT :
2024-12-22 07:11:28 +03:00
if ( ! GL_CheckExtension ( " GL_OES_draw_elements_base_vertex " , drawrangeelementsbasevertexfuncs , ARRAYSIZE ( drawrangeelementsbasevertexfuncs ) , " gl_drawrangeelementsbasevertex " , GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX_EXT , 0 ) )
GL_CheckExtension ( " GL_EXT_draw_elements_base_vertex " , drawrangeelementsbasevertexfuncs , ARRAYSIZE ( drawrangeelementsbasevertexfuncs ) , " gl_drawrangeelementsbasevertex " , GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX_EXT , 3.2 ) ;
2023-10-13 00:11:39 +03:00
break ;
case GL_MAP_BUFFER_RANGE_EXT :
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_EXT_map_buffer_range " , mapbufferrangefuncs , ARRAYSIZE ( mapbufferrangefuncs ) , " gl_map_buffer_range " , GL_MAP_BUFFER_RANGE_EXT , 3.0 ) ;
2023-10-13 00:11:39 +03:00
break ;
case GL_BUFFER_STORAGE_EXT :
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_EXT_buffer_storage " , bufferstoragefuncs , ARRAYSIZE ( bufferstoragefuncs ) , " gl_buffer_storage " , GL_BUFFER_STORAGE_EXT , 0 ) ;
2023-10-13 00:11:39 +03:00
break ;
2023-10-05 18:57:26 +03:00
# endif
2019-08-08 05:52:36 +03:00
case GL_DEBUG_OUTPUT :
if ( glw_state . extended )
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_KHR_debug " , debugoutputfuncs , ARRAYSIZE ( debugoutputfuncs ) , " gl_debug_output " , extid , 0 ) ;
2023-10-26 04:47:44 +03:00
else
GL_SetExtension ( extid , false ) ;
2019-08-08 05:52:36 +03:00
break ;
2019-04-05 01:37:22 +03:00
// case GL_TEXTURE_COMPRESSION_EXT: NOPE
// case GL_SHADER_GLSL100_EXT: NOPE
// case GL_TEXTURE_2D_RECT_EXT: NOPE
// case GL_TEXTURE_ARRAY_EXT: NOPE
// case GL_TEXTURE_3D_EXT: NOPE
// case GL_CLAMPTOEDGE_EXT: NOPE
// case GL_CLAMP_TEXBORDER_EXT: NOPE
// case GL_ARB_TEXTURE_FLOAT_EXT: NOPE
// case GL_ARB_DEPTH_FLOAT_EXT: NOPE
// case GL_ARB_SEAMLESS_CUBEMAP: NOPE
// case GL_EXT_GPU_SHADER4: NOPE
// case GL_DEPTH_TEXTURE: NOPE
2019-11-17 18:51:03 +03:00
// case GL_DRAWRANGEELEMENTS_EXT: NOPE
2019-04-05 01:37:22 +03:00
default :
GL_SetExtension ( extid , false ) ;
}
}
2024-10-09 02:01:10 +03:00
# if !XASH_GL_STATIC
2023-10-05 00:24:40 +03:00
GL2_ShimInit ( ) ;
2023-10-05 18:57:26 +03:00
# endif
2019-02-24 18:45:27 +03:00
}
# else
2024-01-27 20:18:05 +03:00
static void GL_InitExtensionsBigGL ( void )
2019-02-24 18:45:27 +03:00
{
// intialize wrapper type
2023-10-05 03:32:02 +03:00
glConfig . context = gEngfuncs . Sys_CheckParm ( " -glcore " ) ? CONTEXT_TYPE_GL_CORE : CONTEXT_TYPE_GL ;
2019-02-24 18:45:27 +03:00
glConfig . wrapper = GLES_WRAPPER_NONE ;
if ( Q_stristr ( glConfig . renderer_string , " geforce " ) )
glConfig . hardware_type = GLHW_NVIDIA ;
else if ( Q_stristr ( glConfig . renderer_string , " quadro fx " ) )
glConfig . hardware_type = GLHW_NVIDIA ;
else if ( Q_stristr ( glConfig . renderer_string , " rv770 " ) )
glConfig . hardware_type = GLHW_RADEON ;
else if ( Q_stristr ( glConfig . renderer_string , " radeon hd " ) )
glConfig . hardware_type = GLHW_RADEON ;
else if ( Q_stristr ( glConfig . renderer_string , " eah4850 " ) | | Q_stristr ( glConfig . renderer_string , " eah4870 " ) )
glConfig . hardware_type = GLHW_RADEON ;
else if ( Q_stristr ( glConfig . renderer_string , " radeon " ) )
glConfig . hardware_type = GLHW_RADEON ;
else if ( Q_stristr ( glConfig . renderer_string , " intel " ) )
glConfig . hardware_type = GLHW_INTEL ;
else glConfig . hardware_type = GLHW_GENERIC ;
2020-02-25 12:58:36 +07:00
// gl4es may be used system-wide
if ( Q_stristr ( glConfig . renderer_string , " gl4es " ) )
glConfig . wrapper = GLES_WRAPPER_GL4ES ;
2019-02-24 18:45:27 +03:00
// multitexture
glConfig . max_texture_units = glConfig . max_texture_coords = glConfig . max_teximage_units = 1 ;
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_ARB_multitexture " , multitexturefuncs , ARRAYSIZE ( multitexturefuncs ) , " gl_arb_multitexture " , GL_ARB_MULTITEXTURE , 1.3f ) )
2019-02-24 18:45:27 +03:00
{
pglGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & glConfig . max_texture_units ) ;
}
if ( glConfig . max_texture_units = = 1 )
GL_SetExtension ( GL_ARB_MULTITEXTURE , false ) ;
// 3d texture support
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_EXT_texture3D " , texture3dextfuncs , ARRAYSIZE ( texture3dextfuncs ) , " gl_texture_3d " , GL_TEXTURE_3D_EXT , 2.0f ) )
2019-02-24 18:45:27 +03:00
{
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 ) ;
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Printf ( S_ERROR " GL_EXT_texture3D reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled \n " ) ;
2019-02-24 18:45:27 +03:00
}
}
// 2d texture array support
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_EXT_texture_array " , texture3dextfuncs , ARRAYSIZE ( texture3dextfuncs ) , " gl_texture_2d_array " , GL_TEXTURE_ARRAY_EXT , 0 ) )
2019-02-24 18:45:27 +03:00
pglGetIntegerv ( GL_MAX_ARRAY_TEXTURE_LAYERS_EXT , & glConfig . max_2d_texture_layers ) ;
// cubemaps support
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_ARB_texture_cube_map " , NULL , 0 , " gl_texture_cubemap " , GL_TEXTURE_CUBEMAP_EXT , 0 ) )
2019-02-24 18:45:27 +03:00
{
pglGetIntegerv ( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB , & glConfig . max_cubemap_size ) ;
// check for seamless cubemaps too
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_ARB_seamless_cube_map " , NULL , 0 , " gl_texture_cubemap_seamless " , GL_ARB_SEAMLESS_CUBEMAP , 0 ) ;
2019-02-24 18:45:27 +03:00
}
2025-02-28 17:08:21 +03:00
GL_CheckExtension ( " GL_ARB_texture_non_power_of_two " , NULL , 0 , " gl_texture_npot " , GL_ARB_TEXTURE_NPOT_EXT , 0 ) ;
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_ARB_texture_compression " , texturecompressionfuncs , ARRAYSIZE ( texturecompressionfuncs ) , " gl_texture_dxt_compression " , GL_TEXTURE_COMPRESSION_EXT , 0 ) ;
if ( ! GL_CheckExtension ( " GL_EXT_texture_edge_clamp " , NULL , 0 , " gl_clamp_to_edge " , GL_CLAMPTOEDGE_EXT , 2.0 ) ) // present in ES2
GL_CheckExtension ( " GL_SGIS_texture_edge_clamp " , NULL , 0 , " gl_clamp_to_edge " , GL_CLAMPTOEDGE_EXT , 0 ) ;
2019-02-24 18:45:27 +03:00
glConfig . max_texture_anisotropy = 0.0f ;
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_EXT_texture_filter_anisotropic " , NULL , 0 , " gl_texture_anisotropic_filter " , GL_ANISOTROPY_EXT , 0 ) )
2019-02-24 18:45:27 +03:00
pglGetFloatv ( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT , & glConfig . max_texture_anisotropy ) ;
2019-11-24 03:52:08 +03:00
# if XASH_WIN32 // Win32 only drivers?
2019-02-24 18:45:27 +03:00
// g-cont. because lodbias it too glitchy on Intel's cards
if ( glConfig . hardware_type ! = GLHW_INTEL )
# endif
2019-08-08 05:52:36 +03:00
{
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_EXT_texture_lod_bias " , NULL , 0 , " gl_texture_mipmap_biasing " , GL_TEXTURE_LOD_BIAS , 1.4 ) )
2019-08-08 05:52:36 +03:00
pglGetFloatv ( GL_MAX_TEXTURE_LOD_BIAS_EXT , & glConfig . max_texture_lod_bias ) ;
}
2019-02-24 18:45:27 +03:00
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_ARB_texture_border_clamp " , NULL , 0 , NULL , GL_CLAMP_TEXBORDER_EXT , 2.0 ) ; // present in ES2
2019-05-25 02:44:24 +03:00
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_ARB_depth_texture " , NULL , 0 , NULL , GL_DEPTH_TEXTURE , 1.4 ) ; // missing in gles, check GL_OES_depth_texture
GL_CheckExtension ( " GL_ARB_texture_float " , NULL , 0 , " gl_texture_float " , GL_ARB_TEXTURE_FLOAT_EXT , 0 ) ;
GL_CheckExtension ( " GL_ARB_depth_buffer_float " , NULL , 0 , " gl_texture_depth_float " , GL_ARB_DEPTH_FLOAT_EXT , 0 ) ;
GL_CheckExtension ( " GL_EXT_gpu_shader4 " , NULL , 0 , NULL , GL_EXT_GPU_SHADER4 , 0 ) ; // don't confuse users
GL_CheckExtension ( " GL_ARB_vertex_buffer_object " , vbofuncs , ARRAYSIZE ( vbofuncs ) , " gl_vertex_buffer_object " , GL_ARB_VERTEX_BUFFER_OBJECT_EXT , 2.0 ) ;
GL_CheckExtension ( " GL_ARB_texture_multisample " , multisampletexfuncs , ARRAYSIZE ( multisampletexfuncs ) , " gl_texture_multisample " , GL_TEXTURE_MULTISAMPLE , 0 ) ;
GL_CheckExtension ( " GL_ARB_texture_compression_bptc " , NULL , 0 , " gl_texture_bptc_compression " , GL_ARB_TEXTURE_COMPRESSION_BPTC , 0 ) ;
2024-10-09 02:01:10 +03:00
# if !XASH_GL_STATIC
2023-10-15 04:30:18 +03:00
if ( glConfig . context = = CONTEXT_TYPE_GL_CORE )
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " shader_objects " , shaderobjectsfuncs_gles , ARRAYSIZE ( shaderobjectsfuncs_gles ) , " gl_shaderobjects " , GL_SHADER_OBJECTS_EXT , 2.0 ) ;
2023-10-05 18:57:26 +03:00
else
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_ARB_shader_objects " , shaderobjectsfuncs , ARRAYSIZE ( shaderobjectsfuncs ) , " gl_shaderobjects " , GL_SHADER_OBJECTS_EXT , 2.0 ) ;
GL_CheckExtension ( " GL_ARB_vertex_array_object " , vaofuncs , ARRAYSIZE ( vaofuncs ) , " gl_vertex_array_object " , GL_ARB_VERTEX_ARRAY_OBJECT_EXT , 3.0 ) ;
GL_CheckExtension ( " GL_ARB_buffer_storage " , bufferstoragefuncs , ARRAYSIZE ( bufferstoragefuncs ) , " gl_buffer_storage " , GL_BUFFER_STORAGE_EXT , 4.4 ) ;
GL_CheckExtension ( " GL_ARB_map_buffer_range " , mapbufferrangefuncs , ARRAYSIZE ( mapbufferrangefuncs ) , " gl_map_buffer_range " , GL_MAP_BUFFER_RANGE_EXT , 3.0 ) ;
GL_CheckExtension ( " GL_ARB_draw_elements_base_vertex " , drawrangeelementsbasevertexfuncs , ARRAYSIZE ( drawrangeelementsbasevertexfuncs ) , " gl_drawrangeelementsbasevertex " , GL_DRAW_RANGE_ELEMENTS_BASE_VERTEX_EXT , 3.2 ) ;
2023-10-05 18:57:26 +03:00
# endif
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " GL_ARB_shading_language_100 " , NULL , 0 , NULL , GL_SHADER_GLSL100_EXT , 2.0 ) )
2019-02-24 18:45:27 +03:00
{
pglGetIntegerv ( GL_MAX_TEXTURE_COORDS_ARB , & glConfig . max_texture_coords ) ;
pglGetIntegerv ( GL_MAX_TEXTURE_IMAGE_UNITS_ARB , & glConfig . max_teximage_units ) ;
// check for hardware skinning
pglGetIntegerv ( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB , & glConfig . max_vertex_uniforms ) ;
pglGetIntegerv ( GL_MAX_VERTEX_ATTRIBS_ARB , & glConfig . max_vertex_attribs ) ;
2019-11-24 03:52:08 +03:00
# if XASH_WIN32 // Win32 only drivers?
2019-02-24 18:45:27 +03:00
if ( glConfig . hardware_type = = GLHW_RADEON & & glConfig . max_vertex_uniforms > 512 )
glConfig . max_vertex_uniforms / = 4 ; // radeon returns not correct info
# endif
}
else
{
// just get from multitexturing
glConfig . max_texture_coords = glConfig . max_teximage_units = glConfig . max_texture_units ;
}
2019-08-08 05:52:36 +03:00
// rectangle textures support
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_ARB_texture_rectangle " , NULL , 0 , " gl_texture_rectangle " , GL_TEXTURE_2D_RECT_EXT , 0 ) ;
2019-08-08 05:52:36 +03:00
2024-12-22 07:11:28 +03:00
if ( ! GL_CheckExtension ( " glDrawRangeElements " , drawrangeelementsfuncs , ARRAYSIZE ( drawrangeelementsfuncs ) , " gl_drawrangeelements " , GL_DRAW_RANGEELEMENTS_EXT , 0 ) )
2019-11-17 18:51:03 +03:00
{
2024-12-22 07:11:28 +03:00
if ( GL_CheckExtension ( " glDrawRangeElementsEXT " , drawrangeelementsextfuncs , ARRAYSIZE ( drawrangeelementsextfuncs ) ,
2023-10-15 04:30:18 +03:00
" gl_drawrangelements " , GL_DRAW_RANGEELEMENTS_EXT , 0 ) )
2019-11-17 18:51:03 +03:00
{
2024-10-09 02:01:10 +03:00
# if !XASH_GL_STATIC
2019-11-17 18:51:03 +03:00
pglDrawRangeElements = pglDrawRangeElementsEXT ;
2020-02-25 12:58:36 +07:00
# endif
2019-11-17 18:51:03 +03:00
}
}
2019-08-08 05:52:36 +03:00
// this won't work without extended context
if ( glw_state . extended )
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " GL_ARB_debug_output " , debugoutputfuncs , ARRAYSIZE ( debugoutputfuncs ) , " gl_debug_output " , GL_DEBUG_OUTPUT , 0 ) ;
2023-02-19 01:31:54 +01:00
# if XASH_PSVITA
2023-02-26 21:06:41 +01:00
// not all GL1.1 functions are implemented in vitaGL, but there's enough
GL_SetExtension ( GL_OPENGL_110 , true ) ;
2023-02-21 23:32:47 +01:00
// init our immediate mode override
VGL_ShimInit ( ) ;
2023-02-19 01:31:54 +01:00
# endif
2024-10-09 02:01:10 +03:00
# if !XASH_GLES && !XASH_GL_STATIC
2023-10-15 04:30:18 +03:00
if ( gEngfuncs . Sys_CheckParm ( " -gl2shim " ) )
2023-10-04 18:29:29 +03:00
GL2_ShimInit ( ) ;
# endif
2019-02-24 18:45:27 +03:00
}
# endif
void GL_InitExtensions ( void )
{
2022-12-18 22:55:53 +05:00
char value [ MAX_VA_STRING ] ;
2023-10-13 22:40:35 +03:00
GLint major = 0 , minor = 0 ;
2022-12-18 22:55:53 +05:00
2019-05-12 18:02:59 +03:00
GL_OnContextCreated ( ) ;
2019-02-24 18:45:27 +03:00
// initialize gl extensions
2024-12-22 07:11:28 +03:00
GL_CheckExtension ( " OpenGL 1.1.0 " , opengl_110funcs , ARRAYSIZE ( opengl_110funcs ) , NULL , GL_OPENGL_110 , 1.0 ) ;
2019-02-24 18:45:27 +03:00
// get our various GL strings
2019-07-13 23:25:03 +03:00
glConfig . vendor_string = ( const char * ) pglGetString ( GL_VENDOR ) ;
glConfig . renderer_string = ( const char * ) pglGetString ( GL_RENDERER ) ;
glConfig . version_string = ( const char * ) pglGetString ( GL_VERSION ) ;
glConfig . extensions_string = ( const char * ) pglGetString ( GL_EXTENSIONS ) ;
2023-10-13 22:40:35 +03:00
2023-10-15 04:30:18 +03:00
pglGetIntegerv ( GL_MAJOR_VERSION , & major ) ;
pglGetIntegerv ( GL_MINOR_VERSION , & minor ) ;
2023-10-13 22:40:35 +03:00
if ( ! major & & glConfig . version_string )
{
const char * str = glConfig . version_string ;
float ver ;
2023-10-15 04:30:18 +03:00
while ( * str & & ( * str < ' 0 ' | | * str > ' 9 ' ) ) str + + ;
2023-10-13 22:40:35 +03:00
ver = Q_atof ( str ) ;
if ( ver )
{
glConfig . version_major = ver ;
glConfig . version_minor = ( int ) ( ver * 10 ) % 10 ;
}
}
else
2023-10-12 21:46:08 +03:00
{
2023-10-13 22:40:35 +03:00
glConfig . version_major = major ;
glConfig . version_minor = minor ;
2023-10-12 21:46:08 +03:00
}
2024-10-09 02:01:10 +03:00
# if !XASH_GL_STATIC
2023-10-12 21:46:08 +03:00
if ( ! glConfig . extensions_string )
{
int n = 0 ;
2023-10-15 04:30:18 +03:00
pglGetStringi = gEngfuncs . GL_GetProcAddress ( " glGetStringi " ) ;
2023-10-12 21:46:08 +03:00
2023-10-15 04:30:18 +03:00
pglGetIntegerv ( GL_NUM_EXTENSIONS , & n ) ;
if ( n & & pglGetStringi )
2023-10-12 21:46:08 +03:00
{
2023-10-15 04:30:18 +03:00
int i , len = 1 ;
2023-10-12 21:46:08 +03:00
char * str ;
2023-10-15 04:30:18 +03:00
for ( i = 0 ; i < n ; i + + )
len + = Q_strlen ( ( const char * ) pglGetStringi ( GL_EXTENSIONS , i ) ) + 1 ;
2023-10-13 01:40:33 +03:00
str = ( char * ) Mem_Calloc ( r_temppool , len ) ;
2023-10-12 21:46:08 +03:00
glConfig . extensions_string = str ;
2023-10-15 04:30:18 +03:00
for ( i = 0 ; i < n ; i + + )
2023-10-12 21:46:08 +03:00
{
2023-10-15 04:30:18 +03:00
int l = Q_strncpy ( str , pglGetStringi ( GL_EXTENSIONS , i ) , len ) ;
2023-10-12 21:46:08 +03:00
str + = l ;
* str + + = ' ' ;
len - = l + 1 ;
}
}
}
# endif
2019-03-06 16:23:33 +03:00
gEngfuncs . Con_Reportf ( " ^3Video^7: %s \n " , glConfig . renderer_string ) ;
2019-02-24 18:45:27 +03:00
2024-10-09 02:01:10 +03:00
# if XASH_GLES
2019-02-24 18:45:27 +03:00
GL_InitExtensionsGLES ( ) ;
# else
GL_InitExtensionsBigGL ( ) ;
# endif
2019-08-08 05:52:36 +03:00
pglGetIntegerv ( GL_MAX_TEXTURE_SIZE , & glConfig . max_2d_texture_size ) ;
if ( glConfig . max_2d_texture_size < = 0 ) glConfig . max_2d_texture_size = 256 ;
2024-10-09 02:01:10 +03:00
# if !XASH_GL4ES
2019-04-05 01:37:22 +03:00
// enable gldebug if allowed
if ( GL_Support ( GL_DEBUG_OUTPUT ) )
{
if ( gpGlobals - > developer )
{
gEngfuncs . Con_Reportf ( " Installing GL_DebugOutput... \n " ) ;
pglDebugMessageCallbackARB ( GL_DebugOutput , NULL ) ;
// force everything to happen in the main thread instead of in a separate driver thread
pglEnable ( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB ) ;
2023-10-26 04:47:44 +03:00
2019-04-05 01:37:22 +03:00
}
// enable all the low priority messages
pglDebugMessageControlARB ( GL_DONT_CARE , GL_DONT_CARE , GL_DEBUG_SEVERITY_LOW_ARB , 0 , NULL , true ) ;
}
2020-02-25 12:58:36 +07:00
# endif
2019-02-24 18:45:27 +03:00
if ( GL_Support ( GL_TEXTURE_2D_RECT_EXT ) )
pglGetIntegerv ( GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT , & glConfig . max_2d_rectangle_size ) ;
2022-12-18 22:55:53 +05:00
Q_snprintf ( value , sizeof ( value ) , " %i " , glConfig . max_2d_texture_size ) ;
gEngfuncs . Cvar_Get ( " gl_max_size " , value , 0 , " opengl texture max dims " ) ;
2023-05-20 20:27:15 +03:00
gEngfuncs . Cvar_SetValue ( " gl_anisotropy " , bound ( 0 , gl_texture_anisotropy . value , glConfig . max_texture_anisotropy ) ) ;
2019-02-24 18:45:27 +03:00
if ( GL_Support ( GL_TEXTURE_COMPRESSION_EXT ) )
2019-03-06 16:23:33 +03:00
gEngfuncs . Image_AddCmdFlags ( IL_DDS_HARDWARE ) ;
2019-02-24 18:45:27 +03:00
// MCD has buffering issues
2019-11-24 03:52:08 +03:00
# if XASH_WIN32
2019-02-24 18:45:27 +03:00
if ( Q_strstr ( glConfig . renderer_string , " gdi " ) )
2019-03-06 17:14:25 +03:00
gEngfuncs . Cvar_SetValue ( " gl_finish " , 1 ) ;
2019-02-24 18:45:27 +03:00
# endif
2019-08-08 05:52:36 +03:00
R_RenderInfo_f ( ) ;
2019-02-24 18:45:27 +03:00
tr . framecount = tr . visframecount = 1 ;
glw_state . initialized = true ;
}
void GL_ClearExtensions ( void )
{
// now all extensions are disabled
memset ( glConfig . extension , 0 , sizeof ( glConfig . extension ) ) ;
glw_state . initialized = false ;
2023-02-21 23:32:47 +01:00
# if XASH_PSVITA
// deinit our immediate mode override
VGL_ShimShutdown ( ) ;
# endif
2019-02-24 18:45:27 +03:00
}
2019-02-23 21:49:46 +03:00
//=======================================================================
/*
= = = = = = = = = = = = = = = = =
GL_InitCommands
= = = = = = = = = = = = = = = = =
*/
2024-01-27 20:18:05 +03:00
static void GL_InitCommands ( void )
2019-02-23 21:49:46 +03:00
{
2021-12-06 04:57:32 +03:00
RETRIEVE_ENGINE_SHARED_CVAR_LIST ( ) ;
2023-05-20 20:27:15 +03:00
gEngfuncs . Cvar_RegisterVariable ( & r_lighting_extended ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_lighting_ambient ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_novis ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_nocull ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_detailtextures ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_lockpvs ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_lockfrustum ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_traceglow ) ;
2023-10-14 08:11:25 +03:00
gEngfuncs . Cvar_RegisterVariable ( & r_studio_sort_textures ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_studio_drawelements ) ;
2023-10-30 06:25:28 +03:00
gEngfuncs . Cvar_RegisterVariable ( & r_ripple ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_ripple_updatetime ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_ripple_spawntime ) ;
2024-10-28 02:10:24 +03:00
gEngfuncs . Cvar_RegisterVariable ( & r_shadows ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_vbo ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_vbo_dlightmode ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_vbo_overbrightmode ) ;
gEngfuncs . Cvar_RegisterVariable ( & r_vbo_detail ) ;
2025-02-05 13:02:37 +03:00
gEngfuncs . Cvar_RegisterVariable ( & r_large_lightmaps ) ;
2025-02-07 22:05:54 +03:00
gEngfuncs . Cvar_RegisterVariable ( & r_dlight_virtual_radius ) ;
2023-05-20 20:27:15 +03:00
gEngfuncs . Cvar_RegisterVariable ( & gl_extensions ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_texture_nearest ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_lightmap_nearest ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_check_errors ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_texture_anisotropy ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_texture_lodbias ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_keeptjunctions ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_finish ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_nosort ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_test ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_wireframe ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_msaa ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_stencilbits ) ;
gEngfuncs . Cvar_RegisterVariable ( & gl_round_down ) ;
2024-01-06 19:35:49 +03:00
gEngfuncs . Cvar_RegisterVariable ( & gl_overbright ) ;
2024-11-21 23:17:30 +04:00
gEngfuncs . Cvar_RegisterVariable ( & gl_fog ) ;
2021-12-06 04:57:32 +03:00
2019-02-23 21:49:46 +03:00
// these cvar not used by engine but some mods requires this
2023-05-20 20:27:15 +03:00
gEngfuncs . Cvar_RegisterVariable ( & gl_polyoffset ) ;
2019-02-23 21:49:46 +03:00
// make sure gl_vsync is checked after vid_restart
SetBits ( gl_vsync - > flags , FCVAR_CHANGED ) ;
2019-03-06 16:23:33 +03:00
gEngfuncs . Cmd_AddCommand ( " r_info " , R_RenderInfo_f , " display renderer info " ) ;
gEngfuncs . Cmd_AddCommand ( " timerefresh " , SCR_TimeRefresh_f , " turn quickly and print rendering statistcs " ) ;
2019-02-23 21:49:46 +03:00
}
/*
= = = = = = = = = = = = = = =
R_CheckVBO
register VBO cvars and get default value
= = = = = = = = = = = = = = =
*/
static void R_CheckVBO ( void )
{
qboolean disable = false ;
2024-10-28 02:10:24 +03:00
int flags = 0 ;
2019-02-23 21:49:46 +03:00
// some bad GLES1 implementations breaks dlights completely
if ( glConfig . max_texture_units < 3 )
disable = true ;
2024-10-09 02:01:10 +03:00
# if XASH_MOBILE_PLATFORM
2019-02-23 21:49:46 +03:00
// VideoCore4 drivers have a problem with mixing VBO and client arrays
// Disable it, as there is no suitable workaround here
if ( Q_stristr ( glConfig . renderer_string , " VideoCore IV " ) | | Q_stristr ( glConfig . renderer_string , " vc4 " ) )
disable = true ;
# endif
2024-10-28 02:10:24 +03:00
// we do not want to write vbo code that does not use multitexture
if ( ! GL_Support ( GL_ARB_VERTEX_BUFFER_OBJECT_EXT ) | | ! GL_Support ( GL_ARB_MULTITEXTURE ) | | glConfig . max_texture_units < 2 )
2019-02-23 21:49:46 +03:00
{
2024-10-28 02:10:24 +03:00
flags = FCVAR_READ_ONLY ;
disable = true ;
2019-02-23 21:49:46 +03:00
}
2024-10-28 02:10:24 +03:00
if ( disable )
{
gEngfuncs . Cvar_FullSet ( r_vbo . name , " 0 " , flags ) ;
gEngfuncs . Cvar_FullSet ( r_vbo_dlightmode . name , " 0 " , flags ) ;
}
2019-02-23 21:49:46 +03:00
}
2019-03-16 05:15:32 +03:00
/*
= = = = = = = = = = = = = = = = =
GL_RemoveCommands
= = = = = = = = = = = = = = = = =
*/
2024-01-27 20:18:05 +03:00
static void GL_RemoveCommands ( void )
2019-03-16 05:15:32 +03:00
{
gEngfuncs . Cmd_RemoveCommand ( " r_info " ) ;
2024-10-28 01:59:39 +03:00
gEngfuncs . Cmd_RemoveCommand ( " timerefresh " ) ;
2019-03-16 05:15:32 +03:00
}
2019-02-23 21:49:46 +03:00
/*
= = = = = = = = = = = = = = =
R_Init
= = = = = = = = = = = = = = =
*/
qboolean R_Init ( void )
{
if ( glw_state . initialized )
return true ;
GL_InitCommands ( ) ;
GL_InitRandomTable ( ) ;
GL_SetDefaultState ( ) ;
2023-10-13 01:40:33 +03:00
r_temppool = Mem_AllocPool ( " Render Zone " ) ;
2019-02-23 21:49:46 +03:00
// create the window and set up the context
2019-03-16 05:15:32 +03:00
if ( ! gEngfuncs . R_Init_Video ( REF_GL ) ) // request GL context
2019-02-23 21:49:46 +03:00
{
GL_RemoveCommands ( ) ;
2019-03-16 05:15:32 +03:00
gEngfuncs . R_Free_Video ( ) ;
2020-07-08 08:46:07 +07:00
// Why? Host_Error again???
// gEngfuncs.Host_Error( "Can't initialize video subsystem\nProbably driver was not installed" );
2023-10-13 01:40:33 +03:00
Mem_FreePool ( & r_temppool ) ;
2019-02-23 21:49:46 +03:00
return false ;
}
2023-11-02 02:44:50 +03:00
// see R_ProcessEntData for tr.entities initialization
2023-12-28 22:19:30 +03:00
tr . world = ( struct world_static_s * ) ENGINE_GET_PARM ( PARM_GET_WORLD_PTR ) ;
tr . movevars = ( movevars_t * ) ENGINE_GET_PARM ( PARM_GET_MOVEVARS_PTR ) ;
tr . palette = ( color24 * ) ENGINE_GET_PARM ( PARM_GET_PALETTE_PTR ) ;
tr . viewent = ( cl_entity_t * ) ENGINE_GET_PARM ( PARM_GET_VIEWENT_PTR ) ;
2024-11-02 22:11:22 +03:00
tr . texgammatable = ( byte * ) ENGINE_GET_PARM ( PARM_GET_TEXGAMMATABLE_PTR ) ;
tr . lightgammatable = ( uint * ) ENGINE_GET_PARM ( PARM_GET_LIGHTGAMMATABLE_PTR ) ;
tr . screengammatable = ( uint * ) ENGINE_GET_PARM ( PARM_GET_SCREENGAMMATABLE_PTR ) ;
tr . lineargammatable = ( uint * ) ENGINE_GET_PARM ( PARM_GET_LINEARGAMMATABLE_PTR ) ;
2024-11-02 22:51:57 +03:00
tr . dlights = ( dlight_t * ) ENGINE_GET_PARM ( PARM_GET_DLIGHTS_PTR ) ;
tr . elights = ( dlight_t * ) ENGINE_GET_PARM ( PARM_GET_ELIGHTS_PTR ) ;
2023-11-02 02:44:50 +03:00
2019-02-23 21:49:46 +03:00
GL_SetDefaults ( ) ;
R_CheckVBO ( ) ;
R_InitImages ( ) ;
R_SpriteInit ( ) ;
R_StudioInit ( ) ;
R_AliasInit ( ) ;
R_ClearDecals ( ) ;
R_ClearScene ( ) ;
return true ;
}
/*
= = = = = = = = = = = = = = =
R_Shutdown
= = = = = = = = = = = = = = =
*/
void R_Shutdown ( void )
{
if ( ! glw_state . initialized )
return ;
GL_RemoveCommands ( ) ;
R_ShutdownImages ( ) ;
2024-10-09 02:01:10 +03:00
# if !XASH_GLES && !XASH_GL_STATIC
2023-10-13 16:25:30 +03:00
GL2_ShimShutdown ( ) ;
# endif
2019-02-23 21:49:46 +03:00
Mem_FreePool ( & r_temppool ) ;
2024-10-09 02:01:10 +03:00
# if XASH_GL4ES
2021-10-31 20:59:20 +06:00
close_gl4es ( ) ;
# endif // XASH_GL4ES
2019-02-23 21:49:46 +03:00
// shut down OS specific OpenGL stuff like contexts, etc.
2019-03-16 05:15:32 +03:00
gEngfuncs . R_Free_Video ( ) ;
2019-02-23 21:49:46 +03:00
}
/*
= = = = = = = = = = = = = = = = =
GL_ErrorString
convert errorcode to string
= = = = = = = = = = = = = = = = =
*/
const char * GL_ErrorString ( int err )
{
switch ( err )
{
case GL_STACK_OVERFLOW :
return " GL_STACK_OVERFLOW " ;
case GL_STACK_UNDERFLOW :
return " GL_STACK_UNDERFLOW " ;
case GL_INVALID_ENUM :
return " GL_INVALID_ENUM " ;
case GL_INVALID_VALUE :
return " GL_INVALID_VALUE " ;
case GL_INVALID_OPERATION :
return " GL_INVALID_OPERATION " ;
case GL_OUT_OF_MEMORY :
return " GL_OUT_OF_MEMORY " ;
default :
return " UNKNOWN ERROR " ;
}
}
/*
= = = = = = = = = = = = = = = = =
GL_CheckForErrors
obsolete
= = = = = = = = = = = = = = = = =
*/
void GL_CheckForErrors_ ( const char * filename , const int fileline )
{
int err ;
2023-05-20 20:27:15 +03:00
if ( ! gl_check_errors . value )
2019-02-23 21:49:46 +03:00
return ;
if ( ( err = pglGetError ( ) ) = = GL_NO_ERROR )
return ;
2021-08-01 20:09:00 +04:00
gEngfuncs . Con_Printf ( S_OPENGL_ERROR " %s (at %s:%i) \n " , GL_ErrorString ( err ) , filename , fileline ) ;
2019-02-23 21:49:46 +03:00
}
2019-03-16 05:15:32 +03:00
void GL_SetupAttributes ( int safegl )
{
int context_flags = 0 ; // REFTODO!!!!!
int samples = 0 ;
2024-10-09 02:01:10 +03:00
# if XASH_GLES
2019-03-16 05:15:32 +03:00
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_PROFILE_MASK , REF_GL_CONTEXT_PROFILE_ES ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_EGL , 1 ) ;
2024-10-09 02:01:10 +03:00
# if XASH_NANOGL
2019-03-16 05:15:32 +03:00
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MAJOR_VERSION , 1 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MINOR_VERSION , 1 ) ;
2024-10-09 02:01:10 +03:00
# else // !XASH_NANOGL
2019-03-16 05:15:32 +03:00
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MAJOR_VERSION , 2 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MINOR_VERSION , 0 ) ;
# endif
2024-10-09 02:01:10 +03:00
# elif XASH_GL4ES
2020-02-25 12:58:36 +07:00
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_PROFILE_MASK , REF_GL_CONTEXT_PROFILE_ES ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_EGL , 1 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MAJOR_VERSION , 2 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MINOR_VERSION , 0 ) ;
2019-03-16 05:15:32 +03:00
# else // GL1.x
if ( gEngfuncs . Sys_CheckParm ( " -glcore " ) )
{
SetBits ( context_flags , FCONTEXT_CORE_PROFILE ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_PROFILE_MASK , REF_GL_CONTEXT_PROFILE_CORE ) ;
2023-10-05 03:32:02 +03:00
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MAJOR_VERSION , 3 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MINOR_VERSION , 3 ) ;
2019-03-16 05:15:32 +03:00
}
else
{
2023-10-13 05:05:34 +03:00
if ( ! safegl )
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_PROFILE_MASK , REF_GL_CONTEXT_PROFILE_COMPATIBILITY ) ;
else
{
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MAJOR_VERSION , 1 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_MINOR_VERSION , 1 ) ;
}
2019-03-16 05:15:32 +03:00
}
# endif // XASH_GLES
2023-10-15 04:30:18 +03:00
if ( gEngfuncs . Sys_CheckParm ( " -gldebug " ) )
2019-04-05 01:37:22 +03:00
{
gEngfuncs . Con_Reportf ( " Creating an extended GL context for debug... \n " ) ;
SetBits ( context_flags , FCONTEXT_DEBUG_ARB ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_CONTEXT_FLAGS , REF_GL_CONTEXT_DEBUG_FLAG ) ;
glw_state . extended = true ;
}
2019-03-16 05:15:32 +03:00
if ( safegl > SAFE_DONTCARE )
{
safegl = - 1 ; // can't retry anymore, can only shutdown engine
return ;
}
gEngfuncs . Con_Printf ( " Trying safe opengl mode %d \n " , safegl ) ;
if ( safegl = = SAFE_DONTCARE )
return ;
gEngfuncs . GL_SetAttribute ( REF_GL_DOUBLEBUFFER , 1 ) ;
if ( safegl < SAFE_NOACC )
gEngfuncs . GL_SetAttribute ( REF_GL_ACCELERATED_VISUAL , 1 ) ;
2019-10-26 04:37:01 +03:00
gEngfuncs . Con_Printf ( " bpp %d \n " , gpGlobals - > desktopBitsPixel ) ;
2019-03-16 05:15:32 +03:00
if ( safegl < SAFE_NOSTENCIL )
2023-05-20 20:27:15 +03:00
gEngfuncs . GL_SetAttribute ( REF_GL_STENCIL_SIZE , gl_stencilbits . value ) ;
2019-03-16 05:15:32 +03:00
if ( safegl < SAFE_NOALPHA )
gEngfuncs . GL_SetAttribute ( REF_GL_ALPHA_SIZE , 8 ) ;
if ( safegl < SAFE_NODEPTH )
gEngfuncs . GL_SetAttribute ( REF_GL_DEPTH_SIZE , 24 ) ;
else
gEngfuncs . GL_SetAttribute ( REF_GL_DEPTH_SIZE , 8 ) ;
if ( safegl < SAFE_NOCOLOR )
{
2019-10-26 04:37:01 +03:00
if ( gpGlobals - > desktopBitsPixel > = 24 )
2019-03-16 05:15:32 +03:00
{
gEngfuncs . GL_SetAttribute ( REF_GL_RED_SIZE , 8 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_GREEN_SIZE , 8 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_BLUE_SIZE , 8 ) ;
}
2019-10-26 04:37:01 +03:00
else if ( gpGlobals - > desktopBitsPixel > = 16 )
2019-03-16 05:15:32 +03:00
{
gEngfuncs . GL_SetAttribute ( REF_GL_RED_SIZE , 5 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_GREEN_SIZE , 6 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_BLUE_SIZE , 5 ) ;
}
else
{
gEngfuncs . GL_SetAttribute ( REF_GL_RED_SIZE , 3 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_GREEN_SIZE , 3 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_BLUE_SIZE , 2 ) ;
}
}
if ( safegl < SAFE_NOMSAA )
{
2021-11-22 13:42:16 +04:00
switch ( ( int ) gEngfuncs . pfnGetCvarFloat ( " gl_msaa_samples " ) )
2019-03-16 05:15:32 +03:00
{
case 2 :
case 4 :
case 8 :
case 16 :
2021-11-22 13:42:16 +04:00
samples = gEngfuncs . pfnGetCvarFloat ( " gl_msaa_samples " ) ;
2019-03-16 05:15:32 +03:00
break ;
default :
samples = 0 ; // don't use, because invalid parameter is passed
}
if ( samples )
{
gEngfuncs . GL_SetAttribute ( REF_GL_MULTISAMPLEBUFFERS , 1 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_MULTISAMPLESAMPLES , samples ) ;
glConfig . max_multisamples = samples ;
}
else
{
gEngfuncs . GL_SetAttribute ( REF_GL_MULTISAMPLEBUFFERS , 0 ) ;
gEngfuncs . GL_SetAttribute ( REF_GL_MULTISAMPLESAMPLES , 0 ) ;
glConfig . max_multisamples = 0 ;
}
}
else
{
2021-11-22 13:42:16 +04:00
gEngfuncs . Cvar_Set ( " gl_msaa_samples " , " 0 " ) ;
2019-03-16 05:15:32 +03:00
}
}
2019-10-06 06:55:04 +03:00
void wes_init ( const char * gles2 ) ;
int nanoGL_Init ( void ) ;
2024-10-09 02:01:10 +03:00
# if XASH_GL4ES
2024-01-27 20:18:05 +03:00
static void GL4ES_GetMainFBSize ( int * width , int * height )
2020-02-25 12:58:36 +07:00
{
* width = gpGlobals - > width ;
* height = gpGlobals - > height ;
}
2024-01-27 20:18:05 +03:00
static void * GL4ES_GetProcAddress ( const char * name )
2020-02-25 12:58:36 +07:00
{
if ( ! Q_strcmp ( name , " glShadeModel " ) )
// combined gles/gles2/gl implementation exports this, but it is invalid
return NULL ;
return gEngfuncs . GL_GetProcAddress ( name ) ;
}
2024-10-09 02:01:10 +03:00
# endif // XASH_GL4ES
2019-10-06 06:55:04 +03:00
2019-03-16 05:15:32 +03:00
void GL_OnContextCreated ( void )
{
int colorBits [ 3 ] ;
2024-10-09 02:01:10 +03:00
# if XASH_NANOGL
2019-03-16 05:15:32 +03:00
nanoGL_Init ( ) ;
# endif
gEngfuncs . GL_GetAttribute ( REF_GL_RED_SIZE , & colorBits [ 0 ] ) ;
gEngfuncs . GL_GetAttribute ( REF_GL_GREEN_SIZE , & colorBits [ 1 ] ) ;
gEngfuncs . GL_GetAttribute ( REF_GL_BLUE_SIZE , & colorBits [ 2 ] ) ;
glConfig . color_bits = colorBits [ 0 ] + colorBits [ 1 ] + colorBits [ 2 ] ;
gEngfuncs . GL_GetAttribute ( REF_GL_ALPHA_SIZE , & glConfig . alpha_bits ) ;
gEngfuncs . GL_GetAttribute ( REF_GL_DEPTH_SIZE , & glConfig . depth_bits ) ;
gEngfuncs . GL_GetAttribute ( REF_GL_STENCIL_SIZE , & glConfig . stencil_bits ) ;
glState . stencilEnabled = glConfig . stencil_bits ? true : false ;
gEngfuncs . GL_GetAttribute ( REF_GL_MULTISAMPLESAMPLES , & glConfig . msaasamples ) ;
2023-10-12 21:46:08 +03:00
gEngfuncs . GL_GetAttribute ( REF_GL_CONTEXT_MAJOR_VERSION , & glConfig . version_major ) ;
gEngfuncs . GL_GetAttribute ( REF_GL_CONTEXT_MINOR_VERSION , & glConfig . version_minor ) ;
2019-03-16 05:15:32 +03:00
2024-10-09 02:01:10 +03:00
# if XASH_WES
2019-08-08 05:52:36 +03:00
wes_init ( " " ) ;
2024-10-09 02:01:10 +03:00
# endif // XASH_WES
# if XASH_GL4ES
2020-02-25 12:58:36 +07:00
set_getprocaddress ( GL4ES_GetProcAddress ) ;
set_getmainfbsize ( GL4ES_GetMainFBSize ) ;
initialize_gl4es ( ) ;
// merge glBegin/glEnd in beams and console
pglHint ( GL_BEGINEND_HINT_GL4ES , 1 ) ;
// dxt unpacked to 16-bit looks ugly
pglHint ( GL_AVOID16BITS_HINT_GL4ES , 1 ) ;
2024-10-09 02:01:10 +03:00
# endif // XASH_GL4ES
2020-02-25 12:58:36 +07:00
}