Grievre's lightmap/fullbright multitexture patch (fbs not tested due to

lack of drivers supporting 3 tmus)
This commit is contained in:
Bill Currie 2004-02-14 05:10:29 +00:00
parent c493a82de1
commit 85a268c62f
4 changed files with 175 additions and 51 deletions

View file

@ -39,6 +39,7 @@ extern QF_glMultiTexCoord2fARB qglMultiTexCoord2f;
extern QF_glMultiTexCoord2fvARB qglMultiTexCoord2fv; extern QF_glMultiTexCoord2fvARB qglMultiTexCoord2fv;
extern qboolean gl_mtex_active; extern qboolean gl_mtex_active;
extern qboolean gl_mtex_capable; extern qboolean gl_mtex_capable;
extern qboolean gl_mtex_fullbright;
extern GLenum gl_mtex_enum; extern GLenum gl_mtex_enum;
extern float gldepthmin, gldepthmax; extern float gldepthmin, gldepthmax;
extern int texture_extension_number; extern int texture_extension_number;

View file

@ -282,14 +282,16 @@ R_BuildLightMap_1 (msurface_t *surf)
store: store:
// bound and shift // bound and shift
// Also, invert because we're using a diff blendfunc now
stride = (BLOCK_WIDTH - smax) * lightmap_bytes; stride = (BLOCK_WIDTH - smax) * lightmap_bytes;
bl = blocklights; bl = blocklights;
dest = lightmaps[surf->lightmaptexturenum] dest = lightmaps[surf->lightmaptexturenum]
+ (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes; + (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes;
for (i = 0; i < tmax; i++, dest += stride) { for (i = 0; i < tmax; i++, dest += stride) {
for (j = 0; j < smax; j++) { for (j = smax; j; j--) {
*dest++ = min (*bl >> 8, 255); *dest++ = 255 - min (*bl >> 8, 255);
bl++; bl++;
} }
} }
@ -339,6 +341,7 @@ R_BuildLightMap_3 (msurface_t *surf)
store: store:
// bound and shift // bound and shift
// and invert too
stride = (BLOCK_WIDTH - smax) * lightmap_bytes; stride = (BLOCK_WIDTH - smax) * lightmap_bytes;
bl = blocklights; bl = blocklights;
@ -346,11 +349,11 @@ R_BuildLightMap_3 (msurface_t *surf)
+ (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes; + (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes;
for (i = 0; i < tmax; i++, dest += stride) { for (i = 0; i < tmax; i++, dest += stride) {
for (j = 0; j < smax; j++) { for (j = 0; j < smax; j++) {
*dest++ = min (*bl >> 8, 255); *dest++ = 255 - min (*bl >> 8, 255);
bl++; bl++;
*dest++ = min (*bl >> 8, 255); *dest++ = 255 - min (*bl >> 8, 255);
bl++; bl++;
*dest++ = min (*bl >> 8, 255); *dest++ = 255 - min (*bl >> 8, 255);
bl++; bl++;
} }
} }
@ -400,6 +403,7 @@ R_BuildLightMap_4 (msurface_t *surf)
store: store:
// bound and shift // bound and shift
// and invert too
stride = (BLOCK_WIDTH - smax) * lightmap_bytes; stride = (BLOCK_WIDTH - smax) * lightmap_bytes;
bl = blocklights; bl = blocklights;
@ -407,14 +411,13 @@ R_BuildLightMap_4 (msurface_t *surf)
+ (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes; + (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes;
for (i = 0; i < tmax; i++, dest += stride) { for (i = 0; i < tmax; i++, dest += stride) {
for (j = 0; j < smax; j++) { for (j = 0; j < smax; j++) {
*dest++ = min (*bl >> 8, 255); *dest++ = 255 - min (*bl >> 8, 255);
bl++; bl++;
*dest++ = min (*bl >> 8, 255); *dest++ = 255 - min (*bl >> 8, 255);
bl++; bl++;
*dest++ = min (*bl >> 8, 255); *dest++ = 255 - min (*bl >> 8, 255);
bl++; bl++;
dest++; // `*dest++ = 255;` for RGBA internal format *dest++ = 255;
// instead of RGB
} }
} }
} }
@ -475,7 +478,7 @@ R_BlendLightmaps (void)
glpoly_t *p; glpoly_t *p;
qfglDepthMask (GL_FALSE); // don't bother writing Z qfglDepthMask (GL_FALSE); // don't bother writing Z
qfglBlendFunc (GL_DST_COLOR, GL_SRC_COLOR); qfglBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
for (i = 0; i < MAX_LIGHTMAPS; i++) { for (i = 0; i < MAX_LIGHTMAPS; i++) {
p = lightmap_polys[i]; p = lightmap_polys[i];
@ -506,7 +509,7 @@ R_CalcAndBlendLightmaps (void)
glpoly_t *p; glpoly_t *p;
qfglDepthMask (GL_FALSE); // don't bother writing Z qfglDepthMask (GL_FALSE); // don't bother writing Z
qfglBlendFunc (GL_DST_COLOR, GL_SRC_COLOR); qfglBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
for (i = 0; i < MAX_LIGHTMAPS; i++) { for (i = 0; i < MAX_LIGHTMAPS; i++) {
p = lightmap_polys[i]; p = lightmap_polys[i];
@ -654,11 +657,6 @@ GL_BuildLightmaps (model_t **models, int num_models)
} }
} }
#if 0
if (gl_mtex_active)
qglActiveTexture (gl_mtex_enum + 1);
#endif
// upload all lightmaps that were filled // upload all lightmaps that were filled
for (i = 0; i < MAX_LIGHTMAPS; i++) { for (i = 0; i < MAX_LIGHTMAPS; i++) {
if (!allocated[i][0]) if (!allocated[i][0])
@ -675,9 +673,4 @@ GL_BuildLightmaps (model_t **models, int num_models)
BLOCK_HEIGHT, 0, gl_lightmap_format, BLOCK_HEIGHT, 0, gl_lightmap_format,
GL_UNSIGNED_BYTE, lightmaps[i]); GL_UNSIGNED_BYTE, lightmaps[i]);
} }
#if 0
if (gl_mtex_active)
qglActiveTexture (gl_mtex_enum + 0);
#endif
} }

