From d10512a72b53896e513107295c93bb72affe0d2c Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Tue, 19 Aug 2014 02:20:12 +0000 Subject: [PATCH] Fence texture support on brush models, e.g. for rmqdemo2 e1m6rq.bsp. Based on Baker's implementation in Fitz Mark V. Consistent with Fitz Mark V, RMQEngine, FTEQW rendering. Not implemented for world polys (afaik it's useless for world polys) but could be added if needed. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@970 af15c1b1-3010-417e-b628-4374ebc0bcbd --- Quake/gl_model.c | 22 +++++++++++++++++----- Quake/gl_model.h | 1 + Quake/gl_texmgr.c | 21 +++++++++++++++++++-- Quake/r_brush.c | 19 +++++++++++++++++-- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/Quake/gl_model.c b/Quake/gl_model.c index 8033ac37..bf03567b 100644 --- a/Quake/gl_model.c +++ b/Quake/gl_model.c @@ -491,6 +491,14 @@ void Mod_LoadTextures (lump_t *l) } else //regular texture { + // ericw -- fence textures + int extraflags; + + extraflags = 0; + if (tx->name[0] == '{') + extraflags |= TEXPREF_ALPHA; + // ericw + //external textures -- first look in "textures/mapname/" then look in "textures/" mark = Hunk_LowMark (); COM_StripExtension (loadmodel->name + 5, mapname, sizeof(mapname)); @@ -506,7 +514,7 @@ void Mod_LoadTextures (lump_t *l) if (data) //load external image { tx->gltexture = TexMgr_LoadImage (loadmodel, filename, fwidth, fheight, - SRC_RGBA, data, filename, 0, TEXPREF_MIPMAP); + SRC_RGBA, data, filename, 0, TEXPREF_MIPMAP | extraflags ); //now try to load glow/luma image from the same place Hunk_FreeToLowMark (mark); @@ -518,7 +526,7 @@ void Mod_LoadTextures (lump_t *l) if (data) tx->fullbright = TexMgr_LoadImage (loadmodel, filename2, fwidth, fheight, - SRC_RGBA, data, filename, 0, TEXPREF_MIPMAP ); + SRC_RGBA, data, filename, 0, TEXPREF_MIPMAP | extraflags ); } else //use the texture from the bsp file { @@ -527,15 +535,15 @@ void Mod_LoadTextures (lump_t *l) if (Mod_CheckFullbrights ((byte *)(tx+1), pixels)) { tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height, - SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_NOBRIGHT); + SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_NOBRIGHT | extraflags); q_snprintf (texturename, sizeof(texturename), "%s:%s_glow", loadmodel->name, tx->name); tx->fullbright = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height, - SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_FULLBRIGHT); + SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | TEXPREF_FULLBRIGHT | extraflags); } else { tx->gltexture = TexMgr_LoadImage (loadmodel, texturename, tx->width, tx->height, - SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP); + SRC_INDEXED, (byte *)(tx+1), loadmodel->name, offset, TEXPREF_MIPMAP | extraflags); } } Hunk_FreeToLowMark (mark); @@ -1178,6 +1186,10 @@ void Mod_LoadFaces (lump_t *l, qboolean bsp2) Mod_PolyForUnlitSurface (out); GL_SubdivideSurface (out); } + else if (out->texinfo->texture->name[0] == '{') // ericw -- fence textures + { + out->flags |= SURF_DRAWFENCE; + } else if (out->texinfo->flags & TEX_MISSING) // texture is missing from bsp { if (out->samples) //lightmapped diff --git a/Quake/gl_model.h b/Quake/gl_model.h index 9cd82696..2647a070 100644 --- a/Quake/gl_model.h +++ b/Quake/gl_model.h @@ -99,6 +99,7 @@ typedef struct texture_s #define SURF_DRAWBACKGROUND 0x40 #define SURF_UNDERWATER 0x80 #define SURF_NOTEXTURE 0x100 //johnfitz +#define SURF_DRAWFENCE 0x200 // !!! if this is changed, it must be changed in asm_draw.h too !!! typedef struct diff --git a/Quake/gl_texmgr.c b/Quake/gl_texmgr.c index 05b05b2e..7e43fd5d 100644 --- a/Quake/gl_texmgr.c +++ b/Quake/gl_texmgr.c @@ -39,7 +39,9 @@ gltexture_t *notexture, *nulltexture; unsigned int d_8to24table[256]; unsigned int d_8to24table_fbright[256]; +unsigned int d_8to24table_fbright_fence[256]; unsigned int d_8to24table_nobright[256]; +unsigned int d_8to24table_nobright_fence[256]; unsigned int d_8to24table_conchars[256]; unsigned int d_8to24table_shirt[256]; unsigned int d_8to24table_pants[256]; @@ -491,6 +493,14 @@ void TexMgr_LoadPalette (void) dst[2] = dst[1] = dst[0] = 0; } + //fullbright palette, for fence textures + memcpy(d_8to24table_fbright_fence, d_8to24table_fbright, 256*4); + d_8to24table_fbright_fence[255] = 0; // Alpha of zero. + + //nobright palette, for fence textures + memcpy(d_8to24table_nobright_fence, d_8to24table_nobright, 256*4); + d_8to24table_nobright_fence[255] = 0; // Alpha of zero. + //conchars palette, 0 and 255 are transparent memcpy(d_8to24table_conchars, d_8to24table, 256*4); ((byte *) &d_8to24table_conchars[0]) [3] = 0; @@ -1072,12 +1082,19 @@ static void TexMgr_LoadImage8 (gltexture_t *glt, byte *data) // choose palette and padbyte if (glt->flags & TEXPREF_FULLBRIGHT) { - usepal = d_8to24table_fbright; + if (glt->flags & TEXPREF_ALPHA) + usepal = d_8to24table_fbright_fence; + else + usepal = d_8to24table_fbright; padbyte = 0; } else if (glt->flags & TEXPREF_NOBRIGHT && gl_fullbrights.value) { - usepal = d_8to24table_nobright; + if (glt->flags & TEXPREF_ALPHA) + usepal = d_8to24table_nobright_fence; + else + usepal = d_8to24table_nobright; + padbyte = 0; } else if (glt->flags & TEXPREF_CONCHARS) diff --git a/Quake/r_brush.c b/Quake/r_brush.c index ee179b43..7d519b00 100644 --- a/Quake/r_brush.c +++ b/Quake/r_brush.c @@ -181,9 +181,17 @@ void R_DrawSequentialPoly (msurface_t *s) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4f(1, 1, 1, entalpha); } + + if (s->flags & SURF_DRAWFENCE) + glEnable (GL_ALPHA_TEST); // Flip on alpha test + GL_Bind (t->gltexture); DrawGLPoly (s->polys); rs_brushpasses++; + + if (s->flags & SURF_DRAWFENCE) + glDisable (GL_ALPHA_TEST); // Flip alpha test back off + if (entalpha < 1) { glDepthMask(GL_TRUE); @@ -307,6 +315,10 @@ void R_DrawSequentialPoly (msurface_t *s) } else glColor3f(1, 1, 1); + + if (s->flags & SURF_DRAWFENCE) + glEnable (GL_ALPHA_TEST); // Flip on alpha test + if (gl_overbright.value) { if (gl_texture_env_combine && gl_mtexable) //case 1: texture and lightmap in one pass, overbright using texture combiners @@ -336,7 +348,7 @@ void R_DrawSequentialPoly (msurface_t *s) GL_DisableMultitexture (); rs_brushpasses++; } - else if (entalpha < 1) //case 2: can't do multipass if entity has alpha, so just draw the texture + else if (entalpha < 1 || (s->flags & SURF_DRAWFENCE)) //case 2: can't do multipass if entity has alpha, so just draw the texture { GL_Bind (t->gltexture); DrawGLPoly (s->polys); @@ -409,7 +421,7 @@ void R_DrawSequentialPoly (msurface_t *s) GL_DisableMultitexture (); rs_brushpasses++; } - else if (entalpha < 1) //case 5: can't do multipass if entity has alpha, so just draw the texture + else if (entalpha < 1 || (s->flags & SURF_DRAWFENCE)) //case 5: can't do multipass if entity has alpha, so just draw the texture { GL_Bind (t->gltexture); DrawGLPoly (s->polys); @@ -468,6 +480,9 @@ void R_DrawSequentialPoly (msurface_t *s) glColor3f(1, 1, 1); } + if (s->flags & SURF_DRAWFENCE) + glDisable (GL_ALPHA_TEST); // Flip alpha test back off + fullbrights: return; // ericw - optimization: moved to a separate pass through the polys // so we're not constantly thrashing the texture bound in TEXTURE0