Rewrote multitexture rendering. (faster, no fullbright bugs)

This commit is contained in:
Forest Hale 2000-07-04 09:29:56 +00:00
parent d24e28f28b
commit 54648f9a93
6 changed files with 136 additions and 422 deletions

View file

@ -998,8 +998,6 @@ void GL_Set2D (void)
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity (); glLoadIdentity ();
GL_DisableMultitexture ();
glEnable (GL_BLEND); glEnable (GL_BLEND);
glDisable (GL_DEPTH_TEST); glDisable (GL_DEPTH_TEST);
glDisable (GL_CULL_FACE); glDisable (GL_CULL_FACE);
@ -1474,13 +1472,3 @@ int GL_LoadPicTexture (qpic_t *pic)
{ {
return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true, 1); return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true, 1);
} }
/****************************************/
void GL_SelectTexture (GLenum target)
{
if (!gl_mtexable)
return;
qglSelectTexture (target + gl_mtex_enum);
}

View file

@ -519,9 +519,8 @@ void R_DrawParticles (void)
qboolean alphaTestEnabled; qboolean alphaTestEnabled;
glBindTexture (GL_TEXTURE_2D, particletexture); glBindTexture (GL_TEXTURE_2D, particletexture);
// LordHavoc: reset to single texture and modulate mode before drawing particles // LordHavoc: particles should not affect zbuffer
GL_DisableMultitexture(); glDepthMask(0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
alphaTestEnabled = glIsEnabled(GL_ALPHA_TEST); alphaTestEnabled = glIsEnabled(GL_ALPHA_TEST);
if (alphaTestEnabled) if (alphaTestEnabled)
@ -655,6 +654,7 @@ void R_DrawParticles (void)
glEnd (); glEnd ();
if (alphaTestEnabled) if (alphaTestEnabled)
glEnable(GL_ALPHA_TEST); glEnable(GL_ALPHA_TEST);
glDepthMask(1);
} }
/* /*

View file

@ -299,8 +299,6 @@ void R_DrawSpriteModel (entity_t *e)
else else
glColor4f(1,1,1,1); glColor4f(1,1,1,1);
GL_DisableMultitexture();
glBindTexture (GL_TEXTURE_2D, frame->gl_texturenum); glBindTexture (GL_TEXTURE_2D, frame->gl_texturenum);
glEnable (GL_ALPHA_TEST); glEnable (GL_ALPHA_TEST);
@ -620,8 +618,6 @@ void R_DrawAliasModel (entity_t *e)
// draw all the triangles // draw all the triangles
// //
GL_DisableMultitexture();
glPushMatrix (); glPushMatrix ();
R_RotateForEntity (e); R_RotateForEntity (e);
@ -968,8 +964,6 @@ void R_RenderScene (void)
R_DrawEntitiesOnList (); R_DrawEntitiesOnList ();
GL_DisableMultitexture();
R_RenderDlights (); R_RenderDlights ();
R_UpdateFires (); R_UpdateFires ();
R_DrawParticles (); R_DrawParticles ();

View file

@ -309,8 +309,6 @@ void R_TranslatePlayerSkin (int playernum)
extern byte player_8bit_texels[320*200]; extern byte player_8bit_texels[320*200];
char s[512]; char s[512];
GL_DisableMultitexture();
player = &cl.players[playernum]; player = &cl.players[playernum];
if (!player->name[0]) if (!player->name[0])
return; return;

View file

@ -93,12 +93,8 @@ int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH];
// LordHavoc: changed to be allocated at runtime (typically lower memory usage) // LordHavoc: changed to be allocated at runtime (typically lower memory usage)
byte *lightmaps[MAX_LIGHTMAPS]; byte *lightmaps[MAX_LIGHTMAPS];
// For gl_texsort 0
msurface_t *skychain = NULL;
msurface_t *waterchain = NULL; msurface_t *waterchain = NULL;
void R_RenderDynamicLightmaps (msurface_t *fa);
extern qboolean lighthalf; extern qboolean lighthalf;
// LordHavoc: place for gl_rsurf setup code // LordHavoc: place for gl_rsurf setup code
@ -380,7 +376,7 @@ Returns the proper texture for a given time and base texture
*/ */
texture_t *R_TextureAnimation (texture_t *base) texture_t *R_TextureAnimation (texture_t *base)
{ {
int reletive; int relative;
int count; int count;
if (currententity->frame) if (currententity->frame)
@ -392,10 +388,10 @@ texture_t *R_TextureAnimation (texture_t *base)
if (!base->anim_total) if (!base->anim_total)
return base; return base;
reletive = (int)(cl.time*10) % base->anim_total; relative = (int)(cl.time*10) % base->anim_total;
count = 0; count = 0;
while (base->anim_min > reletive || base->anim_max <= reletive) while (base->anim_min > relative || base->anim_max <= relative)
{ {
base = base->anim_next; base = base->anim_next;
if (!base) if (!base)
@ -424,42 +420,9 @@ extern float speedscale; // for top sky and bottom sky
lpMTexFUNC qglMTexCoord2f = NULL; lpMTexFUNC qglMTexCoord2f = NULL;
lpSelTexFUNC qglSelectTexture = NULL; lpSelTexFUNC qglSelectTexture = NULL;
qboolean mtexenabled = false; void GL_UploadLightmap(int i, int x, int y, int w, int h)
void GL_SelectTexture (GLenum target);
void GL_DisableMultitexture(void)
{ {
if (mtexenabled) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, BLOCK_WIDTH, h, gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps[i] + (y * BLOCK_WIDTH) * lightmap_bytes);
{
glDisable(GL_TEXTURE_2D);
GL_SelectTexture(0);
mtexenabled = false;
}
}
void GL_EnableMultitexture(void)
{
if (gl_mtexable)
{
GL_SelectTexture(1);
glEnable(GL_TEXTURE_2D);
mtexenabled = true;
}
}
void GL_UploadLightmap(int i)
{
glRect_t *theRect;
lightmap_modified[i] = false;
theRect = &lightmap_rectchange[i];
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
lightmaps[i] + (theRect->t * BLOCK_WIDTH) * lightmap_bytes);
theRect->l = BLOCK_WIDTH;
theRect->t = BLOCK_HEIGHT;
theRect->h = 0;
theRect->w = 0;
} }
/* /*
@ -470,170 +433,54 @@ Systems that have fast state and texture changes can
just do everything as it passes with no need to sort just do everything as it passes with no need to sort
================ ================
*/ */
void R_DrawWorldSequentialPoly (msurface_t *s) void R_DrawMultitexturePoly (msurface_t *s)
{ {
glpoly_t *p; int maps;
float *v; float *v;
int i; int i;
texture_t *t;
// normal lightmaped poly c_brush_polys++;
R_RenderDynamicLightmaps (s);
p = s->polys;
t = R_TextureAnimation (s->texinfo->texture);
if (gl_mtexable)
{
// Binds world to texture env 0
GL_SelectTexture(0);
glBindTexture (GL_TEXTURE_2D, t->gl_texturenum);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Binds lightmap to texenv 1
GL_EnableMultitexture(); // Same as SelectTexture (TEXTURE1)
glBindTexture (GL_TEXTURE_2D, lightmap_textures + s->lightmaptexturenum);
i = s->lightmaptexturenum; i = s->lightmaptexturenum;
if (lightmap_modified[i])
GL_UploadLightmap(i); // Binds world to texture env 0
qglSelectTexture (gl_mtex_enum+0);
glBindTexture (GL_TEXTURE_2D, R_TextureAnimation (s->texinfo->texture)->gl_texturenum);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Binds lightmap to texenv 1
qglSelectTexture (gl_mtex_enum+1);
glBindTexture (GL_TEXTURE_2D, lightmap_textures + i);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_2D);
// check for lightmap modification
if (r_dynamic->value)
{
for (maps = 0;maps < MAXLIGHTMAPS && s->styles[maps] != 255;maps++)
if (d_lightstylevalue[s->styles[maps]] != s->cached_light[maps])
goto dynamic;
if (s->dlightframe == r_framecount // dynamic this frame
|| s->cached_dlight) // dynamic previously
{
dynamic:
R_BuildLightMap (s, lightmaps[s->lightmaptexturenum] + (s->light_t * BLOCK_WIDTH + s->light_s) * lightmap_bytes, BLOCK_WIDTH*lightmap_bytes);
GL_UploadLightmap(i, s->light_s, s->light_t, (s->extents[0]>>4)+1, (s->extents[1]>>4)+1);
}
}
glBegin(GL_POLYGON); glBegin(GL_POLYGON);
v = p->verts[0]; v = s->polys->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE) for (i=0 ; i<s->polys->numverts ; i++, v+= VERTEXSIZE)
{ {
qglMTexCoord2f (gl_mtex_enum + 0, v[3], v[4]); qglMTexCoord2f (gl_mtex_enum + 0, v[3], v[4]);
qglMTexCoord2f (gl_mtex_enum + 1, v[5], v[6]); qglMTexCoord2f (gl_mtex_enum + 1, v[5], v[6]);
glVertex3fv (v); glVertex3fv (v);
} }
}
else
{
glBindTexture (GL_TEXTURE_2D, t->gl_texturenum);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin (GL_POLYGON);
v = p->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
{
glTexCoord2fv (&v[3]);
glVertex3fv (v);
}
glEnd (); glEnd ();
glDisable(GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, lightmap_textures + s->lightmaptexturenum); qglSelectTexture (gl_mtex_enum+0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
glEnable(GL_BLEND);
glBegin (GL_POLYGON);
v = p->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
{
glTexCoord2fv (&v[5]);
glVertex3fv (v);
} }
glDisable(GL_BLEND);
}
glEnd ();
}
void R_DrawModelSequentialPoly (msurface_t *s)
{
glpoly_t *p;
float *v;
int i;
texture_t *t;
//
// normal lightmaped poly
//
if (!(s->flags & (SURF_DRAWSKY|SURF_DRAWTURB)))
{
R_RenderDynamicLightmaps (s);
p = s->polys;
t = R_TextureAnimation (s->texinfo->texture);
if (gl_mtexable)
{
// Binds world to texture env 0
GL_SelectTexture(0);
glBindTexture (GL_TEXTURE_2D, t->gl_texturenum);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Binds lightmap to texenv 1
GL_EnableMultitexture(); // Same as SelectTexture (TEXTURE1)
glBindTexture (GL_TEXTURE_2D, lightmap_textures + s->lightmaptexturenum);
i = s->lightmaptexturenum;
if (lightmap_modified[i])
GL_UploadLightmap(i);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBegin(GL_POLYGON);
v = p->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
{
qglMTexCoord2f (gl_mtex_enum + 0, v[3], v[4]);
qglMTexCoord2f (gl_mtex_enum + 1, v[5], v[6]);
glVertex3fv (v);
}
}
else
{
glBindTexture (GL_TEXTURE_2D, t->gl_texturenum);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin (GL_POLYGON);
v = p->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
{
glTexCoord2fv (&v[3]);
glVertex3fv (v);
}
glEnd ();
glBindTexture (GL_TEXTURE_2D, lightmap_textures + s->lightmaptexturenum);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
glEnable(GL_BLEND);
glBegin (GL_POLYGON);
v = p->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
{
glTexCoord2fv (&v[5]);
glVertex3fv (v);
}
glDisable(GL_BLEND);
}
glEnd ();
return;
}
//
// subdivided water surface warp
//
if (s->flags & SURF_DRAWTURB)
{
EmitWaterPolys (s);
return;
}
}
/*
================
DrawGLPoly
================
*/
void DrawGLPoly (glpoly_t *p)
{
int i;
float *v;
glBegin (GL_POLYGON);
v = p->verts[0];
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
{
glTexCoord2fv (&v[3]);
glVertex3fv (v);
}
glEnd ();
}
/* /*
================ ================
@ -646,9 +493,6 @@ void R_BlendLightmaps (void)
glpoly_t *p; glpoly_t *p;
float *v; float *v;
if (!gl_texsort->value)
return;
glDepthMask (0); // don't bother writing Z glDepthMask (0); // don't bother writing Z
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
@ -662,7 +506,10 @@ void R_BlendLightmaps (void)
continue; continue;
glBindTexture (GL_TEXTURE_2D, lightmap_textures+i); glBindTexture (GL_TEXTURE_2D, lightmap_textures+i);
if (lightmap_modified[i]) if (lightmap_modified[i])
GL_UploadLightmap(i); {
GL_UploadLightmap(i, lightmap_rectchange[i].l, lightmap_rectchange[i].t, lightmap_rectchange[i].w, lightmap_rectchange[i].h);
lightmap_modified[i] = false;
}
for (;p;p = p->chain) for (;p;p = p->chain)
{ {
glBegin (GL_POLYGON); glBegin (GL_POLYGON);
@ -689,31 +536,25 @@ R_RenderBrushPoly
*/ */
void R_RenderBrushPoly (msurface_t *fa) void R_RenderBrushPoly (msurface_t *fa)
{ {
texture_t *t;
byte *base; byte *base;
int maps; int maps;
glRect_t *theRect; glRect_t *theRect;
int i;
float *v;
int smax, tmax; int smax, tmax;
c_brush_polys++; c_brush_polys++;
if (fa->flags & SURF_DRAWSKY) glBindTexture (GL_TEXTURE_2D, R_TextureAnimation (fa->texinfo->texture)->gl_texturenum);
{ // warp texture, no lightmaps
// EmitBothSkyLayers (fa); glBegin (GL_POLYGON);
return; v = fa->polys->verts[0];
for (i = 0;i < fa->polys->numverts;i++, v += VERTEXSIZE)
{
glTexCoord2fv (&v[3]);
glVertex3fv (v);
} }
glEnd ();
t = R_TextureAnimation (fa->texinfo->texture);
glBindTexture (GL_TEXTURE_2D, t->gl_texturenum);
if (fa->flags & SURF_DRAWTURB)
{ // warp texture, no lightmaps
EmitWaterPolys (fa);
return;
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
DrawGLPoly (fa->polys);
// add the poly to the proper lightmap chain // add the poly to the proper lightmap chain
@ -750,92 +591,29 @@ dynamic:
theRect->w = (fa->light_s-theRect->l)+smax; theRect->w = (fa->light_s-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t + tmax)) if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax; theRect->h = (fa->light_t-theRect->t)+tmax;
if (lightmap_bytes==3) { base = lightmaps[fa->lightmaptexturenum] + (fa->light_t * BLOCK_WIDTH + fa->light_s) * lightmap_bytes;
base = lightmaps[fa->lightmaptexturenum] + (fa->light_t * BLOCK_WIDTH + fa->light_s) * 3; R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes);
R_BuildLightMap (fa, base, BLOCK_WIDTH*3);
} else {
base = lightmaps[fa->lightmaptexturenum] + (fa->light_t * BLOCK_WIDTH + fa->light_s);
R_BuildLightMap (fa, base, BLOCK_WIDTH);
}
} }
} }
} }
/* void GL_WaterSurface(msurface_t *s)
================
R_RenderDynamicLightmaps
Multitexture
================
*/
void R_RenderDynamicLightmaps (msurface_t *fa)
{ {
byte *base; glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
int maps; if (lighthalf)
glRect_t *theRect; glColor4f(0.5,0.5,0.5, r_wateralpha->value);
int smax, tmax; else
glColor4f(1,1,1, r_wateralpha->value);
c_brush_polys++; if (r_wateralpha->value < 1.0)
if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) )
return;
fa->polys->chain = lightmap_polys[fa->lightmaptexturenum];
lightmap_polys[fa->lightmaptexturenum] = fa->polys;
// check for lightmap modification
for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ;
maps++)
if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps])
goto dynamic;
if (fa->dlightframe == r_framecount // dynamic this frame
|| fa->cached_dlight) // dynamic previously
{ {
dynamic: glDepthMask(0);
if (r_dynamic->value) EmitWaterPolys (s);
{ glDepthMask(1);
lightmap_modified[fa->lightmaptexturenum] = true;
theRect = &lightmap_rectchange[fa->lightmaptexturenum];
if (fa->light_t < theRect->t) {
if (theRect->h)
theRect->h += theRect->t - fa->light_t;
theRect->t = fa->light_t;
} }
if (fa->light_s < theRect->l) { else
if (theRect->w) EmitWaterPolys (s);
theRect->w += theRect->l - fa->light_s; glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
theRect->l = fa->light_s;
} }
smax = (fa->extents[0]>>4)+1;
tmax = (fa->extents[1]>>4)+1;
if ((theRect->w + theRect->l) < (fa->light_s + smax))
theRect->w = (fa->light_s-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax;
if (lightmap_bytes==3) {
base = lightmaps[fa->lightmaptexturenum] + (fa->light_t * BLOCK_WIDTH + fa->light_s) * 3;
R_BuildLightMap (fa, base, BLOCK_WIDTH*3);
} else {
base = lightmaps[fa->lightmaptexturenum] + (fa->light_t * BLOCK_WIDTH + fa->light_s);
R_BuildLightMap (fa, base, BLOCK_WIDTH);
}
}
}
}
/*
================
R_MirrorChain
================
*/
void R_MirrorChain (msurface_t *s)
{
if (mirror)
return;
mirror = true;
mirror_plane = s->plane;
}
/* /*
================ ================
@ -846,67 +624,38 @@ void R_DrawWaterSurfaces (void)
{ {
int i; int i;
msurface_t *s; msurface_t *s;
texture_t *t;
if (r_wateralpha->value == 1.0 && gl_texsort->value) if (!waterchain)
return; return;
//
// go back to the world matrix // go back to the world matrix
//
glLoadMatrixf (r_world_matrix); glLoadMatrixf (r_world_matrix);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
if (lighthalf) if (lighthalf)
glColor4f(0.5,0.5,0.5, r_wateralpha->value); glColor4f(0.5,0.5,0.5, r_wateralpha->value);
else else
glColor4f(1,1,1, r_wateralpha->value); glColor4f(1,1,1, r_wateralpha->value);
if (r_wateralpha->value < 1.0) if (r_wateralpha->value < 1.0)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDepthMask(0);
else
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
if (!gl_texsort->value)
{
if (!waterchain)
return;
i = -1;
for (s = waterchain;s;s = s->texturechain) for (s = waterchain;s;s = s->texturechain)
{ {
glBindTexture (GL_TEXTURE_2D, s->texinfo->texture->gl_texturenum); if (i != s->texinfo->texture->gl_texturenum)
{
i = s->texinfo->texture->gl_texturenum;
glBindTexture (GL_TEXTURE_2D, i);
}
EmitWaterPolys (s); EmitWaterPolys (s);
} }
waterchain = NULL; waterchain = NULL;
}
else
{
for (i=0 ; i<cl.worldmodel->numtextures ; i++)
{
t = cl.worldmodel->textures[i];
if (!t)
continue;
s = t->texturechain;
if (!s)
continue;
if ( !(s->flags & SURF_DRAWTURB ) )
continue;
// set modulate mode explicitly
glBindTexture (GL_TEXTURE_2D, t->gl_texturenum);
for ( ; s ; s=s->texturechain)
EmitWaterPolys (s);
t->texturechain = NULL;
}
}
glColor3f(1,1,1); glColor3f(1,1,1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (r_wateralpha->value < 1.0)
glDepthMask(1);
} }
@ -919,43 +668,15 @@ void DrawTextureChains (void)
{ {
int i; int i;
msurface_t *s; msurface_t *s;
texture_t *t;
if (!gl_texsort->value) {
GL_DisableMultitexture();
if (skychain)
{
skychain = NULL;
}
return;
}
for (i=0 ; i<cl.worldmodel->numtextures ; i++) for (i=0 ; i<cl.worldmodel->numtextures ; i++)
{ {
t = cl.worldmodel->textures[i]; if (!cl.worldmodel->textures[i])
if (!t)
continue; continue;
s = t->texturechain; for (s = cl.worldmodel->textures[i]->texturechain;s;s = s->texturechain)
if (!s)
continue;
/* if (i == skytexturenum)
R_DrawSkyChain (s);
else*/ if (i == mirrortexturenum && r_mirroralpha->value != 1.0)
{
R_MirrorChain (s);
continue;
}
else
{
if ((s->flags & SURF_DRAWTURB) && r_wateralpha->value != 1.0)
continue; // draw translucent water later
for ( ; s ; s=s->texturechain)
R_RenderBrushPoly (s); R_RenderBrushPoly (s);
}
t->texturechain = NULL; cl.worldmodel->textures[i]->texturechain = NULL;
} }
} }
@ -1039,11 +760,20 @@ void R_DrawBrushModel (entity_t *e)
R_RotateForEntity (e); R_RotateForEntity (e);
e->angles[0] = -e->angles[0]; // stupid quake bug e->angles[0] = -e->angles[0]; // stupid quake bug
// LordHavoc: anyone without multitexture won't want texsort 0 anyway...
if (!gl_mtexable)
gl_texsort->value = 1;
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// //
// draw texture // draw texture
// //
for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++) for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++)
{ {
if (psurf->flags & SURF_DRAWSKY)
return;
// find which side of the node we are on // find which side of the node we are on
pplane = psurf->plane; pplane = psurf->plane;
@ -1053,14 +783,18 @@ void R_DrawBrushModel (entity_t *e)
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{ {
if (gl_texsort->value) if (psurf->flags & SURF_DRAWTURB)
GL_WaterSurface(psurf);
else if (gl_texsort->value)
R_RenderBrushPoly (psurf); R_RenderBrushPoly (psurf);
else else
R_DrawModelSequentialPoly (psurf); R_DrawMultitexturePoly (psurf);
} }
} }
if (gl_texsort->value)
R_BlendLightmaps (); R_BlendLightmaps ();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND); glEnable(GL_BLEND);
@ -1165,22 +899,21 @@ void R_RecursiveWorldNode (mnode_t *node)
if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))
continue; // wrong side continue; // wrong side
// if sorting by texture, just store it out if (surf->flags & SURF_DRAWSKY)
if (gl_texsort->value) { continue;
if (!mirror || surf->texinfo->texture !=
cl.worldmodel->textures[mirrortexturenum]) {
if (surf->flags & SURF_DRAWTURB)
{
surf->texturechain = waterchain;
waterchain = surf;
}
else if (gl_texsort->value)
{
surf->texturechain = surf->texinfo->texture->texturechain; surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf; surf->texinfo->texture->texturechain = surf;
} }
} else if (surf->flags & SURF_DRAWSKY) { else
surf->texturechain = skychain; R_DrawMultitexturePoly (surf);
skychain = surf;
} else if (surf->flags & SURF_DRAWTURB) {
surf->texturechain = waterchain;
waterchain = surf;
} else
R_DrawWorldSequentialPoly (surf);
} }
} }
@ -1209,16 +942,24 @@ void R_DrawWorld (void)
currententity = &ent; currententity = &ent;
// LordHavoc: anyone without multitexture won't want texsort 0 anyway...
if (!gl_mtexable)
gl_texsort->value = 1;
glColor3f (1.0, 1.0, 1.0); glColor3f (1.0, 1.0, 1.0);
memset (lightmap_polys, 0, sizeof(lightmap_polys)); memset (lightmap_polys, 0, sizeof(lightmap_polys));
// Be sure to clear the skybox --KB // Be sure to clear the skybox --KB
R_DrawSky (); R_DrawSky ();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
R_RecursiveWorldNode (cl.worldmodel->nodes); R_RecursiveWorldNode (cl.worldmodel->nodes);
DrawTextureChains (); DrawTextureChains ();
if (gl_texsort->value)
R_BlendLightmaps (); R_BlendLightmaps ();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND); glEnable(GL_BLEND);
@ -1464,13 +1205,8 @@ void GL_CreateSurfaceLightmap (msurface_t *surf)
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>4)+1;
surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t); surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t);
if (lightmap_bytes==3) { base = lightmaps[surf->lightmaptexturenum] + (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes;
base = lightmaps[surf->lightmaptexturenum] + (surf->light_t * BLOCK_WIDTH + surf->light_s) * 3; R_BuildLightMap (surf, base, BLOCK_WIDTH*lightmap_bytes);
R_BuildLightMap (surf, base, BLOCK_WIDTH*3);
} else {
base = lightmaps[surf->lightmaptexturenum] + (surf->light_t * BLOCK_WIDTH + surf->light_s);
R_BuildLightMap (surf, base, BLOCK_WIDTH);
}
} }
@ -1531,8 +1267,8 @@ void GL_BuildLightmaps (void)
} }
} }
if (!gl_texsort->value) if (gl_mtexable && !gl_texsort->value)
GL_SelectTexture(1); qglSelectTexture (gl_mtex_enum+1);
// //
// upload all lightmaps that were filled // upload all lightmaps that were filled
@ -1554,8 +1290,7 @@ void GL_BuildLightmaps (void)
GL_UNSIGNED_BYTE, lightmaps[i]); GL_UNSIGNED_BYTE, lightmaps[i]);
} }
if (!gl_texsort->value) if (gl_mtexable && !gl_texsort->value)
GL_SelectTexture(0); qglSelectTexture (gl_mtex_enum+0);
} }

View file

@ -650,7 +650,6 @@ R_DrawSkyBox (void)
{ {
int i, j; int i, j;
GL_DisableMultitexture ();
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_ALWAYS); glDepthFunc (GL_ALWAYS);
// glDisable (GL_BLEND); // glDisable (GL_BLEND);
@ -732,13 +731,13 @@ R_DrawSkyLayer (float s)
void void
R_DrawSkyDome (void) R_DrawSkyDome (void)
{ {
GL_DisableMultitexture ();
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_ALWAYS); glDepthFunc (GL_ALWAYS);
// glDisable (GL_BLEND); // glDisable (GL_BLEND);
// glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthRange (gldepthmax, gldepthmax); glDepthRange (gldepthmax, gldepthmax);
glDisable (GL_BLEND);
if (lighthalf) if (lighthalf)
glColor3f(0.5,0.5,0.5); glColor3f(0.5,0.5,0.5);
else else