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:
Zephaniah E. Hull 2000-01-05 15:23:12 +00:00
parent c90b93d0b7
commit dbbeff44fc
5 changed files with 445 additions and 107 deletions

View file

@ -142,7 +142,8 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
int i, j, size;
byte *lightmap;
unsigned scale;
int maps;
int maps;
int lightadj[4];
unsigned *bl;
surf->cached_dlight = (surf->dlightframe == r_framecount);
@ -153,7 +154,7 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
lightmap = surf->samples;
// 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++)
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
@ -461,6 +361,34 @@ void R_DrawSequentialPoly (msurface_t *s)
glVertex3fv (v);
}
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;
} else {
p = s->polys;
@ -569,6 +497,44 @@ void R_DrawSequentialPoly (msurface_t *s)
}
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 {
p = s->polys;
@ -582,7 +548,6 @@ void R_DrawSequentialPoly (msurface_t *s)
glDisable (GL_BLEND);
}
}
#endif
/*

View file

@ -345,6 +345,30 @@ void Mod_LoadTextures (lump_t *l)
texture_t *altanims[10];
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)
{
loadmodel->textures = NULL;
@ -370,25 +394,172 @@ void Mod_LoadTextures (lump_t *l)
if ( (mt->width & 15) || (mt->height & 15) )
Sys_Error ("Texture %s is not 16 aligned", mt->name);
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;
memcpy (tx->name, mt->name, sizeof(tx->name));
tx->width = mt->width;
tx->height = mt->height;
for (j=0 ; j<MIPLEVELS ; j++)
{
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
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))
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;
// 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);
// 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;
}
}

View file

@ -76,6 +76,15 @@ typedef struct mplane_s
byte pad[2];
} 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
{
char name[16];
@ -87,6 +96,12 @@ typedef struct texture_s
struct texture_s *anim_next; // in the animation sequence
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
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;

View file

@ -345,6 +345,30 @@ void Mod_LoadTextures (lump_t *l)
texture_t *altanims[10];
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)
{
loadmodel->textures = NULL;
@ -371,6 +395,37 @@ void Mod_LoadTextures (lump_t *l)
if ( (mt->width & 15) || (mt->height & 15) )
Sys_Error ("Texture %s is not 16 aligned", mt->name);
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 );
loadmodel->textures[i] = tx;
@ -378,17 +433,134 @@ void Mod_LoadTextures (lump_t *l)
tx->width = mt->width;
tx->height = mt->height;
for (j=0 ; j<MIPLEVELS ; j++)
{
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
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))
{
// 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;
// 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);
//
// 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;
}
}

View file

@ -73,6 +73,15 @@ typedef struct mplane_s
byte pad[2];
} 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
{
char name[16];
@ -84,6 +93,12 @@ typedef struct texture_s
struct texture_s *anim_next; // in the animation sequence
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
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;