2019-01-13 16:51:50 +00:00
/*
Lingering issues :
nvidia vsync :
with vsync enabled and framerates fluctuating across the 1000f ps boundary , there is serious stuttering , like its re - showing the previous frame again .
this only happens with windows gl , and not vulkan / d3d so I ' m assuming this is a driver bug with it mispredicting timings .
workaround : enable bloom or something else that ' s wasteful in terms of gpu time , to keep it under 1000f ps .
nouveau vsync :
vsync seems forced when running fullscreen , but not when running windowed .
workaround : run windowed .
nouveau framerates :
nouveau doesn ' t seem to have any pstate control enabled .
workaround : sudo echo AUTO > / sys / kernel / debug / dri / 0 / pstate
( you could also use different ids for explicit pstates - eg to return to a low - power state )
( the engine cannot do this , as it requires root , nor does it know WHICH dri device to control )
( more recent gpus might not support this at all due to nvidia blocking them , but works for my 750 ti )
( note that nouveau ' s presentation engine isn ' t that good , so don ' t expect 5000f ps , but it should make rtlights usable )
core vs compatibility :
vid_gl_context_compatibility defaults to 1 , because it still gives higher framerates ( due to streaming vertex data from the cpu ) .
*/
2004-08-22 22:29:09 +00:00
# include "quakedef.h"
2009-11-04 21:16:50 +00:00
# ifdef GLQUAKE
2004-08-22 22:29:09 +00:00
# include "glquake.h"
2009-11-04 21:16:50 +00:00
# include "gl_draw.h"
2011-01-04 02:56:16 +00:00
# include "shader.h"
2018-04-27 16:40:50 +00:00
extern cvar_t gl_immutable_textures ;
extern cvar_t gl_immutable_buffers ;
2013-04-02 05:18:17 +00:00
# ifndef GL_STATIC
//standard gles2 opengl calls.
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglBlendFunc ) ( GLenum sfactor , GLenum dfactor ) ;
void ( APIENTRY * qglClear ) ( GLbitfield mask ) ;
void ( APIENTRY * qglClearColor ) ( GLclampf red , GLclampf green , GLclampf blue , GLclampf alpha ) ;
void ( APIENTRY * qglClearStencil ) ( GLint s ) ;
void ( APIENTRY * qglColorMask ) ( GLboolean red , GLboolean green , GLboolean blue , GLboolean alpha ) ;
2005-01-12 22:15:50 +00:00
void ( APIENTRY * qglCopyTexImage2D ) ( GLenum target , GLint level , GLenum internalFormat , GLint x , GLint y , GLsizei width , GLsizei height , GLint border ) ;
2006-03-03 03:31:19 +00:00
void ( APIENTRY * qglCopyTexSubImage2D ) ( GLenum target , GLint level , GLint xoffset , GLint yoffset , GLint x , GLint y , GLsizei width , GLsizei height ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglCullFace ) ( GLenum mode ) ;
void ( APIENTRY * qglDepthFunc ) ( GLenum func ) ;
void ( APIENTRY * qglDepthMask ) ( GLboolean flag ) ;
2018-01-22 19:18:04 +00:00
//void (APIENTRY *qglDepthRangef) (GLclampf zNear, GLclampf zFar);
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglDisable ) ( GLenum cap ) ;
void ( APIENTRY * qglEnable ) ( GLenum cap ) ;
void ( APIENTRY * qglFinish ) ( void ) ;
void ( APIENTRY * qglFlush ) ( void ) ;
2009-11-04 21:16:50 +00:00
void ( APIENTRY * qglGenTextures ) ( GLsizei n , GLuint * textures ) ;
2019-09-04 08:32:22 +00:00
void ( APIENTRY * qglGenerateMipmap ) ( GLenum target ) ;
2012-09-30 05:52:03 +00:00
void ( APIENTRY * qglGetBooleanv ) ( GLenum pname , GLboolean * params ) ;
2004-09-13 03:20:04 +00:00
GLenum ( APIENTRY * qglGetError ) ( void ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglGetFloatv ) ( GLenum pname , GLfloat * params ) ;
void ( APIENTRY * qglGetIntegerv ) ( GLenum pname , GLint * params ) ;
const GLubyte * ( APIENTRY * qglGetString ) ( GLenum name ) ;
void ( APIENTRY * qglHint ) ( GLenum target , GLenum mode ) ;
2013-05-14 18:38:42 +00:00
GLboolean ( APIENTRY * qglIsEnabled ) ( GLenum cap ) ;
2019-06-17 04:21:41 +00:00
void ( APIENTRY * qglPixelStorei ) ( GLenum pname , GLint param ) ;
2013-04-02 05:18:17 +00:00
void ( APIENTRY * qglPolygonOffset ) ( GLfloat factor , GLfloat units ) ;
2019-03-03 02:02:29 +00:00
void ( APIENTRY * qglLineWidth ) ( GLfloat width ) ;
2013-04-02 05:18:17 +00:00
void ( APIENTRY * qglReadPixels ) ( GLint x , GLint y , GLsizei width , GLsizei height , GLenum format , GLenum type , GLvoid * pixels ) ;
void ( APIENTRY * qglTexImage2D ) ( GLenum target , GLint level , GLint internalformat , GLsizei width , GLsizei height , GLint border , GLenum format , GLenum type , const GLvoid * pixels ) ;
void ( APIENTRY * qglTexSubImage2D ) ( GLenum target , GLint level , GLint xoffset , GLint yoffset , GLsizei width , GLsizei height , GLenum format , GLenum type , const GLvoid * pixels ) ;
void ( APIENTRY * qglTexParameteri ) ( GLenum target , GLenum pname , GLint param ) ;
void ( APIENTRY * qglTexParameterf ) ( GLenum target , GLenum pname , GLfloat param ) ;
void ( APIENTRY * qglTexParameteriv ) ( GLenum target , GLenum pname , const GLint * params ) ;
void ( APIENTRY * qglTexParameterfv ) ( GLenum target , GLenum pname , const GLfloat * params ) ;
void ( APIENTRY * qglViewport ) ( GLint x , GLint y , GLsizei width , GLsizei height ) ;
void ( APIENTRY * qglDrawElements ) ( GLenum mode , GLsizei count , GLenum type , const GLvoid * indices ) ;
void ( APIENTRY * qglDrawArrays ) ( GLenum mode , GLint first , GLsizei count ) ;
void ( APIENTRY * qglScissor ) ( GLint x , GLint y , GLsizei width , GLsizei height ) ;
void ( APIENTRY * qglStencilOp ) ( GLenum fail , GLenum zfail , GLenum zpass ) ;
void ( APIENTRY * qglStencilFunc ) ( GLenum func , GLint ref , GLuint mask ) ;
void ( APIENTRY * qglDeleteTextures ) ( GLsizei n , const GLuint * textures ) ;
2018-03-05 04:00:56 +00:00
FTEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2D ;
void ( APIENTRY * qglCompressedTexSubImage2D ) ( GLenum target , GLint level , GLint xoffset , GLint yoffset , GLsizei width , GLsizei height , GLenum format , GLsizei imageSize , const void * data ) ; //gl1.3
2013-04-02 05:18:17 +00:00
void ( APIENTRY * qglGenFramebuffersEXT ) ( GLsizei n , GLuint * ids ) ;
void ( APIENTRY * qglDeleteFramebuffersEXT ) ( GLsizei n , const GLuint * ids ) ;
void ( APIENTRY * qglBindFramebufferEXT ) ( GLenum target , GLuint id ) ;
void ( APIENTRY * qglDeleteRenderbuffersEXT ) ( GLsizei n , const GLuint * ids ) ;
void ( APIENTRY * qglFramebufferTexture2DEXT ) ( GLenum target , GLenum attachmentPoint , GLenum textureTarget , GLuint textureId , GLint level ) ;
FTEPFNGLVERTEXATTRIBPOINTER qglVertexAttribPointer ;
2018-11-27 16:48:19 +00:00
FTEPFNGLVERTEXATTRIB4FARBPROC qglVertexAttrib4f ;
2013-04-02 05:18:17 +00:00
FTEPFNGLGETVERTEXATTRIBIV qglGetVertexAttribiv ;
FTEPFNGLENABLEVERTEXATTRIBARRAY qglEnableVertexAttribArray ;
FTEPFNGLDISABLEVERTEXATTRIBARRAY qglDisableVertexAttribArray ;
2019-04-15 18:43:42 +00:00
void ( APIENTRY * qglStencilOpSeparate ) ( GLenum face , GLenum fail , GLenum zfail , GLenum zpass ) ;
2013-05-08 02:06:02 +00:00
void ( APIENTRY * qglGetFramebufferAttachmentParameteriv ) ( GLenum target , GLenum attachment , GLenum pname , GLint * params ) ;
2013-05-13 13:43:18 +00:00
void ( APIENTRY * qglGetVertexAttribPointerv ) ( GLuint index , GLenum pname , GLvoid * * pointer ) ;
2013-04-02 05:18:17 +00:00
//quick hack that made quake work on both 1+ext and 1.1 gl implementations.
BINDTEXFUNCPTR qglBindTexture ;
2013-04-04 08:08:49 +00:00
/*glslang - arb_shader_objects
gl core uses different names / distinctions from the extension
*/
2014-05-10 13:42:13 +00:00
FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB ;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_ ;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_ ;
FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB ;
FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB ;
FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB ;
FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB ;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_ ;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_ ;
FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB ;
FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_ ;
FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_ ;
FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB ;
FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB ;
2013-04-04 08:08:49 +00:00
FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB ;
2014-05-10 13:42:13 +00:00
FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB ;
2013-04-04 08:08:49 +00:00
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4fvARB ;
2014-05-10 13:42:13 +00:00
FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB ;
FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB ;
FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB ;
FTEPFNGLUNIFORM3FVARBPROC qglUniform3fvARB ;
FTEPFNGLUNIFORM4FVARBPROC qglUniform2fvARB ;
FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB ;
FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB ;
FTEPFNGLGETSHADERSOURCEARBPROC qglGetShaderSource ;
2013-04-02 05:18:17 +00:00
# endif
2014-08-25 07:35:41 +00:00
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix3x4fv ;
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4x3fv ;
2016-07-12 00:40:13 +00:00
//GL_ARB_occlusion_query
void ( APIENTRY * qglGenQueriesARB ) ( GLsizei n , GLuint * ids ) ;
void ( APIENTRY * qglDeleteQueriesARB ) ( GLsizei n , const GLuint * ids ) ;
//extern GLboolean (APIENTRY *qglIsQueryARB)(GLuint id);
void ( APIENTRY * qglBeginQueryARB ) ( GLenum target , GLuint id ) ;
void ( APIENTRY * qglEndQueryARB ) ( GLenum target ) ;
//extern void (APIENTRY *qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
//extern void (APIENTRY *qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
void ( APIENTRY * qglGetQueryObjectuivARB ) ( GLuint id , GLenum pname , GLuint * params ) ;
2014-08-25 07:35:41 +00:00
//GL_OES_get_program_binary
void ( APIENTRY * qglGetProgramBinary ) ( GLuint program , GLsizei bufSize , GLsizei * length , GLenum * binaryFormat , GLvoid * binary ) ;
void ( APIENTRY * qglProgramBinary ) ( GLuint program , GLenum binaryFormat , const GLvoid * binary , GLint length ) ;
# define GL_PROGRAM_BINARY_LENGTH 0x8741
2013-04-02 05:18:17 +00:00
//standard 1.1 opengl calls
void ( APIENTRY * qglAlphaFunc ) ( GLenum func , GLclampf ref ) ;
void ( APIENTRY * qglBegin ) ( GLenum mode ) ;
void ( APIENTRY * qglCallList ) ( GLuint list ) ;
void ( APIENTRY * qglClearDepth ) ( GLclampd depth ) ;
void ( APIENTRY * qglClipPlane ) ( GLenum plane , const GLdouble * equation ) ;
2015-09-14 10:36:42 +00:00
//void (APIENTRY *qglColor3f) (GLfloat red, GLfloat green, GLfloat blue);
//void (APIENTRY *qglColor3ub) (GLubyte red, GLubyte green, GLubyte blue);
2013-04-02 05:18:17 +00:00
void ( APIENTRY * qglColor4f ) ( GLfloat red , GLfloat green , GLfloat blue , GLfloat alpha ) ;
void ( APIENTRY * qglColor4fv ) ( const GLfloat * v ) ;
2015-09-14 10:36:42 +00:00
//void (APIENTRY *qglColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
//void (APIENTRY *qglColor4ubv) (const GLubyte *v);
2018-01-22 19:18:04 +00:00
//void (APIENTRY *qglDepthRange) (GLclampd zNear, GLclampd zFar);
2013-04-02 05:18:17 +00:00
void ( APIENTRY * qglDrawBuffer ) ( GLenum mode ) ;
void ( APIENTRY * qglDrawPixels ) ( GLsizei width , GLsizei height , GLenum format , GLenum type , const GLvoid * pixels ) ;
void ( APIENTRY * qglEnd ) ( void ) ;
void ( APIENTRY * qglEndList ) ( void ) ;
void ( APIENTRY * qglFrustum ) ( GLdouble left , GLdouble right , GLdouble bottom , GLdouble top , GLdouble zNear , GLdouble zFar ) ;
GLuint ( APIENTRY * qglGenLists ) ( GLsizei range ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglLoadIdentity ) ( void ) ;
void ( APIENTRY * qglLoadMatrixf ) ( const GLfloat * m ) ;
void ( APIENTRY * qglNormal3f ) ( GLfloat nx , GLfloat ny , GLfloat nz ) ;
void ( APIENTRY * qglNormal3fv ) ( const GLfloat * v ) ;
void ( APIENTRY * qglMatrixMode ) ( GLenum mode ) ;
void ( APIENTRY * qglMultMatrixf ) ( const GLfloat * m ) ;
2005-09-09 23:40:55 +00:00
void ( APIENTRY * qglNewList ) ( GLuint list , GLenum mode ) ;
2015-07-03 02:07:41 +00:00
//void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglPolygonMode ) ( GLenum face , GLenum mode ) ;
void ( APIENTRY * qglPopMatrix ) ( void ) ;
void ( APIENTRY * qglPushMatrix ) ( void ) ;
void ( APIENTRY * qglReadBuffer ) ( GLenum mode ) ;
void ( APIENTRY * qglRotatef ) ( GLfloat angle , GLfloat x , GLfloat y , GLfloat z ) ;
void ( APIENTRY * qglScalef ) ( GLfloat x , GLfloat y , GLfloat z ) ;
void ( APIENTRY * qglShadeModel ) ( GLenum mode ) ;
void ( APIENTRY * qglTexCoord1f ) ( GLfloat s ) ;
void ( APIENTRY * qglTexCoord2f ) ( GLfloat s , GLfloat t ) ;
void ( APIENTRY * qglTexCoord2fv ) ( const GLfloat * v ) ;
void ( APIENTRY * qglTexEnvf ) ( GLenum target , GLenum pname , GLfloat param ) ;
2004-09-13 03:20:04 +00:00
void ( APIENTRY * qglTexEnvfv ) ( GLenum target , GLenum pname , const GLfloat * param ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglTexEnvi ) ( GLenum target , GLenum pname , GLint param ) ;
void ( APIENTRY * qglTexGeni ) ( GLenum coord , GLenum pname , GLint param ) ;
2009-07-05 18:45:53 +00:00
void ( APIENTRY * qglTexGenfv ) ( GLenum coord , GLenum pname , const GLfloat * param ) ;
2011-12-23 03:12:29 +00:00
void ( APIENTRY * qglTexImage3D ) ( GLenum target , GLint level , GLint internalformat , GLsizei width , GLsizei height , GLsizei depth , GLint border , GLenum format , GLenum type , const GLvoid * pixels ) ;
2018-03-04 14:41:16 +00:00
void ( APIENTRY * qglTexSubImage3D ) ( GLenum target , GLint level , GLint xoffset , GLint yoffset , GLint zoffset , GLsizei width , GLsizei height , GLsizei depth , GLenum format , GLenum type , const void * pixels ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglTranslatef ) ( GLfloat x , GLfloat y , GLfloat z ) ;
void ( APIENTRY * qglVertex2f ) ( GLfloat x , GLfloat y ) ;
void ( APIENTRY * qglVertex3f ) ( GLfloat x , GLfloat y , GLfloat z ) ;
void ( APIENTRY * qglVertex3fv ) ( const GLfloat * v ) ;
void ( APIENTRY * qglGetTexLevelParameteriv ) ( GLenum target , GLint level , GLenum pname , GLint * params ) ;
2013-05-13 13:43:18 +00:00
void ( APIENTRY * qglGetTexEnviv ) ( GLenum target , GLenum pname , GLint * params ) ;
2004-08-22 22:29:09 +00:00
2005-05-13 10:42:48 +00:00
void ( APIENTRY * qglDrawRangeElements ) ( GLenum , GLuint , GLuint , GLsizei , GLenum , const GLvoid * ) ;
2019-01-13 16:51:50 +00:00
void ( APIENTRY * qglMultiDrawElements ) ( GLenum mode , const GLsizei * count , GLenum type , const GLvoid * const * indices , GLsizei drawcount ) ;
2004-10-19 16:10:14 +00:00
void ( APIENTRY * qglArrayElement ) ( GLint i ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglVertexPointer ) ( GLint size , GLenum type , GLsizei stride , const GLvoid * pointer ) ;
void ( APIENTRY * qglNormalPointer ) ( GLenum type , GLsizei stride , const GLvoid * pointer ) ;
void ( APIENTRY * qglTexCoordPointer ) ( GLint size , GLenum type , GLsizei stride , const GLvoid * pointer ) ;
void ( APIENTRY * qglColorPointer ) ( GLint size , GLenum type , GLsizei stride , const GLvoid * pointer ) ;
void ( APIENTRY * qglDisableClientState ) ( GLenum array ) ;
void ( APIENTRY * qglEnableClientState ) ( GLenum array ) ;
void ( APIENTRY * qglPushAttrib ) ( GLbitfield mask ) ;
void ( APIENTRY * qglPopAttrib ) ( void ) ;
2006-06-02 17:42:36 +00:00
2014-10-22 19:41:20 +00:00
GLenum ( APIENTRY * qglGetGraphicsResetStatus ) ( void ) ;
2006-06-02 17:42:36 +00:00
void ( APIENTRY * qglFogf ) ( GLenum pname , GLfloat param ) ;
void ( APIENTRY * qglFogi ) ( GLenum pname , GLint param ) ;
void ( APIENTRY * qglFogfv ) ( GLenum pname , const GLfloat * params ) ;
2013-08-07 14:20:24 +00:00
# ifndef GL_STATIC
2009-05-24 10:11:17 +00:00
void ( APIENTRY * qglGenBuffersARB ) ( GLsizei n , GLuint * ids ) ;
void ( APIENTRY * qglDeleteBuffersARB ) ( GLsizei n , GLuint * ids ) ;
void ( APIENTRY * qglBindBufferARB ) ( GLenum target , GLuint id ) ;
void ( APIENTRY * qglBufferDataARB ) ( GLenum target , GLsizei size , const void * data , GLenum usage ) ;
void ( APIENTRY * qglBufferSubDataARB ) ( GLenum target , GLint offset , GLsizei size , void * data ) ;
2009-06-21 17:45:33 +00:00
void * ( APIENTRY * qglMapBufferARB ) ( GLenum target , GLenum access ) ;
GLboolean ( APIENTRY * qglUnmapBufferARB ) ( GLenum target ) ;
2017-09-20 11:27:13 +00:00
void * ( APIENTRY * qglMapBufferRange ) ( GLenum target , GLintptr offset , GLsizeiptr length , GLbitfield access ) ;
2013-08-07 14:20:24 +00:00
# endif
2009-05-24 10:11:17 +00:00
2018-04-08 14:24:50 +00:00
void ( APIENTRY * qglBufferStorage ) ( GLenum target , GLsizeiptr size , const GLvoid * data , GLbitfield flags ) ;
2018-03-04 14:41:16 +00:00
void ( APIENTRY * qglTexStorage2D ) ( GLenum target , GLsizei levels , GLenum internalformat , GLsizei width , GLsizei height ) ; //gl4.2
void ( APIENTRY * qglTexStorage3D ) ( GLenum target , GLsizei levels , GLenum internalformat , GLsizei width , GLsizei height , GLsizei depth ) ; //gl4.2
2018-03-05 04:00:56 +00:00
FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImage ;
2018-03-04 14:41:16 +00:00
void ( APIENTRY * qglCompressedTexSubImage3D ) ( GLenum target , GLint level , GLint xoffset , GLint yoffset , GLint zoffset , GLsizei width , GLsizei height , GLsizei depth , GLenum format , GLsizei imageSize , const void * data ) ; //gl1.3
2018-03-05 04:00:56 +00:00
FTEPFNGLCOMPRESSEDTEXIMAGE3DARBPROC qglCompressedTexImage3D ;
2018-03-04 14:41:16 +00:00
2012-04-24 07:59:11 +00:00
void ( APIENTRY * qglGenVertexArrays ) ( GLsizei n , GLuint * arrays ) ;
void ( APIENTRY * qglBindVertexArray ) ( GLuint vaoarray ) ;
2009-11-04 21:16:50 +00:00
const GLubyte * ( APIENTRY * qglGetStringi ) ( GLenum name , GLuint index ) ;
2013-05-13 13:43:18 +00:00
void ( APIENTRY * qglGetPointerv ) ( GLenum pname , GLvoid * * parms ) ;
2009-11-04 21:16:50 +00:00
2014-08-27 08:41:31 +00:00
void ( APIENTRY * qglDrawBuffers ) ( GLsizei n , GLsizei * ids ) ; //gl2
2013-08-07 14:20:24 +00:00
# ifndef GL_STATIC
2014-08-27 08:41:31 +00:00
void ( APIENTRY * qglGenRenderbuffersEXT ) ( GLsizei n , GLuint * ids ) ;
2009-11-04 21:16:50 +00:00
void ( APIENTRY * qglBindRenderbufferEXT ) ( GLenum target , GLuint id ) ;
void ( APIENTRY * qglRenderbufferStorageEXT ) ( GLenum target , GLenum internalFormat , GLsizei width , GLsizei height ) ;
2011-09-03 03:49:43 +00:00
void ( APIENTRY * qglFramebufferRenderbufferEXT ) ( GLenum target , GLenum attachmentPoint , GLenum textureTarget , GLuint textureId ) ;
GLenum ( APIENTRY * qglCheckFramebufferStatusEXT ) ( GLenum target ) ;
2013-08-07 14:20:24 +00:00
# endif
2009-11-04 21:16:50 +00:00
2013-03-12 23:09:25 +00:00
void ( APIENTRY * qglDepthBoundsEXT ) ( GLclampd zmin , GLclampd zmax ) ;
2005-04-19 21:09:29 +00:00
/*
2004-09-13 03:20:04 +00:00
PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB ;
PFNGLBINDPROGRAMARBPROC qglBindProgramARB ;
PFNGLGENPROGRAMSARBPROC qglGenProgramsARB ;
2005-04-19 21:09:29 +00:00
*/
2007-09-22 19:28:27 +00:00
FTEPFNGLLOCKARRAYSEXTPROC qglLockArraysEXT ;
FTEPFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT ;
2004-08-22 22:29:09 +00:00
//extensions
//arb multitexture
2013-08-07 14:20:24 +00:00
# ifndef qglActiveTextureARB
2004-08-22 22:29:09 +00:00
qlpSelTexFUNC qglActiveTextureARB ;
2013-08-07 14:20:24 +00:00
# endif
2004-08-22 22:29:09 +00:00
qlpSelTexFUNC qglClientActiveTextureARB ;
//generic multitexture
lpSelTexFUNC qglSelectTextureSGIS ;
int mtexid0 ;
//ati_truform
2007-09-22 19:28:27 +00:00
FTEPFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI ;
FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI ;
2004-08-22 22:29:09 +00:00
2014-11-05 05:39:24 +00:00
void ( APIENTRY * qglPatchParameteriARB ) ( GLenum pname , GLint value ) ; //core in gl4
2004-08-22 22:29:09 +00:00
//stencil shadowing
2007-09-22 19:28:27 +00:00
FTEPFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
# define GLchar char
2013-08-06 10:48:51 +00:00
# ifdef NACL
# undef DEBUG
# elif defined(_DEBUG) && !defined(DEBUG)
2010-07-28 21:55:10 +00:00
# define DEBUG
# endif
# if defined(DEBUG)
2014-03-30 00:39:37 +00:00
//always defining this, my system headers use void instead of GLvoid which results in gcc warnings.
typedef void ( APIENTRY * qGLDEBUGPROCARB ) ( GLenum source ,
2012-01-01 02:26:42 +00:00
GLenum type ,
GLuint id ,
2010-07-28 21:55:10 +00:00
GLenum severity ,
2012-01-01 02:26:42 +00:00
GLsizei length ,
2010-07-28 21:55:10 +00:00
const GLchar * message ,
GLvoid * userParam ) ;
2012-09-30 05:52:03 +00:00
void ( APIENTRY * qglDebugMessageControlARB ) ( GLenum source ,
GLenum type ,
GLenum severity ,
2010-07-28 21:55:10 +00:00
GLsizei count ,
const GLuint * ids ,
GLboolean enabled ) ;
2012-09-30 05:52:03 +00:00
void ( APIENTRY * qglDebugMessageInsertARB ) ( GLenum source ,
GLenum type ,
2010-07-28 21:55:10 +00:00
GLuint id ,
2012-09-30 05:52:03 +00:00
GLenum severity ,
2010-07-28 21:55:10 +00:00
GLsizei length ,
const char * buf ) ;
2014-03-30 00:39:37 +00:00
void ( APIENTRY * qglDebugMessageCallbackARB ) ( qGLDEBUGPROCARB callback ,
2010-07-28 21:55:10 +00:00
void * userParam ) ;
2012-01-01 02:26:42 +00:00
GLuint ( APIENTRY * qglGetDebugMessageLogARB ) ( GLuint count ,
2010-07-28 21:55:10 +00:00
GLsizei bufsize ,
2012-01-01 02:26:42 +00:00
GLenum * sources ,
GLenum * types ,
2010-07-28 21:55:10 +00:00
GLuint * ids ,
2012-01-01 02:26:42 +00:00
GLuint * severities ,
GLsizei * lengths ,
char * messageLog ) ;
2014-03-30 00:39:37 +00:00
# ifndef GL_ARB_debug_output
2012-01-01 02:26:42 +00:00
# define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
# define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
# define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
# define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
# define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
# define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
# define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
# define GL_DEBUG_SOURCE_API_ARB 0x8246
# define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
# define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
# define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
# define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
# define GL_DEBUG_SOURCE_OTHER_ARB 0x824B
# define GL_DEBUG_TYPE_ERROR_ARB 0x824C
# define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
# define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
# define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
# define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
# define GL_DEBUG_TYPE_OTHER_ARB 0x8251
# define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
# define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
# define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
2014-03-30 00:39:37 +00:00
# endif
2012-01-01 02:26:42 +00:00
void ( APIENTRY myGLDEBUGPROCAMD ) ( GLenum source ,
GLenum type ,
GLuint id ,
2010-07-28 21:55:10 +00:00
GLenum severity ,
GLsizei length ,
const GLchar * message ,
GLvoid * userParam )
{
# ifndef _WIN32
2013-11-10 21:41:12 +00:00
# define OutputDebugStringA(s) puts(s)
2010-07-28 21:55:10 +00:00
# endif
2012-01-01 02:26:42 +00:00
switch ( type )
2010-07-28 21:55:10 +00:00
{
2012-01-01 02:26:42 +00:00
case GL_DEBUG_TYPE_ERROR_ARB :
2013-11-10 21:14:28 +00:00
OutputDebugStringA ( " Error: " ) ;
2010-07-28 21:55:10 +00:00
break ;
2012-01-01 02:26:42 +00:00
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB :
2013-11-10 21:14:28 +00:00
OutputDebugStringA ( " Depricated: " ) ;
2010-07-28 21:55:10 +00:00
break ;
2012-01-01 02:26:42 +00:00
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB :
2013-11-10 21:14:28 +00:00
OutputDebugStringA ( " Undefined: " ) ;
2010-07-28 21:55:10 +00:00
break ;
2012-01-01 02:26:42 +00:00
case GL_DEBUG_TYPE_PORTABILITY_ARB :
2013-11-10 21:14:28 +00:00
OutputDebugStringA ( " Portability: " ) ;
2010-07-28 21:55:10 +00:00
break ;
2012-01-01 02:26:42 +00:00
case GL_DEBUG_TYPE_PERFORMANCE_ARB :
2013-11-10 21:14:28 +00:00
OutputDebugStringA ( " Performance: " ) ;
2010-07-28 21:55:10 +00:00
break ;
default :
2012-01-01 02:26:42 +00:00
case GL_DEBUG_TYPE_OTHER_ARB :
2014-12-02 02:00:41 +00:00
return ;
2013-11-10 21:14:28 +00:00
OutputDebugStringA ( " Other: " ) ;
2010-07-28 21:55:10 +00:00
break ;
}
2013-11-10 21:14:28 +00:00
OutputDebugStringA ( message ) ;
OutputDebugStringA ( " \n " ) ;
2010-07-28 21:55:10 +00:00
}
# endif
2004-08-22 22:29:09 +00:00
int gl_mtexarbable = 0 ; //max texture units
qboolean gl_mtexable = false ;
2004-09-13 03:20:04 +00:00
2016-07-17 18:41:01 +00:00
extern qboolean gammaworks ; //if the gl drivers can set proper gamma.
2004-08-22 22:29:09 +00:00
2004-10-19 16:10:14 +00:00
gl_config_t gl_config ;
2011-12-05 15:23:40 +00:00
int gl_stencilbits ;
2004-12-09 23:44:29 +00:00
float gldepthmin , gldepthmax ;
const char * gl_vendor ;
const char * gl_renderer ;
const char * gl_version ;
2009-11-04 21:16:50 +00:00
static const char * gl_extensions ;
static unsigned int gl_num_extensions ;
2011-12-27 08:35:19 +00:00
extern cvar_t gl_workaround_ati_shadersource ;
2009-11-04 21:16:50 +00:00
qboolean GL_CheckExtension ( char * extname )
{
int i ;
2012-11-27 03:23:19 +00:00
int len ;
const char * foo ;
2010-07-11 02:22:39 +00:00
cvar_t * v = Cvar_Get ( va ( " gl_ext_%s " , extname ) , " 1 " , 0 , " GL Extensions " ) ;
if ( v & & ! v - > ival )
2012-09-30 05:52:03 +00:00
{
Con_Printf ( " Cvar %s is 0 \n " , v - > name ) ;
2010-07-11 02:22:39 +00:00
return false ;
2012-09-30 05:52:03 +00:00
}
2010-07-11 02:22:39 +00:00
2009-11-04 21:16:50 +00:00
if ( gl_num_extensions & & qglGetStringi )
{
for ( i = 0 ; i < gl_num_extensions ; i + + )
if ( ! strcmp ( qglGetStringi ( GL_EXTENSIONS , i ) , extname ) )
2012-09-30 05:52:03 +00:00
{
2019-05-23 15:11:32 +00:00
Con_DPrintf ( " GL: Found %s \n " , extname ) ;
2009-11-04 21:16:50 +00:00
return true ;
2012-09-30 05:52:03 +00:00
}
2009-11-04 21:16:50 +00:00
}
if ( ! gl_extensions )
return false ;
2004-10-19 16:10:14 +00:00
2012-11-27 03:23:19 +00:00
//the list is space delimited. we cannot just strstr lest we find leading/trailing _FOO_.
len = strlen ( extname ) ;
for ( foo = gl_extensions ; * foo ; )
{
if ( ! strncmp ( foo , extname , len ) & & ( foo [ len ] = = ' ' | | ! foo [ len ] ) )
return true ;
while ( * foo & & * foo ! = ' ' )
foo + + ;
if ( * foo = = ' ' )
foo + + ;
}
return false ;
2009-11-04 21:16:50 +00:00
}
2009-06-21 17:45:33 +00:00
2005-05-23 05:32:55 +00:00
void APIENTRY GL_DrawRangeElementsEmul ( GLenum mode , GLuint start , GLuint end , GLsizei count , GLenum type , const GLvoid * indices )
2005-05-21 01:33:58 +00:00
{
2005-05-23 05:32:55 +00:00
qglDrawElements ( mode , count , type , indices ) ;
2005-05-21 01:33:58 +00:00
}
2015-09-14 10:36:42 +00:00
void APIENTRY GL_Color4fv_Emul ( const GLfloat * v )
{
qglColor4f ( v [ 0 ] , v [ 1 ] , v [ 2 ] , v [ 3 ] ) ;
}
2009-07-11 18:23:07 +00:00
void APIENTRY GL_BindBufferARBStub ( GLenum target , GLuint id )
{
}
2005-05-21 01:33:58 +00:00
2011-02-06 20:56:39 +00:00
void APIENTRY GL_ClientStateStub ( GLenum array )
{
}
2012-11-27 03:23:19 +00:00
void APIENTRY GL_ClientActiveTextureStub ( GLenum texid )
{
}
2004-08-22 22:29:09 +00:00
# define getglcore getglfunction
# define getglext(name) getglfunction(name)
2012-04-24 07:59:11 +00:00
void GL_CheckExtensions ( void * ( * getglfunction ) ( char * name ) )
2004-08-22 22:29:09 +00:00
{
2013-04-02 05:18:17 +00:00
qboolean webgl = false ;
2012-04-24 07:59:11 +00:00
unsigned int gl_major_version = 0 ;
unsigned int gl_minor_version = 0 ;
2004-10-19 16:10:14 +00:00
memset ( & gl_config , 0 , sizeof ( gl_config ) ) ;
2004-08-22 22:29:09 +00:00
2013-04-02 05:18:17 +00:00
if ( ! strncmp ( gl_version , " WebGL " , 5 ) )
{
gl_config . gles = true ;
webgl = true ;
2014-08-25 07:35:41 +00:00
if ( ! strcmp ( gl_renderer , " Internet Explorer " ) )
gl_config . webgl_ie = true ;
2013-04-02 05:18:17 +00:00
}
else if ( ! strncmp ( gl_version , " OpenGL ES " , 9 ) )
2011-01-23 03:44:49 +00:00
gl_config . gles = true ;
else
gl_config . gles = false ;
2012-04-24 07:59:11 +00:00
if ( ! gl_config . gles )
{
if ( qglGetError ( ) )
Con_Printf ( " glGetError %s:%i \n " , __FILE__ , __LINE__ ) ;
qglGetIntegerv ( GL_MAJOR_VERSION , & gl_major_version ) ;
qglGetIntegerv ( GL_MINOR_VERSION , & gl_minor_version ) ;
}
if ( ! gl_major_version | | qglGetError ( ) )
{
/*GL_MAJOR_VERSION not supported? try and parse (es-aware)*/
const char * s ;
for ( s = gl_version ; * s & & ( * s < ' 0 ' | | * s > ' 9 ' ) ; s + + )
;
gl_major_version = atoi ( s ) ;
while ( * s > = ' 0 ' & & * s < = ' 9 ' )
s + + ;
if ( * s = = ' . ' )
s + + ;
gl_minor_version = atoi ( s ) ;
}
2015-09-14 10:36:42 +00:00
# ifdef _DEBUG
{ extern cvar_t vid_gl_context_es ;
if ( vid_gl_context_es . ival = = 3 )
{
gl_config . gles = true ;
gl_major_version = 1 ;
gl_minor_version = 0 ;
} }
# endif
2014-08-27 08:41:31 +00:00
if ( webgl ) //webgl version 1 equates to gles 2.
{
if ( gl_major_version < 1 )
{ //ie reports a bollocks version. don't try using fixed function stuff.
gl_major_version = 2 ;
gl_minor_version = 0 ;
}
else if ( gl_major_version = = 1 )
gl_major_version + = 1 ;
//webgl2 is not defined yet. either 2 will be gles3 or they'll skip it or something I don't know.
//so assume webgl2 is still equivelent to gles2, to avoid confusions.
}
//FIXME: verify gles3 works properly.
2012-11-27 03:23:19 +00:00
//yes, I know, this can't cope with minor versions of 10+... I don't care yet.
gl_config . glversion + = gl_major_version + ( gl_minor_version / 10.f ) ;
2012-04-24 07:59:11 +00:00
/*gl3 adds glGetStringi instead, as core, with the old form require GL_ARB_compatibility*/
if ( gl_major_version > = 3 & & qglGetStringi ) /*warning: wine fails to export qglGetStringi*/
{
int i ;
qglGetIntegerv ( GL_NUM_EXTENSIONS , & gl_num_extensions ) ;
2018-09-23 19:35:24 +00:00
if ( developer . value > 1 )
2012-04-24 07:59:11 +00:00
{
Con_Printf ( " GL_EXTENSIONS: \n " ) ;
for ( i = 0 ; i < gl_num_extensions ; i + + )
{
Con_Printf ( " %s " , qglGetStringi ( GL_EXTENSIONS , i ) ) ;
Con_Printf ( " \n " ) ;
}
Con_Printf ( " end of list \n " ) ;
}
else
Con_DPrintf ( " GL_EXTENSIONS: %i extensions \n " , gl_num_extensions ) ;
gl_extensions = NULL ;
}
else
{
gl_num_extensions = 0 ;
gl_extensions = qglGetString ( GL_EXTENSIONS ) ;
Con_DPrintf ( " GL_EXTENSIONS: %s \n " , gl_extensions ) ;
if ( ! gl_extensions )
Sys_Error ( " no extensions \n " ) ;
}
2015-09-14 10:36:42 +00:00
# ifdef _DEBUG
{ extern cvar_t vid_gl_context_es ;
if ( vid_gl_context_es . ival = = 3 )
{
gl_extensions = " " ;
} }
# endif
2011-05-20 04:10:46 +00:00
if ( gl_config . gles )
gl_config . nofixedfunc = gl_config . glversion > = 2 ;
else
{
/*in gl3.0 things are depricated but not removed*/
/*in gl3.1 depricated things are removed unless compatibility is present*/
2011-05-27 17:59:31 +00:00
/*in gl3.2 there's a profile flag we can query*/
2011-06-05 23:53:33 +00:00
if ( gl_config . glversion > = 3.2 )
2011-05-27 17:59:31 +00:00
{
GLint profile = 0 ;
# define GL_CONTEXT_PROFILE_MASK 0x9126
2011-06-05 01:36:14 +00:00
# define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
2011-05-27 17:59:31 +00:00
# define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
2013-05-03 04:28:08 +00:00
# define GL_CONTEXT_FLAGS 0x821E
2014-03-30 00:39:37 +00:00
# ifndef GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT
2013-05-03 04:28:08 +00:00
# define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
2014-03-30 00:39:37 +00:00
# endif
2011-05-27 17:59:31 +00:00
qglGetIntegerv ( GL_CONTEXT_PROFILE_MASK , & profile ) ;
2011-06-05 01:36:14 +00:00
if ( ! profile )
{
Con_DPrintf ( " Driver reports invalid profile, assuming compatibility support \n " ) ;
gl_config . nofixedfunc = false ;
}
else
gl_config . nofixedfunc = ! ( profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT ) ;
2011-05-27 17:59:31 +00:00
}
2013-05-03 04:28:08 +00:00
else if ( gl_config . glversion > = 3.0 )
{
GLint flags = 0 ;
qglGetIntegerv ( GL_CONTEXT_FLAGS , & flags ) ;
gl_config . nofixedfunc = ! ! ( flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT ) ;
if ( gl_config . glversion > = 3.0999 )
gl_config . nofixedfunc = ! GL_CheckExtension ( " GL_ARB_compatibility " ) ;
}
2011-05-20 04:10:46 +00:00
else
gl_config . nofixedfunc = false ;
2014-10-22 19:41:20 +00:00
# ifdef GLSLONLY
gl_config . nofixedfunc = true ;
# endif
2011-05-20 04:10:46 +00:00
}
2011-01-23 03:44:49 +00:00
2012-01-17 07:57:46 +00:00
gl_config . maxglslversion = 0 ;
if ( gl_config . gles & & gl_config . glversion > = 2 )
2017-11-05 13:15:08 +00:00
{
if ( gl_config . glversion > = 3.2 )
gl_config . maxglslversion = 320 ;
else if ( gl_config . glversion > = 3.1 )
gl_config . maxglslversion = 310 ;
else if ( gl_config . glversion > = 3 )
gl_config . maxglslversion = 300 ;
else
gl_config . maxglslversion = 100 ;
}
2012-01-17 07:57:46 +00:00
else if ( gl_config . glversion > = 2 )
{
# define GL_SHADING_LANGUAGE_VERSION 0x8B8C
const char * s = qglGetString ( GL_SHADING_LANGUAGE_VERSION ) ;
if ( s )
{
gl_config . maxglslversion = atoi ( s ) * 100 ;
while ( * s > = ' 0 ' & & * s < = ' 9 ' )
s + + ;
if ( * s = = ' . ' )
s + + ;
gl_config . maxglslversion + = atoi ( s ) ;
}
else
gl_config . maxglslversion = 110 ;
}
else
gl_config . maxglslversion = 110 ;
2004-08-22 22:29:09 +00:00
//multitexture
gl_mtexable = false ;
gl_mtexarbable = 0 ;
2013-08-07 14:20:24 +00:00
# ifndef qglActiveTextureARB
2004-08-22 22:29:09 +00:00
qglActiveTextureARB = NULL ;
2013-08-07 14:20:24 +00:00
# endif
2004-08-22 22:29:09 +00:00
qglSelectTextureSGIS = NULL ;
mtexid0 = 0 ;
2013-04-02 05:18:17 +00:00
# ifndef GL_STATIC
qglGenFramebuffersEXT = NULL ;
qglDeleteFramebuffersEXT = NULL ;
qglBindFramebufferEXT = NULL ;
qglGenRenderbuffersEXT = NULL ;
qglDeleteRenderbuffersEXT = NULL ;
qglBindRenderbufferEXT = NULL ;
qglRenderbufferStorageEXT = NULL ;
qglFramebufferTexture2DEXT = NULL ;
# endif
2004-08-22 22:29:09 +00:00
//no GL_EXT_stencil_two_side
qglActiveStencilFaceEXT = NULL ;
//no truform. sorry.
qglPNTrianglesfATI = NULL ;
qglPNTrianglesiATI = NULL ;
2004-09-13 03:20:04 +00:00
//fragment programs
2005-04-19 21:09:29 +00:00
/* gl_config.arb_fragment_program = false;
2004-09-13 03:20:04 +00:00
qglProgramStringARB = NULL ;
qglGetProgramivARB = NULL ;
qglBindProgramARB = NULL ;
qglGenProgramsARB = NULL ;
2005-04-19 21:09:29 +00:00
*/
2004-09-13 03:20:04 +00:00
2019-06-17 04:21:41 +00:00
if ( gl_config . glversion > = ( gl_config . gles ? 3 : 1.2 ) )
qglDrawRangeElements = ( void * ) getglext ( " glDrawRangeElements " ) ;
else if ( GL_CheckExtension ( " GL_EXT_draw_range_elements " ) )
qglDrawRangeElements = ( void * ) getglext ( " glDrawRangeElementsEXT " ) ;
else
qglDrawRangeElements = NULL ;
if ( qglDrawRangeElements = = NULL )
qglDrawRangeElements = GL_DrawRangeElementsEmul ;
2012-11-29 13:37:48 +00:00
gl_config . ext_packed_depth_stencil = GL_CheckExtension ( " GL_EXT_packed_depth_stencil " ) ;
2019-07-29 05:28:20 +00:00
if ( ( ! gl_config . gles & & gl_config . glversion > = 4.6 ) | | GL_CheckExtension ( " GL_EXT_texture_filter_anisotropic " ) | | GL_CheckExtension ( " GL_ARB_texture_filter_anisotropic " ) )
2005-12-01 11:22:20 +00:00
{
2006-06-04 02:25:10 +00:00
qglGetIntegerv ( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT , & gl_config . ext_texture_filter_anisotropic ) ;
2019-07-29 05:28:20 +00:00
Con_DPrintf ( " Anisotropic filtering supported (%dx max). \n " , gl_config . ext_texture_filter_anisotropic ) ;
2005-12-01 11:22:20 +00:00
}
2018-05-06 16:09:07 +00:00
if ( ( ! gl_config . gles & & gl_config . glversion > = 2 ) | | GL_CheckExtension ( " GL_ARB_texture_non_power_of_two " ) )
sh_config . texture_allow_block_padding = true ; //gl2/npot explicitly relaxes this restriction
else
sh_config . texture_allow_block_padding = false ; //gles does not support padded sizes, even with gles3. This is especially true if we're running atop d3d-via-webgl.
2015-08-02 11:36:46 +00:00
if ( ! gl_config . gles & & gl_config . glversion > = 3 )
{ //GL_ARB_texture_non_power_of_two is supposed to be mandatory in gl2+ and thus checking for it is redundant and not forwards-compatible
//geforcefx apparently software emulates it, so only activate it unconditionally on gl3+ hardware.
2019-07-29 05:28:20 +00:00
//gl2 drivers will likely still be explicitly advertising GL_ARB_texture_non_power_of_two so there's probably no great loss from requiring a higher version.
sh_config . texture_non_power_of_two = true ;
sh_config . texture_non_power_of_two_pic = true ;
}
else if ( gl_config . gles & & gl_config . glversion > = 3 )
{ //gles3 is meant to have full npot support (like gl2+ was meant to).
2014-10-11 19:39:45 +00:00
sh_config . texture_non_power_of_two = true ;
2015-08-02 11:36:46 +00:00
sh_config . texture_non_power_of_two_pic = true ;
2014-10-05 20:04:11 +00:00
}
2015-08-02 11:36:46 +00:00
else if ( GL_CheckExtension ( " GL_ARB_texture_non_power_of_two " ) )
{ //gl1 devices might still support npot
sh_config . texture_non_power_of_two = true ;
sh_config . texture_non_power_of_two_pic = true ;
}
else if ( gl_config . gles & & GL_CheckExtension ( " GL_OES_texture_npot " ) )
{ //gles devices might have full npot too, but with a different extension name. because consistancy is good...
sh_config . texture_non_power_of_two = true ;
sh_config . texture_non_power_of_two_pic = true ;
}
else if ( gl_config . gles & & gl_config . glversion > = 2 )
{ //gles2 has npot (clamp + no mips) support as base.
sh_config . texture_non_power_of_two = false ;
sh_config . texture_non_power_of_two_pic = true ;
}
else if ( gl_config . gles & & GL_CheckExtension ( " GL_APPLE_texture_2D_limited_npot " ) )
{ //gles1 MIGHT have SOME npot support.
2014-10-11 19:39:45 +00:00
sh_config . texture_non_power_of_two = false ;
sh_config . texture_non_power_of_two_pic = true ;
2014-10-05 20:04:11 +00:00
}
else
2015-08-02 11:36:46 +00:00
{ //really old hardware/drivers with no npot support at all.
2014-10-11 19:39:45 +00:00
sh_config . texture_non_power_of_two = false ;
sh_config . texture_non_power_of_two_pic = false ;
2014-10-05 20:04:11 +00:00
}
2009-11-04 21:16:50 +00:00
// if (GL_CheckExtension("GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken.
2005-01-18 21:10:24 +00:00
// gl_config.sgis_generate_mipmap = true;
2004-10-10 06:32:29 +00:00
2019-01-13 16:51:50 +00:00
if ( gl_config . gles | | gl_config_nofixedfunc )
2011-01-23 03:44:49 +00:00
{
2013-08-07 14:20:24 +00:00
# ifndef qglActiveTextureARB
2011-01-23 03:44:49 +00:00
qglActiveTextureARB = ( void * ) getglext ( " glActiveTexture " ) ;
2013-08-07 14:20:24 +00:00
# endif
2019-01-13 16:51:50 +00:00
qglClientActiveTextureARB = ( void * ) getglext ( " glClientActiveTexture " ) ; //compat contexts only...
2011-01-23 03:44:49 +00:00
qglSelectTextureSGIS = qglActiveTextureARB ;
mtexid0 = GL_TEXTURE0_ARB ;
2012-04-09 19:12:12 +00:00
if ( ! gl_config . nofixedfunc )
qglGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & gl_mtexarbable ) ;
2012-04-24 07:59:11 +00:00
else
gl_mtexarbable = 8 ;
2011-01-23 03:44:49 +00:00
}
else if ( GL_CheckExtension ( " GL_ARB_multitexture " ) & & ! COM_CheckParm ( " -noamtex " ) )
2004-08-22 22:29:09 +00:00
{ //ARB multitexture is the popular choice.
2013-08-07 14:20:24 +00:00
# ifndef qglActiveTextureARB
2004-08-22 22:29:09 +00:00
qglActiveTextureARB = ( void * ) getglext ( " glActiveTextureARB " ) ;
2013-08-07 14:20:24 +00:00
# endif
2004-08-22 22:29:09 +00:00
qglClientActiveTextureARB = ( void * ) getglext ( " glClientActiveTextureARB " ) ;
2005-01-07 03:16:44 +00:00
qglGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & gl_mtexarbable ) ;
2004-08-22 22:29:09 +00:00
gl_mtexable = true ;
qglSelectTextureSGIS = qglActiveTextureARB ;
mtexid0 = GL_TEXTURE0_ARB ;
2013-08-07 14:20:24 +00:00
# ifndef qglActiveTextureARB
2019-01-13 16:51:50 +00:00
if ( ! qglActiveTextureARB | | ! qglClientActiveTextureARB )
2014-03-30 00:39:37 +00:00
gl_mtexable = false ;
else if ( gl_mtexarbable = = 1 )
{
Con_Printf ( " OpenGL Driver Bug detected: 1 texture is NOT multitexture \n " ) ;
gl_mtexable = false ;
}
if ( ! gl_mtexable )
2004-08-22 22:29:09 +00:00
{
qglActiveTextureARB = NULL ;
2005-05-20 12:48:06 +00:00
qglClientActiveTextureARB = NULL ;
2004-08-22 22:29:09 +00:00
qglSelectTextureSGIS = NULL ;
gl_mtexable = false ;
gl_mtexarbable = false ;
}
2005-05-20 12:48:06 +00:00
else
{
2011-01-29 19:53:38 +00:00
Con_DPrintf ( " ARB Multitexture extensions found. Use -noamtex to disable. \n " ) ;
2005-05-20 12:48:06 +00:00
}
2013-08-07 14:20:24 +00:00
# endif
2004-08-22 22:29:09 +00:00
}
2012-11-27 03:23:19 +00:00
/*
2009-11-04 21:16:50 +00:00
else if ( GL_CheckExtension ( " GL_SGIS_multitexture " ) & & ! COM_CheckParm ( " -nomtex " ) )
2004-08-22 22:29:09 +00:00
{ //SGIS multitexture, limited in many ways but basic functionality is identical to ARB
Con_SafePrintf ( " Multitexture extensions found. \n " ) ;
qglMTexCoord2fSGIS = ( void * ) getglext ( " glMTexCoord2fSGIS " ) ;
qglSelectTextureSGIS = ( void * ) getglext ( " glSelectTextureSGIS " ) ;
gl_mtexable = true ;
mtexid0 = GL_TEXTURE0_SGIS ;
}
2012-11-27 03:23:19 +00:00
*/
if ( ! qglClientActiveTextureARB )
{
qglClientActiveTextureARB = GL_ClientActiveTextureStub ;
}
2004-08-22 22:29:09 +00:00
2012-04-24 07:59:11 +00:00
if ( ( gl_config . gles & & gl_config . glversion > = 2 ) | | GL_CheckExtension ( " GL_EXT_stencil_wrap " ) )
2004-10-19 16:10:14 +00:00
gl_config . ext_stencil_wrap = true ;
2004-08-22 22:29:09 +00:00
2013-04-02 05:18:17 +00:00
# ifndef GL_STATIC
2019-04-15 18:43:42 +00:00
qglStencilOpSeparate = NULL ;
2014-03-30 00:39:37 +00:00
if ( ( gl_config . gles & & gl_config . glversion > = 2 ) | | ( ! gl_config . gles & & gl_config . glversion > = 3 ) ) //theoretically that should be a 2 not 3.
2019-04-15 18:43:42 +00:00
qglStencilOpSeparate = ( void * ) getglext ( " glStencilOpSeparate " ) ;
2012-04-24 07:59:11 +00:00
else if ( GL_CheckExtension ( " GL_ATI_separate_stencil " ) )
2019-04-15 18:43:42 +00:00
qglStencilOpSeparate = ( void * ) getglext ( " glStencilOpSeparateATI " ) ;
2013-04-02 05:18:17 +00:00
# endif
qglActiveStencilFaceEXT = NULL ;
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_EXT_stencil_two_side " ) )
2004-08-22 22:29:09 +00:00
qglActiveStencilFaceEXT = ( void * ) getglext ( " glActiveStencilFaceEXT " ) ;
2011-12-26 15:19:13 +00:00
/*not enabled - its only useful for shadow volumes, but (on nvidia) it affects the depth values even when not clamped which results in shadow z-fighting. best rely upon infinite projection matricies instead*/
2012-07-05 19:42:36 +00:00
if ( GL_CheckExtension ( " GL_ARB_depth_clamp " ) | | GL_CheckExtension ( " GL_NV_depth_clamp " ) )
gl_config . arb_depth_clamp = true ;
2011-12-05 15:23:40 +00:00
2018-03-05 04:00:56 +00:00
# ifndef GL_STATIC
2017-10-31 22:52:58 +00:00
if ( gl_config . gles )
{ //GL_ARB_texture_compression is not quite supported in gles, but works for custom compressed formats (like etc2).
2018-03-05 04:00:56 +00:00
qglCompressedTexImage2D = ( void * ) getglext ( " glCompressedTexImage2D " ) ;
qglCompressedTexImage3D = ( void * ) getglext ( " glCompressedTexImage3D " ) ;
2018-03-04 14:41:16 +00:00
qglCompressedTexSubImage2D = ( void * ) getglext ( " glCompressedTexSubImage2D " ) ;
qglCompressedTexSubImage3D = ( void * ) getglext ( " glCompressedTexSubImage3D " ) ;
2018-03-05 04:00:56 +00:00
qglGetCompressedTexImage = NULL ;
2017-10-31 22:52:58 +00:00
}
else if ( ! gl_config . gles & & gl_config . glversion > 1.3 )
{ //GL_ARB_texture_compression is core in gl1.3
2018-03-05 04:00:56 +00:00
qglCompressedTexImage2D = ( void * ) getglext ( " glCompressedTexImage2D " ) ;
qglCompressedTexImage3D = ( void * ) getglext ( " glCompressedTexImage3D " ) ;
2018-03-04 14:41:16 +00:00
qglCompressedTexSubImage2D = ( void * ) getglext ( " glCompressedTexSubImage2D " ) ;
qglCompressedTexSubImage3D = ( void * ) getglext ( " glCompressedTexSubImage3D " ) ;
2018-03-05 04:00:56 +00:00
qglGetCompressedTexImage = ( void * ) getglext ( " glGetCompressedTexImage " ) ;
2017-10-31 22:52:58 +00:00
gl_config . arb_texture_compression = true ;
}
else if ( GL_CheckExtension ( " GL_ARB_texture_compression " ) )
2004-08-22 22:29:09 +00:00
{
2018-03-05 04:00:56 +00:00
qglCompressedTexImage2D = ( void * ) getglext ( " glCompressedTexImage2DARB " ) ;
qglCompressedTexImage3D = ( void * ) getglext ( " glCompressedTexImage3DARB " ) ;
2018-03-04 14:41:16 +00:00
qglCompressedTexSubImage2D = ( void * ) getglext ( " glCompressedTexSubImage2DARB " ) ;
qglCompressedTexSubImage3D = ( void * ) getglext ( " glCompressedTexSubImage3DARB " ) ;
2018-03-05 04:00:56 +00:00
qglGetCompressedTexImage = ( void * ) getglext ( " glGetCompressedTexImageARB " ) ;
2004-08-22 22:29:09 +00:00
2018-03-05 04:00:56 +00:00
if ( ! qglCompressedTexImage2D | | ! qglGetCompressedTexImage )
2004-08-22 22:29:09 +00:00
{
2018-03-05 04:00:56 +00:00
qglCompressedTexImage2D = NULL ;
qglGetCompressedTexImage = NULL ;
2004-08-22 22:29:09 +00:00
}
else
2004-10-19 16:10:14 +00:00
gl_config . arb_texture_compression = true ;
2004-08-22 22:29:09 +00:00
}
2018-03-05 04:00:56 +00:00
# endif
2019-09-04 08:32:22 +00:00
gl_config . astc_decodeprecision = GL_CheckExtension ( " GL_EXT_texture_compression_astc_decode_mode " ) ;
2012-07-05 19:42:36 +00:00
/*
2011-10-27 16:16:29 +00:00
if ( GL_CheckExtension ( " GL_EXT_depth_bounds_test " ) )
qglDepthBoundsEXT = ( void * ) getglext ( " glDepthBoundsEXT " ) ;
else if ( GL_CheckExtension ( " GL_NV_depth_bounds_test " ) )
qglDepthBoundsEXT = ( void * ) getglext ( " glDepthBoundsNV " ) ;
else
qglDepthBoundsEXT = NULL ;
2012-07-05 19:42:36 +00:00
*/
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_ATI_pn_triangles " ) )
2004-08-22 22:29:09 +00:00
{
qglPNTrianglesfATI = ( void * ) getglext ( " glPNTrianglesfATI " ) ;
qglPNTrianglesiATI = ( void * ) getglext ( " glPNTrianglesiATI " ) ;
}
2018-12-29 07:43:02 +00:00
if ( ( ! gl_config . gles & & gl_config . glversion > = 4.0 ) | | ( gl_config . gles & & gl_config . glversion > = 3.2 ) )
{
gl_config . arb_tessellation_shader = true ;
2014-11-05 05:39:24 +00:00
qglPatchParameteriARB = getglext ( " glPatchParameteri " ) ;
2018-12-29 07:43:02 +00:00
}
2014-11-05 05:39:24 +00:00
else if ( GL_CheckExtension ( " GL_ARB_tessellation_shader " ) )
2018-12-29 07:43:02 +00:00
{
gl_config . arb_tessellation_shader = true ;
2014-11-05 05:39:24 +00:00
qglPatchParameteriARB = getglext ( " glPatchParameteriARB " ) ;
2018-12-29 07:43:02 +00:00
}
else if ( GL_CheckExtension ( " GL_OES_tessellation_shader " ) )
{
gl_config . arb_tessellation_shader = true ;
qglPatchParameteriARB = getglext ( " glPatchParameteriOES " ) ;
}
2014-11-05 05:39:24 +00:00
else
qglPatchParameteriARB = NULL ;
2004-08-22 22:29:09 +00:00
2013-04-02 05:18:17 +00:00
# ifndef GL_STATIC
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_EXT_texture_object " ) )
2004-08-22 22:29:09 +00:00
{
2013-04-02 05:18:17 +00:00
qglBindTexture = ( void * ) getglext ( " glBindTextureEXT " ) ;
if ( ! qglBindTexture ) //grrr
qglBindTexture = ( void * ) getglext ( " glBindTexture " ) ;
2004-08-22 22:29:09 +00:00
}
2013-04-02 05:18:17 +00:00
# endif
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_EXT_compiled_vertex_array " ) )
2004-10-28 07:07:44 +00:00
{
qglLockArraysEXT = ( void * ) getglext ( " glLockArraysEXT " ) ;
qglUnlockArraysEXT = ( void * ) getglext ( " glUnlockArraysEXT " ) ;
}
2018-03-04 14:41:16 +00:00
else
{
qglLockArraysEXT = NULL ;
qglUnlockArraysEXT = NULL ;
}
2004-10-28 07:07:44 +00:00
2010-07-11 02:22:39 +00:00
/*various combiner features*/
2009-11-04 21:16:50 +00:00
gl_config . tex_env_combine = GL_CheckExtension ( " GL_EXT_texture_env_combine " ) ;
gl_config . env_add = GL_CheckExtension ( " GL_EXT_texture_env_add " ) ;
gl_config . nv_tex_env_combine4 = GL_CheckExtension ( " GL_NV_texture_env_combine4 " ) ;
gl_config . arb_texture_env_combine = GL_CheckExtension ( " GL_ARB_texture_env_combine " ) ;
gl_config . arb_texture_env_dot3 = GL_CheckExtension ( " GL_ARB_texture_env_dot3 " ) ;
2004-10-19 16:10:14 +00:00
2018-04-08 14:24:50 +00:00
qglBufferStorage = NULL ;
2013-08-07 14:20:24 +00:00
# if !defined(GL_STATIC)
2013-11-21 23:02:28 +00:00
/*vbos, were made core in gl1.5 or gles2.0*/
if ( ( gl_config . gles & & gl_config . glversion > = 2 ) | | ( ! gl_config . gles & & ( gl_major_version > 1 | | ( gl_major_version = = 1 & & gl_minor_version > = 5 ) ) ) )
2012-04-09 19:12:12 +00:00
{
qglGenBuffersARB = ( void * ) getglext ( " glGenBuffers " ) ;
qglDeleteBuffersARB = ( void * ) getglext ( " glDeleteBuffers " ) ;
qglBindBufferARB = ( void * ) getglext ( " glBindBuffer " ) ;
qglBufferDataARB = ( void * ) getglext ( " glBufferData " ) ;
qglBufferSubDataARB = ( void * ) getglext ( " glBufferSubData " ) ;
qglMapBufferARB = ( void * ) getglext ( " glMapBuffer " ) ;
qglUnmapBufferARB = ( void * ) getglext ( " glUnmapBuffer " ) ;
}
else if ( GL_CheckExtension ( " GL_ARB_vertex_buffer_object " ) )
2009-05-24 10:11:17 +00:00
{
qglGenBuffersARB = ( void * ) getglext ( " glGenBuffersARB " ) ;
qglDeleteBuffersARB = ( void * ) getglext ( " glDeleteBuffersARB " ) ;
qglBindBufferARB = ( void * ) getglext ( " glBindBufferARB " ) ;
qglBufferDataARB = ( void * ) getglext ( " glBufferDataARB " ) ;
qglBufferSubDataARB = ( void * ) getglext ( " glBufferSubDataARB " ) ;
2009-06-21 17:45:33 +00:00
qglMapBufferARB = ( void * ) getglext ( " glMapBufferARB " ) ;
qglUnmapBufferARB = ( void * ) getglext ( " glUnmapBufferARB " ) ;
2009-05-24 10:11:17 +00:00
}
2015-08-22 02:59:01 +00:00
else
{
qglGenBuffersARB = NULL ;
qglDeleteBuffersARB = NULL ;
qglBindBufferARB = NULL ;
qglBufferDataARB = NULL ;
qglBufferSubDataARB = NULL ;
qglMapBufferARB = NULL ;
qglUnmapBufferARB = NULL ;
}
2017-09-20 11:27:13 +00:00
//ARB_map_buffer_range: core in gl3.0/gles3.0, the extension is backported, and thus no ARB postfix on functions.
qglMapBufferRange = ( void * ) getglext ( " glMapBufferRange " ) ;
2018-04-08 14:24:50 +00:00
if ( qglBufferSubDataARB & & qglMapBufferRange )
2013-08-07 14:20:24 +00:00
# endif
2018-04-08 14:24:50 +00:00
{
if ( ( ! gl_config . gles & & gl_config . glversion > = 4.4 ) | | GL_CheckExtension ( " GL_ARB_buffer_storage " ) )
2018-04-27 16:40:50 +00:00
if ( gl_immutable_buffers . ival )
qglBufferStorage = ( void * ) getglext ( " glBufferStorage " ) ; //no arb postfix even with the extension form of it.
2018-04-08 14:24:50 +00:00
}
2009-05-24 10:11:17 +00:00
2013-04-04 08:08:49 +00:00
# ifdef GL_STATIC
gl_config . arb_shader_objects = true ;
# else
2018-01-22 19:18:04 +00:00
if ( Cvar_Get ( " gl_blacklist_debug_glsl " , " 0 " , CVAR_VIDEOLATCH , " gl blacklists " ) - > ival & & ! gl_config . nofixedfunc )
2012-07-05 19:42:36 +00:00
{
Con_Printf ( CON_NOTICE " GLSL disabled \n " ) ;
2012-08-04 01:35:52 +00:00
gl_config . arb_shader_objects = false ;
qglCreateProgramObjectARB = NULL ;
qglDeleteProgramObject_ = NULL ;
qglDeleteShaderObject_ = NULL ;
qglUseProgramObjectARB = NULL ;
qglCreateShaderObjectARB = NULL ;
qglGetProgramParameteriv_ = NULL ;
qglGetShaderParameteriv_ = NULL ;
qglAttachObjectARB = NULL ;
qglGetProgramInfoLog_ = NULL ;
qglGetShaderInfoLog_ = NULL ;
qglShaderSourceARB = NULL ;
qglCompileShaderARB = NULL ;
qglLinkProgramARB = NULL ;
qglBindAttribLocationARB = NULL ;
qglGetAttribLocationARB = NULL ;
2018-11-27 16:48:19 +00:00
qglVertexAttrib4f = NULL ;
2012-08-04 01:35:52 +00:00
qglVertexAttribPointer = NULL ;
qglGetVertexAttribiv = NULL ;
2013-05-13 13:43:18 +00:00
qglGetVertexAttribPointerv = NULL ;
2012-08-04 01:35:52 +00:00
qglEnableVertexAttribArray = NULL ;
qglDisableVertexAttribArray = NULL ;
qglGetUniformLocationARB = NULL ;
qglUniformMatrix4fvARB = NULL ;
qglUniformMatrix3x4fv = NULL ;
qglUniformMatrix4x3fv = NULL ;
qglUniform4fARB = NULL ;
qglUniform4fvARB = NULL ;
qglUniform3fARB = NULL ;
qglUniform3fvARB = NULL ;
qglUniform2fvARB = NULL ;
qglUniform1iARB = NULL ;
qglUniform1fARB = NULL ;
2014-05-10 13:42:13 +00:00
qglGetShaderSource = NULL ;
2012-07-05 19:42:36 +00:00
}
2005-01-04 23:34:42 +00:00
// glslang
2005-02-28 07:16:19 +00:00
//the gf2 to gf4 cards emulate vertex_shader and thus supports shader_objects.
//but our code kinda requires both for clean workings.
2018-01-22 19:18:04 +00:00
else if ( strstr ( gl_renderer , " Mesa " ) & & ( gl_config . glversion < 3 | | gl_config . gles ) & & Cvar_Get ( " gl_blacklist_mesa_glsl " , " 1 " , CVAR_VIDEOLATCH , " gl blacklists " ) - > ival )
2011-12-05 15:23:40 +00:00
{
//(9:12:33 PM) bigfoot: Spike, can you please blacklist your menu shader on Mesa? My machine just hard locked up again because I forgot that pressing escape in FTE is verboten
//(11:51:42 PM) bigfoot: OpenGL vendor string: Tungsten Graphics, Inc
//(11:51:50 PM) bigfoot: OpenGL version string: 2.1 Mesa 7.7.1
//blacklist all glsl, it can't handle #define macros properly either.
//if the menu shader is hardlocking, I don't know what else will do it too.
Con_Printf ( CON_NOTICE " Mesa detected, ignoring any GLSL support. Use '+set gl_blacklist_mesa_glsl 0' on the commandline to reenable it. \n " ) ;
}
else if ( gl_config . glversion > = 2 ) // && (gl_config.gles || 0))
2011-07-30 14:14:56 +00:00
{
/*core names are different from extension names (more functions too)*/
qglCreateProgramObjectARB = ( void * ) getglext ( " glCreateProgram " ) ;
qglDeleteProgramObject_ = ( void * ) getglext ( " glDeleteProgram " ) ;
qglDeleteShaderObject_ = ( void * ) getglext ( " glDeleteShader " ) ;
qglUseProgramObjectARB = ( void * ) getglext ( " glUseProgram " ) ;
qglCreateShaderObjectARB = ( void * ) getglext ( " glCreateShader " ) ;
qglGetProgramParameteriv_ = ( void * ) getglext ( " glGetProgramiv " ) ;
qglGetShaderParameteriv_ = ( void * ) getglext ( " glGetShaderiv " ) ;
qglAttachObjectARB = ( void * ) getglext ( " glAttachShader " ) ;
qglGetProgramInfoLog_ = ( void * ) getglext ( " glGetProgramInfoLog " ) ;
qglGetShaderInfoLog_ = ( void * ) getglext ( " glGetShaderInfoLog " ) ;
qglShaderSourceARB = ( void * ) getglext ( " glShaderSource " ) ;
qglCompileShaderARB = ( void * ) getglext ( " glCompileShader " ) ;
qglLinkProgramARB = ( void * ) getglext ( " glLinkProgram " ) ;
qglBindAttribLocationARB = ( void * ) getglext ( " glBindAttribLocation " ) ;
qglGetAttribLocationARB = ( void * ) getglext ( " glGetAttribLocation " ) ;
qglGetUniformLocationARB = ( void * ) getglext ( " glGetUniformLocation " ) ;
qglUniformMatrix4fvARB = ( void * ) getglext ( " glUniformMatrix4fv " ) ;
qglUniformMatrix3x4fv = ( void * ) getglext ( " glUniformMatrix3x4fv " ) ;
qglUniformMatrix4x3fv = ( void * ) getglext ( " glUniformMatrix4x3fv " ) ;
qglUniform4fARB = ( void * ) getglext ( " glUniform4f " ) ;
qglUniform4fvARB = ( void * ) getglext ( " glUniform4fv " ) ;
qglUniform3fARB = ( void * ) getglext ( " glUniform3f " ) ;
qglUniform3fvARB = ( void * ) getglext ( " glUniform3fv " ) ;
2012-04-24 07:59:11 +00:00
qglUniform2fvARB = ( void * ) getglext ( " glUniform2fv " ) ;
2011-07-30 14:14:56 +00:00
qglUniform1iARB = ( void * ) getglext ( " glUniform1i " ) ;
qglUniform1fARB = ( void * ) getglext ( " glUniform1f " ) ;
2018-11-27 16:48:19 +00:00
qglVertexAttrib4f = ( void * ) getglext ( " glVertexAttrib4f " ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer = ( void * ) getglext ( " glVertexAttribPointer " ) ;
qglGetVertexAttribiv = ( void * ) getglext ( " glGetVertexAttribiv " ) ;
2013-05-13 13:43:18 +00:00
qglGetVertexAttribPointerv = ( void * ) getglext ( " glGetVertexAttribPointerv " ) ;
2013-04-04 08:08:49 +00:00
qglEnableVertexAttribArray = ( void * ) getglext ( " glEnableVertexAttribArray " ) ;
qglDisableVertexAttribArray = ( void * ) getglext ( " glDisableVertexAttribArray " ) ;
2014-05-10 13:42:13 +00:00
qglGetShaderSource = ( void * ) getglext ( " glGetShaderSource " ) ;
2019-04-15 18:43:42 +00:00
if ( qglCreateProgramObjectARB & & qglLinkProgramARB )
{
Con_DPrintf ( " GLSL available \n " ) ;
gl_config . arb_shader_objects = true ;
}
else
Con_Printf ( CON_ERROR " GL version specifies GLSL support, but GLSL functions are not available \n " ) ;
2011-07-30 14:14:56 +00:00
}
else if ( GL_CheckExtension ( " GL_ARB_fragment_shader " )
2010-07-11 02:22:39 +00:00
& & GL_CheckExtension ( " GL_ARB_vertex_shader " )
& & GL_CheckExtension ( " GL_ARB_shader_objects " ) )
2005-01-04 23:34:42 +00:00
{
gl_config . arb_shader_objects = true ;
qglCreateProgramObjectARB = ( void * ) getglext ( " glCreateProgramObjectARB " ) ;
2011-01-23 03:44:49 +00:00
qglDeleteProgramObject_ = ( void * ) getglext ( " glDeleteObjectARB " ) ;
qglDeleteShaderObject_ = ( void * ) getglext ( " glDeleteObjectARB " ) ;
2005-01-04 23:34:42 +00:00
qglUseProgramObjectARB = ( void * ) getglext ( " glUseProgramObjectARB " ) ;
qglCreateShaderObjectARB = ( void * ) getglext ( " glCreateShaderObjectARB " ) ;
qglShaderSourceARB = ( void * ) getglext ( " glShaderSourceARB " ) ;
qglCompileShaderARB = ( void * ) getglext ( " glCompileShaderARB " ) ;
2011-01-23 03:44:49 +00:00
qglGetProgramParameteriv_ = ( void * ) getglext ( " glGetObjectParameterivARB " ) ;
qglGetShaderParameteriv_ = ( void * ) getglext ( " glGetObjectParameterivARB " ) ;
2005-01-04 23:34:42 +00:00
qglAttachObjectARB = ( void * ) getglext ( " glAttachObjectARB " ) ;
2011-01-23 03:44:49 +00:00
qglGetProgramInfoLog_ = ( void * ) getglext ( " glGetInfoLogARB " ) ;
qglGetShaderInfoLog_ = ( void * ) getglext ( " glGetInfoLogARB " ) ;
2005-01-04 23:34:42 +00:00
qglLinkProgramARB = ( void * ) getglext ( " glLinkProgramARB " ) ;
2011-01-23 03:44:49 +00:00
qglBindAttribLocationARB = ( void * ) getglext ( " glBindAttribLocationARB " ) ;
qglGetAttribLocationARB = ( void * ) getglext ( " glGetAttribLocationARB " ) ;
2018-11-27 16:48:19 +00:00
qglVertexAttrib4f = ( void * ) getglext ( " glVertexAttrib4fARB " ) ;
2011-01-23 03:44:49 +00:00
qglVertexAttribPointer = ( void * ) getglext ( " glVertexAttribPointerARB " ) ;
2011-05-26 16:46:43 +00:00
qglGetVertexAttribiv = ( void * ) getglext ( " glGetVertexAttribivARB " ) ;
2013-05-13 13:43:18 +00:00
qglGetVertexAttribPointerv = ( void * ) getglext ( " glGetVertexAttribPointervARB " ) ;
2011-01-23 03:44:49 +00:00
qglEnableVertexAttribArray = ( void * ) getglext ( " glEnableVertexAttribArrayARB " ) ;
qglDisableVertexAttribArray = ( void * ) getglext ( " glDisableVertexAttribArrayARB " ) ;
2005-01-04 23:34:42 +00:00
qglGetUniformLocationARB = ( void * ) getglext ( " glGetUniformLocationARB " ) ;
2009-11-04 21:16:50 +00:00
qglUniformMatrix4fvARB = ( void * ) getglext ( " glUniformMatrix4fvARB " ) ;
2011-07-30 14:14:56 +00:00
qglUniformMatrix3x4fv = ( void * ) getglext ( " glUniformMatrix3x4fvARB " ) ;
qglUniformMatrix4x3fv = ( void * ) getglext ( " glUniformMatrix4x3fvARB " ) ;
2005-01-04 23:34:42 +00:00
qglUniform4fARB = ( void * ) getglext ( " glUniform4fARB " ) ;
2006-03-11 03:12:10 +00:00
qglUniform4fvARB = ( void * ) getglext ( " glUniform4fvARB " ) ;
2005-04-16 16:21:27 +00:00
qglUniform3fARB = ( void * ) getglext ( " glUniform3fARB " ) ;
qglUniform3fvARB = ( void * ) getglext ( " glUniform3fvARB " ) ;
2012-04-24 07:59:11 +00:00
qglUniform2fvARB = ( void * ) getglext ( " glUniform2fvARB " ) ;
2005-01-04 23:34:42 +00:00
qglUniform1iARB = ( void * ) getglext ( " glUniform1iARB " ) ;
qglUniform1fARB = ( void * ) getglext ( " glUniform1fARB " ) ;
2014-05-10 13:42:13 +00:00
qglGetShaderSource = ( void * ) getglext ( " glGetShaderSourceARB " ) ;
2011-01-29 19:53:38 +00:00
Con_DPrintf ( " GLSL available \n " ) ;
2005-01-04 23:34:42 +00:00
}
2015-07-09 18:02:49 +00:00
2019-02-24 07:43:32 +00:00
if ( Cvar_Get ( " gl_blacklist_invariant " , " 0 " , CVAR_VIDEOLATCH , " gl blacklists " ) - > ival )
gl_config . blacklist_invariant = true ;
else if ( gl_config . arb_shader_objects & & ! gl_config_nofixedfunc & &
2019-03-04 00:48:36 +00:00
( strstr ( gl_renderer , " Mesa " ) | | strstr ( gl_version , " Mesa " ) ) & & Cvar_Get ( " gl_blacklist_mesa_invariant " , " 1 " , CVAR_VIDEOLATCH , " gl blacklists " ) - > ival )
2019-02-24 07:43:32 +00:00
{
gl_config . blacklist_invariant = true ;
2019-04-17 09:48:03 +00:00
Con_Printf ( CON_NOTICE " Mesa detected, disabling the use of glsl's invariant keyword. " CON_DEFAULT " This will result in z-fighting. Use '+set gl_blacklist_mesa_invariant 0' on the commandline to reenable it (but you will probably get glsl compilation errors from your driver). \n " ) ;
2019-02-24 07:43:32 +00:00
}
2015-07-09 18:02:49 +00:00
if ( gl_config . arb_shader_objects )
qglGetIntegerv ( GL_MAX_VERTEX_ATTRIBS_ARB , & gl_config . maxattribs ) ;
2013-04-02 05:18:17 +00:00
# endif
2014-03-30 08:55:06 +00:00
qglGetProgramBinary = NULL ;
qglProgramBinary = NULL ;
if ( gl_config . arb_shader_objects )
{
if ( gl_config . glversion > = 4.1 | | GL_CheckExtension ( " GL_ARB_get_program_binary " ) )
{
qglGetProgramBinary = ( void * ) getglext ( " glGetProgramBinary " ) ;
qglProgramBinary = ( void * ) getglext ( " glProgramBinary " ) ;
}
else if ( GL_CheckExtension ( " GL_OES_get_program_binary " ) )
{
//no PROGRAM_BINARY_RETRIEVABLE_HINT
qglGetProgramBinary = ( void * ) getglext ( " glGetProgramBinaryOES " ) ;
qglProgramBinary = ( void * ) getglext ( " glProgramBinaryOES " ) ;
}
}
2014-10-22 19:41:20 +00:00
if ( gl_config . glversion > = 4.5 ) //the core version
qglGetGraphicsResetStatus = ( void * ) getglext ( " glGetGraphicsResetStatus " ) ;
else if ( GL_CheckExtension ( " GL_ARB_robustness " ) ) //desktop extension
qglGetGraphicsResetStatus = ( void * ) getglext ( " glGetGraphicsResetStatusARB " ) ;
else if ( GL_CheckExtension ( " GL_KHR_robustness " ) ) //glorified gles extension
qglGetGraphicsResetStatus = ( void * ) getglext ( " glGetGraphicsResetStatusKHR " ) ;
else
qglGetGraphicsResetStatus = NULL ; //its not allowed to crash us. probably will. grr. oh well.
2014-03-30 08:55:06 +00:00
2013-05-13 13:43:18 +00:00
//we only use vao if we don't have a choice.
//certain drivers (*cough* mesa *cough*) update vao0 state even when a different vao is bound.
//they also don't support client arrays, so are unusable without glsl or vertex streaming (which is *really* hard to optimise for - especially with webgl etc)
//so only use them with gl3+ core contexts where vbo is mandatory anyway.
2015-10-27 15:20:15 +00:00
if ( ! gl_config_nofixedfunc )
2012-10-14 10:55:09 +00:00
{
//don't bother if we've no glsl
qglGenVertexArrays = NULL ;
qglBindVertexArray = NULL ;
}
2014-03-30 00:39:37 +00:00
else if ( gl_config . glversion > = 3 & & ! gl_config . gles )
2012-10-14 10:55:09 +00:00
{
/*yay core!*/
2014-03-30 00:39:37 +00:00
Con_Printf ( " Using vao (core) \n " ) ;
2012-10-14 10:55:09 +00:00
qglGenVertexArrays = ( void * ) getglext ( " glGenVertexArrays " ) ;
qglBindVertexArray = ( void * ) getglext ( " glBindVertexArray " ) ;
}
else if ( GL_CheckExtension ( " GL_ARB_vertex_array_object " ) )
{
2014-03-30 00:39:37 +00:00
Con_Printf ( " Using vao (extension) \n " ) ;
2012-10-14 10:55:09 +00:00
qglGenVertexArrays = ( void * ) getglext ( " glGenVertexArraysARB " ) ;
qglBindVertexArray = ( void * ) getglext ( " glBindVertexArrayARB " ) ;
}
else
2012-05-10 01:00:41 +00:00
{
qglGenVertexArrays = NULL ;
qglBindVertexArray = NULL ;
}
2009-11-04 21:16:50 +00:00
2014-08-27 08:41:31 +00:00
if ( gl_config . gles )
{ //gles has different TexImage2D arguments for specifying quality.
gl_config . arb_depth_texture = GL_CheckExtension ( " GL_OES_depth_texture " ) ; //gles2
gl_config . arb_depth_texture | = GL_CheckExtension ( " GL_CHROMIUM_depth_texture " ) ; //nacl
gl_config . arb_depth_texture | = GL_CheckExtension ( " GL_WEBGL_depth_texture " ) ; //webgl. duh.
2016-12-13 11:50:15 +00:00
gl_config . arb_depth_texture | = GL_CheckExtension ( " GL_ANGLE_depth_texture " ) ; //gah. should just use wildcards huh (no uploads)
2019-01-13 16:51:50 +00:00
gl_config . arb_shadow = gl_config . glversion > = 3.0 ; //||GL_CheckExtension("GL_EXT_shadow_samplers");
2014-08-27 08:41:31 +00:00
}
else
{
2019-01-13 16:51:50 +00:00
gl_config . arb_depth_texture = gl_config . glversion > = 1.4 | | GL_CheckExtension ( " GL_ARB_depth_texture " ) ;
gl_config . arb_shadow = gl_config . glversion > = 1.4 | | GL_CheckExtension ( " GL_ARB_shadow " ) ;
2014-08-27 08:41:31 +00:00
}
//gl_config.arb_shadow |= GL_CheckExtension("GL_EXT_shadow_samplers"); //gles2. nvidia fucks up. depend on brute-force. :s
2013-10-29 17:38:22 +00:00
2015-05-03 19:57:46 +00:00
if ( GL_CheckExtension ( " GL_ARB_seamless_cube_map " ) )
qglEnable ( 0x884F ) ; //TEXTURE_CUBE_MAP_SEAMLESS 0x884F
2018-12-29 07:43:02 +00:00
if ( gl_config . gles )
gl_config . geometryshaders = ( gl_config . glversion > = 3.2 ) | | GL_CheckExtension ( " GL_OES_geometry_shader " ) ;
2015-07-01 23:15:25 +00:00
else
2018-12-29 07:43:02 +00:00
gl_config . geometryshaders = ( gl_config . glversion > = 3.2 ) ;
2015-07-01 23:15:25 +00:00
2018-04-27 16:40:50 +00:00
qglTexStorage2D = NULL ;
qglTexStorage3D = NULL ;
2018-03-04 14:41:16 +00:00
if ( ( ! gl_config . gles & & gl_config . glversion > = 4.2 ) | |
( gl_config . gles & & gl_config . glversion > = 3.0 ) )
{ //from gles3.0 or gl4.2 onwards
2018-04-27 16:40:50 +00:00
if ( gl_immutable_textures . ival )
{
qglTexStorage2D = getglext ( " glTexStorage2D " ) ;
qglTexStorage3D = getglext ( " glTexStorage3D " ) ;
}
2018-03-04 14:41:16 +00:00
}
2014-08-27 08:41:31 +00:00
# ifdef GL_STATIC
gl_config . ext_framebuffer_objects = true ; //exists as core in gles2
# else
if ( ( gl_config . gles & & gl_config . glversion > = 2 ) | | //exists as core in gles2
( ! gl_config . gles & & gl_config . glversion > = 3 ) | | //exists as core in gl3
2018-03-04 14:41:16 +00:00
GL_CheckExtension ( " GL_ARB_framebuffer_object " ) ) //exists as an extension in gl2 (defined in terms of gl3 so no ARB postfix needed)
2013-05-03 04:28:08 +00:00
{
gl_config . ext_framebuffer_objects = true ;
qglGenFramebuffersEXT = ( void * ) getglext ( " glGenFramebuffers " ) ;
qglDeleteFramebuffersEXT = ( void * ) getglext ( " glDeleteFramebuffers " ) ;
qglBindFramebufferEXT = ( void * ) getglext ( " glBindFramebuffer " ) ;
qglGenRenderbuffersEXT = ( void * ) getglext ( " glGenRenderbuffers " ) ;
qglDeleteRenderbuffersEXT = ( void * ) getglext ( " glDeleteRenderbuffers " ) ;
qglBindRenderbufferEXT = ( void * ) getglext ( " glBindRenderbuffer " ) ;
qglRenderbufferStorageEXT = ( void * ) getglext ( " glRenderbufferStorage " ) ;
qglFramebufferTexture2DEXT = ( void * ) getglext ( " glFramebufferTexture2D " ) ;
qglFramebufferRenderbufferEXT = ( void * ) getglext ( " glFramebufferRenderbuffer " ) ;
qglCheckFramebufferStatusEXT = ( void * ) getglext ( " glCheckFramebufferStatus " ) ;
qglGetFramebufferAttachmentParameteriv = ( void * ) getglext ( " glGetFramebufferAttachmentParameteriv " ) ;
2017-07-28 01:49:25 +00:00
gl_config . arb_framebuffer_srgb = GL_CheckExtension ( " GL_ARB_framebuffer_sRGB " ) ;
2013-05-03 04:28:08 +00:00
}
else if ( GL_CheckExtension ( " GL_EXT_framebuffer_object " ) )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
gl_config . ext_framebuffer_objects = true ;
2011-09-03 03:49:43 +00:00
qglGenFramebuffersEXT = ( void * ) getglext ( " glGenFramebuffersEXT " ) ;
qglDeleteFramebuffersEXT = ( void * ) getglext ( " glDeleteFramebuffersEXT " ) ;
qglBindFramebufferEXT = ( void * ) getglext ( " glBindFramebufferEXT " ) ;
qglGenRenderbuffersEXT = ( void * ) getglext ( " glGenRenderbuffersEXT " ) ;
qglDeleteRenderbuffersEXT = ( void * ) getglext ( " glDeleteRenderbuffersEXT " ) ;
qglBindRenderbufferEXT = ( void * ) getglext ( " glBindRenderbufferEXT " ) ;
qglRenderbufferStorageEXT = ( void * ) getglext ( " glRenderbufferStorageEXT " ) ;
qglFramebufferTexture2DEXT = ( void * ) getglext ( " glFramebufferTexture2DEXT " ) ;
qglFramebufferRenderbufferEXT = ( void * ) getglext ( " glFramebufferRenderbufferEXT " ) ;
qglCheckFramebufferStatusEXT = ( void * ) getglext ( " glCheckFramebufferStatusEXT " ) ;
2013-05-03 04:28:08 +00:00
qglGetFramebufferAttachmentParameteriv = ( void * ) getglext ( " glGetFramebufferAttachmentParameterivEXT " ) ;
2009-11-04 21:16:50 +00:00
}
2013-03-12 23:09:25 +00:00
/* //I don't think we care about the differences, so this code should be safe, but I have no way to test that theory right now
else if ( GL_CheckExtension ( " GL_OES_framebuffer_object " ) )
{
gl_config . ext_framebuffer_objects = true ;
qglGenFramebuffersEXT = ( void * ) getglext ( " glGenFramebuffersOES " ) ;
qglDeleteFramebuffersEXT = ( void * ) getglext ( " glDeleteFramebuffersOES " ) ;
qglBindFramebufferEXT = ( void * ) getglext ( " glBindFramebufferOES " ) ;
qglGenRenderbuffersEXT = ( void * ) getglext ( " glGenRenderbuffersOES " ) ;
qglDeleteRenderbuffersEXT = ( void * ) getglext ( " glDeleteRenderbuffersOES " ) ;
qglBindRenderbufferEXT = ( void * ) getglext ( " glBindRenderbufferOES " ) ;
qglRenderbufferStorageEXT = ( void * ) getglext ( " glRenderbufferStorageOES " ) ;
qglFramebufferTexture2DEXT = ( void * ) getglext ( " glFramebufferTexture2DOES " ) ;
qglFramebufferRenderbufferEXT = ( void * ) getglext ( " glFramebufferRenderbufferOES " ) ;
qglCheckFramebufferStatusEXT = ( void * ) getglext ( " glCheckFramebufferStatusOES " ) ;
}
*/
2013-04-02 05:18:17 +00:00
# endif
2010-07-28 21:55:10 +00:00
# ifdef DEBUG
2012-01-01 02:26:42 +00:00
if ( GL_CheckExtension ( " GL_ARB_debug_output " ) )
2010-07-28 21:55:10 +00:00
{
2012-01-01 02:26:42 +00:00
qglDebugMessageControlARB = ( void * ) getglext ( " glDebugMessageControlARB " ) ;
qglDebugMessageInsertARB = ( void * ) getglext ( " glDebugMessageInsertARB " ) ;
qglDebugMessageCallbackARB = ( void * ) getglext ( " glDebugMessageCallbackARB " ) ;
qglGetDebugMessageLogARB = ( void * ) getglext ( " glGetDebugMessageLogARB " ) ;
2010-07-28 21:55:10 +00:00
}
2015-04-14 23:12:17 +00:00
else if ( GL_CheckExtension ( " GL_KHR_debug " ) )
{
if ( gl_config_gles )
{
qglDebugMessageControlARB = ( void * ) getglext ( " glDebugMessageControlKHR " ) ;
qglDebugMessageInsertARB = ( void * ) getglext ( " glDebugMessageInsertKHR " ) ;
qglDebugMessageCallbackARB = ( void * ) getglext ( " glDebugMessageCallbackKHR " ) ;
qglGetDebugMessageLogARB = ( void * ) getglext ( " glGetDebugMessageLogKHR " ) ;
}
else
{
qglDebugMessageControlARB = ( void * ) getglext ( " glDebugMessageControl " ) ;
qglDebugMessageInsertARB = ( void * ) getglext ( " glDebugMessageInsert " ) ;
qglDebugMessageCallbackARB = ( void * ) getglext ( " glDebugMessageCallback " ) ;
qglGetDebugMessageLogARB = ( void * ) getglext ( " glGetDebugMessageLog " ) ;
}
}
2010-07-28 21:55:10 +00:00
else
{
2012-01-01 02:26:42 +00:00
qglDebugMessageControlARB = NULL ;
qglDebugMessageInsertARB = NULL ;
qglDebugMessageCallbackARB = NULL ;
qglGetDebugMessageLogARB = NULL ;
2010-07-28 21:55:10 +00:00
}
# endif
2015-08-28 03:13:45 +00:00
2016-07-12 00:40:13 +00:00
if ( ! gl_config . nofixedfunc )
{ //clamping breaks overbrights. so if this isn't deprecated, try to use it.
//part of GL_ARB_color_buffer_float, made core with gl3, and then deprecated in gl3.1. *sigh*
# define GL_CLAMP_VERTEX_COLOR 0x891A
# define GL_CLAMP_FRAGMENT_COLOR 0x891B
# define GL_CLAMP_READ_COLOR 0x891C
void ( APIENTRY * qglClampColor ) ( GLenum target , GLenum clamp ) ;
qglClampColor = ( void * ) getglext ( " glClampColor " ) ;
if ( ! qglClampColor )
qglClampColor = ( void * ) getglext ( " glClampColorARB " ) ;
if ( qglClampColor )
{
qglClampColor ( GL_CLAMP_VERTEX_COLOR , GL_FALSE ) ;
qglClampColor ( GL_CLAMP_FRAGMENT_COLOR , GL_FALSE ) ;
qglClampColor ( GL_CLAMP_READ_COLOR , GL_FALSE ) ;
}
}
if ( ( ! gl_config . gles & & gl_config . glversion > = 1.5 ) | | ( gl_config . gles & & gl_config . glversion > = 3.0 ) )
2015-10-11 11:34:58 +00:00
{
qglGenQueriesARB = ( void * ) getglext ( " glGenQueries " ) ;
qglDeleteQueriesARB = ( void * ) getglext ( " glDeleteQueries " ) ;
qglBeginQueryARB = ( void * ) getglext ( " glBeginQuery " ) ;
qglEndQueryARB = ( void * ) getglext ( " glEndQuery " ) ;
qglGetQueryObjectuivARB = ( void * ) getglext ( " glGetQueryObjectuiv " ) ;
}
else if ( GL_CheckExtension ( " GL_ARB_occlusion_query " ) )
{
qglGenQueriesARB = ( void * ) getglext ( " glGenQueriesARB " ) ;
qglDeleteQueriesARB = ( void * ) getglext ( " glDeleteQueriesARB " ) ;
qglBeginQueryARB = ( void * ) getglext ( " glBeginQueryARB " ) ;
qglEndQueryARB = ( void * ) getglext ( " glEndQueryARB " ) ;
qglGetQueryObjectuivARB = ( void * ) getglext ( " glGetQueryObjectuivARB " ) ;
}
else
{
qglGenQueriesARB = NULL ;
qglDeleteQueriesARB = NULL ;
qglBeginQueryARB = NULL ;
qglEndQueryARB = NULL ;
qglGetQueryObjectuivARB = NULL ;
}
2015-08-28 03:13:45 +00:00
if ( ! gl_config . gles & & gl_config_nofixedfunc )
qglDisableClientState ( GL_VERTEX_ARRAY ) ;
2016-07-12 00:40:13 +00:00
if ( qglGenVertexArrays )
{
GLuint vao ;
qglGenVertexArrays ( 1 , & vao ) ;
qglBindVertexArray ( vao ) ;
qglGenVertexArrays = NULL ;
qglBindVertexArray = NULL ;
}
2005-01-04 23:34:42 +00:00
}
2011-10-27 16:16:29 +00:00
static const char * glsl_hdrs [ ] =
{
2015-03-03 00:14:43 +00:00
" sys/defs.h " ,
" #define DEFS_DEFINED \n "
" #ifdef VERTEX_SHADER \n "
2017-02-11 16:14:06 +00:00
// "attribute vec3 v_position1;" //defined elsewhere, depending on fixed function availability
// "attribute vec3 v_position2;"
" attribute vec4 v_colour; "
" attribute vec2 v_texcoord; "
" attribute vec2 v_lmcoord; "
" attribute vec3 v_normal; "
" attribute vec3 v_svector; "
" attribute vec3 v_tvector; "
" attribute vec4 v_bone; " //fixme: make ints
" attribute vec4 v_weight; "
2015-03-03 00:14:43 +00:00
# if MAXRLIGHTMAPS > 1
2017-02-11 16:14:06 +00:00
" \n #define v_lmcoord1 v_lmcoord \n "
" attribute vec2 v_lmcoord2; "
" attribute vec2 v_lmcoord3; "
" attribute vec2 v_lmcoord4; "
" \n #define v_colour1 v_colour \n "
" attribute vec4 v_colour2; "
" attribute vec4 v_colour3; "
" attribute vec4 v_colour4; "
2015-03-03 00:14:43 +00:00
# endif
2017-02-11 16:14:06 +00:00
" \n #endif \n "
2018-12-28 00:04:36 +00:00
2017-08-29 02:29:06 +00:00
" #ifndef SPECEXP \n "
" #define SPECEXP 1.0 \n "
" #endif \n "
2017-10-12 12:02:25 +00:00
" #ifndef SPECULAR_BASE_POW \n "
" #define SPECULAR_BASE_POW 32.0 \n "
" #define SPECULAR_BASE_MUL 1.0 \n "
" #endif \n "
" #define FTE_SPECULAR_EXPONENT (SPECULAR_BASE_POW*float(SPECEXP)) \n "
2017-08-29 02:29:06 +00:00
" #ifndef SPECMUL \n "
" #define SPECMUL 1.0 \n "
" #endif \n "
2017-10-12 12:02:25 +00:00
" #define FTE_SPECULAR_MULTIPLIER (SPECULAR_BASE_MUL*float(SPECMUL)) \n "
2019-04-16 22:40:05 +00:00
#if 0 //def HAVE_LEGACY
2017-02-11 16:14:06 +00:00
" uniform sampler2DShadow s_shadowmap; "
" uniform samplerCube s_projectionmap; "
" uniform sampler2D s_diffuse; "
" uniform sampler2D s_normalmap; "
" uniform sampler2D s_specular; "
" uniform sampler2D s_upper; "
" uniform sampler2D s_lower; "
" uniform sampler2D s_fullbright; "
" uniform sampler2D s_paletted; "
" uniform samplerCube s_reflectcube; "
" uniform sampler2D s_reflectmask; "
" uniform sampler2D s_lightmap; "
2018-07-05 16:21:44 +00:00
" uniform sampler2D s_deluxemap; "
2017-02-11 16:14:06 +00:00
" \n #define s_lightmap0 s_lightmap \n "
2018-07-05 16:21:44 +00:00
" #define s_deluxemap0 s_deluxemap \n "
2015-07-14 14:47:00 +00:00
# if MAXRLIGHTMAPS > 1
2017-02-11 16:14:06 +00:00
" uniform sampler2D s_lightmap1; "
" uniform sampler2D s_lightmap2; "
" uniform sampler2D s_lightmap3; "
2018-07-05 16:21:44 +00:00
" uniform sampler2D s_deluxemap1; "
" uniform sampler2D s_deluxemap2; "
" uniform sampler2D s_deluxemap3; \n "
//FIXME: remove these some time.
// "#define s_deluxmap s_deluxemap\n"
// "#define s_deluxmap0 s_deluxemap0\n"
// "#define s_deluxmap1 s_deluxemap1\n"
// "#define s_deluxmap2 s_deluxemap2\n"
// "#define s_deluxmap3 s_deluxemap3\n"
2016-07-26 11:47:59 +00:00
# endif
2015-03-03 00:14:43 +00:00
# endif
2019-03-12 05:04:27 +00:00
" #if defined(ORM) || defined(SG) \n "
" uniform vec4 factors[3]; \n "
" #define factor_base factors[0] \n "
" #define factor_spec factors[1] \n "
" #define factor_emit factors[2] \n "
" #else \n "
" #define factor_base vec4(1.0) \n "
" #define factor_spec vec4(1.0) \n "
" #define factor_emit vec4(1.0) \n "
" #endif \n "
2015-03-03 00:14:43 +00:00
" #ifdef USEUBOS \n "
" layout(std140) uniform u_lightinfo \n "
2017-02-11 16:14:06 +00:00
" { "
" vec3 l_lightscreen; "
" float l_lightradius; "
" vec3 l_lightcolour; "
2015-03-03 00:14:43 +00:00
" float l_pad1; \n "
2017-02-11 16:14:06 +00:00
" vec3 l_lightcolourscale;n "
" float l_pad2; "
" vec3 l_lightposition; "
" float l_pad3; "
" mat4 l_cubematrix; "
" vec4 l_shadowmapproj; "
" vec2 l_shadowmapscale; "
" vec2 l_pad4; "
2015-03-03 00:14:43 +00:00
" }; \n "
" layout(std140) uniform u_entityinfo \n "
" { \n "
2017-02-11 16:14:06 +00:00
" vec2 e_vblend; "
" vec2 e_pad1; "
" vec3 e_glowmod; "
" float e_pad2; "
" vec3 e_origin; "
" float e_pad3; "
" vec4 colormod; "
" vec3 e_glowmod; "
" float e_pad4; "
" vec3 e_uppercolour; "
" float e_pad5; "
" vec3 e_lowercolour; "
" float e_pad6; "
" vec3 w_fogcolour; "
" float w_fogalpha; "
" vec3 e_light_dir; "
" float w_fogdensity; "
" vec3 e_light_mul; "
" float w_fogdepthbias; "
" vec3 e_light_ambient; "
" float e_time; "
2015-03-03 00:14:43 +00:00
" }; \n "
2017-01-29 13:10:53 +00:00
" #ifdef SKELETAL \n "
" layout(std140) unform u_bones \n "
" { \n "
" #ifdef PACKEDBONES \n "
2018-12-28 00:04:36 +00:00
" vec4 m_bones_packed[3*MAX_GPU_BONES]; \n "
2017-01-29 13:10:53 +00:00
" #else \n "
2018-12-28 00:04:36 +00:00
" mat3x4 m_bones_mat3x4[MAX_GPU_BONES] \n "
2017-01-29 13:10:53 +00:00
" #endif \n "
" }; \n "
" #endif \n "
2015-03-03 00:14:43 +00:00
" #else \n "
2017-02-11 16:14:06 +00:00
" uniform mat4 m_model; "
" uniform mat4 m_view; "
" uniform mat4 m_modelview; "
2015-03-03 00:14:43 +00:00
" uniform mat4 m_projection; \n "
2017-02-11 16:14:06 +00:00
" #ifndef VERTEX_SHADER \n "
" uniform mat4 m_modelviewprojection; \n "
" #endif \n "
2015-07-14 14:47:00 +00:00
" #ifdef SKELETAL \n " //skeletal permutation tends to require glsl 120
2017-01-29 13:10:53 +00:00
" #ifdef PACKEDBONES \n "
2018-12-28 00:04:36 +00:00
" uniform vec4 m_bones_packed[3*MAX_GPU_BONES]; \n "
2017-01-29 13:10:53 +00:00
" #else \n "
2018-12-28 00:04:36 +00:00
" uniform mat3x4 m_bones_mat3x4[MAX_GPU_BONES]; \n "
2017-01-29 13:10:53 +00:00
" #endif \n "
2015-07-14 14:47:00 +00:00
" #endif \n "
2017-02-11 16:14:06 +00:00
" uniform mat4 m_invviewprojection; "
" uniform mat4 m_invmodelviewprojection; "
2015-03-03 00:14:43 +00:00
/*viewer properties*/
2017-02-11 16:14:06 +00:00
" uniform vec3 v_eyepos; "
2015-03-03 00:14:43 +00:00
" uniform vec4 w_fog[2]; \n "
" #define w_fogcolour w_fog[0].rgb \n "
" #define w_fogalpha w_fog[0].a \n "
" #define w_fogdensity w_fog[1].x \n "
" #define w_fogdepthbias w_fog[1].y \n "
2017-12-03 08:27:27 +00:00
" uniform vec4 w_user[16]; \n "
2015-03-03 00:14:43 +00:00
/*ent properties*/
//"uniform vec2 e_vblend;\n"
" #ifdef LIGHTSTYLED \n "
" uniform vec4 e_lmscale[4]; \n "
" #else \n "
" uniform vec4 e_lmscale; \n "
" #endif \n "
2017-02-11 16:14:06 +00:00
" uniform vec3 e_origin; "
" uniform float e_time; "
" uniform vec3 e_eyepos; "
" uniform vec4 e_colour; "
" uniform vec4 e_colourident; "
" uniform vec3 e_glowmod; "
" uniform vec3 e_uppercolour; "
" uniform vec3 e_lowercolour; "
" uniform vec3 e_light_dir; "
" uniform vec3 e_light_mul; "
" uniform vec3 e_light_ambient; "
2015-03-03 00:14:43 +00:00
/*rtlight properties, use with caution*/
2017-02-11 16:14:06 +00:00
" uniform vec2 l_lightscreen; "
" uniform float l_lightradius; "
" uniform vec3 l_lightcolour; "
" uniform vec3 l_lightposition; "
2018-07-22 11:49:37 +00:00
" uniform vec3 l_lightdirection; "
2017-02-11 16:14:06 +00:00
" uniform vec3 l_lightcolourscale; "
" uniform mat4 l_cubematrix; "
" uniform vec4 l_shadowmapproj; "
" uniform vec2 l_shadowmapscale; "
2015-03-03 00:14:43 +00:00
" uniform vec2 e_rendertexturescale; \n "
" #endif \n "
,
2011-10-27 16:16:29 +00:00
" sys/skeletal.h " ,
2015-03-03 00:14:43 +00:00
" #ifndef DEFS_DEFINED \n "
2017-02-11 16:14:06 +00:00
" attribute vec3 v_normal; "
" attribute vec3 v_svector; "
" attribute vec3 v_tvector; "
" \n #endif \n "
2011-10-27 16:16:29 +00:00
" #ifdef SKELETAL \n "
2015-03-03 00:14:43 +00:00
" #ifndef DEFS_DEFINED \n "
" attribute vec4 v_bone; "
2017-01-29 13:10:53 +00:00
" attribute vec4 v_weight; \n "
" #ifdef PACKEDBONES \n "
2018-12-28 00:04:36 +00:00
" uniform vec4 m_bones_packed[3*MAX_GPU_BONES]; \n "
2017-01-29 13:10:53 +00:00
" #else \n "
2018-12-28 00:04:36 +00:00
" uniform mat3x4 m_bones_mat3x4[MAX_GPU_BONES]; \n "
2017-01-29 13:10:53 +00:00
" #endif \n "
2015-03-03 00:14:43 +00:00
" #endif \n "
2011-10-27 16:16:29 +00:00
2017-01-29 13:10:53 +00:00
" #ifdef PACKEDBONES \n "
" vec4 skeletaltransform() "
" { "
" mat4 wmat; "
2018-12-28 00:04:36 +00:00
" wmat[0] = m_bones_packed[0+3*int(v_bone.x)] * v_weight.x; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.y)] * v_weight.y; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.z)] * v_weight.z; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.w)] * v_weight.w; "
" wmat[1] = m_bones_packed[1+3*int(v_bone.x)] * v_weight.x; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.y)] * v_weight.y; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.z)] * v_weight.z; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.w)] * v_weight.w; "
" wmat[2] = m_bones_packed[2+3*int(v_bone.x)] * v_weight.x; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.y)] * v_weight.y; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.z)] * v_weight.z; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.w)] * v_weight.w; "
2017-01-29 13:10:53 +00:00
" wmat[3] = vec4(0.0,0.0,0.0,1.0); \n "
" return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat); "
" } \n "
" vec4 skeletaltransform_nst(out vec3 n, out vec3 t, out vec3 b) "
" { "
" mat4 wmat; "
2018-12-28 00:04:36 +00:00
" wmat[0] = m_bones_packed[0+3*int(v_bone.x)] * v_weight.x; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.y)] * v_weight.y; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.z)] * v_weight.z; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.w)] * v_weight.w; "
" wmat[1] = m_bones_packed[1+3*int(v_bone.x)] * v_weight.x; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.y)] * v_weight.y; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.z)] * v_weight.z; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.w)] * v_weight.w; "
" wmat[2] = m_bones_packed[2+3*int(v_bone.x)] * v_weight.x; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.y)] * v_weight.y; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.z)] * v_weight.z; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.w)] * v_weight.w; "
2017-01-29 13:10:53 +00:00
" wmat[3] = vec4(0.0,0.0,0.0,1.0); "
" n = (vec4(v_normal.xyz, 0.0) * wmat).xyz; "
" t = (vec4(v_svector.xyz, 0.0) * wmat).xyz; "
" b = (vec4(v_tvector.xyz, 0.0) * wmat).xyz; "
" return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat); "
" } \n "
" vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b) "
" { "
" mat4 wmat; "
2018-12-28 00:04:36 +00:00
" wmat[0] = m_bones_packed[0+3*int(v_bone.x)] * v_weight.x; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.y)] * v_weight.y; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.z)] * v_weight.z; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.w)] * v_weight.w; "
" wmat[1] = m_bones_packed[1+3*int(v_bone.x)] * v_weight.x; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.y)] * v_weight.y; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.z)] * v_weight.z; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.w)] * v_weight.w; "
" wmat[2] = m_bones_packed[2+3*int(v_bone.x)] * v_weight.x; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.y)] * v_weight.y; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.z)] * v_weight.z; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.w)] * v_weight.w; "
2017-01-29 13:10:53 +00:00
" wmat[3] = vec4(0.0,0.0,0.0,1.0); "
" n = (vec4(v_normal.xyz, 0.0) * wmat).xyz; "
" t = (vec4(v_svector.xyz, 0.0) * wmat).xyz; "
" b = (vec4(v_tvector.xyz, 0.0) * wmat).xyz; "
" w = (vec4(v_position.xyz, 1.0) * wmat).xyz; "
" return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat); "
" } \n "
2019-02-19 06:49:03 +00:00
" vec4 skeletaltransform_wnst(out vec3 w) "
" { "
" mat4 wmat; "
" wmat[0] = m_bones_packed[0+3*int(v_bone.x)] * v_weight.x; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.y)] * v_weight.y; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.z)] * v_weight.z; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.w)] * v_weight.w; "
" wmat[1] = m_bones_packed[1+3*int(v_bone.x)] * v_weight.x; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.y)] * v_weight.y; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.z)] * v_weight.z; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.w)] * v_weight.w; "
" wmat[2] = m_bones_packed[2+3*int(v_bone.x)] * v_weight.x; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.y)] * v_weight.y; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.z)] * v_weight.z; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.w)] * v_weight.w; "
" wmat[3] = vec4(0.0,0.0,0.0,1.0); "
" w = (vec4(v_position.xyz, 1.0) * wmat).xyz; "
" return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat); "
" } \n "
2017-01-29 13:10:53 +00:00
" vec4 skeletaltransform_n(out vec3 n) "
" { "
" mat4 wmat; "
2018-12-28 00:04:36 +00:00
" wmat[0] = m_bones_packed[0+3*int(v_bone.x)] * v_weight.x; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.y)] * v_weight.y; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.z)] * v_weight.z; "
" wmat[0] += m_bones_packed[0+3*int(v_bone.w)] * v_weight.w; "
" wmat[1] = m_bones_packed[1+3*int(v_bone.x)] * v_weight.x; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.y)] * v_weight.y; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.z)] * v_weight.z; "
" wmat[1] += m_bones_packed[1+3*int(v_bone.w)] * v_weight.w; "
" wmat[2] = m_bones_packed[2+3*int(v_bone.x)] * v_weight.x; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.y)] * v_weight.y; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.z)] * v_weight.z; "
" wmat[2] += m_bones_packed[2+3*int(v_bone.w)] * v_weight.w; "
2017-01-29 13:10:53 +00:00
" wmat[3] = vec4(0.0,0.0,0.0,1.0); "
" n = (vec4(v_normal.xyz, 0.0) * wmat).xyz; "
" return m_modelviewprojection * (vec4(v_position.xyz, 1.0) * wmat); "
" } \n "
" #else \n "
" vec4 skeletaltransform() "
" { "
" mat3x4 wmat; "
2018-12-28 00:04:36 +00:00
" wmat = m_bones_mat3x4[int(v_bone.x)] * v_weight.x; "
" wmat += m_bones_mat3x4[int(v_bone.y)] * v_weight.y; "
" wmat += m_bones_mat3x4[int(v_bone.z)] * v_weight.z; "
" wmat += m_bones_mat3x4[int(v_bone.w)] * v_weight.w; "
2017-01-29 13:10:53 +00:00
" return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0); "
" } \n "
" vec4 skeletaltransform_nst(out vec3 n, out vec3 t, out vec3 b) "
" { "
" mat3x4 wmat; "
2018-12-28 00:04:36 +00:00
" wmat = m_bones_mat3x4[int(v_bone.x)] * v_weight.x; "
" wmat += m_bones_mat3x4[int(v_bone.y)] * v_weight.y; "
" wmat += m_bones_mat3x4[int(v_bone.z)] * v_weight.z; "
" wmat += m_bones_mat3x4[int(v_bone.w)] * v_weight.w; "
2017-01-29 13:10:53 +00:00
" n = vec4(v_normal.xyz, 0.0) * wmat; "
" t = vec4(v_svector.xyz, 0.0) * wmat; "
" b = vec4(v_tvector.xyz, 0.0) * wmat; "
" return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0); "
" } \n "
" vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b) "
" { "
" mat3x4 wmat; "
2018-12-28 00:04:36 +00:00
" wmat = m_bones_mat3x4[int(v_bone.x)] * v_weight.x; "
" wmat += m_bones_mat3x4[int(v_bone.y)] * v_weight.y; "
" wmat += m_bones_mat3x4[int(v_bone.z)] * v_weight.z; "
" wmat += m_bones_mat3x4[int(v_bone.w)] * v_weight.w; "
2017-01-29 13:10:53 +00:00
" n = vec4(v_normal.xyz, 0.0) * wmat; "
" t = vec4(v_svector.xyz, 0.0) * wmat; "
" b = vec4(v_tvector.xyz, 0.0) * wmat; "
" w = vec4(v_position.xyz, 1.0) * wmat; "
" return m_modelviewprojection * vec4(w, 1.0); "
" } \n "
2019-02-19 06:49:03 +00:00
" vec4 skeletaltransform_w(out vec3 w) "
" { "
" mat3x4 wmat; "
" wmat = m_bones_mat3x4[int(v_bone.x)] * v_weight.x; "
" wmat += m_bones_mat3x4[int(v_bone.y)] * v_weight.y; "
" wmat += m_bones_mat3x4[int(v_bone.z)] * v_weight.z; "
" wmat += m_bones_mat3x4[int(v_bone.w)] * v_weight.w; "
" w = vec4(v_position.xyz, 1.0) * wmat; "
" return m_modelviewprojection * vec4(w, 1.0); "
" } \n "
2017-01-29 13:10:53 +00:00
" vec4 skeletaltransform_n(out vec3 n) "
" { "
" mat3x4 wmat; "
2018-12-28 00:04:36 +00:00
" wmat = m_bones_mat3x4[int(v_bone.x)] * v_weight.x; "
" wmat += m_bones_mat3x4[int(v_bone.y)] * v_weight.y; "
" wmat += m_bones_mat3x4[int(v_bone.z)] * v_weight.z; "
" wmat += m_bones_mat3x4[int(v_bone.w)] * v_weight.w; "
2017-01-29 13:10:53 +00:00
" n = vec4(v_normal.xyz, 0.0) * wmat; "
" return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0); "
" } \n "
" #endif \n "
2011-10-27 16:16:29 +00:00
" #else \n "
2015-05-14 03:06:58 +00:00
" #define skeletaltransform ftetransform \n "
2011-10-27 16:16:29 +00:00
" vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b) "
" { "
" n = v_normal; "
" t = v_svector; "
" b = v_tvector; "
" w = v_position.xyz; "
" return ftetransform(); "
" } \n "
2019-02-19 06:49:03 +00:00
" vec4 skeletaltransform_w(out vec3 w) "
" { "
" w = v_position.xyz; "
" return ftetransform(); "
" } \n "
2011-10-27 16:16:29 +00:00
" vec4 skeletaltransform_nst(out vec3 n, out vec3 t, out vec3 b) "
" { "
" n = v_normal; "
" t = v_svector; "
" b = v_tvector; "
" return ftetransform(); "
" } \n "
" vec4 skeletaltransform_n(out vec3 n) "
" { "
" n = v_normal; "
" return ftetransform(); "
" } \n "
" #endif \n "
,
2011-12-23 03:12:29 +00:00
" sys/fog.h " ,
" #ifdef FRAGMENT_SHADER \n "
" #ifdef FOG \n "
2015-03-03 00:14:43 +00:00
" #ifndef DEFS_DEFINED \n "
2014-03-30 08:55:06 +00:00
" uniform vec4 w_fog[2]; \n "
2015-03-03 00:14:43 +00:00
" #define w_fogcolour w_fog[0].rgb \n "
" #define w_fogalpha w_fog[0].a \n "
" #define w_fogdensity w_fog[1].x \n "
" #define w_fogdepthbias w_fog[1].y \n "
" #endif \n "
2011-12-23 03:12:29 +00:00
" vec3 fog3(in vec3 regularcolour) "
" { "
2015-03-03 00:14:43 +00:00
" float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w; \n "
" z = max(0.0,z-w_fogdepthbias); \n "
2012-04-09 19:12:12 +00:00
" #if #include \" cvar/r_fog_exp2 \" \n "
" z *= z; \n "
" #endif \n "
" float fac = exp2(-(z * 1.442695)); \n "
2015-03-03 00:14:43 +00:00
" fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha); \n "
" return mix(w_fogcolour, regularcolour, fac); \n "
2011-12-23 03:12:29 +00:00
" } \n "
" vec3 fog3additive(in vec3 regularcolour) "
" { "
2015-03-03 00:14:43 +00:00
" float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w; \n "
" z = max(0.0,z-w_fogdepthbias); \n "
2012-04-09 19:12:12 +00:00
" #if #include \" cvar/r_fog_exp2 \" \n "
" z *= z; \n "
" #endif \n "
" float fac = exp2(-(z * 1.442695)); \n "
2015-03-03 00:14:43 +00:00
" fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha); \n "
2011-12-23 03:12:29 +00:00
" return regularcolour * fac; \n "
" } \n "
" vec4 fog4(in vec4 regularcolour) "
" { "
" return vec4(fog3(regularcolour.rgb), 1.0) * regularcolour.a; \n "
" } \n "
" vec4 fog4additive(in vec4 regularcolour) "
" { "
2015-03-03 00:14:43 +00:00
" float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w; \n "
" z = max(0.0,z-w_fogdepthbias); \n "
2012-04-09 19:12:12 +00:00
" #if #include \" cvar/r_fog_exp2 \" \n "
" z *= z; \n "
" #endif \n "
" float fac = exp2(-(z * 1.442695)); \n "
2015-03-03 00:14:43 +00:00
" fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha); \n "
2011-12-23 03:12:29 +00:00
" return regularcolour * vec4(fac, fac, fac, 1.0); \n "
" } \n "
" vec4 fog4blend(in vec4 regularcolour) "
" { "
2015-03-03 00:14:43 +00:00
" float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w; \n "
" z = max(0.0,z-w_fogdepthbias); \n "
2012-04-09 19:12:12 +00:00
" #if #include \" cvar/r_fog_exp2 \" \n "
" z *= z; \n "
" #endif \n "
" float fac = exp2(-(z * 1.442695)); \n "
2015-03-03 00:14:43 +00:00
" fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha); \n "
2011-12-23 03:12:29 +00:00
" return regularcolour * vec4(1.0, 1.0, 1.0, fac); \n "
" } \n "
" #else \n "
/*don't use macros for this - mesa bugs out*/
" vec3 fog3(in vec3 regularcolour) { return regularcolour; } \n "
" vec3 fog3additive(in vec3 regularcolour) { return regularcolour; } \n "
" vec4 fog4(in vec4 regularcolour) { return regularcolour; } \n "
" vec4 fog4additive(in vec4 regularcolour) { return regularcolour; } \n "
" vec4 fog4blend(in vec4 regularcolour) { return regularcolour; } \n "
" #endif \n "
" #endif \n "
,
2012-01-17 07:57:46 +00:00
" sys/offsetmapping.h " ,
" uniform float cvar_r_glsl_offsetmapping_scale; \n "
" vec2 offsetmap(sampler2D normtex, vec2 base, vec3 eyevector) \n "
" { \n "
2014-11-05 05:39:24 +00:00
" #if !defined(OFFSETMAPPING_SCALE) \n "
" #define OFFSETMAPPING_SCALE 1.0 \n "
" #endif \n "
2017-10-12 12:02:25 +00:00
" #if !defined(OFFSETMAPPING_BIAS) \n "
" #define OFFSETMAPPING_BIAS 0.0 \n "
" #endif \n "
2012-04-24 07:59:11 +00:00
" #if defined(RELIEFMAPPING) && !defined(GL_ES) \n "
2012-01-17 07:57:46 +00:00
" float i, f; \n "
2014-11-05 05:39:24 +00:00
" vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * OFFSETMAPPING_SCALE * vec2(-1.0, 1.0), -1.0); \n "
2012-01-17 07:57:46 +00:00
" vec3 RT = vec3(vec2(base.xy " /* - OffsetVector.xy*OffsetMapping_Bias*/ " ), 1.0); \n "
" OffsetVector /= 10.0; \n "
" for(i = 1.0; i < 10.0; ++i) \n "
" RT += OffsetVector * step(texture2D(normtex, RT.xy).a, RT.z); \n "
" for(i = 0.0, f = 1.0; i < 5.0; ++i, f *= 0.5) \n "
" RT += OffsetVector * (step(texture2D(normtex, RT.xy).a, RT.z) * f - 0.5 * f); \n "
" return RT.xy; \n "
" #elif defined(OFFSETMAPPING) \n "
2014-11-05 05:39:24 +00:00
" vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * OFFSETMAPPING_SCALE * vec2(-1.0, 1.0); \n "
2012-01-17 07:57:46 +00:00
" vec2 tc = base; \n "
" tc += OffsetVector; \n "
" OffsetVector *= 0.333; \n "
2018-12-28 00:04:36 +00:00
" tc -= OffsetVector * texture2D(normtex, tc).a; \n "
" tc -= OffsetVector * texture2D(normtex, tc).a; \n "
" tc -= OffsetVector * texture2D(normtex, tc).a; \n "
2012-01-17 07:57:46 +00:00
" return tc; \n "
" #else \n "
" return base; \n "
" #endif \n "
" } \n "
,
2019-03-12 05:04:27 +00:00
" sys/pbr.h " ,
//ripped from the gltf webgl demo.
//https://github.com/KhronosGroup/glTF-WebGL-PBR/blob/master/shaders/pbr-frag.glsl
//because most of this maths is gibberish, especially the odd magic number.
" #ifdef PBR \n "
" const float PI = 3.141592653589793; \n "
" vec3 diffuse(vec3 diffuseColor) \n " //Basic Lambertian diffuse
" { \n "
" return diffuseColor / PI; \n "
" } \n "
" vec3 specularReflection(vec3 reflectance0, vec3 reflectance90, float VdotH) \n "
" { \n "
" return reflectance0 + (reflectance90 - reflectance0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0); \n "
" } \n "
" float geometricOcclusion(float NdotL, float NdotV, float r) \n "
" { \n "
" float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); \n "
" float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); \n "
" return attenuationL * attenuationV; \n "
" } \n "
" float microfacetDistribution(float alphaRoughness, float NdotH) \n " //Trowbridge-Reitz
" { \n "
" float roughnessSq = alphaRoughness * alphaRoughness; \n "
" float f = (NdotH * roughnessSq - NdotH) * NdotH + 1.0; \n "
" return roughnessSq / (PI * f * f); \n "
" } \n "
" vec3 DoPBR(vec3 n, vec3 v, vec3 l, float perceptualRoughness, vec3 diffuseColor, vec3 specularColor, vec3 scales) \n "
" { \n "
// Compute reflectance.
" float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b); \n "
" float alphaRoughness = perceptualRoughness * perceptualRoughness; \n "
// For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
// For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
" float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0); \n "
" vec3 specularEnvironmentR0 = specularColor.rgb; \n "
" vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90; \n "
" vec3 h = normalize(l+v); \n " // Half vector between both l and v
" vec3 reflection = -normalize(reflect(v, n)); \n "
" float NdotL = clamp(dot(n, l), 0.001, 1.0); \n "
" float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0); \n "
" float NdotH = clamp(dot(n, h), 0.0, 1.0); \n "
" float LdotH = clamp(dot(l, h), 0.0, 1.0); \n "
" float VdotH = clamp(dot(v, h), 0.0, 1.0); \n "
// Calculate the shading terms for the microfacet specular shading model
" vec3 F = specularReflection(specularEnvironmentR0, specularEnvironmentR90, VdotH); \n "
" float G = geometricOcclusion(NdotL, NdotV, alphaRoughness); \n "
" float D = microfacetDistribution(alphaRoughness, NdotH); \n "
// Calculation of analytical lighting contribution
" vec3 diffuseContrib = (1.0 - F) * diffuse(diffuseColor) * scales.y; \n "
" vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV) * scales.z; \n "
// Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
" return NdotL * (diffuseContrib + specContrib); \n "
" } \n "
" #endif \n "
,
2013-10-29 17:38:22 +00:00
" sys/pcf.h " ,
2017-03-06 14:06:12 +00:00
//!!cvardf r_glsl_pcf
" #ifndef PCF \n "
2017-10-31 22:52:58 +00:00
" #define ShadowmapFilter(smap,proj) 1.0 \n " //s_shadowmap generally. returns a scaler to say how much light should be used for this pixel.
2013-10-29 17:38:22 +00:00
" #else \n "
2017-03-06 14:06:12 +00:00
" #ifndef r_glsl_pcf \n "
" #define r_glsl_pcf 9 \n "
" #endif \n "
" #if r_glsl_pcf < 1 \n "
" #undef r_glsl_pcf \n "
" #define r_glsl_pcf 9 \n "
" #endif \n "
" #ifndef DEFS_DEFINED \n "
" uniform vec4 l_shadowmapproj; \n " //light projection matrix info
" uniform vec2 l_shadowmapscale; \n " //xy are the texture scale, z is 1, w is the scale.
" #endif \n "
2017-10-31 22:52:58 +00:00
" vec3 ShadowmapCoord(vec4 cubeproj) \n "
2013-10-29 17:38:22 +00:00
" { \n "
2017-03-06 14:06:12 +00:00
" #ifdef SPOT \n "
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
2018-01-22 19:18:04 +00:00
" return ((cubeproj.yxz-vec3(0.0,0.0,0.015))/cubeproj.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5); \n "
" #elif defined(ORTHO) \n "
//the light's origin is in the center of the 'cube', projecting from one side to the other, so don't bias the z.
2018-07-22 11:49:37 +00:00
" return ((cubeproj.xyz-vec3(0.0,0.0,0.015))/cubeproj.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5); \n "
2017-03-06 14:06:12 +00:00
//"#elif defined(CUBESHADOW)\n"
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
" #else \n "
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
2017-10-31 22:52:58 +00:00
" vec3 dir = abs(cubeproj.xyz); \n "
2017-03-06 14:06:12 +00:00
//assume z is the major axis (ie: forward from the light)
2017-10-31 22:52:58 +00:00
" vec3 t = cubeproj.xyz; \n "
2017-03-06 14:06:12 +00:00
" float ma = dir.z; \n "
" vec3 axis = vec3(0.5/3.0, 0.5/2.0, 0.5); \n "
" if (dir.x > ma) \n "
" { \n "
" ma = dir.x; \n "
2017-10-31 22:52:58 +00:00
" t = cubeproj.zyx; \n "
2017-03-06 14:06:12 +00:00
" axis.x = 0.5; \n "
" } \n "
" if (dir.y > ma) \n "
" { \n "
" ma = dir.y; \n "
2017-10-31 22:52:58 +00:00
" t = cubeproj.xzy; \n "
2017-03-06 14:06:12 +00:00
" axis.x = 2.5/3.0; \n "
" } \n "
//if the axis is negative, flip it.
" if (t.z > 0.0) \n "
" { \n "
" axis.y = 1.5/2.0; \n "
" t.z = -t.z; \n "
" } \n "
2013-10-29 17:38:22 +00:00
2017-03-06 14:06:12 +00:00
//we also need to pass the result through the light's projection matrix too
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
" return axis + ((l_shadowmapproj.xyz*t.xyz + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z); \n "
" #endif \n "
" } \n "
2013-10-29 17:38:22 +00:00
2017-10-31 22:52:58 +00:00
" float ShadowmapFilter(sampler2DShadow smap, vec4 cubeproj) \n "
2017-03-06 14:06:12 +00:00
" { \n "
2017-10-31 22:52:58 +00:00
" vec3 shadowcoord = ShadowmapCoord(cubeproj); \n "
2018-01-22 19:18:04 +00:00
# ifdef SHADOWDBG_COLOURNOTDEPTH
//just r, unfortunately. oh well.
" return texture2D(smap, shadowcoord.xy + (vec2(0.0,0.0)*l_shadowmapscale.xy)).r; \n "
# else
2017-03-06 14:06:12 +00:00
" #if 0 \n " //def GL_ARB_texture_gather
" vec2 ipart, fpart; \n "
" #define dosamp(x,y) textureGatherOffset(smap, ipart.xy, vec2(x,y))) \n "
" vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0)); \n "
" vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0)); \n "
" vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0)); \n "
" vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0)); \n "
//we now have 4*4 results, woo
//we can just average them for 1/16th precision, but that's still limited graduations
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
" vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + " //middle two rows are full strength
" mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y); \n " //top+bottom rows
" return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); \n " //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.
2013-10-29 17:38:22 +00:00
" #else \n "
2017-03-06 14:06:12 +00:00
" #ifdef USE_ARB_SHADOW \n "
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
2017-04-18 11:12:17 +00:00
" #define dosamp(x,y) float(shadow2D(smap, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx))) \n "
2017-03-06 14:06:12 +00:00
" #else \n "
" #define dosamp(x,y) float(texture2D(smap, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z) \n "
" #endif \n "
" float s = 0.0; \n "
" #if r_glsl_pcf >= 1 && r_glsl_pcf < 5 \n "
" s += dosamp(0.0, 0.0); \n "
" return s; \n "
" #elif r_glsl_pcf >= 5 && r_glsl_pcf < 9 \n "
" s += dosamp(-1.0, 0.0); \n "
" s += dosamp(0.0, -1.0); \n "
" s += dosamp(0.0, 0.0); \n "
" s += dosamp(0.0, 1.0); \n "
" s += dosamp(1.0, 0.0); \n "
" return s/5.0; \n "
" #else \n "
" s += dosamp(-1.0, -1.0); \n "
" s += dosamp(-1.0, 0.0); \n "
" s += dosamp(-1.0, 1.0); \n "
" s += dosamp(0.0, -1.0); \n "
" s += dosamp(0.0, 0.0); \n "
" s += dosamp(0.0, 1.0); \n "
" s += dosamp(1.0, -1.0); \n "
" s += dosamp(1.0, 0.0); \n "
" s += dosamp(1.0, 1.0); \n "
" return s/9.0; \n "
" #endif \n "
2013-10-29 17:38:22 +00:00
" #endif \n "
2018-01-22 19:18:04 +00:00
# endif
2017-03-06 14:06:12 +00:00
" } \n "
" #endif \n "
2013-10-29 17:38:22 +00:00
,
2011-10-27 16:16:29 +00:00
NULL
} ;
2018-08-04 07:05:20 +00:00
# define GLSLPARTS (64+16)
struct glslparts_s
{
const GLchar * str [ GLSLPARTS ] ;
GLint len [ GLSLPARTS ] ;
const GLchar * file [ GLSLPARTS ] ;
int line [ GLSLPARTS ] ;
int strings ;
const char * error ;
} ;
static void GLSlang_GenerateInternal ( struct glslparts_s * glsl , const char * shadersource )
{
if ( glsl - > strings = = GLSLPARTS )
{
glsl - > error = " Too many parts " ;
return ;
}
glsl - > str [ glsl - > strings ] = shadersource ;
glsl - > len [ glsl - > strings ] = strlen ( shadersource ) ;
glsl - > file [ glsl - > strings ] = NULL ;
glsl - > line [ glsl - > strings ] = 0 ;
glsl - > strings + = 1 ;
}
static void GLSlang_Generate ( struct glslparts_s * glsl , const char * shadersource , GLint length , const char * filename , int linenumber )
{
if ( glsl - > strings = = GLSLPARTS )
{
glsl - > error = " Too many parts " ;
return ;
}
glsl - > str [ glsl - > strings ] = shadersource ;
glsl - > len [ glsl - > strings ] = length ;
glsl - > file [ glsl - > strings ] = filename ;
glsl - > line [ glsl - > strings ] = linenumber ;
glsl - > strings + = 1 ;
}
static qboolean GLSlang_GenerateIncludes ( struct glslparts_s * glsl , const char * shadersource , const char * filename , int linenumber )
2011-10-27 16:16:29 +00:00
{
int i ;
char * incline , * inc ;
char incname [ 256 ] ;
while ( ( incline = strstr ( shadersource , " #include " ) ) )
{
/*emit up to the include*/
2015-03-03 00:14:43 +00:00
if ( incline - shadersource )
{
2018-08-04 07:05:20 +00:00
char * e = incline ;
while ( e > shadersource & & ( e [ - 1 ] = = ' ' | | e [ - 1 ] = = ' \t ' ) )
e - - ;
if ( e > shadersource & & e [ - 1 ] = = ' \n ' )
GLSlang_Generate ( glsl , shadersource , e - shadersource , filename , linenumber ) ;
else
GLSlang_Generate ( glsl , shadersource , incline - shadersource , filename , linenumber ) ;
2015-03-03 00:14:43 +00:00
}
2011-10-27 16:16:29 +00:00
incline + = 8 ;
incline = COM_ParseOut ( incline , incname , sizeof ( incname ) ) ;
2018-08-04 07:05:20 +00:00
if ( ! incline )
{
glsl - > error = " missing include name " ;
return false ;
}
while ( * incline = = ' ' | | * incline = = ' \t ' )
incline + + ;
2011-10-27 16:16:29 +00:00
2012-04-09 19:12:12 +00:00
if ( ! strncmp ( incname , " cvar/ " , 5 ) )
2011-10-27 16:16:29 +00:00
{
2012-04-09 19:12:12 +00:00
cvar_t * var = Cvar_Get ( incname + 5 , " 0 " , 0 , " shader cvars " ) ;
if ( var )
2011-10-27 16:16:29 +00:00
{
2012-04-09 19:12:12 +00:00
var - > flags | = CVAR_SHADERSYSTEM ;
2018-08-04 07:05:20 +00:00
if ( ! GLSlang_GenerateIncludes ( glsl , var - > string , NULL , 0 ) )
2011-10-27 16:16:29 +00:00
return false ;
2012-04-09 19:12:12 +00:00
}
else
{
/*dump something if the cvar doesn't exist*/
2018-08-04 07:05:20 +00:00
GLSlang_Generate ( glsl , " 0 " , strlen ( " 0 " ) , filename , linenumber ) ;
2011-10-27 16:16:29 +00:00
}
}
2012-04-09 19:12:12 +00:00
else
2011-10-27 16:16:29 +00:00
{
2012-04-09 19:12:12 +00:00
for ( i = 0 ; glsl_hdrs [ i ] ; i + = 2 )
2011-10-27 16:16:29 +00:00
{
2012-04-09 19:12:12 +00:00
if ( ! strcmp ( incname , glsl_hdrs [ i ] ) )
2011-10-27 16:16:29 +00:00
{
2018-08-04 07:05:20 +00:00
if ( ! GLSlang_GenerateIncludes ( glsl , glsl_hdrs [ i + 1 ] , glsl_hdrs [ i ] , 1 ) )
2012-04-09 19:12:12 +00:00
return false ;
break ;
}
}
if ( ! glsl_hdrs [ i ] )
{
2018-08-04 07:05:20 +00:00
size_t sz ;
inc = COM_LoadTempMoreFile ( incname , & sz ) ;
if ( inc )
2012-04-09 19:12:12 +00:00
{
2018-08-04 07:05:20 +00:00
if ( ! GLSlang_GenerateIncludes ( glsl , inc , NULL , 1 ) )
2012-04-09 19:12:12 +00:00
return false ;
2018-08-04 07:05:20 +00:00
}
else
{
glsl - > error = " include file not found " ;
return false ; //FIXME: add a warning
2011-10-27 16:16:29 +00:00
}
}
}
/*move the pointer past the include*/
2018-08-04 07:05:20 +00:00
while ( shadersource < incline )
{
if ( * shadersource = = ' \n ' )
linenumber + + ;
shadersource + + ;
}
2011-10-27 16:16:29 +00:00
}
2018-08-04 07:05:20 +00:00
if ( * shadersource )
GLSlang_Generate ( glsl , shadersource , strlen ( shadersource ) , filename , linenumber ) ;
2011-10-27 16:16:29 +00:00
return true ;
}
2005-01-04 23:34:42 +00:00
// glslang helper api function definitions
// type should be GL_FRAGMENT_SHADER_ARB or GL_VERTEX_SHADER_ARB
2014-05-10 13:42:13 +00:00
//doesn't check to see if it was okay. use FinishShader for that.
2016-07-26 11:47:59 +00:00
static GLhandleARB GLSlang_CreateShader ( program_t * prog , const char * name , int ver , const char * * precompilerconstants , const char * shadersource , GLenum shadertype , qboolean silent )
2005-01-04 23:34:42 +00:00
{
GLhandleARB shader ;
2014-05-10 13:42:13 +00:00
int i ;
2018-08-04 07:05:20 +00:00
struct glslparts_s glsl ;
2014-08-25 07:35:41 +00:00
char verline [ 64 ] ;
2005-01-04 23:34:42 +00:00
2018-08-04 07:05:20 +00:00
glsl . strings = 0 ;
glsl . error = NULL ;
2014-11-05 05:39:24 +00:00
if ( ! shadersource )
return 0 ;
2011-10-27 16:16:29 +00:00
if ( ver )
{
2012-01-17 07:57:46 +00:00
/*required version not supported, don't even try*/
if ( ver > gl_config . maxglslversion )
return 0 ;
2013-04-04 08:08:49 +00:00
# ifdef FTE_TARGET_WEB
2015-04-21 20:08:55 +00:00
//emscripten prefixes our shader with a precision specifier, and then the browser bitches at the following (otherwise valid) #version, so don't say anything at all if its ver 100, and the browser won't complain
2013-04-04 08:08:49 +00:00
if ( ver ! = 100 )
# endif
{
2017-02-21 20:22:07 +00:00
//known versions:
2017-11-05 13:15:08 +00:00
//<undefined> == gl
2017-02-21 20:22:07 +00:00
//100 == gles2
//110 == gl2.0
//120 == gl2.1
//130 == gl3.0
//140 == gl3.1
//150 [core|compatibility] == gl3.2
//300 ES == gles3
2017-11-05 13:15:08 +00:00
//310 ES == gles3.1
2019-01-13 16:51:50 +00:00
//320 ES == gles3.2
2017-11-05 13:15:08 +00:00
//330, 400, 410, 420, 430 [core|compatibility] == gl?.??
if ( gl_config_gles )
{
if ( ver < = 110 ) //gles2 is rougly gl2 so 100(es)==110ish
ver = 100 ;
else if ( ver < = 330 ) //gles3 is rougly gl3.3 so 300es==330ish
ver = 300 ;
}
2019-01-13 16:51:50 +00:00
else
{
if ( ver = = 100 )
ver = 110 ; //gles2 is roughly equivelent to gl2
else if ( ver > = 300 & & ver < 330 )
ver = 330 ; //gles3 is roughly equivelent to gl3.3
}
2017-11-05 13:15:08 +00:00
2017-02-21 20:22:07 +00:00
if ( gl_config_gles & & ver ! = 100 )
2017-11-05 13:15:08 +00:00
Q_snprintfz ( verline , sizeof ( verline ) , " #version %u es \n " , ver ) ;
2017-02-21 20:22:07 +00:00
else if ( ! gl_config_gles & & ver > = 150 & & ! gl_config_nofixedfunc )
//favour compatibility profile, simply because we want ftransform to work properly
//note that versions 130+140 are awkward due to deprecation stuff, both assume compatibility profiles where supported.
// however, 130 REMOVED ftransform in revision 2 and then re-added it as deprecated in revision 4 (of 10).
Q_snprintfz ( verline , sizeof ( verline ) , " #version %u compatibility \n " , ver ) ;
else
Q_snprintfz ( verline , sizeof ( verline ) , " #version %u \n " , ver ) ; //core assumed, where defined
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , verline ) ;
2013-04-04 08:08:49 +00:00
}
2011-10-27 16:16:29 +00:00
}
2011-05-26 16:46:43 +00:00
2011-07-30 14:14:56 +00:00
while ( * precompilerconstants )
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , * precompilerconstants + + ) ;
2011-10-27 16:16:29 +00:00
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , " #define ENGINE_ " DISTRIBUTION " \n " ) ;
2018-12-28 00:04:36 +00:00
if ( ver < 120 )
GLSlang_GenerateInternal ( & glsl , " #define PACKEDBONES \n " ) ;
2011-07-30 14:14:56 +00:00
2009-07-05 18:45:53 +00:00
switch ( shadertype )
{
case GL_FRAGMENT_SHADER_ARB :
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , " #define FRAGMENT_SHADER \n " ) ;
2011-06-05 23:53:33 +00:00
if ( gl_config . gles )
{
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
2015-04-14 23:12:17 +00:00
" #ifdef GL_FRAGMENT_PRECISION_HIGH \n "
" precision highp float; \n "
" #else \n "
" precision mediump float; \n "
" #endif \n "
2018-08-04 07:05:20 +00:00
) ;
2011-06-05 23:53:33 +00:00
}
2017-02-11 16:14:06 +00:00
if ( ver > = 130 )
2014-12-09 14:39:54 +00:00
{
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
2019-01-13 16:51:50 +00:00
//gl3+ deprecated some things. these are removed in forwards-compatible / core contexts.
2017-02-21 20:22:07 +00:00
//varying became either in or out, which is important if you have geometry shaders...
2014-12-09 14:39:54 +00:00
" #define varying in \n "
2017-02-21 20:22:07 +00:00
//now only the 'texture' function exists, with overloads for each sampler type.
2017-02-11 16:14:06 +00:00
" #define texture2D texture \n "
" #define textureCube texture \n "
" #define shadow2D texture \n "
2017-02-21 20:22:07 +00:00
//gl_FragColor and gl_FragData got deprecated too, need to make manual outputs
2017-10-31 22:52:58 +00:00
" #if __VERSION__ >= 300 \n " //gl3.3, gles3 (gles3 requires layout stuff)
" layout(location = 0) out vec4 fte_fragdata0; "
" layout(location = 1) out vec4 fte_fragdata1; "
" layout(location = 2) out vec4 fte_fragdata2; "
" layout(location = 3) out vec4 fte_fragdata3; "
" \n #else \n "
" out vec4 fte_fragdata0; "
" out vec4 fte_fragdata1; "
" out vec4 fte_fragdata2; "
" out vec4 fte_fragdata3; "
" \n #endif \n " //gles3 requires this
" #define gl_FragColor fte_fragdata0 \n "
2018-08-04 07:05:20 +00:00
) ;
2017-10-31 22:52:58 +00:00
}
else
{
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
2017-10-31 22:52:58 +00:00
" #define fte_fragdata0 gl_FragData[0] \n "
" #define fte_fragdata1 gl_FragData[1] \n "
" #define fte_fragdata2 gl_FragData[2] \n "
" #define fte_fragdata3 gl_FragData[3] \n "
2018-08-04 07:05:20 +00:00
) ;
2014-12-09 14:39:54 +00:00
}
2016-07-26 11:47:59 +00:00
if ( prog )
2018-11-27 16:48:19 +00:00
{ //for compat with our vulkan processor, which injects samplers in order to control layouts.
2016-07-26 11:47:59 +00:00
const char * defaultsamplernames [ ] =
{
2018-12-28 00:04:36 +00:00
# ifdef SHADOWDBG_COLOURNOTDEPTH
" #define sampler2DShadow sampler2D \n "
# else
" #ifndef USE_ARB_SHADOW \n " //fall back on regular samplers if we must
" #define sampler2DShadow sampler2D \n "
2019-01-13 16:51:50 +00:00
" #elif defined(GL_ES) \n "
2019-05-23 15:11:32 +00:00
" #if __VERSION__ < 300 \n "
" #extension GL_EXT_shadow_samplers : require \n "
" #endif \n "
2019-01-13 16:51:50 +00:00
" precision lowp sampler2DShadow; \n " //gah
2018-12-28 00:04:36 +00:00
" #endif \n "
# endif
2017-02-11 16:14:06 +00:00
" uniform sampler2DShadow s_shadowmap; \n " ,
2018-12-28 00:04:36 +00:00
2016-07-26 11:47:59 +00:00
" uniform samplerCube s_projectionmap; \n " ,
" uniform sampler2D s_diffuse; \n " ,
" uniform sampler2D s_normalmap; \n " ,
" uniform sampler2D s_specular; \n " ,
" uniform sampler2D s_upper; \n " ,
" uniform sampler2D s_lower; \n " ,
" uniform sampler2D s_fullbright; \n " ,
" uniform sampler2D s_paletted; \n " ,
" uniform samplerCube s_reflectcube; \n " ,
" uniform sampler2D s_reflectmask; \n " ,
2019-02-01 08:29:14 +00:00
" uniform sampler2D s_displacement; \n " ,
2019-09-04 07:59:40 +00:00
" uniform sampler2D s_occlusion; \n " ,
2016-07-26 11:47:59 +00:00
" uniform sampler2D s_lightmap; \n #define s_lightmap0 s_lightmap \n " ,
2018-07-05 16:21:44 +00:00
" uniform sampler2D s_deluxemap; \n #define s_deluxemap0 s_deluxemap \n " ,
2016-07-26 11:47:59 +00:00
" uniform sampler2D s_lightmap1; \n " ,
" uniform sampler2D s_lightmap2; \n " ,
" uniform sampler2D s_lightmap3; \n " ,
2018-07-05 16:21:44 +00:00
" uniform sampler2D s_deluxemap1; \n " ,
" uniform sampler2D s_deluxemap2; \n " ,
" uniform sampler2D s_deluxemap3; \n " ,
2016-07-26 11:47:59 +00:00
} ;
for ( i = 0 ; i < countof ( defaultsamplernames ) ; i + + )
{
if ( prog - > defaulttextures & ( 1u < < i ) )
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , defaultsamplernames [ i ] ) ;
2016-07-26 11:47:59 +00:00
}
}
2009-07-05 18:45:53 +00:00
break ;
2015-07-01 23:15:25 +00:00
case GL_GEOMETRY_SHADER_ARB :
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , " #define GEOMETRY_SHADER \n " ) ;
2015-07-01 23:15:25 +00:00
break ;
2014-11-05 05:39:24 +00:00
case GL_TESS_CONTROL_SHADER_ARB :
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
2017-02-11 16:14:06 +00:00
" #define TESS_CONTROL_SHADER \n "
" #if __VERSION__ < 400 \n "
" #extension GL_ARB_tessellation_shader : enable \n "
2018-08-04 07:05:20 +00:00
" #endif \n "
2017-02-11 16:14:06 +00:00
//varyings are arrays, so don't bother defining that here.
2018-08-04 07:05:20 +00:00
) ;
2014-11-05 05:39:24 +00:00
break ;
case GL_TESS_EVALUATION_SHADER_ARB :
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
2017-02-11 16:14:06 +00:00
" #define TESS_EVALUATION_SHADER \n "
" #if __VERSION__ < 400 \n "
" #extension GL_ARB_tessellation_shader : enable \n "
" #endif \n "
2018-08-04 07:05:20 +00:00
" #define varying out \n "
) ;
2014-11-05 05:39:24 +00:00
break ;
2009-07-05 18:45:53 +00:00
case GL_VERTEX_SHADER_ARB :
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , " #define VERTEX_SHADER \n " ) ;
2019-02-24 07:43:32 +00:00
if ( ( ver > = 120 | | gl_config_gles ) & & ! gl_config . blacklist_invariant ) //invariant appeared in glsl 120, or glessl 100. rtlights, stencil shadows, multipass materials, fog volumes, blend-depth-masking all need invariant depth.
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , " invariant gl_Position; \n " ) ;
2011-06-05 23:53:33 +00:00
if ( gl_config . gles )
{
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
2011-07-30 14:14:56 +00:00
" #ifdef GL_FRAGMENT_PRECISION_HIGH \n "
" precision highp float; \n "
" #else \n "
" precision mediump float; \n "
2011-10-27 16:16:29 +00:00
" #endif \n "
2018-08-04 07:05:20 +00:00
) ;
2011-06-05 23:53:33 +00:00
}
2015-10-11 11:34:58 +00:00
if ( ver > = 130 )
2014-11-05 05:39:24 +00:00
{
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
" #define attribute in \n "
" #define varying out \n "
) ;
2014-11-05 05:39:24 +00:00
}
2018-11-27 16:48:19 +00:00
2017-02-21 20:22:07 +00:00
if ( gl_config_nofixedfunc )
2011-06-05 23:53:33 +00:00
{
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
2014-12-09 14:39:54 +00:00
" attribute vec3 v_position1; \n "
2012-04-24 07:59:11 +00:00
" #ifdef FRAMEBLEND \n "
2014-12-09 14:39:54 +00:00
" attribute vec3 v_position2; \n "
2012-04-24 07:59:11 +00:00
" uniform vec2 e_vblend; \n "
2013-10-29 17:38:22 +00:00
" #define v_position ((v_position1*e_vblend.x)+(v_position2*e_vblend.y)) \n "
2013-10-08 14:28:11 +00:00
" #else \n "
" #define v_position v_position1 \n "
2012-04-24 07:59:11 +00:00
" #endif \n "
2011-09-03 03:49:43 +00:00
" uniform mat4 m_modelviewprojection; \n "
2015-05-14 03:06:58 +00:00
# if 1 //def FTE_TARGET_WEB
//IE is buggy
2014-08-25 07:35:41 +00:00
" vec4 ftetransform() { return m_modelviewprojection * vec4(v_position, 1.0); } \n "
2015-05-14 03:06:58 +00:00
# else
" #define ftetransform() (m_modelviewprojection * vec4(v_position, 1.0)) \n "
# endif
2018-08-04 07:05:20 +00:00
) ;
2011-06-05 23:53:33 +00:00
}
else
{
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl ,
2012-04-24 07:59:11 +00:00
" #ifdef FRAMEBLEND \n "
2014-12-09 14:39:54 +00:00
" attribute vec3 v_position2; \n "
2012-04-24 07:59:11 +00:00
" uniform vec2 e_vblend; \n "
" #define v_position (gl_Vertex.xyz*e_vblend.x+v_position2*e_vblend.y) \n "
" uniform mat4 m_modelviewprojection; \n "
2014-08-25 07:35:41 +00:00
" #define ftetransform() (m_modelviewprojection * vec4(v_position, 1.0)) \n "
2012-04-24 07:59:11 +00:00
" #else \n "
2014-05-13 23:17:12 +00:00
" #define v_position gl_Vertex.xyz \n "
2011-10-27 16:16:29 +00:00
" uniform mat4 m_modelviewprojection; \n "
2014-08-25 07:35:41 +00:00
" #define ftetransform ftransform \n "
2012-04-24 07:59:11 +00:00
" #endif \n "
2018-08-04 07:05:20 +00:00
) ;
2011-06-05 23:53:33 +00:00
}
2009-07-05 18:45:53 +00:00
break ;
default :
2018-08-04 07:05:20 +00:00
GLSlang_GenerateInternal ( & glsl , " #define UNKNOWN_SHADER \n " ) ;
2009-07-05 18:45:53 +00:00
break ;
}
2011-10-27 16:16:29 +00:00
2018-08-04 07:05:20 +00:00
GLSlang_GenerateIncludes ( & glsl , shadersource , name , 1 ) ;
2005-01-04 23:34:42 +00:00
2005-04-16 16:21:27 +00:00
shader = qglCreateShaderObjectARB ( shadertype ) ;
2005-01-04 23:34:42 +00:00
2018-08-04 07:05:20 +00:00
if ( developer . ival )
{
GLcharARB * combined ;
int totallen = 1 ;
for ( i = 0 ; i < glsl . strings ; i + + )
2018-09-23 19:35:24 +00:00
totallen + = glsl . len [ i ] + 64 + ( glsl . file [ i ] ? strlen ( glsl . file [ i ] ) : 0 ) ;
2018-08-04 07:05:20 +00:00
combined = malloc ( totallen ) ;
totallen = 0 ;
combined [ totallen ] = 0 ;
for ( i = 0 ; i < glsl . strings ; i + + )
{
if ( ver & & ! i )
; //#version MUST be the first line, don't prefix it with a #line, it'll just break things.
else if ( ! totallen | | combined [ totallen - 1 ] = = ' \n ' )
{ //last line was a newline, hurrah. safe to insert without breaking anything
2018-09-23 19:35:24 +00:00
if ( glsl . file [ i ] )
Q_snprintfz ( combined + totallen , 64 + strlen ( glsl . file [ i ] ) , " #line %i %i //%s \n " , glsl . line [ i ] , i , glsl . file [ i ] ) ;
else
Q_snprintfz ( combined + totallen , 64 , " #line %i %i \n " , glsl . line [ i ] , i ) ;
2018-08-04 07:05:20 +00:00
totallen + = strlen ( combined + totallen ) ;
}
else if ( glsl . len [ i ] & & * glsl . str [ i ] = = ' \n ' )
{ //last line didn't end with a newline, but there is one after. that's okay too, but we need to play it safe.
2018-09-23 19:35:24 +00:00
if ( glsl . file [ i ] )
Q_snprintfz ( combined + totallen , 64 + strlen ( glsl . file [ i ] ) , " \n #line %i %i //%s \n " , glsl . line [ i ] , i , glsl . file [ i ] ) ;
else
Q_snprintfz ( combined + totallen , 64 , " \n #line %i %i \n " , glsl . line [ i ] , i ) ;
2018-08-04 07:05:20 +00:00
totallen + = strlen ( combined + totallen ) ;
}
//now shove stuff there.
memcpy ( combined + totallen , glsl . str [ i ] , glsl . len [ i ] ) ;
totallen + = glsl . len [ i ] ;
combined [ totallen ] = 0 ;
}
qglShaderSourceARB ( shader , 1 , ( const GLcharARB * * ) & combined , NULL ) ;
free ( combined ) ;
}
else if ( gl_workaround_ati_shadersource . ival )
2011-12-26 15:19:13 +00:00
{
2011-12-27 08:35:19 +00:00
/*ATI Driver Bug: ATI drivers ignore the 'length' array.
this code does what the drivers fail to do .
this patch makes the submission more mainstream
if ati can feck it up so much on a system with no real system memory issues , I wouldn ' t be surprised if embedded systems also mess it up .
*/
2012-09-30 05:52:03 +00:00
GLcharARB * combined ;
2011-12-26 15:19:13 +00:00
int totallen = 1 ;
2018-08-04 07:05:20 +00:00
for ( i = 0 ; i < glsl . strings ; i + + )
totallen + = glsl . len [ i ] ;
2011-12-26 15:19:13 +00:00
combined = malloc ( totallen ) ;
totallen = 0 ;
combined [ totallen ] = 0 ;
2018-08-04 07:05:20 +00:00
for ( i = 0 ; i < glsl . strings ; i + + )
2011-12-26 15:19:13 +00:00
{
2018-08-04 07:05:20 +00:00
memcpy ( combined + totallen , glsl . str [ i ] , glsl . len [ i ] ) ;
totallen + = glsl . len [ i ] ;
2011-12-26 15:19:13 +00:00
combined [ totallen ] = 0 ;
}
2012-09-30 05:52:03 +00:00
qglShaderSourceARB ( shader , 1 , ( const GLcharARB * * ) & combined , NULL ) ;
2011-12-26 15:19:13 +00:00
free ( combined ) ;
}
else
2018-08-04 07:05:20 +00:00
qglShaderSourceARB ( shader , glsl . strings , glsl . str , glsl . len ) ;
2005-01-04 23:34:42 +00:00
qglCompileShaderARB ( shader ) ;
2014-05-10 13:42:13 +00:00
return shader ;
}
//called after CreateShader. Checks for success.
//Splitting creation allows for both vertex+fragment shaders to be processed simultaneously if the driver threads glCompileShaderARB.
2017-02-11 16:14:06 +00:00
static GLhandleARB GLSlang_FinishShader ( GLhandleARB shader , const char * name , GLenum shadertype , qboolean * silent )
2014-05-10 13:42:13 +00:00
{
GLint compiled ;
int loglen ;
if ( ! shader ) //if there's no shader, then there was nothing to finish...
return shader ;
2011-01-23 03:44:49 +00:00
qglGetShaderParameteriv_ ( shader , GL_OBJECT_COMPILE_STATUS_ARB , & compiled ) ;
2005-01-04 23:34:42 +00:00
if ( ! compiled )
{
2014-05-17 15:25:02 +00:00
char * typedesc ;
2017-02-11 16:14:06 +00:00
char str [ 65536 ] ;
2014-05-10 13:42:13 +00:00
2015-07-14 14:47:00 +00:00
* str = 0 ;
2011-01-23 03:44:49 +00:00
qglGetShaderInfoLog_ ( shader , sizeof ( str ) , NULL , str ) ;
2017-02-11 16:14:06 +00:00
if ( ! * silent )
2005-01-04 23:34:42 +00:00
{
2017-02-11 16:14:06 +00:00
* silent = true ;
2012-01-17 07:57:46 +00:00
switch ( shadertype )
{
case GL_FRAGMENT_SHADER_ARB :
2014-05-17 15:25:02 +00:00
typedesc = " Fragment " ;
2012-01-17 07:57:46 +00:00
break ;
case GL_VERTEX_SHADER_ARB :
2014-05-17 15:25:02 +00:00
typedesc = " Vertex " ;
2012-01-17 07:57:46 +00:00
break ;
2014-11-05 05:39:24 +00:00
case GL_TESS_CONTROL_SHADER_ARB :
typedesc = " Tesselation Control " ;
break ;
case GL_TESS_EVALUATION_SHADER_ARB :
typedesc = " Tesselation Evaluation " ;
break ;
2012-01-17 07:57:46 +00:00
default :
2014-05-17 15:25:02 +00:00
typedesc = " ??? " ;
2012-01-17 07:57:46 +00:00
break ;
}
2018-11-27 16:48:19 +00:00
Con_Printf ( " %s shader (%s) compilation error: \n " CON_ERROR " %s " CON_DEFAULT " ---------- \n " , typedesc , name , str ) ;
2014-05-17 15:25:02 +00:00
//if there's no fixed function then failure to compile the default2d shader should be considered fatal. this should help avoid black screens on android.
2015-10-27 15:20:15 +00:00
if ( gl_config_nofixedfunc & & ! strcmp ( name , " default2d " ) )
2014-05-17 15:25:02 +00:00
Sys_Error ( " %s shader (%s) compilation error: \n ---------- \n %s---------- \n " , typedesc , name , str ) ;
2018-11-27 16:48:19 +00:00
if ( developer . ival > 1 )
2017-10-31 22:52:58 +00:00
{ //could use echo console-link I guess (with embedded line numbers). shaders can get quite big though.
2018-12-28 00:04:36 +00:00
unsigned int rawline , line , filenum = 0 ;
char * eol , * start , * e ;
const char * filename = name ;
2014-05-10 13:42:13 +00:00
qglGetShaderSource ( shader , sizeof ( str ) , NULL , str ) ;
2015-04-21 20:43:01 +00:00
Con_Printf ( " Shader \" %s \" source: \n " , name ) ;
2018-12-28 00:04:36 +00:00
for ( start = str , line = 1 , rawline = 1 ; ; )
2015-03-03 00:14:43 +00:00
{
eol = strchr ( start , ' \n ' ) ;
if ( eol )
* eol = 0 ;
2018-12-29 07:43:02 +00:00
if ( filename )
Con_Printf ( " %s:%u:%u: %s \n " , filename , line , rawline , start ) ;
else
2018-12-28 00:04:36 +00:00
Con_Printf ( " %u:%u:%u: %s \n " , filenum , line , rawline , start ) ;
if ( ! strncmp ( start , " #line " , 6 ) )
{
line = strtoul ( start + 6 , & e , 0 ) ;
while ( * e = = ' ' )
e + + ;
if ( * e )
{
filenum = strtoul ( e , & e , 0 ) ;
while ( * e = = ' ' )
e + + ;
filename = NULL ;
if ( e [ 0 ] = = ' / ' & & e [ 1 ] = = ' / ' )
filename = e + 2 ;
}
}
else
line + + ;
2015-03-03 00:14:43 +00:00
if ( ! eol )
break ;
start = eol + 1 ;
2018-12-28 00:04:36 +00:00
rawline + + ;
2015-03-03 00:14:43 +00:00
}
2011-10-27 16:16:29 +00:00
}
}
2014-05-13 23:17:12 +00:00
qglDeleteShaderObject_ ( shader ) ;
2005-04-16 16:21:27 +00:00
return 0 ;
2005-01-04 23:34:42 +00:00
}
2009-11-17 00:15:44 +00:00
if ( developer . ival )
{
2011-01-23 03:44:49 +00:00
qglGetShaderParameteriv_ ( shader , GL_OBJECT_INFO_LOG_LENGTH_ARB , & loglen ) ;
2009-11-17 00:15:44 +00:00
if ( loglen )
{
2014-05-10 13:42:13 +00:00
char str [ 8192 ] ;
2011-01-23 03:44:49 +00:00
qglGetShaderInfoLog_ ( shader , sizeof ( str ) , NULL , str ) ;
2009-11-17 00:15:44 +00:00
if ( strstr ( str , " WARNING " ) )
{
2014-05-10 13:42:13 +00:00
Con_Printf ( " Shader \" %s \" log: \n %s " , name , str ) ;
qglGetShaderSource ( shader , sizeof ( str ) , NULL , str ) ;
Con_Printf ( " Shader \" %s \" source: \n %s " , name , str ) ;
2009-11-17 00:15:44 +00:00
}
}
}
2005-01-04 23:34:42 +00:00
return shader ;
}
2017-02-11 16:14:06 +00:00
GLhandleARB GLSlang_CreateProgramObject ( const char * name , GLhandleARB vert , GLhandleARB cont , GLhandleARB eval , GLhandleARB geom , GLhandleARB frag )
2005-01-04 23:34:42 +00:00
{
2014-05-10 13:42:13 +00:00
GLhandleARB program ;
2005-01-04 23:34:42 +00:00
program = qglCreateProgramObjectARB ( ) ;
2014-11-05 05:39:24 +00:00
if ( vert ) qglAttachObjectARB ( program , vert ) ;
2015-07-01 23:15:25 +00:00
if ( geom ) qglAttachObjectARB ( program , geom ) ;
2014-11-05 05:39:24 +00:00
if ( cont ) qglAttachObjectARB ( program , cont ) ;
if ( eval ) qglAttachObjectARB ( program , eval ) ;
if ( frag ) qglAttachObjectARB ( program , frag ) ;
2005-01-04 23:34:42 +00:00
2013-10-29 17:38:22 +00:00
qglBindAttribLocationARB ( program , VATTR_VERTEX1 , " v_position1 " ) ;
2012-04-24 07:59:11 +00:00
qglBindAttribLocationARB ( program , VATTR_COLOUR , " v_colour " ) ;
qglBindAttribLocationARB ( program , VATTR_TEXCOORD , " v_texcoord " ) ;
qglBindAttribLocationARB ( program , VATTR_LMCOORD , " v_lmcoord " ) ;
qglBindAttribLocationARB ( program , VATTR_NORMALS , " v_normal " ) ;
qglBindAttribLocationARB ( program , VATTR_SNORMALS , " v_svector " ) ;
qglBindAttribLocationARB ( program , VATTR_TNORMALS , " v_tvector " ) ;
qglBindAttribLocationARB ( program , VATTR_VERTEX2 , " v_position2 " ) ;
2005-01-04 23:34:42 +00:00
2015-07-09 18:02:49 +00:00
//the following MAY not be valid in gles2.
if ( gl_config . maxattribs > VATTR_BONENUMS )
qglBindAttribLocationARB ( program , VATTR_BONENUMS , " v_bone " ) ;
if ( gl_config . maxattribs > VATTR_BONEWEIGHTS )
qglBindAttribLocationARB ( program , VATTR_BONEWEIGHTS , " v_weight " ) ;
# if MAXRLIGHTMAPS > 1
if ( gl_config . maxattribs > VATTR_COLOUR2 )
qglBindAttribLocationARB ( program , VATTR_COLOUR2 , " v_colour2 " ) ;
if ( gl_config . maxattribs > VATTR_COLOUR3 )
qglBindAttribLocationARB ( program , VATTR_COLOUR3 , " v_colour3 " ) ;
if ( gl_config . maxattribs > VATTR_COLOUR4 )
qglBindAttribLocationARB ( program , VATTR_COLOUR4 , " v_colour4 " ) ;
# endif
# if MAXRLIGHTMAPS > 1
if ( gl_config . maxattribs > VATTR_LMCOORD2 )
qglBindAttribLocationARB ( program , VATTR_LMCOORD2 , " v_lmcoord2 " ) ;
if ( gl_config . maxattribs > VATTR_LMCOORD3 )
qglBindAttribLocationARB ( program , VATTR_LMCOORD3 , " v_lmcoord3 " ) ;
if ( gl_config . maxattribs > VATTR_LMCOORD4 )
qglBindAttribLocationARB ( program , VATTR_LMCOORD4 , " v_lmcoord4 " ) ;
# endif
2011-01-23 03:44:49 +00:00
qglLinkProgramARB ( program ) ;
2014-10-05 20:04:11 +00:00
return program ;
}
2014-11-05 05:39:24 +00:00
qboolean GLSlang_ValidateProgram ( union programhandle_u * h , const char * name , qboolean silent , vfsfile_t * blobfile )
2014-10-05 20:04:11 +00:00
{
char str [ 2048 ] ;
GLint linked ;
2009-11-04 21:16:50 +00:00
2014-11-05 05:39:24 +00:00
if ( ! h - > glsl . handle )
return false ;
qglGetProgramParameteriv_ ( h - > glsl . handle , GL_OBJECT_LINK_STATUS_ARB , & linked ) ;
2005-01-04 23:34:42 +00:00
if ( ! linked )
{
2012-01-17 07:57:46 +00:00
if ( ! silent )
{
2014-11-05 05:39:24 +00:00
qglGetProgramInfoLog_ ( h - > glsl . handle , sizeof ( str ) , NULL , str ) ;
2012-05-14 15:07:03 +00:00
Con_Printf ( " Program link error on glsl program %s: \n %s \n " , name , str ) ;
2012-01-17 07:57:46 +00:00
}
2011-01-23 03:44:49 +00:00
2014-11-05 05:39:24 +00:00
qglDeleteProgramObject_ ( h - > glsl . handle ) ;
h - > glsl . handle = 0 ;
2011-12-26 15:19:13 +00:00
2005-02-28 07:16:19 +00:00
return ( GLhandleARB ) 0 ;
2005-01-04 23:34:42 +00:00
}
2014-10-05 20:04:11 +00:00
2014-11-05 05:39:24 +00:00
if ( h - > glsl . handle & & blobfile & & qglGetProgramBinary )
2014-10-05 20:04:11 +00:00
{
GLuint ui ;
GLenum e ;
unsigned int len , fmt ;
void * blobdata ;
2014-11-05 05:39:24 +00:00
qglGetProgramParameteriv_ ( h - > glsl . handle , GL_PROGRAM_BINARY_LENGTH , & ui ) ;
2014-10-05 20:04:11 +00:00
len = ui ;
blobdata = BZ_Malloc ( len ) ;
2014-11-05 05:39:24 +00:00
qglGetProgramBinary ( h - > glsl . handle , len , NULL , & e , blobdata ) ;
2014-10-05 20:04:11 +00:00
fmt = e ;
VFS_WRITE ( blobfile , & fmt , sizeof ( fmt ) ) ;
VFS_WRITE ( blobfile , & len , sizeof ( len ) ) ;
VFS_WRITE ( blobfile , blobdata , len ) ;
2014-11-05 05:39:24 +00:00
VFS_WRITE ( blobfile , & h - > glsl . usetesselation , sizeof ( h - > glsl . usetesselation ) ) ;
2014-10-05 20:04:11 +00:00
BZ_Free ( blobdata ) ;
}
2014-11-05 05:39:24 +00:00
return true ;
2005-01-04 23:34:42 +00:00
}
2016-07-26 11:47:59 +00:00
union programhandle_u GLSlang_CreateProgram ( program_t * prog , const char * name , int ver , const char * * precompilerconstants , const char * vert , const char * cont , const char * eval , const char * geom , const char * frag , qboolean silent , vfsfile_t * blobfile )
2005-04-16 16:21:27 +00:00
{
2014-11-05 05:39:24 +00:00
union programhandle_u ret ;
2005-04-16 16:21:27 +00:00
GLhandleARB vs ;
2015-07-01 23:15:25 +00:00
GLhandleARB gs ;
2005-04-16 16:21:27 +00:00
GLhandleARB fs ;
2014-11-05 05:39:24 +00:00
GLhandleARB cs ;
GLhandleARB es ;
2014-08-15 02:20:41 +00:00
const char * nullconstants = NULL ;
2005-04-16 16:21:27 +00:00
2014-11-05 05:39:24 +00:00
memset ( & ret , 0 , sizeof ( ret ) ) ;
2005-04-16 16:21:27 +00:00
if ( ! gl_config . arb_shader_objects )
2014-11-05 05:39:24 +00:00
return ret ;
2018-12-29 07:43:02 +00:00
if ( ( cont | | eval ) & & ! gl_config . arb_tessellation_shader )
2014-12-09 14:39:54 +00:00
{
2015-07-01 23:15:25 +00:00
Con_Printf ( " GLSlang_CreateProgram: %s requires tesselation support, but your gl drivers do not appear to support this (gl4.0 feature) \n " , name ) ;
return ret ;
}
if ( geom & & ! gl_config . geometryshaders )
{
Con_Printf ( " GLSlang_CreateProgram: %s requires geometry shader support, but your gl drivers do not appear to support this (gl3.2 feature) \n " , name ) ;
2014-11-05 05:39:24 +00:00
return ret ;
2014-12-09 14:39:54 +00:00
}
2005-04-16 16:21:27 +00:00
2010-08-28 17:14:38 +00:00
if ( ! precompilerconstants )
2011-01-23 03:44:49 +00:00
precompilerconstants = & nullconstants ;
2010-08-28 17:14:38 +00:00
2016-07-26 11:47:59 +00:00
fs = GLSlang_CreateShader ( prog , name , ver , precompilerconstants , frag , GL_FRAGMENT_SHADER_ARB , silent ) ;
gs = GLSlang_CreateShader ( prog , name , ver , precompilerconstants , geom , GL_GEOMETRY_SHADER_ARB , silent ) ;
vs = GLSlang_CreateShader ( prog , name , ver , precompilerconstants , vert , GL_VERTEX_SHADER_ARB , silent ) ;
cs = GLSlang_CreateShader ( prog , name , ver , precompilerconstants , cont , GL_TESS_CONTROL_SHADER_ARB , silent ) ;
es = GLSlang_CreateShader ( prog , name , ver , precompilerconstants , eval , GL_TESS_EVALUATION_SHADER_ARB , silent ) ;
2014-05-10 13:42:13 +00:00
2017-02-11 16:14:06 +00:00
fs = GLSlang_FinishShader ( fs , name , GL_FRAGMENT_SHADER_ARB , & silent ) ;
gs = GLSlang_FinishShader ( gs , name , GL_GEOMETRY_SHADER_ARB , & silent ) ;
vs = GLSlang_FinishShader ( vs , name , GL_VERTEX_SHADER_ARB , & silent ) ;
cs = GLSlang_FinishShader ( cs , name , GL_TESS_CONTROL_SHADER_ARB , & silent ) ;
es = GLSlang_FinishShader ( es , name , GL_TESS_EVALUATION_SHADER_ARB , & silent ) ;
2011-01-23 03:44:49 +00:00
2005-04-16 16:21:27 +00:00
if ( ! vs | | ! fs )
2014-11-05 05:39:24 +00:00
ret . glsl . handle = 0 ;
2010-08-28 17:14:38 +00:00
else
2017-02-11 16:14:06 +00:00
ret . glsl . handle = GLSlang_CreateProgramObject ( name , vs , cs , es , gs , fs ) ;
2010-08-28 17:14:38 +00:00
//delete ignores 0s.
2014-11-05 05:39:24 +00:00
if ( vs ) qglDeleteShaderObject_ ( vs ) ;
2015-07-01 23:15:25 +00:00
if ( gs ) qglDeleteShaderObject_ ( gs ) ;
2014-11-05 05:39:24 +00:00
if ( fs ) qglDeleteShaderObject_ ( fs ) ;
if ( cs ) qglDeleteShaderObject_ ( cs ) ;
if ( es ) qglDeleteShaderObject_ ( es ) ;
2010-08-28 17:14:38 +00:00
2012-04-24 07:59:11 +00:00
checkglerror ( ) ;
2017-02-11 16:14:06 +00:00
ret . glsl . usetesselation = ( cont | | eval ) ;
2014-11-05 05:39:24 +00:00
if ( ret . glsl . handle & & blobfile & & qglGetProgramBinary )
2014-03-30 08:55:06 +00:00
{
GLuint ui ;
GLenum e ;
unsigned int len , fmt ;
void * blobdata ;
2014-11-05 05:39:24 +00:00
qglGetProgramParameteriv_ ( ret . glsl . handle , GL_PROGRAM_BINARY_LENGTH , & ui ) ;
2014-03-30 08:55:06 +00:00
len = ui ;
blobdata = BZ_Malloc ( len ) ;
2014-11-05 05:39:24 +00:00
qglGetProgramBinary ( ret . glsl . handle , len , NULL , & e , blobdata ) ;
2014-03-30 08:55:06 +00:00
fmt = e ;
VFS_WRITE ( blobfile , & fmt , sizeof ( fmt ) ) ;
VFS_WRITE ( blobfile , & len , sizeof ( len ) ) ;
VFS_WRITE ( blobfile , blobdata , len ) ;
2014-11-05 05:39:24 +00:00
VFS_WRITE ( blobfile , & ret . glsl . usetesselation , sizeof ( ret . glsl . usetesselation ) ) ;
2014-03-30 08:55:06 +00:00
BZ_Free ( blobdata ) ;
}
2014-11-05 05:39:24 +00:00
return ret ;
2005-04-16 16:21:27 +00:00
}
2018-11-27 16:48:19 +00:00
qboolean GLSlang_ValidateProgramPermu ( program_t * prog , struct programpermu_s * permu , qboolean noerrors , vfsfile_t * blobfile )
2014-10-05 20:04:11 +00:00
{
2018-11-27 16:48:19 +00:00
if ( ! permu )
return false ;
return GLSlang_ValidateProgram ( & permu - > h , prog - > name , noerrors , blobfile ) ;
2014-10-05 20:04:11 +00:00
}
2018-11-27 16:48:19 +00:00
qboolean GLSlang_CreateProgramPermu ( program_t * prog , struct programpermu_s * permu , int ver , const char * * precompilerconstants , const char * vert , const char * tcs , const char * tes , const char * geom , const char * frag , qboolean noerrors , vfsfile_t * blobfile )
2014-03-30 08:55:06 +00:00
{
2014-06-08 09:36:15 +00:00
if ( ! ver )
{
2017-01-29 13:10:53 +00:00
if ( gl_config . gles )
ver = 100 ;
else
ver = 110 ;
2014-06-08 09:36:15 +00:00
}
2018-11-27 16:48:19 +00:00
if ( ( permu - > permutation & PERMUTATION_SKELETAL ) & & gl_config . maxattribs < 10 )
2015-07-09 18:02:49 +00:00
return false ; //can happen in gles2
# if MAXRLIGHTMAPS > 1
2018-11-27 16:48:19 +00:00
if ( ( permu - > permutation & PERMUTATION_LIGHTSTYLES ) & & gl_config . maxattribs < 16 )
2015-07-09 18:02:49 +00:00
return false ; //can happen in gles2
# endif
2018-11-27 16:48:19 +00:00
permu - > h = GLSlang_CreateProgram ( prog , prog - > name , ver , precompilerconstants , vert , tcs , tes , geom , frag , noerrors , blobfile ) ;
if ( permu - > h . glsl . handle )
2014-03-30 08:55:06 +00:00
return true ;
return false ;
}
2005-01-04 23:34:42 +00:00
GLint GLSlang_GetUniformLocation ( int prog , char * name )
{
int i = qglGetUniformLocationARB ( prog , name ) ;
if ( i = = - 1 )
{
Con_Printf ( " Failed to get location of uniform '%s' \n " , name ) ;
}
return i ;
2004-08-22 22:29:09 +00:00
}
2018-11-27 16:48:19 +00:00
static qboolean GLSlang_LoadBlob ( program_t * prog , unsigned int permu , vfsfile_t * blobfile )
2014-03-30 08:55:06 +00:00
{
2018-11-27 16:48:19 +00:00
return false ;
/*
2014-03-30 08:55:06 +00:00
unsigned int fmt ;
unsigned int length ;
void * binary ;
GLint success ;
if ( ! qglProgramBinary )
return false ;
VFS_READ ( blobfile , & fmt , sizeof ( fmt ) ) ;
VFS_READ ( blobfile , & length , sizeof ( length ) ) ;
binary = BZ_Malloc ( length ) ;
VFS_READ ( blobfile , binary , length ) ;
2015-08-07 17:49:49 +00:00
VFS_READ ( blobfile , & prog - > permu [ permu ] . h . glsl . usetesselation , sizeof ( prog - > permu [ permu ] . h . glsl . usetesselation ) ) ;
2014-03-30 08:55:06 +00:00
2015-08-07 17:49:49 +00:00
prog - > permu [ permu ] . h . glsl . handle = qglCreateProgramObjectARB ( ) ;
qglProgramBinary ( prog - > permu [ permu ] . h . glsl . handle , fmt , binary , length ) ;
2014-03-30 08:55:06 +00:00
BZ_Free ( binary ) ;
2015-08-07 17:49:49 +00:00
qglGetProgramParameteriv_ ( prog - > permu [ permu ] . h . glsl . handle , GL_OBJECT_LINK_STATUS_ARB , & success ) ;
2014-03-30 08:55:06 +00:00
if ( ! success )
{
2015-08-07 17:49:49 +00:00
qglDeleteProgramObject_ ( prog - > permu [ permu ] . h . glsl . handle ) ;
memset ( & prog - > permu [ permu ] . h , 0 , sizeof ( prog - > permu [ permu ] . h ) ) ;
2014-03-30 08:55:06 +00:00
}
return ! ! success ;
2018-11-27 16:48:19 +00:00
*/
2014-03-30 08:55:06 +00:00
}
2016-07-12 00:40:13 +00:00
static void GLSlang_DeleteProg ( program_t * prog )
2014-03-30 08:55:06 +00:00
{
2016-07-12 00:40:13 +00:00
unsigned int permu ;
2018-11-27 16:48:19 +00:00
struct programpermu_s * pp ;
2018-11-28 05:41:39 +00:00
for ( permu = countof ( prog - > permu ) ; permu - - > 0 ; )
2014-03-30 08:55:06 +00:00
{
2018-11-27 16:48:19 +00:00
pp = prog - > permu [ permu ] ;
if ( pp )
2016-07-12 00:40:13 +00:00
{
2018-11-28 05:41:39 +00:00
prog - > permu [ permu ] = NULL ;
if ( pp = = prog - > permu [ 0 ] & & permu )
continue ; //entry 0 (only) can get copied to avoid constant recompile failures (0 is always precompiled)
2018-11-27 16:48:19 +00:00
qglDeleteProgramObject_ ( pp - > h . glsl . handle ) ;
pp - > h . glsl . handle = 0 ;
2015-08-10 18:28:23 +00:00
2018-11-27 16:48:19 +00:00
BZ_Free ( pp - > parm ) ;
pp - > parm = NULL ;
pp - > numparms = 0 ;
2018-11-28 05:41:39 +00:00
Z_Free ( pp ) ;
2016-07-12 00:40:13 +00:00
}
2014-03-30 08:55:06 +00:00
}
}
2018-11-27 16:48:19 +00:00
static void GLSlang_ProgAutoFields ( program_t * prog , struct programpermu_s * pp , cvar_t * * cvars , char * * cvarnames , int * cvartypes )
2014-03-30 08:55:06 +00:00
{
2018-11-27 16:48:19 +00:00
unsigned int i ;
2014-03-30 08:55:06 +00:00
int uniformloc ;
char tmpname [ 128 ] ;
2018-11-27 16:48:19 +00:00
int maxparms = 0 ;
2014-03-30 08:55:06 +00:00
//figure out visible attributes
2018-11-27 16:48:19 +00:00
GLSlang_UseProgram ( pp - > h . glsl . handle ) ;
for ( i = 0 ; shader_attr_names [ i ] . name ; i + + )
2014-03-30 08:55:06 +00:00
{
2018-11-27 16:48:19 +00:00
uniformloc = qglGetAttribLocationARB ( pp - > h . glsl . handle , shader_attr_names [ i ] . name ) ;
if ( uniformloc ! = - 1 )
2014-03-30 08:55:06 +00:00
{
2018-11-27 16:48:19 +00:00
if ( shader_attr_names [ i ] . ptype ! = uniformloc )
Con_Printf ( " Bad attribute: %s \n " , shader_attr_names [ i ] . name ) ;
else
pp - > attrmask | = 1u < < uniformloc ;
2014-03-30 08:55:06 +00:00
}
}
2018-11-27 16:48:19 +00:00
pp - > numparms = 0 ;
pp - > parm = NULL ;
2014-03-30 08:55:06 +00:00
2019-03-12 05:04:27 +00:00
pp - > factorsuniform = qglGetUniformLocationARB ( pp - > h . glsl . handle , " factors " ) ;
2018-11-27 16:48:19 +00:00
for ( i = 0 ; shader_unif_names [ i ] . name ; i + + )
{
uniformloc = qglGetUniformLocationARB ( pp - > h . glsl . handle , shader_unif_names [ i ] . name ) ;
if ( uniformloc > = 0 )
2015-08-07 17:49:49 +00:00
{
2018-11-27 16:48:19 +00:00
if ( pp - > numparms > = maxparms )
2014-03-30 08:55:06 +00:00
{
2018-11-27 16:48:19 +00:00
maxparms = pp - > numparms ? pp - > numparms * 2 : 8 ;
pp - > parm = BZ_Realloc ( pp - > parm , sizeof ( * pp - > parm ) * maxparms ) ;
2014-03-30 08:55:06 +00:00
}
2018-11-27 16:48:19 +00:00
pp - > parm [ pp - > numparms ] . type = shader_unif_names [ i ] . ptype ;
pp - > parm [ pp - > numparms ] . handle = uniformloc ;
pp - > parm [ pp - > numparms ] . pval = NULL ;
pp - > numparms + + ;
2014-03-30 08:55:06 +00:00
}
2018-11-27 16:48:19 +00:00
}
2015-08-07 17:49:49 +00:00
2018-11-27 16:48:19 +00:00
/*set cvar uniforms*/
/*FIXME: enumerate cvars automatically instead*/
for ( i = 0 ; cvarnames [ i ] ; i + + )
{
if ( ! cvars [ i ] )
continue ;
2015-08-07 17:49:49 +00:00
2018-11-27 16:48:19 +00:00
Q_snprintfz ( tmpname , sizeof ( tmpname ) , " cvar_%s " , cvarnames [ i ] ) ;
uniformloc = qglGetUniformLocationARB ( pp - > h . glsl . handle , tmpname ) ;
if ( uniformloc > = 0 )
{
if ( pp - > numparms > = maxparms )
2014-03-30 08:55:06 +00:00
{
2018-11-27 16:48:19 +00:00
maxparms = pp - > numparms ? pp - > numparms * 2 : 8 ;
pp - > parm = BZ_Realloc ( pp - > parm , sizeof ( * pp - > parm ) * maxparms ) ;
2014-03-30 08:55:06 +00:00
}
2018-11-27 16:48:19 +00:00
pp - > parm [ pp - > numparms ] . type = cvartypes [ i ] ;
pp - > parm [ pp - > numparms ] . pval = cvars [ i ] ;
pp - > parm [ pp - > numparms ] . handle = uniformloc ;
pp - > numparms + + ;
2014-03-30 08:55:06 +00:00
}
2018-11-27 16:48:19 +00:00
}
2015-03-03 00:14:43 +00:00
2018-11-27 16:48:19 +00:00
//now scan/set texture uniforms
if ( ! ( pp - > attrmask & ( 1u < < VATTR_VERTEX1 ) ) ) //a shader kinda has to use one of these...
pp - > attrmask | = ( 1u < < VATTR_LEG_VERTEX ) ;
for ( i = 0 ; i < prog - > numsamplers ; i + + )
{
Q_snprintfz ( tmpname , sizeof ( tmpname ) , " s_t%i " , i ) ;
uniformloc = qglGetUniformLocationARB ( pp - > h . glsl . handle , tmpname ) ;
if ( uniformloc ! = - 1 )
2014-03-30 08:55:06 +00:00
{
2018-11-27 16:48:19 +00:00
qglUniform1iARB ( uniformloc , i ) ;
// if (prog->numsamplers < i+1)
// prog->numsamplers = i+1;
2015-03-03 00:14:43 +00:00
}
2018-11-27 16:48:19 +00:00
}
if ( developer . ival )
2017-02-19 00:15:42 +00:00
for ( i = 0 ; sh_defaultsamplers [ i ] . name ; i + + )
2015-03-03 00:14:43 +00:00
{
//figure out which ones are needed.
2017-02-19 00:15:42 +00:00
if ( prog - > defaulttextures & sh_defaultsamplers [ i ] . defaulttexbits )
2015-03-03 00:14:43 +00:00
continue ; //don't spam
2017-02-19 00:15:42 +00:00
uniformloc = qglGetUniformLocationARB ( pp - > h . glsl . handle , sh_defaultsamplers [ i ] . name ) ;
2015-03-03 00:14:43 +00:00
if ( uniformloc ! = - 1 )
2018-11-27 16:48:19 +00:00
Con_Printf ( " glsl \" %s \" needs %s but doesn't declare so \n " , prog - > name , sh_defaultsamplers [ i ] . name ) ;
2015-03-03 00:14:43 +00:00
}
if ( prog - > defaulttextures )
{
2018-11-27 16:48:19 +00:00
unsigned int sampnum = prog - > numsamplers ;
2015-08-07 17:49:49 +00:00
/*set default texture uniforms now that we know the right sampler ids*/
2018-11-27 16:48:19 +00:00
for ( i = 0 ; sh_defaultsamplers [ i ] . name ; i + + )
2015-03-03 00:14:43 +00:00
{
2018-11-27 16:48:19 +00:00
if ( prog - > defaulttextures & sh_defaultsamplers [ i ] . defaulttexbits )
2015-03-03 00:14:43 +00:00
{
2018-11-27 16:48:19 +00:00
uniformloc = qglGetUniformLocationARB ( pp - > h . glsl . handle , sh_defaultsamplers [ i ] . name ) ;
if ( uniformloc ! = - 1 )
qglUniform1iARB ( uniformloc , sampnum ) ;
sampnum + + ;
2015-03-03 00:14:43 +00:00
}
2014-03-30 08:55:06 +00:00
}
}
}
2018-04-27 16:40:50 +00:00
void GL_ForgetPointers ( void )
{ //its at times like this that I wish I had put all of these into a struct.
//but GL_STATIC and webgl makes that sub-optimal. *sigh*
# ifndef GL_STATIC
qglBindTexture = NULL ;
qglBlendFunc = NULL ;
qglClear = NULL ;
qglClearColor = NULL ;
qglClearStencil = NULL ;
qglColorMask = NULL ;
qglCopyTexImage2D = NULL ;
qglCopyTexSubImage2D = NULL ;
qglCullFace = NULL ;
qglDepthFunc = NULL ;
qglDepthMask = NULL ;
// qglDepthRangef = NULL;
qglDisable = NULL ;
qglEnable = NULL ;
qglFinish = NULL ;
qglFlush = NULL ;
qglGenTextures = NULL ;
qglGetFloatv = NULL ;
qglGetIntegerv = NULL ;
qglGetString = NULL ;
qglHint = NULL ;
qglIsEnabled = NULL ;
qglReadPixels = NULL ;
qglTexImage2D = NULL ;
qglTexSubImage2D = NULL ;
qglTexParameteri = NULL ;
qglTexParameterf = NULL ;
qglTexParameteriv = NULL ;
qglTexParameterfv = NULL ;
qglViewport = NULL ;
qglGetBooleanv = NULL ;
qglGetError = NULL ;
qglDeleteTextures = NULL ;
qglDrawElements = NULL ;
qglDrawArrays = NULL ;
qglStencilOp = NULL ;
qglStencilFunc = NULL ;
qglScissor = NULL ;
qglPolygonOffset = NULL ;
# endif
# ifndef FTE_TARGET_WEB
qglAlphaFunc = NULL ;
qglBegin = NULL ;
qglClearDepth = NULL ;
qglClipPlane = NULL ;
// qglColor3f = NULL;
// qglColor3ub = NULL;
qglColor4f = NULL ;
qglColor4fv = NULL ;
// qglColor4ub = NULL;
// qglColor4ubv = NULL;
// qglDepthRange = NULL;
qglDrawBuffer = NULL ;
qglDrawPixels = NULL ;
qglEnd = NULL ;
qglFrustum = NULL ;
qglGetTexLevelParameteriv = NULL ;
qglLoadIdentity = NULL ;
qglLoadMatrixf = NULL ;
qglNormal3f = NULL ;
qglNormal3fv = NULL ;
qglMatrixMode = NULL ;
qglMultMatrixf = NULL ;
// qglOrtho = NULL;
qglPolygonMode = NULL ;
qglPopMatrix = NULL ;
qglPushMatrix = NULL ;
qglReadBuffer = NULL ;
qglRotatef = NULL ;
qglScalef = NULL ;
qglShadeModel = NULL ;
qglTexCoord1f = NULL ;
qglTexCoord2f = NULL ;
qglTexCoord2fv = NULL ;
qglTexEnvf = NULL ;
qglTexEnvfv = NULL ;
qglTexEnvi = NULL ;
qglTexGeni = NULL ;
qglTexGenfv = NULL ;
qglTexImage3D = NULL ;
qglTexSubImage3D = NULL ;
qglTranslatef = NULL ;
qglVertex2f = NULL ;
qglVertex3f = NULL ;
qglVertex3fv = NULL ;
# endif
//various vertex array stuff.
qglArrayElement = NULL ;
qglVertexPointer = NULL ;
qglNormalPointer = NULL ;
qglTexCoordPointer = NULL ;
qglColorPointer = NULL ;
qglEnableClientState = NULL ;
qglDisableClientState = NULL ;
qglDrawRangeElements = NULL ;
//fixme: definatly make non-core
qglPushAttrib = NULL ;
qglPopAttrib = NULL ;
//does this need to be non-core as well?
qglFogi = NULL ;
qglFogf = NULL ;
qglFogfv = NULL ;
qglGetTexEnviv = NULL ;
qglGetPointerv = NULL ;
qglGetStringi = NULL ;
//used by heightmaps
qglGenLists = NULL ;
qglNewList = NULL ;
qglEndList = NULL ;
qglCallList = NULL ;
# ifndef GL_STATIC
qglBindBufferARB = NULL ;
# endif
gl_vendor = NULL ;
gl_renderer = NULL ;
gl_version = NULL ;
gl_extensions = NULL ;
gl_num_extensions = 0 ;
# ifndef qglActiveTextureARB
qglActiveTextureARB = NULL ;
# endif
qglClientActiveTextureARB = NULL ;
qglSelectTextureSGIS = NULL ;
mtexid0 = 0 ;
# ifndef GL_STATIC
qglGenFramebuffersEXT = NULL ;
qglDeleteFramebuffersEXT = NULL ;
qglBindFramebufferEXT = NULL ;
qglGenRenderbuffersEXT = NULL ;
qglDeleteRenderbuffersEXT = NULL ;
qglBindRenderbufferEXT = NULL ;
qglRenderbufferStorageEXT = NULL ;
qglFramebufferTexture2DEXT = NULL ;
# endif
//no GL_EXT_stencil_two_side
qglActiveStencilFaceEXT = NULL ;
//no truform. sorry.
qglPNTrianglesfATI = NULL ;
qglPNTrianglesiATI = NULL ;
//fragment programs
// qglProgramStringARB = NULL;
// qglGetProgramivARB = NULL;
// qglBindProgramARB = NULL;
// qglGenProgramsARB = NULL;
# ifndef GL_STATIC
2019-04-15 18:43:42 +00:00
qglStencilOpSeparate = NULL ;
2018-04-27 16:40:50 +00:00
# endif
qglActiveStencilFaceEXT = NULL ;
# ifndef GL_STATIC
qglCompressedTexImage2D = NULL ;
qglCompressedTexImage3D = NULL ;
qglCompressedTexSubImage2D = NULL ;
qglCompressedTexSubImage3D = NULL ;
qglGetCompressedTexImage = NULL ;
# endif
qglDepthBoundsEXT = NULL ;
qglPNTrianglesfATI = NULL ;
qglPNTrianglesiATI = NULL ;
qglPatchParameteriARB = NULL ;
# ifndef GL_STATIC
qglBindTexture = NULL ;
# endif
qglLockArraysEXT = NULL ;
qglUnlockArraysEXT = NULL ;
qglBufferStorage = NULL ;
# if !defined(GL_STATIC)
qglGenBuffersARB = NULL ;
qglDeleteBuffersARB = NULL ;
qglBindBufferARB = NULL ;
qglBufferDataARB = NULL ;
qglBufferSubDataARB = NULL ;
qglMapBufferARB = NULL ;
qglUnmapBufferARB = NULL ;
qglMapBufferRange = NULL ;
qglCreateProgramObjectARB = NULL ;
qglDeleteProgramObject_ = NULL ;
qglDeleteShaderObject_ = NULL ;
qglUseProgramObjectARB = NULL ;
qglCreateShaderObjectARB = NULL ;
qglGetProgramParameteriv_ = NULL ;
qglGetShaderParameteriv_ = NULL ;
qglAttachObjectARB = NULL ;
qglGetProgramInfoLog_ = NULL ;
qglGetShaderInfoLog_ = NULL ;
qglShaderSourceARB = NULL ;
qglCompileShaderARB = NULL ;
qglLinkProgramARB = NULL ;
qglBindAttribLocationARB = NULL ;
qglGetAttribLocationARB = NULL ;
2018-11-27 16:48:19 +00:00
qglVertexAttrib4f = NULL ;
2018-04-27 16:40:50 +00:00
qglVertexAttribPointer = NULL ;
qglGetVertexAttribiv = NULL ;
qglGetVertexAttribPointerv = NULL ;
qglEnableVertexAttribArray = NULL ;
qglDisableVertexAttribArray = NULL ;
qglGetUniformLocationARB = NULL ;
qglUniformMatrix4fvARB = NULL ;
qglUniformMatrix3x4fv = NULL ;
qglUniformMatrix4x3fv = NULL ;
qglUniform4fARB = NULL ;
qglUniform4fvARB = NULL ;
qglUniform3fARB = NULL ;
qglUniform3fvARB = NULL ;
qglUniform2fvARB = NULL ;
qglUniform1iARB = NULL ;
qglUniform1fARB = NULL ;
qglGetShaderSource = NULL ;
# endif
qglGetProgramBinary = NULL ;
qglProgramBinary = NULL ;
qglGetGraphicsResetStatus = NULL ; //its not allowed to crash us. probably will. grr. oh well.
qglGenVertexArrays = NULL ;
qglBindVertexArray = NULL ;
qglTexStorage2D = NULL ;
qglTexStorage3D = NULL ;
# ifndef GL_STATIC
qglGenFramebuffersEXT = NULL ;
qglDeleteFramebuffersEXT = NULL ;
qglBindFramebufferEXT = NULL ;
qglGenRenderbuffersEXT = NULL ;
qglDeleteRenderbuffersEXT = NULL ;
qglBindRenderbufferEXT = NULL ;
qglRenderbufferStorageEXT = NULL ;
qglFramebufferTexture2DEXT = NULL ;
qglFramebufferRenderbufferEXT = NULL ;
qglCheckFramebufferStatusEXT = NULL ;
qglGetFramebufferAttachmentParameteriv = NULL ;
# endif
# ifdef DEBUG
qglDebugMessageControlARB = NULL ;
qglDebugMessageInsertARB = NULL ;
qglDebugMessageCallbackARB = NULL ;
qglGetDebugMessageLogARB = NULL ;
# endif
qglGenQueriesARB = NULL ;
qglDeleteQueriesARB = NULL ;
qglBeginQueryARB = NULL ;
qglEndQueryARB = NULL ;
qglGetQueryObjectuivARB = NULL ;
qglGenVertexArrays = NULL ;
qglBindVertexArray = NULL ;
qglDrawBuffers = NULL ;
qglLoadMatrixf = NULL ;
qglPolygonMode = NULL ;
qglShadeModel = NULL ;
qglDrawBuffer = NULL ;
memset ( & sh_config , 0 , sizeof ( sh_config ) ) ;
memset ( & gl_config , 0 , sizeof ( gl_config ) ) ;
}
2004-08-22 22:29:09 +00:00
//the vid routines have initialised a window, and now they are giving us a reference to some of of GetProcAddress to get pointers to the funcs.
2017-09-20 11:27:13 +00:00
qboolean GL_Init ( rendererstate_t * info , void * ( * getglfunction ) ( char * name ) )
2004-08-22 22:29:09 +00:00
{
2013-04-02 05:18:17 +00:00
# ifndef GL_STATIC
2014-11-05 05:39:24 +00:00
qglBindTexture = ( void * ) getglcore ( " glBindTexture " ) ; //for compleateness. core in 1.1. needed by fte.
2004-08-22 22:29:09 +00:00
qglBlendFunc = ( void * ) getglcore ( " glBlendFunc " ) ;
qglClear = ( void * ) getglcore ( " glClear " ) ;
qglClearColor = ( void * ) getglcore ( " glClearColor " ) ;
qglClearStencil = ( void * ) getglcore ( " glClearStencil " ) ;
qglColorMask = ( void * ) getglcore ( " glColorMask " ) ;
2005-01-12 22:15:50 +00:00
qglCopyTexImage2D = ( void * ) getglcore ( " glCopyTexImage2D " ) ;
2006-03-03 03:31:19 +00:00
qglCopyTexSubImage2D = ( void * ) getglcore ( " glCopyTexSubImage2D " ) ;
2004-08-22 22:29:09 +00:00
qglCullFace = ( void * ) getglcore ( " glCullFace " ) ;
qglDepthFunc = ( void * ) getglcore ( " glDepthFunc " ) ;
qglDepthMask = ( void * ) getglcore ( " glDepthMask " ) ;
2018-01-22 19:18:04 +00:00
// qglDepthRangef = (void *)getglcore("glDepthRangef");
2004-08-22 22:29:09 +00:00
qglDisable = ( void * ) getglcore ( " glDisable " ) ;
qglEnable = ( void * ) getglcore ( " glEnable " ) ;
qglFinish = ( void * ) getglcore ( " glFinish " ) ;
qglFlush = ( void * ) getglcore ( " glFlush " ) ;
2009-11-04 21:16:50 +00:00
qglGenTextures = ( void * ) getglcore ( " glGenTextures " ) ;
2019-06-17 04:21:41 +00:00
qglPixelStorei = ( void * ) getglcore ( " glPixelStorei " ) ;
2004-08-22 22:29:09 +00:00
qglGetFloatv = ( void * ) getglcore ( " glGetFloatv " ) ;
qglGetIntegerv = ( void * ) getglcore ( " glGetIntegerv " ) ;
qglGetString = ( void * ) getglcore ( " glGetString " ) ;
qglHint = ( void * ) getglcore ( " glHint " ) ;
2013-05-14 18:38:42 +00:00
qglIsEnabled = ( void * ) getglext ( " glIsEnabled " ) ;
2013-04-02 05:18:17 +00:00
qglReadPixels = ( void * ) getglcore ( " glReadPixels " ) ;
qglTexImage2D = ( void * ) getglcore ( " glTexImage2D " ) ;
qglTexSubImage2D = ( void * ) getglcore ( " glTexSubImage2D " ) ;
qglTexParameteri = ( void * ) getglcore ( " glTexParameteri " ) ;
qglTexParameterf = ( void * ) getglcore ( " glTexParameterf " ) ;
qglTexParameteriv = ( void * ) getglcore ( " glTexParameteriv " ) ;
qglTexParameterfv = ( void * ) getglcore ( " glTexParameterfv " ) ;
qglViewport = ( void * ) getglcore ( " glViewport " ) ;
qglGetBooleanv = ( void * ) getglcore ( " glGetBooleanv " ) ;
qglGetError = ( void * ) getglcore ( " glGetError " ) ;
qglDeleteTextures = ( void * ) getglcore ( " glDeleteTextures " ) ;
qglDrawElements = ( void * ) getglcore ( " glDrawElements " ) ;
qglDrawArrays = ( void * ) getglcore ( " glDrawArrays " ) ;
qglStencilOp = ( void * ) getglcore ( " glStencilOp " ) ;
qglStencilFunc = ( void * ) getglcore ( " glStencilFunc " ) ;
qglScissor = ( void * ) getglcore ( " glScissor " ) ;
qglPolygonOffset = ( void * ) getglext ( " glPolygonOffset " ) ;
2019-03-03 02:02:29 +00:00
qglLineWidth = ( void * ) getglcore ( " glLineWidth " ) ;
2013-04-02 05:18:17 +00:00
# endif
2019-04-15 18:43:42 +00:00
2013-04-04 08:08:49 +00:00
# ifndef FTE_TARGET_WEB
2013-04-02 05:18:17 +00:00
qglGetTexLevelParameteriv = ( void * ) getglcore ( " glGetTexLevelParameteriv " ) ;
2004-08-22 22:29:09 +00:00
qglReadBuffer = ( void * ) getglcore ( " glReadBuffer " ) ;
2011-12-23 03:12:29 +00:00
qglTexImage3D = ( void * ) getglext ( " glTexImage3D " ) ;
2018-03-04 14:41:16 +00:00
qglTexSubImage3D = ( void * ) getglext ( " glTexSubImage3D " ) ;
2013-04-04 08:08:49 +00:00
# endif
2004-09-13 03:20:04 +00:00
2019-04-15 18:43:42 +00:00
2004-09-13 03:20:04 +00:00
//various vertex array stuff.
2004-10-19 16:10:14 +00:00
qglArrayElement = ( void * ) getglcore ( " glArrayElement " ) ;
2004-08-22 22:29:09 +00:00
qglVertexPointer = ( void * ) getglcore ( " glVertexPointer " ) ;
qglNormalPointer = ( void * ) getglcore ( " glNormalPointer " ) ;
qglTexCoordPointer = ( void * ) getglcore ( " glTexCoordPointer " ) ;
qglColorPointer = ( void * ) getglcore ( " glColorPointer " ) ;
qglEnableClientState = ( void * ) getglcore ( " glEnableClientState " ) ;
qglDisableClientState = ( void * ) getglcore ( " glDisableClientState " ) ;
2019-01-13 16:51:50 +00:00
qglMultiDrawElements = ( void * ) getglext ( " glMultiDrawElements " ) ; //since gl2
2004-08-22 22:29:09 +00:00
2013-05-13 13:43:18 +00:00
qglGetTexEnviv = ( void * ) getglext ( " glGetTexEnviv " ) ;
qglGetPointerv = ( void * ) getglext ( " glGetPointerv " ) ;
2009-11-04 21:16:50 +00:00
qglGetStringi = ( void * ) getglext ( " glGetStringi " ) ;
2013-08-07 14:20:24 +00:00
# ifndef GL_STATIC
2011-02-06 20:56:39 +00:00
qglBindBufferARB = ( void * ) getglext ( " glBindBufferARB " ) ;
2009-07-11 18:23:07 +00:00
if ( ! qglBindBufferARB )
2011-02-06 20:56:39 +00:00
qglBindBufferARB = ( void * ) getglext ( " glBindBuffer " ) ;
2009-07-11 18:23:07 +00:00
if ( ! qglBindBufferARB )
qglBindBufferARB = GL_BindBufferARBStub ;
2013-08-07 14:20:24 +00:00
# endif
2009-07-11 18:23:07 +00:00
2014-02-07 08:38:40 +00:00
if ( ! qglGetString )
Sys_Error ( " qglGetString not set. Serious gl library initialisation error \n " ) ;
2005-01-07 03:16:44 +00:00
gl_vendor = qglGetString ( GL_VENDOR ) ;
2004-08-22 22:29:09 +00:00
Con_SafePrintf ( " GL_VENDOR: %s \n " , gl_vendor ) ;
2005-01-07 03:16:44 +00:00
gl_renderer = qglGetString ( GL_RENDERER ) ;
2004-08-22 22:29:09 +00:00
Con_SafePrintf ( " GL_RENDERER: %s \n " , gl_renderer ) ;
2005-01-07 03:16:44 +00:00
gl_version = qglGetString ( GL_VERSION ) ;
2004-08-22 22:29:09 +00:00
Con_SafePrintf ( " GL_VERSION: %s \n " , gl_version ) ;
2014-10-11 19:39:45 +00:00
memset ( & sh_config , 0 , sizeof ( sh_config ) ) ;
2012-04-24 07:59:11 +00:00
GL_CheckExtensions ( getglfunction ) ;
2011-01-23 03:44:49 +00:00
2019-09-04 08:32:22 +00:00
if ( gl_config . glversion > = 3.0 )
qglGenerateMipmap = ( void * ) getglext ( " glGenerateMipmap " ) ;
else
qglGenerateMipmap = NULL ;
2019-04-15 18:43:42 +00:00
# ifndef FTE_TARGET_WEB
if ( ! gl_config . gles )
{
qglAlphaFunc = ( void * ) getglcore ( " glAlphaFunc " ) ;
qglBegin = ( void * ) getglcore ( " glBegin " ) ;
qglClearDepth = ( void * ) getglcore ( " glClearDepth " ) ;
qglClipPlane = ( void * ) getglcore ( " glClipPlane " ) ;
// qglColor3f = (void *)getglcore("glColor3f");
// qglColor3ub = (void *)getglcore("glColor3ub");
qglColor4f = ( void * ) getglcore ( " glColor4f " ) ;
qglColor4fv = ( void * ) getglext ( " glColor4fv " ) ;
// qglColor4ub = (void *)getglcore("glColor4ub");
// qglColor4ubv = (void *)getglcore("glColor4ubv");
// qglDepthRange = (void *)getglcore("glDepthRange");
qglDrawBuffer = ( void * ) getglcore ( " glDrawBuffer " ) ;
qglDrawPixels = ( void * ) getglcore ( " glDrawPixels " ) ;
qglEnd = ( void * ) getglcore ( " glEnd " ) ;
qglFrustum = ( void * ) getglcore ( " glFrustum " ) ;
qglLoadIdentity = ( void * ) getglcore ( " glLoadIdentity " ) ;
qglLoadMatrixf = ( void * ) getglcore ( " glLoadMatrixf " ) ;
qglNormal3f = ( void * ) getglcore ( " glNormal3f " ) ;
qglNormal3fv = ( void * ) getglcore ( " glNormal3fv " ) ;
qglMatrixMode = ( void * ) getglcore ( " glMatrixMode " ) ;
qglMultMatrixf = ( void * ) getglcore ( " glMultMatrixf " ) ;
// qglOrtho = (void *)getglcore("glOrtho");
qglPolygonMode = ( void * ) getglcore ( " glPolygonMode " ) ;
qglPopMatrix = ( void * ) getglcore ( " glPopMatrix " ) ;
qglPushMatrix = ( void * ) getglcore ( " glPushMatrix " ) ;
qglRotatef = ( void * ) getglcore ( " glRotatef " ) ;
qglScalef = ( void * ) getglcore ( " glScalef " ) ;
qglShadeModel = ( void * ) getglcore ( " glShadeModel " ) ;
qglTexCoord1f = ( void * ) getglcore ( " glTexCoord1f " ) ;
qglTexCoord2f = ( void * ) getglcore ( " glTexCoord2f " ) ;
qglTexCoord2fv = ( void * ) getglcore ( " glTexCoord2fv " ) ;
qglTexEnvf = ( void * ) getglcore ( " glTexEnvf " ) ;
qglTexEnvfv = ( void * ) getglcore ( " glTexEnvfv " ) ;
qglTexEnvi = ( void * ) getglcore ( " glTexEnvi " ) ;
qglTexGeni = ( void * ) getglcore ( " glTexGeni " ) ;
qglTexGenfv = ( void * ) getglcore ( " glTexGenfv " ) ;
qglTranslatef = ( void * ) getglcore ( " glTranslatef " ) ;
qglVertex2f = ( void * ) getglcore ( " glVertex2f " ) ;
qglVertex3f = ( void * ) getglcore ( " glVertex3f " ) ;
qglVertex3fv = ( void * ) getglcore ( " glVertex3fv " ) ;
//fixme: definatly make non-core
qglPushAttrib = ( void * ) getglcore ( " glPushAttrib " ) ;
qglPopAttrib = ( void * ) getglcore ( " glPopAttrib " ) ;
//does this need to be non-core as well?
qglFogi = ( void * ) getglcore ( " glFogi " ) ;
qglFogf = ( void * ) getglcore ( " glFogf " ) ;
qglFogfv = ( void * ) getglcore ( " glFogfv " ) ;
//used by heightmaps
qglGenLists = ( void * ) getglcore ( " glGenLists " ) ;
qglNewList = ( void * ) getglcore ( " glNewList " ) ;
qglEndList = ( void * ) getglcore ( " glEndList " ) ;
qglCallList = ( void * ) getglcore ( " glCallList " ) ;
}
if ( ! qglColor4fv )
qglColor4fv = GL_Color4fv_Emul ; //can be missing in gles1
# endif
2014-08-27 08:41:31 +00:00
if ( ( gl_config . gles & & gl_config . glversion > = 3 ) | | ( ! gl_config . gles & & gl_config . glversion > = 2 ) )
qglDrawBuffers = ( void * ) getglext ( " glDrawBuffers " ) ;
else
qglDrawBuffers = NULL ;
2011-01-23 03:44:49 +00:00
if ( gl_config . gles & & gl_config . glversion > = 2 )
{
2014-08-27 08:41:31 +00:00
/*these functions do not exist in gles2, they only exist on some platforms because they were provided for gl1*/
2011-01-23 03:44:49 +00:00
qglLoadMatrixf = NULL ;
qglPolygonMode = NULL ;
qglShadeModel = NULL ;
2018-01-22 19:18:04 +00:00
// qglDepthRange = NULL;
2014-08-27 08:41:31 +00:00
qglDrawBuffer = NULL ;
2011-01-23 03:44:49 +00:00
2011-02-06 20:56:39 +00:00
qglEnableClientState = GL_ClientStateStub ;
qglDisableClientState = GL_ClientStateStub ;
2011-01-23 03:44:49 +00:00
qglDrawRangeElements = GL_DrawRangeElementsEmul ;
}
2015-10-27 15:20:15 +00:00
else if ( gl_config_nofixedfunc )
2011-05-20 04:10:46 +00:00
{
qglLoadMatrixf = NULL ;
qglPolygonMode = NULL ;
qglShadeModel = NULL ;
2018-01-22 19:18:04 +00:00
// qglDepthRange = NULL;
2014-08-27 08:41:31 +00:00
qglDrawBuffer = NULL ;
2011-05-20 04:10:46 +00:00
qglEnableClientState = GL_ClientStateStub ;
qglDisableClientState = GL_ClientStateStub ;
}
2004-08-22 22:29:09 +00:00
2014-02-21 12:21:12 +00:00
qglClearColor ( 0 , 0 , 0 , 1 ) ; //clear to black so that it looks a little nicer on start.
2005-01-07 03:16:44 +00:00
qglClear ( GL_COLOR_BUFFER_BIT ) ;
2004-08-22 22:29:09 +00:00
2011-01-23 03:44:49 +00:00
if ( qglPolygonMode )
qglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
if ( qglShadeModel )
qglShadeModel ( GL_FLAT ) ;
2004-08-22 22:29:09 +00:00
2010-07-28 21:55:10 +00:00
# ifdef DEBUG
2012-01-01 02:26:42 +00:00
if ( qglDebugMessageControlARB )
qglDebugMessageControlARB ( 0 , 0 , 0 , 0 , NULL , true ) ;
if ( qglDebugMessageCallbackARB )
2014-08-15 02:20:41 +00:00
{
2012-01-01 02:26:42 +00:00
qglDebugMessageCallbackARB ( myGLDEBUGPROCAMD , NULL ) ;
2014-08-15 02:20:41 +00:00
qglEnable ( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB ) ;
}
2011-01-04 02:56:16 +00:00
qglGetError ( ) ; /*suck up the invalid operation error for non-debug contexts*/
2010-07-28 21:55:10 +00:00
# endif
2014-03-30 08:55:06 +00:00
2017-12-28 16:24:50 +00:00
sh_config . texture2d_maxsize = 256 ; //early minidrivers might not implement this, but anything else should.
qglGetIntegerv ( GL_MAX_TEXTURE_SIZE , & sh_config . texture2d_maxsize ) ;
2014-03-30 08:55:06 +00:00
2017-12-28 16:24:50 +00:00
/*note regarding GL_COMPRESSED_TEXTURE_FORMATS:
nvidia lists bc1 - 3 , oes paletted , etc2 , astc , astc_srgb .
so the only listed formats that the hardware actually supports are bc1 - 3.
and bc4 - 7 are NOT listed , despite eg vulkan supporting them .
or in other words , this info is utterly useless ( its deprecated somewhere , so this shouldn ' t be a huge surprise ) .
*/
2017-10-13 17:50:28 +00:00
2014-03-30 08:55:06 +00:00
if ( gl_config . gles )
{
sh_config . minver = 100 ;
2017-11-05 13:15:08 +00:00
if ( gl_config . glversion > = 3.1 )
sh_config . maxver = 310 ;
else if ( gl_config . glversion > = 3.0 )
sh_config . maxver = 300 ;
else
sh_config . maxver = 100 ;
2014-03-30 08:55:06 +00:00
sh_config . blobpath = " gles/%s.blob " ;
sh_config . progpath = " glsl/%s.glsl " ;
sh_config . shadernamefmt = " %s_gles " ;
2016-07-21 19:27:59 +00:00
sh_config . can_mipcap = gl_config . glversion > = 3.0 ;
2019-02-19 06:49:03 +00:00
sh_config . can_mipbias = false ;
2017-08-29 02:29:06 +00:00
sh_config . havecubemaps = gl_config . glversion > = 2.0 ;
2014-03-30 08:55:06 +00:00
}
else
{
2016-07-21 19:27:59 +00:00
sh_config . can_mipcap = gl_config . glversion > = 1.2 ;
2019-02-19 06:49:03 +00:00
sh_config . can_mipbias = gl_config . glversion > = 1.4 ; //||GL_CheckExtension("GL_EXT_texture_lod_bias");
2016-07-21 19:27:59 +00:00
2019-02-19 06:49:03 +00:00
sh_config . havecubemaps = gl_config . glversion > = 1.3 | | GL_CheckExtension ( " GL_ARB_texture_cube_map " ) ; //cubemaps AND clamp-to-edge.
2017-08-29 02:29:06 +00:00
2017-11-14 14:37:04 +00:00
if ( gl_config . nofixedfunc )
{ //core contexts don't normally support glsl < 140 (such glsl versions have lots of compat syntax still, which will not function on core. drivers might accept it anyway, but yeah, lots of crap that shouldn't work)
//FIXME: GL_NUM_SHADING_LANGUAGE_VERSIONS and GL_SHADING_LANGUAGE_VERSION might allow for earlier versions.
sh_config . minver = 140 ;
sh_config . maxver = gl_config . maxglslversion ;
}
else if ( gl_config . arb_shader_objects )
{
//FIXME: we could accept 100 here, but that gets messy when gles is considered, and old drivers suck anyway.
sh_config . minver = 110 ;
sh_config . maxver = gl_config . maxglslversion ;
}
else
{
sh_config . minver = 0 ;
sh_config . maxver = 0 ;
}
2014-03-30 08:55:06 +00:00
sh_config . blobpath = " glsl/%s.blob " ;
sh_config . progpath = " glsl/%s.glsl " ;
sh_config . shadernamefmt = " %s_glsl " ;
2017-12-28 16:24:50 +00:00
}
sh_config . texturecube_maxsize = 0 ;
if ( sh_config . havecubemaps )
qglGetIntegerv ( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB , & sh_config . texturecube_maxsize ) ;
2018-12-29 07:43:02 +00:00
if ( ! gl_config_gles | | gl_config . glversion > = 3 )
qglGetIntegerv ( GL_MAX_3D_TEXTURE_SIZE , & sh_config . texture3d_maxsize ) ;
if ( gl_config . glversion > = 3 )
qglGetIntegerv ( GL_MAX_ARRAY_TEXTURE_LAYERS , & sh_config . texture2darray_maxlayers ) ;
2014-03-30 08:55:06 +00:00
sh_config . progs_supported = gl_config . arb_shader_objects ;
2014-08-25 07:35:41 +00:00
sh_config . progs_required = gl_config_nofixedfunc ;
2014-03-30 08:55:06 +00:00
2019-04-15 18:43:42 +00:00
if ( sh_config . progs_supported )
2014-10-05 20:04:11 +00:00
{
sh_config . pDeleteProg = GLSlang_DeleteProg ;
sh_config . pLoadBlob = qglProgramBinary ? GLSlang_LoadBlob : NULL ;
sh_config . pCreateProgram = GLSlang_CreateProgramPermu ;
sh_config . pValidateProgram = GLSlang_ValidateProgramPermu ;
sh_config . pProgAutoFields = GLSlang_ProgAutoFields ;
}
2014-03-30 08:55:06 +00:00
2015-10-27 15:20:15 +00:00
if ( gl_config_nofixedfunc )
2014-03-30 08:55:06 +00:00
{
sh_config . tex_env_combine = 1 ;
sh_config . nv_tex_env_combine4 = 1 ;
sh_config . env_add = 1 ;
}
else
{
sh_config . tex_env_combine = gl_config . tex_env_combine ;
sh_config . nv_tex_env_combine4 = gl_config . nv_tex_env_combine4 ;
sh_config . env_add = gl_config . env_add ;
}
2017-09-20 11:27:13 +00:00
2019-04-15 18:43:42 +00:00
// Con_Printf("sh_config.progs supported: %i, required: %i, vers: %i - %i\n", sh_config.progs_supported, sh_config.progs_required, sh_config.minver, sh_config.maxver);
2017-09-20 11:27:13 +00:00
return true ;
2009-11-04 21:16:50 +00:00
}
2009-06-21 17:45:33 +00:00
2004-08-22 22:29:09 +00:00
2013-05-13 13:43:18 +00:00
# ifdef DEBUG
# define GL_VERTEX_ARRAY_BINDING 0x85B5
# define GL_ARRAY_BUFFER 0x8892
# define GL_ELEMENT_ARRAY_BUFFER 0x8893
# define GL_ARRAY_BUFFER_BINDING 0x8894
# define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
# define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
# define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
# define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
# define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
# define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
# define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
# define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
# define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
# define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
# define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
# define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
# define GL_CURRENT_PROGRAM 0x8B8D
2013-07-14 12:22:51 +00:00
static char * DecodeGLEnum ( GLenum num )
2013-05-13 13:43:18 +00:00
{
switch ( num )
{
case GL_CW : return " GL_CW " ;
case GL_CCW : return " GL_CCW " ;
case GL_NEVER : return " GL_NEVER " ;
case GL_LESS : return " GL_LESS " ;
case GL_EQUAL : return " GL_EQUAL " ;
case GL_LEQUAL : return " GL_LEQUAL " ;
case GL_GREATER : return " GL_GREATER " ;
case GL_NOTEQUAL : return " GL_NOTEQUAL " ;
case GL_GEQUAL : return " GL_GEQUAL " ;
case GL_ALWAYS : return " GL_ALWAYS " ;
case GL_FRONT : return " GL_FRONT " ;
case GL_BACK : return " GL_BACK " ;
case GL_FRONT_AND_BACK : return " GL_FRONT_AND_BACK " ;
case GL_COMBINE_ARB : return " GL_COMBINE " ;
case GL_MODULATE : return " GL_MODULATE " ;
case GL_REPLACE : return " GL_REPLACE " ;
case GL_ZERO : return " GL_ZERO " ;
case GL_ONE : return " GL_ONE " ;
case GL_SRC_COLOR : return " GL_SRC_COLOR " ;
case GL_ONE_MINUS_SRC_COLOR : return " GL_ONE_MINUS_SRC_COLOR " ;
case GL_SRC_ALPHA : return " GL_SRC_ALPHA " ;
case GL_ONE_MINUS_SRC_ALPHA : return " GL_ONE_MINUS_SRC_ALPHA " ;
case GL_DST_ALPHA : return " GL_DST_ALPHA " ;
case GL_ONE_MINUS_DST_ALPHA : return " GL_ONE_MINUS_DST_ALPHA " ;
case GL_DST_COLOR : return " GL_DST_COLOR " ;
case GL_ONE_MINUS_DST_COLOR : return " GL_ONE_MINUS_DST_COLOR " ;
case GL_SRC_ALPHA_SATURATE : return " GL_SRC_ALPHA_SATURATE " ;
default : return va ( " 0x%x " , num ) ;
}
}
void DumpGLState ( void )
{
int rval ;
void * ptr ;
int i ;
GLint glint ;
GLint glint4 [ 4 ] ;
2014-03-30 00:39:37 +00:00
// if (qglGetVertexAttribiv)
2013-05-13 13:43:18 +00:00
{
2015-04-14 23:12:17 +00:00
if ( qglBindVertexArray )
{
qglGetIntegerv ( GL_VERTEX_ARRAY_BINDING , & rval ) ;
Sys_Printf ( " VERTEX_ARRAY_BINDING: %i \n " , rval ) ;
}
if ( qglBindBufferARB )
{
qglGetIntegerv ( GL_ARRAY_BUFFER_BINDING , & rval ) ;
Sys_Printf ( " GL_ARRAY_BUFFER_BINDING: %i \n " , rval ) ;
}
2013-05-13 13:43:18 +00:00
if ( qglIsEnabled ( GL_COLOR_ARRAY ) )
{
2015-04-14 23:12:17 +00:00
if ( qglBindBufferARB )
qglGetIntegerv ( GL_COLOR_ARRAY_BUFFER_BINDING , & rval ) ;
else
rval = 0 ;
2013-05-13 13:43:18 +00:00
qglGetPointerv ( GL_COLOR_ARRAY_POINTER , & ptr ) ;
Sys_Printf ( " GL_COLOR_ARRAY: %s %i:%p \n " , qglIsEnabled ( GL_COLOR_ARRAY ) ? " en " : " dis " , rval , ptr ) ;
}
// if (qglIsEnabled(GL_FOG_COORDINATE_ARRAY_EXT))
// {
// qglGetPointerv(GL_FOG_COORD_ARRAY_POINTER, &ptr);
// Sys_Printf("GL_FOG_COORDINATE_ARRAY_EXT: %i (%lx)\n", (int) qglIsEnabled(GL_FOG_COORDINATE_ARRAY_EXT), (int) ptr);
// }
{
2015-04-14 23:12:17 +00:00
if ( qglBindBufferARB )
qglGetIntegerv ( GL_ELEMENT_ARRAY_BUFFER_BINDING , & rval ) ;
else
rval = 0 ;
2013-07-27 23:13:40 +00:00
Sys_Printf ( " GL_ELEMENT_ARRAY_BUFFER_BINDING: %i:%p \n " , rval , ( void * ) 0 ) ;
2013-05-13 13:43:18 +00:00
}
if ( qglIsEnabled ( GL_NORMAL_ARRAY ) )
{
2015-04-14 23:12:17 +00:00
if ( qglBindBufferARB )
qglGetIntegerv ( GL_NORMAL_ARRAY_BUFFER_BINDING , & rval ) ;
else
rval = 0 ;
2013-05-13 13:43:18 +00:00
qglGetPointerv ( GL_NORMAL_ARRAY_POINTER , & ptr ) ;
Sys_Printf ( " GL_NORMAL_ARRAY: %s %i:%p \n " , qglIsEnabled ( GL_NORMAL_ARRAY ) ? " en " : " dis " , rval , ptr ) ;
}
// qglGetPointerv(GL_SECONDARY_COLOR_ARRAY_POINTER, &ptr);
// Sys_Printf("GL_SECONDARY_COLOR_ARRAY: %i (%lx)\n", (int) qglIsEnabled(GL_SECONDARY_COLOR_ARRAY), (int) ptr);
for ( i = 0 ; i < 4 ; i + + )
{
qglClientActiveTextureARB ( mtexid0 + i ) ;
if ( qglIsEnabled ( GL_TEXTURE_COORD_ARRAY ) )
{
2015-04-14 23:12:17 +00:00
if ( qglBindBufferARB )
qglGetIntegerv ( GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING , & rval ) ;
else
rval = 0 ;
2013-05-13 13:43:18 +00:00
qglGetPointerv ( GL_TEXTURE_COORD_ARRAY_POINTER , & ptr ) ;
Sys_Printf ( " GL_TEXTURE_COORD_ARRAY %i: %s %i:%p \n " , i , qglIsEnabled ( GL_TEXTURE_COORD_ARRAY ) ? " en " : " dis " , rval , ptr ) ;
}
}
if ( qglIsEnabled ( GL_VERTEX_ARRAY ) )
{
2015-04-14 23:12:17 +00:00
if ( qglBindBufferARB )
qglGetIntegerv ( GL_VERTEX_ARRAY_BUFFER_BINDING , & rval ) ;
else
rval = 0 ;
2013-05-13 13:43:18 +00:00
qglGetPointerv ( GL_VERTEX_ARRAY_POINTER , & ptr ) ;
Sys_Printf ( " GL_VERTEX_ARRAY: %s %i:%p \n " , qglIsEnabled ( GL_VERTEX_ARRAY ) ? " en " : " dis " , rval , ptr ) ;
}
2014-03-30 00:39:37 +00:00
if ( qglGetVertexAttribiv )
2013-05-13 13:43:18 +00:00
for ( i = 0 ; i < 16 ; i + + )
{
int en , bo , as , st , ty , no ;
qglGetVertexAttribiv ( i , GL_VERTEX_ATTRIB_ARRAY_ENABLED , & en ) ;
if ( ! en )
continue ;
2015-04-14 23:12:17 +00:00
if ( qglBindBufferARB )
qglGetVertexAttribiv ( i , GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING , & bo ) ;
else
bo = 0 ;
2013-05-13 13:43:18 +00:00
qglGetVertexAttribiv ( i , GL_VERTEX_ATTRIB_ARRAY_SIZE , & as ) ;
qglGetVertexAttribiv ( i , GL_VERTEX_ATTRIB_ARRAY_STRIDE , & st ) ;
qglGetVertexAttribiv ( i , GL_VERTEX_ATTRIB_ARRAY_TYPE , & ty ) ;
qglGetVertexAttribiv ( i , GL_VERTEX_ATTRIB_ARRAY_NORMALIZED , & no ) ;
qglGetVertexAttribPointerv ( i , GL_VERTEX_ATTRIB_ARRAY_POINTER , & ptr ) ;
2013-08-27 13:18:09 +00:00
Sys_Printf ( " attrib%i: %s sz:%i st:%i ty:%0x %s%i:%p \n " , i , en ? " en " : " dis " , as , st , ty , no ? " norm " : " " , bo , ptr ) ;
2013-05-13 13:43:18 +00:00
}
2015-04-14 23:12:17 +00:00
if ( qglUseProgramObjectARB )
{
qglGetIntegerv ( GL_CURRENT_PROGRAM , & glint ) ;
Sys_Printf ( " GL_CURRENT_PROGRAM: %i \n " , glint ) ;
}
2013-05-13 13:43:18 +00:00
qglGetIntegerv ( GL_BLEND , & glint ) ;
Sys_Printf ( " GL_BLEND: %i \n " , glint ) ;
qglGetIntegerv ( GL_BLEND_SRC , & glint ) ;
2013-06-23 03:59:48 +00:00
Sys_Printf ( " GL_BLEND_SRC: %s \n " , DecodeGLEnum ( glint ) ) ;
2013-05-13 13:43:18 +00:00
qglGetIntegerv ( GL_BLEND_DST , & glint ) ;
2013-06-23 03:59:48 +00:00
Sys_Printf ( " GL_BLEND_DST: %s \n " , DecodeGLEnum ( glint ) ) ;
2013-05-13 13:43:18 +00:00
qglGetIntegerv ( GL_DEPTH_WRITEMASK , & glint ) ;
Sys_Printf ( " GL_DEPTH_WRITEMASK: %i \n " , glint ) ;
qglGetIntegerv ( GL_DEPTH_TEST , & glint ) ;
Sys_Printf ( " GL_DEPTH_TEST: %i \n " , glint ) ;
qglGetIntegerv ( GL_DEPTH_FUNC , & glint ) ;
Sys_Printf ( " GL_DEPTH_FUNC: %s \n " , DecodeGLEnum ( glint ) ) ;
qglGetIntegerv ( GL_CULL_FACE , & glint ) ;
Sys_Printf ( " GL_CULL_FACE: %i \n " , glint ) ;
qglGetIntegerv ( GL_CULL_FACE_MODE , & glint ) ;
Sys_Printf ( " GL_CULL_FACE_MODE: %s \n " , DecodeGLEnum ( glint ) ) ;
qglGetIntegerv ( GL_FRONT_FACE , & glint ) ;
Sys_Printf ( " GL_FRONT_FACE: %s \n " , DecodeGLEnum ( glint ) ) ;
qglGetIntegerv ( GL_SCISSOR_TEST , & glint ) ;
Sys_Printf ( " GL_SCISSOR_TEST: %i \n " , glint ) ;
qglGetIntegerv ( GL_STENCIL_TEST , & glint ) ;
Sys_Printf ( " GL_STENCIL_TEST: %i \n " , glint ) ;
qglGetIntegerv ( GL_COLOR_WRITEMASK , glint4 ) ;
Sys_Printf ( " GL_COLOR_WRITEMASK: %i %i %i %i \n " , glint4 [ 0 ] , glint4 [ 1 ] , glint4 [ 2 ] , glint4 [ 3 ] ) ;
GL_SelectTexture ( 0 ) ;
qglGetIntegerv ( GL_TEXTURE_2D , & glint ) ;
2013-08-27 13:18:09 +00:00
Sys_Printf ( " 0: GL_TEXTURE_2D: %i \n " , glint ) ;
2013-05-13 13:43:18 +00:00
qglGetTexEnviv ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , & glint ) ;
2013-08-27 13:18:09 +00:00
Sys_Printf ( " 0: GL_TEXTURE_ENV_MODE: %s \n " , DecodeGLEnum ( glint ) ) ;
2013-05-13 13:43:18 +00:00
GL_SelectTexture ( 1 ) ;
qglGetIntegerv ( GL_TEXTURE_2D , & glint ) ;
2013-08-27 13:18:09 +00:00
Sys_Printf ( " 1: GL_TEXTURE_2D: %i \n " , glint ) ;
2013-05-13 13:43:18 +00:00
qglGetTexEnviv ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , & glint ) ;
2013-08-27 13:18:09 +00:00
Sys_Printf ( " 1: GL_TEXTURE_ENV_MODE: %s \n " , DecodeGLEnum ( glint ) ) ;
2013-05-13 13:43:18 +00:00
GL_SelectTexture ( 2 ) ;
qglGetIntegerv ( GL_TEXTURE_2D , & glint ) ;
2013-08-27 13:18:09 +00:00
Sys_Printf ( " 2: GL_TEXTURE_2D: %i \n " , glint ) ;
2013-05-13 13:43:18 +00:00
qglGetTexEnviv ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , & glint ) ;
2013-08-27 13:18:09 +00:00
Sys_Printf ( " 2: GL_TEXTURE_ENV_MODE: %s \n " , DecodeGLEnum ( glint ) ) ;
2013-05-13 13:43:18 +00:00
}
}
# endif
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
rendererinfo_t openglrendererinfo = {
2017-04-18 11:12:17 +00:00
//customise the text printed depending on the actual type of opengl that we're locking ourselves to
2016-07-12 00:40:13 +00:00
# ifdef FTE_TARGET_WEB
" WebGL " ,
2017-04-18 11:12:17 +00:00
# elif defined(GLESONLY)
# ifdef GLSLONLY
" OpenGLES2+ " ,
# else
" OpenGLES " ,
# endif
2016-07-12 00:40:13 +00:00
# else
2009-11-04 21:16:50 +00:00
" OpenGL " ,
2016-07-12 00:40:13 +00:00
# endif
2009-11-04 21:16:50 +00:00
{
2017-04-18 11:12:17 +00:00
//reorder these too, if only so that 'setrenderer' lists gles-only builds as using gles instead of gl
# if defined(GLESONLY)
" gles " ,
" opengles " ,
2009-11-04 21:16:50 +00:00
" gl " ,
" opengl " ,
2017-04-18 11:12:17 +00:00
# else
" gl " ,
" opengl " ,
" gles " ,
" opengles " ,
# endif
2009-11-04 21:16:50 +00:00
} ,
QR_OPENGL ,
GLDraw_Init ,
2011-10-27 16:16:29 +00:00
GLDraw_DeInit ,
2009-11-04 21:16:50 +00:00
2014-10-05 20:04:11 +00:00
GL_UpdateFiltering ,
GL_LoadTextureMips ,
2010-10-02 02:25:39 +00:00
GL_DestroyTexture ,
2009-11-04 21:16:50 +00:00
GLR_Init ,
GLR_DeInit ,
GLR_RenderView ,
GLVID_Init ,
GLVID_DeInit ,
2014-03-30 00:39:37 +00:00
GLVID_SwapBuffers ,
2013-05-11 14:02:55 +00:00
GLVID_ApplyGammaRamps ,
2014-09-02 02:44:43 +00:00
NULL ,
NULL ,
NULL ,
2009-11-04 21:16:50 +00:00
GLVID_SetCaption , //setcaption
2014-03-30 00:39:37 +00:00
GLVID_GetRGBInfo ,
2009-11-04 21:16:50 +00:00
GLSCR_UpdateScreen ,
2011-01-04 02:56:16 +00:00
GLBE_SelectMode ,
GLBE_DrawMesh_List ,
GLBE_DrawMesh_Single ,
GLBE_SubmitBatch ,
GLBE_GetTempBatch ,
GLBE_DrawWorld ,
GLBE_Init ,
GLBE_GenBrushModelVBO ,
GLBE_ClearVBO ,
GLBE_UploadAllLightmaps ,
GLBE_SelectEntity ,
2011-10-27 16:16:29 +00:00
GLBE_SelectDLight ,
2013-06-23 02:17:02 +00:00
GLBE_Scissor ,
2011-01-04 02:56:16 +00:00
GLBE_LightCullModel ,
2013-04-06 03:36:00 +00:00
GLBE_VBO_Begin ,
GLBE_VBO_Data ,
GLBE_VBO_Finish ,
GLBE_VBO_Destroy ,
2014-02-07 14:57:07 +00:00
GLBE_RenderToTextureUpdate2d ,
2009-11-04 21:16:50 +00:00
" "
} ;
2004-12-15 19:53:30 +00:00
# endif
2011-01-23 03:44:49 +00:00