Use HWFlat for ceilings and floors
This commit is contained in:
parent
5443ed76ec
commit
ac212e0147
18 changed files with 266 additions and 626 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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(§ion);
|
||||
|
||||
HWFlatMeshHelper result;
|
||||
HWFlatDispatcher disp(&doomMap, &result, ELightMode::ZDoomSoftware);
|
||||
|
||||
HWFlat flat;
|
||||
flat.section = §ion;
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
86
src/rendering/hwrenderer/scene/hw_flatdispatcher.h
Normal file
86
src/rendering/hwrenderer/scene/hw_flatdispatcher.h
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue