mirror of
https://git.code.sf.net/p/quake/quakeforge-old
synced 2025-02-21 11:01:12 +00:00
We now have fullbright textures for GL!
This is going in as a bug fix after talking it over with Knghtbrd and Deek..
This commit is contained in:
parent
c90b93d0b7
commit
dbbeff44fc
5 changed files with 445 additions and 107 deletions
|
@ -142,7 +142,8 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
|
||||||
int i, j, size;
|
int i, j, size;
|
||||||
byte *lightmap;
|
byte *lightmap;
|
||||||
unsigned scale;
|
unsigned scale;
|
||||||
int maps;
|
int maps;
|
||||||
|
int lightadj[4];
|
||||||
unsigned *bl;
|
unsigned *bl;
|
||||||
|
|
||||||
surf->cached_dlight = (surf->dlightframe == r_framecount);
|
surf->cached_dlight = (surf->dlightframe == r_framecount);
|
||||||
|
@ -153,7 +154,7 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
|
||||||
lightmap = surf->samples;
|
lightmap = surf->samples;
|
||||||
|
|
||||||
// set to full bright if no light data
|
// set to full bright if no light data
|
||||||
if (/* r_fullbright.value || */ !cl.worldmodel->lightdata)
|
if (r_fullbright.value || !cl.worldmodel->lightdata)
|
||||||
{
|
{
|
||||||
for (i=0 ; i<size ; i++)
|
for (i=0 ; i<size ; i++)
|
||||||
blocklights[i] = 255*256;
|
blocklights[i] = 255*256;
|
||||||
|
@ -300,107 +301,6 @@ void GL_EnableMultitexture(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
R_DrawSequentialPoly
|
|
||||||
|
|
||||||
Systems that have fast state and texture changes can
|
|
||||||
just do everything as it passes with no need to sort
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
void R_DrawSequentialPoly (msurface_t *s)
|
|
||||||
{
|
|
||||||
glpoly_t *p;
|
|
||||||
float *v;
|
|
||||||
int i;
|
|
||||||
texture_t *t;
|
|
||||||
|
|
||||||
//
|
|
||||||
// normal lightmaped poly
|
|
||||||
//
|
|
||||||
// if ((!(s->flags & (SURF_DRAWSKY|SURF_DRAWTURB)))
|
|
||||||
// && ((r_viewleaf->contents!=CONTENTS_EMPTY && (s->flags & SURF_UNDERWATER)) ||
|
|
||||||
// (r_viewleaf->contents==CONTENTS_EMPTY && !(s->flags & SURF_UNDERWATER))))
|
|
||||||
if (0)
|
|
||||||
{
|
|
||||||
p = s->polys;
|
|
||||||
|
|
||||||
t = R_TextureAnimation (s->texinfo->texture);
|
|
||||||
GL_Bind (t->gl_texturenum);
|
|
||||||
glBegin (GL_POLYGON);
|
|
||||||
v = p->verts[0];
|
|
||||||
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
|
|
||||||
{
|
|
||||||
glTexCoord2f (v[3], v[4]);
|
|
||||||
glVertex3fv (v);
|
|
||||||
}
|
|
||||||
glEnd ();
|
|
||||||
|
|
||||||
GL_Bind (lightmap_textures + s->lightmaptexturenum);
|
|
||||||
glEnable (GL_BLEND);
|
|
||||||
glBegin (GL_POLYGON);
|
|
||||||
v = p->verts[0];
|
|
||||||
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
|
|
||||||
{
|
|
||||||
glTexCoord2f (v[5], v[6]);
|
|
||||||
glVertex3fv (v);
|
|
||||||
}
|
|
||||||
glEnd ();
|
|
||||||
|
|
||||||
glDisable (GL_BLEND);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// subdivided water surface warp
|
|
||||||
//
|
|
||||||
if (s->flags & SURF_DRAWTURB)
|
|
||||||
{
|
|
||||||
GL_Bind (s->texinfo->texture->gl_texturenum);
|
|
||||||
EmitWaterPolys (s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// subdivided sky warp
|
|
||||||
//
|
|
||||||
if (s->flags & SURF_DRAWSKY)
|
|
||||||
{
|
|
||||||
GL_Bind (solidskytexture);
|
|
||||||
speedscale = realtime*8;
|
|
||||||
speedscale -= (int)speedscale;
|
|
||||||
|
|
||||||
EmitSkyPolys (s);
|
|
||||||
|
|
||||||
glEnable (GL_BLEND);
|
|
||||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
GL_Bind (alphaskytexture);
|
|
||||||
speedscale = realtime*16;
|
|
||||||
speedscale -= (int)speedscale;
|
|
||||||
EmitSkyPolys (s);
|
|
||||||
if (gl_lightmap_format == GL_LUMINANCE)
|
|
||||||
glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
|
|
||||||
|
|
||||||
glDisable (GL_BLEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// underwater warped with lightmap
|
|
||||||
//
|
|
||||||
p = s->polys;
|
|
||||||
|
|
||||||
t = R_TextureAnimation (s->texinfo->texture);
|
|
||||||
GL_Bind (t->gl_texturenum);
|
|
||||||
DrawGLWaterPoly (p);
|
|
||||||
|
|
||||||
GL_Bind (lightmap_textures + s->lightmaptexturenum);
|
|
||||||
glEnable (GL_BLEND);
|
|
||||||
DrawGLWaterPolyLightmap (p);
|
|
||||||
glDisable (GL_BLEND);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
R_DrawSequentialPoly
|
R_DrawSequentialPoly
|
||||||
|
@ -461,6 +361,34 @@ void R_DrawSequentialPoly (msurface_t *s)
|
||||||
glVertex3fv (v);
|
glVertex3fv (v);
|
||||||
}
|
}
|
||||||
glEnd ();
|
glEnd ();
|
||||||
|
|
||||||
|
// Neal White III - 12-29-1999 - render the glow map
|
||||||
|
|
||||||
|
if (t->flags & FLAG_HAS_GLOWMAP)
|
||||||
|
{
|
||||||
|
GL_DisableMultitexture();
|
||||||
|
GL_Bind (t->gl_glowtexnum);
|
||||||
|
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
glEnable (GL_BLEND);
|
||||||
|
glBlendFunc (GL_ONE, GL_ONE);
|
||||||
|
|
||||||
|
glBegin (GL_POLYGON);
|
||||||
|
v = p->verts[0];
|
||||||
|
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
|
||||||
|
{
|
||||||
|
glTexCoord2f (v[3], v[4]);
|
||||||
|
glVertex3fv (v);
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
|
||||||
|
// restore it to Quake's default
|
||||||
|
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glDisable (GL_BLEND);
|
||||||
|
}
|
||||||
|
// Neal White III - 12-29-1999 - END
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
p = s->polys;
|
p = s->polys;
|
||||||
|
@ -569,6 +497,44 @@ void R_DrawSequentialPoly (msurface_t *s)
|
||||||
}
|
}
|
||||||
glEnd ();
|
glEnd ();
|
||||||
|
|
||||||
|
// Neal White III - 12-31-1999 - render the glow map
|
||||||
|
|
||||||
|
if (t->flags & FLAG_HAS_GLOWMAP)
|
||||||
|
{
|
||||||
|
GL_DisableMultitexture();
|
||||||
|
GL_Bind (t->gl_glowtexnum);
|
||||||
|
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
glEnable (GL_BLEND);
|
||||||
|
glBlendFunc (GL_ONE, GL_ONE);
|
||||||
|
|
||||||
|
glBegin (GL_POLYGON);
|
||||||
|
v = p->verts[0];
|
||||||
|
for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
|
||||||
|
{
|
||||||
|
glTexCoord2f (v[3], v[4]);
|
||||||
|
|
||||||
|
// Neal - DON'T DELETE - leaves unmoving glowmap on top
|
||||||
|
// I think this is a clue to the "underwater cracks" bug
|
||||||
|
//
|
||||||
|
//glVertex3fv (v);
|
||||||
|
|
||||||
|
nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
|
||||||
|
nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
|
||||||
|
nv[2] = v[2];
|
||||||
|
|
||||||
|
glVertex3fv (nv);
|
||||||
|
}
|
||||||
|
glEnd ();
|
||||||
|
|
||||||
|
// restore it to Quake's default
|
||||||
|
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glDisable (GL_BLEND);
|
||||||
|
}
|
||||||
|
// Neal White III - 12-31-1999 - END
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
p = s->polys;
|
p = s->polys;
|
||||||
|
|
||||||
|
@ -582,7 +548,6 @@ void R_DrawSequentialPoly (msurface_t *s)
|
||||||
glDisable (GL_BLEND);
|
glDisable (GL_BLEND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -345,6 +345,30 @@ void Mod_LoadTextures (lump_t *l)
|
||||||
texture_t *altanims[10];
|
texture_t *altanims[10];
|
||||||
dmiptexlump_t *m;
|
dmiptexlump_t *m;
|
||||||
|
|
||||||
|
// Neal White III - 12-28-1999 - OpenGL fullbright bugfix
|
||||||
|
// nwhite@softblox.com
|
||||||
|
// http://home.telefragged.com/wally/
|
||||||
|
//
|
||||||
|
// Problem:
|
||||||
|
//
|
||||||
|
// There was a problem in the original glquake with fullbright texels.
|
||||||
|
// In the software renderer, fullbrights glow brightly in the dark.
|
||||||
|
// Essentially, the fullbrights were ignored. I've fixed it by
|
||||||
|
// adding another rendering pass and creating a new glowmap texture.
|
||||||
|
//
|
||||||
|
// Fix:
|
||||||
|
//
|
||||||
|
// When a texture with fullbright (FB) texels is loaded, a copy is made,
|
||||||
|
// then the FB pixels are cleared to black in the original texture. In
|
||||||
|
// the copy, all normal colors are cleared and only the FBs remain. When
|
||||||
|
// it comes time to render the polygons, I do an additional pass and ADD
|
||||||
|
// the glowmap on top of the current polygon.
|
||||||
|
|
||||||
|
byte *ptexel;
|
||||||
|
qboolean hasfullbrights;
|
||||||
|
qboolean noglow = COM_CheckParm("-noglow");
|
||||||
|
// Neal White III - 12-28-1999 - END
|
||||||
|
|
||||||
if (!l->filelen)
|
if (!l->filelen)
|
||||||
{
|
{
|
||||||
loadmodel->textures = NULL;
|
loadmodel->textures = NULL;
|
||||||
|
@ -370,25 +394,172 @@ void Mod_LoadTextures (lump_t *l)
|
||||||
|
|
||||||
if ( (mt->width & 15) || (mt->height & 15) )
|
if ( (mt->width & 15) || (mt->height & 15) )
|
||||||
Sys_Error ("Texture %s is not 16 aligned", mt->name);
|
Sys_Error ("Texture %s is not 16 aligned", mt->name);
|
||||||
|
|
||||||
pixels = mt->width*mt->height/64*85;
|
pixels = mt->width*mt->height/64*85;
|
||||||
tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
|
|
||||||
|
// Neal White III - 12-28-1999 - OpenGL fullbright bugfix
|
||||||
|
|
||||||
|
hasfullbrights = false;
|
||||||
|
|
||||||
|
if ((!Q_strncmp(mt->name,"sky",3)) ||
|
||||||
|
(!Q_strncmp(mt->name,"*",1)) || // turbulent (liquid)
|
||||||
|
(noglow) || (! gl_mtexable))
|
||||||
|
{
|
||||||
|
// sky has no lightmap, nor do liquids (so never needs a glowmap),
|
||||||
|
// -noglow command line parameter, or no multi-texture support
|
||||||
|
//
|
||||||
|
// hasfullbrights is already false
|
||||||
|
}
|
||||||
|
else // check this texture for fullbright texels
|
||||||
|
{
|
||||||
|
ptexel = (byte *)(mt+1);
|
||||||
|
|
||||||
|
for (j=0 ; j<pixels ; j++)
|
||||||
|
{
|
||||||
|
if (ptexel[j] >= 256-32) // 32 fullbright colors
|
||||||
|
{
|
||||||
|
hasfullbrights = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasfullbrights)
|
||||||
|
tx = Hunk_AllocName (sizeof(texture_t) +pixels*2, loadname );
|
||||||
|
else
|
||||||
|
tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
|
||||||
loadmodel->textures[i] = tx;
|
loadmodel->textures[i] = tx;
|
||||||
|
|
||||||
memcpy (tx->name, mt->name, sizeof(tx->name));
|
memcpy (tx->name, mt->name, sizeof(tx->name));
|
||||||
tx->width = mt->width;
|
tx->width = mt->width;
|
||||||
tx->height = mt->height;
|
tx->height = mt->height;
|
||||||
for (j=0 ; j<MIPLEVELS ; j++)
|
for (j=0 ; j<MIPLEVELS ; j++)
|
||||||
|
{
|
||||||
tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
|
tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
|
||||||
|
|
||||||
|
if (hasfullbrights)
|
||||||
|
tx->glowoffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t) + pixels;
|
||||||
|
else
|
||||||
|
tx->glowoffsets[j] = 0;
|
||||||
|
}
|
||||||
// the pixels immediately follow the structures
|
// the pixels immediately follow the structures
|
||||||
memcpy ( tx+1, mt+1, pixels);
|
memcpy ( tx+1, mt+1, pixels);
|
||||||
|
|
||||||
|
if (hasfullbrights)
|
||||||
|
{
|
||||||
|
ptexel = (byte *)(tx+1);
|
||||||
|
memcpy ( ptexel+pixels, mt+1, pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
tx->flags = 0;
|
||||||
|
|
||||||
if (!Q_strncmp(mt->name,"sky",3))
|
if (!Q_strncmp(mt->name,"sky",3))
|
||||||
R_InitSky (tx);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// Neal White III - 12-30-1999 - new variable speed sky layers
|
||||||
|
|
||||||
|
if (!Q_strncmp(mt->name,"!",1))
|
||||||
|
tx->flags |= FLAG_FAR_SKY_STOPPED; // for non-moving stars
|
||||||
|
if (!Q_strncmp(mt->name,".",1))
|
||||||
|
tx->flags |= FLAG_SKY_SLOWER; // sky moves at 1/2 speed
|
||||||
|
else if (!Q_strncmp(mt->name,":",1))
|
||||||
|
tx->flags |= FLAG_SKY_FASTER; // sky moves at 2x speed
|
||||||
|
if (!Q_strncmp(mt->name,"%",1))
|
||||||
|
tx->flags |= FLAG_SKY_TRANS; // near sky is semi-transparent
|
||||||
|
|
||||||
|
// Neal White III - 12-30-1999 - END
|
||||||
|
|
||||||
|
R_InitSky (tx);
|
||||||
|
} else {
|
||||||
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
|
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
|
||||||
|
|
||||||
|
// remove glowing fullbright colors from base texture (make black)
|
||||||
|
if (hasfullbrights)
|
||||||
|
{
|
||||||
|
// SAVE THIS - for debugging
|
||||||
|
//qboolean bColorUsed[256];
|
||||||
|
//Con_Printf ("*** Fullbright Texture: \"%s\", %dx%d, %d pixels\n", mt->name, mt->width, mt->height, pixels);
|
||||||
|
//for (j=0 ; j<256 ; j++)
|
||||||
|
// bColorUsed[j] = false;
|
||||||
|
|
||||||
|
ptexel = (byte *)(tx+1);
|
||||||
|
|
||||||
|
for (j=0 ; j<pixels ; j++)
|
||||||
|
{
|
||||||
|
// bColorUsed[ptexel[j]] = true;
|
||||||
|
|
||||||
|
if (ptexel[j] >= 256-32) // 32 fullbright colors
|
||||||
|
{
|
||||||
|
ptexel[j] = 0; // make fullbrights black
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Con_Printf ("*** Normal colors: ");
|
||||||
|
//for (j=0 ; j<256-32 ; j++)
|
||||||
|
//{
|
||||||
|
// if (bColorUsed[j])
|
||||||
|
// Con_Printf ("%d ", j);
|
||||||
|
//}
|
||||||
|
//Con_Printf ("\n");
|
||||||
|
//Con_Printf ("*** Fullbrights: ");
|
||||||
|
//for (j=256-32 ; j<256 ; j++)
|
||||||
|
//{
|
||||||
|
// if (bColorUsed[j])
|
||||||
|
// Con_Printf ("%d ", j);
|
||||||
|
//}
|
||||||
|
//Con_Printf ("\n");
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Con_Printf ("*** Normal Texture: \"%s\", %d*%d\n", mt->name, mt->width, mt->height);
|
||||||
|
//}
|
||||||
|
|
||||||
tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false);
|
tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false);
|
||||||
|
|
||||||
|
// create glowmap texture (all black except for glowing fullbright colors)
|
||||||
|
if (hasfullbrights)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
qboolean bGlowDoubleCheck = false;
|
||||||
|
#endif
|
||||||
|
char glowname[32];
|
||||||
|
memcpy (glowname, mt->name, sizeof(mt->name));
|
||||||
|
|
||||||
|
glowname[16] = '\0';
|
||||||
|
for (j=0 ; glowname[j] != '\0'; j++)
|
||||||
|
;
|
||||||
|
glowname[j++] = '<';
|
||||||
|
glowname[j++] = 'G';
|
||||||
|
glowname[j++] = 'L';
|
||||||
|
glowname[j++] = 'O';
|
||||||
|
glowname[j++] = 'W';
|
||||||
|
glowname[j++] = '>';
|
||||||
|
glowname[j++] = '\0';
|
||||||
|
|
||||||
|
ptexel = (byte *)(tx+1) + pixels;
|
||||||
|
|
||||||
|
for (j=0 ; j<pixels ; j++)
|
||||||
|
{
|
||||||
|
if (ptexel[j] < 256-32) // build glowmap
|
||||||
|
{
|
||||||
|
ptexel[j] = 0; // make non-fullbrights black
|
||||||
|
}
|
||||||
|
#ifdef _DEBUG
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bGlowDoubleCheck = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
tx->gl_glowtexnum = GL_LoadTexture (glowname, tx->width, tx->height, ptexel, true, false);
|
||||||
|
tx->flags |= FLAG_HAS_GLOWMAP;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (! bGlowDoubleCheck)
|
||||||
|
Con_Printf ("INTERNAL ERROR: Mod_LoadTextures - FullBright texture \"%s\" has no FullBright colors!\n", glowname);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Neal White III - 12-28-1999 - END
|
||||||
|
//
|
||||||
texture_mode = GL_LINEAR;
|
texture_mode = GL_LINEAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,15 @@ typedef struct mplane_s
|
||||||
byte pad[2];
|
byte pad[2];
|
||||||
} mplane_t;
|
} mplane_t;
|
||||||
|
|
||||||
|
// Neal White III - 12-28-1999 - new texture flags
|
||||||
|
#define FLAG_FAR_SKY_STOPPED 0x0001 // for non-moving stars
|
||||||
|
#define FLAG_SKY_SLOWER 0x0002 // sky moves at 1/2 speed
|
||||||
|
#define FLAG_SKY_FASTER 0x0004 // sky moves at 2x speed
|
||||||
|
#define FLAG_SKY_TRANS 0x0008 // near sky is semi-transparent
|
||||||
|
#define FLAG_HAS_GLOWMAP 0x0010 // used for fullbright bugfix
|
||||||
|
// Neal White III - 12-28-1999 - END
|
||||||
|
|
||||||
|
|
||||||
typedef struct texture_s
|
typedef struct texture_s
|
||||||
{
|
{
|
||||||
char name[16];
|
char name[16];
|
||||||
|
@ -87,6 +96,12 @@ typedef struct texture_s
|
||||||
struct texture_s *anim_next; // in the animation sequence
|
struct texture_s *anim_next; // in the animation sequence
|
||||||
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
|
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
|
||||||
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
||||||
|
|
||||||
|
// Neal White III - 12-28-1999 - OpenGL fullbright bugfix
|
||||||
|
int gl_glowtexnum;
|
||||||
|
unsigned flags; // FLAG_HAS_GLOWMAP
|
||||||
|
unsigned glowoffsets[MIPLEVELS]; // four mip maps stored
|
||||||
|
// Neal White III - 12-28-1999 - END
|
||||||
} texture_t;
|
} texture_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -345,6 +345,30 @@ void Mod_LoadTextures (lump_t *l)
|
||||||
texture_t *altanims[10];
|
texture_t *altanims[10];
|
||||||
dmiptexlump_t *m;
|
dmiptexlump_t *m;
|
||||||
|
|
||||||
|
// Neal White III - 12-28-1999 - OpenGL fullbright bugfix
|
||||||
|
// nwhite@softblox.com
|
||||||
|
// http://home.telefragged.com/wally/
|
||||||
|
//
|
||||||
|
// Problem:
|
||||||
|
//
|
||||||
|
// There was a problem in the original glquake with fullbright texels.
|
||||||
|
// In the software renderer, fullbrights glow brightly in the dark.
|
||||||
|
// Essentially, the fullbrights were ignored. I've fixed it by
|
||||||
|
// adding another rendering pass and creating a new glowmap texture.
|
||||||
|
//
|
||||||
|
// Fix:
|
||||||
|
//
|
||||||
|
// When a texture with fullbright (FB) texels is loaded, a copy is made,
|
||||||
|
// then the FB pixels are cleared to black in the original texture. In
|
||||||
|
// the copy, all normal colors are cleared and only the FBs remain. When
|
||||||
|
// it comes time to render the polygons, I do an additional pass and ADD
|
||||||
|
// the glowmap on top of the current polygon.
|
||||||
|
|
||||||
|
byte *ptexel;
|
||||||
|
qboolean hasfullbrights;
|
||||||
|
qboolean noglow = COM_CheckParm("-noglow");
|
||||||
|
// Neal White III - 12-28-1999 - END
|
||||||
|
|
||||||
if (!l->filelen)
|
if (!l->filelen)
|
||||||
{
|
{
|
||||||
loadmodel->textures = NULL;
|
loadmodel->textures = NULL;
|
||||||
|
@ -371,6 +395,37 @@ void Mod_LoadTextures (lump_t *l)
|
||||||
if ( (mt->width & 15) || (mt->height & 15) )
|
if ( (mt->width & 15) || (mt->height & 15) )
|
||||||
Sys_Error ("Texture %s is not 16 aligned", mt->name);
|
Sys_Error ("Texture %s is not 16 aligned", mt->name);
|
||||||
pixels = mt->width*mt->height/64*85;
|
pixels = mt->width*mt->height/64*85;
|
||||||
|
|
||||||
|
// Neal White III - 12-28-1999 - OpenGL fullbright bugfix
|
||||||
|
|
||||||
|
hasfullbrights = false;
|
||||||
|
|
||||||
|
if ((!Q_strncmp(mt->name,"sky",3)) ||
|
||||||
|
(!Q_strncmp(mt->name,"*",1)) || // turbulent (liquid)
|
||||||
|
(noglow) || (! gl_mtexable))
|
||||||
|
{
|
||||||
|
// sky has no lightmap, nor do liquids (so never needs a glowmap),
|
||||||
|
// -noglow command line parameter, or no multi-texture support
|
||||||
|
//
|
||||||
|
// hasfullbrights is already false
|
||||||
|
}
|
||||||
|
else // check this texture for fullbright texels
|
||||||
|
{
|
||||||
|
ptexel = (byte *)(mt+1);
|
||||||
|
|
||||||
|
for (j=0 ; j<pixels ; j++)
|
||||||
|
{
|
||||||
|
if (ptexel[j] >= 256-32) // 32 fullbright colors
|
||||||
|
{
|
||||||
|
hasfullbrights = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasfullbrights)
|
||||||
|
tx = Hunk_AllocName (sizeof(texture_t) +pixels*2, loadname );
|
||||||
|
else
|
||||||
tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
|
tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
|
||||||
loadmodel->textures[i] = tx;
|
loadmodel->textures[i] = tx;
|
||||||
|
|
||||||
|
@ -378,17 +433,134 @@ void Mod_LoadTextures (lump_t *l)
|
||||||
tx->width = mt->width;
|
tx->width = mt->width;
|
||||||
tx->height = mt->height;
|
tx->height = mt->height;
|
||||||
for (j=0 ; j<MIPLEVELS ; j++)
|
for (j=0 ; j<MIPLEVELS ; j++)
|
||||||
|
{
|
||||||
tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
|
tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
|
||||||
|
if (hasfullbrights)
|
||||||
|
tx->glowoffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t) + pixels;
|
||||||
|
else
|
||||||
|
tx->glowoffsets[j] = 0;
|
||||||
|
}
|
||||||
// the pixels immediately follow the structures
|
// the pixels immediately follow the structures
|
||||||
memcpy ( tx+1, mt+1, pixels);
|
memcpy ( tx+1, mt+1, pixels);
|
||||||
|
|
||||||
|
if (hasfullbrights)
|
||||||
|
{
|
||||||
|
ptexel = (byte *)(tx+1);
|
||||||
|
memcpy ( ptexel+pixels, mt+1, pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
tx->flags = 0;
|
||||||
|
|
||||||
|
|
||||||
if (!Q_strncmp(mt->name,"sky",3))
|
if (!Q_strncmp(mt->name,"sky",3))
|
||||||
|
{
|
||||||
|
// Neal White III - 12-30-1999 - new variable speed sky layers
|
||||||
|
|
||||||
|
if (!Q_strncmp(mt->name,"!",1))
|
||||||
|
tx->flags |= FLAG_FAR_SKY_STOPPED; // for non-moving stars
|
||||||
|
if (!Q_strncmp(mt->name,".",1))
|
||||||
|
tx->flags |= FLAG_SKY_SLOWER; // sky moves at 1/2 speed
|
||||||
|
else if (!Q_strncmp(mt->name,":",1))
|
||||||
|
tx->flags |= FLAG_SKY_FASTER; // sky moves at 2x speed
|
||||||
|
if (!Q_strncmp(mt->name,"%",1))
|
||||||
|
tx->flags |= FLAG_SKY_TRANS; // near sky is semi-transparent
|
||||||
|
|
||||||
|
// Neal White III - 12-30-1999 - END
|
||||||
|
|
||||||
R_InitSky (tx);
|
R_InitSky (tx);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
|
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
|
||||||
|
|
||||||
|
// remove glowing fullbright colors from base texture (make black)
|
||||||
|
if (hasfullbrights)
|
||||||
|
{
|
||||||
|
// SAVE THIS - for debugging
|
||||||
|
//qboolean bColorUsed[256];
|
||||||
|
//Con_Printf ("*** Fullbright Texture: \"%s\", %dx%d, %d pixels\n", mt->name, mt->width, mt->height, pixels);
|
||||||
|
//for (j=0 ; j<256 ; j++)
|
||||||
|
// bColorUsed[j] = false;
|
||||||
|
|
||||||
|
ptexel = (byte *)(tx+1);
|
||||||
|
|
||||||
|
for (j=0 ; j<pixels ; j++)
|
||||||
|
{
|
||||||
|
// bColorUsed[ptexel[j]] = true;
|
||||||
|
|
||||||
|
if (ptexel[j] >= 256-32) // 32 fullbright colors
|
||||||
|
{
|
||||||
|
ptexel[j] = 0; // make fullbrights black
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Con_Printf ("*** Normal colors: ");
|
||||||
|
//for (j=0 ; j<256-32 ; j++)
|
||||||
|
//{
|
||||||
|
// if (bColorUsed[j])
|
||||||
|
// Con_Printf ("%d ", j);
|
||||||
|
//}
|
||||||
|
//Con_Printf ("\n");
|
||||||
|
//Con_Printf ("*** Fullbrights: ");
|
||||||
|
//for (j=256-32 ; j<256 ; j++)
|
||||||
|
//{
|
||||||
|
// if (bColorUsed[j])
|
||||||
|
// Con_Printf ("%d ", j);
|
||||||
|
//}
|
||||||
|
//Con_Printf ("\n");
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Con_Printf ("*** Normal Texture: \"%s\", %d*%d\n", mt->name, mt->width, mt->height);
|
||||||
|
//}
|
||||||
|
|
||||||
tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false);
|
tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false);
|
||||||
|
//
|
||||||
|
// create glowmap texture (all black except for glowing fullbright colors)
|
||||||
|
if (hasfullbrights)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
qboolean bGlowDoubleCheck = false;
|
||||||
|
#endif
|
||||||
|
char glowname[32];
|
||||||
|
memcpy (glowname, mt->name, sizeof(mt->name));
|
||||||
|
|
||||||
|
glowname[16] = '\0';
|
||||||
|
for (j=0 ; glowname[j] != '\0'; j++)
|
||||||
|
;
|
||||||
|
glowname[j++] = '<';
|
||||||
|
glowname[j++] = 'G';
|
||||||
|
glowname[j++] = 'L';
|
||||||
|
glowname[j++] = 'O';
|
||||||
|
glowname[j++] = 'W';
|
||||||
|
glowname[j++] = '>';
|
||||||
|
glowname[j++] = '\0';
|
||||||
|
|
||||||
|
ptexel = (byte *)(tx+1) + pixels;
|
||||||
|
|
||||||
|
for (j=0 ; j<pixels ; j++)
|
||||||
|
{
|
||||||
|
if (ptexel[j] < 256-32) // build glowmap
|
||||||
|
{
|
||||||
|
ptexel[j] = 0; // make non-fullbrights black
|
||||||
|
}
|
||||||
|
#ifdef _DEBUG
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bGlowDoubleCheck = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
tx->gl_glowtexnum = GL_LoadTexture (glowname, tx->width, tx->height, ptexel, true, false);
|
||||||
|
tx->flags |= FLAG_HAS_GLOWMAP;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
if (! bGlowDoubleCheck)
|
||||||
|
Con_Printf ("INTERNAL ERROR: Mod_LoadTextures - FullBright texture \"%s\" has no FullBright colors!\n", glowname);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Neal White III - 12-28-1999 - END
|
||||||
|
|
||||||
texture_mode = GL_LINEAR;
|
texture_mode = GL_LINEAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,15 @@ typedef struct mplane_s
|
||||||
byte pad[2];
|
byte pad[2];
|
||||||
} mplane_t;
|
} mplane_t;
|
||||||
|
|
||||||
|
// Neal White III - 12-28-1999 - new texture flags
|
||||||
|
#define FLAG_FAR_SKY_STOPPED 0x0001 // for non-moving stars
|
||||||
|
#define FLAG_SKY_SLOWER 0x0002 // sky moves at 1/2 speed
|
||||||
|
#define FLAG_SKY_FASTER 0x0004 // sky moves at 2x speed
|
||||||
|
#define FLAG_SKY_TRANS 0x0008 // near sky is semi-transparent
|
||||||
|
#define FLAG_HAS_GLOWMAP 0x0010 // used for fullbright bugfix
|
||||||
|
// Neal White III - 12-28-1999 - END
|
||||||
|
|
||||||
|
|
||||||
typedef struct texture_s
|
typedef struct texture_s
|
||||||
{
|
{
|
||||||
char name[16];
|
char name[16];
|
||||||
|
@ -84,6 +93,12 @@ typedef struct texture_s
|
||||||
struct texture_s *anim_next; // in the animation sequence
|
struct texture_s *anim_next; // in the animation sequence
|
||||||
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
|
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
|
||||||
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
||||||
|
//
|
||||||
|
// Neal White III - 12-28-1999 - OpenGL fullbright bugfix
|
||||||
|
int gl_glowtexnum;
|
||||||
|
unsigned flags; // FLAG_HAS_GLOWMAP
|
||||||
|
unsigned glowoffsets[MIPLEVELS]; // four mip maps stored
|
||||||
|
// Neal White III - 12-28-1999 - END
|
||||||
} texture_t;
|
} texture_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue