From 275317fefb550401aca885c4c9bdac8714880939 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 18 Jan 2016 04:46:01 -0800 Subject: [PATCH] OpenGL2: Direct state access, part 1: Texture binds --- Makefile | 1 + code/renderercommon/qgl.h | 17 +++ code/renderergl2/tr_backend.c | 161 +++++++--------------------- code/renderergl2/tr_dsa.c | 132 +++++++++++++++++++++++ code/renderergl2/tr_dsa.h | 46 ++++++++ code/renderergl2/tr_extensions.c | 52 +++++++++ code/renderergl2/tr_image.c | 128 +++++++++------------- code/renderergl2/tr_init.c | 17 ++- code/renderergl2/tr_local.h | 7 +- code/renderergl2/tr_main.c | 2 +- code/renderergl2/tr_shade.c | 16 +-- code/renderergl2/tr_shadows.c | 4 +- code/renderergl2/tr_sky.c | 2 +- code/renderergl2/tr_surface.c | 4 +- misc/msvc12/opengl2.vcxproj | 1 + misc/msvc12/opengl2.vcxproj.filters | 1 + 16 files changed, 356 insertions(+), 235 deletions(-) create mode 100644 code/renderergl2/tr_dsa.c create mode 100644 code/renderergl2/tr_dsa.h diff --git a/Makefile b/Makefile index 6515cb53..d65d9bf6 100644 --- a/Makefile +++ b/Makefile @@ -1644,6 +1644,7 @@ Q3R2OBJ = \ $(B)/renderergl2/tr_bsp.o \ $(B)/renderergl2/tr_cmds.o \ $(B)/renderergl2/tr_curve.o \ + $(B)/renderergl2/tr_dsa.o \ $(B)/renderergl2/tr_extramath.o \ $(B)/renderergl2/tr_extensions.o \ $(B)/renderergl2/tr_fbo.o \ diff --git a/code/renderercommon/qgl.h b/code/renderercommon/qgl.h index 7d94c25a..1b042e91 100644 --- a/code/renderercommon/qgl.h +++ b/code/renderercommon/qgl.h @@ -736,6 +736,23 @@ extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array); #define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5 #endif +// GL_EXT_direct_state_access +extern GLvoid(APIENTRY * qglBindMultiTexture)(GLenum texunit, GLenum target, GLuint texture); +extern GLvoid(APIENTRY * qglTextureParameterf)(GLuint texture, GLenum target, GLenum pname, GLfloat param); +extern GLvoid(APIENTRY * qglTextureParameteri)(GLuint texture, GLenum target, GLenum pname, GLint param); +extern GLvoid(APIENTRY * qglTextureImage2D)(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +extern GLvoid(APIENTRY * qglTextureSubImage2D)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +extern GLvoid(APIENTRY * qglCopyTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +extern GLvoid(APIENTRY * qglCompressedTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +extern GLvoid(APIENTRY * qglCompressedTextureSubImage2D)(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); +extern GLvoid(APIENTRY * qglGenerateTextureMipmap)(GLuint texture, GLenum target); + #if defined(WIN32) // WGL_ARB_create_context diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index 9b54d546..f3f5a6af 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ #include "tr_local.h" +#include "tr_dsa.h" backEndData_t *backEndData; backEndState_t backEnd; @@ -35,81 +36,28 @@ static float s_flipMatrix[16] = { }; -/* -** GL_Bind -*/ -void GL_Bind( image_t *image ) { - int texnum; - - if ( !image ) { - ri.Printf( PRINT_WARNING, "GL_Bind: NULL image\n" ); - texnum = tr.defaultImage->texnum; - } else { - texnum = image->texnum; - } - - if ( r_nobind->integer && tr.dlightImage ) { // performance evaluation option - texnum = tr.dlightImage->texnum; - } - - if ( glState.currenttextures[glState.currenttmu] != texnum ) { - if ( image ) { - image->frameUsed = tr.frameCount; - } - glState.currenttextures[glState.currenttmu] = texnum; - if (image && image->flags & IMGFLAG_CUBEMAP) - qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum ); - else - qglBindTexture( GL_TEXTURE_2D, texnum ); - } -} - -/* -** GL_SelectTexture -*/ -void GL_SelectTexture( int unit ) -{ - if ( glState.currenttmu == unit ) - { - return; - } - - if (!(unit >= 0 && unit <= 31)) - ri.Error( ERR_DROP, "GL_SelectTexture: unit = %i", unit ); - - if (!qglActiveTextureARB) - ri.Error( ERR_DROP, "GL_SelectTexture: multitexture disabled" ); - - qglActiveTextureARB( GL_TEXTURE0_ARB + unit ); - - glState.currenttmu = unit; -} - /* ** GL_BindToTMU */ void GL_BindToTMU( image_t *image, int tmu ) { - int texnum; - int oldtmu = glState.currenttmu; + GLuint texture = (tmu == TB_COLORMAP) ? tr.defaultImage->texnum : 0; + GLenum target = GL_TEXTURE_2D; - if (!image) - texnum = 0; - else - texnum = image->texnum; + if (image) + { + if (image->flags & IMGFLAG_CUBEMAP) + target = GL_TEXTURE_CUBE_MAP; - if ( glState.currenttextures[tmu] != texnum ) { - GL_SelectTexture( tmu ); - if (image) - image->frameUsed = tr.frameCount; - glState.currenttextures[tmu] = texnum; - - if (image && (image->flags & IMGFLAG_CUBEMAP)) - qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum ); - else - qglBindTexture( GL_TEXTURE_2D, texnum ); - GL_SelectTexture( oldtmu ); + image->frameUsed = tr.frameCount; + texture = image->texnum; } + else + { + ri.Printf(PRINT_WARNING, "GL_BindToTMU: NULL image\n"); + } + + GL_BindMultiTexture(GL_TEXTURE0_ARB + tmu, target, texture); } @@ -141,39 +89,6 @@ void GL_Cull( int cullType ) { glState.faceCulling = cullType; } -/* -** GL_TexEnv -*/ -void GL_TexEnv( int env ) -{ - if ( env == glState.texEnv[glState.currenttmu] ) - { - return; - } - - glState.texEnv[glState.currenttmu] = env; - - - switch ( env ) - { - case GL_MODULATE: - qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - break; - case GL_REPLACE: - qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); - break; - case GL_DECAL: - qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); - break; - case GL_ADD: - qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD ); - break; - default: - ri.Error( ERR_DROP, "GL_TexEnv: invalid env '%d' passed", env ); - break; - } -} - /* ** GL_State ** @@ -855,6 +770,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * } RE_UploadCinematic (w, h, cols, rows, data, client, dirty); + GL_BindToTMU(tr.scratchImage[client], TB_COLORMAP); if ( r_speeds->integer ) { end = ri.Milliseconds(); @@ -895,23 +811,30 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * } void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) { + GLuint texture; - GL_Bind( tr.scratchImage[client] ); + if (!tr.scratchImage[client]) + { + ri.Printf(PRINT_WARNING, "RE_UploadCinematic: scratch images not initialized\n"); + return; + } + + texture = tr.scratchImage[client]->texnum; // if the scratchImage isn't in the format we want, specify it as a new texture if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) { tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols; tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows; - qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + qglTextureImage2D(texture, GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } else { if (dirty) { // otherwise, just subimage upload it so that drivers can tell we are going to be changing // it and don't try and do a texture compression - qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data ); + qglTextureSubImage2D(texture, GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data); } } } @@ -1071,11 +994,10 @@ const void *RB_DrawSurfs( const void *data ) { // If we're using multisampling, resolve the depth first FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_DEPTH_BUFFER_BIT, GL_NEAREST); } - else if (tr.renderFbo == NULL) + else if (tr.renderFbo == NULL && tr.renderDepthImage) { // If we're rendering directly to the screen, copy the depth to a texture - GL_BindToTMU(tr.renderDepthImage, 0); - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0); + qglCopyTextureImage2D(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0); } if (r_ssao->integer) @@ -1315,10 +1237,8 @@ const void *RB_DrawSurfs( const void *data ) { cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]; FBO_Bind(NULL); - GL_SelectTexture(TB_CUBEMAP); - GL_BindToTMU(cubemap->image, TB_CUBEMAP); - qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); - GL_SelectTexture(0); + if (cubemap && cubemap->image) + qglGenerateTextureMipmap(cubemap->image->texnum, GL_TEXTURE_CUBE_MAP); } return (const void *)(cmd + 1); @@ -1395,7 +1315,7 @@ void RB_ShowImages( void ) { { vec4_t quadVerts[4]; - GL_Bind(image); + GL_BindToTMU(image, TB_COLORMAP); VectorSet4(quadVerts[0], x, y, 0, 1); VectorSet4(quadVerts[1], x + w, y, 0, 1); @@ -1571,21 +1491,18 @@ const void *RB_CapShadowMap(const void *data) if (cmd->map != -1) { - GL_SelectTexture(0); if (cmd->cubeSide != -1) { if (tr.shadowCubemaps[cmd->map]) { - GL_Bind(tr.shadowCubemaps[cmd->map]); - qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); + qglCopyTextureImage2D(tr.shadowCubemaps[cmd->map]->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); } } else { if (tr.pshadowMaps[cmd->map]) { - GL_Bind(tr.pshadowMaps[cmd->map]); - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); + qglCopyTextureImage2D(tr.pshadowMaps[cmd->map]->texnum, GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - (backEnd.refdef.y + PSHADOW_MAP_SIZE), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0); } } } @@ -1658,7 +1575,7 @@ const void *RB_PostProcess(const void *data) if (srcFbo) { - if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer) && qglActiveTextureARB) + if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer)) { autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer; RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure); @@ -1774,7 +1691,7 @@ const void *RB_ExportCubemaps(const void *data) { char filename[MAX_QPATH]; cubemap_t *cubemap = &tr.cubemaps[i]; - char *p = cubemapPixels; + byte *p = cubemapPixels; for (j = 0; j < 6; j++) { diff --git a/code/renderergl2/tr_dsa.c b/code/renderergl2/tr_dsa.c new file mode 100644 index 00000000..55a731d9 --- /dev/null +++ b/code/renderergl2/tr_dsa.c @@ -0,0 +1,132 @@ +/* +=========================================================================== +Copyright (C) 2016 James Canete + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +=========================================================================== +*/ + +#include "tr_local.h" + +#include "tr_dsa.h" + +static struct +{ + GLuint textures[NUM_TEXTURE_BUNDLES]; + GLenum texunit; +} +glDsaState; + +void GL_BindNullTextures() +{ + int i; + + if (glRefConfig.directStateAccess) + { + for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) + { + qglBindMultiTexture(GL_TEXTURE0_ARB + i, GL_TEXTURE_2D, 0); + glDsaState.textures[i] = 0; + } + } + else + { + for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) + { + qglActiveTextureARB(GL_TEXTURE0_ARB + i); + qglBindTexture(GL_TEXTURE_2D, 0); + glDsaState.textures[i] = 0; + } + + qglActiveTextureARB(GL_TEXTURE0_ARB); + glDsaState.texunit = GL_TEXTURE0_ARB; + } +} + +void GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) +{ + GLuint tmu = texunit - GL_TEXTURE0_ARB; + + if (glDsaState.textures[tmu] == texture) + return; + + qglBindMultiTexture(texunit, target, texture); + glDsaState.textures[tmu] = texture; +} + +GLvoid APIENTRY GLDSA_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) +{ + if (glDsaState.texunit != texunit) + { + qglActiveTextureARB(texunit); + glDsaState.texunit = texunit; + } + + qglBindTexture(target, texture); +} + +GLvoid APIENTRY GLDSA_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexParameterf(target, pname, param); +} + +GLvoid APIENTRY GLDSA_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexParameteri(target, pname, param); +} + +GLvoid APIENTRY GLDSA_TextureImage2D(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); +} + +GLvoid APIENTRY GLDSA_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); +} + +GLvoid APIENTRY GLDSA_CopyTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +} + +GLvoid APIENTRY GLDSA_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCompressedTexImage2DARB(target, level, internalformat, width, height, border, imageSize, data); +} + +GLvoid APIENTRY GLDSA_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imageSize, data); +} + +GLvoid APIENTRY GLDSA_GenerateTextureMipmap(GLuint texture, GLenum target) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglGenerateMipmapEXT(target); +} diff --git a/code/renderergl2/tr_dsa.h b/code/renderergl2/tr_dsa.h new file mode 100644 index 00000000..c166b9f3 --- /dev/null +++ b/code/renderergl2/tr_dsa.h @@ -0,0 +1,46 @@ +/* +=========================================================================== +Copyright (C) 2016 James Canete + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +=========================================================================== +*/ + +#ifndef __TR_DSA_H__ +#define __TR_DSA_H__ + +#include "../renderercommon/qgl.h" + +void GL_BindNullTextures(void); +void GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); + +GLvoid APIENTRY GLDSA_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); +GLvoid APIENTRY GLDSA_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLvoid APIENTRY GLDSA_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param); +GLvoid APIENTRY GLDSA_TextureImage2D(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid APIENTRY GLDSA_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid APIENTRY GLDSA_CopyTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLvoid APIENTRY GLDSA_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +GLvoid APIENTRY GLDSA_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); + +GLvoid APIENTRY GLDSA_GenerateTextureMipmap(GLuint texture, GLenum target); + +#endif diff --git a/code/renderergl2/tr_extensions.c b/code/renderergl2/tr_extensions.c index 91db0632..eec70879 100644 --- a/code/renderergl2/tr_extensions.c +++ b/code/renderergl2/tr_extensions.c @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "tr_local.h" +#include "tr_dsa.h" // GL_EXT_draw_range_elements void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); @@ -184,6 +185,23 @@ void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays); void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays); GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array); +// GL_EXT_direct_state_access +GLvoid (APIENTRY * qglBindMultiTexture)(GLenum texunit, GLenum target, GLuint texture); +GLvoid (APIENTRY * qglTextureParameterf)(GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLvoid (APIENTRY * qglTextureParameteri)(GLuint texture, GLenum target, GLenum pname, GLint param); +GLvoid (APIENTRY * qglTextureImage2D)(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid (APIENTRY * qglTextureSubImage2D)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid (APIENTRY * qglCopyTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLvoid (APIENTRY * qglCompressedTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +GLvoid (APIENTRY * qglCompressedTextureSubImage2D)(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); +GLvoid (APIENTRY * qglGenerateTextureMipmap)(GLuint texture, GLenum target); + static qboolean GLimp_HaveExtension(const char *ext) { const char *ptr = Q_stristr( glConfig.extensions_string, ext ); @@ -750,4 +768,38 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } + // GL_EXT_direct_state_access + extension = "GL_EXT_direct_state_access"; + qglBindMultiTexture = GLDSA_BindMultiTexture; + qglTextureParameterf = GLDSA_TextureParameterf; + qglTextureParameteri = GLDSA_TextureParameteri; + qglTextureImage2D = GLDSA_TextureImage2D; + qglTextureSubImage2D = GLDSA_TextureSubImage2D; + qglCopyTextureImage2D = GLDSA_CopyTextureImage2D; + qglCompressedTextureImage2D = GLDSA_CompressedTextureImage2D; + qglCompressedTextureSubImage2D = GLDSA_CompressedTextureSubImage2D; + qglGenerateTextureMipmap = GLDSA_GenerateTextureMipmap; + glRefConfig.directStateAccess = qfalse; + if (GLimp_HaveExtension(extension)) + { + if (r_ext_direct_state_access->integer) + { + glRefConfig.directStateAccess = qtrue; + qglBindMultiTexture = (void *)SDL_GL_GetProcAddress("glBindMultiTextureEXT"); + qglTextureParameterf = (void *)SDL_GL_GetProcAddress("glTextureParameterfEXT"); + qglTextureParameteri = (void *)SDL_GL_GetProcAddress("glTextureParameteriEXT"); + qglTextureImage2D = (void *)SDL_GL_GetProcAddress("glTextureImage2DEXT"); + qglTextureSubImage2D = (void *)SDL_GL_GetProcAddress("glTextureSubImage2DEXT"); + qglCopyTextureImage2D = (void *)SDL_GL_GetProcAddress("glCopyTextureImage2DEXT"); + qglCompressedTextureImage2D = (void *)SDL_GL_GetProcAddress("glCompressedTextureImage2DEXT"); + qglCompressedTextureSubImage2D = (void *)SDL_GL_GetProcAddress("glCompressedTextureSubImage2DEXT"); + qglGenerateTextureMipmap = (void *)SDL_GL_GetProcAddress("glGenerateTextureMipmapEXT"); + } + + ri.Printf(PRINT_ALL, result[glRefConfig.directStateAccess ? 1 : 0], extension); + } + else + { + ri.Printf(PRINT_ALL, result[2], extension); + } } diff --git a/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index c2f9bb15..7d53d463 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_image.c #include "tr_local.h" +#include "tr_dsa.h" + static byte s_intensitytable[256]; static unsigned char s_gammatable[256]; @@ -114,9 +116,8 @@ void GL_TextureMode( const char *string ) { for ( i = 0 ; i < tr.numImages ; i++ ) { glt = tr.images[ i ]; if ( glt->flags & IMGFLAG_MIPMAP ) { - GL_Bind (glt); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } } } @@ -1817,7 +1818,7 @@ static void CompressMonoBlock(byte outdata[8], const byte indata[16]) } } -static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int mip) +static void RawImage_UploadToRgtc2Texture(GLuint texture, byte *data, int width, int height, int mip) { int wBlocks, hBlocks, y, x, size; byte *compressedData, *p; @@ -1857,13 +1858,13 @@ static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int } } - qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); + qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); ri.Hunk_FreeTempMemory(compressedData); } -static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) { int dataFormat, dataType; qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); @@ -1923,9 +1924,9 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; if (subtexture) - qglCompressedTexSubImage2DARB(GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); + qglCompressedTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); else - qglCompressedTexImage2DARB(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); + qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); x >>= 1; y >>= 1; @@ -1957,13 +1958,13 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei } if ( subtexture ) - qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); + qglTextureSubImage2D(texture, GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); else { if (rgtc) - RawImage_UploadToRgtc2Texture(data, width, height, 0); + RawImage_UploadToRgtc2Texture(texture, data, width, height, 0); else - qglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); + qglTextureImage2D(texture, GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); } if (flags & IMGFLAG_MIPMAP) @@ -1991,14 +1992,14 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei { x >>= 1; y >>= 1; - qglTexSubImage2D( GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); + qglTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); } else { if (rgtc) - RawImage_UploadToRgtc2Texture(data, width, height, miplevel); + RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel); else - qglTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); + qglTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); } } } @@ -2027,14 +2028,14 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (!data) { RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); - RawImage_UploadTexture(NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); goto done; } else if (!subtexture) { if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) { - RawImage_UploadTexture(data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); goto done; } notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); @@ -2074,12 +2075,12 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (subtexture) { // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped - RawImage_UploadTexture(data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); + RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); GL_CheckErrors(); return; } - RawImage_UploadTexture(data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); done: @@ -2089,19 +2090,19 @@ done: if (mipmap) { if ( textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + qglTextureParameteri( image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { if ( textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 ); + qglTextureParameteri(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } // Fix for sampling depth buffer on old nVidia cards @@ -2112,9 +2113,9 @@ done: case GL_DEPTH_COMPONENT16_ARB: case GL_DEPTH_COMPONENT24_ARB: case GL_DEPTH_COMPONENT32_ARB: - qglTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; default: break; @@ -2177,46 +2178,32 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe image->internalFormat = internalFormat; - - // lightmaps are always allocated on TMU 1 - if ( qglActiveTextureARB && isLightmap ) { - image->TMU = 1; - } else { - image->TMU = 0; - } - - if ( qglActiveTextureARB ) { - GL_SelectTexture( image->TMU ); - } - - GL_Bind(image); - if (image->flags & IMGFLAG_CUBEMAP) { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (image->flags & IMGFLAG_MIPMAP) { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); if (image->flags & IMGFLAG_MIPMAP) - qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); + qglGenerateTextureMipmap(image->texnum, GL_TEXTURE_CUBE_MAP); image->uploadWidth = width; image->uploadHeight = height; @@ -2225,12 +2212,10 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe { Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode); } - GL_SelectTexture( 0 ); - hash = generateHashValue(name); image->next = hashTable[hash]; hashTable[hash] = image; @@ -2254,15 +2239,7 @@ image_t *R_CreateImage(const char *name, byte *pic, int width, int height, imgTy void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height ) { - if (qglActiveTextureARB) { - GL_SelectTexture(image->TMU); - } - - GL_Bind(image); - Upload32(pic, x, y, width, height, GL_RGBA8, 0, image); - - GL_SelectTexture(0); } //=================================================================== @@ -2829,11 +2806,10 @@ void R_CreateBuiltinImages( void ) { for ( x = 0; x < 4; x++) { tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB); - GL_Bind(tr.sunShadowDepthImage[x]); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); } tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); @@ -2946,15 +2922,7 @@ void R_DeleteTextures( void ) { tr.numImages = 0; - Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) ); - if ( qglActiveTextureARB ) { - GL_SelectTexture( 1 ); - qglBindTexture( GL_TEXTURE_2D, 0 ); - GL_SelectTexture( 0 ); - qglBindTexture( GL_TEXTURE_2D, 0 ); - } else { - qglBindTexture( GL_TEXTURE_2D, 0 ); - } + GL_BindNullTextures(); } /* diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index 1aa4d4eb..2d7326e3 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" +#include "tr_dsa.h" + glconfig_t glConfig; glRefConfig_t glRefConfig; qboolean textureFilterAnisotropic = qfalse; @@ -106,6 +108,7 @@ cvar_t *r_ext_framebuffer_multisample; cvar_t *r_arb_seamless_cube_map; cvar_t *r_arb_vertex_type_2_10_10_10_rev; cvar_t *r_arb_vertex_array_object; +cvar_t *r_ext_direct_state_access; cvar_t *r_mergeMultidraws; cvar_t *r_mergeLeafSurfaces; @@ -837,7 +840,7 @@ void R_ScreenShotJPEG_f (void) { R_ExportCubemaps ================== */ -void R_ExportCubemaps() +void R_ExportCubemaps(void) { exportCubemapsCommand_t *cmd; @@ -955,19 +958,10 @@ void GL_SetDefaultState( void ) qglColor4f (1,1,1,1); - // initialize downstream texture unit if we're running - // in a multitexture environment - if ( qglActiveTextureARB ) { - GL_SelectTexture( 1 ); - GL_TextureMode( r_textureMode->string ); - GL_TexEnv( GL_MODULATE ); - qglDisable( GL_TEXTURE_2D ); - GL_SelectTexture( 0 ); - } + GL_BindNullTextures(); qglEnable(GL_TEXTURE_2D); GL_TextureMode( r_textureMode->string ); - GL_TexEnv( GL_MODULATE ); //qglShadeModel( GL_SMOOTH ); qglDepthFunc( GL_LEQUAL ); @@ -1180,6 +1174,7 @@ void R_Register( void ) r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH); r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( "r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH); r_arb_vertex_array_object = ri.Cvar_Get( "r_arb_vertex_array_object", "1", CVAR_ARCHIVE | CVAR_LATCH); + r_ext_direct_state_access = ri.Cvar_Get("r_ext_direct_state_access", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "0", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index 22e935aa..2db7eaea 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1351,8 +1351,6 @@ typedef struct { // the renderer front end should never modify glstate_t typedef struct { - int currenttextures[NUM_TEXTURE_BUNDLES]; - int currenttmu; qboolean finishCalled; int texEnv[2]; int faceCulling; @@ -1420,6 +1418,7 @@ typedef struct { qboolean floatLightmap; qboolean vertexArrayObject; + qboolean directStateAccess; } glRefConfig_t; @@ -1718,6 +1717,7 @@ extern cvar_t *r_ext_framebuffer_multisample; extern cvar_t *r_arb_seamless_cube_map; extern cvar_t *r_arb_vertex_type_2_10_10_10_rev; extern cvar_t *r_arb_vertex_array_object; +extern cvar_t *r_ext_direct_state_access; extern cvar_t *r_nobind; // turns off binding to appropriate textures extern cvar_t *r_singleShader; // make most world faces use default shader @@ -1882,17 +1882,14 @@ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, /* ** GL wrapper/helper functions */ -void GL_Bind( image_t *image ); void GL_BindToTMU( image_t *image, int tmu ); void GL_SetDefaultState (void); -void GL_SelectTexture( int unit ); void GL_TextureMode( const char *string ); void GL_CheckErrs( char *file, int line ); #define GL_CheckErrors(...) GL_CheckErrs(__FILE__, __LINE__) void GL_State( unsigned long stateVector ); void GL_SetProjectionMatrix(mat4_t matrix); void GL_SetModelviewMatrix(mat4_t matrix); -void GL_TexEnv( int env ); void GL_Cull( int cullType ); #define GLS_SRCBLEND_ZERO 0x00000001 diff --git a/code/renderergl2/tr_main.c b/code/renderergl2/tr_main.c index ca5327cd..6c78930b 100644 --- a/code/renderergl2/tr_main.c +++ b/code/renderergl2/tr_main.c @@ -2030,7 +2030,7 @@ void R_DebugGraphics( void ) { R_IssuePendingRenderCommands(); - GL_Bind( tr.whiteImage); + GL_BindToTMU(tr.whiteImage, TB_COLORMAP); GL_Cull( CT_FRONT_SIDED ); ri.CM_DrawDebugSurface( R_DebugPolygon ); } diff --git a/code/renderergl2/tr_shade.c b/code/renderergl2/tr_shade.c index fde95e56..5e59c80f 100644 --- a/code/renderergl2/tr_shade.c +++ b/code/renderergl2/tr_shade.c @@ -101,11 +101,9 @@ static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) { int index; if ( bundle->isVideoMap ) { - int oldtmu = glState.currenttmu; - GL_SelectTexture(tmu); ri.CIN_RunCinematic(bundle->videoMapHandle); ri.CIN_UploadCinematic(bundle->videoMapHandle); - GL_SelectTexture(oldtmu); + GL_BindToTMU(tr.scratchImage[bundle->videoMapHandle], tmu); return; } @@ -136,7 +134,7 @@ Draws triangle outlines for debugging ================ */ static void DrawTris (shaderCommands_t *input) { - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); qglDepthRange( 0, 0 ); @@ -414,7 +412,7 @@ static void ProjectDlightTexture( void ) { vector[3] = scale; GLSL_SetUniformVec4(sp, UNIFORM_DLIGHTINFO, vector); - GL_Bind( tr.dlightImage ); + GL_BindToTMU( tr.dlightImage, TB_COLORMAP ); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered @@ -862,11 +860,7 @@ static void ForwardDlight( void ) { } if (r_dlightMode->integer >= 2) - { - GL_SelectTexture(TB_SHADOWMAP); - GL_Bind(tr.shadowCubemaps[l]); - GL_SelectTexture(0); - } + GL_BindToTMU(tr.shadowCubemaps[l], TB_SHADOWMAP); ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); @@ -1266,7 +1260,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) if ( backEnd.depthFill ) { if (!(pStage->stateBits & GLS_ATEST_BITS)) - GL_BindToTMU( tr.whiteImage, 0 ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 ) R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP ); } diff --git a/code/renderergl2/tr_shadows.c b/code/renderergl2/tr_shadows.c index 13fbfdf7..76371752 100644 --- a/code/renderergl2/tr_shadows.c +++ b/code/renderergl2/tr_shadows.c @@ -206,7 +206,7 @@ void RB_ShadowTessEnd( void ) { // draw the silhouette edges - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); qglColor3f( 0.2f, 0.2f, 0.2f ); @@ -256,7 +256,7 @@ void RB_ShadowFinish( void ) { qglDisable (GL_CLIP_PLANE0); GL_Cull( CT_TWO_SIDED ); - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); qglLoadIdentity (); diff --git a/code/renderergl2/tr_sky.c b/code/renderergl2/tr_sky.c index 05ff8f94..840d0149 100644 --- a/code/renderergl2/tr_sky.c +++ b/code/renderergl2/tr_sky.c @@ -374,7 +374,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max //tess.numIndexes = 0; tess.firstIndex = tess.numIndexes; - GL_Bind( image ); + GL_BindToTMU( image, TB_COLORMAP ); GL_Cull( CT_TWO_SIDED ); for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ ) diff --git a/code/renderergl2/tr_surface.c b/code/renderergl2/tr_surface.c index c5b1b0f8..72cd610e 100644 --- a/code/renderergl2/tr_surface.c +++ b/code/renderergl2/tr_surface.c @@ -575,7 +575,7 @@ static void RB_SurfaceBeam( void ) VectorAdd( start_points[i], direction, end_points[i] ); } - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); @@ -1518,7 +1518,7 @@ Draws x/y/z lines from the origin for orientation debugging static void RB_SurfaceAxis( void ) { // FIXME: implement this #if 0 - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_DEFAULT ); qglLineWidth( 3 ); qglBegin( GL_LINES ); diff --git a/misc/msvc12/opengl2.vcxproj b/misc/msvc12/opengl2.vcxproj index d66ea9b3..2f91590e 100644 --- a/misc/msvc12/opengl2.vcxproj +++ b/misc/msvc12/opengl2.vcxproj @@ -514,6 +514,7 @@ cscript.exe glsl_stringify.vbs ..\..\code\renderergl2\glsl\tonemap_vp.glsl ..\.. + diff --git a/misc/msvc12/opengl2.vcxproj.filters b/misc/msvc12/opengl2.vcxproj.filters index 480b8547..d8cded4d 100644 --- a/misc/msvc12/opengl2.vcxproj.filters +++ b/misc/msvc12/opengl2.vcxproj.filters @@ -283,6 +283,7 @@ zlib +