OpenGL2: Direct state access, part 1: Texture binds

This commit is contained in:
SmileTheory 2016-01-18 04:46:01 -08:00
parent 3089df0398
commit 275317fefb
16 changed files with 356 additions and 235 deletions

View file

@ -1644,6 +1644,7 @@ Q3R2OBJ = \
$(B)/renderergl2/tr_bsp.o \ $(B)/renderergl2/tr_bsp.o \
$(B)/renderergl2/tr_cmds.o \ $(B)/renderergl2/tr_cmds.o \
$(B)/renderergl2/tr_curve.o \ $(B)/renderergl2/tr_curve.o \
$(B)/renderergl2/tr_dsa.o \
$(B)/renderergl2/tr_extramath.o \ $(B)/renderergl2/tr_extramath.o \
$(B)/renderergl2/tr_extensions.o \ $(B)/renderergl2/tr_extensions.o \
$(B)/renderergl2/tr_fbo.o \ $(B)/renderergl2/tr_fbo.o \

View file

@ -736,6 +736,23 @@ extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array);
#define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5 #define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5
#endif #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) #if defined(WIN32)
// WGL_ARB_create_context // WGL_ARB_create_context

View file

@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=========================================================================== ===========================================================================
*/ */
#include "tr_local.h" #include "tr_local.h"
#include "tr_dsa.h"
backEndData_t *backEndData; backEndData_t *backEndData;
backEndState_t backEnd; 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 ** GL_BindToTMU
*/ */
void GL_BindToTMU( image_t *image, int tmu ) void GL_BindToTMU( image_t *image, int tmu )
{ {
int texnum; GLuint texture = (tmu == TB_COLORMAP) ? tr.defaultImage->texnum : 0;
int oldtmu = glState.currenttmu; GLenum target = GL_TEXTURE_2D;
if (!image)
texnum = 0;
else
texnum = image->texnum;
if ( glState.currenttextures[tmu] != texnum ) {
GL_SelectTexture( tmu );
if (image) if (image)
image->frameUsed = tr.frameCount; {
glState.currenttextures[tmu] = texnum; if (image->flags & IMGFLAG_CUBEMAP)
target = GL_TEXTURE_CUBE_MAP;
if (image && (image->flags & IMGFLAG_CUBEMAP)) image->frameUsed = tr.frameCount;
qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum ); texture = image->texnum;
else
qglBindTexture( GL_TEXTURE_2D, texnum );
GL_SelectTexture( oldtmu );
} }
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; 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 ** 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); RE_UploadCinematic (w, h, cols, rows, data, client, dirty);
GL_BindToTMU(tr.scratchImage[client], TB_COLORMAP);
if ( r_speeds->integer ) { if ( r_speeds->integer ) {
end = ri.Milliseconds(); 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) { 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 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 ) { if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols; tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows; 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 ); qglTextureImage2D(texture, 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 ); qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} else { } else {
if (dirty) { if (dirty) {
// otherwise, just subimage upload it so that drivers can tell we are going to be changing // 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 // 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 // If we're using multisampling, resolve the depth first
FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_DEPTH_BUFFER_BIT, GL_NEAREST); 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 // If we're rendering directly to the screen, copy the depth to a texture
GL_BindToTMU(tr.renderDepthImage, 0); qglCopyTextureImage2D(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
} }
if (r_ssao->integer) if (r_ssao->integer)
@ -1315,10 +1237,8 @@ const void *RB_DrawSurfs( const void *data ) {
cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]; cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
FBO_Bind(NULL); FBO_Bind(NULL);
GL_SelectTexture(TB_CUBEMAP); if (cubemap && cubemap->image)
GL_BindToTMU(cubemap->image, TB_CUBEMAP); qglGenerateTextureMipmap(cubemap->image->texnum, GL_TEXTURE_CUBE_MAP);
qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
GL_SelectTexture(0);
} }
return (const void *)(cmd + 1); return (const void *)(cmd + 1);
@ -1395,7 +1315,7 @@ void RB_ShowImages( void ) {
{ {
vec4_t quadVerts[4]; vec4_t quadVerts[4];
GL_Bind(image); GL_BindToTMU(image, TB_COLORMAP);
VectorSet4(quadVerts[0], x, y, 0, 1); VectorSet4(quadVerts[0], x, y, 0, 1);
VectorSet4(quadVerts[1], x + w, 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) if (cmd->map != -1)
{ {
GL_SelectTexture(0);
if (cmd->cubeSide != -1) if (cmd->cubeSide != -1)
{ {
if (tr.shadowCubemaps[cmd->map]) if (tr.shadowCubemaps[cmd->map])
{ {
GL_Bind(tr.shadowCubemaps[cmd->map]); 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);
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);
} }
} }
else else
{ {
if (tr.pshadowMaps[cmd->map]) if (tr.pshadowMaps[cmd->map])
{ {
GL_Bind(tr.pshadowMaps[cmd->map]); 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);
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);
} }
} }
} }
@ -1658,7 +1575,7 @@ const void *RB_PostProcess(const void *data)
if (srcFbo) 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; autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer;
RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure); RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure);
@ -1774,7 +1691,7 @@ const void *RB_ExportCubemaps(const void *data)
{ {
char filename[MAX_QPATH]; char filename[MAX_QPATH];
cubemap_t *cubemap = &tr.cubemaps[i]; cubemap_t *cubemap = &tr.cubemaps[i];
char *p = cubemapPixels; byte *p = cubemapPixels;
for (j = 0; j < 6; j++) for (j = 0; j < 6; j++)
{ {

132
code/renderergl2/tr_dsa.c Normal file
View file

@ -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);
}

46
code/renderergl2/tr_dsa.h Normal file
View file

@ -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

View file

@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#endif #endif
#include "tr_local.h" #include "tr_local.h"
#include "tr_dsa.h"
// GL_EXT_draw_range_elements // GL_EXT_draw_range_elements
void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); 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); void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays);
GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array); 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) static qboolean GLimp_HaveExtension(const char *ext)
{ {
const char *ptr = Q_stristr( glConfig.extensions_string, ext ); const char *ptr = Q_stristr( glConfig.extensions_string, ext );
@ -750,4 +768,38 @@ void GLimp_InitExtraExtensions()
ri.Printf(PRINT_ALL, result[2], extension); 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);
}
} }

View file

@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// tr_image.c // tr_image.c
#include "tr_local.h" #include "tr_local.h"
#include "tr_dsa.h"
static byte s_intensitytable[256]; static byte s_intensitytable[256];
static unsigned char s_gammatable[256]; static unsigned char s_gammatable[256];
@ -114,9 +116,8 @@ void GL_TextureMode( const char *string ) {
for ( i = 0 ; i < tr.numImages ; i++ ) { for ( i = 0 ; i < tr.numImages ; i++ ) {
glt = tr.images[ i ]; glt = tr.images[ i ];
if ( glt->flags & IMGFLAG_MIPMAP ) { if ( glt->flags & IMGFLAG_MIPMAP ) {
GL_Bind (glt); qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
qglTexParameterf(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; int wBlocks, hBlocks, y, x, size;
byte *compressedData, *p; 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); 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; int dataFormat, dataType;
qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); 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; int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block;
if (subtexture) 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 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; x >>= 1;
y >>= 1; y >>= 1;
@ -1957,13 +1958,13 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei
} }
if ( subtexture ) 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 else
{ {
if (rgtc) if (rgtc)
RawImage_UploadToRgtc2Texture(data, width, height, 0); RawImage_UploadToRgtc2Texture(texture, data, width, height, 0);
else 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) if (flags & IMGFLAG_MIPMAP)
@ -1991,14 +1992,14 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei
{ {
x >>= 1; x >>= 1;
y >>= 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 else
{ {
if (rgtc) if (rgtc)
RawImage_UploadToRgtc2Texture(data, width, height, miplevel); RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel);
else 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) if (!data)
{ {
RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); 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; goto done;
} }
else if (!subtexture) else if (!subtexture)
{ {
if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) 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; goto done;
} }
notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); 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) if (subtexture)
{ {
// FIXME: Incorrect if original texture was not a power of 2 texture or picmipped // 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(); GL_CheckErrors();
return; 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: done:
@ -2089,19 +2090,19 @@ done:
if (mipmap) if (mipmap)
{ {
if ( textureFilterAnisotropic ) 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 ) ); (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTextureParameterf(image->texnum, 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_MAG_FILTER, gl_filter_max);
} }
else else
{ {
if ( textureFilterAnisotropic ) 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 ); qglTextureParameterf(image->texnum, 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_MAG_FILTER, GL_LINEAR);
} }
// Fix for sampling depth buffer on old nVidia cards // Fix for sampling depth buffer on old nVidia cards
@ -2112,9 +2113,9 @@ done:
case GL_DEPTH_COMPONENT16_ARB: case GL_DEPTH_COMPONENT16_ARB:
case GL_DEPTH_COMPONENT24_ARB: case GL_DEPTH_COMPONENT24_ARB:
case GL_DEPTH_COMPONENT32_ARB: case GL_DEPTH_COMPONENT32_ARB:
qglTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); qglTextureParameterf(image->texnum, 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_TEXTURE_MAG_FILTER, GL_NEAREST);
break; break;
default: default:
break; break;
@ -2177,46 +2178,32 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe
image->internalFormat = internalFormat; 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) if (image->flags & IMGFLAG_CUBEMAP)
{ {
qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTextureParameteri(image->texnum, 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); qglTextureParameteri(image->texnum, 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_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) 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 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); qglTextureImage2D(image->texnum, 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); qglTextureImage2D(image->texnum, 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); qglTextureImage2D(image->texnum, 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); qglTextureImage2D(image->texnum, 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); qglTextureImage2D(image->texnum, 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_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic);
if (image->flags & IMGFLAG_MIPMAP) if (image->flags & IMGFLAG_MIPMAP)
qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); qglGenerateTextureMipmap(image->texnum, GL_TEXTURE_CUBE_MAP);
image->uploadWidth = width; image->uploadWidth = width;
image->uploadHeight = height; 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 ); Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); qglTextureParameterf(image->texnum, 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_T, glWrapClampMode);
} }
GL_SelectTexture( 0 );
hash = generateHashValue(name); hash = generateHashValue(name);
image->next = hashTable[hash]; image->next = hashTable[hash];
hashTable[hash] = image; 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 ) 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); 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++) 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); 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]); qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexParameterf(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);
qglTexParameterf(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);
qglTexParameterf(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); 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; tr.numImages = 0;
Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) ); GL_BindNullTextures();
if ( qglActiveTextureARB ) {
GL_SelectTexture( 1 );
qglBindTexture( GL_TEXTURE_2D, 0 );
GL_SelectTexture( 0 );
qglBindTexture( GL_TEXTURE_2D, 0 );
} else {
qglBindTexture( GL_TEXTURE_2D, 0 );
}
} }
/* /*

View file

@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "tr_local.h" #include "tr_local.h"
#include "tr_dsa.h"
glconfig_t glConfig; glconfig_t glConfig;
glRefConfig_t glRefConfig; glRefConfig_t glRefConfig;
qboolean textureFilterAnisotropic = qfalse; qboolean textureFilterAnisotropic = qfalse;
@ -106,6 +108,7 @@ cvar_t *r_ext_framebuffer_multisample;
cvar_t *r_arb_seamless_cube_map; cvar_t *r_arb_seamless_cube_map;
cvar_t *r_arb_vertex_type_2_10_10_10_rev; cvar_t *r_arb_vertex_type_2_10_10_10_rev;
cvar_t *r_arb_vertex_array_object; cvar_t *r_arb_vertex_array_object;
cvar_t *r_ext_direct_state_access;
cvar_t *r_mergeMultidraws; cvar_t *r_mergeMultidraws;
cvar_t *r_mergeLeafSurfaces; cvar_t *r_mergeLeafSurfaces;
@ -837,7 +840,7 @@ void R_ScreenShotJPEG_f (void) {
R_ExportCubemaps R_ExportCubemaps
================== ==================
*/ */
void R_ExportCubemaps() void R_ExportCubemaps(void)
{ {
exportCubemapsCommand_t *cmd; exportCubemapsCommand_t *cmd;
@ -955,19 +958,10 @@ void GL_SetDefaultState( void )
qglColor4f (1,1,1,1); qglColor4f (1,1,1,1);
// initialize downstream texture unit if we're running GL_BindNullTextures();
// 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 );
}
qglEnable(GL_TEXTURE_2D); qglEnable(GL_TEXTURE_2D);
GL_TextureMode( r_textureMode->string ); GL_TextureMode( r_textureMode->string );
GL_TexEnv( GL_MODULATE );
//qglShadeModel( GL_SMOOTH ); //qglShadeModel( GL_SMOOTH );
qglDepthFunc( GL_LEQUAL ); 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_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_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_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", r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic",
"0", CVAR_ARCHIVE | CVAR_LATCH ); "0", CVAR_ARCHIVE | CVAR_LATCH );

View file

@ -1351,8 +1351,6 @@ typedef struct {
// the renderer front end should never modify glstate_t // the renderer front end should never modify glstate_t
typedef struct { typedef struct {
int currenttextures[NUM_TEXTURE_BUNDLES];
int currenttmu;
qboolean finishCalled; qboolean finishCalled;
int texEnv[2]; int texEnv[2];
int faceCulling; int faceCulling;
@ -1420,6 +1418,7 @@ typedef struct {
qboolean floatLightmap; qboolean floatLightmap;
qboolean vertexArrayObject; qboolean vertexArrayObject;
qboolean directStateAccess;
} glRefConfig_t; } 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_seamless_cube_map;
extern cvar_t *r_arb_vertex_type_2_10_10_10_rev; extern cvar_t *r_arb_vertex_type_2_10_10_10_rev;
extern cvar_t *r_arb_vertex_array_object; 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_nobind; // turns off binding to appropriate textures
extern cvar_t *r_singleShader; // make most world faces use default shader 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 ** GL wrapper/helper functions
*/ */
void GL_Bind( image_t *image );
void GL_BindToTMU( image_t *image, int tmu ); void GL_BindToTMU( image_t *image, int tmu );
void GL_SetDefaultState (void); void GL_SetDefaultState (void);
void GL_SelectTexture( int unit );
void GL_TextureMode( const char *string ); void GL_TextureMode( const char *string );
void GL_CheckErrs( char *file, int line ); void GL_CheckErrs( char *file, int line );
#define GL_CheckErrors(...) GL_CheckErrs(__FILE__, __LINE__) #define GL_CheckErrors(...) GL_CheckErrs(__FILE__, __LINE__)
void GL_State( unsigned long stateVector ); void GL_State( unsigned long stateVector );
void GL_SetProjectionMatrix(mat4_t matrix); void GL_SetProjectionMatrix(mat4_t matrix);
void GL_SetModelviewMatrix(mat4_t matrix); void GL_SetModelviewMatrix(mat4_t matrix);
void GL_TexEnv( int env );
void GL_Cull( int cullType ); void GL_Cull( int cullType );
#define GLS_SRCBLEND_ZERO 0x00000001 #define GLS_SRCBLEND_ZERO 0x00000001

View file

@ -2030,7 +2030,7 @@ void R_DebugGraphics( void ) {
R_IssuePendingRenderCommands(); R_IssuePendingRenderCommands();
GL_Bind( tr.whiteImage); GL_BindToTMU(tr.whiteImage, TB_COLORMAP);
GL_Cull( CT_FRONT_SIDED ); GL_Cull( CT_FRONT_SIDED );
ri.CM_DrawDebugSurface( R_DebugPolygon ); ri.CM_DrawDebugSurface( R_DebugPolygon );
} }

View file

@ -101,11 +101,9 @@ static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) {
int index; int index;
if ( bundle->isVideoMap ) { if ( bundle->isVideoMap ) {
int oldtmu = glState.currenttmu;
GL_SelectTexture(tmu);
ri.CIN_RunCinematic(bundle->videoMapHandle); ri.CIN_RunCinematic(bundle->videoMapHandle);
ri.CIN_UploadCinematic(bundle->videoMapHandle); ri.CIN_UploadCinematic(bundle->videoMapHandle);
GL_SelectTexture(oldtmu); GL_BindToTMU(tr.scratchImage[bundle->videoMapHandle], tmu);
return; return;
} }
@ -136,7 +134,7 @@ Draws triangle outlines for debugging
================ ================
*/ */
static void DrawTris (shaderCommands_t *input) { static void DrawTris (shaderCommands_t *input) {
GL_Bind( tr.whiteImage ); GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
qglDepthRange( 0, 0 ); qglDepthRange( 0, 0 );
@ -414,7 +412,7 @@ static void ProjectDlightTexture( void ) {
vector[3] = scale; vector[3] = scale;
GLSL_SetUniformVec4(sp, UNIFORM_DLIGHTINFO, vector); 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 // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
// where they aren't rendered // where they aren't rendered
@ -862,11 +860,7 @@ static void ForwardDlight( void ) {
} }
if (r_dlightMode->integer >= 2) if (r_dlightMode->integer >= 2)
{ GL_BindToTMU(tr.shadowCubemaps[l], TB_SHADOWMAP);
GL_SelectTexture(TB_SHADOWMAP);
GL_Bind(tr.shadowCubemaps[l]);
GL_SelectTexture(0);
}
ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
@ -1266,7 +1260,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
if ( backEnd.depthFill ) if ( backEnd.depthFill )
{ {
if (!(pStage->stateBits & GLS_ATEST_BITS)) 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 ) else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 )
R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP ); R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP );
} }

View file

@ -206,7 +206,7 @@ void RB_ShadowTessEnd( void ) {
// draw the silhouette edges // draw the silhouette edges
GL_Bind( tr.whiteImage ); GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
qglColor3f( 0.2f, 0.2f, 0.2f ); qglColor3f( 0.2f, 0.2f, 0.2f );
@ -256,7 +256,7 @@ void RB_ShadowFinish( void ) {
qglDisable (GL_CLIP_PLANE0); qglDisable (GL_CLIP_PLANE0);
GL_Cull( CT_TWO_SIDED ); GL_Cull( CT_TWO_SIDED );
GL_Bind( tr.whiteImage ); GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
qglLoadIdentity (); qglLoadIdentity ();

View file

@ -374,7 +374,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max
//tess.numIndexes = 0; //tess.numIndexes = 0;
tess.firstIndex = tess.numIndexes; tess.firstIndex = tess.numIndexes;
GL_Bind( image ); GL_BindToTMU( image, TB_COLORMAP );
GL_Cull( CT_TWO_SIDED ); GL_Cull( CT_TWO_SIDED );
for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ ) for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )

View file

@ -575,7 +575,7 @@ static void RB_SurfaceBeam( void )
VectorAdd( start_points[i], direction, end_points[i] ); 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 ); 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 ) { static void RB_SurfaceAxis( void ) {
// FIXME: implement this // FIXME: implement this
#if 0 #if 0
GL_Bind( tr.whiteImage ); GL_BindToTMU( tr.whiteImage, TB_COLORMAP );
GL_State( GLS_DEFAULT ); GL_State( GLS_DEFAULT );
qglLineWidth( 3 ); qglLineWidth( 3 );
qglBegin( GL_LINES ); qglBegin( GL_LINES );

View file

@ -514,6 +514,7 @@ cscript.exe glsl_stringify.vbs ..\..\code\renderergl2\glsl\tonemap_vp.glsl ..\..
<ClCompile Include="..\..\code\renderergl2\tr_bsp.c" /> <ClCompile Include="..\..\code\renderergl2\tr_bsp.c" />
<ClCompile Include="..\..\code\renderergl2\tr_cmds.c" /> <ClCompile Include="..\..\code\renderergl2\tr_cmds.c" />
<ClCompile Include="..\..\code\renderergl2\tr_curve.c" /> <ClCompile Include="..\..\code\renderergl2\tr_curve.c" />
<ClCompile Include="..\..\code\renderergl2\tr_dsa.c" />
<ClCompile Include="..\..\code\renderergl2\tr_extensions.c" /> <ClCompile Include="..\..\code\renderergl2\tr_extensions.c" />
<ClCompile Include="..\..\code\renderergl2\tr_extramath.c" /> <ClCompile Include="..\..\code\renderergl2\tr_extramath.c" />
<ClCompile Include="..\..\code\renderergl2\tr_fbo.c" /> <ClCompile Include="..\..\code\renderergl2\tr_fbo.c" />

View file

@ -283,6 +283,7 @@
<ClCompile Include="..\..\code\zlib\zutil.c"> <ClCompile Include="..\..\code\zlib\zutil.c">
<Filter>zlib</Filter> <Filter>zlib</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\code\renderergl2\tr_dsa.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\code\cgame\tr_types.h" /> <ClInclude Include="..\..\code\cgame\tr_types.h" />