mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- 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:
parent
64d991b9b3
commit
b09405a8bd
9 changed files with 57 additions and 49 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue