mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-03-14 06:43:27 +00:00
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+ssh://svn.code.sf.net/p/quakespasm/code/trunk@1035 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
parent
dea5f4274c
commit
960676cef8
6 changed files with 136 additions and 73 deletions
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -1409,27 +1410,12 @@ qboolean mtexenabled = false;
|
|||
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)
|
||||
return;
|
||||
|
||||
|
||||
GL_SelectTextureFunc(target);
|
||||
|
||||
if (target == GL_TEXTURE0_ARB)
|
||||
{
|
||||
ct1 = currenttexture;
|
||||
currenttexture = ct0;
|
||||
}
|
||||
else //target == GL_TEXTURE1_ARB
|
||||
{
|
||||
ct0 = currenttexture;
|
||||
currenttexture = ct1;
|
||||
}
|
||||
|
||||
currenttarget = target;
|
||||
}
|
||||
|
||||
|
@ -1473,10 +1459,10 @@ void GL_Bind (gltexture_t *texture)
|
|||
if (!texture)
|
||||
texture = nulltexture;
|
||||
|
||||
if (texture->texnum != currenttexture)
|
||||
if (texture->texnum != currenttexture[currenttarget - GL_TEXTURE0_ARB])
|
||||
{
|
||||
currenttexture = texture->texnum;
|
||||
glBindTexture (GL_TEXTURE_2D, currenttexture);
|
||||
currenttexture[currenttarget - GL_TEXTURE0_ARB] = texture->texnum;
|
||||
glBindTexture (GL_TEXTURE_2D, texture->texnum);
|
||||
texture->visframe = r_framecount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ int TexMgr_PadConditional (int s);
|
|||
|
||||
// TEXTURE BINDING & TEXTURE UNIT SWITCHING
|
||||
|
||||
void GL_SelectTexture (GLenum target);
|
||||
void GL_DisableMultitexture (void); //selects texture unit 0
|
||||
void GL_EnableMultitexture (void); //selects texture unit 1
|
||||
void GL_Bind (gltexture_t *texture);
|
||||
|
|
|
@ -93,6 +93,7 @@ qboolean gl_anisotropy_able = false; //johnfitz
|
|||
float gl_max_anisotropy; //johnfitz
|
||||
qboolean gl_texture_NPOT = false; //ericw
|
||||
qboolean gl_vbo_able = false; //ericw
|
||||
GLint gl_max_texture_units = 0; //ericw
|
||||
|
||||
PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc = NULL; //johnfitz
|
||||
PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc = NULL; //johnfitz
|
||||
|
@ -831,6 +832,9 @@ static void GL_CheckExtensions (void)
|
|||
{
|
||||
Con_Printf("FOUND: ARB_multitexture\n");
|
||||
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
|
||||
{
|
||||
|
|
|
@ -155,6 +155,7 @@ extern qboolean gl_mtexable;
|
|||
extern PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc;
|
||||
extern PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc;
|
||||
extern PFNGLCLIENTACTIVETEXTUREARBPROC GL_ClientActiveTextureFunc;
|
||||
extern GLint gl_max_texture_units; //ericw
|
||||
|
||||
//johnfitz -- anisotropic filtering
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
|
|
|
@ -975,7 +975,7 @@ void GL_BuildVBOs (void)
|
|||
qmodel_t *m;
|
||||
float *varray;
|
||||
|
||||
if (!(gl_vbo_able && gl_mtexable))
|
||||
if (!(gl_vbo_able && gl_mtexable && gl_max_texture_units >= 3))
|
||||
return;
|
||||
|
||||
// ask GL for a name for our VBO
|
||||
|
@ -1024,7 +1024,7 @@ void GL_BuildVBOs (void)
|
|||
// setup vertex array. this will need to move if we use vertex arrays for other things
|
||||
glVertexPointer (3, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0));
|
||||
glEnableClientState (GL_VERTEX_ARRAY);
|
||||
|
||||
|
||||
GL_ClientActiveTextureFunc (GL_TEXTURE0_ARB);
|
||||
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 3);
|
||||
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
||||
|
@ -1032,6 +1032,11 @@ void GL_BuildVBOs (void)
|
|||
GL_ClientActiveTextureFunc (GL_TEXTURE1_ARB);
|
||||
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 5);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
return 3 * (s->numedges - 2);
|
||||
|
@ -475,8 +452,6 @@ R_ClearBatch
|
|||
*/
|
||||
static void R_ClearBatch ()
|
||||
{
|
||||
if (!(gl_vbo_able && gl_mtexable)) return;
|
||||
|
||||
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 ()
|
||||
{
|
||||
if (!(gl_vbo_able && gl_mtexable)) return;
|
||||
|
||||
if (num_vbo_indices > 0)
|
||||
{
|
||||
glDrawElements (GL_TRIANGLES, num_vbo_indices, GL_UNSIGNED_INT, vbo_indices);
|
||||
|
@ -509,13 +482,7 @@ using VBOs.
|
|||
static void R_BatchSurface (msurface_t *s)
|
||||
{
|
||||
int num_surf_indices;
|
||||
|
||||
if (!(gl_vbo_able && gl_mtexable))
|
||||
{
|
||||
R_MultitexturedDrawGLPoly (s->polys);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
num_surf_indices = R_NumTriangleIndicesForSurf (s);
|
||||
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
msurface_t *s;
|
||||
texture_t *t;
|
||||
float *v;
|
||||
qboolean bound;
|
||||
int lastlightmap;
|
||||
|
||||
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))
|
||||
continue;
|
||||
|
||||
R_ClearBatch ();
|
||||
|
||||
bound = false;
|
||||
lastlightmap = 0; // avoid compiler warning
|
||||
for (s = t->texturechains[chain]; s; s = s->texturechain)
|
||||
if (!s->culled)
|
||||
{
|
||||
|
@ -561,22 +525,20 @@ void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_
|
|||
|
||||
GL_EnableMultitexture(); // selects TEXTURE1
|
||||
bound = true;
|
||||
lastlightmap = s->lightmaptexturenum;
|
||||
}
|
||||
R_RenderDynamicLightmaps (s);
|
||||
|
||||
if (s->lightmaptexturenum != lastlightmap)
|
||||
R_FlushBatch ();
|
||||
|
||||
GL_Bind (lightmap_textures[s->lightmaptexturenum]);
|
||||
lastlightmap = s->lightmaptexturenum;
|
||||
R_BatchSurface (s);
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
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++;
|
||||
}
|
||||
|
||||
R_FlushBatch ();
|
||||
|
||||
GL_DisableMultitexture(); // selects TEXTURE0
|
||||
|
||||
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
|
||||
|
@ -859,6 +918,13 @@ void R_DrawTextureChains (qmodel_t *model, entity_t *ent, texchain_t 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_texture_env_combine && gl_mtexable) //case 1: texture and lightmap in one pass, overbright using texture combiners
|
||||
|
|
Loading…
Reference in a new issue