mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 14:51:46 +00:00
- 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:
parent
43b491ea33
commit
96ac1fa363
5 changed files with 60 additions and 50 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue