- 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->glowtopcolor_index, 1, mGlowTop.vec);
glUniform4fv(activeShader->glowbottomcolor_index, 1, mGlowBottom.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) if (mLightEnabled)
{ {
glUniform3iv(activeShader->lightrange_index, 1, mNumLights); glUniform3iv(activeShader->lightrange_index, 1, mNumLights);

View file

@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include "c_cvars.h" #include "c_cvars.h"
#include "r_defs.h"
EXTERN_CVAR(Bool, gl_direct_state_change) EXTERN_CVAR(Bool, gl_direct_state_change)
@ -105,6 +106,7 @@ class FRenderState
FStateVec3 mCameraPos; FStateVec3 mCameraPos;
FStateVec4 mGlowTop, mGlowBottom; FStateVec4 mGlowTop, mGlowBottom;
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
PalEntry mFogColor; PalEntry mFogColor;
float mFogDensity; float mFogDensity;
@ -184,7 +186,13 @@ public:
mGlowBottom.Set(b[0], b[1], b[2], b[3]); 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[0] = r;
mDynLight[1] = g; 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; 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; 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); glTexCoord2f(tcs[1].u + facu * fracfac, tcs[1].v + facv * fracfac);
glVertex3f(cseg->v2->fx, ztop[0] + fact * fracfac, cseg->v2->fy); 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; 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; 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); glTexCoord2f(tcs[0].u + facu * fracfac, tcs[0].v + facv * fracfac);
glVertex3f(cseg->v2->fx, zbottom[0] + facb * fracfac, cseg->v2->fy); 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; 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] <= zbottom[0] ) i++;
while (i<vi->numheights && vi->heightlist[i] < ztop[0]) 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, glTexCoord2f(factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u,
factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v); factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v);
glVertex3f(glseg.x1, vi->heightlist[i], glseg.y1); 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; 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] >= ztop[1]) i--;
while (i>0 && vi->heightlist[i] > zbottom[1]) 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, glTexCoord2f(factu2 * (vi->heightlist[i] - ztop[1]) + tcs[2].u,
factv2 * (vi->heightlist[i] - ztop[1]) + tcs[2].v); factv2 * (vi->heightlist[i] - ztop[1]) + tcs[2].v);
glVertex3f(glseg.x2, vi->heightlist[i], glseg.y2); glVertex3f(glseg.x2, vi->heightlist[i], glseg.y2);

View file

@ -141,6 +141,7 @@ public:
FTextureID topflat,bottomflat; 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!!! // these are not the same as ytop and ybottom!!!
float zceil[2]; float zceil[2];
@ -158,8 +159,6 @@ private:
void SetupLights(); void SetupLights();
bool PrepareLight(texcoord * tcs, ADynamicLight * light); bool PrepareLight(texcoord * tcs, ADynamicLight * light);
void RenderWall(int textured, float * color2, ADynamicLight * light=NULL); 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); void FloodPlane(int pass);
@ -211,10 +210,10 @@ private:
void RenderMirrorSurface(); void RenderMirrorSurface();
void RenderTranslucentWall(); void RenderTranslucentWall();
void SplitLeftEdge(texcoord * tcs, bool glow); void SplitLeftEdge(texcoord * tcs);
void SplitRightEdge(texcoord * tcs, bool glow); void SplitRightEdge(texcoord * tcs);
void SplitUpperEdge(texcoord * tcs, bool glow); void SplitUpperEdge(texcoord * tcs);
void SplitLowerEdge(texcoord * tcs, bool glow); void SplitLowerEdge(texcoord * tcs);
public: 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 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. 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 ;) ) // Save a little time (up to 0.3 ms per frame ;) )
if (frontsector->floorplane.a | frontsector->floorplane.b) 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 topflat = frontsector->GetTexture(sector_t::ceiling); // for glowing textures
bottomflat = frontsector->GetTexture(sector_t::floor); bottomflat = frontsector->GetTexture(sector_t::floor);
topplane = frontsector->ceilingplane;
bottomplane = frontsector->floorplane;
zfloor[0] = zfloor[1] = FIXED2FLOAT(ffh); zfloor[0] = zfloor[1] = FIXED2FLOAT(ffh);

View file

@ -223,7 +223,6 @@ void GLWall::SetupLights()
void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light) void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
{ {
texcoord tcs[4]; texcoord tcs[4];
bool glowing;
bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ)); bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ));
if (!light) if (!light)
@ -232,15 +231,18 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
tcs[1]=uplft; tcs[1]=uplft;
tcs[2]=uprgt; tcs[2]=uprgt;
tcs[3]=lorgt; 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 else
{ {
if (!PrepareLight(tcs, light)) return; if (!PrepareLight(tcs, light)) return;
glowing = false;
} }
if (glowing) gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
gl_RenderState.Apply(); gl_RenderState.Apply();
@ -249,35 +251,31 @@ void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
// lower left corner // 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); if (textured&1) glTexCoord2f(tcs[0].u,tcs[0].v);
glVertex3f(glseg.x1,zbottom[0],glseg.y1); 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 // 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); if (textured&1) glTexCoord2f(tcs[1].u,tcs[1].v);
glVertex3f(glseg.x1,ztop[0],glseg.y1); 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 // color for right side
if (color2) glColor4fv(color2); if (color2) glColor4fv(color2);
// upper right corner // 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); if (textured&1) glTexCoord2f(tcs[2].u,tcs[2].v);
glVertex3f(glseg.x2,ztop[1],glseg.y2); 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 // 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); if (textured&1) glTexCoord2f(tcs[3].u,tcs[3].v);
glVertex3f(glseg.x2,zbottom[1],glseg.y2); glVertex3f(glseg.x2,zbottom[1],glseg.y2);
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, glowing); if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs);
glEnd(); 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, hVertProg);
glAttachShader(hShader, hFragProg); glAttachShader(hShader, hFragProg);
glBindAttribLocation(hShader, VATTR_GLOWDISTANCE, "glowdistance");
glBindAttribLocation(hShader, VATTR_FOGPARAMS, "fogparams"); glBindAttribLocation(hShader, VATTR_FOGPARAMS, "fogparams");
glBindAttribLocation(hShader, VATTR_LIGHTLEVEL, "lightlevel_in"); // Korshun. 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"); glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor");
glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor"); glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor");
glowbottomplane_index = glGetUniformLocation(hShader, "glowbottomplane");
glowtopplane_index = glGetUniformLocation(hShader, "glowtopplane");
glUseProgram(hShader); glUseProgram(hShader);

View file

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

View file

@ -5,7 +5,7 @@
#endif #endif
#ifndef NO_GLOW #ifndef NO_GLOW
varying vec2 glowdist; varying vec2 glowdist;
attribute vec2 glowdistance; uniform vec4 glowbottomplane, glowtopplane;
#endif #endif
#ifdef SOFTLIGHT #ifdef SOFTLIGHT
@ -36,7 +36,8 @@ void main()
#endif #endif
#ifndef NO_GLOW #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 #endif
#ifdef SPHEREMAP #ifdef SPHEREMAP
@ -54,16 +55,6 @@ void main()
gl_TexCoord[0].xy = sst; gl_TexCoord[0].xy = sst;
#endif #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 #ifndef NO_SM4
gl_Position = gl_ModelViewProjectionMatrix * worldcoord; gl_Position = gl_ModelViewProjectionMatrix * worldcoord;
#else #else