mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-03-10 12:01:43 +00:00
Add support for lit water
This commit is contained in:
parent
1f6888e7bc
commit
87835bc3e3
7 changed files with 151 additions and 31 deletions
|
@ -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,8 +1329,13 @@ static void Mod_LoadFaces (lump_t *l, qboolean bsp2)
|
|||
out->flags |= SURF_DRAWTELE;
|
||||
else out->flags |= SURF_DRAWWATER;
|
||||
|
||||
Mod_PolyForUnlitSurface (out);
|
||||
GL_SubdivideSurface (out);
|
||||
// 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
|
||||
{
|
||||
|
|
|
@ -484,7 +484,7 @@ typedef struct qmodel_s
|
|||
qboolean viswarn; // for Mod_DecompressVis()
|
||||
|
||||
int bspversion;
|
||||
|
||||
qboolean haslitwater;
|
||||
//
|
||||
// alias model
|
||||
//
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
125
Quake/r_world.c
125
Quake/r_world.c
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue