mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 14:01:45 +00:00
Add HWDrawContext so that multiple threads can maintain their own drawinfo without need for synchronization
This commit is contained in:
parent
0adb152913
commit
dba5399635
25 changed files with 295 additions and 298 deletions
|
@ -721,6 +721,7 @@ set( FASTMATH_SOURCES
|
|||
rendering/hwrenderer/scene/hw_bsp.cpp
|
||||
rendering/hwrenderer/scene/hw_fakeflat.cpp
|
||||
rendering/hwrenderer/scene/hw_decal.cpp
|
||||
rendering/hwrenderer/scene/hw_drawcontext.cpp
|
||||
rendering/hwrenderer/scene/hw_drawinfo.cpp
|
||||
rendering/hwrenderer/scene/hw_drawlist.cpp
|
||||
rendering/hwrenderer/scene/hw_clipper.cpp
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#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"
|
||||
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
|
@ -125,7 +126,11 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou
|
|||
|
||||
screen->SetLevelMesh(camera->Level->levelMesh);
|
||||
|
||||
meshcache.Update(mainvp);
|
||||
static HWDrawContext mainthread_drawctx;
|
||||
|
||||
hw_ClearFakeFlat(&mainthread_drawctx);
|
||||
|
||||
meshcache.Update(&mainthread_drawctx, mainvp);
|
||||
|
||||
// Update the attenuation flag of all light defaults for each viewpoint.
|
||||
// This function will only do something if the setting differs.
|
||||
|
@ -149,7 +154,7 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou
|
|||
RenderState.EnableDrawBuffers(RenderState.GetPassDrawBufferCount(), true);
|
||||
}
|
||||
|
||||
auto di = HWDrawInfo::StartDrawInfo(mainvp.ViewLevel, nullptr, mainvp, nullptr);
|
||||
auto di = HWDrawInfo::StartDrawInfo(&mainthread_drawctx, mainvp.ViewLevel, nullptr, mainvp, nullptr);
|
||||
auto& vp = di->Viewpoint;
|
||||
|
||||
di->Set3DViewport(RenderState);
|
||||
|
@ -274,7 +279,6 @@ void WriteSavePic(player_t* player, FileWriter* file, int width, int height)
|
|||
screen->ImageTransitionScene(true);
|
||||
|
||||
hw_postprocess.SetTonemapMode(level.info ? level.info->tonemap : ETonemapMode::None);
|
||||
hw_ClearFakeFlat();
|
||||
RenderState.ResetVertices();
|
||||
RenderState.SetFlatVertexBuffer();
|
||||
|
||||
|
@ -327,8 +331,6 @@ sector_t* RenderView(player_t* player)
|
|||
}
|
||||
else
|
||||
{
|
||||
hw_ClearFakeFlat();
|
||||
|
||||
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
||||
|
||||
checkBenchActive();
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "hw_renderstate.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "hw_models.h"
|
||||
#include "hwrenderer/scene/hw_drawcontext.h"
|
||||
|
||||
CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE)
|
||||
EXTERN_CVAR(Bool, gl_texture);
|
||||
|
@ -70,7 +71,7 @@ void FHWModelRenderer::BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf
|
|||
// TO-DO: Implement proper depth sorting.
|
||||
if (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES))
|
||||
{
|
||||
state.SetCulling((mirrored ^ portalState.isMirrored()) ? Cull_CCW : Cull_CW);
|
||||
state.SetCulling((mirrored ^ di->drawctx->portalState.isMirrored()) ? Cull_CCW : Cull_CW);
|
||||
}
|
||||
|
||||
VSMatrix normalModelMatrix;
|
||||
|
@ -105,7 +106,7 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj
|
|||
// TO-DO: Implement proper depth sorting.
|
||||
if (!(style == DefaultRenderStyle()))
|
||||
{
|
||||
state.SetCulling((mirrored ^ portalState.isMirrored()) ? Cull_CW : Cull_CCW);
|
||||
state.SetCulling((mirrored ^ di->drawctx->portalState.isMirrored()) ? Cull_CW : Cull_CCW);
|
||||
}
|
||||
|
||||
VSMatrix normalModelMatrix;
|
||||
|
|
|
@ -144,14 +144,14 @@ void HWDrawInfo::WorkerThread()
|
|||
SetupWall.Clock();
|
||||
wall.sub = job->sub;
|
||||
|
||||
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
||||
front = hw_FakeFlat(drawctx, job->sub->sector, in_area, false);
|
||||
auto seg = job->seg;
|
||||
auto backsector = seg->backsector;
|
||||
if (!backsector && seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0]) // For one-sided portals use the portal's destination sector as backsector.
|
||||
{
|
||||
auto portal = seg->linedef->getPortal();
|
||||
backsector = portal->mDestination->frontsector;
|
||||
back = hw_FakeFlat(backsector, in_area, true);
|
||||
back = hw_FakeFlat(drawctx, backsector, in_area, true);
|
||||
if (front->floorplane.isSlope() || front->ceilingplane.isSlope() || back->floorplane.isSlope() || back->ceilingplane.isSlope())
|
||||
{
|
||||
// Having a one-sided portal like this with slopes is too messy so let's ignore that case.
|
||||
|
@ -166,7 +166,7 @@ void HWDrawInfo::WorkerThread()
|
|||
}
|
||||
else
|
||||
{
|
||||
back = hw_FakeFlat(backsector, in_area, true);
|
||||
back = hw_FakeFlat(drawctx, backsector, in_area, true);
|
||||
}
|
||||
}
|
||||
else back = nullptr;
|
||||
|
@ -182,7 +182,7 @@ void HWDrawInfo::WorkerThread()
|
|||
HWFlat flat;
|
||||
SetupFlat.Clock();
|
||||
flat.section = job->sub->section;
|
||||
front = hw_FakeFlat(job->sub->render_sector, in_area, false);
|
||||
front = hw_FakeFlat(drawctx, job->sub->render_sector, in_area, false);
|
||||
flat.ProcessSector(this, state, front);
|
||||
SetupFlat.Unclock();
|
||||
break;
|
||||
|
@ -190,14 +190,14 @@ void HWDrawInfo::WorkerThread()
|
|||
|
||||
case RenderJob::SpriteJob:
|
||||
SetupSprite.Clock();
|
||||
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
||||
front = hw_FakeFlat(drawctx, job->sub->sector, in_area, false);
|
||||
RenderThings(job->sub, front, state);
|
||||
SetupSprite.Unclock();
|
||||
break;
|
||||
|
||||
case RenderJob::ParticleJob:
|
||||
SetupSprite.Clock();
|
||||
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
||||
front = hw_FakeFlat(drawctx, job->sub->sector, in_area, false);
|
||||
RenderParticles(job->sub, front, state);
|
||||
SetupSprite.Unclock();
|
||||
break;
|
||||
|
@ -321,7 +321,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
|||
// 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, in_area, true);
|
||||
backsector = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
|
||||
if (hw_CheckClip(seg->sidedef, currentsector, backsector))
|
||||
{
|
||||
|
@ -648,7 +648,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
|||
}
|
||||
if (mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet.
|
||||
|
||||
fakesector=hw_FakeFlat(sector, in_area, false);
|
||||
fakesector=hw_FakeFlat(drawctx, sector, in_area, false);
|
||||
|
||||
if (mClipPortal)
|
||||
{
|
||||
|
@ -725,7 +725,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
|||
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, in_area, false);
|
||||
fakesector = hw_FakeFlat(drawctx, sector, in_area, false);
|
||||
}
|
||||
|
||||
uint8_t &srf = section_renderflags[Level->sections.SectionIndex(sub->section)];
|
||||
|
|
|
@ -39,13 +39,6 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "basics.h"
|
||||
|
||||
unsigned Clipper::starttime;
|
||||
|
||||
Clipper::Clipper()
|
||||
{
|
||||
starttime++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// RemoveRange
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef __GL_CLIPPER
|
||||
#define __GL_CLIPPER
|
||||
#pragma once
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "xs_Float.h"
|
||||
|
@ -22,7 +21,7 @@ class ClipNode
|
|||
|
||||
class Clipper
|
||||
{
|
||||
static unsigned starttime;
|
||||
unsigned int starttime = 1;
|
||||
FMemArena nodearena;
|
||||
ClipNode * freelist = nullptr;
|
||||
|
||||
|
@ -41,8 +40,6 @@ class Clipper
|
|||
|
||||
public:
|
||||
|
||||
Clipper();
|
||||
|
||||
void Clear();
|
||||
|
||||
void Free(ClipNode *node)
|
||||
|
@ -158,5 +155,3 @@ public:
|
|||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
57
src/rendering/hwrenderer/scene/hw_drawcontext.cpp
Normal file
57
src/rendering/hwrenderer/scene/hw_drawcontext.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
|
||||
#include "hw_drawcontext.h"
|
||||
#include "hw_drawinfo.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Try to reuse the lists as often as possible as they contain resources that
|
||||
// are expensive to create and delete.
|
||||
//
|
||||
// Note: If multithreading gets used, this class needs synchronization.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
HWDrawInfo* FDrawInfoList::GetNew()
|
||||
{
|
||||
if (mList.Size() > 0)
|
||||
{
|
||||
HWDrawInfo* di;
|
||||
mList.Pop(di);
|
||||
return di;
|
||||
}
|
||||
return new HWDrawInfo(drawctx);
|
||||
}
|
||||
|
||||
void FDrawInfoList::Release(HWDrawInfo* di)
|
||||
{
|
||||
di->ClearBuffers();
|
||||
di->Level = nullptr;
|
||||
mList.Push(di);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
SortNode* StaticSortNodeArray::GetNew()
|
||||
{
|
||||
if (usecount == TArray<SortNode*>::Size())
|
||||
{
|
||||
Push(new SortNode);
|
||||
}
|
||||
return operator[](usecount++);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
HWDrawContext::HWDrawContext() : RenderDataAllocator(1024 * 1024), FakeSectorAllocator(20 * sizeof(sector_t))
|
||||
{
|
||||
di_list.drawctx = this;
|
||||
}
|
||||
|
||||
HWDrawContext::~HWDrawContext()
|
||||
{
|
||||
}
|
||||
|
||||
void HWDrawContext::ResetRenderDataAllocator()
|
||||
{
|
||||
RenderDataAllocator.FreeAll();
|
||||
}
|
55
src/rendering/hwrenderer/scene/hw_drawcontext.h
Normal file
55
src/rendering/hwrenderer/scene/hw_drawcontext.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include "common/utility/tarray.h"
|
||||
#include "hw_clipper.h"
|
||||
#include "hw_portal.h"
|
||||
|
||||
struct HWDrawInfo;
|
||||
struct SortNode;
|
||||
struct FDynamicLight;
|
||||
class HWDrawContext;
|
||||
|
||||
class FDrawInfoList
|
||||
{
|
||||
public:
|
||||
HWDrawContext* drawctx = nullptr;
|
||||
TDeletingArray<HWDrawInfo*> mList;
|
||||
|
||||
HWDrawInfo* GetNew();
|
||||
void Release(HWDrawInfo*);
|
||||
};
|
||||
|
||||
class StaticSortNodeArray : public TDeletingArray<SortNode*>
|
||||
{
|
||||
public:
|
||||
unsigned int Size() { return usecount; }
|
||||
void Clear() { usecount = 0; }
|
||||
void Release(int start) { usecount = start; }
|
||||
SortNode* GetNew();
|
||||
|
||||
private:
|
||||
unsigned int usecount = 0;
|
||||
};
|
||||
|
||||
class HWDrawContext
|
||||
{
|
||||
public:
|
||||
HWDrawContext();
|
||||
~HWDrawContext();
|
||||
|
||||
void ResetRenderDataAllocator();
|
||||
|
||||
FDrawInfoList di_list;
|
||||
Clipper staticClipper; // Since all scenes are processed sequentially we only need one clipper.
|
||||
HWDrawInfo* gl_drawinfo = nullptr; // This is a linked list of all active DrawInfos and needed to free the memory arena after the last one goes out of scope.
|
||||
|
||||
FMemArena RenderDataAllocator; // Use large blocks to reduce allocation time.
|
||||
StaticSortNodeArray SortNodes;
|
||||
|
||||
sector_t** fakesectorbuffer = nullptr;
|
||||
FMemArena FakeSectorAllocator;
|
||||
|
||||
FPortalSceneState portalState;
|
||||
|
||||
TArray<FDynamicLight*> addedLightsArray;
|
||||
};
|
|
@ -34,6 +34,7 @@
|
|||
#include "hw_portal.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "hw_drawinfo.h"
|
||||
#include "hw_drawcontext.h"
|
||||
#include "po_man.h"
|
||||
#include "models.h"
|
||||
#include "hw_clock.h"
|
||||
|
@ -64,50 +65,6 @@ CVAR(Bool, gl_meshcache, false, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/)
|
|||
|
||||
sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FDrawInfoList
|
||||
{
|
||||
public:
|
||||
TDeletingArray<HWDrawInfo *> mList;
|
||||
|
||||
HWDrawInfo * GetNew();
|
||||
void Release(HWDrawInfo *);
|
||||
};
|
||||
|
||||
|
||||
FDrawInfoList di_list;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Try to reuse the lists as often as possible as they contain resources that
|
||||
// are expensive to create and delete.
|
||||
//
|
||||
// Note: If multithreading gets used, this class needs synchronization.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
HWDrawInfo *FDrawInfoList::GetNew()
|
||||
{
|
||||
if (mList.Size() > 0)
|
||||
{
|
||||
HWDrawInfo *di;
|
||||
mList.Pop(di);
|
||||
return di;
|
||||
}
|
||||
return new HWDrawInfo();
|
||||
}
|
||||
|
||||
void FDrawInfoList::Release(HWDrawInfo * di)
|
||||
{
|
||||
di->ClearBuffers();
|
||||
di->Level = nullptr;
|
||||
mList.Push(di);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -115,28 +72,18 @@ void FDrawInfoList::Release(HWDrawInfo * di)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
HWDrawInfo *HWDrawInfo::StartDrawInfo(FLevelLocals *lev, HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms)
|
||||
HWDrawInfo *HWDrawInfo::StartDrawInfo(HWDrawContext* drawctx, FLevelLocals *lev, HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms)
|
||||
{
|
||||
HWDrawInfo *di = di_list.GetNew();
|
||||
HWDrawInfo *di = drawctx->di_list.GetNew();
|
||||
di->Level = lev;
|
||||
di->StartScene(parentvp, uniforms);
|
||||
return di;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static Clipper staticClipper; // Since all scenes are processed sequentially we only need one clipper.
|
||||
static HWDrawInfo * gl_drawinfo; // This is a linked list of all active DrawInfos and needed to free the memory arena after the last one goes out of scope.
|
||||
|
||||
void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms)
|
||||
{
|
||||
staticClipper.Clear();
|
||||
mClipper = &staticClipper;
|
||||
drawctx->staticClipper.Clear();
|
||||
mClipper = &drawctx->staticClipper;
|
||||
|
||||
Viewpoint = parentvp;
|
||||
lightmode = getRealLightmode(Level, true);
|
||||
|
@ -181,8 +128,8 @@ void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uni
|
|||
if (outer != nullptr) FullbrightFlags = outer->FullbrightFlags;
|
||||
else FullbrightFlags = 0;
|
||||
|
||||
outer = gl_drawinfo;
|
||||
gl_drawinfo = this;
|
||||
outer = drawctx->gl_drawinfo;
|
||||
drawctx->gl_drawinfo = this;
|
||||
|
||||
}
|
||||
|
||||
|
@ -196,11 +143,11 @@ HWDrawInfo *HWDrawInfo::EndDrawInfo()
|
|||
{
|
||||
assert(this == gl_drawinfo);
|
||||
for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset();
|
||||
gl_drawinfo = outer;
|
||||
di_list.Release(this);
|
||||
if (gl_drawinfo == nullptr)
|
||||
ResetRenderDataAllocator();
|
||||
return gl_drawinfo;
|
||||
drawctx->gl_drawinfo = outer;
|
||||
drawctx->di_list.Release(this);
|
||||
if (drawctx->gl_drawinfo == nullptr)
|
||||
drawctx->ResetRenderDataAllocator();
|
||||
return drawctx->gl_drawinfo;
|
||||
}
|
||||
|
||||
|
||||
|
@ -422,7 +369,7 @@ HWPortal * HWDrawInfo::FindPortal(const void * src)
|
|||
|
||||
HWDecal *HWDrawInfo::AddDecal(bool onmirror)
|
||||
{
|
||||
auto decal = (HWDecal*)RenderDataAllocator.Alloc(sizeof(HWDecal));
|
||||
auto decal = (HWDecal*)drawctx->RenderDataAllocator.Alloc(sizeof(HWDecal));
|
||||
Decals[onmirror ? 1 : 0].Push(decal);
|
||||
return decal;
|
||||
}
|
||||
|
@ -442,7 +389,7 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
|
|||
mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + a1, vp.Angles.Yaw.BAMs() - a1);
|
||||
|
||||
// reset the portal manager
|
||||
portalState.StartFrame();
|
||||
drawctx->portalState.StartFrame();
|
||||
|
||||
ProcessAll.Clock();
|
||||
|
||||
|
@ -583,7 +530,7 @@ void HWDrawInfo::RenderPortal(HWPortal *p, FRenderState &state, bool usestencil)
|
|||
{
|
||||
auto gp = static_cast<HWPortal *>(p);
|
||||
gp->SetupStencil(this, state, usestencil);
|
||||
auto new_di = StartDrawInfo(this->Level, this, Viewpoint, &VPUniforms);
|
||||
auto new_di = StartDrawInfo(drawctx, this->Level, this, Viewpoint, &VPUniforms);
|
||||
new_di->mCurrentPortal = gp;
|
||||
state.SetLightIndex(-1);
|
||||
gp->DrawContents(new_di, state);
|
||||
|
@ -840,7 +787,7 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state)
|
|||
}
|
||||
|
||||
state.SetDepthMask(true);
|
||||
if (!gl_no_skyclear) portalState.RenderFirstSkyPortal(recursion, this, state);
|
||||
if (!gl_no_skyclear) drawctx->portalState.RenderFirstSkyPortal(recursion, this, state);
|
||||
|
||||
RenderScene(state);
|
||||
|
||||
|
@ -853,7 +800,7 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state)
|
|||
// Handle all portals after rendering the opaque objects but before
|
||||
// doing all translucent stuff
|
||||
recursion++;
|
||||
portalState.EndFrame(this, state);
|
||||
drawctx->portalState.EndFrame(this, state);
|
||||
recursion--;
|
||||
RenderTranslucent(state);
|
||||
}
|
||||
|
@ -867,7 +814,7 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state)
|
|||
|
||||
void HWDrawInfo::ProcessScene(bool toscreen, FRenderState& state)
|
||||
{
|
||||
portalState.BeginScene();
|
||||
drawctx->portalState.BeginScene();
|
||||
|
||||
int mapsection = Level->PointInRenderSubsector(Viewpoint.Pos)->mapsection;
|
||||
CurrentMapSections.Set(mapsection);
|
||||
|
@ -886,7 +833,7 @@ void HWDrawInfo::AddSubsectorToPortal(FSectorPortalGroup *ptg, subsector_t *sub)
|
|||
auto portal = FindPortal(ptg);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWSectorStackPortal(&portalState, ptg);
|
||||
portal = new HWSectorStackPortal(&drawctx->portalState, ptg);
|
||||
Portals.Push(portal);
|
||||
}
|
||||
auto ptl = static_cast<HWSectorStackPortal*>(portal);
|
||||
|
|
|
@ -34,12 +34,9 @@ class Clipper;
|
|||
class HWPortal;
|
||||
class HWScenePortalBase;
|
||||
class FRenderState;
|
||||
class HWDrawContext;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// these are used to link faked planes due to missing textures to a sector
|
||||
//
|
||||
//==========================================================================
|
||||
struct gl_subsectorrendernode
|
||||
{
|
||||
gl_subsectorrendernode * next;
|
||||
|
@ -132,6 +129,8 @@ struct HWDrawInfo
|
|||
bool isNightvision() const { return !!(FullbrightFlags & Nightvision); }
|
||||
bool isStealthVision() const { return !!(FullbrightFlags & StealthVision); }
|
||||
|
||||
HWDrawContext* drawctx = nullptr;
|
||||
|
||||
HWDrawList drawlists[GLDL_TYPES];
|
||||
int vpIndex;
|
||||
ELightMode lightmode;
|
||||
|
@ -142,7 +141,6 @@ struct HWDrawInfo
|
|||
std::atomic<int> spriteindex;
|
||||
HWPortal *mClipPortal;
|
||||
HWPortal *mCurrentPortal;
|
||||
//FRotator mAngles;
|
||||
Clipper *mClipper;
|
||||
FRenderViewpoint Viewpoint;
|
||||
HWViewpointUniforms VPUniforms; // per-viewpoint uniform state
|
||||
|
@ -165,9 +163,6 @@ struct HWDrawInfo
|
|||
TMap<int, gl_floodrendernode*> floodFloorSegs;
|
||||
TMap<int, gl_floodrendernode*> floodCeilingSegs;
|
||||
|
||||
//TArray<sector_t *> CeilingStacks;
|
||||
//TArray<sector_t *> FloorStacks;
|
||||
|
||||
TArray<subsector_t *> HandledSubsectors;
|
||||
|
||||
TArray<uint8_t> section_renderflags;
|
||||
|
@ -182,44 +177,7 @@ struct HWDrawInfo
|
|||
|
||||
bool MeshBuilding = false;
|
||||
|
||||
private:
|
||||
// For ProcessLowerMiniseg
|
||||
bool inview;
|
||||
subsector_t * viewsubsector;
|
||||
TArray<seg_t *> lowersegs;
|
||||
|
||||
subsector_t *currentsubsector; // used by the line processing code.
|
||||
sector_t *currentsector;
|
||||
|
||||
void WorkerThread();
|
||||
|
||||
void UnclipSubsector(subsector_t *sub);
|
||||
|
||||
void AddLine(seg_t *seg, bool portalclip, FRenderState& state);
|
||||
void PolySubsector(subsector_t * sub, FRenderState& state);
|
||||
void RenderPolyBSPNode(void *node, FRenderState& state);
|
||||
void AddPolyobjs(subsector_t *sub, FRenderState& state);
|
||||
void AddLines(subsector_t * sub, sector_t * sector, FRenderState& state);
|
||||
void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, linebase_t *line, FRenderState& state);
|
||||
public:
|
||||
void RenderThings(subsector_t * sub, sector_t * sector, FRenderState& state);
|
||||
void RenderParticles(subsector_t *sub, sector_t *front, FRenderState& state);
|
||||
void DoSubsector(subsector_t * sub, FRenderState& state);
|
||||
int SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &lightdata, const secplane_t *plane, FRenderState& state);
|
||||
int CreateOtherPlaneVertices(subsector_t *sub, const secplane_t *plane, FRenderState& state);
|
||||
void DrawPSprite(HUDSprite *huds, FRenderState &state);
|
||||
void SetColor(FRenderState &state, int sectorlightlevel, int rellight, bool fullbright, const FColormap &cm, float alpha, bool weapon = false);
|
||||
void SetFog(FRenderState &state, int lightlevel, int rellight, bool fullbright, const FColormap *cmap, bool isadditive);
|
||||
void SetShaderLight(FRenderState &state, float level, float olight);
|
||||
int CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor);
|
||||
PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor);
|
||||
float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
|
||||
bool CheckFog(sector_t *frontsector, sector_t *backsector);
|
||||
WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos);
|
||||
|
||||
void PreparePlayerSprites2D(sector_t * viewsector, area_t in_area, FRenderState& state);
|
||||
void PreparePlayerSprites3D(sector_t * viewsector, area_t in_area, FRenderState& state);
|
||||
public:
|
||||
HWDrawInfo(HWDrawContext* drawctx) : drawctx(drawctx) { for (HWDrawList& list : drawlists) list.drawctx = drawctx; }
|
||||
|
||||
void SetCameraPos(const DVector3 &pos)
|
||||
{
|
||||
|
@ -243,7 +201,7 @@ public:
|
|||
void RenderBSPNode(void *node, FRenderState& state);
|
||||
void RenderBSP(void *node, bool drawpsprites, FRenderState& state);
|
||||
|
||||
static HWDrawInfo *StartDrawInfo(FLevelLocals *lev, HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
||||
static HWDrawInfo *StartDrawInfo(HWDrawContext* drawctx, FLevelLocals *lev, HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
||||
void StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms);
|
||||
void ClearBuffers();
|
||||
HWDrawInfo *EndDrawInfo();
|
||||
|
@ -269,8 +227,6 @@ public:
|
|||
bool CollectSubsectorsFloor(subsector_t * sub, sector_t * anchor);
|
||||
bool CheckAnchorCeiling(subsector_t * sub);
|
||||
bool CollectSubsectorsCeiling(subsector_t * sub, sector_t * anchor);
|
||||
void CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor, area_t in_area);
|
||||
void CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor, area_t in_area);
|
||||
|
||||
void DispatchRenderHacks(FRenderState& state);
|
||||
void AddUpperMissingTexture(side_t * side, subsector_t *sub, float backheight);
|
||||
|
@ -284,9 +240,6 @@ public:
|
|||
|
||||
void AddHackedSubsector(subsector_t * sub);
|
||||
void HandleHackedSubsectors(FRenderState& state);
|
||||
void AddFloorStack(sector_t * sec);
|
||||
void AddCeilingStack(sector_t * sec);
|
||||
void ProcessSectorStacks(area_t in_area);
|
||||
|
||||
void ProcessActorsInPortal(FLinePortalSpan *glport, area_t in_area, FRenderState& state);
|
||||
|
||||
|
@ -317,6 +270,23 @@ public:
|
|||
void AddFlat(HWFlat *flat, bool fog);
|
||||
void AddSprite(HWSprite *sprite, bool translucent);
|
||||
|
||||
void RenderThings(subsector_t* sub, sector_t* sector, FRenderState& state);
|
||||
void RenderParticles(subsector_t* sub, sector_t* front, FRenderState& state);
|
||||
void DoSubsector(subsector_t* sub, FRenderState& state);
|
||||
int SetupLightsForOtherPlane(subsector_t* sub, FDynLightData& lightdata, const secplane_t* plane, FRenderState& state);
|
||||
int CreateOtherPlaneVertices(subsector_t* sub, const secplane_t* plane, FRenderState& state);
|
||||
void DrawPSprite(HUDSprite* huds, FRenderState& state);
|
||||
void SetColor(FRenderState& state, int sectorlightlevel, int rellight, bool fullbright, const FColormap& cm, float alpha, bool weapon = false);
|
||||
void SetFog(FRenderState& state, int lightlevel, int rellight, bool fullbright, const FColormap* cmap, bool isadditive);
|
||||
void SetShaderLight(FRenderState& state, float level, float olight);
|
||||
int CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor);
|
||||
PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor);
|
||||
float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
|
||||
bool CheckFog(sector_t* frontsector, sector_t* backsector);
|
||||
WeaponLighting GetWeaponLighting(sector_t* viewsector, const DVector3& pos, int cm, area_t in_area, const DVector3& playerpos);
|
||||
|
||||
void PreparePlayerSprites2D(sector_t* viewsector, area_t in_area, FRenderState& state);
|
||||
void PreparePlayerSprites3D(sector_t* viewsector, area_t in_area, FRenderState& state);
|
||||
|
||||
HWDecal *AddDecal(bool onmirror);
|
||||
|
||||
|
@ -345,6 +315,25 @@ public:
|
|||
lightmode = ELightMode::Doom;
|
||||
}
|
||||
|
||||
private:
|
||||
// For ProcessLowerMiniseg
|
||||
bool inview;
|
||||
subsector_t* viewsubsector;
|
||||
TArray<seg_t*> lowersegs;
|
||||
|
||||
subsector_t* currentsubsector; // used by the line processing code.
|
||||
sector_t* currentsector;
|
||||
|
||||
void WorkerThread();
|
||||
|
||||
void UnclipSubsector(subsector_t* sub);
|
||||
|
||||
void AddLine(seg_t* seg, bool portalclip, FRenderState& state);
|
||||
void PolySubsector(subsector_t* sub, FRenderState& state);
|
||||
void RenderPolyBSPNode(void* node, FRenderState& state);
|
||||
void AddPolyobjs(subsector_t* sub, FRenderState& state);
|
||||
void AddLines(subsector_t* sub, sector_t* sector, FRenderState& state);
|
||||
void AddSpecialPortalLines(subsector_t* sub, sector_t* sector, linebase_t* line, FRenderState& state);
|
||||
};
|
||||
|
||||
void CleanSWDrawer();
|
||||
|
|
|
@ -37,41 +37,7 @@
|
|||
#include "hw_renderstate.h"
|
||||
#include "hw_drawinfo.h"
|
||||
#include "hw_fakeflat.h"
|
||||
|
||||
FMemArena RenderDataAllocator(1024*1024); // Use large blocks to reduce allocation time.
|
||||
|
||||
void ResetRenderDataAllocator()
|
||||
{
|
||||
RenderDataAllocator.FreeAll();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
class StaticSortNodeArray : public TDeletingArray<SortNode*>
|
||||
{
|
||||
unsigned usecount;
|
||||
public:
|
||||
unsigned Size() { return usecount; }
|
||||
void Clear() { usecount=0; }
|
||||
void Release(int start) { usecount=start; }
|
||||
SortNode * GetNew();
|
||||
};
|
||||
|
||||
|
||||
SortNode * StaticSortNodeArray::GetNew()
|
||||
{
|
||||
if (usecount==TArray<SortNode*>::Size())
|
||||
{
|
||||
Push(new SortNode);
|
||||
}
|
||||
return operator[](usecount++);
|
||||
}
|
||||
|
||||
|
||||
static StaticSortNodeArray SortNodes;
|
||||
#include "hw_drawcontext.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -80,7 +46,7 @@ static StaticSortNodeArray SortNodes;
|
|||
//==========================================================================
|
||||
void HWDrawList::Reset()
|
||||
{
|
||||
if (sorted) SortNodes.Release(SortNodeStart);
|
||||
if (sorted) drawctx->SortNodes.Release(SortNodeStart);
|
||||
sorted=NULL;
|
||||
walls.Clear();
|
||||
flats.Clear();
|
||||
|
@ -163,9 +129,9 @@ void HWDrawList::MakeSortList()
|
|||
SortNode * p, * n, * c;
|
||||
unsigned i;
|
||||
|
||||
SortNodeStart=SortNodes.Size();
|
||||
SortNodeStart=drawctx->SortNodes.Size();
|
||||
p=NULL;
|
||||
n=SortNodes.GetNew();
|
||||
n=drawctx->SortNodes.GetNew();
|
||||
for(i=0;i<drawitems.Size();i++)
|
||||
{
|
||||
n->itemindex=(int)i;
|
||||
|
@ -174,7 +140,7 @@ void HWDrawList::MakeSortList()
|
|||
p=n;
|
||||
if (i!=drawitems.Size()-1)
|
||||
{
|
||||
c=SortNodes.GetNew();
|
||||
c=drawctx->SortNodes.GetNew();
|
||||
n->next=c;
|
||||
n=c;
|
||||
}
|
||||
|
@ -308,7 +274,7 @@ void HWDrawList::SortWallIntoPlane(HWDrawInfo* di, FRenderState& state, SortNode
|
|||
ws->MakeVertices(di, state, false);
|
||||
}
|
||||
|
||||
SortNode * sort2 = SortNodes.GetNew();
|
||||
SortNode * sort2 = drawctx->SortNodes.GetNew();
|
||||
memset(sort2, 0, sizeof(SortNode));
|
||||
sort2->itemindex = drawitems.Size() - 1;
|
||||
|
||||
|
@ -365,7 +331,7 @@ void HWDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort)
|
|||
}
|
||||
}
|
||||
|
||||
SortNode * sort2 = SortNodes.GetNew();
|
||||
SortNode * sort2 = drawctx->SortNodes.GetNew();
|
||||
memset(sort2, 0, sizeof(SortNode));
|
||||
sort2->itemindex = drawitems.Size() - 1;
|
||||
|
||||
|
@ -454,7 +420,7 @@ void HWDrawList::SortWallIntoWall(HWDrawInfo *di, FRenderState& state, SortNode
|
|||
ws->MakeVertices(di, state, false);
|
||||
w->MakeVertices(di, state, false);
|
||||
|
||||
SortNode * sort2=SortNodes.GetNew();
|
||||
SortNode * sort2=drawctx->SortNodes.GetNew();
|
||||
memset(sort2,0,sizeof(SortNode));
|
||||
sort2->itemindex=drawitems.Size()-1;
|
||||
|
||||
|
@ -553,7 +519,7 @@ void HWDrawList::SortSpriteIntoWall(HWDrawInfo *di, FRenderState& state, SortNod
|
|||
s->y1=ss->y2=iy;
|
||||
s->ul=ss->ur=iu;
|
||||
|
||||
SortNode * sort2=SortNodes.GetNew();
|
||||
SortNode * sort2=drawctx->SortNodes.GetNew();
|
||||
memset(sort2,0,sizeof(SortNode));
|
||||
sort2->itemindex=drawitems.Size()-1;
|
||||
|
||||
|
@ -711,7 +677,7 @@ void HWDrawList::Sort(HWDrawInfo *di, FRenderState& state)
|
|||
reverseSort = !!(di->Level->i_compatflags & COMPATF_SPRITESORT);
|
||||
SortZ = di->Viewpoint.Pos.Z;
|
||||
MakeSortList();
|
||||
sorted = DoSort(di, state, SortNodes[SortNodeStart]);
|
||||
sorted = DoSort(di, state, drawctx->SortNodes[SortNodeStart]);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -758,7 +724,7 @@ void HWDrawList::SortFlats()
|
|||
|
||||
HWWall *HWDrawList::NewWall()
|
||||
{
|
||||
auto wall = (HWWall*)RenderDataAllocator.Alloc(sizeof(HWWall));
|
||||
auto wall = (HWWall*)drawctx->RenderDataAllocator.Alloc(sizeof(HWWall));
|
||||
drawitems.Push(HWDrawItem(DrawType_WALL, walls.Push(wall)));
|
||||
return wall;
|
||||
}
|
||||
|
@ -770,7 +736,7 @@ HWWall *HWDrawList::NewWall()
|
|||
//==========================================================================
|
||||
HWFlat *HWDrawList::NewFlat()
|
||||
{
|
||||
auto flat = (HWFlat*)RenderDataAllocator.Alloc(sizeof(HWFlat));
|
||||
auto flat = (HWFlat*)drawctx->RenderDataAllocator.Alloc(sizeof(HWFlat));
|
||||
drawitems.Push(HWDrawItem(DrawType_FLAT,flats.Push(flat)));
|
||||
return flat;
|
||||
}
|
||||
|
@ -782,7 +748,7 @@ HWFlat *HWDrawList::NewFlat()
|
|||
//==========================================================================
|
||||
HWSprite *HWDrawList::NewSprite()
|
||||
{
|
||||
auto sprite = (HWSprite*)RenderDataAllocator.Alloc(sizeof(HWSprite));
|
||||
auto sprite = (HWSprite*)drawctx->RenderDataAllocator.Alloc(sizeof(HWSprite));
|
||||
drawitems.Push(HWDrawItem(DrawType_SPRITE, sprites.Push(sprite)));
|
||||
return sprite;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
#include "memarena.h"
|
||||
|
||||
extern FMemArena RenderDataAllocator;
|
||||
void ResetRenderDataAllocator();
|
||||
struct HWDrawInfo;
|
||||
class HWWall;
|
||||
class HWFlat;
|
||||
class HWSprite;
|
||||
class HWDrawContext;
|
||||
class FRenderState;
|
||||
|
||||
//==========================================================================
|
||||
|
@ -60,22 +59,21 @@ struct SortNode
|
|||
|
||||
struct HWDrawList
|
||||
{
|
||||
//private:
|
||||
HWDrawContext* drawctx = nullptr;
|
||||
TArray<HWWall*> walls;
|
||||
TArray<HWFlat*> flats;
|
||||
TArray<HWSprite*> sprites;
|
||||
TArray<HWDrawItem> drawitems;
|
||||
int SortNodeStart;
|
||||
float SortZ;
|
||||
SortNode * sorted;
|
||||
bool reverseSort;
|
||||
int SortNodeStart = 0;
|
||||
float SortZ = 0.0f;
|
||||
SortNode* sorted = nullptr;
|
||||
bool reverseSort = false;
|
||||
|
||||
public:
|
||||
HWDrawList()
|
||||
{
|
||||
next=NULL;
|
||||
next=nullptr;
|
||||
SortNodeStart=-1;
|
||||
sorted=NULL;
|
||||
sorted=nullptr;
|
||||
}
|
||||
|
||||
~HWDrawList()
|
||||
|
@ -117,7 +115,7 @@ public:
|
|||
void DrawSorted(HWDrawInfo *di, FRenderState &state, SortNode * head);
|
||||
void DrawSorted(HWDrawInfo *di, FRenderState &state);
|
||||
|
||||
HWDrawList * next;
|
||||
HWDrawList *next = nullptr;
|
||||
} ;
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ class FRenderState;
|
|||
struct HWDecal;
|
||||
struct FSection;
|
||||
enum area_t : int;
|
||||
class HWDrawContext;
|
||||
|
||||
enum HWRenderStyle
|
||||
{
|
||||
|
@ -432,7 +433,7 @@ inline float Dist2(float x1,float y1,float x2,float y2)
|
|||
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
|
||||
}
|
||||
|
||||
void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata);
|
||||
void hw_GetDynModelLight(HWDrawContext* drawctx, AActor *self, FDynLightData &modellightdata);
|
||||
|
||||
extern const float LARGE_VALUE;
|
||||
|
||||
|
|
|
@ -34,11 +34,10 @@
|
|||
#include "hw_fakeflat.h"
|
||||
#include "hw_drawinfo.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "hw_drawcontext.h"
|
||||
#include "r_utility.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
static sector_t **fakesectorbuffer;
|
||||
|
||||
extern thread_local bool isWorkerThread;
|
||||
|
||||
//==========================================================================
|
||||
|
@ -186,24 +185,17 @@ 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)
|
||||
static sector_t *allocateSector(HWDrawContext* drawctx, sector_t *sec)
|
||||
{
|
||||
if (fakesectorbuffer == nullptr)
|
||||
if (drawctx->fakesectorbuffer == nullptr)
|
||||
{
|
||||
unsigned numsectors = sec->Level->sectors.Size();
|
||||
fakesectorbuffer = (sector_t**)FakeSectorAllocator.Alloc(numsectors * sizeof(sector_t*));
|
||||
memset(fakesectorbuffer, 0, numsectors * sizeof(sector_t*));
|
||||
drawctx->fakesectorbuffer = (sector_t**)drawctx->FakeSectorAllocator.Alloc(numsectors * sizeof(sector_t*));
|
||||
memset(drawctx->fakesectorbuffer, 0, numsectors * sizeof(sector_t*));
|
||||
}
|
||||
auto sectornum = sec->sectornum;
|
||||
fakesectorbuffer[sectornum] = (sector_t*)FakeSectorAllocator.Alloc(sizeof(sector_t));
|
||||
return fakesectorbuffer[sectornum];
|
||||
drawctx->fakesectorbuffer[sectornum] = (sector_t*)drawctx->FakeSectorAllocator.Alloc(sizeof(sector_t));
|
||||
return drawctx->fakesectorbuffer[sectornum];
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -213,7 +205,7 @@ static sector_t *allocateSector(sector_t *sec)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *localcopy)
|
||||
sector_t * hw_FakeFlat(HWDrawContext* drawctx, sector_t * sec, area_t in_area, bool back, sector_t *localcopy)
|
||||
{
|
||||
if (!sec->GetHeightSec() || sec->heightsec==sec)
|
||||
{
|
||||
|
@ -221,8 +213,8 @@ sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *loca
|
|||
// 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);
|
||||
if (drawctx->fakesectorbuffer && drawctx->fakesectorbuffer[sec->sectornum]) return drawctx->fakesectorbuffer[sec->sectornum];
|
||||
auto dest = localcopy? localcopy : allocateSector(drawctx, sec);
|
||||
*dest = *sec;
|
||||
dest->floorplane = sec->ceilingplane;
|
||||
dest->floorplane.FlipVert();
|
||||
|
@ -241,9 +233,9 @@ sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *loca
|
|||
}
|
||||
#endif
|
||||
|
||||
if (fakesectorbuffer && fakesectorbuffer[sec->sectornum])
|
||||
if (drawctx->fakesectorbuffer && drawctx->fakesectorbuffer[sec->sectornum])
|
||||
{
|
||||
return fakesectorbuffer[sec->sectornum];
|
||||
return drawctx->fakesectorbuffer[sec->sectornum];
|
||||
}
|
||||
assert(!(isWorkerThread && localcopy == nullptr));
|
||||
|
||||
|
@ -255,7 +247,7 @@ sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *loca
|
|||
int diffTex = (sec->heightsec->MoreFlags & SECMF_CLIPFAKEPLANES);
|
||||
sector_t * s = sec->heightsec;
|
||||
|
||||
auto dest = localcopy ? localcopy : allocateSector(sec);
|
||||
auto dest = localcopy ? localcopy : allocateSector(drawctx, sec);
|
||||
*dest = *sec;
|
||||
|
||||
// Replace floor and ceiling height with control sector's heights.
|
||||
|
@ -417,8 +409,8 @@ sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *loca
|
|||
}
|
||||
|
||||
|
||||
void hw_ClearFakeFlat()
|
||||
void hw_ClearFakeFlat(HWDrawContext* drawctx)
|
||||
{
|
||||
FakeSectorAllocator.FreeAll();
|
||||
fakesectorbuffer = nullptr;
|
||||
drawctx->FakeSectorAllocator.FreeAll();
|
||||
drawctx->fakesectorbuffer = nullptr;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
class HWDrawContext;
|
||||
|
||||
enum area_t : int
|
||||
{
|
||||
area_normal,
|
||||
|
@ -8,10 +10,9 @@ enum area_t : int
|
|||
area_default
|
||||
};
|
||||
|
||||
|
||||
// Global functions.
|
||||
bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsector);
|
||||
void hw_ClearFakeFlat();
|
||||
sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *localcopy = nullptr);
|
||||
void hw_ClearFakeFlat(HWDrawContext* drawctx);
|
||||
sector_t * hw_FakeFlat(HWDrawContext* drawctx, 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);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ void HWMeshCache::Clear()
|
|||
TranslucentDepthBiased.reset();
|
||||
}
|
||||
|
||||
void HWMeshCache::Update(FRenderViewpoint& vp)
|
||||
void HWMeshCache::Update(HWDrawContext* drawctx, FRenderViewpoint& vp)
|
||||
{
|
||||
if (!gl_meshcache)
|
||||
return;
|
||||
|
@ -74,7 +74,7 @@ void HWMeshCache::Update(FRenderViewpoint& vp)
|
|||
|
||||
if (!Opaque)
|
||||
{
|
||||
HWDrawInfo* di = HWDrawInfo::StartDrawInfo(vp.ViewLevel, nullptr, vp, nullptr);
|
||||
HWDrawInfo* di = HWDrawInfo::StartDrawInfo(drawctx, vp.ViewLevel, nullptr, vp, nullptr);
|
||||
di->MeshBuilding = true;
|
||||
|
||||
MeshBuilder state;
|
||||
|
@ -98,7 +98,7 @@ void HWMeshCache::Update(FRenderViewpoint& vp)
|
|||
|
||||
HWFlat flat;
|
||||
flat.section = subsector->section;
|
||||
sector_t* front = hw_FakeFlat(subsector->render_sector, area_default, false);
|
||||
sector_t* front = hw_FakeFlat(di->drawctx, subsector->render_sector, area_default, false);
|
||||
flat.ProcessSector(di, state, front);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "r_defs.h"
|
||||
|
||||
struct FRenderViewpoint;
|
||||
class HWDrawContext;
|
||||
|
||||
#if 0
|
||||
class HWCachedSector
|
||||
|
@ -21,7 +22,7 @@ class HWMeshCache
|
|||
{
|
||||
public:
|
||||
void Clear();
|
||||
void Update(FRenderViewpoint& vp);
|
||||
void Update(HWDrawContext* drawctx, FRenderViewpoint& vp);
|
||||
|
||||
#if 0
|
||||
TArray<HWCachedSector> Sectors;
|
||||
|
|
|
@ -73,7 +73,6 @@ CCMD(gl_portalinfo)
|
|||
}
|
||||
|
||||
static FString indent;
|
||||
FPortalSceneState portalState;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -55,7 +55,7 @@ class HWPortal
|
|||
STP_AllInOne
|
||||
};
|
||||
|
||||
ActorRenderFlags savedvisibility;
|
||||
ActorRenderFlags savedvisibility = {};
|
||||
TArray<unsigned int> mPrimIndices;
|
||||
unsigned int mTopCap = ~0u, mBottomCap = ~0u;
|
||||
|
||||
|
@ -130,7 +130,6 @@ struct FPortalSceneState
|
|||
void RenderPortal(HWPortal *p, FRenderState &state, bool usestencil, HWDrawInfo *outer_di);
|
||||
};
|
||||
|
||||
extern FPortalSceneState portalState;
|
||||
|
||||
|
||||
class HWScenePortalBase : public HWPortal
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "a_dynlight.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
#include "hw_drawcontext.h"
|
||||
#include "hw_drawinfo.h"
|
||||
#include "hw_drawstructs.h"
|
||||
#include "hw_clock.h"
|
||||
|
@ -56,28 +57,28 @@ void HWDrawInfo::DispatchRenderHacks(FRenderState& state)
|
|||
glflat.section = nullptr;
|
||||
while (ofi.NextPair(pair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&Level->sectors[pair->Key], in_area, false);
|
||||
auto sec = hw_FakeFlat(drawctx, &Level->sectors[pair->Key], in_area, false);
|
||||
glflat.ProcessSector(this, state, sec, SSRF_RENDERFLOOR | SSRF_PLANEHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_subsectorrendernode*>::Iterator oci(otherCeilingPlanes);
|
||||
while (oci.NextPair(pair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&Level->sectors[pair->Key], in_area, false);
|
||||
auto sec = hw_FakeFlat(drawctx, &Level->sectors[pair->Key], in_area, false);
|
||||
glflat.ProcessSector(this, state, sec, SSRF_RENDERCEILING | SSRF_PLANEHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_floodrendernode*>::Iterator ffi(floodFloorSegs);
|
||||
while (ffi.NextPair(fpair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&Level->sectors[fpair->Key], in_area, false);
|
||||
auto sec = hw_FakeFlat(drawctx, &Level->sectors[fpair->Key], in_area, false);
|
||||
glflat.ProcessSector(this, state, sec, SSRF_RENDERFLOOR | SSRF_FLOODHACK);
|
||||
}
|
||||
|
||||
TMap<int, gl_floodrendernode*>::Iterator fci(floodCeilingSegs);
|
||||
while (fci.NextPair(fpair))
|
||||
{
|
||||
auto sec = hw_FakeFlat(&Level->sectors[fpair->Key], in_area, false);
|
||||
auto sec = hw_FakeFlat(drawctx, &Level->sectors[fpair->Key], in_area, false);
|
||||
glflat.ProcessSector(this, state, sec, SSRF_RENDERCEILING | SSRF_FLOODHACK);
|
||||
}
|
||||
}
|
||||
|
@ -89,14 +90,14 @@ void HWDrawInfo::DispatchRenderHacks(FRenderState& state)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static gl_subsectorrendernode *NewSubsectorRenderNode()
|
||||
static gl_subsectorrendernode *NewSubsectorRenderNode(HWDrawContext* drawctx)
|
||||
{
|
||||
return (gl_subsectorrendernode*)RenderDataAllocator.Alloc(sizeof(gl_subsectorrendernode));
|
||||
return (gl_subsectorrendernode*)drawctx->RenderDataAllocator.Alloc(sizeof(gl_subsectorrendernode));
|
||||
}
|
||||
|
||||
static gl_floodrendernode *NewFloodRenderNode()
|
||||
static gl_floodrendernode *NewFloodRenderNode(HWDrawContext* drawctx)
|
||||
{
|
||||
return (gl_floodrendernode*)RenderDataAllocator.Alloc(sizeof(gl_floodrendernode));
|
||||
return (gl_floodrendernode*)drawctx->RenderDataAllocator.Alloc(sizeof(gl_floodrendernode));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -335,7 +336,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, in_area, true);
|
||||
sector_t * sec = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
|
||||
// Don't bother with slopes
|
||||
if (sec->ceilingplane.isSlope()) return false;
|
||||
|
@ -393,7 +394,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, in_area, true);
|
||||
sector_t * sec = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
|
||||
// Don't bother with slopes
|
||||
if (sec->floorplane.isSlope()) return false;
|
||||
|
@ -452,7 +453,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, in_area, true);
|
||||
sector_t * sec = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
|
||||
// Don't bother with slopes
|
||||
if (sec->floorplane.isSlope()) return false;
|
||||
|
@ -505,7 +506,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, in_area, true);
|
||||
sector_t * sec = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
|
||||
// Don't bother with slopes
|
||||
if (sec->ceilingplane.isSlope()) return false;
|
||||
|
@ -553,7 +554,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area, FRenderState& state)
|
|||
sector_t * sec = MissingUpperTextures[i].seg->backsector;
|
||||
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode(drawctx);
|
||||
node->sub = HandledSubsectors[j];
|
||||
|
||||
AddOtherCeilingPlane(sec->sectornum, node, state);
|
||||
|
@ -586,7 +587,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area, FRenderState& state)
|
|||
|
||||
{
|
||||
// It isn't a hole. Now check whether it might be a fake bridge
|
||||
sector_t * fakesector = hw_FakeFlat(MissingUpperTextures[i].seg->frontsector, in_area, false);
|
||||
sector_t * fakesector = hw_FakeFlat(drawctx, MissingUpperTextures[i].seg->frontsector, in_area, false);
|
||||
float planez = (float)fakesector->GetPlaneTexZ(sector_t::ceiling);
|
||||
|
||||
backsub->validcount = validcount;
|
||||
|
@ -594,7 +595,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area, FRenderState& state)
|
|||
{
|
||||
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode(drawctx);
|
||||
node->sub = HandledSubsectors[j];
|
||||
AddOtherCeilingPlane(fakesector->sectornum, node, state);
|
||||
}
|
||||
|
@ -620,7 +621,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area, FRenderState& state)
|
|||
|
||||
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode(drawctx);
|
||||
node->sub = HandledSubsectors[j];
|
||||
AddOtherFloorPlane(sec->sectornum, node, state);
|
||||
}
|
||||
|
@ -652,7 +653,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area, FRenderState& state)
|
|||
|
||||
{
|
||||
// It isn't a hole. Now check whether it might be a fake bridge
|
||||
sector_t * fakesector = hw_FakeFlat(MissingLowerTextures[i].seg->frontsector, in_area, false);
|
||||
sector_t * fakesector = hw_FakeFlat(drawctx, MissingLowerTextures[i].seg->frontsector, in_area, false);
|
||||
float planez = (float)fakesector->GetPlaneTexZ(sector_t::floor);
|
||||
|
||||
backsub->validcount = validcount;
|
||||
|
@ -660,7 +661,7 @@ void HWDrawInfo::HandleMissingTextures(area_t in_area, FRenderState& state)
|
|||
{
|
||||
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode(drawctx);
|
||||
node->sub = HandledSubsectors[j];
|
||||
AddOtherFloorPlane(fakesector->sectornum, node, state);
|
||||
}
|
||||
|
@ -726,8 +727,8 @@ void HWDrawInfo::CreateFloodPoly(wallseg * ws, FFlatVertex *vertices, float plan
|
|||
void HWDrawInfo::PrepareUpperGap(seg_t * seg, FRenderState& state)
|
||||
{
|
||||
wallseg ws;
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, in_area, false);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
sector_t * fakefsector = hw_FakeFlat(drawctx, seg->frontsector, in_area, false);
|
||||
sector_t * fakebsector = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
|
||||
vertex_t * v1, *v2;
|
||||
|
||||
|
@ -763,7 +764,7 @@ void HWDrawInfo::PrepareUpperGap(seg_t * seg, FRenderState& state)
|
|||
CreateFloodStencilPoly(&ws, vertices.first);
|
||||
CreateFloodPoly(&ws, vertices.first+4, ws.z2, fakebsector, true);
|
||||
|
||||
gl_floodrendernode *node = NewFloodRenderNode();
|
||||
gl_floodrendernode *node = NewFloodRenderNode(drawctx);
|
||||
auto pNode = floodCeilingSegs.CheckKey(fakebsector->sectornum);
|
||||
|
||||
node->next = pNode? *pNode : nullptr;
|
||||
|
@ -782,8 +783,8 @@ void HWDrawInfo::PrepareUpperGap(seg_t * seg, FRenderState& state)
|
|||
void HWDrawInfo::PrepareLowerGap(seg_t * seg, FRenderState& state)
|
||||
{
|
||||
wallseg ws;
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, in_area, false);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
sector_t * fakefsector = hw_FakeFlat(drawctx, seg->frontsector, in_area, false);
|
||||
sector_t * fakebsector = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
|
||||
vertex_t * v1, *v2;
|
||||
|
||||
|
@ -820,7 +821,7 @@ void HWDrawInfo::PrepareLowerGap(seg_t * seg, FRenderState& state)
|
|||
CreateFloodStencilPoly(&ws, vertices.first);
|
||||
CreateFloodPoly(&ws, vertices.first+4, ws.z1, fakebsector, false);
|
||||
|
||||
gl_floodrendernode *node = NewFloodRenderNode();
|
||||
gl_floodrendernode *node = NewFloodRenderNode(drawctx);
|
||||
auto pNode = floodFloorSegs.CheckKey(fakebsector->sectornum);
|
||||
|
||||
node->next = pNode? *pNode : nullptr;
|
||||
|
@ -1141,7 +1142,7 @@ void HWDrawInfo::HandleHackedSubsectors(FRenderState& state)
|
|||
{
|
||||
for(unsigned int j=0;j<HandledSubsectors.Size();j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode(drawctx);
|
||||
node->sub = HandledSubsectors[j];
|
||||
AddOtherFloorPlane(sub->render_sector->sectornum, node, state);
|
||||
}
|
||||
|
@ -1163,7 +1164,7 @@ void HWDrawInfo::HandleHackedSubsectors(FRenderState& state)
|
|||
{
|
||||
for(unsigned int j=0;j<HandledSubsectors.Size();j++)
|
||||
{
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode();
|
||||
gl_subsectorrendernode * node = NewSubsectorRenderNode(drawctx);
|
||||
node->sub = HandledSubsectors[j];
|
||||
AddOtherCeilingPlane(sub->render_sector->sectornum, node, state);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "hw_portal.h"
|
||||
#include "hw_lighting.h"
|
||||
#include "hw_cvars.h"
|
||||
|
||||
#include "hw_drawcontext.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -119,7 +119,7 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool
|
|||
}
|
||||
|
||||
// Make fog a little denser when inside a skybox
|
||||
if (portalState.inskybox) fogdensity += fogdensity / 2;
|
||||
if (drawctx->portalState.inskybox) fogdensity += fogdensity / 2;
|
||||
|
||||
|
||||
// no fog in enhanced vision modes!
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "g_level.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "actorinlines.h"
|
||||
#include "hw_drawcontext.h"
|
||||
#include "hw_dynlightdata.h"
|
||||
#include "hw_shadowmap.h"
|
||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||
|
@ -217,17 +218,14 @@ void HWDrawInfo::GetDynSpriteLight(AActor *thing, particle_t *particle, float *o
|
|||
}
|
||||
}
|
||||
|
||||
// static so that we build up a reserve (memory allocations stop)
|
||||
// For multithread processing each worker thread needs its own copy, though.
|
||||
static thread_local TArray<FDynamicLight*> addedLightsArray;
|
||||
|
||||
void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata)
|
||||
void hw_GetDynModelLight(HWDrawContext* drawctx, AActor *self, FDynLightData &modellightdata)
|
||||
{
|
||||
modellightdata.Clear();
|
||||
|
||||
if (self)
|
||||
{
|
||||
auto &addedLights = addedLightsArray; // avoid going through the thread local storage for each use.
|
||||
auto &addedLights = drawctx->addedLightsArray;
|
||||
|
||||
addedLights.Clear();
|
||||
|
||||
|
|
|
@ -550,7 +550,7 @@ inline void HWSprite::PutSprite(HWDrawInfo *di, FRenderState& state, bool transl
|
|||
// That's a lot of checks...
|
||||
if (modelframe && !modelframe->isVoxel && !(modelframe->flags & MDL_NOPERPIXELLIGHTING) && RenderStyle.BlendOp != STYLEOP_Shadow && gl_light_sprites && di->Level->HasDynamicLights && !di->isFullbrightScene() && !fullbright)
|
||||
{
|
||||
hw_GetDynModelLight(actor, lightdata);
|
||||
hw_GetDynModelLight(di->drawctx, actor, lightdata);
|
||||
dynlightindex = state.UploadLights(lightdata);
|
||||
}
|
||||
else
|
||||
|
@ -871,7 +871,7 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto
|
|||
{
|
||||
// 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);
|
||||
rendersector = hw_FakeFlat(di->drawctx, thing->Sector, in_area, false, &rs);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1518,11 +1518,11 @@ void HWDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport, area_t in_area,
|
|||
// [Nash] draw sprite shadow
|
||||
if (R_ShouldDrawSpriteShadow(th))
|
||||
{
|
||||
spr.Process(this, state, th, hw_FakeFlat(th->Sector, in_area, false, &fakesector), in_area, 2, true);
|
||||
spr.Process(this, state, th, hw_FakeFlat(drawctx, th->Sector, in_area, false, &fakesector), in_area, 2, true);
|
||||
}
|
||||
|
||||
// This is called from the worker thread and must not alter the fake sector cache.
|
||||
spr.Process(this, state, th, hw_FakeFlat(th->Sector, in_area, false, &fakesector), in_area, 2);
|
||||
spr.Process(this, state, th, hw_FakeFlat(drawctx, th->Sector, in_area, false, &fakesector), in_area, 2);
|
||||
th->Angles.Yaw = savedangle;
|
||||
th->SetXYZ(savedpos);
|
||||
th->Prev -= newpos - savedpos;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "hw_cvars.h"
|
||||
#include "hw_clock.h"
|
||||
#include "hw_lighting.h"
|
||||
#include "hw_drawcontext.h"
|
||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
|
@ -572,11 +573,11 @@ void HWWall::PutPortal(HWDrawInfo *di, FRenderState& state, int ptype, int plane
|
|||
// portals don't go into the draw list.
|
||||
// Instead they are added to the portal manager
|
||||
case PORTALTYPE_HORIZON:
|
||||
horizon = portalState.UniqueHorizons.Get(horizon);
|
||||
horizon = di->drawctx->portalState.UniqueHorizons.Get(horizon);
|
||||
portal = di->FindPortal(horizon);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWHorizonPortal(&portalState, state, horizon, di->Viewpoint);
|
||||
portal = new HWHorizonPortal(&di->drawctx->portalState, state, horizon, di->Viewpoint);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
|
@ -587,10 +588,10 @@ void HWWall::PutPortal(HWDrawInfo *di, FRenderState& state, int ptype, int plane
|
|||
if (!portal)
|
||||
{
|
||||
// either a regular skybox or an Eternity-style horizon
|
||||
if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new HWEEHorizonPortal(&portalState, secportal);
|
||||
if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new HWEEHorizonPortal(&di->drawctx->portalState, secportal);
|
||||
else
|
||||
{
|
||||
portal = new HWSkyboxPortal(&portalState, secportal);
|
||||
portal = new HWSkyboxPortal(&di->drawctx->portalState, secportal);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
}
|
||||
|
@ -601,20 +602,20 @@ void HWWall::PutPortal(HWDrawInfo *di, FRenderState& state, int ptype, int plane
|
|||
portal = di->FindPortal(this->portal);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWSectorStackPortal(&portalState, this->portal);
|
||||
portal = new HWSectorStackPortal(&di->drawctx->portalState, this->portal);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_PLANEMIRROR:
|
||||
if (portalState.PlaneMirrorMode * planemirror->fC() <= 0)
|
||||
if (di->drawctx->portalState.PlaneMirrorMode * planemirror->fC() <= 0)
|
||||
{
|
||||
planemirror = portalState.UniquePlaneMirrors.Get(planemirror);
|
||||
planemirror = di->drawctx->portalState.UniquePlaneMirrors.Get(planemirror);
|
||||
portal = di->FindPortal(planemirror);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWPlaneMirrorPortal(&portalState, planemirror);
|
||||
portal = new HWPlaneMirrorPortal(&di->drawctx->portalState, planemirror);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
|
@ -625,7 +626,7 @@ void HWWall::PutPortal(HWDrawInfo *di, FRenderState& state, int ptype, int plane
|
|||
portal = di->FindPortal(seg->linedef);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWMirrorPortal(&portalState, seg->linedef);
|
||||
portal = new HWMirrorPortal(&di->drawctx->portalState, seg->linedef);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
|
@ -647,18 +648,18 @@ void HWWall::PutPortal(HWDrawInfo *di, FRenderState& state, int ptype, int plane
|
|||
{
|
||||
di->ProcessActorsInPortal(otherside->getPortal()->mGroup, di->in_area, state);
|
||||
}
|
||||
portal = new HWLineToLinePortal(&portalState, lineportal);
|
||||
portal = new HWLineToLinePortal(&di->drawctx->portalState, lineportal);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKY:
|
||||
sky = portalState.UniqueSkies.Get(sky);
|
||||
sky = di->drawctx->portalState.UniqueSkies.Get(sky);
|
||||
portal = di->FindPortal(sky);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWSkyPortal(screen->mSkyData, &portalState, sky);
|
||||
portal = new HWSkyPortal(screen->mSkyData, &di->drawctx->portalState, sky);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
|
|
|
@ -316,7 +316,7 @@ WeaponLighting HWDrawInfo::GetWeaponLighting(sector_t *viewsector, const DVector
|
|||
}
|
||||
else
|
||||
{
|
||||
auto fakesec = hw_FakeFlat(viewsector, in_area, false);
|
||||
auto fakesec = hw_FakeFlat(drawctx, viewsector, in_area, false);
|
||||
|
||||
// calculate light level for weapon sprites
|
||||
l.lightlevel = hw_ClampLight(fakesec->lightlevel);
|
||||
|
@ -840,7 +840,7 @@ void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area, F
|
|||
// set the lighting parameters
|
||||
if (hudsprite.RenderStyle.BlendOp != STYLEOP_Shadow && Level->HasDynamicLights && !isFullbrightScene() && gl_light_sprites)
|
||||
{
|
||||
hw_GetDynModelLight(playermo, lightdata);
|
||||
hw_GetDynModelLight(drawctx, playermo, lightdata);
|
||||
hudsprite.lightindex = state.UploadLights(lightdata);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue