Some initial decal rendering
This commit is contained in:
parent
21d99b105c
commit
1e23dcee7c
12 changed files with 249 additions and 68 deletions
|
|
@ -3,20 +3,21 @@
|
|||
|
||||
struct NullLevelMeshUpdater : UpdateLevelMesh
|
||||
{
|
||||
virtual void FloorHeightChanged(struct sector_t* sector) {};
|
||||
virtual void CeilingHeightChanged(struct sector_t* sector) {};
|
||||
virtual void MidTex3DHeightChanged(struct sector_t* sector) {};
|
||||
void FloorHeightChanged(sector_t* sector) override {}
|
||||
void CeilingHeightChanged(sector_t* sector) override {}
|
||||
void MidTex3DHeightChanged(sector_t* sector) override {}
|
||||
|
||||
virtual void FloorTextureChanged(struct sector_t* sector) {};
|
||||
virtual void CeilingTextureChanged(struct sector_t* sector) {};
|
||||
void FloorTextureChanged(sector_t* sector) override {}
|
||||
void CeilingTextureChanged(sector_t* sector) override {}
|
||||
|
||||
virtual void SectorChangedOther(struct sector_t* sector) {};
|
||||
void SectorChangedOther(sector_t* sector) override {}
|
||||
|
||||
virtual void SideTextureChanged(struct side_t* side, int section) {};
|
||||
void SideTextureChanged(side_t* side, int section) override {}
|
||||
void SideDecalsChanged(side_t* side) override {}
|
||||
|
||||
virtual void SectorLightChanged(struct sector_t* sector) {};
|
||||
virtual void SectorLightThinkerCreated(struct sector_t* sector, class DLighting* lightthinker) {};
|
||||
virtual void SectorLightThinkerDestroyed(struct sector_t* sector, class DLighting* lightthinker) {};
|
||||
void SectorLightChanged(sector_t* sector) override {}
|
||||
void SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) override {}
|
||||
void SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) override {}
|
||||
};
|
||||
|
||||
static NullLevelMeshUpdater nullUpdater;
|
||||
|
|
|
|||
|
|
@ -2,22 +2,27 @@
|
|||
// level mesh helper
|
||||
// this is a minimal include to keep the other source files a little bit leaner
|
||||
|
||||
struct sector_t;
|
||||
struct side_t;
|
||||
class DLighting;
|
||||
|
||||
struct UpdateLevelMesh
|
||||
{
|
||||
virtual void FloorHeightChanged(struct sector_t *sector) = 0;
|
||||
virtual void CeilingHeightChanged(struct sector_t *sector) = 0;
|
||||
virtual void MidTex3DHeightChanged(struct sector_t *sector) = 0;
|
||||
virtual void FloorHeightChanged(sector_t *sector) = 0;
|
||||
virtual void CeilingHeightChanged(sector_t *sector) = 0;
|
||||
virtual void MidTex3DHeightChanged(sector_t *sector) = 0;
|
||||
|
||||
virtual void FloorTextureChanged(struct sector_t *sector) = 0;
|
||||
virtual void CeilingTextureChanged(struct sector_t *sector) = 0;
|
||||
virtual void FloorTextureChanged(sector_t *sector) = 0;
|
||||
virtual void CeilingTextureChanged(sector_t *sector) = 0;
|
||||
|
||||
virtual void SectorChangedOther(struct sector_t *sector) = 0;
|
||||
virtual void SectorChangedOther(sector_t *sector) = 0;
|
||||
|
||||
virtual void SideTextureChanged(struct side_t *side, int section) = 0;
|
||||
virtual void SideTextureChanged(side_t *side, int section) = 0;
|
||||
virtual void SideDecalsChanged(side_t* side) = 0;
|
||||
|
||||
virtual void SectorLightChanged(struct sector_t* sector) = 0;
|
||||
virtual void SectorLightThinkerCreated(struct sector_t* sector, class DLighting* lightthinker) = 0;
|
||||
virtual void SectorLightThinkerDestroyed(struct sector_t* sector, class DLighting* lightthinker) = 0;
|
||||
virtual void SectorLightChanged(sector_t* sector) = 0;
|
||||
virtual void SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) = 0;
|
||||
virtual void SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) = 0;
|
||||
};
|
||||
|
||||
extern UpdateLevelMesh* LevelMeshUpdater;
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ void DBaseDecal::Remove ()
|
|||
{
|
||||
if (WallPrev == nullptr)
|
||||
{
|
||||
if (Side != nullptr) Side->AttachedDecals = WallNext;
|
||||
if (Side != nullptr)
|
||||
Side->AttachedDecals = WallNext;
|
||||
}
|
||||
else WallPrev->WallNext = WallNext;
|
||||
|
||||
|
|
@ -164,6 +165,9 @@ void DBaseDecal::Remove ()
|
|||
|
||||
WallPrev = nullptr;
|
||||
WallNext = nullptr;
|
||||
|
||||
if (Side)
|
||||
LevelMeshUpdater->SideDecalsChanged(Side);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -262,6 +266,8 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, double x, double y, F3DFloor *
|
|||
else wall->AttachedDecals = this;
|
||||
WallNext = nullptr;
|
||||
|
||||
LevelMeshUpdater->SideDecalsChanged(wall);
|
||||
|
||||
|
||||
sector_t *front, *back;
|
||||
line_t *line;
|
||||
|
|
|
|||
|
|
@ -318,6 +318,44 @@ void DoomLevelMesh::UpdateWallPortals()
|
|||
}
|
||||
}
|
||||
|
||||
void DoomLevelMesh::ProcessDecals(HWDrawInfo* di, FRenderState& state)
|
||||
{
|
||||
for (int sideIndex : level.levelMesh->SideDecals)
|
||||
{
|
||||
const auto& side = Sides[sideIndex];
|
||||
|
||||
Plane p;
|
||||
if (side.Decals[0].Size() != 0 || side.Decals[1].Size() != 0)
|
||||
{
|
||||
if (side.FirstSurface == -1)
|
||||
continue;
|
||||
p.Set(Mesh.Surfaces[side.FirstSurface].Plane.XYZ(), Mesh.Surfaces[side.FirstSurface].Plane.W);
|
||||
}
|
||||
|
||||
for (int onmirror = 0; onmirror < 2; onmirror++)
|
||||
{
|
||||
for (const HWDecal& decal : side.Decals[onmirror])
|
||||
{
|
||||
HWDecal* gldecal = di->AddDecal(onmirror == 1);
|
||||
*gldecal = decal;
|
||||
|
||||
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && decal.texture != nullptr)
|
||||
{
|
||||
gldecal->SetupLights(di, state, lightdata, p, level.sides[sideIndex].lighthead);
|
||||
}
|
||||
|
||||
auto verts = state.AllocVertices(4);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
verts.first[i] = side.DecalVertices[decal.vertindex + i];
|
||||
}
|
||||
gldecal->vertindex = verts.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DoomLevelMesh::CreateLights(FLevelLocals& doomMap)
|
||||
{
|
||||
if (LightsCreated)
|
||||
|
|
@ -525,6 +563,9 @@ void DoomLevelMesh::FreeSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
Sides[sideIndex].Uniforms.Clear();
|
||||
|
||||
Sides[sideIndex].WallPortals.Clear();
|
||||
Sides[sideIndex].Decals[0].Clear();
|
||||
Sides[sideIndex].Decals[1].Clear();
|
||||
Sides[sideIndex].DecalVertices.Clear();
|
||||
}
|
||||
|
||||
void DoomLevelMesh::FreeFlat(FLevelLocals& doomMap, unsigned int sectorIndex)
|
||||
|
|
@ -553,7 +594,7 @@ void DoomLevelMesh::FreeFlat(FLevelLocals& doomMap, unsigned int sectorIndex)
|
|||
Flats[sectorIndex].Uniforms.Clear();
|
||||
}
|
||||
|
||||
void DoomLevelMesh::FloorHeightChanged(struct sector_t* sector)
|
||||
void DoomLevelMesh::FloorHeightChanged(sector_t* sector)
|
||||
{
|
||||
UpdateFlat(sector->Index(), SurfaceUpdateType::Full);
|
||||
for (line_t* line : sector->Lines)
|
||||
|
|
@ -565,7 +606,7 @@ void DoomLevelMesh::FloorHeightChanged(struct sector_t* sector)
|
|||
}
|
||||
}
|
||||
|
||||
void DoomLevelMesh::CeilingHeightChanged(struct sector_t* sector)
|
||||
void DoomLevelMesh::CeilingHeightChanged(sector_t* sector)
|
||||
{
|
||||
UpdateFlat(sector->Index(), SurfaceUpdateType::Full);
|
||||
for (line_t* line : sector->Lines)
|
||||
|
|
@ -577,32 +618,37 @@ void DoomLevelMesh::CeilingHeightChanged(struct sector_t* sector)
|
|||
}
|
||||
}
|
||||
|
||||
void DoomLevelMesh::MidTex3DHeightChanged(struct sector_t* sector)
|
||||
void DoomLevelMesh::MidTex3DHeightChanged(sector_t* sector)
|
||||
{
|
||||
// UpdateFlat(sector->Index(), SurfaceUpdateType::Full);
|
||||
}
|
||||
|
||||
void DoomLevelMesh::FloorTextureChanged(struct sector_t* sector)
|
||||
void DoomLevelMesh::FloorTextureChanged(sector_t* sector)
|
||||
{
|
||||
UpdateFlat(sector->Index(), SurfaceUpdateType::Full);
|
||||
}
|
||||
|
||||
void DoomLevelMesh::CeilingTextureChanged(struct sector_t* sector)
|
||||
void DoomLevelMesh::CeilingTextureChanged(sector_t* sector)
|
||||
{
|
||||
UpdateFlat(sector->Index(), SurfaceUpdateType::Full);
|
||||
}
|
||||
|
||||
void DoomLevelMesh::SectorChangedOther(struct sector_t* sector)
|
||||
void DoomLevelMesh::SectorChangedOther(sector_t* sector)
|
||||
{
|
||||
UpdateFlat(sector->Index(), SurfaceUpdateType::Full);
|
||||
}
|
||||
|
||||
void DoomLevelMesh::SideTextureChanged(struct side_t* side, int section)
|
||||
void DoomLevelMesh::SideTextureChanged(side_t* side, int section)
|
||||
{
|
||||
UpdateSide(side->Index(), SurfaceUpdateType::Full);
|
||||
}
|
||||
|
||||
void DoomLevelMesh::SectorLightChanged(struct sector_t* sector)
|
||||
void DoomLevelMesh::SideDecalsChanged(side_t* side)
|
||||
{
|
||||
UpdateSide(side->Index(), SurfaceUpdateType::Full);
|
||||
}
|
||||
|
||||
void DoomLevelMesh::SectorLightChanged(sector_t* sector)
|
||||
{
|
||||
UpdateFlat(sector->Index(), SurfaceUpdateType::LightsOnly);
|
||||
for (line_t* line : sector->Lines)
|
||||
|
|
@ -614,11 +660,11 @@ void DoomLevelMesh::SectorLightChanged(struct sector_t* sector)
|
|||
}
|
||||
}
|
||||
|
||||
void DoomLevelMesh::SectorLightThinkerCreated(struct sector_t* sector, class DLighting* lightthinker)
|
||||
void DoomLevelMesh::SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker)
|
||||
{
|
||||
}
|
||||
|
||||
void DoomLevelMesh::SectorLightThinkerDestroyed(struct sector_t* sector, class DLighting* lightthinker)
|
||||
void DoomLevelMesh::SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -676,6 +722,30 @@ void DoomLevelMesh::CreateSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
wall.sub = sub;
|
||||
wall.Process(&disp, state, seg, front, back);
|
||||
|
||||
auto& sideBlock = Sides[sideIndex];
|
||||
|
||||
// Grab the decals generated
|
||||
for (int onmirror = 0; onmirror < 2; onmirror++)
|
||||
{
|
||||
if (result.decals[onmirror].Size() != 0 && !sideBlock.InSideDecalsList)
|
||||
{
|
||||
SideDecals.Push(sideIndex);
|
||||
sideBlock.InSideDecalsList = true;
|
||||
}
|
||||
|
||||
for (const HWDecal& decal : result.decals[onmirror])
|
||||
{
|
||||
int oldvertindex = decal.vertindex;
|
||||
int newvertindex = sideBlock.DecalVertices.Size();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
sideBlock.DecalVertices.Push(state.mVertices[oldvertindex + i]);
|
||||
}
|
||||
sideBlock.Decals[onmirror].Push(decal);
|
||||
sideBlock.Decals[onmirror].Last().vertindex = newvertindex;
|
||||
}
|
||||
}
|
||||
|
||||
// Part 1: solid geometry. This is set up so that there are no transparent parts
|
||||
state.SetDepthFunc(DF_LEqual);
|
||||
state.ClearDepthBias();
|
||||
|
|
@ -684,16 +754,16 @@ void DoomLevelMesh::CreateSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||
CreateWallSurface(side, disp, state, result.list, back ? LevelMeshDrawType::Masked : LevelMeshDrawType::Opaque, true, sideIndex);
|
||||
|
||||
if (result.portals.Size() != 0 && !Sides[sideIndex].InSidePortalsList)
|
||||
if (result.portals.Size() != 0 && !sideBlock.InSidePortalsList)
|
||||
{
|
||||
// Register side having portals
|
||||
SidePortals.Push(sideIndex);
|
||||
Sides[sideIndex].InSidePortalsList = true;
|
||||
sideBlock.InSidePortalsList = true;
|
||||
}
|
||||
|
||||
for (HWWall& portal : result.portals)
|
||||
{
|
||||
Sides[sideIndex].WallPortals.Push(portal);
|
||||
sideBlock.WallPortals.Push(portal);
|
||||
}
|
||||
|
||||
CreateWallSurface(side, disp, state, result.portals, LevelMeshDrawType::Portal, false, sideIndex);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
struct FLevelLocals;
|
||||
struct FPolyObj;
|
||||
struct HWWallDispatcher;
|
||||
struct HWDrawInfo;
|
||||
class DoomLevelMesh;
|
||||
class MeshBuilder;
|
||||
|
||||
|
|
@ -67,7 +68,10 @@ struct SideSurfaceBlock
|
|||
TArray<GeometryFreeInfo> Geometries;
|
||||
TArray<UniformsAllocInfo> Uniforms;
|
||||
TArray<HWWall> WallPortals;
|
||||
TArray<HWDecal> Decals[2];
|
||||
TArray<FFlatVertex> DecalVertices;
|
||||
bool InSidePortalsList = false;
|
||||
bool InSideDecalsList = false;
|
||||
TArray<DrawRangeInfo> DrawRanges;
|
||||
SurfaceUpdateType UpdateType = SurfaceUpdateType::None;
|
||||
};
|
||||
|
|
@ -94,6 +98,9 @@ public:
|
|||
|
||||
void BuildSectorGroups(const FLevelLocals& doomMap);
|
||||
|
||||
void ProcessDecals(HWDrawInfo* drawinfo, FRenderState& state);
|
||||
|
||||
TArray<int> SideDecals;
|
||||
TArray<int> SidePortals;
|
||||
TArray<HWWall*> WallPortals;
|
||||
|
||||
|
|
@ -103,16 +110,17 @@ public:
|
|||
|
||||
void CreateLights(FLevelLocals& doomMap);
|
||||
|
||||
void FloorHeightChanged(struct sector_t* sector) override;
|
||||
void CeilingHeightChanged(struct sector_t* sector) override;
|
||||
void MidTex3DHeightChanged(struct sector_t* sector) override;
|
||||
void FloorTextureChanged(struct sector_t* sector) override;
|
||||
void CeilingTextureChanged(struct sector_t* sector) override;
|
||||
void SectorChangedOther(struct sector_t* sector) override;
|
||||
void SideTextureChanged(struct side_t* side, int section) override;
|
||||
void SectorLightChanged(struct sector_t* sector) override;
|
||||
void SectorLightThinkerCreated(struct sector_t* sector, class DLighting* lightthinker) override;
|
||||
void SectorLightThinkerDestroyed(struct sector_t* sector, class DLighting* lightthinker) override;
|
||||
void FloorHeightChanged(sector_t* sector) override;
|
||||
void CeilingHeightChanged(sector_t* sector) override;
|
||||
void MidTex3DHeightChanged(sector_t* sector) override;
|
||||
void FloorTextureChanged(sector_t* sector) override;
|
||||
void CeilingTextureChanged(sector_t* sector) override;
|
||||
void SectorChangedOther(sector_t* sector) override;
|
||||
void SideTextureChanged(side_t* side, int section) override;
|
||||
void SideDecalsChanged(side_t* side) override;
|
||||
void SectorLightChanged(sector_t* sector) override;
|
||||
void SectorLightThinkerCreated(sector_t* sector, DLighting* lightthinker) override;
|
||||
void SectorLightThinkerDestroyed(sector_t* sector, DLighting* lightthinker) override;
|
||||
|
||||
void Reset(const LevelMeshLimits& limits) override
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@
|
|||
#include "flatvertices.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "texturemanager.h"
|
||||
#include "hw_walldispatcher.h"
|
||||
#include "hw_dynlightdata.h"
|
||||
#include "a_dynlight.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
@ -189,7 +192,7 @@ static float mix(float a, float b, float t)
|
|||
return a * (1.0f - t) + b * t;
|
||||
}
|
||||
|
||||
void HWWall::ProcessDecal(HWDrawInfo *di, FRenderState& state, DBaseDecal *decal, const FVector3 &normal)
|
||||
void HWWall::ProcessDecal(HWWallDispatcher* di, FRenderState& state, DBaseDecal *decal, const FVector3 &normal)
|
||||
{
|
||||
line_t * line = seg->linedef;
|
||||
side_t * side = seg->sidedef;
|
||||
|
|
@ -448,7 +451,7 @@ void HWWall::ProcessDecal(HWDrawInfo *di, FRenderState& state, DBaseDecal *decal
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::ProcessDecals(HWDrawInfo *di, FRenderState& state)
|
||||
void HWWall::ProcessDecals(HWWallDispatcher* di, FRenderState& state)
|
||||
{
|
||||
if (seg->sidedef != nullptr)
|
||||
{
|
||||
|
|
@ -465,3 +468,73 @@ void HWWall::ProcessDecals(HWDrawInfo *di, FRenderState& state)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
void HWDecal::SetupLights(HWDrawInfo* di, FRenderState& state, FDynLightData& lightdata, Plane p, FLightNode* node)
|
||||
{
|
||||
lightdata.Clear();
|
||||
|
||||
// if (RenderStyle == STYLE_Add && !di->Level->lightadditivesurfaces) return; // no lights on additively blended surfaces.
|
||||
|
||||
//float vtx[] = { glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2 };
|
||||
//Plane p;
|
||||
// auto normal = glseg.Normal();
|
||||
// p.Set(normal, -normal.X * glseg.x1 - normal.Z * glseg.y1);
|
||||
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
while (node)
|
||||
{
|
||||
if (node->lightsource->IsActive() && !node->lightsource->DontLightMap())
|
||||
{
|
||||
iter_dlight++;
|
||||
|
||||
DVector3 posrel = node->lightsource->PosRelative(frontsector->PortalGroup);
|
||||
float x = posrel.X;
|
||||
float y = posrel.Y;
|
||||
float z = posrel.Z;
|
||||
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||
float radius = node->lightsource->GetRadius();
|
||||
//float scale = 1.0f / ((2.f * radius) - dist);
|
||||
//FVector3 fn, pos;
|
||||
|
||||
if (radius > 0.f && dist < radius)
|
||||
{
|
||||
/*
|
||||
FVector3 nearPt, up, right;
|
||||
|
||||
pos = { x, z, y };
|
||||
fn = p.Normal();
|
||||
|
||||
fn.GetRightUp(right, up);
|
||||
|
||||
FVector3 tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
|
||||
FVector3 t1;
|
||||
int outcnt[4] = { 0,0,0,0 };
|
||||
texcoord tcs[4];
|
||||
|
||||
// do a quick check whether the light touches this polygon
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
t1 = FVector3(&vtx[i * 3]);
|
||||
FVector3 nearToVert = t1 - nearPt;
|
||||
tcs[i].u = ((nearToVert | right) * scale) + 0.5f;
|
||||
tcs[i].v = ((nearToVert | up) * scale) + 0.5f;
|
||||
|
||||
if (tcs[i].u < 0) outcnt[0]++;
|
||||
if (tcs[i].u > 1) outcnt[1]++;
|
||||
if (tcs[i].v < 0) outcnt[2]++;
|
||||
if (tcs[i].v > 1) outcnt[3]++;
|
||||
|
||||
}
|
||||
if (outcnt[0] != 4 && outcnt[1] != 4 && outcnt[2] != 4 && outcnt[3] != 4)*/
|
||||
{
|
||||
draw_dlight += GetLight(lightdata, frontsector->PortalGroup, p, node->lightsource, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
dynlightindex = state.UploadLights(lightdata);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -507,6 +507,17 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
|
|||
}
|
||||
}
|
||||
|
||||
// Draw Decals
|
||||
{
|
||||
level.levelMesh->ProcessDecals(this, state);
|
||||
state.SetRenderStyle(STYLE_Translucent);
|
||||
state.SetDepthFunc(DF_LEqual);
|
||||
DrawDecals(state, Decals[0]);
|
||||
DrawDecals(state, Decals[1]); // Mirror decals - when should they be drawn?
|
||||
Decals[0].Clear();
|
||||
Decals[1].Clear();
|
||||
}
|
||||
|
||||
// Draw sprites
|
||||
auto it = level.GetThinkerIterator<AActor>();
|
||||
AActor* thing;
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ public:
|
|||
void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub);
|
||||
|
||||
void AddWall(HWWall *w);
|
||||
void AddMirrorSurface(HWWall *w, FRenderState& state);
|
||||
void AddMirrorSurface(HWWallDispatcher* di, HWWall *w, FRenderState& state);
|
||||
void AddFlat(HWFlat *flat, bool fog);
|
||||
void AddSprite(HWSprite *sprite, bool translucent);
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ void HWDrawInfo::AddWall(HWWall *wall)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWDrawInfo::AddMirrorSurface(HWWall *w, FRenderState& state)
|
||||
void HWDrawInfo::AddMirrorSurface(HWWallDispatcher* di, HWWall *w, FRenderState& state)
|
||||
{
|
||||
w->type = RENDERWALL_MIRRORSURFACE;
|
||||
auto newwall = drawlists[GLDL_TRANSLUCENTBORDER].NewWall();
|
||||
|
|
@ -87,7 +87,7 @@ void HWDrawInfo::AddMirrorSurface(HWWall *w, FRenderState& state)
|
|||
{
|
||||
newwall->SetupLights(this, state, lightdata);
|
||||
}
|
||||
newwall->ProcessDecals(this, state);
|
||||
newwall->ProcessDecals(di, state);
|
||||
newwall->dynlightindex = -1; // the environment map should not be affected by lights - only the decals.
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -281,8 +281,8 @@ public:
|
|||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
float bch1, float bch2, float bfh1, float bfh2);
|
||||
|
||||
void ProcessDecal(HWDrawInfo* di, FRenderState& state, DBaseDecal* decal, const FVector3& normal);
|
||||
void ProcessDecals(HWDrawInfo* di, FRenderState& state);
|
||||
void ProcessDecal(HWWallDispatcher* di, FRenderState& state, DBaseDecal* decal, const FVector3& normal);
|
||||
void ProcessDecals(HWWallDispatcher* di, FRenderState& state);
|
||||
|
||||
int CreateVertices(FFlatVertex*& ptr, bool nosplit);
|
||||
void SplitLeftEdge(FFlatVertex*& ptr);
|
||||
|
|
@ -427,8 +427,9 @@ public:
|
|||
void DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct FDynLightData;
|
||||
struct FLightNode;
|
||||
class FRenderState;
|
||||
|
||||
struct DecalVertex
|
||||
{
|
||||
|
|
@ -455,7 +456,7 @@ struct HWDecal
|
|||
FVector3 Normal;
|
||||
|
||||
void DrawDecal(HWDrawInfo *di, FRenderState &state);
|
||||
|
||||
void SetupLights(HWDrawInfo* di, FRenderState& state, FDynLightData& lightdata, Plane p, FLightNode* node);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ struct HWMeshHelper
|
|||
TArray<HWWall> portals;
|
||||
TArray<HWMissing> lower;
|
||||
TArray<HWMissing> upper;
|
||||
TArray<HWDecal> decals[2];
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -77,4 +78,10 @@ struct HWWallDispatcher
|
|||
mh->portals.Push(*wal);
|
||||
}
|
||||
|
||||
HWDecal* AddDecal(bool onmirror)
|
||||
{
|
||||
if (di) return di->AddDecal(onmirror);
|
||||
mh->decals[onmirror].Reserve(1);
|
||||
return &mh->decals[onmirror].Last();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -524,24 +524,23 @@ void HWWall::PutWall(HWWallDispatcher *di, FRenderState& state, bool translucent
|
|||
{
|
||||
flags &= ~HWF_GLOW;
|
||||
}
|
||||
|
||||
bool solid;
|
||||
if (passflag[type] == 1) solid = true;
|
||||
else if (type == RENDERWALL_FFBLOCK) solid = texture && !texture->isMasked();
|
||||
else solid = false;
|
||||
|
||||
bool hasDecals = solid && seg->sidedef && seg->sidedef->AttachedDecals;
|
||||
if (hasDecals)
|
||||
{
|
||||
// If we want to use the light infos for the decal we cannot delay the creation until the render pass.
|
||||
if (ddi->Level->HasDynamicLights && !ddi->isFullbrightScene() && texture != nullptr)
|
||||
{
|
||||
SetupLights(ddi, state, lightdata);
|
||||
}
|
||||
ProcessDecals(ddi, state);
|
||||
}
|
||||
}
|
||||
|
||||
bool solid;
|
||||
if (passflag[type] == 1) solid = true;
|
||||
else if (type == RENDERWALL_FFBLOCK) solid = texture && !texture->isMasked();
|
||||
else solid = false;
|
||||
|
||||
bool hasDecals = solid && seg->sidedef && seg->sidedef->AttachedDecals;
|
||||
if (hasDecals)
|
||||
{
|
||||
// If we want to use the light infos for the decal we cannot delay the creation until the render pass.
|
||||
if (ddi && ddi->Level->HasDynamicLights && !ddi->isFullbrightScene() && texture != nullptr)
|
||||
{
|
||||
SetupLights(ddi, state, lightdata);
|
||||
}
|
||||
ProcessDecals(di, state);
|
||||
}
|
||||
|
||||
di->AddWall(this);
|
||||
|
||||
|
|
@ -631,7 +630,7 @@ void HWWall::PutPortal(HWWallDispatcher *di, FRenderState& state, int ptype, int
|
|||
if (gl_mirror_envmap)
|
||||
{
|
||||
// draw a reflective layer over the mirror
|
||||
ddi->AddMirrorSurface(this, state);
|
||||
ddi->AddMirrorSurface(di, this, state);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue