Use HWFlat for ceilings and floors

This commit is contained in:
Magnus Norddahl 2023-12-05 10:01:03 +01:00
commit ac212e0147
18 changed files with 266 additions and 626 deletions

View file

@ -727,7 +727,6 @@ set( FASTMATH_SOURCES
rendering/hwrenderer/scene/hw_clipper.cpp
rendering/hwrenderer/scene/hw_flats.cpp
rendering/hwrenderer/scene/hw_portal.cpp
rendering/hwrenderer/scene/hw_meshportal.cpp
rendering/hwrenderer/scene/hw_renderhacks.cpp
rendering/hwrenderer/scene/hw_sky.cpp
rendering/hwrenderer/scene/hw_skyportal.cpp
@ -896,7 +895,6 @@ set (PCH_SOURCES
rendering/hwrenderer/scene/hw_lighting.cpp
rendering/hwrenderer/scene/hw_drawlistadd.cpp
rendering/hwrenderer/scene/hw_setcolor.cpp
rendering/hwrenderer/scene/hw_meshcache.cpp
maploader/edata.cpp
maploader/specials.cpp
maploader/maploader.cpp

View file

@ -83,7 +83,6 @@
#include "vm.h"
#include "texturemanager.h"
#include "hw_vertexbuilder.h"
#include "scene/hw_meshcache.h"
#include "version.h"
#include "vulkan/accelstructs/halffloat.h"
@ -3713,7 +3712,6 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
InitRenderInfo(); // create hardware independent renderer resources for the level. This must be done BEFORE the PolyObj Spawn!!!
Level->ClearDynamic3DFloorData(); // CreateVBO must be run on the plain 3D floor data.
CreateVBO(*screen->RenderState(), Level->sectors);
meshcache.Clear();
for (auto &sec : Level->sectors)
{

View file

@ -8,9 +8,11 @@
#include "g_levellocals.h"
#include "a_dynlight.h"
#include "hw_renderstate.h"
#include "hw_vertexbuilder.h"
#include "hwrenderer/scene/hw_drawstructs.h"
#include "hwrenderer/scene/hw_drawinfo.h"
#include "hwrenderer/scene/hw_walldispatcher.h"
#include "hwrenderer/scene/hw_flatdispatcher.h"
#include "common/rendering/hwrenderer/data/hw_meshbuilder.h"
#include "common/rendering/vulkan/accelstructs/vk_lightmap.h"
#include "common/rendering/vulkan/accelstructs/halffloat.h"
@ -88,6 +90,8 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap)
}
}
MeshBuilder state;
// Create surface objects for all visible side parts
for (unsigned int i = 0; i < doomMap.sides.Size(); i++)
{
@ -104,7 +108,6 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap)
sector_t* front = side->sector;
sector_t* back = (side->linedef->frontsector == front) ? side->linedef->backsector : side->linedef->frontsector;
MeshBuilder state;
HWMeshHelper result;
HWWallDispatcher disp(&doomMap, &result, ELightMode::ZDoomSoftware);
HWWall wall;
@ -150,8 +153,18 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap)
MeshUniformIndexes.Push(uniformsIndex);
}
}
for (MeshDrawCommand& command : it.second.mIndexedDraws)
{
for (int i = command.Start, end = command.Start + command.Count; i < end; i++)
{
MeshVertices.Push(state.mVertices[state.mIndexes[i]]);
MeshUniformIndexes.Push(uniformsIndex);
}
}
}
state.mSortedLists.clear();
state.mVertices.Clear();
state.mIndexes.Clear();
DoomLevelMeshSurface surf;
surf.Submesh = this;
@ -177,20 +190,103 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap)
}
// Create surfaces for all flats
for (unsigned int i = 0; i < doomMap.subsectors.Size(); i++)
for (unsigned int i = 0; i < doomMap.sectors.Size(); i++)
{
subsector_t* sub = &doomMap.subsectors[i];
if (sub->numlines < 3 || !sub->sector)
continue;
sector_t* sector = sub->sector;
CreateFloorSurface(doomMap, sub, sector, nullptr, i);
CreateCeilingSurface(doomMap, sub, sector, nullptr, i);
for (unsigned int j = 0; j < sector->e->XFloor.ffloors.Size(); j++)
sector_t* sector = &doomMap.sectors[i];
for (FSection& section : doomMap.sections.SectionsForSector(i))
{
CreateFloorSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i);
CreateCeilingSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i);
int sectionIndex = doomMap.sections.SectionIndex(&section);
HWFlatMeshHelper result;
HWFlatDispatcher disp(&doomMap, &result, ELightMode::ZDoomSoftware);
HWFlat flat;
flat.section = &section;
flat.ProcessSector(&disp, state, sector);
// Part 1: solid geometry. This is set up so that there are no transparent parts
state.SetDepthFunc(DF_Less);
state.ClearDepthBias();
state.EnableTexture(gl_texture);
state.EnableBrightmap(true);
for (HWFlat& flatpart : result.list)
{
if (flatpart.texture && flatpart.texture->isMasked())
{
state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
}
else
{
state.AlphaFunc(Alpha_GEqual, 0.f);
}
flatpart.DrawFlat(&disp, state, false);
int pipelineID = 0;
int uniformsIndex = 0;
bool foundDraw = false;
for (auto& it : state.mSortedLists)
{
const MeshApplyState& applyState = it.first;
pipelineID = screen->GetLevelMeshPipelineID(applyState.applyData, applyState.surfaceUniforms, applyState.material);
uniformsIndex = MeshSurfaceUniforms.Size();
MeshSurfaceUniforms.Push(applyState.surfaceUniforms);
MeshSurfaceMaterials.Push(applyState.material);
foundDraw = true;
break;
}
state.mSortedLists.clear();
state.mVertices.Clear();
state.mIndexes.Clear();
if (!foundDraw)
continue;
auto plane = sector->GetSecPlane(flatpart.ceiling);
DoomLevelMeshSurface surf;
surf.Submesh = this;
surf.Type = flatpart.ceiling ? ST_CEILING : ST_FLOOR;
surf.ControlSector = flatpart.controlsector ? flatpart.controlsector->model : nullptr;
surf.AlwaysUpdate = !!(sector->Flags & SECF_LM_DYNAMIC);
surf.sectorGroup = sectorGroup[sector->Index()];
surf.alpha = flatpart.alpha;
surf.texture = flatpart.texture;
surf.PipelineID = pipelineID;
surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.D);
for (subsector_t* sub : section.subsectors)
{
int startVertIndex = MeshVertices.Size();
for (int i = 0, end = sub->numlines; i < end; i++)
{
auto& vt = sub->firstline[i].v1;
FFlatVertex ffv;
ffv.x = (float)vt->fX();
ffv.y = (float)vt->fY();
ffv.z = (float)plane.ZatPoint(vt);
ffv.u = (float)vt->fX() / 64.f;
ffv.v = -(float)vt->fY() / 64.f;
ffv.lu = 0.0f;
ffv.lv = 0.0f;
ffv.lindex = -1.0f;
MeshVertices.Push(ffv);
MeshUniformIndexes.Push(uniformsIndex);
}
surf.TypeIndex = sub->Index();
surf.Subsector = sub;
surf.startVertIndex = startVertIndex;
surf.numVerts = sub->numlines;
Surfaces.Push(surf);
}
}
}
}
}
@ -532,192 +628,6 @@ void DoomLevelSubmesh::SetSideLightmap(DoomLevelMeshSurface* surface)
}
}
void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *sub, sector_t *sector, sector_t *controlSector, int typeIndex)
{
DoomLevelMeshSurface surf;
surf.Submesh = this;
secplane_t plane;
if (!controlSector)
{
plane = sector->floorplane;
surf.bSky = IsSkySector(sector, sector_t::floor);
}
else
{
plane = controlSector->ceilingplane;
plane.FlipVert();
surf.bSky = false;
}
surf.numVerts = sub->numlines;
surf.startVertIndex = MeshVertices.Size();
surf.texture = TexMan.GetGameTexture((controlSector ? controlSector : sector)->planes[sector_t::floor].Texture);
FGameTexture* txt = surf.texture;
float w = txt->GetDisplayWidth();
float h = txt->GetDisplayHeight();
VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::floor);
int uniformsIndex = MeshSurfaceUniforms.Size();
MeshVertices.Resize(surf.startVertIndex + surf.numVerts);
FFlatVertex* verts = &MeshVertices[surf.startVertIndex];
for (int j = 0; j < surf.numVerts; j++)
{
seg_t* seg = &sub->firstline[j];
FVector2 v1 = ToFVector2(seg->v1->fPos());
FVector2 uv = (mat * FVector4(v1.X / 64.f, -v1.Y / 64.f, 0.f, 1.f)).XY(); // The magic 64.f and negative Y is based on SetFlatVertex
verts[j].x = v1.X;
verts[j].y = v1.Y;
verts[j].z = (float)plane.ZatPoint(v1);
verts[j].u = uv.X;
verts[j].v = uv.Y;
MeshUniformIndexes.Push(uniformsIndex);
}
surf.Type = ST_FLOOR;
surf.TypeIndex = typeIndex;
surf.sampleDimension = (controlSector ? controlSector : sector)->planes[sector_t::floor].LightmapSampleDistance;
surf.ControlSector = controlSector;
surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.D);
surf.sectorGroup = sectorGroup[sector->Index()];
surf.AlwaysUpdate = !!(sector->Flags & SECF_LM_DYNAMIC);
surf.Subsector = sub;
SurfaceUniforms uniforms = DefaultUniforms();
uniforms.uLightLevel = sector->lightlevel * (1.0f / 255.0f);
FMaterialState material;
material.mMaterial = FMaterial::ValidateTexture(txt, 0);
material.mClampMode = CLAMP_NONE;
material.mTranslation = 0;
material.mOverrideShader = -1;
material.mChanged = true;
if (material.mMaterial)
{
auto scale = material.mMaterial->GetDetailScale();
uniforms.uDetailParms = { scale.X, scale.Y, 2, 0 };
}
MeshSurfaceUniforms.Push(uniforms);
MeshSurfaceMaterials.Push(material);
Surfaces.Push(surf);
}
void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* sub, sector_t* sector, sector_t* controlSector, int typeIndex)
{
DoomLevelMeshSurface surf;
surf.Submesh = this;
secplane_t plane;
if (!controlSector)
{
plane = sector->ceilingplane;
surf.bSky = IsSkySector(sector, sector_t::ceiling);
}
else
{
plane = controlSector->floorplane;
plane.FlipVert();
surf.bSky = false;
}
surf.numVerts = sub->numlines;
surf.startVertIndex = MeshVertices.Size();
surf.texture = TexMan.GetGameTexture((controlSector ? controlSector : sector)->planes[sector_t::ceiling].Texture);
FGameTexture* txt = surf.texture;
float w = txt->GetDisplayWidth();
float h = txt->GetDisplayHeight();
VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::ceiling);
int uniformsIndex = MeshSurfaceUniforms.Size();
MeshVertices.Resize(surf.startVertIndex + surf.numVerts);
FFlatVertex* verts = &MeshVertices[surf.startVertIndex];
for (int j = 0; j < surf.numVerts; j++)
{
seg_t* seg = &sub->firstline[j];
FVector2 v1 = ToFVector2(seg->v1->fPos());
FVector2 uv = (mat * FVector4(v1.X / 64.f, -v1.Y / 64.f, 0.f, 1.f)).XY(); // The magic 64.f and negative Y is based on SetFlatVertex
verts[j].x = v1.X;
verts[j].y = v1.Y;
verts[j].z = (float)plane.ZatPoint(v1);
verts[j].u = uv.X;
verts[j].v = uv.Y;
MeshUniformIndexes.Push(uniformsIndex);
}
surf.Type = ST_CEILING;
surf.TypeIndex = typeIndex;
surf.sampleDimension = (controlSector ? controlSector : sector)->planes[sector_t::ceiling].LightmapSampleDistance;
surf.ControlSector = controlSector;
surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.D);
surf.sectorGroup = sectorGroup[sector->Index()];
surf.AlwaysUpdate = !!(sector->Flags & SECF_LM_DYNAMIC);
surf.Subsector = sub;
SurfaceUniforms uniforms = DefaultUniforms();
uniforms.uLightLevel = sector->lightlevel * (1.0f / 255.0f);
FMaterialState material;
material.mMaterial = FMaterial::ValidateTexture(txt, 0);
material.mClampMode = CLAMP_NONE;
material.mTranslation = 0;
material.mOverrideShader = -1;
material.mChanged = true;
if (material.mMaterial)
{
auto scale = material.mMaterial->GetDetailScale();
uniforms.uDetailParms = { scale.X, scale.Y, 2, 0 };
}
MeshSurfaceUniforms.Push(uniforms);
MeshSurfaceMaterials.Push(material);
Surfaces.Push(surf);
}
void DoomLevelSubmesh::CreateSubsectorSurfaces(FLevelLocals &doomMap)
{
for (unsigned int i = 0; i < doomMap.subsectors.Size(); i++)
{
subsector_t *sub = &doomMap.subsectors[i];
if (sub->numlines < 3)
{
continue;
}
sector_t *sector = sub->sector;
if (!sector)
continue;
CreateFloorSurface(doomMap, sub, sector, nullptr, i);
CreateCeilingSurface(doomMap, sub, sector, nullptr, i);
for (unsigned int j = 0; j < sector->e->XFloor.ffloors.Size(); j++)
{
CreateFloorSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i);
CreateCeilingSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i);
}
}
}
bool DoomLevelSubmesh::IsSkySector(sector_t* sector, int plane)
{
// plane is either sector_t::ceiling or sector_t::floor
return sector->GetTexture(plane) == skyflatnum;
}
bool DoomLevelSubmesh::IsDegenerate(const FVector3 &v0, const FVector3 &v1, const FVector3 &v2)
{
// A degenerate triangle has a zero cross product for two of its sides.
@ -933,39 +843,3 @@ void DoomLevelSubmesh::BuildSurfaceParams(int lightMapTextureWidth, int lightMap
surface.AtlasTile.Width = width;
surface.AtlasTile.Height = height;
}
SurfaceUniforms DoomLevelSubmesh::DefaultUniforms()
{
SurfaceUniforms surfaceUniforms = {};
surfaceUniforms.uFogColor = toFVector4(PalEntry(0xffffffff));
surfaceUniforms.uDesaturationFactor = 0.0f;
surfaceUniforms.uAlphaThreshold = 0.5f;
surfaceUniforms.uAddColor = toFVector4(PalEntry(0));
surfaceUniforms.uObjectColor = toFVector4(PalEntry(0xffffffff));
surfaceUniforms.uObjectColor2 = toFVector4(PalEntry(0));
surfaceUniforms.uTextureBlendColor = toFVector4(PalEntry(0));
surfaceUniforms.uTextureAddColor = toFVector4(PalEntry(0));
surfaceUniforms.uTextureModulateColor = toFVector4(PalEntry(0));
surfaceUniforms.uLightDist = 0.0f;
surfaceUniforms.uLightFactor = 0.0f;
surfaceUniforms.uFogDensity = 0.0f;
surfaceUniforms.uLightLevel = -1.0f;
surfaceUniforms.uInterpolationFactor = 0;
surfaceUniforms.uVertexColor = { 1.0f, 1.0f, 1.0f, 1.0f };
surfaceUniforms.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f };
surfaceUniforms.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f };
surfaceUniforms.uGlowTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
surfaceUniforms.uGlowBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
surfaceUniforms.uGradientTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
surfaceUniforms.uGradientBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
surfaceUniforms.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
surfaceUniforms.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
surfaceUniforms.uDynLightColor = { 0.0f, 0.0f, 0.0f, 1.0f };
surfaceUniforms.uDetailParms = { 0.0f, 0.0f, 0.0f, 0.0f };
#ifdef NPOT_EMULATION
surfaceUniforms.uNpotEmulation = { 0,0,0,0 };
#endif
surfaceUniforms.uClipSplit.X = -1000000.f;
surfaceUniforms.uClipSplit.Y = 1000000.f;
return surfaceUniforms;
}

View file

@ -58,10 +58,6 @@ private:
void CreateStaticSurfaces(FLevelLocals& doomMap);
void CreateDynamicSurfaces(FLevelLocals& doomMap);
void CreateSubsectorSurfaces(FLevelLocals& doomMap);
void CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* sub, sector_t* sector, sector_t* controlSector, int typeIndex);
void CreateFloorSurface(FLevelLocals& doomMap, subsector_t* sub, sector_t* sector, sector_t* controlSector, int typeIndex);
void SetSubsectorLightmap(DoomLevelMeshSurface* surface);
void SetSideLightmap(DoomLevelMeshSurface* surface);
@ -69,8 +65,6 @@ private:
void CreateIndexes();
static bool IsSkySector(sector_t* sector, int plane);
static FVector4 ToPlane(const FVector3& pt1, const FVector3& pt2, const FVector3& pt3)
{
FVector3 n = ((pt2 - pt1) ^ (pt3 - pt2)).Unit();
@ -111,8 +105,6 @@ private:
static FVector2 ToFVector2(const DVector2& v) { return FVector2((float)v.X, (float)v.Y); }
static FVector3 ToFVector3(const DVector3& v) { return FVector3((float)v.X, (float)v.Y, (float)v.Z); }
static FVector4 ToFVector4(const DVector4& v) { return FVector4((float)v.X, (float)v.Y, (float)v.Z, (float)v.W); }
static SurfaceUniforms DefaultUniforms();
};
static_assert(alignof(FVector2) == alignof(float[2]) && sizeof(FVector2) == sizeof(float) * 2);

View file

@ -47,7 +47,6 @@
#include "hwrenderer/scene/hw_fakeflat.h"
#include "hwrenderer/scene/hw_clipper.h"
#include "hwrenderer/scene/hw_portal.h"
#include "hwrenderer/scene/hw_meshcache.h"
#include "hwrenderer/scene/hw_drawcontext.h"
#include "hw_vrmodes.h"
@ -134,8 +133,6 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou
hw_ClearFakeFlat(&mainthread_drawctx);
meshcache.Update(&mainthread_drawctx, mainvp);
// Render (potentially) multiple views for stereo 3d
// Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode.
auto vrmode = VRMode::GetVRMode(mainview && toscreen);

View file

@ -42,8 +42,8 @@
#include "hw_clock.h"
#include "flatvertices.h"
#include "hw_vertexbuilder.h"
#include "hw_meshportal.h"
#include "hw_walldispatcher.h"
#include "hw_flatdispatcher.h"
#ifdef ARCH_IA32
#include <immintrin.h>
@ -52,7 +52,6 @@
CVAR(Bool, gl_multithread, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
EXTERN_CVAR(Float, r_actorspriteshadowdist)
EXTERN_CVAR(Bool, gl_meshcache)
thread_local bool isWorkerThread;
ctpl::thread_pool renderPool(1);
@ -109,6 +108,7 @@ void HWDrawInfo::WorkerThread()
{
sector_t *front, *back;
HWWallDispatcher disp(this);
HWFlatDispatcher fdisp(this);
FRenderState& state = *screen->RenderState();
@ -171,23 +171,12 @@ void HWDrawInfo::WorkerThread()
}
else back = nullptr;
if (MeshBSP)
{
SetupWall.Clock();
HWPortalWall portalwall;
portalwall.Process(&disp, state, job->seg, front, back);
rendered_lines++;
SetupWall.Unclock();
}
else
{
HWWall wall;
SetupWall.Clock();
wall.sub = job->sub;
wall.Process(&disp, state, job->seg, front, back);
rendered_lines++;
SetupWall.Unclock();
}
HWWall wall;
SetupWall.Clock();
wall.sub = job->sub;
wall.Process(&disp, state, job->seg, front, back);
rendered_lines++;
SetupWall.Unclock();
break;
}
@ -197,7 +186,7 @@ void HWDrawInfo::WorkerThread()
SetupFlat.Clock();
flat.section = job->sub->section;
front = hw_FakeFlat(drawctx, job->sub->render_sector, in_area, false);
flat.ProcessSector(this, state, front);
flat.ProcessSector(&fdisp, state, front);
SetupFlat.Unclock();
break;
}
@ -361,15 +350,6 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
{
jobQueue.AddJob(RenderJob::WallJob, seg->Subsector, seg);
}
else if (MeshBSP)
{
SetupWall.Clock();
HWPortalWall portalwall;
HWWallDispatcher disp(this);
portalwall.Process(&disp, state, seg, currentsector, backsector);
rendered_lines++;
SetupWall.Unclock();
}
else
{
HWWall wall;
@ -757,20 +737,18 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
{
srf |= SSRF_PROCESSED;
if (!MeshBSP)
if (multithread)
{
if (multithread)
{
jobQueue.AddJob(RenderJob::FlatJob, sub);
}
else
{
HWFlat flat;
flat.section = sub->section;
SetupFlat.Clock();
flat.ProcessSector(this, state, fakesector);
SetupFlat.Unclock();
}
jobQueue.AddJob(RenderJob::FlatJob, sub);
}
else
{
HWFlat flat;
flat.section = sub->section;
HWFlatDispatcher disp(this);
SetupFlat.Clock();
flat.ProcessSector(&disp, state, fakesector);
SetupFlat.Unclock();
}
}
// mark subsector as processed - but mark for rendering only if it has an actual area.
@ -870,7 +848,6 @@ void HWDrawInfo::RenderBSP(void *node, bool drawpsprites, FRenderState& state)
validcount++; // used for processing sidedefs only once by the renderer.
MeshBSP = gl_meshcache;
multithread = gl_multithread;
if (multithread)
{

View file

@ -43,7 +43,6 @@
#include "flatvertices.h"
#include "hw_vrmodes.h"
#include "hw_clipper.h"
#include "hw_meshcache.h"
#include "v_draw.h"
#include "texturemanager.h"
#include "actorinlines.h"
@ -66,7 +65,6 @@ CVAR(Float, gl_mask_sprite_threshold, 0.5f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, gl_coronas, true, CVAR_ARCHIVE);
CVAR(Bool, gl_meshcache, false, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/)
CVAR(Bool, gl_levelmesh, false, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/)
sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back);
@ -594,21 +592,11 @@ void HWDrawInfo::RenderScene(FRenderState &state)
drawlists[GLDL_PLAINWALLS].DrawWalls(this, state, false);
drawlists[GLDL_PLAINFLATS].DrawFlats(this, state, false);
if (gl_meshcache && meshcache.Opaque)
{
meshcache.Opaque->Draw(state);
}
// Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show
state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
drawlists[GLDL_MASKEDWALLS].DrawWalls(this, state, false);
drawlists[GLDL_MASKEDFLATS].DrawFlats(this, state, false);
if (gl_meshcache && meshcache.Translucent)
{
meshcache.Translucent->Draw(state);
}
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
if (drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
{
@ -617,13 +605,6 @@ void HWDrawInfo::RenderScene(FRenderState &state)
state.ClearDepthBias();
}
if (gl_meshcache && meshcache.TranslucentDepthBiased)
{
state.SetDepthBias(-1, -128);
meshcache.TranslucentDepthBiased->Draw(state);
state.ClearDepthBias();
}
drawlists[GLDL_MODELS].Draw(this, state, false);
state.SetRenderStyle(STYLE_Translucent);

View file

@ -181,8 +181,6 @@ struct HWDrawInfo
fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster.
bool multithread;
bool MeshBSP = false;
bool MeshBuilding = false;
TArray<bool> QueryResultsBuffer;
HWDrawInfo(HWDrawContext* drawctx) : drawctx(drawctx) { for (HWDrawList& list : drawlists) list.drawctx = drawctx; }

View file

@ -39,6 +39,7 @@
#include "hw_fakeflat.h"
#include "hw_drawcontext.h"
#include "hw_walldispatcher.h"
#include "hw_flatdispatcher.h"
//==========================================================================
//
@ -714,8 +715,9 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i
case DrawType_FLAT:
{
HWFlat * f= flats[drawitems[i].index];
HWFlatDispatcher dis(di);
RenderFlat.Clock();
f->DrawFlat(di, state, translucent);
f->DrawFlat(&dis, state, translucent);
RenderFlat.Unclock();
}
break;
@ -777,10 +779,11 @@ void HWDrawList::DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent
//==========================================================================
void HWDrawList::DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent)
{
HWFlatDispatcher dis(di);
RenderFlat.Clock();
for (unsigned i = 0; i<drawitems.Size(); i++)
{
flats[drawitems[i].index]->DrawFlat(di, state, translucent);
flats[drawitems[i].index]->DrawFlat(&dis, state, translucent);
}
RenderFlat.Unclock();
}

View file

@ -33,6 +33,7 @@ struct FSection;
enum area_t : int;
class HWDrawContext;
class DoomLevelMeshSurface;
struct HWFlatDispatcher;
enum HWRenderStyle
{
@ -347,16 +348,18 @@ public:
int dynlightindex;
void CreateSkyboxVertices(FFlatVertex *buffer);
void SetupLights(HWDrawInfo *di, FRenderState& state, FLightNode *head, FDynLightData &lightdata, int portalgroup);
F3DFloor* controlsector;
void PutFlat(HWDrawInfo *di, bool fog = false);
void Process(HWDrawInfo *di, FRenderState& state, sector_t * model, int whichplane, bool notexture);
void CreateSkyboxVertices(FFlatVertex *buffer);
void SetupLights(HWFlatDispatcher *di, FRenderState& state, FLightNode *head, FDynLightData &lightdata, int portalgroup);
void PutFlat(HWFlatDispatcher *di, bool fog = false);
void Process(HWFlatDispatcher *di, FRenderState& state, sector_t * model, int whichplane, bool notexture);
void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside);
void ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies.
void ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies.
void DrawSubsectors(HWDrawInfo *di, FRenderState &state);
void DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent);
void DrawSubsectors(HWFlatDispatcher *di, FRenderState &state);
void DrawFlat(HWFlatDispatcher *di, FRenderState &state, bool translucent);
void DrawOtherPlanes(HWDrawInfo *di, FRenderState &state);
void DrawFloodPlanes(HWDrawInfo *di, FRenderState &state);

View file

@ -0,0 +1,86 @@
#pragma once
struct HWFlatMeshHelper
{
TArray<HWFlat> list;
TArray<HWFlat> translucent;
TArray<HWFlat> translucentborder;
TArray<HWFlat> portals;
uint8_t section_renderflags = 0;
};
struct HWFlatDispatcher
{
FLevelLocals* Level;
HWDrawInfo* di;
HWFlatMeshHelper* mh;
ELightMode lightmode;
HWFlatDispatcher(HWDrawInfo* info)
{
Level = info->Level;
di = info;
mh = nullptr;
lightmode = info->lightmode;
}
HWFlatDispatcher(FLevelLocals* lev, HWFlatMeshHelper* help, ELightMode lm)
{
Level = lev;
di = nullptr;
mh = help;
lightmode = lm;
}
bool isFullbrightScene()
{
// The mesh builder cannot know this and must treat everything as not fullbright.
return di && di->isFullbrightScene();
}
void AddFlat(HWFlat* flat, bool fog)
{
if (di)
{
di->AddFlat(flat, fog);
}
else
{
if (flat->renderstyle != STYLE_Translucent || flat->alpha < 1.f - FLT_EPSILON || fog || flat->texture == nullptr)
{
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
if (flat->renderflags & SSRF_RENDER3DPLANES)
mh->translucent.Push(*flat);
else
mh->translucentborder.Push(*flat);
}
else if (flat->texture->GetTranslucency())
{
if (flat->stack)
{
mh->translucentborder.Push(*flat);
}
else if ((flat->renderflags & SSRF_RENDER3DPLANES) && !flat->plane.plane.isSlope())
{
mh->translucent.Push(*flat);
}
else
{
mh->list.Push(*flat);
}
}
else
{
bool masked = flat->texture->isMasked() && ((flat->renderflags & SSRF_RENDER3DPLANES) || flat->stack);
if (masked)
{
mh->list.Push(*flat); // Do we need a different list for this?
}
else
{
mh->list.Push(*flat);
}
}
}
}
};

View file

@ -47,6 +47,7 @@
#include "hw_drawstructs.h"
#include "hw_renderstate.h"
#include "texturemanager.h"
#include "hw_flatdispatcher.h"
#ifdef _DEBUG
CVAR(Int, gl_breaksec, -1, 0)
@ -156,8 +157,14 @@ void HWFlat::CreateSkyboxVertices(FFlatVertex *vert)
//
//==========================================================================
void HWFlat::SetupLights(HWDrawInfo *di, FRenderState& state, FLightNode * node, FDynLightData &lightdata, int portalgroup)
void HWFlat::SetupLights(HWFlatDispatcher *di, FRenderState& state, FLightNode * node, FDynLightData &lightdata, int portalgroup)
{
if (!di->di)
{
dynlightindex = -1;
return;
}
Plane p;
lightdata.Clear();
@ -200,7 +207,7 @@ void HWFlat::SetupLights(HWDrawInfo *di, FRenderState& state, FLightNode * node,
//
//==========================================================================
void HWFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state)
void HWFlat::DrawSubsectors(HWFlatDispatcher *di, FRenderState &state)
{
if (di->Level->HasDynamicLights && !di->isFullbrightScene())
{
@ -309,7 +316,7 @@ void HWFlat::DrawFloodPlanes(HWDrawInfo *di, FRenderState &state)
//
//
//==========================================================================
void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
void HWFlat::DrawFlat(HWFlatDispatcher *di, FRenderState &state, bool translucent)
{
#ifdef _DEBUG
if (sector->sectornum == gl_breaksec)
@ -323,7 +330,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
state.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y);
SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, alpha);
SetFog(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), &Colormap, false, di->drawctx->portalState.inskybox);
SetFog(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), &Colormap, false, di->di ? di->di->drawctx->portalState.inskybox : false);
state.SetObjectColor(FlatColor | 0xff000000);
state.SetAddColor(AddColor | 0xff000000);
state.ApplyTextureManipulation(TextureFx);
@ -331,11 +338,13 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
if (hacktype & SSRF_PLANEHACK)
{
DrawOtherPlanes(di, state);
if (di->di)
DrawOtherPlanes(di->di, state);
}
else if (hacktype & SSRF_FLOODHACK)
{
DrawFloodPlanes(di, state);
if (di->di)
DrawFloodPlanes(di->di, state);
}
else if (!translucent)
{
@ -391,7 +400,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
//
//==========================================================================
inline void HWFlat::PutFlat(HWDrawInfo *di, bool fog)
inline void HWFlat::PutFlat(HWFlatDispatcher *di, bool fog)
{
if (di->isFullbrightScene())
{
@ -407,7 +416,7 @@ inline void HWFlat::PutFlat(HWDrawInfo *di, bool fog)
//
//==========================================================================
void HWFlat::Process(HWDrawInfo *di, FRenderState& state, sector_t * model, int whichplane, bool fog)
void HWFlat::Process(HWFlatDispatcher *di, FRenderState& state, sector_t * model, int whichplane, bool fog)
{
plane.GetFromSector(model, whichplane);
if (whichplane != int(ceiling))
@ -478,6 +487,8 @@ void HWFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside)
alpha = rover->alpha/255.0f;
renderstyle = rover->flags&FF_ADDITIVETRANS? STYLE_Add : STYLE_Translucent;
iboindex = plane.vindex;
controlsector = rover;
}
//==========================================================================
@ -488,7 +499,7 @@ void HWFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside)
//
//==========================================================================
void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * frontsector, int which)
void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t * frontsector, int which)
{
lightlist_t * light;
FSectorPortal *port;
@ -500,6 +511,8 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
}
#endif
controlsector = nullptr;
// Get the real sector for this one.
sector = &di->Level->sectors[frontsector->sectornum];
extsector_t::xfloor &x = sector->e->XFloor;
@ -507,13 +520,13 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
hacktype = (which & (SSRF_PLANEHACK|SSRF_FLOODHACK));
uint8_t sink;
uint8_t &srf = hacktype? sink : di->section_renderflags[di->Level->sections.SectionIndex(section)];
const auto &vp = di->Viewpoint;
uint8_t &srf = hacktype? sink : (di->di ? di->di->section_renderflags[di->Level->sections.SectionIndex(section)] : di->mh->section_renderflags);
FRenderViewpoint* vp = di->di ? &di->di->Viewpoint : nullptr;
//
// Lightmaps
//
if (level.lightmaps)
if (di->di && level.lightmaps)
{
for (int i = 0, count = sector->subsectorcount; i < count; ++i)
{
@ -524,7 +537,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
{
if (auto surface = sector->subsectors[i]->surface[plane].Size() > j ? sector->subsectors[i]->surface[plane][j] : nullptr)
{
di->PushVisibleSurface(surface);
di->di->PushVisibleSurface(surface);
}
}
}
@ -538,7 +551,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
//
//
//
if ((which & SSRF_RENDERFLOOR) && (di->MeshBuilding || frontsector->floorplane.ZatPoint(vp.Pos) <= vp.Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERFLOOR)))
if ((which & SSRF_RENDERFLOOR) && (!di->di || frontsector->floorplane.ZatPoint(vp->Pos) <= vp->Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERFLOOR)))
{
// process the original floor first.
@ -596,7 +609,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
//
//
//
if ((which & SSRF_RENDERCEILING) && (di->MeshBuilding || frontsector->ceilingplane.ZatPoint(vp.Pos) >= vp.Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERCEILING)))
if ((which & SSRF_RENDERCEILING) && (!di->di || frontsector->ceilingplane.ZatPoint(vp->Pos) >= vp->Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERCEILING)))
{
// process the original ceiling first.
@ -681,7 +694,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
double ff_top = rover->top.plane->ZatPoint(sector->centerspot);
if (ff_top < lastceilingheight)
{
if (di->MeshBuilding || vp.Pos.Z <= rover->top.plane->ZatPoint(vp.Pos))
if (!di->di || vp->Pos.Z <= rover->top.plane->ZatPoint(vp->Pos))
{
SetFrom3DFloor(rover, true, !!(rover->flags&FF_FOG));
Colormap.FadeColor = frontsector->Colormap.FadeColor;
@ -695,7 +708,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
double ff_bottom = rover->bottom.plane->ZatPoint(sector->centerspot);
if (ff_bottom < lastceilingheight)
{
if (di->MeshBuilding || vp.Pos.Z <= rover->bottom.plane->ZatPoint(vp.Pos))
if (!di->di || vp->Pos.Z <= rover->bottom.plane->ZatPoint(vp->Pos))
{
SetFrom3DFloor(rover, false, !(rover->flags&FF_FOG));
Colormap.FadeColor = frontsector->Colormap.FadeColor;
@ -721,7 +734,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
double ff_bottom = rover->bottom.plane->ZatPoint(sector->centerspot);
if (ff_bottom > lastfloorheight || (rover->flags&FF_FIX))
{
if (di->MeshBuilding || vp.Pos.Z >= rover->bottom.plane->ZatPoint(vp.Pos))
if (!di->di || vp->Pos.Z >= rover->bottom.plane->ZatPoint(vp->Pos))
{
SetFrom3DFloor(rover, false, !(rover->flags&FF_FOG));
Colormap.FadeColor = frontsector->Colormap.FadeColor;
@ -742,7 +755,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front
double ff_top = rover->top.plane->ZatPoint(sector->centerspot);
if (ff_top > lastfloorheight)
{
if (di->MeshBuilding || vp.Pos.Z >= rover->top.plane->ZatPoint(vp.Pos))
if (!di->di || vp->Pos.Z >= rover->top.plane->ZatPoint(vp->Pos))
{
SetFrom3DFloor(rover, true, !!(rover->flags&FF_FOG));
Colormap.FadeColor = frontsector->Colormap.FadeColor;

View file

@ -1,162 +0,0 @@
#include "hw_meshcache.h"
#include "hw_drawinfo.h"
#include "hw_drawstructs.h"
#include "hw_mesh.h"
#include "hw_fakeflat.h"
#include "hw_vertexbuilder.h"
#include "hw_walldispatcher.h"
#include "g_levellocals.h"
#include <unordered_set>
EXTERN_CVAR(Bool, gl_texture)
EXTERN_CVAR(Float, gl_mask_threshold)
EXTERN_CVAR(Bool, gl_meshcache)
HWMeshCache meshcache;
void HWMeshCache::Clear()
{
#if 0
Sectors.Reset();
#endif
Opaque.reset();
Translucent.reset();
TranslucentDepthBiased.reset();
}
void HWMeshCache::Update(HWDrawContext* drawctx, FRenderViewpoint& vp)
{
if (!gl_meshcache)
return;
auto level = vp.ViewLevel;
#if 0
unsigned int count = level->sectors.Size();
Sectors.Resize(count);
// Look for changes
for (unsigned int i = 0; i < count; i++)
{
auto sector = &level->sectors[i];
auto cacheitem = &Sectors[i];
if (cacheitem->Floorplane != sector->floorplane || cacheitem->Ceilingplane != sector->ceilingplane) // Sector height changes
{
cacheitem->NeedsUpdate = true;
for (line_t* line : sector->Lines)
{
sector_t* backsector = (line->frontsector == sector) ? line->backsector : line->frontsector;
if (backsector)
{
Sectors[backsector->Index()].NeedsUpdate = true;
}
}
}
}
// Update changed sectors
for (unsigned int i = 0; i < count; i++)
{
auto sector = &level->sectors[i];
auto cacheitem = &Sectors[i];
if (cacheitem->NeedsUpdate)
{
cacheitem->NeedsUpdate = false;
cacheitem->Sector = sector;
cacheitem->Floorplane = sector->floorplane;
cacheitem->Ceilingplane = sector->ceilingplane;
cacheitem->Update(vp);
}
}
#endif
if (!Opaque)
{
HWDrawInfo* di = HWDrawInfo::StartDrawInfo(drawctx, vp.ViewLevel, nullptr, vp, nullptr);
di->MeshBuilding = true;
MeshBuilder state;
state.SetShadowData(sector_vertices, sector_indexes);
// Add to the draw lists
unsigned int count = level->sectors.Size();
for (unsigned int i = 0; i < count; i++)
{
auto sector = &level->sectors[i];
// CheckUpdate(state, sector);
std::unordered_set<FSection*> seenSections;
for (int i = 0, count = sector->subsectorcount; i < count; i++)
{
subsector_t* subsector = sector->subsectors[i];
if (seenSections.find(subsector->section) == seenSections.end())
{
seenSections.insert(subsector->section);
HWFlat flat;
flat.section = subsector->section;
sector_t* front = hw_FakeFlat(di->drawctx, subsector->render_sector, area_default, false);
flat.ProcessSector(di, state, front);
}
}
for (line_t* line : sector->Lines)
{
side_t* side = (line->sidedef[0]->sector == sector) ? line->sidedef[0] : line->sidedef[1];
HWWall wall;
HWWallDispatcher disp(di);
wall.sub = sector->subsectors[0];
wall.Process(&disp, state, side->segs[0], sector, (line->sidedef[0]->sector == sector) ? line->backsector : line->frontsector);
}
}
// Convert draw lists to meshes
state.SetDepthMask(true);
state.EnableFog(true);
state.SetRenderStyle(STYLE_Source);
di->drawlists[GLDL_PLAINWALLS].SortWalls();
di->drawlists[GLDL_PLAINFLATS].SortFlats();
di->drawlists[GLDL_MASKEDWALLS].SortWalls();
di->drawlists[GLDL_MASKEDFLATS].SortFlats();
di->drawlists[GLDL_MASKEDWALLSOFS].SortWalls();
// Part 1: solid geometry. This is set up so that there are no transparent parts
state.SetDepthFunc(DF_Less);
state.AlphaFunc(Alpha_GEqual, 0.f);
state.ClearDepthBias();
state.EnableTexture(gl_texture);
state.EnableBrightmap(true);
di->drawlists[GLDL_PLAINWALLS].DrawWalls(di, state, false);
di->drawlists[GLDL_PLAINFLATS].DrawFlats(di, state, false);
Opaque = state.Create();
// Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show
state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
di->drawlists[GLDL_MASKEDWALLS].DrawWalls(di, state, false);
di->drawlists[GLDL_MASKEDFLATS].DrawFlats(di, state, false);
Translucent = state.Create();
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
if (di->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
{
state.SetDepthBias(-1, -128);
di->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(di, state, false);
state.ClearDepthBias();
TranslucentDepthBiased = state.Create();
}
else
{
TranslucentDepthBiased.reset();
}
di->MeshBuilding = false;
di->EndDrawInfo();
}
}

View file

@ -1,36 +0,0 @@
#pragma once
#include "hw_mesh.h"
#include "r_defs.h"
struct FRenderViewpoint;
class HWDrawContext;
#if 0
class HWCachedSector
{
public:
bool NeedsUpdate = true;
sector_t* Sector = nullptr;
secplane_t Floorplane;
secplane_t Ceilingplane;
};
#endif
class HWMeshCache
{
public:
void Clear();
void Update(HWDrawContext* drawctx, FRenderViewpoint& vp);
#if 0
TArray<HWCachedSector> Sectors;
#endif
std::unique_ptr<Mesh> Opaque;
std::unique_ptr<Mesh> Translucent;
std::unique_ptr<Mesh> TranslucentDepthBiased;
};
extern HWMeshCache meshcache;

View file

@ -1,64 +0,0 @@
#include "hw_meshportal.h"
#include "p_local.h"
#include "p_lnspec.h"
#include "a_dynlight.h"
#include "a_sharedglobal.h"
#include "r_defs.h"
#include "r_sky.h"
#include "r_utility.h"
#include "p_maputl.h"
#include "doomdata.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include "texturemanager.h"
#include "hw_dynlightdata.h"
#include "hw_material.h"
#include "hw_cvars.h"
#include "hw_clock.h"
#include "hw_lighting.h"
#include "hw_drawcontext.h"
#include "hw_drawinfo.h"
#include "hw_renderstate.h"
void HWPortalWall::Process(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* frontsector, sector_t* backsector)
{
// The portal code wants a HWWall struct.
if (IsPortal(di, state, seg, frontsector, backsector))
{
HWWall wall;
wall.sub = seg->Subsector;
wall.Process(di, state, seg, frontsector, backsector);
}
}
bool HWPortalWall::IsPortal(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* frontsector, sector_t* backsector)
{
// Note: This is incomplete. It assumes a completely valid map. Good luck adding the full range of checks!
if (seg->linedef->special == Line_Mirror && gl_mirrors)
return true;
if (seg->linedef->special == Line_Horizon)
return true;
if (seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0])
return true;
if (seg->linedef->GetTransferredPortal())
return true;
for (int plane : { sector_t::floor, sector_t::ceiling })
{
FSectorPortal* sportal = frontsector->ValidatePortal(plane);
if (frontsector->ValidatePortal(plane) && !(sportal->mFlags & PORTSF_INSKYBOX)) // no recursions
return true;
if (frontsector->GetTexture(plane) == skyflatnum)
return true;
if (frontsector->GetReflect(plane) > 0)
return true;
}
return false;
}

View file

@ -1,12 +0,0 @@
#pragma once
#include "hw_drawstructs.h"
class HWPortalWall
{
public:
static void Process(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* frontsector, sector_t* backsector);
private:
static bool IsPortal(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* frontsector, sector_t* backsector);
};

View file

@ -42,6 +42,7 @@
#include "hwrenderer/scene/hw_portal.h"
#include "hw_fakeflat.h"
#include "hw_walldispatcher.h"
#include "hw_flatdispatcher.h"
//==========================================================================
//
@ -51,6 +52,7 @@
void HWDrawInfo::DispatchRenderHacks(FRenderState& state)
{
HWFlatDispatcher dis(this);
TMap<int, gl_subsectorrendernode*>::Pair *pair;
TMap<int, gl_floodrendernode*>::Pair *fpair;
TMap<int, gl_subsectorrendernode*>::Iterator ofi(otherFloorPlanes);
@ -59,28 +61,28 @@ void HWDrawInfo::DispatchRenderHacks(FRenderState& state)
while (ofi.NextPair(pair))
{
auto sec = hw_FakeFlat(drawctx, &Level->sectors[pair->Key], in_area, false);
glflat.ProcessSector(this, state, sec, SSRF_RENDERFLOOR | SSRF_PLANEHACK);
glflat.ProcessSector(&dis, state, sec, SSRF_RENDERFLOOR | SSRF_PLANEHACK);
}
TMap<int, gl_subsectorrendernode*>::Iterator oci(otherCeilingPlanes);
while (oci.NextPair(pair))
{
auto sec = hw_FakeFlat(drawctx, &Level->sectors[pair->Key], in_area, false);
glflat.ProcessSector(this, state, sec, SSRF_RENDERCEILING | SSRF_PLANEHACK);
glflat.ProcessSector(&dis, state, sec, SSRF_RENDERCEILING | SSRF_PLANEHACK);
}
TMap<int, gl_floodrendernode*>::Iterator ffi(floodFloorSegs);
while (ffi.NextPair(fpair))
{
auto sec = hw_FakeFlat(drawctx, &Level->sectors[fpair->Key], in_area, false);
glflat.ProcessSector(this, state, sec, SSRF_RENDERFLOOR | SSRF_FLOODHACK);
glflat.ProcessSector(&dis, state, sec, SSRF_RENDERFLOOR | SSRF_FLOODHACK);
}
TMap<int, gl_floodrendernode*>::Iterator fci(floodCeilingSegs);
while (fci.NextPair(fpair))
{
auto sec = hw_FakeFlat(drawctx, &Level->sectors[fpair->Key], in_area, false);
glflat.ProcessSector(this, state, sec, SSRF_RENDERCEILING | SSRF_FLOODHACK);
glflat.ProcessSector(&dis, state, sec, SSRF_RENDERCEILING | SSRF_FLOODHACK);
}
}

View file

@ -45,8 +45,6 @@
#include "hw_skydome.h"
#include "hw_walldispatcher.h"
EXTERN_CVAR(Bool, gl_meshcache);
void SetGlowPlanes(FRenderState &state, const secplane_t& top, const secplane_t& bottom)
{
auto& tn = top.Normal();
@ -491,9 +489,6 @@ const char HWWall::passflag[] = {
//==========================================================================
void HWWall::PutWall(HWWallDispatcher *di, FRenderState& state, bool translucent)
{
if (gl_meshcache && di->di && !di->di->MeshBuilding) // Don't draw walls when only collecting portals
return;
if (texture && texture->GetTranslucency() && passflag[type] == 2)
{
translucent = true;
@ -559,9 +554,6 @@ void HWWall::PutWall(HWWallDispatcher *di, FRenderState& state, bool translucent
void HWWall::PutPortal(HWWallDispatcher *di, FRenderState& state, int ptype, int plane)
{
if (di->di && di->di->MeshBuilding)
return;
HWPortal * portal = nullptr;
auto ddi = di->di;