diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 19af11168..73cc5ec90 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -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); diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 6fea56707..061f5c2df 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -3,6 +3,7 @@ #include #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; diff --git a/src/gl/scene/gl_vertex.cpp b/src/gl/scene/gl_vertex.cpp index 4df381311..3aff28d1f 100644 --- a/src/gl/scene/gl_vertex.cpp +++ b/src/gl/scene/gl_vertex.cpp @@ -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 (inumheights && vi->heightlist[i] <= zbottom[0] ) i++; while (inumheights && 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); diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 00459644c..e53513167 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -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: diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index c65e1aa3b..2d14e0949 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -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); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index c71e23a20..d7edc6ef7 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -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(); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 241c5097f..ca1921bd4 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -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,7 +184,9 @@ 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); int texture_index = glGetUniformLocation(hShader, "texture2"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 0211eeac0..61053287c 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -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(); diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 87402bed0..7aebb8171 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -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