mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +00:00
- cache the results of hw_FakeFlat for the remainder of the current scene instead of storing this in local variables.
An exception is made for the sprite drawer which needs to call this in the worker thread on some occasions for as-yet unprocessed sectors. This case may not alter the cache to avoid having to add thread synchronization to it. The main reason for this change is that pointers to such manipulated sectors can now be considered static in the renderer. Due to them being short lived local buffers it was not possible to carry them along with the render data for information retrieval.
This commit is contained in:
parent
9a7f570b19
commit
a90655b295
10 changed files with 87 additions and 54 deletions
|
@ -53,6 +53,7 @@
|
|||
#include "hwrenderer/postprocessing/hw_shadowmapshader.h"
|
||||
#include "hwrenderer/data/flatvertices.h"
|
||||
#include "hwrenderer/scene/hw_skydome.h"
|
||||
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||
#include "gl/shaders/gl_postprocessshaderinstance.h"
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
#include "hwrenderer/dynlights/hw_lightbuffer.h"
|
||||
|
@ -231,6 +232,8 @@ sector_t *FGLRenderer::RenderView(player_t* player)
|
|||
}
|
||||
else
|
||||
{
|
||||
hw_ClearFakeFlat();
|
||||
|
||||
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
||||
|
||||
checkBenchActive();
|
||||
|
@ -302,6 +305,7 @@ void FGLRenderer::BindToFrameBuffer(FMaterial *mat)
|
|||
|
||||
void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
|
||||
{
|
||||
// This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene.
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
|
||||
|
||||
int width = gltex->TextureWidth();
|
||||
|
@ -343,7 +347,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i
|
|||
// Switch to render buffers dimensioned for the savepic
|
||||
mBuffers = mSaveBuffers;
|
||||
|
||||
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
|
||||
hw_ClearFakeFlat();
|
||||
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
|
||||
gl_RenderState.SetVertexBuffer(screen->mVertexData);
|
||||
screen->mVertexData->Reset();
|
||||
screen->mLights->Clear();
|
||||
|
|
|
@ -122,8 +122,6 @@ private:
|
|||
|
||||
};
|
||||
|
||||
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||
|
||||
struct TexFilter_s
|
||||
{
|
||||
int minfilter;
|
||||
|
|
|
@ -96,7 +96,7 @@ static RenderJobQueue jobQueue; // One static queue is sufficient here. This cod
|
|||
|
||||
void HWDrawInfo::WorkerThread()
|
||||
{
|
||||
sector_t fakefront, fakeback, *front, *back;
|
||||
sector_t *front, *back;
|
||||
|
||||
WTTotal.Clock();
|
||||
isWorkerThread = true; // for adding asserts in GL API code. The worker thread may never call any GL API.
|
||||
|
@ -118,6 +118,8 @@ void HWDrawInfo::WorkerThread()
|
|||
_mm_pause();
|
||||
_mm_pause();
|
||||
}
|
||||
// Note that the main thread MUST have prepared the fake sectors that get used below!
|
||||
// This worker thread cannot prepare them itself without costly synchronization.
|
||||
else switch (job->type)
|
||||
{
|
||||
case RenderJob::TerminateJob:
|
||||
|
@ -130,7 +132,7 @@ void HWDrawInfo::WorkerThread()
|
|||
SetupWall.Clock();
|
||||
wall.sub = job->sub;
|
||||
|
||||
front = hw_FakeFlat(job->sub->sector, &fakefront, in_area, false);
|
||||
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
||||
auto seg = job->seg;
|
||||
if (seg->backsector)
|
||||
{
|
||||
|
@ -140,7 +142,7 @@ void HWDrawInfo::WorkerThread()
|
|||
}
|
||||
else
|
||||
{
|
||||
back = hw_FakeFlat(seg->backsector, &fakeback, in_area, true);
|
||||
back = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
}
|
||||
}
|
||||
else back = nullptr;
|
||||
|
@ -156,7 +158,7 @@ void HWDrawInfo::WorkerThread()
|
|||
GLFlat flat;
|
||||
SetupFlat.Clock();
|
||||
flat.section = job->sub->section;
|
||||
front = hw_FakeFlat(job->sub->render_sector, &fakefront, in_area, false);
|
||||
front = hw_FakeFlat(job->sub->render_sector, in_area, false);
|
||||
flat.ProcessSector(this, front);
|
||||
SetupFlat.Unclock();
|
||||
break;
|
||||
|
@ -164,14 +166,14 @@ void HWDrawInfo::WorkerThread()
|
|||
|
||||
case RenderJob::SpriteJob:
|
||||
SetupSprite.Clock();
|
||||
front = hw_FakeFlat(job->sub->sector, &fakefront, in_area, false);
|
||||
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
||||
RenderThings(job->sub, front);
|
||||
SetupSprite.Unclock();
|
||||
break;
|
||||
|
||||
case RenderJob::ParticleJob:
|
||||
SetupSprite.Clock();
|
||||
front = hw_FakeFlat(job->sub->sector, &fakefront, in_area, false);
|
||||
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
||||
RenderParticles(job->sub, front);
|
||||
SetupSprite.Unclock();
|
||||
break;
|
||||
|
@ -228,7 +230,6 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
|
|||
#endif
|
||||
|
||||
sector_t * backsector = nullptr;
|
||||
sector_t bs;
|
||||
|
||||
if (portalclip)
|
||||
{
|
||||
|
@ -291,7 +292,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
|
|||
// clipping checks are only needed when the backsector is not the same as the front sector
|
||||
if (in_area == area_default) in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector);
|
||||
|
||||
backsector = hw_FakeFlat(seg->backsector, &bs, in_area, true);
|
||||
backsector = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
|
||||
if (hw_CheckClip(seg->sidedef, currentsector, backsector))
|
||||
{
|
||||
|
@ -575,7 +576,6 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
|
|||
{
|
||||
sector_t * sector;
|
||||
sector_t * fakesector;
|
||||
sector_t fake;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (sub->sector->sectornum==931)
|
||||
|
@ -600,7 +600,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
|
|||
}
|
||||
if (mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet.
|
||||
|
||||
fakesector=hw_FakeFlat(sector, &fake, in_area, false);
|
||||
fakesector=hw_FakeFlat(sector, in_area, false);
|
||||
|
||||
if (mClipPortal)
|
||||
{
|
||||
|
@ -677,7 +677,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
|
|||
sector = sub->render_sector;
|
||||
// the planes of this subsector are faked to belong to another sector
|
||||
// This means we need the heightsec parts and light info of the render sector, not the actual one.
|
||||
fakesector = hw_FakeFlat(sector, &fake, in_area, false);
|
||||
fakesector = hw_FakeFlat(sector, in_area, false);
|
||||
}
|
||||
|
||||
uint8_t &srf = section_renderflags[level.sections.SectionIndex(sub->section)];
|
||||
|
|
|
@ -193,8 +193,6 @@ private:
|
|||
subsector_t *currentsubsector; // used by the line processing code.
|
||||
sector_t *currentsector;
|
||||
|
||||
sector_t fakesec; // this is a struct member because it gets used in recursively called functions so it cannot be put on the stack.
|
||||
|
||||
void WorkerThread();
|
||||
|
||||
void UnclipSubsector(subsector_t *sub);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "hwrenderer/utility/hw_clock.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "hw_drawinfo.h"
|
||||
#include "hw_fakeflat.h"
|
||||
|
||||
FMemArena RenderDataAllocator(1024*1024); // Use large blocks to reduce allocation time.
|
||||
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
static sector_t **fakesectorbuffer;
|
||||
|
||||
extern thread_local bool isWorkerThread;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -182,6 +185,24 @@ area_t hw_CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, secto
|
|||
return area_default;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
static FMemArena FakeSectorAllocator(20 * sizeof(sector_t));
|
||||
|
||||
static sector_t *allocateSector(sector_t *sec)
|
||||
{
|
||||
if (fakesectorbuffer == nullptr)
|
||||
{
|
||||
fakesectorbuffer = (sector_t**)FakeSectorAllocator.Alloc(level.sectors.Size() * sizeof(sector_t*));
|
||||
memset(fakesectorbuffer, 0, level.sectors.Size() * sizeof(sector_t*));
|
||||
}
|
||||
auto sectornum = sec->sectornum;
|
||||
fakesectorbuffer[sectornum] = (sector_t*)FakeSectorAllocator.Alloc(sizeof(sector_t));
|
||||
return fakesectorbuffer[sectornum];
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -189,7 +210,8 @@ area_t hw_CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, secto
|
|||
// by hardware rendering
|
||||
//
|
||||
//==========================================================================
|
||||
sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back)
|
||||
|
||||
sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *localcopy)
|
||||
{
|
||||
if (!sec->GetHeightSec() || sec->heightsec==sec)
|
||||
{
|
||||
|
@ -197,6 +219,8 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
// visual glitches because upper amd lower textures overlap.
|
||||
if (back && (sec->MoreFlags & SECMF_OVERLAPPING))
|
||||
{
|
||||
if (fakesectorbuffer && fakesectorbuffer[sec->sectornum]) return fakesectorbuffer[sec->sectornum];
|
||||
auto dest = localcopy? localcopy : allocateSector(sec);
|
||||
*dest = *sec;
|
||||
dest->ceilingplane = sec->floorplane;
|
||||
dest->ceilingplane.FlipVert();
|
||||
|
@ -215,6 +239,12 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
}
|
||||
#endif
|
||||
|
||||
if (fakesectorbuffer && fakesectorbuffer[sec->sectornum])
|
||||
{
|
||||
return fakesectorbuffer[sec->sectornum];
|
||||
}
|
||||
assert(!(isWorkerThread && localcopy == nullptr));
|
||||
|
||||
if (in_area==area_above)
|
||||
{
|
||||
if (sec->heightsec->MoreFlags&SECMF_FAKEFLOORONLY /*|| sec->GetTexture(sector_t::ceiling)==skyflatnum*/) in_area=area_normal;
|
||||
|
@ -223,11 +253,8 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
int diffTex = (sec->heightsec->MoreFlags & SECMF_CLIPFAKEPLANES);
|
||||
sector_t * s = sec->heightsec;
|
||||
|
||||
#if 0
|
||||
*dest=*sec; // This will invoke the copy operator which isn't really needed here. Memcpy is faster.
|
||||
#else
|
||||
memcpy(dest, sec, sizeof(sector_t));
|
||||
#endif
|
||||
auto dest = localcopy ? localcopy : allocateSector(sec);
|
||||
*dest = *sec;
|
||||
|
||||
// Replace floor and ceiling height with control sector's heights.
|
||||
if (diffTex)
|
||||
|
@ -309,7 +336,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
dest->lightlevel = s->lightlevel;
|
||||
}
|
||||
|
||||
if (!back)
|
||||
//if (!back)
|
||||
{
|
||||
dest->SetTexture(sector_t::floor, diffTex ? sec->GetTexture(sector_t::floor) : s->GetTexture(sector_t::floor), false);
|
||||
dest->planes[sector_t::floor].xform = s->planes[sector_t::floor].xform;
|
||||
|
@ -362,7 +389,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
dest->lightlevel = s->lightlevel;
|
||||
}
|
||||
|
||||
if (!back)
|
||||
//if (!back)
|
||||
{
|
||||
dest->SetTexture(sector_t::ceiling, diffTex ? sec->GetTexture(sector_t::ceiling) : s->GetTexture(sector_t::ceiling), false);
|
||||
dest->SetTexture(sector_t::floor, s->GetTexture(sector_t::ceiling), false);
|
||||
|
@ -386,3 +413,10 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
void hw_ClearFakeFlat()
|
||||
{
|
||||
FakeSectorAllocator.FreeAll();
|
||||
fakesectorbuffer = nullptr;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ enum area_t : int
|
|||
|
||||
// Global functions.
|
||||
bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsector);
|
||||
sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back);
|
||||
void hw_ClearFakeFlat();
|
||||
sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *localcopy = nullptr);
|
||||
area_t hw_CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, sector_t *backsector);
|
||||
|
||||
|
|
|
@ -38,8 +38,7 @@
|
|||
#include "hwrenderer/data/flatvertices.h"
|
||||
#include "hwrenderer/dynlights/hw_lightbuffer.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
|
||||
sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back);
|
||||
#include "hw_fakeflat.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -53,32 +52,31 @@ void HWDrawInfo::DispatchRenderHacks()
|
|||
TMap<int, gl_floodrendernode*>::Pair *fpair;
|
||||
TMap<int, gl_subsectorrendernode*>::Iterator ofi(otherFloorPlanes);
|
||||
GLFlat glflat;
|
||||
sector_t fakesec;
|
||||
glflat.section = nullptr;
|
||||
while (ofi.NextPair(pair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&level.sectors[pair->Key], &fakesec, in_area, false);
|
||||
auto sec = hw_FakeFlat(&level.sectors[pair->Key], in_area, false);
|
||||
glflat.ProcessSector(this, sec, SSRF_RENDERFLOOR | SSRF_PLANEHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_subsectorrendernode*>::Iterator oci(otherCeilingPlanes);
|
||||
while (ofi.NextPair(pair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&level.sectors[pair->Key], &fakesec, in_area, false);
|
||||
auto sec = hw_FakeFlat(&level.sectors[pair->Key], in_area, false);
|
||||
glflat.ProcessSector(this, sec, SSRF_RENDERCEILING | SSRF_PLANEHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_floodrendernode*>::Iterator ffi(floodFloorSegs);
|
||||
while (ffi.NextPair(fpair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&level.sectors[fpair->Key], &fakesec, in_area, false);
|
||||
auto sec = hw_FakeFlat(&level.sectors[fpair->Key], in_area, false);
|
||||
glflat.ProcessSector(this, sec, SSRF_RENDERFLOOR | SSRF_FLOODHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_floodrendernode*>::Iterator fci(floodCeilingSegs);
|
||||
while (fci.NextPair(fpair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&level.sectors[fpair->Key], &fakesec, in_area, false);
|
||||
auto sec = hw_FakeFlat(&level.sectors[fpair->Key], in_area, false);
|
||||
glflat.ProcessSector(this, sec, SSRF_RENDERCEILING | SSRF_FLOODHACK);
|
||||
}
|
||||
}
|
||||
|
@ -336,7 +334,7 @@ bool HWDrawInfo::DoOneSectorUpper(subsector_t * subsec, float Planez, area_t in_
|
|||
// Note: if this is a real line between sectors
|
||||
// we can be sure that render_sector is the real sector!
|
||||
|
||||
sector_t * sec = hw_FakeFlat(seg->backsector, &fakesec, in_area, true);
|
||||
sector_t * sec = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
|
||||
// Don't bother with slopes
|
||||
if (sec->ceilingplane.isSlope()) return false;
|
||||
|
@ -394,7 +392,7 @@ bool HWDrawInfo::DoOneSectorLower(subsector_t * subsec, float Planez, area_t in_
|
|||
// Note: if this is a real line between sectors
|
||||
// we can be sure that render_sector is the real sector!
|
||||
|
||||
sector_t * sec = hw_FakeFlat(seg->backsector, &fakesec, in_area, true);
|
||||
sector_t * sec = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
|
||||
// Don't bother with slopes
|
||||
if (sec->floorplane.isSlope()) return false;
|
||||
|
@ -453,7 +451,7 @@ bool HWDrawInfo::DoFakeBridge(subsector_t * subsec, float Planez, area_t in_area
|
|||
// Note: if this is a real line between sectors
|
||||
// we can be sure that render_sector is the real sector!
|
||||
|
||||
sector_t * sec = hw_FakeFlat(seg->backsector, &fakesec, in_area, true);
|
||||
sector_t * sec = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
|
||||
// Don't bother with slopes
|
||||
if (sec->floorplane.isSlope()) return false;
|
||||
|
@ -506,7 +504,7 @@ bool HWDrawInfo::DoFakeCeilingBridge(subsector_t * subsec, float Planez, area_t
|
|||
// Note: if this is a real line between sectors
|
||||
// we can be sure that render_sector is the real sector!
|
||||
|
||||
sector_t * sec = hw_FakeFlat(seg->backsector, &fakesec, in_area, true);
|
||||
sector_t * sec = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
|
||||
// Don't bother with slopes
|
||||
if (sec->ceilingplane.isSlope()) return false;
|
||||
|
@ -538,8 +536,6 @@ bool HWDrawInfo::DoFakeCeilingBridge(subsector_t * subsec, float Planez, area_t
|
|||
//==========================================================================
|
||||
void HWDrawInfo::HandleMissingTextures(area_t in_area)
|
||||
{
|
||||
sector_t fake;
|
||||
|
||||
for (unsigned int i = 0; i < MissingUpperTextures.Size(); i++)
|
||||
{
|
||||
if (!MissingUpperTextures[i].seg) continue;
|
||||
|
@ -589,7 +585,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
|
|||
|
||||
{
|
||||
// It isn't a hole. Now check whether it might be a fake bridge
|
||||
sector_t * fakesector = hw_FakeFlat(MissingUpperTextures[i].seg->frontsector, &fake, in_area, false);
|
||||
sector_t * fakesector = hw_FakeFlat(MissingUpperTextures[i].seg->frontsector, in_area, false);
|
||||
float planez = (float)fakesector->GetPlaneTexZ(sector_t::ceiling);
|
||||
|
||||
backsub->validcount = validcount;
|
||||
|
@ -655,7 +651,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area)
|
|||
|
||||
{
|
||||
// It isn't a hole. Now check whether it might be a fake bridge
|
||||
sector_t * fakesector = hw_FakeFlat(MissingLowerTextures[i].seg->frontsector, &fake, in_area, false);
|
||||
sector_t * fakesector = hw_FakeFlat(MissingLowerTextures[i].seg->frontsector, in_area, false);
|
||||
float planez = (float)fakesector->GetPlaneTexZ(sector_t::floor);
|
||||
|
||||
backsub->validcount = validcount;
|
||||
|
@ -729,9 +725,8 @@ void HWDrawInfo::CreateFloodPoly(wallseg * ws, FFlatVertex *vertices, float plan
|
|||
void HWDrawInfo::PrepareUpperGap(seg_t * seg)
|
||||
{
|
||||
wallseg ws;
|
||||
sector_t ffake, bfake;
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false);
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, in_area, false);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
|
||||
vertex_t * v1, *v2;
|
||||
|
||||
|
@ -786,9 +781,8 @@ void HWDrawInfo::PrepareUpperGap(seg_t * seg)
|
|||
void HWDrawInfo::PrepareLowerGap(seg_t * seg)
|
||||
{
|
||||
wallseg ws;
|
||||
sector_t ffake, bfake;
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false);
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, in_area, false);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
|
||||
vertex_t * v1, *v2;
|
||||
|
||||
|
@ -1220,7 +1214,7 @@ void HWDrawInfo::CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor
|
|||
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
|
||||
|
||||
// Must be the exact same visplane
|
||||
sector_t * me = hw_FakeFlat(sub->render_sector, &fakesec, in_area, false);
|
||||
sector_t * me = hw_FakeFlat(sub->render_sector, in_area, false);
|
||||
if (me->GetTexture(sector_t::ceiling) != anchor->GetTexture(sector_t::ceiling) ||
|
||||
me->ceilingplane != anchor->ceilingplane ||
|
||||
me->GetCeilingLight() != anchor->GetCeilingLight() ||
|
||||
|
@ -1264,7 +1258,7 @@ void HWDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor,
|
|||
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
|
||||
|
||||
// Must be the exact same visplane
|
||||
sector_t * me = hw_FakeFlat(sub->render_sector, &fakesec, in_area, false);
|
||||
sector_t * me = hw_FakeFlat(sub->render_sector, in_area, false);
|
||||
if (me->GetTexture(sector_t::floor) != anchor->GetTexture(sector_t::floor) ||
|
||||
me->floorplane != anchor->floorplane ||
|
||||
me->GetFloorLight() != anchor->GetFloorLight() ||
|
||||
|
@ -1303,7 +1297,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
|
|||
validcount++;
|
||||
for (i=0;i<CeilingStacks.Size (); i++)
|
||||
{
|
||||
sector_t *sec = hw_FakeFlat(CeilingStacks[i], &fakesec, in_area, false);
|
||||
sector_t *sec = hw_FakeFlat(CeilingStacks[i], in_area, false);
|
||||
auto portal = sec->GetPortalGroup(sector_t::ceiling);
|
||||
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
|
||||
{
|
||||
|
@ -1347,7 +1341,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
|
|||
validcount++;
|
||||
for (i=0;i<FloorStacks.Size (); i++)
|
||||
{
|
||||
sector_t *sec = hw_FakeFlat(FloorStacks[i], &fakesec, in_area, false);
|
||||
sector_t *sec = hw_FakeFlat(FloorStacks[i], in_area, false);
|
||||
auto portal = sec->GetPortalGroup(sector_t::floor);
|
||||
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
|
||||
{
|
||||
|
|
|
@ -755,7 +755,9 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
|
||||
if (sector->sectornum != thing->Sector->sectornum && !thruportal)
|
||||
{
|
||||
rendersector = hw_FakeFlat(thing->Sector, &rs, in_area, false);
|
||||
// This cannot create a copy in the fake sector cache because it'd interfere with the main thread, so provide a local buffer for the copy.
|
||||
// Adding synchronization for this one case would cost more than it might save if the result here could be cached.
|
||||
rendersector = hw_FakeFlat(thing->Sector, in_area, false, &rs);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1287,7 +1289,8 @@ void HWDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport, area_t in_area)
|
|||
th->Prev += newpos - savedpos;
|
||||
|
||||
GLSprite spr;
|
||||
spr.Process(this, th, hw_FakeFlat(th->Sector, &fakesector, in_area, false), in_area, 2);
|
||||
// This is called from the worker thread and must not alter the fake sector cache.
|
||||
spr.Process(this, th, hw_FakeFlat(th->Sector, in_area, false, &fakesector), in_area, 2);
|
||||
th->Angles.Yaw = savedangle;
|
||||
th->SetXYZ(savedpos);
|
||||
th->Prev -= newpos - savedpos;
|
||||
|
|
|
@ -222,8 +222,7 @@ static WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &po
|
|||
}
|
||||
else
|
||||
{
|
||||
sector_t fs;
|
||||
auto fakesec = hw_FakeFlat(viewsector, &fs, in_area, false);
|
||||
auto fakesec = hw_FakeFlat(viewsector, in_area, false);
|
||||
|
||||
// calculate light level for weapon sprites
|
||||
l.lightlevel = hw_ClampLight(fakesec->lightlevel);
|
||||
|
|
Loading…
Reference in a new issue