Disable skyhack for level mesh and fix frustum test against skies
This commit is contained in:
parent
1d635d9a39
commit
8d10617762
5 changed files with 118 additions and 23 deletions
|
|
@ -10,6 +10,7 @@
|
|||
#include "hw_renderstate.h"
|
||||
#include "hw_vertexbuilder.h"
|
||||
#include "hw_dynlightdata.h"
|
||||
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||
#include "hwrenderer/scene/hw_lighting.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||
|
|
@ -329,23 +330,33 @@ void DoomLevelMesh::AddSectorsToDrawLists(const TArray<int>& sectors, LevelMeshD
|
|||
}
|
||||
}
|
||||
|
||||
void DoomLevelMesh::AddSidesToDrawLists(const TArray<int>& sides, LevelMeshDrawLists& lists, HWDrawInfo* di)
|
||||
void DoomLevelMesh::AddSidesToDrawLists(const TArray<int>& sides, LevelMeshDrawLists& lists, HWDrawInfo* di, FRenderState& state)
|
||||
{
|
||||
for (int sideIndex : sides)
|
||||
{
|
||||
for (const DrawRangeInfo& di : Sides[sideIndex].DrawRanges)
|
||||
if (!Sides[sideIndex].NeedsImmediateRendering)
|
||||
{
|
||||
lists.Add(di.DrawType, di.PipelineID, { di.IndexStart, di.IndexStart + di.IndexCount });
|
||||
}
|
||||
for (const DrawRangeInfo& di : Sides[sideIndex].DrawRanges)
|
||||
{
|
||||
lists.Add(di.DrawType, di.PipelineID, { di.IndexStart, di.IndexStart + di.IndexCount });
|
||||
}
|
||||
|
||||
for (const HWMissing& missing : Sides[sideIndex].MissingUpper)
|
||||
{
|
||||
di->AddUpperMissingTexture(missing.side, missing.sub, missing.plane);
|
||||
}
|
||||
for (const HWMissing& missing : Sides[sideIndex].MissingUpper)
|
||||
{
|
||||
di->AddUpperMissingTexture(missing.side, missing.sub, missing.plane);
|
||||
}
|
||||
|
||||
for (const HWMissing& missing : Sides[sideIndex].MissingLower)
|
||||
for (const HWMissing& missing : Sides[sideIndex].MissingLower)
|
||||
{
|
||||
di->AddLowerMissingTexture(missing.side, missing.sub, missing.plane);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
di->AddLowerMissingTexture(missing.side, missing.sub, missing.plane);
|
||||
// To do: is it good enough to just grab the first seg here?
|
||||
side_t* side = &di->Level->sides[sideIndex];
|
||||
seg_t* seg = side->segs[0];
|
||||
di->ProcessSeg(seg, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -673,6 +684,8 @@ void DoomLevelMesh::FreeSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
Sides[sideIndex].MissingUpper.Clear();
|
||||
Sides[sideIndex].MissingLower.Clear();
|
||||
Sides[sideIndex].Decals.Clear();
|
||||
|
||||
Sides[sideIndex].NeedsImmediateRendering = false;
|
||||
}
|
||||
|
||||
void DoomLevelMesh::FreeFlat(FLevelLocals& doomMap, unsigned int sectorIndex)
|
||||
|
|
@ -1088,6 +1101,29 @@ void DoomLevelMesh::CreateSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
state.SetDepthFunc(DF_LEqual);
|
||||
// DrawDecals(state, Decals[0]);
|
||||
|
||||
// These things aren't working properly with the level mesh.
|
||||
bool incompatible = false;
|
||||
for (const HWWall& wall : result.opaque)
|
||||
if ((wall.flags & HWWall::HWF_SKYHACK) != 0)
|
||||
incompatible = true;
|
||||
for (const HWWall& wall : result.masked)
|
||||
if ((wall.flags & HWWall::HWF_SKYHACK) != 0)
|
||||
incompatible = true;
|
||||
for (const HWWall& wall : result.maskedOffset)
|
||||
if ((wall.flags & HWWall::HWF_SKYHACK) != 0)
|
||||
incompatible = true;
|
||||
|
||||
if (result.translucent.size() != 0 || result.translucentBorder.size() != 0 || incompatible)
|
||||
{
|
||||
// For things that HWWall doesn't do correctly when drawn into the level mesh for one reason or another.
|
||||
sideBlock.NeedsImmediateRendering = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const HWWall& portal : result.portals)
|
||||
sideBlock.WallPortals.Push(portal);
|
||||
}
|
||||
|
||||
/*
|
||||
// final pass: translucent stuff
|
||||
state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||
|
|
@ -1102,9 +1138,6 @@ void DoomLevelMesh::CreateSide(FLevelLocals& doomMap, unsigned int sideIndex)
|
|||
state.SetRenderStyle(STYLE_Normal);
|
||||
*/
|
||||
|
||||
for (const HWWall& portal : result.portals)
|
||||
sideBlock.WallPortals.Push(portal);
|
||||
|
||||
for (const HWMissing& missing : result.upper)
|
||||
sideBlock.MissingUpper.Push(missing);
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ struct SideSurfaceBlock
|
|||
TArray<HWMissing> MissingLower;
|
||||
TArray<HWDecalCreateInfo> Decals;
|
||||
bool InSideDecalsList = false;
|
||||
bool NeedsImmediateRendering = false;
|
||||
TArray<DrawRangeInfo> DrawRanges;
|
||||
SurfaceUpdateType UpdateType = SurfaceUpdateType::None;
|
||||
LightListAllocInfo Lights;
|
||||
|
|
@ -152,7 +153,7 @@ public:
|
|||
void ProcessDecals(HWDrawInfo* drawinfo, FRenderState& state);
|
||||
|
||||
void AddSectorsToDrawLists(const TArray<int>& sectors, LevelMeshDrawLists& lists);
|
||||
void AddSidesToDrawLists(const TArray<int>& sides, LevelMeshDrawLists& lists, HWDrawInfo* di);
|
||||
void AddSidesToDrawLists(const TArray<int>& sides, LevelMeshDrawLists& lists, HWDrawInfo* di, FRenderState& state);
|
||||
|
||||
TArray<HWWall>& GetSidePortals(int sideIndex);
|
||||
|
||||
|
|
|
|||
|
|
@ -447,12 +447,13 @@ void HWDrawInfo::RenderPVS(bool drawpsprites, FRenderState& state)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Anything outside the BSP using this?
|
||||
viewx = FLOAT2FIXED(Viewpoint.Pos.X);
|
||||
viewy = FLOAT2FIXED(Viewpoint.Pos.Y);
|
||||
multithread = false;
|
||||
uselevelmesh = true;
|
||||
|
||||
validcount++; // used for processing sidedefs only once by the renderer.
|
||||
|
||||
Bsp.Clock();
|
||||
|
||||
ClipWall.Clock();
|
||||
|
|
@ -504,6 +505,14 @@ void HWDrawInfo::RenderPVS(bool drawpsprites, FRenderState& state)
|
|||
}
|
||||
}
|
||||
|
||||
if (gl_levelmesh)
|
||||
level.levelMesh->CurFrameStats.Portals++;
|
||||
|
||||
SeenFlatsDrawLists.Clear();
|
||||
SeenSidesDrawLists.Clear();
|
||||
level.levelMesh->AddSectorsToDrawLists(SeenSectors.Get(), SeenFlatsDrawLists);
|
||||
level.levelMesh->AddSidesToDrawLists(SeenSides.Get(), SeenSidesDrawLists, this, state);
|
||||
|
||||
if (gl_render_things)
|
||||
{
|
||||
for (int subIndex : SeenSubsectors.Get())
|
||||
|
|
@ -537,6 +546,43 @@ void HWDrawInfo::RenderPVS(bool drawpsprites, FRenderState& state)
|
|||
}
|
||||
}
|
||||
|
||||
void HWDrawInfo::ProcessSeg(seg_t* seg, FRenderState& state)
|
||||
{
|
||||
subsector_t* sub = seg->Subsector;
|
||||
sector_t* front, * back;
|
||||
front = hw_FakeFlat(drawctx, sub->sector, in_area, false);
|
||||
auto backsector = seg->backsector;
|
||||
if (!backsector && seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0]) // For one-sided portals use the portal's destination sector as backsector.
|
||||
{
|
||||
auto portal = seg->linedef->getPortal();
|
||||
backsector = portal->mDestination->frontsector;
|
||||
back = hw_FakeFlat(drawctx, backsector, in_area, true);
|
||||
if (front->floorplane.isSlope() || front->ceilingplane.isSlope() || back->floorplane.isSlope() || back->ceilingplane.isSlope())
|
||||
{
|
||||
// Having a one-sided portal like this with slopes is too messy so let's ignore that case.
|
||||
back = nullptr;
|
||||
}
|
||||
}
|
||||
else if (backsector)
|
||||
{
|
||||
if (front->sectornum == backsector->sectornum || (seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
back = front;
|
||||
}
|
||||
else
|
||||
{
|
||||
back = hw_FakeFlat(drawctx, backsector, in_area, true);
|
||||
}
|
||||
}
|
||||
else back = nullptr;
|
||||
|
||||
HWMeshHelper result;
|
||||
HWWallDispatcher disp(this);
|
||||
HWWall wall;
|
||||
wall.sub = sub;
|
||||
wall.Process(&disp, state, seg, front, back);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// CreateScene
|
||||
|
|
@ -569,14 +615,6 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
|
|||
|
||||
RenderPVS(drawpsprites, state);
|
||||
|
||||
if (gl_levelmesh)
|
||||
level.levelMesh->CurFrameStats.Portals++;
|
||||
|
||||
SeenFlatsDrawLists.Clear();
|
||||
SeenSidesDrawLists.Clear();
|
||||
level.levelMesh->AddSectorsToDrawLists(SeenSectors.Get(), SeenFlatsDrawLists);
|
||||
level.levelMesh->AddSidesToDrawLists(SeenSides.Get(), SeenSidesDrawLists, this);
|
||||
|
||||
// And now the crappy hacks that have to be done to avoid rendering anomalies.
|
||||
// These cannot be multithreaded when the time comes because all these depend
|
||||
// on the global 'validcount' variable.
|
||||
|
|
|
|||
|
|
@ -316,6 +316,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void ProcessSeg(seg_t* seg, FRenderState& state);
|
||||
|
||||
HWPortal * FindPortal(const void * src);
|
||||
void RenderBSPNode(void *node, FRenderState& state);
|
||||
void RenderOrthoNoFog(FRenderState& state);
|
||||
|
|
|
|||
|
|
@ -158,6 +158,27 @@ bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto
|
|||
|
||||
if (frustum)
|
||||
{
|
||||
if (frontsector->GetTexture(sector_t::ceiling) == skyflatnum)
|
||||
{
|
||||
fs_ceilingheight1 = 32768.0;
|
||||
fs_ceilingheight2 = 32768.0;
|
||||
}
|
||||
if (frontsector->GetTexture(sector_t::floor) == skyflatnum)
|
||||
{
|
||||
fs_floorheight1 = -32768.0;
|
||||
fs_floorheight1 = -32768.0;
|
||||
}
|
||||
if (backsector->GetTexture(sector_t::ceiling) == skyflatnum)
|
||||
{
|
||||
bs_ceilingheight1 = 32768.0;
|
||||
bs_ceilingheight2 = 32768.0;
|
||||
}
|
||||
if (backsector->GetTexture(sector_t::floor) == skyflatnum)
|
||||
{
|
||||
bs_floorheight1 = -32768.0;
|
||||
bs_floorheight1 = -32768.0;
|
||||
}
|
||||
|
||||
// Is the line visible by the camera's clip frustum?
|
||||
DVector3 p0(linedef->v1->fX(), std::min(bs_ceilingheight1, fs_ceilingheight1), linedef->v1->fY());
|
||||
DVector3 p1(linedef->v2->fX(), std::min(bs_ceilingheight2, fs_ceilingheight2), linedef->v2->fY());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue