mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
- clean out GLWall::SplitWall and instead of actually splitting the wall just attach a list of lights to it.
Actual handling will be in the rendering function because this doesn't need multiple vertex transfers to the GPU. All slices can be drawn from the same buffer with different uniform info being set.
This commit is contained in:
parent
fc57180d7e
commit
1d9ab5c632
2 changed files with 21 additions and 197 deletions
|
@ -85,6 +85,15 @@ struct GLSectorPlane
|
|||
};
|
||||
|
||||
|
||||
struct GLWallLightEntry
|
||||
{
|
||||
secplane_t *cliptop;
|
||||
secplane_t *clipbottom;
|
||||
int lightlevel;
|
||||
FColormap colormap;
|
||||
};
|
||||
|
||||
extern FMemArena GLWallLightEntryArena;
|
||||
|
||||
class GLWall
|
||||
{
|
||||
|
@ -126,6 +135,7 @@ public:
|
|||
|
||||
fixed_t viewdistance;
|
||||
|
||||
GLWallLightEntry *lights;
|
||||
int lightlevel;
|
||||
BYTE type;
|
||||
BYTE flags;
|
||||
|
@ -150,8 +160,6 @@ public:
|
|||
FTextureID topflat,bottomflat;
|
||||
secplane_t topplane, bottomplane; // we need to save these to pass them to the shader for calculating glows.
|
||||
|
||||
secplane_t *toplight, *bottomlight; // These refer to the planes within the lightlist_t entries.
|
||||
|
||||
// these are not the same as ytop and ybottom!!!
|
||||
float zceil[2];
|
||||
float zfloor[2];
|
||||
|
@ -177,7 +185,6 @@ private:
|
|||
void SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
|
||||
void SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
|
||||
|
||||
void Put3DWall(lightlist_t * lightlist, bool translucent);
|
||||
void SplitWall(sector_t * frontsector, bool translucent);
|
||||
void LightPass();
|
||||
void SetHorizon(vertex_t * ul, vertex_t * ur, vertex_t * ll, vertex_t * lr);
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
#include "gl/shaders/gl_shader.h"
|
||||
|
||||
|
||||
FMemArena GLWallLightEntryArena;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Checks whether a wall should glow
|
||||
|
@ -217,25 +219,6 @@ void GLWall::PutWall(bool translucent)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets 3D-floor lighting info
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::Put3DWall(lightlist_t * lightlist, bool translucent)
|
||||
{
|
||||
// only modify the light level if it doesn't originate from the seg's frontsector. This is to account for light transferring effects
|
||||
if (lightlist->p_lightlevel != &seg->sidedef->sector->lightlevel)
|
||||
{
|
||||
lightlevel = gl_ClampLight(*lightlist->p_lightlevel);
|
||||
}
|
||||
// relative light won't get changed here. It is constant across the entire wall.
|
||||
|
||||
Colormap.CopyFrom3DLight(lightlist);
|
||||
PutWall(translucent);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Splits a wall vertically if a 3D-floor
|
||||
|
@ -245,11 +228,6 @@ void GLWall::Put3DWall(lightlist_t * lightlist, bool translucent)
|
|||
|
||||
void GLWall::SplitWall(sector_t * frontsector, bool translucent)
|
||||
{
|
||||
GLWall copyWall1,copyWall2;
|
||||
float maplightbottomleft;
|
||||
float maplightbottomright;
|
||||
unsigned int i;
|
||||
int origlight = lightlevel;
|
||||
TArray<lightlist_t> & lightlist=frontsector->e->XFloor.lightlist;
|
||||
|
||||
if (glseg.x1==glseg.x2 && glseg.y1==glseg.y2)
|
||||
|
@ -258,178 +236,17 @@ void GLWall::SplitWall(sector_t * frontsector, bool translucent)
|
|||
}
|
||||
::SplitWall.Clock();
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (seg->linedef-lines==1)
|
||||
lights = (GLWallLightEntry*)GLWallLightEntryArena.Alloc(sizeof(GLWallLightEntry)*lightlist.Size());
|
||||
secplane_t *upperplane = &topplane;
|
||||
for (unsigned i = 0; i < lightlist.Size(); i++)
|
||||
{
|
||||
int a = 0;
|
||||
lights[i].cliptop = &lightlist[i].plane;
|
||||
lights[i].clipbottom = i == lightlist.Size() - 1 ? &bottomplane : &lightlist[i + 1].plane;
|
||||
lights[i].lightlevel = lightlist[i].caster != NULL? gl_ClampLight(*lightlist[i].p_lightlevel) : lightlevel;
|
||||
lights[i].colormap.FadeColor = Colormap.FadeColor;
|
||||
lights[i].colormap.CopyFrom3DLight(&lightlist[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lightlist.Size()>1)
|
||||
{
|
||||
for(i=0;i<lightlist.Size()-1;i++)
|
||||
{
|
||||
if (i<lightlist.Size()-1)
|
||||
{
|
||||
secplane_t &p = lightlist[i+1].plane;
|
||||
if (p.a | p.b)
|
||||
{
|
||||
maplightbottomleft = p.ZatPoint(glseg.x1,glseg.y1);
|
||||
maplightbottomright= p.ZatPoint(glseg.x2,glseg.y2);
|
||||
}
|
||||
else
|
||||
{
|
||||
maplightbottomleft =
|
||||
maplightbottomright= p.ZatPoint(glseg.x2,glseg.y2);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
maplightbottomright = maplightbottomleft = -32000;
|
||||
}
|
||||
|
||||
// The light is completely above the wall!
|
||||
if (maplightbottomleft>=ztop[0] && maplightbottomright>=ztop[1])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for an intersection with the upper plane
|
||||
if ((maplightbottomleft<ztop[0] && maplightbottomright>ztop[1]) ||
|
||||
(maplightbottomleft>ztop[0] && maplightbottomright<ztop[1]))
|
||||
{
|
||||
float clen = MAX<float>(fabsf(glseg.x2-glseg.x1), fabsf(glseg.y2-glseg.y2));
|
||||
|
||||
float dch=ztop[1]-ztop[0];
|
||||
float dfh=maplightbottomright-maplightbottomleft;
|
||||
float coeff= (ztop[0]-maplightbottomleft)/(dfh-dch);
|
||||
|
||||
// check for inaccuracies - let's be a little generous here!
|
||||
if (coeff*clen<.1f)
|
||||
{
|
||||
maplightbottomleft=ztop[0];
|
||||
}
|
||||
else if (coeff*clen>clen-.1f)
|
||||
{
|
||||
maplightbottomright=ztop[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// split the wall in 2 at the intersection and recursively split both halves
|
||||
copyWall1=copyWall2=*this;
|
||||
|
||||
copyWall1.glseg.x2 = copyWall2.glseg.x1 = glseg.x1 + coeff * (glseg.x2-glseg.x1);
|
||||
copyWall1.glseg.y2 = copyWall2.glseg.y1 = glseg.y1 + coeff * (glseg.y2-glseg.y1);
|
||||
copyWall1.ztop[1] = copyWall2.ztop[0] = ztop[0] + coeff * (ztop[1]-ztop[0]);
|
||||
copyWall1.zbottom[1] = copyWall2.zbottom[0] = zbottom[0] + coeff * (zbottom[1]-zbottom[0]);
|
||||
copyWall1.glseg.fracright = copyWall2.glseg.fracleft = glseg.fracleft + coeff * (glseg.fracright-glseg.fracleft);
|
||||
copyWall1.uprgt.u = copyWall2.uplft.u = uplft.u + coeff * (uprgt.u-uplft.u);
|
||||
copyWall1.uprgt.v = copyWall2.uplft.v = uplft.v + coeff * (uprgt.v-uplft.v);
|
||||
copyWall1.lorgt.u = copyWall2.lolft.u = lolft.u + coeff * (lorgt.u-lolft.u);
|
||||
copyWall1.lorgt.v = copyWall2.lolft.v = lolft.v + coeff * (lorgt.v-lolft.v);
|
||||
|
||||
::SplitWall.Unclock();
|
||||
|
||||
copyWall1.SplitWall(frontsector, translucent);
|
||||
copyWall2.SplitWall(frontsector, translucent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check for an intersection with the lower plane
|
||||
if ((maplightbottomleft<zbottom[0] && maplightbottomright>zbottom[1]) ||
|
||||
(maplightbottomleft>zbottom[0] && maplightbottomright<zbottom[1]))
|
||||
{
|
||||
float clen = MAX<float>(fabsf(glseg.x2-glseg.x1), fabsf(glseg.y2-glseg.y2));
|
||||
|
||||
float dch=zbottom[1]-zbottom[0];
|
||||
float dfh=maplightbottomright-maplightbottomleft;
|
||||
float coeff= (zbottom[0]-maplightbottomleft)/(dfh-dch);
|
||||
|
||||
// check for inaccuracies - let's be a little generous here because there's
|
||||
// some conversions between floats and fixed_t's involved
|
||||
if (coeff*clen<.1f)
|
||||
{
|
||||
maplightbottomleft=zbottom[0];
|
||||
}
|
||||
else if (coeff*clen>clen-.1f)
|
||||
{
|
||||
maplightbottomright=zbottom[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// split the wall in 2 at the intersection and recursively split both halves
|
||||
copyWall1=copyWall2=*this;
|
||||
|
||||
copyWall1.glseg.x2 = copyWall2.glseg.x1 = glseg.x1 + coeff * (glseg.x2-glseg.x1);
|
||||
copyWall1.glseg.y2 = copyWall2.glseg.y1 = glseg.y1 + coeff * (glseg.y2-glseg.y1);
|
||||
copyWall1.ztop[1] = copyWall2.ztop[0] = ztop[0] + coeff * (ztop[1]-ztop[0]);
|
||||
copyWall1.zbottom[1] = copyWall2.zbottom[0] = zbottom[0] + coeff * (zbottom[1]-zbottom[0]);
|
||||
copyWall1.glseg.fracright = copyWall2.glseg.fracleft = glseg.fracleft + coeff * (glseg.fracright-glseg.fracleft);
|
||||
copyWall1.uprgt.u = copyWall2.uplft.u = uplft.u + coeff * (uprgt.u-uplft.u);
|
||||
copyWall1.uprgt.v = copyWall2.uplft.v = uplft.v + coeff * (uprgt.v-uplft.v);
|
||||
copyWall1.lorgt.u = copyWall2.lolft.u = lolft.u + coeff * (lorgt.u-lolft.u);
|
||||
copyWall1.lorgt.v = copyWall2.lolft.v = lolft.v + coeff * (lorgt.v-lolft.v);
|
||||
|
||||
::SplitWall.Unclock();
|
||||
|
||||
copyWall1.SplitWall(frontsector, translucent);
|
||||
copyWall2.SplitWall(frontsector, translucent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 3D floor is completely within this light
|
||||
if (maplightbottomleft<=zbottom[0] && maplightbottomright<=zbottom[1])
|
||||
{
|
||||
// These values must not be destroyed!
|
||||
int ll=lightlevel;
|
||||
FColormap lc=Colormap;
|
||||
|
||||
Put3DWall(&lightlist[i], translucent);
|
||||
|
||||
lightlevel=ll;
|
||||
Colormap=lc;
|
||||
|
||||
::SplitWall.Unclock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (maplightbottomleft<=ztop[0] && maplightbottomright<=ztop[1] &&
|
||||
(maplightbottomleft!=ztop[0] || maplightbottomright!=ztop[1]))
|
||||
{
|
||||
copyWall1=*this;
|
||||
|
||||
copyWall1.flags |= GLWF_NOSPLITLOWER;
|
||||
flags |= GLWF_NOSPLITUPPER;
|
||||
ztop[0]=copyWall1.zbottom[0]=maplightbottomleft;
|
||||
ztop[1]=copyWall1.zbottom[1]=maplightbottomright;
|
||||
uplft.v=copyWall1.lolft.v=copyWall1.uplft.v+
|
||||
(maplightbottomleft-copyWall1.ztop[0])*(copyWall1.lolft.v-copyWall1.uplft.v)/(zbottom[0]-copyWall1.ztop[0]);
|
||||
uprgt.v=copyWall1.lorgt.v=copyWall1.uprgt.v+
|
||||
(maplightbottomright-copyWall1.ztop[1])*(copyWall1.lorgt.v-copyWall1.uprgt.v)/(zbottom[1]-copyWall1.ztop[1]);
|
||||
copyWall1.Put3DWall(&lightlist[i], translucent);
|
||||
}
|
||||
if (ztop[0]==zbottom[0] && ztop[1]==zbottom[1])
|
||||
{
|
||||
::SplitWall.Unclock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These values must not be destroyed!
|
||||
int ll=lightlevel;
|
||||
FColormap lc=Colormap;
|
||||
|
||||
Put3DWall(&lightlist[lightlist.Size()-1], translucent);
|
||||
|
||||
lightlevel=ll;
|
||||
Colormap=lc;
|
||||
flags &= ~GLWF_NOSPLITUPPER;
|
||||
::SplitWall.Unclock();
|
||||
PutWall(translucent);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue