Add support for lit water

This commit is contained in:
JosiahJack 2022-08-07 05:31:18 -05:00
parent 1f6888e7bc
commit 87835bc3e3
7 changed files with 151 additions and 31 deletions

View file

@ -1311,7 +1311,14 @@ static void Mod_LoadFaces (lump_t *l, qboolean bsp2)
}
else if (out->texinfo->texture->name[0] == '*') // warp surface
{
out->flags |= (SURF_DRAWTURB | SURF_DRAWTILED);
out->flags |= SURF_DRAWTURB;
if (out->texinfo->flags & TEX_SPECIAL)
out->flags |= SURF_DRAWTILED;
else if (out->samples && !loadmodel->haslitwater)
{
Con_DPrintf ("Map has lit water\n");
loadmodel->haslitwater = true;
}
// detect special liquid types
if (!strncmp (out->texinfo->texture->name, "*lava", 5))
@ -1322,9 +1329,14 @@ static void Mod_LoadFaces (lump_t *l, qboolean bsp2)
out->flags |= SURF_DRAWTELE;
else out->flags |= SURF_DRAWWATER;
// polys are only created for unlit water here.
// lit water is handled in BuildSurfaceDisplayList
if (out->flags & SURF_DRAWTILED)
{
Mod_PolyForUnlitSurface (out);
GL_SubdivideSurface (out);
}
}
else if (out->texinfo->texture->name[0] == '{') // ericw -- fence textures
{
out->flags |= SURF_DRAWFENCE;

View file

@ -484,7 +484,7 @@ typedef struct qmodel_s
qboolean viswarn; // for Mod_DecompressVis()
int bspversion;
qboolean haslitwater;
//
// alias model
//

View file

@ -64,6 +64,7 @@ cvar_t r_fullbright = {"r_fullbright","0",CVAR_NONE};
cvar_t r_lightmap = {"r_lightmap","0",CVAR_NONE};
cvar_t r_shadows = {"r_shadows","0",CVAR_ARCHIVE};
cvar_t r_wateralpha = {"r_wateralpha","1",CVAR_ARCHIVE};
cvar_t r_litwater = {"r_litwater","1",CVAR_NONE};
cvar_t r_dynamic = {"r_dynamic","1",CVAR_ARCHIVE};
cvar_t r_novis = {"r_novis","0",CVAR_ARCHIVE};

View file

@ -176,6 +176,7 @@ void R_Init (void)
Cvar_RegisterVariable (&r_shadows);
Cvar_RegisterVariable (&r_wateralpha);
Cvar_SetCallback (&r_wateralpha, R_SetWateralpha_f);
Cvar_RegisterVariable (&r_litwater);
Cvar_RegisterVariable (&r_dynamic);
Cvar_RegisterVariable (&r_novis);
Cvar_RegisterVariable (&r_speeds);

View file

@ -139,6 +139,7 @@ extern cvar_t r_wateralpha;
extern cvar_t r_lavaalpha;
extern cvar_t r_telealpha;
extern cvar_t r_slimealpha;
extern cvar_t r_litwater;
extern cvar_t r_dynamic;
extern cvar_t r_novis;
extern cvar_t r_scale;

View file

@ -784,6 +784,12 @@ void GL_CreateSurfaceLightmap (msurface_t *surf)
int smax, tmax;
byte *base;
if (surf->flags & SURF_DRAWTILED)
{
surf->lightmaptexturenum = -1;
return;
}
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
@ -803,7 +809,7 @@ void BuildSurfaceDisplayList (msurface_t *fa)
int i, lindex, lnumverts;
medge_t *pedges, *r_pedge;
float *vec;
float s, t;
float s, t, s0, t0, sdiv, tdiv;
glpoly_t *poly;
// reconstruct the polygon
@ -818,6 +824,20 @@ void BuildSurfaceDisplayList (msurface_t *fa)
fa->polys = poly;
poly->numverts = lnumverts;
if (fa->flags & SURF_DRAWTURB)
{
// match Mod_PolyForUnlitSurface
s0 = t0 = 0.f;
sdiv = tdiv = 128.f;
}
else
{
s0 = fa->texinfo->vecs[0][3];
t0 = fa->texinfo->vecs[1][3];
sdiv = fa->texinfo->texture->width;
tdiv = fa->texinfo->texture->height;
}
for (i=0 ; i<lnumverts ; i++)
{
lindex = currentmodel->surfedges[fa->firstedge + i];
@ -832,11 +852,11 @@ void BuildSurfaceDisplayList (msurface_t *fa)
r_pedge = &pedges[-lindex];
vec = r_pcurrentvertbase[r_pedge->v[1]].position;
}
s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
s /= fa->texinfo->texture->width;
s = DotProduct (vec, fa->texinfo->vecs[0]) + s0;
s /= sdiv;
t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
t /= fa->texinfo->texture->height;
t = DotProduct (vec, fa->texinfo->vecs[1]) + t0;
t /= tdiv;
VectorCopy (vec, poly->verts[i]);
poly->verts[i][3] = s;
@ -871,6 +891,10 @@ void BuildSurfaceDisplayList (msurface_t *fa)
//johnfitz -- removed gl_keeptjunctions code
poly->numverts = lnumverts;
// support r_oldwater 1 on lit water
if (fa->flags & SURF_DRAWTURB)
GL_SubdivideSurface (fa);
}
/*

View file

@ -412,7 +412,7 @@ void R_DrawTextureChains_Multitexture (qmodel_t *model, entity_t *ent, texchain_
{
t = model->textures[i];
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTILED | SURF_NOTEXTURE))
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTURB | SURF_DRAWTILED | SURF_NOTEXTURE))
continue;
bound = false;
@ -541,6 +541,24 @@ float GL_WaterAlphaForEntitySurface (entity_t *ent, msurface_t *s)
return entalpha;
}
static GLuint r_world_program;
extern GLuint gl_bmodel_vbo;
// uniforms used in vert shader
// uniforms used in frag shader
static GLuint texLoc;
static GLuint LMTexLoc;
static GLuint fullbrightTexLoc;
static GLuint useFullbrightTexLoc;
static GLuint useOverbrightLoc;
static GLuint useAlphaTestLoc;
static GLuint alphaLoc;
#define vertAttrIndex 0
#define texCoordsAttrIndex 1
#define LMCoordsAttrIndex 2
/*
================
R_DrawTextureChains_Water -- johnfitz
@ -554,6 +572,7 @@ void R_DrawTextureChains_Water (qmodel_t *model, entity_t *ent, texchain_t chain
glpoly_t *p;
qboolean bound;
float entalpha;
int lastlightmap;
if (r_drawflat_cheatsafe || r_lightmap_cheatsafe) // ericw -- !r_drawworld_cheatsafe check moved to R_DrawWorld_Water ()
return;
@ -585,8 +604,90 @@ void R_DrawTextureChains_Water (qmodel_t *model, entity_t *ent, texchain_t chain
R_EndTransparentDrawing (entalpha);
}
}
else if (cl.worldmodel->haslitwater && r_litwater.value && r_world_program != 0)
{
GL_UseProgramFunc (r_world_program);
// Bind the buffers
GL_BindBuffer (GL_ARRAY_BUFFER, gl_bmodel_vbo);
GL_BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
GL_EnableVertexAttribArrayFunc (vertAttrIndex);
GL_EnableVertexAttribArrayFunc (texCoordsAttrIndex);
GL_EnableVertexAttribArrayFunc (LMCoordsAttrIndex);
GL_VertexAttribPointerFunc (vertAttrIndex, 3, GL_FLOAT, GL_FALSE, VERTEXSIZE * sizeof(float), ((float *)0));
GL_VertexAttribPointerFunc (texCoordsAttrIndex, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE * sizeof(float), ((float *)0) + 3);
GL_VertexAttribPointerFunc (LMCoordsAttrIndex, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE * sizeof(float), ((float *)0) + 5);
// Set uniforms
GL_Uniform1iFunc (texLoc, 0);
GL_Uniform1iFunc (LMTexLoc, 1);
GL_Uniform1iFunc (fullbrightTexLoc, 2);
GL_Uniform1iFunc (useFullbrightTexLoc, 0);
GL_Uniform1iFunc (useOverbrightLoc, (int)gl_overbright.value);
GL_Uniform1iFunc (useAlphaTestLoc, 0);
for (i=0 ; i<model->numtextures ; i++)
{
t = model->textures[i];
if (!t || !t->texturechains[chain] || !(t->texturechains[chain]->flags & SURF_DRAWTURB))
continue;
bound = false;
entalpha = 1.0f;
lastlightmap = 0;
for (s = t->texturechains[chain]; s; s = s->texturechain)
{
if (!bound) //only bind once we are sure we need this texture
{
entalpha = GL_WaterAlphaForEntitySurface (ent, s);
if (entalpha < 1.0f)
{
GL_Uniform1fFunc (alphaLoc, entalpha);
R_BeginTransparentDrawing (entalpha);
}
GL_SelectTexture (GL_TEXTURE0);
GL_Bind (t->warpimage);
if (model != cl.worldmodel)
{
// ericw -- this is copied from R_DrawSequentialPoly.
// If the poly is not part of the world we have to
// set this flag
t->update_warp = true; // FIXME: one frame too late!
}
bound = true;
lastlightmap = s->lightmaptexturenum;
}
if (s->lightmaptexturenum != lastlightmap)
R_FlushBatch ();
GL_SelectTexture (GL_TEXTURE1);
GL_Bind (lightmaps[s->lightmaptexturenum].texture);
lastlightmap = s->lightmaptexturenum;
R_BatchSurface (s);
rs_brushpasses++;
}
R_FlushBatch ();
R_EndTransparentDrawing (entalpha);
}
// clean up
GL_DisableVertexAttribArrayFunc (vertAttrIndex);
GL_DisableVertexAttribArrayFunc (texCoordsAttrIndex);
GL_DisableVertexAttribArrayFunc (LMCoordsAttrIndex);
GL_UseProgramFunc (0);
GL_SelectTexture (GL_TEXTURE0);
}
else
{
// Unlit water
for (i=0 ; i<model->numtextures ; i++)
{
t = model->textures[i];
@ -680,23 +781,6 @@ void R_DrawLightmapChains (void)
}
}
static GLuint r_world_program;
// uniforms used in vert shader
// uniforms used in frag shader
static GLuint texLoc;
static GLuint LMTexLoc;
static GLuint fullbrightTexLoc;
static GLuint useFullbrightTexLoc;
static GLuint useOverbrightLoc;
static GLuint useAlphaTestLoc;
static GLuint alphaLoc;
#define vertAttrIndex 0
#define texCoordsAttrIndex 1
#define LMCoordsAttrIndex 2
/*
=============
GLWorld_CreateShaders
@ -781,8 +865,6 @@ void GLWorld_CreateShaders (void)
}
}
extern GLuint gl_bmodel_vbo;
/*
================
R_DrawTextureChains_GLSL -- ericw
@ -837,7 +919,7 @@ void R_DrawTextureChains_GLSL (qmodel_t *model, entity_t *ent, texchain_t chain)
{
t = model->textures[i];
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTILED | SURF_NOTEXTURE))
if (!t || !t->texturechains[chain] || t->texturechains[chain]->flags & (SURF_DRAWTURB | SURF_DRAWTILED | SURF_NOTEXTURE))
continue;
// Enable/disable TMU 2 (fullbrights)
@ -861,7 +943,6 @@ void R_DrawTextureChains_GLSL (qmodel_t *model, entity_t *ent, texchain_t chain)
{
GL_SelectTexture (GL_TEXTURE0);
GL_Bind ((R_TextureAnimation(t, ent != NULL ? ent->frame : 0))->gltexture);
if (t->texturechains[chain]->flags & SURF_DRAWFENCE)
GL_Uniform1iFunc (useAlphaTestLoc, 1); // Flip alpha test back on