View file

@ -148,18 +148,38 @@ inline void
R_RenderBrushPoly (msurface_t *fa) R_RenderBrushPoly (msurface_t *fa)
{ {
float *v; float *v;
int maps, smax, tmax, i; int i;
glRect_t *theRect;
c_brush_polys++; c_brush_polys++;
qfglBegin (GL_POLYGON); qfglBegin (GL_POLYGON);
v = fa->polys->verts[0]; v = fa->polys->verts[0];
if (gl_mtex_active) {
for (i = 0; i < fa->polys->numverts; i++, v += VERTEXSIZE) {
qglMultiTexCoord2fv (gl_mtex_enum + 0, &v[3]);
qglMultiTexCoord2fv (gl_mtex_enum + 1, &v[5]);
if (gl_mtex_fullbright)
qglMultiTexCoord2fv (gl_mtex_enum + 2, &v[3]);
qfglVertex3fv (v);
}
} else {
for (i = 0; i < fa->polys->numverts; i++, v += VERTEXSIZE) { for (i = 0; i < fa->polys->numverts; i++, v += VERTEXSIZE) {
qfglTexCoord2fv (&v[3]); qfglTexCoord2fv (&v[3]);
qfglVertex3fv (v); qfglVertex3fv (v);
} }
}
qfglEnd (); qfglEnd ();
}
static inline void
R_AddToLightmapChain (msurface_t *fa)
{
int maps, smax, tmax;
glRect_t *theRect;
// add the poly to the proper lightmap chain // add the poly to the proper lightmap chain
@ -173,7 +193,7 @@ R_RenderBrushPoly (msurface_t *fa)
if ((fa->dlightframe == r_framecount) || fa->cached_dlight) { if ((fa->dlightframe == r_framecount) || fa->cached_dlight) {
dynamic: dynamic:
if (r_dynamic->int_val) { if (r_dynamic->int_val && fa->dlightbits) {
lightmap_modified[fa->lightmaptexturenum] = true; lightmap_modified[fa->lightmaptexturenum] = true;
theRect = &lightmap_rectchange[fa->lightmaptexturenum]; theRect = &lightmap_rectchange[fa->lightmaptexturenum];
if (fa->light_t < theRect->t) { if (fa->light_t < theRect->t) {
@ -240,15 +260,51 @@ DrawTextureChains (void)
msurface_t *s; msurface_t *s;
texture_t *tex; texture_t *tex;
if (gl_mtex_active) {
qglActiveTexture (gl_mtex_enum + 0);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
} else {
qfglDisable (GL_BLEND); qfglDisable (GL_BLEND);
}
for (i = 0; i < r_worldentity.model->numtextures; i++) { for (i = 0; i < r_worldentity.model->numtextures; i++) {
tex = r_worldentity.model->textures[i]; tex = r_worldentity.model->textures[i];
if (!tex) if (!tex)
continue; continue;
qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum); qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
if (gl_mtex_fullbright&& gl_fb_bmodels->int_val && tex->gl_fb_texturenum) {
qglActiveTexture (gl_mtex_enum + 2);
qfglBindTexture (GL_TEXTURE_2D, tex->gl_fb_texturenum);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
qfglEnable (GL_TEXTURE_2D);
}
if (gl_mtex_active) {
for (s = tex->texturechain; s; s = s->texturechain) {
qglActiveTexture (gl_mtex_enum + 1);
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures +
s->lightmaptexturenum);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
qfglEnable (GL_TEXTURE_2D);
R_RenderBrushPoly (s);
qfglDisable (GL_TEXTURE_2D);
}
} else {
for (s = tex->texturechain; s; s = s->texturechain) for (s = tex->texturechain; s; s = s->texturechain)
R_RenderBrushPoly (s); R_RenderBrushPoly (s);
}
if (gl_mtex_fullbright && gl_fb_bmodels->int_val && tex->gl_fb_texturenum) {
qglActiveTexture (gl_mtex_enum + 2);
qfglDisable (GL_TEXTURE_2D);
}
if (gl_mtex_active)
qglActiveTexture (gl_mtex_enum + 0);
tex->texturechain = NULL; tex->texturechain = NULL;
tex->texturechain_tail = &tex->texturechain; tex->texturechain_tail = &tex->texturechain;
@ -257,7 +313,12 @@ DrawTextureChains (void)
tex->texturechain = NULL; tex->texturechain = NULL;
tex->texturechain_tail = &tex->texturechain; tex->texturechain_tail = &tex->texturechain;
if (!gl_mtex_active)
qfglEnable (GL_BLEND); qfglEnable (GL_BLEND);
else {
qglActiveTexture (gl_mtex_enum + 0);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
} }
void void
@ -336,6 +397,14 @@ 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
// Build lightmap chains
for (i = 0; i < model->nummodelsurfaces; i++, psurf++)
R_AddToLightmapChain(psurf);
R_CalcLightmaps ();
psurf = &model->surfaces[model->firstmodelsurface];
// draw texture // draw texture
for (i = 0; i < model->nummodelsurfaces; i++, psurf++) { for (i = 0; i < model->nummodelsurfaces; i++, psurf++) {
// find which side of the node we are on // find which side of the node we are on
@ -371,22 +440,65 @@ R_DrawBrushModel (entity_t *e)
tex = psurf->texinfo->texture; tex = psurf->texinfo->texture;
else else
tex = R_TextureAnimation (psurf); tex = R_TextureAnimation (psurf);
if (tex->gl_fb_texturenum > 0) {
if (gl_mtex_active) {
qglActiveTexture (gl_mtex_enum + 0);
qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
} else {
qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
}
qfglColor4fv (color);
if (gl_fb_bmodels->int_val && gl_mtex_fullbright
&& tex->gl_fb_texturenum > 0) {
qglActiveTexture (gl_mtex_enum + 2);
qfglBindTexture (GL_TEXTURE_2D, tex->gl_fb_texturenum);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
qfglEnable (GL_TEXTURE_2D);
}
if (gl_mtex_active) {
qglActiveTexture (gl_mtex_enum + 1);
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures +
psurf->lightmaptexturenum);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
qfglEnable (GL_TEXTURE_2D);
}
R_RenderBrushPoly (psurf);
if (gl_mtex_active) {
qfglDisable (GL_TEXTURE_2D);
}
if (gl_fb_bmodels->int_val && gl_mtex_fullbright
&& tex->gl_fb_texturenum > 0) {
qglActiveTexture (gl_mtex_enum + 1);
qfglDisable (GL_TEXTURE_2D);
}
if (gl_mtex_active) {
qglActiveTexture (gl_mtex_enum + 0);
qfglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
qfglColor3ubv (color_white);
if (tex->gl_fb_texturenum > 0 && gl_fb_bmodels->int_val) {
psurf->polys->fb_chain = psurf->polys->fb_chain =
fullbright_polys[tex->gl_fb_texturenum]; fullbright_polys[tex->gl_fb_texturenum];
fullbright_polys[tex->gl_fb_texturenum] = psurf->polys; fullbright_polys[tex->gl_fb_texturenum] = psurf->polys;
} }
qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum);
qfglColor4fv (color);
R_RenderBrushPoly (psurf);
qfglColor3ubv (color_white);
} }
} }
} }
R_CalcAndBlendLightmaps (); if (!gl_mtex_active)
R_BlendLightmaps ();
if (gl_fb_bmodels->int_val) if (gl_fb_bmodels->int_val && !gl_mtex_fullbright)
R_RenderFullbrights (); R_RenderFullbrights ();
qfglPopMatrix (); qfglPopMatrix ();
@ -453,6 +565,8 @@ R_RecursiveWorldNode (mnode_t *node)
} else { } else {
texture_t *tex; texture_t *tex;
R_AddToLightmapChain (surf);
if (!surf->texinfo->texture->anim_total) if (!surf->texinfo->texture->anim_total)
tex = surf->texinfo->texture; tex = surf->texinfo->texture;
else else
@ -492,15 +606,16 @@ R_DrawWorld (void)
R_RecursiveWorldNode (r_worldentity.model->nodes); R_RecursiveWorldNode (r_worldentity.model->nodes);
R_CalcLightmaps ();
R_DrawSkyChain (sky_chain); R_DrawSkyChain (sky_chain);
DrawTextureChains (); DrawTextureChains ();
R_CalcLightmaps (); if (!gl_mtex_active)
R_BlendLightmaps (); R_BlendLightmaps ();
if (gl_fb_bmodels->int_val) if (gl_fb_bmodels->int_val && !gl_mtex_fullbright)
R_RenderFullbrights (); R_RenderFullbrights ();
} }

