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"
2004-08-22 22:29:09 +00:00
//standard 1.1 opengl calls
void ( APIENTRY * qglAlphaFunc ) ( GLenum func , GLclampf ref ) ;
void ( APIENTRY * qglBegin ) ( GLenum mode ) ;
void ( APIENTRY * qglBlendFunc ) ( GLenum sfactor , GLenum dfactor ) ;
2005-09-09 23:40:55 +00:00
void ( APIENTRY * qglCallList ) ( GLuint list ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglClear ) ( GLbitfield mask ) ;
void ( APIENTRY * qglClearColor ) ( GLclampf red , GLclampf green , GLclampf blue , GLclampf alpha ) ;
void ( APIENTRY * qglClearDepth ) ( GLclampd depth ) ;
void ( APIENTRY * qglClearStencil ) ( GLint s ) ;
2010-07-11 02:22:39 +00:00
void ( APIENTRY * qglClipPlane ) ( GLenum plane , const GLdouble * equation ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglColor3f ) ( GLfloat red , GLfloat green , GLfloat blue ) ;
void ( APIENTRY * qglColor3ub ) ( GLubyte red , GLubyte green , GLubyte blue ) ;
void ( APIENTRY * qglColor4f ) ( GLfloat red , GLfloat green , GLfloat blue , GLfloat alpha ) ;
void ( APIENTRY * qglColor4fv ) ( const GLfloat * v ) ;
void ( APIENTRY * qglColor4ub ) ( GLubyte red , GLubyte green , GLubyte blue , GLubyte alpha ) ;
void ( APIENTRY * qglColor4ubv ) ( const GLubyte * v ) ;
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 ) ;
void ( APIENTRY * qglDepthRange ) ( GLclampd zNear , GLclampd zFar ) ;
void ( APIENTRY * qglDisable ) ( GLenum cap ) ;
void ( APIENTRY * qglDrawBuffer ) ( GLenum mode ) ;
void ( APIENTRY * qglDrawPixels ) ( GLsizei width , GLsizei height , GLenum format , GLenum type , const GLvoid * pixels ) ;
void ( APIENTRY * qglEnable ) ( GLenum cap ) ;
void ( APIENTRY * qglEnd ) ( void ) ;
2005-09-09 23:40:55 +00:00
void ( APIENTRY * qglEndList ) ( void ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglFinish ) ( void ) ;
void ( APIENTRY * qglFlush ) ( void ) ;
void ( APIENTRY * qglFrustum ) ( GLdouble left , GLdouble right , GLdouble bottom , GLdouble top , GLdouble zNear , GLdouble zFar ) ;
2005-09-09 23:40:55 +00:00
GLuint ( APIENTRY * qglGenLists ) ( GLsizei range ) ;
2009-11-04 21:16:50 +00:00
void ( APIENTRY * qglGenTextures ) ( GLsizei n , GLuint * textures ) ;
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 ) ;
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 ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglOrtho ) ( GLdouble left , GLdouble right , GLdouble bottom , GLdouble top , GLdouble zNear , GLdouble zFar ) ;
void ( APIENTRY * qglPolygonMode ) ( GLenum face , GLenum mode ) ;
2004-12-11 16:45:38 +00:00
void ( APIENTRY * qglPolygonOffset ) ( GLfloat factor , GLfloat units ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglPopMatrix ) ( void ) ;
void ( APIENTRY * qglPushMatrix ) ( void ) ;
void ( APIENTRY * qglReadBuffer ) ( GLenum mode ) ;
void ( APIENTRY * qglReadPixels ) ( GLint x , GLint y , GLsizei width , GLsizei height , GLenum format , GLenum type , GLvoid * pixels ) ;
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 ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglTexImage2D ) ( GLenum target , GLint level , GLint internalformat , GLsizei width , GLsizei height , GLint border , GLenum format , GLenum type , const GLvoid * pixels ) ;
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 ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglTexParameteri ) ( GLenum target , GLenum pname , GLint param ) ;
void ( APIENTRY * qglTexParameterf ) ( GLenum target , GLenum pname , GLfloat param ) ;
2006-06-15 21:40:54 +00:00
void ( APIENTRY * qglTexParameteriv ) ( GLenum target , GLenum pname , const GLint * params ) ;
void ( APIENTRY * qglTexParameterfv ) ( GLenum target , GLenum pname , const GLfloat * params ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglTexSubImage2D ) ( GLenum target , GLint level , GLint xoffset , GLint yoffset , GLsizei width , GLsizei height , GLenum format , GLenum type , const GLvoid * pixels ) ;
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 * qglViewport ) ( GLint x , GLint y , GLsizei width , GLsizei height ) ;
void ( APIENTRY * qglGetTexLevelParameteriv ) ( GLenum target , GLint level , GLenum pname , GLint * params ) ;
2005-05-13 10:42:48 +00:00
void ( APIENTRY * qglDrawRangeElements ) ( GLenum , GLuint , GLuint , GLsizei , GLenum , const GLvoid * ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglDrawElements ) ( GLenum mode , GLsizei count , GLenum type , const GLvoid * indices ) ;
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 ) ;
2004-09-13 03:20:04 +00:00
void ( APIENTRY * qglDrawArrays ) ( GLenum mode , GLint first , GLsizei count ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglDisableClientState ) ( GLenum array ) ;
void ( APIENTRY * qglEnableClientState ) ( GLenum array ) ;
2004-10-26 14:55:41 +00:00
void ( APIENTRY * qglScissor ) ( GLint x , GLint y , GLsizei width , GLsizei height ) ;
2004-08-22 22:29:09 +00:00
void ( APIENTRY * qglStencilOp ) ( GLenum fail , GLenum zfail , GLenum zpass ) ;
void ( APIENTRY * qglStencilFunc ) ( GLenum func , GLint ref , GLuint mask ) ;
void ( APIENTRY * qglPushAttrib ) ( GLbitfield mask ) ;
void ( APIENTRY * qglPopAttrib ) ( 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 ) ;
2008-11-09 22:29:28 +00:00
void ( APIENTRY * qglDeleteTextures ) ( GLsizei n , const GLuint * textures ) ;
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 ) ;
2009-05-24 10:11:17 +00:00
2009-11-04 21:16:50 +00:00
const GLubyte * ( APIENTRY * qglGetStringi ) ( GLenum name , GLuint index ) ;
void ( APIENTRY * qglGenFramebuffersEXT ) ( GLsizei n , GLuint * ids ) ;
void ( APIENTRY * qglDeleteFramebuffersEXT ) ( GLsizei n , const GLuint * ids ) ;
void ( APIENTRY * qglBindFramebufferEXT ) ( GLenum target , GLuint id ) ;
void ( APIENTRY * qglGenRenderbuffersEXT ) ( GLsizei n , GLuint * ids ) ;
void ( APIENTRY * qglDeleteRenderbuffersEXT ) ( GLsizei n , const GLuint * ids ) ;
void ( APIENTRY * qglBindRenderbufferEXT ) ( GLenum target , GLuint id ) ;
void ( APIENTRY * qglRenderbufferStorageEXT ) ( GLenum target , GLenum internalFormat , GLsizei width , GLsizei height ) ;
void ( APIENTRY * qglFramebufferTexture2DEXT ) ( GLenum target , GLenum attachmentPoint , GLenum textureTarget , GLuint textureId , GLint level ) ;
2011-09-03 03:49:43 +00:00
void ( APIENTRY * qglFramebufferRenderbufferEXT ) ( GLenum target , GLenum attachmentPoint , GLenum textureTarget , GLuint textureId ) ;
GLenum ( APIENTRY * qglCheckFramebufferStatusEXT ) ( GLenum target ) ;
2009-11-04 21:16:50 +00:00
2005-04-19 21:09:29 +00:00
/*
2004-09-13 03:20:04 +00:00
PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB ;
PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB ;
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
2011-01-23 03:44:49 +00:00
/*glslang - arb_shader_objects
gl core uses different names / distinctions from the extension
*/
2007-09-22 19:28:27 +00:00
FTEPFNGLCREATEPROGRAMOBJECTARBPROC qglCreateProgramObjectARB ;
2011-01-23 03:44:49 +00:00
FTEPFNGLDELETEOBJECTARBPROC qglDeleteProgramObject_ ;
FTEPFNGLDELETEOBJECTARBPROC qglDeleteShaderObject_ ;
2007-09-22 19:28:27 +00:00
FTEPFNGLUSEPROGRAMOBJECTARBPROC qglUseProgramObjectARB ;
FTEPFNGLCREATESHADEROBJECTARBPROC qglCreateShaderObjectARB ;
FTEPFNGLSHADERSOURCEARBPROC qglShaderSourceARB ;
FTEPFNGLCOMPILESHADERARBPROC qglCompileShaderARB ;
2011-01-23 03:44:49 +00:00
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetShaderParameteriv_ ;
FTEPFNGLGETOBJECTPARAMETERIVARBPROC qglGetProgramParameteriv_ ;
2007-09-22 19:28:27 +00:00
FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB ;
2011-01-23 03:44:49 +00:00
FTEPFNGLGETINFOLOGARBPROC qglGetShaderInfoLog_ ;
FTEPFNGLGETINFOLOGARBPROC qglGetProgramInfoLog_ ;
2007-09-22 19:28:27 +00:00
FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB ;
2011-01-23 03:44:49 +00:00
FTEPFNGLBINDATTRIBLOCATIONARBPROC qglBindAttribLocationARB ;
FTEPFNGLGETATTRIBLOCATIONARBPROC qglGetAttribLocationARB ;
FTEPFNGLVERTEXATTRIBPOINTER qglVertexAttribPointer ;
2011-05-26 16:46:43 +00:00
FTEPFNGLGETVERTEXATTRIBIV qglGetVertexAttribiv ;
2011-01-23 03:44:49 +00:00
FTEPFNGLENABLEVERTEXATTRIBARRAY qglEnableVertexAttribArray ;
FTEPFNGLDISABLEVERTEXATTRIBARRAY qglDisableVertexAttribArray ;
2007-09-22 19:28:27 +00:00
FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB ;
2011-07-30 14:14:56 +00:00
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4fvARB ;
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix3x4fv ;
FTEPFNGLUNIFORMMATRIXPROC qglUniformMatrix4x3fv ;
2007-09-22 19:28:27 +00:00
FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB ;
FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB ;
FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB ;
FTEPFNGLUNIFORM3FVARBPROC qglUniform3fvARB ;
FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB ;
FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB ;
2004-08-22 22:29:09 +00:00
//extensions
//arb multitexture
qlpSelTexFUNC qglActiveTextureARB ;
qlpSelTexFUNC qglClientActiveTextureARB ;
qlpMTex3FUNC qglMultiTexCoord3fARB ;
qlpMTex2FUNC qglMultiTexCoord2fARB ;
//generic multitexture
lpMTexFUNC qglMTexCoord2fSGIS ;
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
//stencil shadowing
void ( APIENTRY * qglStencilOpSeparateATI ) ( GLenum face , GLenum fail , GLenum zfail , GLenum zpass ) ;
2007-09-22 19:28:27 +00:00
FTEPFNGLACTIVESTENCILFACEEXTPROC qglActiveStencilFaceEXT ;
2004-08-22 22:29:09 +00:00
//quick hack that made quake work on both 1 and 1.1 gl implementations.
BINDTEXFUNCPTR bindTexFunc ;
2011-10-27 16:16:29 +00:00
# define GLchar char
2010-07-28 21:55:10 +00:00
# if defined(_DEBUG) && !defined(DEBUG)
# define DEBUG
# endif
# if defined(DEBUG)
2012-01-01 02:26:42 +00:00
typedef void ( APIENTRY * GLDEBUGPROCARB ) ( GLenum source ,
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-01-01 02:26:42 +00:00
void ( APIENTRY * qglDebugMessageControlARB ) ( enum source ,
enum type ,
enum severity ,
2010-07-28 21:55:10 +00:00
GLsizei count ,
const GLuint * ids ,
GLboolean enabled ) ;
2012-01-01 02:26:42 +00:00
void ( APIENTRY * qglDebugMessageInsertARB ) ( enum source ,
enum type ,
2010-07-28 21:55:10 +00:00
GLuint id ,
2012-01-01 02:26:42 +00:00
enum severity ,
2010-07-28 21:55:10 +00:00
GLsizei length ,
const char * buf ) ;
2012-01-01 02:26:42 +00:00
void ( APIENTRY * qglDebugMessageCallbackARB ) ( GLDEBUGPROCARB 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 ) ;
# 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
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
# define OutputDebugString(s) puts(s)
# 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 :
OutputDebugString ( " 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 :
OutputDebugString ( " 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 :
OutputDebugString ( " Undefined: " ) ;
2010-07-28 21:55:10 +00:00
break ;
2012-01-01 02:26:42 +00:00
case GL_DEBUG_TYPE_PORTABILITY_ARB :
OutputDebugString ( " Portability: " ) ;
2010-07-28 21:55:10 +00:00
break ;
2012-01-01 02:26:42 +00:00
case GL_DEBUG_TYPE_PERFORMANCE_ARB :
OutputDebugString ( " 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 :
OutputDebugString ( " Other: " ) ;
2010-07-28 21:55:10 +00:00
break ;
}
OutputDebugString ( message ) ;
OutputDebugString ( " \n " ) ;
}
# 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
2004-09-26 03:34:26 +00:00
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 ;
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 )
return false ;
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 ) )
return true ;
}
if ( ! gl_extensions )
return false ;
2004-10-19 16:10:14 +00:00
2009-11-04 21:16:50 +00:00
//note that this is not actually correct...
return ! ! strstr ( gl_extensions , extname ) ;
}
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
}
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 )
{
}
2004-08-22 22:29:09 +00:00
# define getglcore getglfunction
# define getglext(name) getglfunction(name)
2011-01-23 03:44:49 +00:00
void GL_CheckExtensions ( void * ( * getglfunction ) ( char * name ) , float ver )
2004-08-22 22:29:09 +00:00
{
2004-10-19 16:10:14 +00:00
memset ( & gl_config , 0 , sizeof ( gl_config ) ) ;
2004-08-22 22:29:09 +00:00
2011-01-23 03:44:49 +00:00
gl_config . glversion = ver ;
if ( ! strncmp ( gl_version , " OpenGL ES " , 9 ) )
gl_config . gles = true ;
else
gl_config . gles = false ;
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
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
}
else if ( gl_config . glversion = = 3.1 )
2011-05-20 04:10:46 +00:00
gl_config . nofixedfunc = ! GL_CheckExtension ( " GL_ARB_compatibility " ) ;
else
gl_config . nofixedfunc = false ;
}
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 )
gl_config . maxglslversion = 100 ;
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 ;
qglActiveTextureARB = NULL ;
qglMultiTexCoord2fARB = NULL ;
qglMultiTexCoord3fARB = NULL ;
qglMTexCoord2fSGIS = NULL ;
qglSelectTextureSGIS = NULL ;
mtexid0 = 0 ;
//no GL_ATI_separate_stencil
qglStencilOpSeparateATI = NULL ;
//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
2009-11-04 21:16:50 +00:00
qglGenFramebuffersEXT = NULL ;
qglDeleteFramebuffersEXT = NULL ;
qglBindFramebufferEXT = NULL ;
qglGenRenderbuffersEXT = NULL ;
qglDeleteRenderbuffersEXT = NULL ;
qglBindRenderbufferEXT = NULL ;
qglRenderbufferStorageEXT = NULL ;
qglFramebufferTexture2DEXT = NULL ;
2004-10-19 16:10:14 +00:00
gl_config . arb_texture_non_power_of_two = false ;
gl_config . sgis_generate_mipmap = false ;
2004-10-10 06:32:29 +00:00
2004-11-23 01:23:45 +00:00
gl_config . tex_env_combine = false ;
gl_config . env_add = false ;
gl_config . nv_tex_env_combine4 = false ;
gl_config . arb_texture_env_combine = false ;
gl_config . arb_texture_env_dot3 = false ;
gl_config . arb_texture_cube_map = false ;
2005-01-04 23:34:42 +00:00
gl_config . arb_shader_objects = false ;
2010-07-11 02:22:39 +00:00
gl_config . ext_framebuffer_objects = false ;
2004-11-23 01:23:45 +00:00
2006-06-04 02:25:10 +00:00
gl_config . ext_texture_filter_anisotropic = 0 ;
2005-12-01 11:22:20 +00:00
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_EXT_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 ) ;
2005-12-01 11:22:20 +00:00
2011-01-29 19:53:38 +00:00
Con_DPrintf ( " Anisotropic filter extension found (%dx max). \n " , gl_config . ext_texture_filter_anisotropic ) ;
2005-12-01 11:22:20 +00:00
}
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_ARB_texture_non_power_of_two " ) )
2004-10-19 16:10:14 +00:00
gl_config . arb_texture_non_power_of_two = true ;
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
2011-01-23 03:44:49 +00:00
if ( gl_config . gles )
{
qglActiveTextureARB = ( void * ) getglext ( " glActiveTexture " ) ;
2011-09-05 01:48:23 +00:00
qglClientActiveTextureARB = ( void * ) getglext ( " glClientActiveTexture " ) ;
2011-01-23 03:44:49 +00:00
qglSelectTextureSGIS = qglActiveTextureARB ;
mtexid0 = GL_TEXTURE0_ARB ;
2012-01-16 06:22:06 +00:00
qglGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & gl_mtexarbable ) ;
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.
qglActiveTextureARB = ( void * ) getglext ( " glActiveTextureARB " ) ;
qglClientActiveTextureARB = ( void * ) getglext ( " glClientActiveTextureARB " ) ;
qglMultiTexCoord2fARB = ( void * ) getglext ( " glMultiTexCoord2fARB " ) ;
2005-09-09 23:40:55 +00:00
qglMultiTexCoord3fARB = ( void * ) getglext ( " glMultiTexCoord3fARB " ) ;
2004-08-22 22:29:09 +00:00
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 ;
qglMTexCoord2fSGIS = qglMultiTexCoord2fARB ;
qglSelectTextureSGIS = qglActiveTextureARB ;
mtexid0 = GL_TEXTURE0_ARB ;
2005-05-21 01:33:58 +00:00
if ( ! qglActiveTextureARB | | ! qglClientActiveTextureARB | | ! qglMultiTexCoord2fARB )
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
qglMultiTexCoord2fARB = NULL ;
qglMTexCoord2fSGIS = NULL ;
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
}
2004-08-22 22:29:09 +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 ;
}
2009-11-04 21:16:50 +00:00
if ( 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
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_ATI_separate_stencil " ) )
2004-08-22 22:29:09 +00:00
qglStencilOpSeparateATI = ( void * ) getglext ( " glStencilOpSeparateATI " ) ;
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*/
// 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
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_ARB_texture_compression " ) )
2004-08-22 22:29:09 +00:00
{
qglCompressedTexImage2DARB = ( void * ) getglext ( " glCompressedTexImage2DARB " ) ;
qglGetCompressedTexImageARB = ( void * ) getglext ( " glGetCompressedTexImageARB " ) ;
if ( ! qglCompressedTexImage2DARB | | ! qglGetCompressedTexImageARB )
{
qglCompressedTexImage2DARB = NULL ;
qglGetCompressedTexImageARB = NULL ;
}
else
2004-10-19 16:10:14 +00:00
gl_config . arb_texture_compression = true ;
2004-08-22 22:29:09 +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 ;
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 " ) ;
}
2009-11-04 21:16:50 +00:00
if ( GL_CheckExtension ( " GL_EXT_texture_object " ) )
2004-08-22 22:29:09 +00:00
{
bindTexFunc = ( void * ) getglext ( " glBindTextureEXT " ) ;
if ( ! bindTexFunc ) //grrr
bindTexFunc = ( void * ) getglext ( " glBindTexture " ) ;
}
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 " ) ;
}
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
2009-11-04 21:16:50 +00:00
gl_config . arb_texture_cube_map = GL_CheckExtension ( " GL_ARB_texture_cube_map " ) ;
2004-08-22 22:29:09 +00:00
2010-07-11 02:22:39 +00:00
/*vbos*/
2009-11-04 21:16:50 +00:00
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
}
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.
2011-12-05 15:23:40 +00:00
if ( strstr ( gl_renderer , " Mesa " ) & & Cvar_Get ( " gl_blacklist_mesa_glsl " , " 1 " , CVAR_RENDERERLATCH , " gl blacklists " ) - > ival & & ( gl_config . glversion < 3 | | gl_config . gles ) )
{
//(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)*/
gl_config . arb_shader_objects = true ;
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 " ) ;
qglVertexAttribPointer = ( void * ) getglext ( " glVertexAttribPointer " ) ;
qglGetVertexAttribiv = ( void * ) getglext ( " glGetVertexAttribiv " ) ;
qglEnableVertexAttribArray = ( void * ) getglext ( " glEnableVertexAttribArray " ) ;
qglDisableVertexAttribArray = ( void * ) getglext ( " glDisableVertexAttribArray " ) ;
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 " ) ;
qglUniform1iARB = ( void * ) getglext ( " glUniform1i " ) ;
qglUniform1fARB = ( void * ) getglext ( " glUniform1f " ) ;
Con_DPrintf ( " GLSL available \n " ) ;
}
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 " ) ;
qglVertexAttribPointer = ( void * ) getglext ( " glVertexAttribPointerARB " ) ;
2011-05-26 16:46:43 +00:00
qglGetVertexAttribiv = ( void * ) getglext ( " glGetVertexAttribivARB " ) ;
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 " ) ;
2005-01-04 23:34:42 +00:00
qglUniform1iARB = ( void * ) getglext ( " glUniform1iARB " ) ;
qglUniform1fARB = ( void * ) getglext ( " glUniform1fARB " ) ;
2011-01-29 19:53:38 +00:00
Con_DPrintf ( " GLSL available \n " ) ;
2005-01-04 23:34:42 +00:00
}
2009-11-04 21:16:50 +00:00
2010-07-11 02:22:39 +00:00
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 " ) ;
2009-11-04 21:16:50 +00:00
}
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
}
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
2005-01-04 23:34:42 +00:00
}
2011-10-27 16:16:29 +00:00
static const char * glsl_hdrs [ ] =
{
" sys/skeletal.h " ,
" attribute vec3 v_normal; \n "
" attribute vec3 v_svector; \n "
" attribute vec3 v_tvector; \n "
" #ifdef SKELETAL \n "
" attribute vec4 v_bone; "
" attribute vec4 v_weight; "
" uniform mat3x4 m_bones[ " STRINGIFY ( MAX_BONES ) " ]; \n "
" vec4 skeletaltransform() "
" { "
" mat3x4 wmat; \n "
" wmat = m_bones[int(v_bone.x)] * v_weight.x; \n "
" wmat += m_bones[int(v_bone.y)] * v_weight.y; \n "
" wmat += m_bones[int(v_bone.z)] * v_weight.z; \n "
" wmat += m_bones[int(v_bone.w)] * v_weight.w; \n "
" 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; \n "
" wmat = m_bones[int(v_bone.x)] * v_weight.x; "
" wmat += m_bones[int(v_bone.y)] * v_weight.y; "
" wmat += m_bones[int(v_bone.z)] * v_weight.z; "
" wmat += m_bones[int(v_bone.w)] * v_weight.w; "
" n = vec4(v_normal.xyz, 1.0) * wmat; "
" t = vec4(v_svector.xyz, 1.0) * wmat; "
" b = vec4(v_tvector.xyz, 1.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; \n "
" wmat = m_bones[int(v_bone.x)] * v_weight.x; "
" wmat += m_bones[int(v_bone.y)] * v_weight.y; "
" wmat += m_bones[int(v_bone.z)] * v_weight.z; "
" wmat += m_bones[int(v_bone.w)] * v_weight.w; "
" n = vec4(v_normal.xyz, 1.0) * wmat; "
" t = vec4(v_svector.xyz, 1.0) * wmat; "
" b = vec4(v_tvector.xyz, 1.0) * wmat; "
" w = vec4(v_position.xyz, 1.0) * wmat; "
" return m_modelviewprojection * vec4(w, 1.0); "
" } \n "
" vec4 skeletaltransform_n(out vec3 n) "
" { "
" mat3x4 wmat; \n "
" wmat = m_bones[int(v_bone.x)] * v_weight.x; "
" wmat += m_bones[int(v_bone.y)] * v_weight.y; "
" wmat += m_bones[int(v_bone.z)] * v_weight.z; "
" wmat += m_bones[int(v_bone.w)] * v_weight.w; "
" n = vec4(v_normal.xyz, 1.0) * wmat; "
" return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0); "
" } \n "
" #else \n "
" #define skeletaltransform() ftetransform() \n "
" 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 "
" 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 "
" uniform vec4 w_fog; \n "
" vec3 fog3(in vec3 regularcolour) "
" { "
" float z = gl_FragCoord.z / gl_FragCoord.w; \n "
" float fac = exp2(-( "
" w_fog.w * w_fog.w * "
" z * z * "
" 1.442695)); \n "
" fac = clamp(fac, 0.0, 1.0); \n "
" return mix(w_fog.rgb, regularcolour, fac); \n "
" } \n "
" vec3 fog3additive(in vec3 regularcolour) "
" { "
" float z = gl_FragCoord.z / gl_FragCoord.w; \n "
" float fac = exp2(-( "
" w_fog.w * w_fog.w * "
" z * z * "
" 1.442695)); \n "
" fac = clamp(fac, 0.0, 1.0); \n "
" 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) "
" { "
" float z = gl_FragCoord.z / gl_FragCoord.w; \n "
" float fac = exp2(-( "
" w_fog.w * w_fog.w * "
" z * z * "
" 1.442695)); \n "
" fac = clamp(fac, 0.0, 1.0); \n "
" return regularcolour * vec4(fac, fac, fac, 1.0); \n "
" } \n "
" vec4 fog4blend(in vec4 regularcolour) "
" { "
" float z = gl_FragCoord.z / gl_FragCoord.w; \n "
" float fac = exp2(-( "
" w_fog.w * w_fog.w * "
" z * z * "
" 1.442695)); \n "
" fac = clamp(fac, 0.0, 1.0); \n "
" 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 "
" #if defined(RELIEFMAPPING) \n "
" float i, f; \n "
" vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * vec2(1.0, -1.0), -1.0); \n "
" 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 "
" vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * vec2(1.0, -1.0); \n "
" vec2 tc = base; \n "
" tc += OffsetVector; \n "
" OffsetVector *= 0.333; \n "
" tc -= OffsetVector * texture2D(normtex, tc).w; \n "
" tc -= OffsetVector * texture2D(normtex, tc).w; \n "
" tc -= OffsetVector * texture2D(normtex, tc).w; \n "
" return tc; \n "
" #else \n "
" return base; \n "
" #endif \n "
" } \n "
,
2011-10-27 16:16:29 +00:00
NULL
} ;
qboolean GLSlang_GenerateIncludes ( int maxstrings , int * strings , const GLchar * prstrings [ ] , GLint length [ ] , const char * shadersource )
{
int i ;
char * incline , * inc ;
char incname [ 256 ] ;
while ( ( incline = strstr ( shadersource , " #include " ) ) )
{
if ( * strings = = maxstrings )
return false ;
/*emit up to the include*/
prstrings [ * strings ] = shadersource ;
length [ * strings ] = incline - shadersource ;
* strings + = 1 ;
incline + = 8 ;
incline = COM_ParseOut ( incline , incname , sizeof ( incname ) ) ;
for ( i = 0 ; glsl_hdrs [ i ] ; i + = 2 )
{
if ( ! strcmp ( incname , glsl_hdrs [ i ] ) )
{
if ( ! GLSlang_GenerateIncludes ( maxstrings , strings , prstrings , length , glsl_hdrs [ i + 1 ] ) )
return false ;
break ;
}
}
if ( ! glsl_hdrs [ i ] )
{
if ( FS_LoadFile ( incname , & inc ) > = 0 )
{
if ( ! GLSlang_GenerateIncludes ( maxstrings , strings , prstrings , length , inc ) )
{
FS_FreeFile ( inc ) ;
return false ;
}
FS_FreeFile ( inc ) ;
}
}
/*move the pointer past the include*/
shadersource = incline ;
}
if ( * shadersource )
{
if ( * strings = = maxstrings )
return false ;
/*dump the remaining shader string*/
prstrings [ * strings ] = shadersource ;
length [ * strings ] = strlen ( prstrings [ * strings ] ) ;
* strings + = 1 ;
}
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
2012-01-17 07:57:46 +00:00
GLhandleARB GLSlang_CreateShader ( char * name , int ver , char * * precompilerconstants , const char * shadersource , GLenum shadertype , qboolean silent )
2005-01-04 23:34:42 +00:00
{
GLhandleARB shader ;
GLint compiled ;
char str [ 1024 ] ;
2011-01-29 19:53:38 +00:00
int loglen , i ;
2011-10-27 16:16:29 +00:00
const GLchar * prstrings [ 64 + 16 ] ;
GLint length [ sizeof ( prstrings ) / sizeof ( prstrings [ 0 ] ) ] ;
2011-01-23 03:44:49 +00:00
int strings = 0 ;
2005-01-04 23:34:42 +00:00
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 ;
2011-10-27 16:16:29 +00:00
prstrings [ strings ] = va ( " #version %u \n " , ver ) ;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
}
2011-05-26 16:46:43 +00:00
2011-07-30 14:14:56 +00:00
while ( * precompilerconstants )
2011-10-27 16:16:29 +00:00
{
prstrings [ strings ] = * precompilerconstants + + ;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
}
prstrings [ strings ] = " #define ENGINE_ " DISTRIBUTION " \n " ;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
2011-07-30 14:14:56 +00:00
2009-07-05 18:45:53 +00:00
switch ( shadertype )
{
case GL_FRAGMENT_SHADER_ARB :
2011-10-27 16:16:29 +00:00
prstrings [ strings ] = " #define FRAGMENT_SHADER \n " ;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
2011-06-05 23:53:33 +00:00
if ( gl_config . gles )
{
2011-10-27 16:16:29 +00:00
prstrings [ strings ] = " precision mediump float; \n " ;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
2011-06-05 23:53:33 +00:00
}
2009-07-05 18:45:53 +00:00
break ;
case GL_VERTEX_SHADER_ARB :
2011-10-27 16:16:29 +00:00
prstrings [ strings ] = " #define VERTEX_SHADER \n " ;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
2011-06-05 23:53:33 +00:00
if ( gl_config . gles )
{
2011-10-27 16:16:29 +00:00
prstrings [ strings ] =
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 "
;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
2011-06-05 23:53:33 +00:00
}
if ( gl_config . nofixedfunc )
{
2011-10-27 16:16:29 +00:00
prstrings [ strings ] =
" attribute vec3 v_position; \n "
2011-09-03 03:49:43 +00:00
" #define ftetransform() (m_modelviewprojection * vec4(v_position, 1.0)) \n "
" uniform mat4 m_modelviewprojection; \n "
2011-10-27 16:16:29 +00:00
;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
2011-06-05 23:53:33 +00:00
}
else
{
2011-10-27 16:16:29 +00:00
prstrings [ strings ] =
" #define ftetransform ftransform \n "
" #define v_position gl_Vertex \n "
" uniform mat4 m_modelviewprojection; \n "
;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
2011-06-05 23:53:33 +00:00
}
2009-07-05 18:45:53 +00:00
break ;
default :
2011-10-27 16:16:29 +00:00
prstrings [ strings ] = " #define UNKNOWN_SHADER \n " ;
length [ strings ] = strlen ( prstrings [ strings ] ) ;
strings + + ;
2009-07-05 18:45:53 +00:00
break ;
}
2011-10-27 16:16:29 +00:00
GLSlang_GenerateIncludes ( sizeof ( prstrings ) / sizeof ( prstrings [ 0 ] ) , & strings , prstrings , length , shadersource ) ;
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
2011-12-27 08:35:19 +00:00
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 .
*/
2011-12-26 15:19:13 +00:00
char * combined ;
int totallen = 1 ;
for ( i = 0 ; i < strings ; i + + )
totallen + = length [ i ] ;
combined = malloc ( totallen ) ;
totallen = 0 ;
combined [ totallen ] = 0 ;
for ( i = 0 ; i < strings ; i + + )
{
memcpy ( combined + totallen , prstrings [ i ] , length [ i ] ) ;
totallen + = length [ i ] ;
combined [ totallen ] = 0 ;
}
qglShaderSourceARB ( shader , 1 , & combined , NULL ) ;
free ( combined ) ;
}
else
qglShaderSourceARB ( shader , strings , prstrings , length ) ;
2005-01-04 23:34:42 +00:00
qglCompileShaderARB ( 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 )
{
2011-01-23 03:44:49 +00:00
qglGetShaderInfoLog_ ( shader , sizeof ( str ) , NULL , str ) ;
qglDeleteShaderObject_ ( shader ) ;
2012-01-17 07:57:46 +00:00
if ( ! silent )
2005-01-04 23:34:42 +00:00
{
2012-01-17 07:57:46 +00:00
switch ( shadertype )
{
case GL_FRAGMENT_SHADER_ARB :
Con_Printf ( " Fragment shader (%s) compilation error: \n ---------- \n %s---------- \n " , name , str ) ;
break ;
case GL_VERTEX_SHADER_ARB :
Con_Printf ( " Vertex shader (%s) compilation error: \n ---------- \n %s---------- \n " , name , str ) ;
break ;
default :
Con_Printf ( " Shader_CreateShader: This shouldn't happen ever \n " ) ;
break ;
}
Con_DPrintf ( " Shader \" %s \" source: \n " , name ) ;
for ( i = 0 ; i < strings ; i + + )
2011-10-27 16:16:29 +00:00
{
2012-01-17 07:57:46 +00:00
int j ;
if ( length [ i ] < 0 )
Con_DPrintf ( " %s " , prstrings [ i ] ) ;
else
{
for ( j = 0 ; j < length [ i ] ; j + + )
Con_DPrintf ( " %c " , prstrings [ i ] [ j ] ) ;
}
2011-10-27 16:16:29 +00:00
}
2012-01-17 07:57:46 +00:00
Con_DPrintf ( " %s \n " , str ) ;
2011-10-27 16:16:29 +00:00
}
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 )
{
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 " ) )
{
2011-01-29 19:53:38 +00:00
Con_Printf ( " Shader source: \n " ) ;
for ( i = 0 ; i < strings ; i + + )
Con_Printf ( " %s " , prstrings [ i ] ) ;
2009-11-17 00:15:44 +00:00
Con_Printf ( " %s \n " , str ) ;
}
}
}
2005-01-04 23:34:42 +00:00
return shader ;
}
2012-01-17 07:57:46 +00:00
GLhandleARB GLSlang_CreateProgramObject ( GLhandleARB vert , GLhandleARB frag , qboolean silent )
2005-01-04 23:34:42 +00:00
{
GLhandleARB program ;
GLint linked ;
char str [ 1024 ] ;
program = qglCreateProgramObjectARB ( ) ;
qglAttachObjectARB ( program , vert ) ;
qglAttachObjectARB ( program , frag ) ;
2011-06-05 23:53:33 +00:00
qglBindAttribLocationARB ( program , gl_config . nofixedfunc ? 0 : 7 , " v_position " ) ;
2011-01-23 03:44:49 +00:00
qglBindAttribLocationARB ( program , 1 , " v_colour " ) ;
qglBindAttribLocationARB ( program , 2 , " v_texcoord " ) ;
qglBindAttribLocationARB ( program , 3 , " v_lmcoord " ) ;
qglBindAttribLocationARB ( program , 4 , " v_normal " ) ;
qglBindAttribLocationARB ( program , 5 , " v_snormal " ) ;
qglBindAttribLocationARB ( program , 6 , " v_tnormal " ) ;
2011-07-30 14:14:56 +00:00
qglBindAttribLocationARB ( program , 8 , " v_bone " ) ;
qglBindAttribLocationARB ( program , 9 , " v_weight " ) ;
2005-01-04 23:34:42 +00:00
2011-01-23 03:44:49 +00:00
qglLinkProgramARB ( program ) ;
2009-11-04 21:16:50 +00:00
2011-01-23 03:44:49 +00:00
qglGetProgramParameteriv_ ( program , 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 )
{
qglGetProgramInfoLog_ ( program , sizeof ( str ) , NULL , str ) ;
Con_Printf ( " Program link error: %s \n " , str ) ;
}
2011-01-23 03:44:49 +00:00
2011-12-26 15:19:13 +00:00
qglDeleteProgramObject_ ( program ) ;
2005-02-28 07:16:19 +00:00
return ( GLhandleARB ) 0 ;
2005-01-04 23:34:42 +00:00
}
return program ;
}
2012-01-17 07:57:46 +00:00
GLhandleARB GLSlang_CreateProgram ( char * name , int ver , char * * precompilerconstants , char * vert , char * frag , qboolean silent )
2005-04-16 16:21:27 +00:00
{
2010-08-28 17:14:38 +00:00
GLhandleARB handle ;
2005-04-16 16:21:27 +00:00
GLhandleARB vs ;
GLhandleARB fs ;
2011-01-23 03:44:49 +00:00
char * nullconstants = NULL ;
2005-04-16 16:21:27 +00:00
if ( ! gl_config . arb_shader_objects )
return 0 ;
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
2012-01-17 07:57:46 +00:00
vs = GLSlang_CreateShader ( name , ver , precompilerconstants , vert , GL_VERTEX_SHADER_ARB , silent ) ;
fs = GLSlang_CreateShader ( name , ver , precompilerconstants , frag , GL_FRAGMENT_SHADER_ARB , silent ) ;
2011-01-23 03:44:49 +00:00
2005-04-16 16:21:27 +00:00
if ( ! vs | | ! fs )
2010-08-28 17:14:38 +00:00
handle = 0 ;
else
2012-01-17 07:57:46 +00:00
handle = GLSlang_CreateProgramObject ( vs , fs , silent ) ;
2010-08-28 17:14:38 +00:00
//delete ignores 0s.
2011-01-23 03:44:49 +00:00
qglDeleteShaderObject_ ( vs ) ;
qglDeleteShaderObject_ ( fs ) ;
2010-08-28 17:14:38 +00:00
return handle ;
2005-04-16 16:21:27 +00:00
}
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
}
//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.
void GL_Init ( void * ( * getglfunction ) ( char * name ) )
{
2010-11-22 02:03:28 +00:00
unsigned int gl_major_version ;
unsigned int gl_minor_version ;
2004-08-22 22:29:09 +00:00
qglAlphaFunc = ( void * ) getglcore ( " glAlphaFunc " ) ;
qglBegin = ( void * ) getglcore ( " glBegin " ) ;
qglBlendFunc = ( void * ) getglcore ( " glBlendFunc " ) ;
bindTexFunc = ( void * ) getglcore ( " glBindTexture " ) ; //for compleateness
qglClear = ( void * ) getglcore ( " glClear " ) ;
qglClearColor = ( void * ) getglcore ( " glClearColor " ) ;
qglClearDepth = ( void * ) getglcore ( " glClearDepth " ) ;
qglClearStencil = ( void * ) getglcore ( " glClearStencil " ) ;
2010-07-11 02:22:39 +00:00
qglClipPlane = ( void * ) getglcore ( " glClipPlane " ) ;
2004-08-22 22:29:09 +00:00
qglColor3f = ( void * ) getglcore ( " glColor3f " ) ;
qglColor3ub = ( void * ) getglcore ( " glColor3ub " ) ;
qglColor4f = ( void * ) getglcore ( " glColor4f " ) ;
qglColor4fv = ( void * ) getglcore ( " glColor4fv " ) ;
qglColor4ub = ( void * ) getglcore ( " glColor4ub " ) ;
qglColor4ubv = ( void * ) getglcore ( " glColor4ubv " ) ;
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 " ) ;
qglDepthRange = ( void * ) getglcore ( " glDepthRange " ) ;
qglDisable = ( void * ) getglcore ( " glDisable " ) ;
qglDrawBuffer = ( void * ) getglcore ( " glDrawBuffer " ) ;
qglDrawPixels = ( void * ) getglcore ( " glDrawPixels " ) ;
qglEnable = ( void * ) getglcore ( " glEnable " ) ;
qglEnd = ( void * ) getglcore ( " glEnd " ) ;
qglFinish = ( void * ) getglcore ( " glFinish " ) ;
qglFlush = ( void * ) getglcore ( " glFlush " ) ;
qglFrustum = ( void * ) getglcore ( " glFrustum " ) ;
2009-11-04 21:16:50 +00:00
qglGenTextures = ( void * ) getglcore ( " glGenTextures " ) ;
2004-08-22 22:29:09 +00:00
qglGetFloatv = ( void * ) getglcore ( " glGetFloatv " ) ;
qglGetIntegerv = ( void * ) getglcore ( " glGetIntegerv " ) ;
qglGetString = ( void * ) getglcore ( " glGetString " ) ;
qglGetTexLevelParameteriv = ( void * ) getglcore ( " glGetTexLevelParameteriv " ) ;
qglHint = ( void * ) getglcore ( " glHint " ) ;
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 " ) ;
qglReadBuffer = ( void * ) getglcore ( " glReadBuffer " ) ;
qglReadPixels = ( void * ) getglcore ( " glReadPixels " ) ;
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 " ) ;
2004-09-13 03:20:04 +00:00
qglTexEnvfv = ( void * ) getglcore ( " glTexEnvfv " ) ;
2004-08-22 22:29:09 +00:00
qglTexEnvi = ( void * ) getglcore ( " glTexEnvi " ) ;
qglTexGeni = ( void * ) getglcore ( " glTexGeni " ) ;
2009-07-05 18:45:53 +00:00
qglTexGenfv = ( void * ) getglcore ( " glTexGenfv " ) ;
2004-08-22 22:29:09 +00:00
qglTexImage2D = ( void * ) getglcore ( " glTexImage2D " ) ;
2011-12-23 03:12:29 +00:00
qglTexImage3D = ( void * ) getglext ( " glTexImage3D " ) ;
2004-08-22 22:29:09 +00:00
qglTexParameteri = ( void * ) getglcore ( " glTexParameteri " ) ;
qglTexParameterf = ( void * ) getglcore ( " glTexParameterf " ) ;
2006-06-15 21:40:54 +00:00
qglTexParameteriv = ( void * ) getglcore ( " glTexParameteriv " ) ;
qglTexParameterfv = ( void * ) getglcore ( " glTexParameterfv " ) ;
2004-08-22 22:29:09 +00:00
qglTexSubImage2D = ( void * ) getglcore ( " glTexSubImage2D " ) ;
qglTranslatef = ( void * ) getglcore ( " glTranslatef " ) ;
qglVertex2f = ( void * ) getglcore ( " glVertex2f " ) ;
qglVertex3f = ( void * ) getglcore ( " glVertex3f " ) ;
qglVertex3fv = ( void * ) getglcore ( " glVertex3fv " ) ;
qglViewport = ( void * ) getglcore ( " glViewport " ) ;
2004-09-13 03:20:04 +00:00
qglGetError = ( void * ) getglcore ( " glGetError " ) ;
2008-11-09 22:29:28 +00:00
qglDeleteTextures = ( void * ) getglcore ( " glDeleteTextures " ) ;
2004-09-13 03:20:04 +00:00
//various vertex array stuff.
2004-08-22 22:29:09 +00:00
qglDrawElements = ( void * ) getglcore ( " glDrawElements " ) ;
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 " ) ;
2004-09-13 03:20:04 +00:00
qglDrawArrays = ( void * ) getglcore ( " glDrawArrays " ) ;
2004-08-22 22:29:09 +00:00
qglEnableClientState = ( void * ) getglcore ( " glEnableClientState " ) ;
qglDisableClientState = ( void * ) getglcore ( " glDisableClientState " ) ;
2005-05-13 10:42:48 +00:00
qglDrawRangeElements = ( void * ) getglext ( " glDrawRangeElements " ) ;
2005-05-21 01:33:58 +00:00
if ( qglDrawRangeElements = = 0 )
qglDrawRangeElements = GL_DrawRangeElementsEmul ;
2005-05-13 10:42:48 +00:00
2004-08-22 22:29:09 +00:00
//fixme: definatly make non-core
qglStencilOp = ( void * ) getglcore ( " glStencilOp " ) ;
qglStencilFunc = ( void * ) getglcore ( " glStencilFunc " ) ;
qglPushAttrib = ( void * ) getglcore ( " glPushAttrib " ) ;
qglPopAttrib = ( void * ) getglcore ( " glPopAttrib " ) ;
2004-10-26 14:55:41 +00:00
qglScissor = ( void * ) getglcore ( " glScissor " ) ;
2004-08-22 22:29:09 +00:00
2006-06-02 17:42:36 +00:00
//does this need to be non-core as well?
qglFogi = ( void * ) getglcore ( " glFogi " ) ;
qglFogf = ( void * ) getglcore ( " glFogf " ) ;
qglFogfv = ( void * ) getglcore ( " glFogfv " ) ;
2004-12-11 16:45:38 +00:00
qglPolygonOffset = ( void * ) getglext ( " glPolygonOffset " ) ;
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
qglGetStringi = ( void * ) getglext ( " glGetStringi " ) ;
2005-09-09 23:40:55 +00:00
//used by heightmaps
qglGenLists = ( void * ) getglcore ( " glGenLists " ) ;
qglNewList = ( void * ) getglcore ( " glNewList " ) ;
qglEndList = ( void * ) getglcore ( " glEndList " ) ;
qglCallList = ( void * ) getglcore ( " glCallList " ) ;
2004-08-22 22:29:09 +00:00
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 ;
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 ) ;
2009-11-04 21:16:50 +00:00
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 ( qglGetError ( ) )
{
2011-01-23 03:44:49 +00:00
/*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 ) ;
2010-11-22 02:03:28 +00:00
}
2011-01-30 12:30:15 +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*/
2009-11-04 21:16:50 +00:00
{
int i ;
2011-01-30 12:30:15 +00:00
qglGetIntegerv ( GL_NUM_EXTENSIONS , & gl_num_extensions ) ;
2009-11-04 21:16:50 +00:00
if ( developer . value )
{
2011-01-23 03:44:49 +00:00
Con_Printf ( " GL_EXTENSIONS: \n " ) ;
2009-11-04 21:16:50 +00:00
for ( i = 0 ; i < gl_num_extensions ; i + + )
2011-01-04 02:56:16 +00:00
{
2010-07-12 22:46:37 +00:00
Con_Printf ( " %s " , qglGetStringi ( GL_EXTENSIONS , i ) ) ;
2011-01-23 03:44:49 +00:00
Con_Printf ( " \n " ) ;
2011-01-04 02:56:16 +00:00
}
2011-01-23 03:44:49 +00:00
Con_Printf ( " end of list \n " ) ;
2009-11-04 21:16:50 +00:00
}
else
Con_Printf ( " 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 " ) ;
}
2011-01-23 03:44:49 +00:00
GL_CheckExtensions ( getglfunction , gl_major_version + ( gl_minor_version / 10.f ) ) ;
if ( gl_config . gles & & gl_config . glversion > = 2 )
{
/*no matricies in gles, so don't try!*/
qglLoadMatrixf = NULL ;
qglPolygonMode = NULL ;
qglShadeModel = NULL ;
qglDepthRange = NULL ;
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 ;
}
2011-05-20 04:10:46 +00:00
else if ( gl_config . nofixedfunc )
{
qglLoadMatrixf = NULL ;
qglPolygonMode = NULL ;
qglShadeModel = NULL ;
qglDepthRange = NULL ;
qglEnableClientState = GL_ClientStateStub ;
qglDisableClientState = GL_ClientStateStub ;
}
2004-08-22 22:29:09 +00:00
2005-01-07 03:16:44 +00:00
qglClearColor ( 0 , 0 , 0 , 0 ) ; //clear to black so that it looks a little nicer on start.
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
2009-11-04 21:16:50 +00:00
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_REPEAT ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_REPEAT ) ;
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 )
qglDebugMessageCallbackARB ( myGLDEBUGPROCAMD , NULL ) ;
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
2009-11-04 21:16:50 +00:00
}
2009-06-21 17:45:33 +00:00
2009-11-04 21:16:50 +00:00
unsigned int d_8to24rgbtable [ 256 ] ;
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
rendererinfo_t openglrendererinfo = {
" OpenGL " ,
{
" gl " ,
" opengl " ,
" hardware " ,
} ,
QR_OPENGL ,
GLDraw_Init ,
2011-10-27 16:16:29 +00:00
GLDraw_DeInit ,
2009-11-04 21:16:50 +00:00
2010-10-02 02:25:39 +00:00
GL_LoadTextureFmt ,
GL_LoadTexture8Pal24 ,
GL_LoadTexture8Pal32 ,
GL_LoadCompressed ,
GL_FindTexture ,
GL_AllocNewTexture ,
GL_UploadFmt ,
GL_DestroyTexture ,
2009-11-04 21:16:50 +00:00
GLR_Init ,
GLR_DeInit ,
GLR_RenderView ,
GLR_NewMap ,
GLR_PreNewMap ,
GLR_LightPoint ,
2009-11-07 13:29:15 +00:00
Surf_AddStain ,
Surf_LessenStains ,
2009-11-04 21:16:50 +00:00
RMod_Init ,
2011-02-02 00:41:01 +00:00
RMod_Shutdown ,
2009-11-04 21:16:50 +00:00
RMod_ClearAll ,
RMod_ForName ,
RMod_FindName ,
RMod_Extradata ,
RMod_TouchModel ,
RMod_NowLoadExternal ,
RMod_Think ,
Mod_GetTag ,
Mod_TagNumForName ,
Mod_SkinNumForName ,
Mod_FrameNumForName ,
Mod_FrameDuration ,
GLVID_Init ,
GLVID_DeInit ,
GLVID_SetPalette ,
GLVID_ShiftPalette ,
GLVID_GetRGBInfo ,
GLVID_SetCaption , //setcaption
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 ,
2011-01-04 02:56:16 +00:00
GLBE_LightCullModel ,
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