0
0
Fork 0
mirror of https://github.com/ZDoom/gzdoom.git synced 2025-03-08 10:34:48 +00:00

Build a mesh cache for all sectors

This commit is contained in:
Magnus Norddahl 2022-12-28 18:05:25 +01:00 committed by Christoph Oelckers
parent 528afe3ee3
commit 31a861f343
6 changed files with 129 additions and 0 deletions

View file

@ -891,6 +891,7 @@ 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

@ -50,6 +50,7 @@
#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 "hw_vrmodes.h"
EXTERN_CVAR(Bool, cl_capfps)
@ -127,6 +128,8 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou
screen->SetLevelMesh(camera->Level->levelMesh);
meshcache.Update(mainvp);
// Update the attenuation flag of all light defaults for each viewpoint.
// This function will only do something if the setting differs.
FLightDefaults::SetAttenuationForLevel(!!(camera->Level->flags3 & LEVEL3_ATTENUATE));

View file

@ -182,6 +182,8 @@ 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 MeshBuilding = false;
private:
// For ProcessLowerMiniseg
bool inview;

View file

@ -0,0 +1,90 @@
#include "hw_meshcache.h"
#include "hw_drawinfo.h"
#include "hw_drawstructs.h"
#include "hw_mesh.h"
#include "g_levellocals.h"
EXTERN_CVAR(Bool, gl_texture)
EXTERN_CVAR(Float, gl_mask_threshold)
HWMeshCache meshcache;
void HWMeshCache::Update(FRenderViewpoint& vp)
{
auto level = vp.ViewLevel;
unsigned int count = level->sectors.Size();
Sectors.Resize(count);
for (unsigned int i = 0; i < count; i++)
{
auto sector = &level->sectors[i];
if (Sectors[i].Sector != sector) // Note: this is just a stupid way to detect we changed map. What is the proper way?
{
Sectors[i].Sector = sector;
Sectors[i].Update(vp);
}
}
}
void HWCachedSector::Update(FRenderViewpoint& vp)
{
HWDrawInfo* di = HWDrawInfo::StartDrawInfo(vp.ViewLevel, nullptr, vp, nullptr);
di->MeshBuilding = true;
// Add all the walls to the draw lists
for (line_t* line : Sector->Lines)
{
side_t* side = (line->sidedef[0]->sector == Sector) ? line->sidedef[0] : line->sidedef[1];
HWWall wall;
wall.sub = Sector->subsectors[0];
wall.Process(di, side->segs[0], Sector, (line->sidedef[0]->sector == Sector) ? line->backsector : line->frontsector);
}
// Convert draw lists to meshes
MeshBuilder state;
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

@ -0,0 +1,30 @@
#pragma once
#include "hw_mesh.h"
#include "r_defs.h"
struct FRenderViewpoint;
class HWCachedSector
{
public:
sector_t* Sector = nullptr;
std::unique_ptr<Mesh> Opaque;
std::unique_ptr<Mesh> Translucent;
std::unique_ptr<Mesh> TranslucentDepthBiased;
void Update(FRenderViewpoint& vp);
};
class HWMeshCache
{
public:
void Update(FRenderViewpoint& vp);
TArray<HWCachedSector> Sectors;
private:
};
extern HWMeshCache meshcache;

View file

@ -565,6 +565,9 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent)
void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane)
{
if (di->MeshBuilding)
return;
HWPortal * portal = nullptr;
MakeVertices(di, *screen->RenderState(), false);