Remove R_DrawSequentialPoly and use texture chains for drawing brush models.

To make this work with the drawing order we use in gl_rmain (world excluding water, opaque ents, world water, transparent ents), I made each texture_t have two texture chains, one for world and one for bmodels. This way they can be cleared during entity drawing without having to regenerate the world ones.

Other than this the changes are mostly minor adjustments to the R_DrawTextureChains_* functions so they can work for things other than the world.

git-svn-id: svn+ssh://svn.code.sf.net/p/quakespasm/code/trunk@979 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
ewasylishen 2014-08-29 08:27:22 +00:00
parent 97e9b4e473
commit 65db1b5a32
6 changed files with 250 additions and 118 deletions

View file

@ -74,6 +74,13 @@ typedef struct mplane_s
byte pad[2];
} mplane_t;
// ericw -- each texture has two chains, so we can clear the model chains
// without affecting the world
typedef enum {
chain_world = 0,
chain_model = 1
} texchain_t;
typedef struct texture_s
{
char name[16];
@ -82,7 +89,7 @@ typedef struct texture_s
struct gltexture_s *fullbright; //johnfitz -- fullbright mask texture
struct gltexture_s *warpimage; //johnfitz -- for water animation
qboolean update_warp; //johnfitz -- update warp this frame
struct msurface_s *texturechain; // for texture chains
struct msurface_s *texturechains[2]; // for texture chains
int anim_total; // total tenths in sequence ( 0 = no)
int anim_min, anim_max; // time for this frame min <=time< max
struct texture_s *anim_next; // in the animation sequence

View file

@ -443,6 +443,10 @@ void R_SetupView (void)
else if (r_lightmap.value) r_lightmap_cheatsafe = true;
}
//johnfitz
// mh dynamic lightmap speedup: upload all modified lightmaps from the last
// frame in a single batch
R_UploadLightmaps ();
}
//==============================================================================
@ -643,7 +647,7 @@ void R_ShowTris (void)
if (r_drawworld.value)
{
R_DrawTextureChains_ShowTris ();
R_DrawWorld_ShowTris ();
}
if (r_drawentities.value)
@ -750,7 +754,7 @@ void R_RenderScene (void)
R_DrawEntitiesOnList (false); //johnfitz -- false means this is the pass for nonalpha entities
R_DrawTextureChains_Water (); //johnfitz -- drawn here since they might have transparency
R_DrawWorld_Water (); //johnfitz -- drawn here since they might have transparency
R_DrawEntitiesOnList (true); //johnfitz -- true means this is the pass for alpha entities

View file

@ -526,10 +526,10 @@ void Sky_ProcessTextureChains (void)
{
t = cl.worldmodel->textures[i];
if (!t || !t->texturechain || !(t->texturechain->flags & SURF_DRAWSKY))
if (!t || !t->texturechains[chain_world] || !(t->texturechains[chain_world]->flags & SURF_DRAWSKY))
continue;
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain_world]; s; s = s->texturechain)
if (!s->culled)
Sky_ProcessPoly (s->polys);
}

View file

@ -275,7 +275,7 @@ void R_DrawAliasModel (entity_t *e);
void R_DrawBrushModel (entity_t *e);
void R_DrawSpriteModel (entity_t *e);
void R_DrawTextureChains_Water (void);
void R_DrawTextureChains_Water (qmodel_t *model, entity_t *ent, texchain_t chain);
void R_RenderDlights (void);
void GL_BuildLightmaps (void);
@ -288,7 +288,7 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride);
void R_RenderDynamicLightmaps (msurface_t *fa);
void R_UploadLightmaps (void);
void R_DrawTextureChains_ShowTris (void);
void R_DrawWorld_ShowTris (void);
void R_DrawBrushModel_ShowTris (entity_t *e);
void R_DrawAliasModel_ShowTris (entity_t *e);
void R_DrawParticles_ShowTris (void);
@ -307,5 +307,10 @@ void Sky_LoadSkyBox (const char *name);
void TexMgr_RecalcWarpImageSize (void);
void R_ClearTextureChains (qmodel_t *mod, texchain_t chain);
void R_ChainSurface (msurface_t *surf, texchain_t chain);
void R_DrawTextureChains (qmodel_t *model, entity_t *ent, texchain_t chain);
void R_DrawWorld_Water (void);
#endif /* __GLQUAKE_H */

View file

@ -133,6 +133,7 @@ void DrawGLTriangleFan (glpoly_t *p)
=============================================================
*/
#if 0
/*
================
R_DrawSequentialPoly -- johnfitz -- rewritten
@ -503,7 +504,7 @@ fullbrights:
rs_brushpasses++;
}
}
#endif
/*
=================
R_DrawBrushModel
@ -570,12 +571,7 @@ void R_DrawBrushModel (entity_t *e)
}
e->angles[0] = -e->angles[0]; // stupid quake bug
//
// draw it
//
if (r_drawflat_cheatsafe) //johnfitz
glDisable(GL_TEXTURE_2D);
R_ClearTextureChains (clmodel, chain_model);
for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++)
{
pplane = psurf->plane;
@ -583,15 +579,13 @@ void R_DrawBrushModel (entity_t *e)
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{
R_DrawSequentialPoly (psurf);
R_ChainSurface (psurf, chain_model);
rs_brushpolys++;
}
}
if (r_drawflat_cheatsafe) //johnfitz
glEnable(GL_TEXTURE_2D);
GL_DisableMultitexture(); // selects TEXTURE0
R_DrawTextureChains (clmodel, e, chain_model);
R_DrawTextureChains_Water (clmodel, e, chain_model);
glPopMatrix ();
}

View file

@ -37,6 +37,38 @@ int vis_changed; //if true, force pvs to be refreshed
//
//==============================================================================
/*
================
R_ClearTextureChains -- ericw
clears texture chains for all textures used by the given model, and also
clears the lightmap chains
================
*/
void R_ClearTextureChains (qmodel_t *mod, texchain_t chain)
{
int i;
// set all chains to null
for (i=0 ; i<mod->numtextures ; i++)
if (mod->textures[i])
mod->textures[i]->texturechains[chain] = NULL;
// clear lightmap chains
memset (lightmap_polys, 0, sizeof(lightmap_polys));
}
/*
================
R_ChainSurface -- ericw -- adds the given surface to its texture chain
================
*/
void R_ChainSurface (msurface_t *surf, texchain_t chain)
{
surf->texturechain = surf->texinfo->texture->texturechains[chain];
surf->texinfo->texture->texturechains[chain] = surf;
}
/*
===============
R_MarkSurfaces -- johnfitz -- mark surfaces based on PVS and rebuild texture chains
@ -103,7 +135,7 @@ void R_MarkSurfaces (void)
// set all chains to null
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
if (cl.worldmodel->textures[i])
cl.worldmodel->textures[i]->texturechain = NULL;
cl.worldmodel->textures[i]->texturechains[chain_world] = NULL;
// rebuild chains
@ -116,8 +148,7 @@ void R_MarkSurfaces (void)
for (j=0, surf=&cl.worldmodel->surfaces[node->firstsurface] ; j<node->numsurfaces ; j++, surf++)
if (surf->visframe == r_visframecount)
{
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
R_ChainSurface(surf, chain_world);
}
#else
//the old way
@ -126,8 +157,7 @@ void R_MarkSurfaces (void)
{
if (surf->visframe == r_visframecount)
{
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
R_ChainSurface(surf, chain_world);
}
}
#endif
@ -200,7 +230,7 @@ void R_CullSurfaces (void)
R_BuildLightmapChains -- johnfitz -- used for r_lightmap 1
================
*/
void R_BuildLightmapChains (void)
void R_BuildLightmapChains (qmodel_t *model)
{
msurface_t *s;
int i;
@ -209,9 +239,9 @@ void R_BuildLightmapChains (void)
memset (lightmap_polys, 0, sizeof(lightmap_polys));
// now rebuild them
s = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface];
for (i=0 ; i<cl.worldmodel->nummodelsurfaces ; i++, s++)
if (s->visframe == r_visframecount && !R_CullBox(s->mins, s->maxs) && !R_BackFaceCull (s))
s = &model->surfaces[model->firstmodelsurface];
for (i=0 ; i<model->nummodelsurfaces ; i++, s++)
if (model != cl.worldmodel || (s->visframe == r_visframecount && !R_CullBox(s->mins, s->maxs) && !R_BackFaceCull (s)))
R_RenderDynamicLightmaps (s);
}
@ -221,27 +251,59 @@ void R_BuildLightmapChains (void)
//
//==============================================================================
/*
=============
R_BeginTransparentDrawing -- ericw
=============
*/
static void R_BeginTransparentDrawing (float entalpha)
{
if (entalpha < 1.0f)
{
glDepthMask (GL_FALSE);
glEnable (GL_BLEND);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor4f (1,1,1,entalpha);
}
}
/*
=============
R_EndTransparentDrawing -- ericw
=============
*/
static void R_EndTransparentDrawing (float entalpha)
{
if (entalpha < 1.0f)
{
glDepthMask (GL_TRUE);
glDisable (GL_BLEND);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor3f (1, 1, 1);
}
}
/*
================
R_DrawTextureChains_ShowTris -- johnfitz
================
*/
void R_DrawTextureChains_ShowTris (void)
void R_DrawTextureChains_ShowTris (qmodel_t *model, texchain_t chain)
{
int i;
msurface_t *s;
texture_t *t;
glpoly_t *p;
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
t = model->textures[i];
if (!t)
continue;
if (r_oldwater.value && t->texturechain && (t->texturechain->flags & SURF_DRAWTURB))
if (r_oldwater.value && t->texturechains[chain] && (t->texturechains[chain]->flags & SURF_DRAWTURB))
{
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain]; s; s = s->texturechain)
if (!s->culled)
for (p = s->polys->next; p; p = p->next)
{
@ -250,7 +312,7 @@ void R_DrawTextureChains_ShowTris (void)
}
else
{
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain]; s; s = s->texturechain)
if (!s->culled)
{
DrawGLTriangleFan (s->polys);
@ -264,22 +326,22 @@ void R_DrawTextureChains_ShowTris (void)
R_DrawTextureChains_Drawflat -- johnfitz
================
*/
void R_DrawTextureChains_Drawflat (void)
void R_DrawTextureChains_Drawflat (qmodel_t *model, texchain_t chain)
{
int i;
msurface_t *s;
texture_t *t;
glpoly_t *p;
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
t = model->textures[i];
if (!t)
continue;
if (r_oldwater.value && t->texturechain && (t->texturechain->flags & SURF_DRAWTURB))
if (r_oldwater.value && t->texturechains[chain] && (t->texturechains[chain]->flags & SURF_DRAWTURB))
{
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain]; s; s = s->texturechain)
if (!s->culled)
for (p = s->polys->next; p; p = p->next)
{
@ -291,7 +353,7 @@ void R_DrawTextureChains_Drawflat (void)
}
else
{
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain]; s; s = s->texturechain)
if (!s->culled)
{
srand((unsigned int) (uintptr_t) s->polys);
@ -310,7 +372,7 @@ void R_DrawTextureChains_Drawflat (void)
R_DrawTextureChains_Glow -- johnfitz
================
*/
void R_DrawTextureChains_Glow (void)
void R_DrawTextureChains_Glow (qmodel_t *model, entity_t *ent, texchain_t chain)
{
int i;
msurface_t *s;
@ -318,16 +380,16 @@ void R_DrawTextureChains_Glow (void)
gltexture_t *glt;
qboolean bound;
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
t = model->textures[i];
if (!t || !t->texturechain || !(glt = R_TextureAnimation(t,0)->fullbright))
if (!t || !t->texturechains[chain] || !(glt = R_TextureAnimation(t, ent != NULL ? ent->frame : 0)->fullbright))
continue;
bound = false;
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain]; s; s = s->texturechain)
if (!s->culled)
{
if (!bound) //only bind once we are sure we need this texture
@ -346,7 +408,7 @@ void R_DrawTextureChains_Glow (void)
R_DrawTextureChains_Multitexture -- johnfitz
================
*/
void R_DrawTextureChains_Multitexture (void)
void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_t chain)
{
int i, j;
msurface_t *s;
@ -354,22 +416,22 @@ void R_DrawTextureChains_Multitexture (void)
float *v;
qboolean bound;
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
t = model->textures[i];
if (!t || !t->texturechain || t->texturechain->flags & (SURF_DRAWTILED | SURF_NOTEXTURE))
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTILED | SURF_NOTEXTURE))
continue;
bound = false;
for (s = t->texturechain; s; s = s->texturechain)
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_Bind ((R_TextureAnimation(t,0))->gltexture);
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
if (t->texturechain->flags & SURF_DRAWFENCE)
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
glEnable (GL_ALPHA_TEST); // Flip alpha test back on
GL_EnableMultitexture(); // selects TEXTURE1
@ -390,7 +452,7 @@ void R_DrawTextureChains_Multitexture (void)
}
GL_DisableMultitexture(); // selects TEXTURE0
if (bound && t->texturechain->flags & SURF_DRAWFENCE)
if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE)
glDisable (GL_ALPHA_TEST); // Flip alpha test back off
}
}
@ -402,23 +464,23 @@ R_DrawTextureChains_NoTexture -- johnfitz
draws surfs whose textures were missing from the BSP
================
*/
void R_DrawTextureChains_NoTexture (void)
void R_DrawTextureChains_NoTexture (qmodel_t *model, texchain_t chain)
{
int i;
msurface_t *s;
texture_t *t;
qboolean bound;
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
t = model->textures[i];
if (!t || !t->texturechain || !(t->texturechain->flags & SURF_NOTEXTURE))
if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_NOTEXTURE))
continue;
bound = false;
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain]; s; s = s->texturechain)
if (!s->culled)
{
if (!bound) //only bind once we are sure we need this texture
@ -437,30 +499,30 @@ void R_DrawTextureChains_NoTexture (void)
R_DrawTextureChains_TextureOnly -- johnfitz
================
*/
void R_DrawTextureChains_TextureOnly (void)
void R_DrawTextureChains_TextureOnly (qmodel_t *model, entity_t *ent, texchain_t chain)
{
int i;
msurface_t *s;
texture_t *t;
qboolean bound;
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
t = model->textures[i];
if (!t || !t->texturechain || t->texturechain->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTURB | SURF_DRAWSKY))
continue;
bound = false;
for (s = t->texturechain; s; s = s->texturechain)
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_Bind ((R_TextureAnimation(t,0))->gltexture);
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
if (t->texturechain->flags & SURF_DRAWFENCE)
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
glEnable (GL_ALPHA_TEST); // Flip alpha test back on
bound = true;
@ -470,7 +532,7 @@ void R_DrawTextureChains_TextureOnly (void)
rs_brushpasses++;
}
if (bound && t->texturechain->flags & SURF_DRAWFENCE)
if (bound && t->texturechains[chain]->flags & SURF_DRAWFENCE)
glDisable (GL_ALPHA_TEST); // Flip alpha test back off
}
}
@ -480,34 +542,34 @@ void R_DrawTextureChains_TextureOnly (void)
R_DrawTextureChains_Water -- johnfitz
================
*/
void R_DrawTextureChains_Water (void)
void R_DrawTextureChains_Water (qmodel_t *model, entity_t *ent, texchain_t chain)
{
int i;
msurface_t *s;
texture_t *t;
glpoly_t *p;
qboolean bound;
float entalpha;
if (r_drawflat_cheatsafe || r_lightmap_cheatsafe || !r_drawworld_cheatsafe)
if (r_drawflat_cheatsafe || r_lightmap_cheatsafe) // ericw -- !r_drawworld_cheatsafe check moved to R_DrawWorld_Water ()
return;
if (r_wateralpha.value < 1.0)
{
glDepthMask(GL_FALSE);
glEnable (GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor4f (1,1,1,r_wateralpha.value);
}
if (ent == NULL || ent->alpha == ENTALPHA_DEFAULT)
entalpha = r_wateralpha.value;
else
entalpha = ENTALPHA_DECODE(ent->alpha);
R_BeginTransparentDrawing (entalpha);
if (r_oldwater.value)
{
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
if (!t || !t->texturechain || !(t->texturechain->flags & SURF_DRAWTURB))
t = model->textures[i];
if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_DRAWTURB))
continue;
bound = false;
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain]; s; s = s->texturechain)
if (!s->culled)
{
if (!bound) //only bind once we are sure we need this texture
@ -525,18 +587,27 @@ void R_DrawTextureChains_Water (void)
}
else
{
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
if (!t || !t->texturechain || !(t->texturechain->flags & SURF_DRAWTURB))
t = model->textures[i];
if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_DRAWTURB))
continue;
bound = false;
for (s = t->texturechain; s; s = s->texturechain)
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_Bind (t->warpimage);
if (model != cl.worldmodel)
{
// ericw -- this is copied from R_DrawSequentialPoly.
// If the poly is not part of the world we have to
// set this flag
t->update_warp = true; // FIXME: one frame too late!
}
bound = true;
}
DrawGLPoly (s->polys);
@ -545,13 +616,7 @@ void R_DrawTextureChains_Water (void)
}
}
if (r_wateralpha.value < 1.0)
{
glDepthMask(GL_TRUE);
glDisable (GL_BLEND);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor3f (1,1,1);
}
R_EndTransparentDrawing (entalpha);
}
/*
@ -559,21 +624,21 @@ void R_DrawTextureChains_Water (void)
R_DrawTextureChains_White -- johnfitz -- draw sky and water as white polys when r_lightmap is 1
================
*/
void R_DrawTextureChains_White (void)
void R_DrawTextureChains_White (qmodel_t *model, texchain_t chain)
{
int i;
msurface_t *s;
texture_t *t;
glDisable (GL_TEXTURE_2D);
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
for (i=0 ; i<model->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
t = model->textures[i];
if (!t || !t->texturechain || !(t->texturechain->flags & SURF_DRAWTILED))
if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_DRAWTILED))
continue;
for (s = t->texturechain; s; s = s->texturechain)
for (s = t->texturechains[chain]; s; s = s->texturechain)
if (!s->culled)
{
DrawGLPoly (s->polys);
@ -620,32 +685,34 @@ void R_DrawLightmapChains (void)
R_DrawWorld -- johnfitz -- rewritten
=============
*/
void R_DrawWorld (void)
void R_DrawTextureChains (qmodel_t *model, entity_t *ent, texchain_t chain)
{
if (!r_drawworld_cheatsafe)
return;
// mh dynamic lightmap speedup: upload all modified lightmaps from the last
// frame in a single batch
R_UploadLightmaps ();
float entalpha;
if (ent != NULL)
entalpha = ENTALPHA_DECODE(ent->alpha);
else
entalpha = 1;
if (r_drawflat_cheatsafe)
{
glDisable (GL_TEXTURE_2D);
R_DrawTextureChains_Drawflat ();
R_DrawTextureChains_Drawflat (model, chain);
glEnable (GL_TEXTURE_2D);
return;
}
if (r_fullbright_cheatsafe)
{
R_DrawTextureChains_TextureOnly ();
R_BeginTransparentDrawing (entalpha);
R_DrawTextureChains_TextureOnly (model, ent, chain);
R_EndTransparentDrawing (entalpha);
goto fullbrights;
}
if (r_lightmap_cheatsafe)
{
R_BuildLightmapChains ();
R_BuildLightmapChains (model);
if (!gl_overbright.value)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
@ -657,15 +724,17 @@ void R_DrawWorld (void)
glColor3f(1,1,1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
R_DrawTextureChains_White ();
R_DrawTextureChains_White (model, chain);
return;
}
R_DrawTextureChains_NoTexture ();
R_BeginTransparentDrawing (entalpha);
R_DrawTextureChains_NoTexture (model, chain);
if (gl_overbright.value)
{
if (gl_texture_env_combine && gl_mtexable)
if (gl_texture_env_combine && gl_mtexable) //case 1: texture and lightmap in one pass, overbright using texture combiners
{
GL_EnableMultitexture ();
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
@ -674,20 +743,24 @@ void R_DrawWorld (void)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);
GL_DisableMultitexture ();
R_DrawTextureChains_Multitexture ();
R_DrawTextureChains_Multitexture (model, ent, chain);
GL_EnableMultitexture ();
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0f);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
GL_DisableMultitexture ();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
else
else if (entalpha < 1) //case 2: can't do multipass if entity has alpha, so just draw the texture
{
R_DrawTextureChains_TextureOnly (model, ent, chain);
}
else //case 3: texture in one pass, lightmap in second pass using 2x modulation blend func, fog in third pass
{
//to make fog work with multipass lightmapping, need to do one pass
//with no fog, one modulate pass with black fog, and one additive
//pass with black geometry and normal fog
Fog_DisableGFog ();
R_DrawTextureChains_TextureOnly ();
R_DrawTextureChains_TextureOnly (model, ent, chain);
Fog_EnableGFog ();
glDepthMask (GL_FALSE);
glEnable (GL_BLEND);
@ -700,7 +773,7 @@ void R_DrawWorld (void)
glBlendFunc(GL_ONE, GL_ONE); //add
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f(0,0,0);
R_DrawTextureChains_TextureOnly ();
R_DrawTextureChains_TextureOnly (model, ent, chain);
glColor3f(1,1,1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
@ -711,21 +784,25 @@ void R_DrawWorld (void)
}
else
{
if (gl_mtexable)
if (gl_mtexable) //case 4: texture and lightmap in one pass, regular modulation
{
GL_EnableMultitexture ();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
GL_DisableMultitexture ();
R_DrawTextureChains_Multitexture ();
R_DrawTextureChains_Multitexture (model, ent, chain);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
else
else if (entalpha < 1) //case 5: can't do multipass if entity has alpha, so just draw the texture
{
R_DrawTextureChains_TextureOnly (model, ent, chain);
}
else //case 6: texture in one pass, lightmap in a second pass, fog in third pass
{
//to make fog work with multipass lightmapping, need to do one pass
//with no fog, one modulate pass with black fog, and one additive
//pass with black geometry and normal fog
Fog_DisableGFog ();
R_DrawTextureChains_TextureOnly ();
R_DrawTextureChains_TextureOnly (model, ent, chain);
Fog_EnableGFog ();
glDepthMask (GL_FALSE);
glEnable (GL_BLEND);
@ -738,7 +815,7 @@ void R_DrawWorld (void)
glBlendFunc(GL_ONE, GL_ONE); //add
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f(0,0,0);
R_DrawTextureChains_TextureOnly ();
R_DrawTextureChains_TextureOnly (model, ent, chain);
glColor3f(1,1,1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
@ -748,17 +825,62 @@ void R_DrawWorld (void)
}
}
R_EndTransparentDrawing (entalpha);
fullbrights:
if (gl_fullbrights.value)
{
glDepthMask (GL_FALSE);
glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f (entalpha, entalpha, entalpha);
Fog_StartAdditive ();
R_DrawTextureChains_Glow ();
R_DrawTextureChains_Glow (model, ent, chain);
Fog_StopAdditive ();
glColor3f (1, 1, 1);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable (GL_BLEND);
glDepthMask (GL_TRUE);
}
}
/*
=============
R_DrawWorld -- ericw -- moved from R_DrawTextureChains, which is no longer specific to the world.
=============
*/
void R_DrawWorld (void)
{
if (!r_drawworld_cheatsafe)
return;
R_DrawTextureChains (cl.worldmodel, NULL, chain_world);
}
/*
=============
R_DrawWorld_Water -- ericw -- moved from R_DrawTextureChains_Water, which is no longer specific to the world.
=============
*/
void R_DrawWorld_Water (void)
{
if (!r_drawworld_cheatsafe)
return;
R_DrawTextureChains_Water (cl.worldmodel, NULL, chain_world);
}
/*
=============
R_DrawWorld_ShowTris -- ericw -- moved from R_DrawTextureChains_ShowTris, which is no longer specific to the world.
=============
*/
void R_DrawWorld_ShowTris (void)
{
if (!r_drawworld_cheatsafe)
return;
R_DrawTextureChains_ShowTris (cl.worldmodel, chain_world);
}