r_world: Add a new R_DrawTextureChains_Multitexture_VBO function. Draws lightmapped surfaces with fulbrights in one pass, using the VBO. Requires 3 TMUs, GL_COMBINE_EXT, and GL_ADD.
R_DrawTextureChains_Multitexture: revert to the way it was before VBO support was added. gl_texmgr: expose GL_SelectTexture. make the implementation less convoluted and support 3 TMUs. gl_vidsdl: check GL_MAX_TEXTURE_UNITS r_brush: only create VBOs if 3 TMUs available git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1035 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
parent
d37b1574fe
commit
90b26fc215
|
@ -1401,7 +1401,8 @@ void TexMgr_ReloadNobrightImages (void)
|
||||||
================================================================================
|
================================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static GLuint currenttexture = (GLuint)-1; // to avoid unnecessary texture sets
|
static GLuint currenttexture[3] = {-1, -1, -1}; // to avoid unnecessary texture sets
|
||||||
|
static GLenum currenttarget = GL_TEXTURE0_ARB;
|
||||||
qboolean mtexenabled = false;
|
qboolean mtexenabled = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1409,27 +1410,12 @@ qboolean mtexenabled = false;
|
||||||
GL_SelectTexture -- johnfitz -- rewritten
|
GL_SelectTexture -- johnfitz -- rewritten
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
static void GL_SelectTexture (GLenum target)
|
void GL_SelectTexture (GLenum target)
|
||||||
{
|
{
|
||||||
static GLenum currenttarget;
|
|
||||||
static GLuint ct0, ct1;
|
|
||||||
|
|
||||||
if (target == currenttarget)
|
if (target == currenttarget)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GL_SelectTextureFunc(target);
|
GL_SelectTextureFunc(target);
|
||||||
|
|
||||||
if (target == GL_TEXTURE0_ARB)
|
|
||||||
{
|
|
||||||
ct1 = currenttexture;
|
|
||||||
currenttexture = ct0;
|
|
||||||
}
|
|
||||||
else //target == GL_TEXTURE1_ARB
|
|
||||||
{
|
|
||||||
ct0 = currenttexture;
|
|
||||||
currenttexture = ct1;
|
|
||||||
}
|
|
||||||
|
|
||||||
currenttarget = target;
|
currenttarget = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1473,10 +1459,10 @@ void GL_Bind (gltexture_t *texture)
|
||||||
if (!texture)
|
if (!texture)
|
||||||
texture = nulltexture;
|
texture = nulltexture;
|
||||||
|
|
||||||
if (texture->texnum != currenttexture)
|
if (texture->texnum != currenttexture[currenttarget - GL_TEXTURE0_ARB])
|
||||||
{
|
{
|
||||||
currenttexture = texture->texnum;
|
currenttexture[currenttarget - GL_TEXTURE0_ARB] = texture->texnum;
|
||||||
glBindTexture (GL_TEXTURE_2D, currenttexture);
|
glBindTexture (GL_TEXTURE_2D, texture->texnum);
|
||||||
texture->visframe = r_framecount;
|
texture->visframe = r_framecount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ int TexMgr_PadConditional (int s);
|
||||||
|
|
||||||
// TEXTURE BINDING & TEXTURE UNIT SWITCHING
|
// TEXTURE BINDING & TEXTURE UNIT SWITCHING
|
||||||
|
|
||||||
|
void GL_SelectTexture (GLenum target);
|
||||||
void GL_DisableMultitexture (void); //selects texture unit 0
|
void GL_DisableMultitexture (void); //selects texture unit 0
|
||||||
void GL_EnableMultitexture (void); //selects texture unit 1
|
void GL_EnableMultitexture (void); //selects texture unit 1
|
||||||
void GL_Bind (gltexture_t *texture);
|
void GL_Bind (gltexture_t *texture);
|
||||||
|
|
|
@ -93,6 +93,7 @@ qboolean gl_anisotropy_able = false; //johnfitz
|
||||||
float gl_max_anisotropy; //johnfitz
|
float gl_max_anisotropy; //johnfitz
|
||||||
qboolean gl_texture_NPOT = false; //ericw
|
qboolean gl_texture_NPOT = false; //ericw
|
||||||
qboolean gl_vbo_able = false; //ericw
|
qboolean gl_vbo_able = false; //ericw
|
||||||
|
GLint gl_max_texture_units = 0; //ericw
|
||||||
|
|
||||||
PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc = NULL; //johnfitz
|
PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc = NULL; //johnfitz
|
||||||
PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc = NULL; //johnfitz
|
PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc = NULL; //johnfitz
|
||||||
|
@ -831,6 +832,9 @@ static void GL_CheckExtensions (void)
|
||||||
{
|
{
|
||||||
Con_Printf("FOUND: ARB_multitexture\n");
|
Con_Printf("FOUND: ARB_multitexture\n");
|
||||||
gl_mtexable = true;
|
gl_mtexable = true;
|
||||||
|
|
||||||
|
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gl_max_texture_units);
|
||||||
|
Con_Printf("GL_MAX_TEXTURE_UNITS: %d\n", (int)gl_max_texture_units);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -155,6 +155,7 @@ extern qboolean gl_mtexable;
|
||||||
extern PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc;
|
extern PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc;
|
||||||
extern PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc;
|
extern PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc;
|
||||||
extern PFNGLCLIENTACTIVETEXTUREARBPROC GL_ClientActiveTextureFunc;
|
extern PFNGLCLIENTACTIVETEXTUREARBPROC GL_ClientActiveTextureFunc;
|
||||||
|
extern GLint gl_max_texture_units; //ericw
|
||||||
|
|
||||||
//johnfitz -- anisotropic filtering
|
//johnfitz -- anisotropic filtering
|
||||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||||
|
|
|
@ -975,7 +975,7 @@ void GL_BuildVBOs (void)
|
||||||
qmodel_t *m;
|
qmodel_t *m;
|
||||||
float *varray;
|
float *varray;
|
||||||
|
|
||||||
if (!(gl_vbo_able && gl_mtexable))
|
if (!(gl_vbo_able && gl_mtexable && gl_max_texture_units >= 3))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// ask GL for a name for our VBO
|
// ask GL for a name for our VBO
|
||||||
|
@ -1032,6 +1032,11 @@ void GL_BuildVBOs (void)
|
||||||
GL_ClientActiveTextureFunc (GL_TEXTURE1_ARB);
|
GL_ClientActiveTextureFunc (GL_TEXTURE1_ARB);
|
||||||
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 5);
|
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 5);
|
||||||
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
|
// TMU 2 is for fullbrights; same texture coordinates as TMU 0
|
||||||
|
GL_ClientActiveTextureFunc (GL_TEXTURE2_ARB);
|
||||||
|
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 3);
|
||||||
|
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
164
Quake/r_world.c
164
Quake/r_world.c
|
@ -416,29 +416,6 @@ void R_DrawTextureChains_Glow (qmodel_t *model, entity_t *ent, texchain_t chain)
|
||||||
//
|
//
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
R_MultitexturedDrawGLPoly
|
|
||||||
|
|
||||||
Fallback immediate mode code to draw a multitexutred glpoly_t
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
static void R_MultitexturedDrawGLPoly (glpoly_t *p)
|
|
||||||
{
|
|
||||||
float *v;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
glBegin(GL_POLYGON);
|
|
||||||
v = p->verts[0];
|
|
||||||
for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
|
|
||||||
{
|
|
||||||
GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, v[3], v[4]);
|
|
||||||
GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, v[5], v[6]);
|
|
||||||
glVertex3fv (v);
|
|
||||||
}
|
|
||||||
glEnd ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int R_NumTriangleIndicesForSurf (msurface_t *s)
|
static unsigned int R_NumTriangleIndicesForSurf (msurface_t *s)
|
||||||
{
|
{
|
||||||
return 3 * (s->numedges - 2);
|
return 3 * (s->numedges - 2);
|
||||||
|
@ -475,8 +452,6 @@ R_ClearBatch
|
||||||
*/
|
*/
|
||||||
static void R_ClearBatch ()
|
static void R_ClearBatch ()
|
||||||
{
|
{
|
||||||
if (!(gl_vbo_able && gl_mtexable)) return;
|
|
||||||
|
|
||||||
num_vbo_indices = 0;
|
num_vbo_indices = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,8 +464,6 @@ Draw the current batch if non-empty and clears it, ready for more R_BatchSurface
|
||||||
*/
|
*/
|
||||||
static void R_FlushBatch ()
|
static void R_FlushBatch ()
|
||||||
{
|
{
|
||||||
if (!(gl_vbo_able && gl_mtexable)) return;
|
|
||||||
|
|
||||||
if (num_vbo_indices > 0)
|
if (num_vbo_indices > 0)
|
||||||
{
|
{
|
||||||
glDrawElements (GL_TRIANGLES, num_vbo_indices, GL_UNSIGNED_INT, vbo_indices);
|
glDrawElements (GL_TRIANGLES, num_vbo_indices, GL_UNSIGNED_INT, vbo_indices);
|
||||||
|
@ -510,12 +483,6 @@ static void R_BatchSurface (msurface_t *s)
|
||||||
{
|
{
|
||||||
int num_surf_indices;
|
int num_surf_indices;
|
||||||
|
|
||||||
if (!(gl_vbo_able && gl_mtexable))
|
|
||||||
{
|
|
||||||
R_MultitexturedDrawGLPoly (s->polys);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_surf_indices = R_NumTriangleIndicesForSurf (s);
|
num_surf_indices = R_NumTriangleIndicesForSurf (s);
|
||||||
|
|
||||||
if (num_vbo_indices + num_surf_indices > MAX_BATCH_SIZE)
|
if (num_vbo_indices + num_surf_indices > MAX_BATCH_SIZE)
|
||||||
|
@ -532,11 +499,11 @@ R_DrawTextureChains_Multitexture -- johnfitz
|
||||||
*/
|
*/
|
||||||
void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_t chain)
|
void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_t chain)
|
||||||
{
|
{
|
||||||
int i;
|
int i, j;
|
||||||
msurface_t *s;
|
msurface_t *s;
|
||||||
texture_t *t;
|
texture_t *t;
|
||||||
|
float *v;
|
||||||
qboolean bound;
|
qboolean bound;
|
||||||
int lastlightmap;
|
|
||||||
|
|
||||||
for (i=0 ; i<model->numtextures ; i++)
|
for (i=0 ; i<model->numtextures ; i++)
|
||||||
{
|
{
|
||||||
|
@ -545,10 +512,7 @@ void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_
|
||||||
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTILED | SURF_NOTEXTURE))
|
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTILED | SURF_NOTEXTURE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
R_ClearBatch ();
|
|
||||||
|
|
||||||
bound = false;
|
bound = false;
|
||||||
lastlightmap = 0; // avoid compiler warning
|
|
||||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||||
if (!s->culled)
|
if (!s->culled)
|
||||||
{
|
{
|
||||||
|
@ -561,22 +525,20 @@ void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_
|
||||||
|
|
||||||
GL_EnableMultitexture(); // selects TEXTURE1
|
GL_EnableMultitexture(); // selects TEXTURE1
|
||||||
bound = true;
|
bound = true;
|
||||||
lastlightmap = s->lightmaptexturenum;
|
|
||||||
}
|
}
|
||||||
R_RenderDynamicLightmaps (s);
|
R_RenderDynamicLightmaps (s);
|
||||||
|
|
||||||
if (s->lightmaptexturenum != lastlightmap)
|
|
||||||
R_FlushBatch ();
|
|
||||||
|
|
||||||
GL_Bind (lightmap_textures[s->lightmaptexturenum]);
|
GL_Bind (lightmap_textures[s->lightmaptexturenum]);
|
||||||
lastlightmap = s->lightmaptexturenum;
|
glBegin(GL_POLYGON);
|
||||||
R_BatchSurface (s);
|
v = s->polys->verts[0];
|
||||||
|
for (j=0 ; j<s->polys->numverts ; j++, v+= VERTEXSIZE)
|
||||||
|
{
|
||||||
|
GL_MTexCoord2fFunc (GL_TEXTURE0_ARB, v[3], v[4]);
|
||||||
|
GL_MTexCoord2fFunc (GL_TEXTURE1_ARB, v[5], v[6]);
|
||||||
|
glVertex3fv (v);
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
rs_brushpasses++;
|
rs_brushpasses++;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_FlushBatch ();
|
|
||||||
|
|
||||||
GL_DisableMultitexture(); // selects TEXTURE0
|
GL_DisableMultitexture(); // selects TEXTURE0
|
||||||
|
|
||||||
if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||||
|
@ -807,6 +769,103 @@ void R_DrawLightmapChains (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
R_DrawTextureChains_Multitexture_VBO -- ericw
|
||||||
|
|
||||||
|
Draw lightmapped surfaces with fulbrights in one pass, using VBO.
|
||||||
|
Requires 3 TMUs, GL_COMBINE_EXT, and GL_ADD.
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void R_DrawTextureChains_Multitexture_VBO (qmodel_t *model, entity_t *ent, texchain_t chain)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
msurface_t *s;
|
||||||
|
texture_t *t;
|
||||||
|
qboolean bound;
|
||||||
|
int lastlightmap;
|
||||||
|
gltexture_t *fullbright = NULL;
|
||||||
|
|
||||||
|
// Setup TMU 1 (lightmap)
|
||||||
|
GL_SelectTexture (GL_TEXTURE1_ARB);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, gl_overbright.value ? 2.0f : 1.0f);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
// Setup TMU 2 (fullbrights)
|
||||||
|
GL_SelectTexture (GL_TEXTURE2_ARB);
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
|
||||||
|
|
||||||
|
for (i=0 ; i<model->numtextures ; i++)
|
||||||
|
{
|
||||||
|
t = model->textures[i];
|
||||||
|
|
||||||
|
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTILED | SURF_NOTEXTURE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Enable/disable TMU 2 (fullbrights)
|
||||||
|
GL_SelectTexture (GL_TEXTURE2_ARB);
|
||||||
|
if (gl_fullbrights.value && (fullbright = R_TextureAnimation(t, ent != NULL ? ent->frame : 0)->fullbright))
|
||||||
|
{
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
GL_Bind (fullbright);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
R_ClearBatch ();
|
||||||
|
|
||||||
|
bound = false;
|
||||||
|
lastlightmap = 0; // avoid compiler warning
|
||||||
|
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||||
|
if (!s->culled)
|
||||||
|
{
|
||||||
|
if (!bound) //only bind once we are sure we need this texture
|
||||||
|
{
|
||||||
|
GL_SelectTexture (GL_TEXTURE0_ARB);
|
||||||
|
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
|
||||||
|
|
||||||
|
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||||
|
glEnable (GL_ALPHA_TEST); // Flip alpha test back on
|
||||||
|
|
||||||
|
bound = true;
|
||||||
|
lastlightmap = s->lightmaptexturenum;
|
||||||
|
}
|
||||||
|
R_RenderDynamicLightmaps (s);
|
||||||
|
|
||||||
|
if (s->lightmaptexturenum != lastlightmap)
|
||||||
|
R_FlushBatch ();
|
||||||
|
|
||||||
|
GL_SelectTexture (GL_TEXTURE1_ARB);
|
||||||
|
GL_Bind (lightmap_textures[s->lightmaptexturenum]);
|
||||||
|
lastlightmap = s->lightmaptexturenum;
|
||||||
|
R_BatchSurface (s);
|
||||||
|
|
||||||
|
rs_brushpasses++;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_FlushBatch ();
|
||||||
|
|
||||||
|
if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE)
|
||||||
|
glDisable (GL_ALPHA_TEST); // Flip alpha test back off
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset TMU states
|
||||||
|
GL_SelectTexture (GL_TEXTURE2_ARB);
|
||||||
|
glDisable (GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
GL_SelectTexture (GL_TEXTURE1_ARB);
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
glDisable (GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
GL_SelectTexture (GL_TEXTURE0_ARB);
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
R_DrawWorld -- johnfitz -- rewritten
|
R_DrawWorld -- johnfitz -- rewritten
|
||||||
|
@ -859,6 +918,13 @@ void R_DrawTextureChains (qmodel_t *model, entity_t *ent, texchain_t chain)
|
||||||
|
|
||||||
R_DrawTextureChains_NoTexture (model, chain);
|
R_DrawTextureChains_NoTexture (model, chain);
|
||||||
|
|
||||||
|
if (gl_vbo_able && gl_texture_env_combine && gl_texture_env_add && gl_mtexable && gl_max_texture_units >= 3)
|
||||||
|
{
|
||||||
|
R_DrawTextureChains_Multitexture_VBO (model, ent, chain);
|
||||||
|
R_EndTransparentDrawing (entalpha);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (gl_overbright.value)
|
if (gl_overbright.value)
|
||||||
{
|
{
|
||||||
if (gl_texture_env_combine && gl_mtexable) //case 1: texture and lightmap in one pass, overbright using texture combiners
|
if (gl_texture_env_combine && gl_mtexable) //case 1: texture and lightmap in one pass, overbright using texture combiners
|
||||||
|
|
Loading…
Reference in New Issue