- changed rendering of glowing walls so that it doesn't require an additional vertex attribute, just pass the floor and ceiling planes as uniforms.

This commit is contained in:
Christoph Oelckers 2014-05-10 17:09:43 +02:00
parent 64d991b9b3
commit b09405a8bd
9 changed files with 57 additions and 49 deletions

View file

@ -237,7 +237,18 @@ bool FRenderState::ApplyShader()
{
glUniform4fv(activeShader->glowtopcolor_index, 1, mGlowTop.vec);
glUniform4fv(activeShader->glowbottomcolor_index, 1, mGlowBottom.vec);
glUniform4fv(activeShader->glowtopplane_index, 1, mGlowTopPlane.vec);
glUniform4fv(activeShader->glowbottomplane_index, 1, mGlowBottomPlane.vec);
activeShader->currentglowstate = 1;
}
else if (activeShader->currentglowstate)
{
// if glowing is on, disable it.
glUniform4f(activeShader->glowtopcolor_index, 0.f, 0.f, 0.f, 0.f);
glUniform4f(activeShader->glowbottomcolor_index, 0.f, 0.f, 0.f, 0.f);
activeShader->currentglowstate = 0;
}
if (mLightEnabled)
{
glUniform3iv(activeShader->lightrange_index, 1, mNumLights);

View file

@ -3,6 +3,7 @@
#include <string.h>
#include "c_cvars.h"
#include "r_defs.h"
EXTERN_CVAR(Bool, gl_direct_state_change)
@ -105,6 +106,7 @@ class FRenderState
FStateVec3 mCameraPos;
FStateVec4 mGlowTop, mGlowBottom;
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
PalEntry mFogColor;
float mFogDensity;
@ -184,7 +186,13 @@ public:
mGlowBottom.Set(b[0], b[1], b[2], b[3]);
}
void SetDynLight(float r,float g, float b)
void SetGlowPlanes(const secplane_t &top, const secplane_t &bottom)
{
mGlowTopPlane.Set(FIXED2FLOAT(top.a), FIXED2FLOAT(top.b), FIXED2FLOAT(top.ic), FIXED2FLOAT(top.d));
mGlowBottomPlane.Set(FIXED2FLOAT(bottom.a), FIXED2FLOAT(bottom.b), FIXED2FLOAT(bottom.ic), FIXED2FLOAT(bottom.d));
}
void SetDynLight(float r, float g, float b)
{
mDynLight[0] = r;
mDynLight[1] = g;

View file

@ -61,7 +61,7 @@ extern int vertexcount;
//
//==========================================================================
void GLWall::SplitUpperEdge(texcoord * tcs, bool glow)
void GLWall::SplitUpperEdge(texcoord * tcs)
{
if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return;
@ -82,9 +82,6 @@ void GLWall::SplitUpperEdge(texcoord * tcs, bool glow)
float fracfac = sidefrac - glseg.fracleft;
if (glow) glVertexAttrib2f(VATTR_GLOWDISTANCE, zceil[0] - ztop[0] + (facc - fact) * fracfac,
ztop[0] - zfloor[0] + (fact - facf) * fracfac);
glTexCoord2f(tcs[1].u + facu * fracfac, tcs[1].v + facv * fracfac);
glVertex3f(cseg->v2->fx, ztop[0] + fact * fracfac, cseg->v2->fy);
}
@ -97,7 +94,7 @@ void GLWall::SplitUpperEdge(texcoord * tcs, bool glow)
//
//==========================================================================
void GLWall::SplitLowerEdge(texcoord * tcs, bool glow)
void GLWall::SplitLowerEdge(texcoord * tcs)
{
if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return;
@ -118,9 +115,6 @@ void GLWall::SplitLowerEdge(texcoord * tcs, bool glow)
float fracfac = sidefrac - glseg.fracleft;
if (glow) glVertexAttrib2f(VATTR_GLOWDISTANCE, zceil[0] - zbottom[0] + (facc - facb) * fracfac,
zbottom[0] - zfloor[0] + (facb - facf) * fracfac);
glTexCoord2f(tcs[0].u + facu * fracfac, tcs[0].v + facv * fracfac);
glVertex3f(cseg->v2->fx, zbottom[0] + facb * fracfac, cseg->v2->fy);
}
@ -133,7 +127,7 @@ void GLWall::SplitLowerEdge(texcoord * tcs, bool glow)
//
//==========================================================================
void GLWall::SplitLeftEdge(texcoord * tcs, bool glow)
void GLWall::SplitLeftEdge(texcoord * tcs)
{
if (vertexes[0]==NULL) return;
@ -150,7 +144,6 @@ void GLWall::SplitLeftEdge(texcoord * tcs, bool glow)
while (i<vi->numheights && vi->heightlist[i] <= zbottom[0] ) i++;
while (i<vi->numheights && vi->heightlist[i] < ztop[0])
{
if (glow) glVertexAttrib2f(VATTR_GLOWDISTANCE, zceil[0] - vi->heightlist[i], vi->heightlist[i] - zfloor[0]);
glTexCoord2f(factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u,
factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v);
glVertex3f(glseg.x1, vi->heightlist[i], glseg.y1);
@ -166,7 +159,7 @@ void GLWall::SplitLeftEdge(texcoord * tcs, bool glow)
//
//==========================================================================
void GLWall::SplitRightEdge(texcoord * tcs, bool glow)
void GLWall::SplitRightEdge(texcoord * tcs)
{
if (vertexes[1]==NULL) return;
@ -183,7 +176,6 @@ void GLWall::SplitRightEdge(texcoord * tcs, bool glow)
while (i>0 && vi->heightlist[i] >= ztop[1]) i--;
while (i>0 && vi->heightlist[i] > zbottom[1])
{
if (glow) glVertexAttrib2f(VATTR_GLOWDISTANCE, zceil[1] - vi->heightlist[i], vi->heightlist[i] - zfloor[1]);
glTexCoord2f(factu2 * (vi->heightlist[i] - ztop[1]) + tcs[2].u,
factv2 * (vi->heightlist[i] - ztop[1]) + tcs[2].v);
glVertex3f(glseg.x2, vi->heightlist[i], glseg.y2);

View file

@ -141,6 +141,7 @@ public:
FTextureID topflat,bottomflat;
secplane_t topplane, bottomplane; // we need to save these to pass them to the shader for calculating glows.
// these are not the same as ytop and ybottom!!!
float zceil[2];
@ -158,8 +159,6 @@ private:
void SetupLights();
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
void RenderWall(int textured, float * color2, ADynamicLight * light=NULL);
void RenderGlowingPoly(int textured, ADynamicLight * light=NULL);
int Intersection(FloatRect * rc,GLWall * result);
void FloodPlane(int pass);
@ -211,10 +210,10 @@ private:
void RenderMirrorSurface();
void RenderTranslucentWall();
void SplitLeftEdge(texcoord * tcs, bool glow);
void SplitRightEdge(texcoord * tcs, bool glow);
void SplitUpperEdge(texcoord * tcs, bool glow);
void SplitLowerEdge(texcoord * tcs, bool glow);
void SplitLeftEdge(texcoord * tcs);
void SplitRightEdge(texcoord * tcs);
void SplitUpperEdge(texcoord * tcs);
void SplitLowerEdge(texcoord * tcs);
public:

View file

@ -1539,6 +1539,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
topflat=frontsector->GetTexture(sector_t::ceiling); // for glowing textures. These must be saved because
bottomflat=frontsector->GetTexture(sector_t::floor); // the sector passed here might be a temporary copy.
topplane = frontsector->ceilingplane;
bottomplane = frontsector->floorplane;
// Save a little time (up to 0.3 ms per frame ;) )
if (frontsector->floorplane.a | frontsector->floorplane.b)
@ -1775,6 +1777,8 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
topflat = frontsector->GetTexture(sector_t::ceiling); // for glowing textures
bottomflat = frontsector->GetTexture(sector_t::floor);
topplane = frontsector->ceilingplane;
bottomplane = frontsector->floorplane;
zfloor[0] = zfloor[1] = FIXED2FLOAT(ffh);

View file

@ -223,7 +223,6 @@ void GLWall::SetupLights()
void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
{
texcoord tcs[4];
bool glowing;
bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ));
if (!light)
@ -232,15 +231,18 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
tcs[1]=uplft;
tcs[2]=uprgt;
tcs[3]=lorgt;
glowing = !!(flags&GLWF_GLOW) && (textured & 2);
if (!!(flags&GLWF_GLOW) && (textured & 2))
{
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
}
}
else
{
if (!PrepareLight(tcs, light)) return;
glowing = false;
}
if (glowing) gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
gl_RenderState.Apply();
@ -249,35 +251,31 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
glBegin(GL_TRIANGLE_FAN);
// lower left corner
if (glowing) glVertexAttrib2f(VATTR_GLOWDISTANCE, zceil[0] - zbottom[0], zbottom[0] - zfloor[0]);
if (textured&1) glTexCoord2f(tcs[0].u,tcs[0].v);
glVertex3f(glseg.x1,zbottom[0],glseg.y1);
if (split && glseg.fracleft==0) SplitLeftEdge(tcs, glowing);
if (split && glseg.fracleft==0) SplitLeftEdge(tcs);
// upper left corner
if (glowing) glVertexAttrib2f(VATTR_GLOWDISTANCE, zceil[0] - ztop[0], ztop[0] - zfloor[0]);
if (textured&1) glTexCoord2f(tcs[1].u,tcs[1].v);
glVertex3f(glseg.x1,ztop[0],glseg.y1);
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, glowing);
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs);
// color for right side
if (color2) glColor4fv(color2);
// upper right corner
if (glowing) glVertexAttrib2f(VATTR_GLOWDISTANCE, zceil[1] - ztop[1], ztop[1] - zfloor[1]);
if (textured&1) glTexCoord2f(tcs[2].u,tcs[2].v);
glVertex3f(glseg.x2,ztop[1],glseg.y2);
if (split && glseg.fracright==1) SplitRightEdge(tcs, glowing);
if (split && glseg.fracright==1) SplitRightEdge(tcs);
// lower right corner
if (glowing) glVertexAttrib2f(VATTR_GLOWDISTANCE, zceil[1] - zbottom[1], zbottom[1] - zfloor[1]);
if (textured&1) glTexCoord2f(tcs[3].u,tcs[3].v);
glVertex3f(glseg.x2,zbottom[1],glseg.y2);
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, glowing);
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs);
glEnd();

View file

@ -141,7 +141,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
glAttachShader(hShader, hVertProg);
glAttachShader(hShader, hFragProg);
glBindAttribLocation(hShader, VATTR_GLOWDISTANCE, "glowdistance");
glBindAttribLocation(hShader, VATTR_FOGPARAMS, "fogparams");
glBindAttribLocation(hShader, VATTR_LIGHTLEVEL, "lightlevel_in"); // Korshun.
@ -185,6 +184,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor");
glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor");
glowbottomplane_index = glGetUniformLocation(hShader, "glowbottomplane");
glowtopplane_index = glGetUniformLocation(hShader, "glowtopplane");
glUseProgram(hShader);

View file

@ -7,7 +7,6 @@
extern bool gl_shaderactive;
const int VATTR_GLOWDISTANCE = 15;
const int VATTR_FOGPARAMS = 14;
const int VATTR_LIGHTLEVEL = 13; // Korshun.
@ -37,10 +36,12 @@ class FShader
int fogcolor_index;
int lights_index;
int dlightcolor_index;
int glowbottomcolor_index;
int glowtopcolor_index;
int glowbottomplane_index;
int glowtopplane_index;
int currentglowstate;
int currentfogenabled;
int currenttexturemode;
float currentlightfactor;
@ -55,7 +56,7 @@ public:
FShader()
{
hShader = hVertProg = hFragProg = 0;
currentfogenabled = currenttexturemode = 0;
currentglowstate = currentfogenabled = currenttexturemode = 0;
currentlightfactor = currentlightdist = 0.0f;
currentfogdensity = -1;
currentfogcolor = 0;
@ -72,7 +73,10 @@ public:
fogcolor_index = -1;
lights_index = -1;
dlightcolor_index = -1;
glowtopplane_index = -1;
glowbottomplane_index = -1;
glowtopcolor_index = -1;
glowbottomcolor_index = -1;
}
~FShader();

View file

@ -5,7 +5,7 @@
#endif
#ifndef NO_GLOW
varying vec2 glowdist;
attribute vec2 glowdistance;
uniform vec4 glowbottomplane, glowtopplane;
#endif
#ifdef SOFTLIGHT
@ -36,7 +36,8 @@ void main()
#endif
#ifndef NO_GLOW
glowdist = glowdistance;
glowdist.x = -((glowtopplane.w + glowtopplane.x * worldcoord.x + glowtopplane.y * worldcoord.z) * glowtopplane.z) - worldcoord.y;
glowdist.y = worldcoord.y + ((glowbottomplane.w + glowbottomplane.x * worldcoord.x + glowbottomplane.y * worldcoord.z) * glowbottomplane.z);
#endif
#ifdef SPHEREMAP
@ -54,16 +55,6 @@ void main()
gl_TexCoord[0].xy = sst;
#endif
/* only for reference purposes. I don't think this will ever get used.
#ifdef NUM_LAYERS
#ifndef SPHEREMAP_1
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord0;
#else
gl_TexCoord[1].xy = sst;
#endif
#endif
*/
#ifndef NO_SM4
gl_Position = gl_ModelViewProjectionMatrix * worldcoord;
#else