- changed GLDecal to work without a pointer to the generating GLWall.

Although this is currently safe there is no guarantee that future refactorings will keep the current draw lists, so it's better if GLDecal used its own copy of the data.
This commit is contained in:
Christoph Oelckers 2018-05-03 21:42:34 +02:00
parent 43b491ea33
commit 96ac1fa363
5 changed files with 60 additions and 50 deletions

View file

@ -464,10 +464,8 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
//==========================================================================
void FDrawInfo::DrawDecal(GLDecal *gldecal)
{
auto wall = gldecal->wall;
auto decal = gldecal->decal;
auto tex = gldecal->gltexture;
auto &seg = wall->seg;
// calculate dynamic light effect.
if (level.HasDynamicLights && !mDrawer->FixedColormap && gl_light_sprites)
@ -475,8 +473,8 @@ void FDrawInfo::DrawDecal(GLDecal *gldecal)
// Note: This should be replaced with proper shader based lighting.
double x, y;
float out[3];
decal->GetXY(seg->sidedef, x, y);
GetDynSpriteLight(nullptr, x, y, gldecal->zcenter, wall->sub, out);
decal->GetXY(decal->Side, x, y);
GetDynSpriteLight(nullptr, x, y, gldecal->zcenter, decal->Side->lighthead, decal->Side->sector->PortalGroup, out);
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
}
@ -495,7 +493,7 @@ void FDrawInfo::DrawDecal(GLDecal *gldecal)
else gl_RenderState.AlphaFunc(GL_GREATER, 0.f);
mDrawer->SetColor(gldecal->light, gldecal->rel, gldecal->colormap, gldecal->a);
mDrawer->SetColor(gldecal->lightlevel, gldecal->rellight, gldecal->Colormap, gldecal->alpha);
// for additively drawn decals we must temporarily set the fog color to black.
PalEntry fc = gl_RenderState.GetFogColor();
if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One)
@ -503,20 +501,20 @@ void FDrawInfo::DrawDecal(GLDecal *gldecal)
gl_RenderState.SetFog(0, -1);
}
gl_RenderState.SetNormal(wall->glseg.Normal());
gl_RenderState.SetNormal(gldecal->Normal);
if (wall->lightlist == nullptr)
if (gldecal->lightlist == nullptr)
{
gl_RenderState.Apply();
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, gldecal->vertindex, 4);
}
else
{
auto &lightlist = *wall->lightlist;
auto &lightlist = *gldecal->lightlist;
for (unsigned k = 0; k < lightlist.Size(); k++)
{
secplane_t &lowplane = k == lightlist.Size() - 1 ? wall->bottomplane : lightlist[k + 1].plane;
secplane_t &lowplane = k == lightlist.Size() - 1 ? gldecal->bottomplane : lightlist[k + 1].plane;
DecalVertex *dv = gldecal->dv;
float low1 = lowplane.ZatPoint(dv[1].x, dv[1].y);
@ -524,13 +522,13 @@ void FDrawInfo::DrawDecal(GLDecal *gldecal)
if (low1 < dv[1].z || low2 < dv[2].z)
{
int thisll = lightlist[k].caster != NULL ? hw_ClampLight(*lightlist[k].p_lightlevel) : wall->lightlevel;
int thisll = lightlist[k].caster != NULL ? hw_ClampLight(*lightlist[k].p_lightlevel) : gldecal->lightlevel;
FColormap thiscm;
thiscm.FadeColor = wall->Colormap.FadeColor;
thiscm.FadeColor = gldecal->Colormap.FadeColor;
thiscm.CopyFrom3DLight(&lightlist[k]);
mDrawer->SetColor(thisll, gldecal->rel, thiscm, gldecal->a);
mDrawer->SetColor(thisll, gldecal->rellight, thiscm, gldecal->alpha);
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) thiscm.Decolorize();
mDrawer->SetFog(thisll, gldecal->rel, &thiscm, wall->RenderStyle == STYLE_Add);
mDrawer->SetFog(thisll, gldecal->rellight, &thiscm, false);
gl_RenderState.SetSplitPlanes(lightlist[k].plane, lowplane);
gl_RenderState.Apply();
@ -554,25 +552,28 @@ void FDrawInfo::DrawDecal(GLDecal *gldecal)
//==========================================================================
void FDrawInfo::DrawDecals()
{
GLWall *wall = nullptr;
side_t *wall = nullptr;
bool splitting = false;
for (auto gldecal : decals[0])
{
if (gldecal->wall != wall)
if (gldecal->decal->Side != wall)
{
wall = gldecal->wall;
if (wall->lightlist != nullptr)
wall = gldecal->decal->Side;
if (gldecal->lightlist != nullptr)
{
gl_RenderState.EnableSplit(true);
splitting = true;
}
else
{
gl_RenderState.EnableSplit(false);
mDrawer->SetFog(wall->lightlevel, wall->rellight + getExtraLight(), &wall->Colormap, false);
splitting = false;
mDrawer->SetFog(gldecal->lightlevel, gldecal->rellight, &gldecal->Colormap, false);
}
}
DrawDecal(gldecal);
}
if (wall && wall->lightlist != nullptr) gl_RenderState.EnableSplit(false);
if (splitting) gl_RenderState.EnableSplit(false);
}
//==========================================================================
@ -585,7 +586,7 @@ void FDrawInfo::DrawDecalsForMirror(GLWall *wall)
mDrawer->SetFog(wall->lightlevel, wall->rellight + getExtraLight(), &wall->Colormap, false);
for (auto gldecal : decals[1])
{
if (gldecal->wall == wall)
if (gldecal->decal->Side == wall->seg->sidedef)
{
DrawDecal(gldecal);
}

View file

@ -36,7 +36,7 @@
#include "hwrenderer/utility/hw_lighting.h"
#include "hwrenderer/data/flatvertices.h"
void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &normal)
{
line_t * line = seg->linedef;
side_t * side = seg->sidedef;
@ -228,35 +228,37 @@ void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal)
for (i = 0; i < 4; i++) dv[i].v = vb - dv[i].v;
}
GLDecal &gldecal = *di->AddDecal(type == RENDERWALL_MIRRORSURFACE);
gldecal.gltexture = tex;
gldecal.wall = this;
gldecal.decal = decal;
GLDecal *gldecal = di->AddDecal(type == RENDERWALL_MIRRORSURFACE);
gldecal->gltexture = tex;
gldecal->decal = decal;
if (decal->RenderFlags & RF_FULLBRIGHT)
{
gldecal.light = 255;
gldecal.rel = 0;
gldecal->lightlevel = 255;
gldecal->rellight = 0;
}
else
{
gldecal.light = lightlevel;
gldecal.rel = rellight + getExtraLight();
gldecal->lightlevel = lightlevel;
gldecal->rellight = rellight + getExtraLight();
}
gldecal.colormap = Colormap;
gldecal->Colormap = Colormap;
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING)
{
gldecal.colormap.Decolorize();
gldecal->Colormap.Decolorize();
}
gldecal.a = decal->Alpha;
gldecal.zcenter = zpos - decalheight * 0.5f;
memcpy(gldecal.dv, dv, sizeof(dv));
gldecal->alpha = decal->Alpha;
gldecal->zcenter = zpos - decalheight * 0.5f;
gldecal->bottomplane = bottomplane;
gldecal->Normal = normal;
gldecal->lightlist = lightlist;
memcpy(gldecal->dv, dv, sizeof(dv));
auto verts = di->AllocVertices(4);
gldecal.vertindex = verts.second;
gldecal->vertindex = verts.second;
for (i = 0; i < 4; i++)
{
@ -274,11 +276,15 @@ void GLWall::ProcessDecals(HWDrawInfo *di)
if (seg->sidedef != nullptr)
{
DBaseDecal *decal = seg->sidedef->AttachedDecals;
if (decal)
{
auto normal = glseg.Normal(); // calculate the normal only once per wall because it requires a square root.
while (decal)
{
ProcessDecal(di, decal);
ProcessDecal(di, decal, normal);
decal = decal->WallNext;
}
}
}
}

View file

@ -12,6 +12,7 @@ class GLSprite;
struct GLDecal;
class IShadowMap;
struct particle_t;
struct FDynLightData;
//==========================================================================
//
@ -140,7 +141,7 @@ public:
void AddOtherFloorPlane(int sector, gl_subsectorrendernode * node);
void AddOtherCeilingPlane(int sector, gl_subsectorrendernode * node);
void GetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * subsec, float *out);
void GetDynSpriteLight(AActor *self, float x, float y, float z, FLightNode *node, int portalgroup, float *out);
void GetDynSpriteLight(AActor *thing, particle_t *particle, float *out);
virtual void DrawWall(GLWall *wall, int pass) = 0;

View file

@ -247,7 +247,7 @@ public:
float fch1, float fch2, float ffh1, float ffh2,
float bch1, float bch2, float bfh1, float bfh2);
void ProcessDecal(HWDrawInfo *di, DBaseDecal *decal);
void ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &normal);
void ProcessDecals(HWDrawInfo *di);
void CreateVertices(FFlatVertex *&ptr, bool nosplit);
@ -412,16 +412,19 @@ struct DecalVertex
struct GLDecal
{
FMaterial *gltexture;
GLWall *wall;
TArray<lightlist_t> *lightlist;
DBaseDecal *decal;
DecalVertex dv[4];
float zcenter;
unsigned int vertindex;
int light;
int rel;
float a;
FColormap colormap;
FRenderStyle renderstyle;
int lightlevel;
int rellight;
float alpha;
FColormap Colormap;
secplane_t bottomplane;
FVector3 Normal;
};

View file

@ -49,7 +49,7 @@ T smoothstep(const T edge0, const T edge1, const T x)
//
//==========================================================================
void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * subsec, float *out)
void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FLightNode *node, int portalgroup, float *out)
{
ADynamicLight *light;
float frac, lr, lg, lb;
@ -57,7 +57,6 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, subs
out[0] = out[1] = out[2] = 0.f;
// Go through both light lists
FLightNode * node = subsec->lighthead;
while (node)
{
light=node->lightsource;
@ -71,7 +70,7 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, subs
if (level.Displacements.size > 0)
{
int fromgroup = light->Sector->PortalGroup;
int togroup = subsec->sector->PortalGroup;
int togroup = portalgroup;
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
DVector2 offset = level.Displacements.getOffset(fromgroup, togroup);
@ -132,11 +131,11 @@ void HWDrawInfo::GetDynSpriteLight(AActor *thing, particle_t *particle, float *o
{
if (thing != NULL)
{
GetDynSpriteLight(thing, thing->X(), thing->Y(), thing->Center(), thing->subsector, out);
GetDynSpriteLight(thing, thing->X(), thing->Y(), thing->Center(), thing->subsector->lighthead, thing->Sector->PortalGroup, out);
}
else if (particle != NULL)
{
GetDynSpriteLight(NULL, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector, out);
GetDynSpriteLight(NULL, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector->lighthead, particle->subsector->sector->PortalGroup, out);
}
}