View file

@ -85,8 +85,10 @@ int gl_filter_max = GL_LINEAR;
float gldepthmin, gldepthmax; float gldepthmin, gldepthmax;
// ARB Multitexture // ARB Multitexture
qboolean gl_mtex_active = false;
qboolean gl_mtex_capable = false; qboolean gl_mtex_capable = false;
qboolean gl_mtex_active = false;
qboolean gl_mtex_fullbright = false;
GLenum gl_mtex_enum = GL_TEXTURE0_ARB; GLenum gl_mtex_enum = GL_TEXTURE0_ARB;
QF_glColorTableEXT qglColorTableEXT = NULL; QF_glColorTableEXT qglColorTableEXT = NULL;
@ -106,6 +108,7 @@ cvar_t *gl_screenshot_byte_swap;
cvar_t *vid_mode; cvar_t *vid_mode;
cvar_t *vid_use8bit; cvar_t *vid_use8bit;
static int gl_mtex_tmus = 0;
static void static void
gl_max_size_f (cvar_t *var) gl_max_size_f (cvar_t *var)
@ -124,8 +127,22 @@ gl_max_size_f (cvar_t *var)
static void static void
gl_multitexture_f (cvar_t *var) gl_multitexture_f (cvar_t *var)
{ {
if (var) if (!var)
gl_mtex_active = gl_mtex_capable && var->int_val; return;
if (var->int_val && gl_mtex_capable) {
gl_mtex_active = true;
if (gl_mtex_tmus >= 3) {
gl_mtex_fullbright = true;
} else {
gl_mtex_fullbright = false;
Con_Printf ("Not enough TMUs for BSP fullbrights.\n");
}
} else {
gl_mtex_active = false;
gl_mtex_fullbright = false;
}
} }
static void static void
@ -191,11 +208,9 @@ CheckMultiTextureExtensions (void)
} }
if (QFGL_ExtensionPresent ("GL_ARB_multitexture")) { if (QFGL_ExtensionPresent ("GL_ARB_multitexture")) {
int max_texture_units = 0; qfglGetIntegerv (GL_MAX_TEXTURE_UNITS_ARB, &gl_mtex_tmus);
if (gl_mtex_tmus >= 2) {
qfglGetIntegerv (GL_MAX_TEXTURE_UNITS_ARB, &max_texture_units); Con_Printf ("enabled, %d TMUs.\n", gl_mtex_tmus);
if (max_texture_units >= 2) {
Con_Printf ("enabled, %d TMUs.\n", max_texture_units);
qglMultiTexCoord2f = qglMultiTexCoord2f =
QFGL_ExtensionAddress ("glMultiTexCoord2fARB"); QFGL_ExtensionAddress ("glMultiTexCoord2fARB");
qglMultiTexCoord2fv = qglMultiTexCoord2fv =