mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-29 07:12:36 +00:00
Hook up thread slices and eliminate some statics hiding in misc functions
This commit is contained in:
parent
f50532af8a
commit
d9e545a519
12 changed files with 154 additions and 76 deletions
|
@ -64,7 +64,6 @@ namespace swrenderer
|
||||||
|
|
||||||
void SWRenderLine::Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, bool infog, FDynamicColormap *colormap)
|
void SWRenderLine::Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, bool infog, FDynamicColormap *colormap)
|
||||||
{
|
{
|
||||||
static sector_t tempsec; // killough 3/8/98: ceiling/water hack
|
|
||||||
bool solid;
|
bool solid;
|
||||||
DVector2 pt1, pt2;
|
DVector2 pt1, pt2;
|
||||||
|
|
||||||
|
@ -284,11 +283,7 @@ namespace swrenderer
|
||||||
rw_floorstat = wallbottom.Project(frontsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
rw_floorstat = wallbottom.Project(frontsector->floorplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SWRenderLine *self = this;
|
bool visible = Thread->ClipSegments->Clip(WallC.sx1, WallC.sx2, solid, this);
|
||||||
bool visible = Thread->ClipSegments->Clip(WallC.sx1, WallC.sx2, solid, [](int x1, int x2) -> bool
|
|
||||||
{
|
|
||||||
return self->RenderWallSegment(x1, x2);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (visible)
|
if (visible)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "r_wallsetup.h"
|
#include "r_wallsetup.h"
|
||||||
|
#include "swrenderer/segments/r_clipsegment.h"
|
||||||
|
|
||||||
struct seg_t;
|
struct seg_t;
|
||||||
struct subsector_t;
|
struct subsector_t;
|
||||||
|
@ -48,7 +49,7 @@ namespace swrenderer
|
||||||
void InitFromLine(RenderThread *thread, const DVector2 &left, const DVector2 &right);
|
void InitFromLine(RenderThread *thread, const DVector2 &left, const DVector2 &right);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SWRenderLine
|
class SWRenderLine : VisibleSegmentRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SWRenderLine(RenderThread *thread);
|
SWRenderLine(RenderThread *thread);
|
||||||
|
@ -57,7 +58,7 @@ namespace swrenderer
|
||||||
RenderThread *Thread = nullptr;
|
RenderThread *Thread = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool RenderWallSegment(int x1, int x2);
|
bool RenderWallSegment(int x1, int x2) override;
|
||||||
void SetWallVariables(bool needlights);
|
void SetWallVariables(bool needlights);
|
||||||
void RenderWallSegmentTextures(int x1, int x2);
|
void RenderWallSegmentTextures(int x1, int x2);
|
||||||
|
|
||||||
|
@ -133,5 +134,7 @@ namespace swrenderer
|
||||||
ProjectedWallLine wallupper;
|
ProjectedWallLine wallupper;
|
||||||
ProjectedWallLine walllower;
|
ProjectedWallLine walllower;
|
||||||
ProjectedWallTexcoords walltexcoords;
|
ProjectedWallTexcoords walltexcoords;
|
||||||
|
|
||||||
|
sector_t tempsec; // killough 3/8/98: ceiling/water hack
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "swrenderer/line/r_walldraw.h"
|
#include "swrenderer/line/r_walldraw.h"
|
||||||
#include "swrenderer/line/r_wallsetup.h"
|
#include "swrenderer/line/r_wallsetup.h"
|
||||||
#include "swrenderer/r_renderthread.h"
|
#include "swrenderer/r_renderthread.h"
|
||||||
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
|
@ -188,14 +189,22 @@ namespace swrenderer
|
||||||
drawerargs.dc_viewpos.Z = (float)((viewport->CenterY - y1 - 0.5) / viewport->InvZtoScale * zcol);
|
drawerargs.dc_viewpos.Z = (float)((viewport->CenterY - y1 - 0.5) / viewport->InvZtoScale * zcol);
|
||||||
drawerargs.dc_viewpos_step.Z = (float)(-zcol / viewport->InvZtoScale);
|
drawerargs.dc_viewpos_step.Z = (float)(-zcol / viewport->InvZtoScale);
|
||||||
|
|
||||||
static TriLight lightbuffer[64 * 1024];
|
// Calculate max lights that can touch column so we can allocate memory for the list
|
||||||
static int nextlightindex = 0;
|
int max_lights = 0;
|
||||||
|
FLightNode *cur_node = light_list;
|
||||||
|
while (cur_node)
|
||||||
|
{
|
||||||
|
if (!(cur_node->lightsource->flags2&MF2_DORMANT))
|
||||||
|
max_lights++;
|
||||||
|
cur_node = cur_node->nextLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawerargs.dc_num_lights = 0;
|
||||||
|
drawerargs.dc_lights = Thread->FrameMemory->AllocMemory<TriLight>(max_lights);
|
||||||
|
|
||||||
// Setup lights for column
|
// Setup lights for column
|
||||||
drawerargs.dc_num_lights = 0;
|
cur_node = light_list;
|
||||||
drawerargs.dc_lights = lightbuffer + nextlightindex;
|
while (cur_node)
|
||||||
FLightNode *cur_node = light_list;
|
|
||||||
while (cur_node && nextlightindex < 64 * 1024)
|
|
||||||
{
|
{
|
||||||
if (!(cur_node->lightsource->flags2&MF2_DORMANT))
|
if (!(cur_node->lightsource->flags2&MF2_DORMANT))
|
||||||
{
|
{
|
||||||
|
@ -220,7 +229,6 @@ namespace swrenderer
|
||||||
uint32_t green = cur_node->lightsource->GetGreen();
|
uint32_t green = cur_node->lightsource->GetGreen();
|
||||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||||
|
|
||||||
nextlightindex++;
|
|
||||||
auto &light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
auto &light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||||
light.x = lconstant;
|
light.x = lconstant;
|
||||||
light.y = nlconstant;
|
light.y = nlconstant;
|
||||||
|
@ -232,9 +240,6 @@ namespace swrenderer
|
||||||
|
|
||||||
cur_node = cur_node->nextLight;
|
cur_node = cur_node->nextLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextlightindex == 64 * 1024)
|
|
||||||
nextlightindex = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,9 +56,10 @@
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
RenderThread::RenderThread(RenderScene *scene)
|
RenderThread::RenderThread(RenderScene *scene, bool mainThread)
|
||||||
{
|
{
|
||||||
Scene = scene;
|
Scene = scene;
|
||||||
|
MainThread = mainThread;
|
||||||
FrameMemory = std::make_unique<RenderMemory>();
|
FrameMemory = std::make_unique<RenderMemory>();
|
||||||
DrawQueue = std::make_shared<DrawerCommandQueue>(this);
|
DrawQueue = std::make_shared<DrawerCommandQueue>(this);
|
||||||
OpaquePass = std::make_unique<RenderOpaquePass>(this);
|
OpaquePass = std::make_unique<RenderOpaquePass>(this);
|
||||||
|
|
|
@ -47,12 +47,13 @@ namespace swrenderer
|
||||||
class RenderThread
|
class RenderThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RenderThread(RenderScene *scene);
|
RenderThread(RenderScene *scene, bool mainThread = true);
|
||||||
~RenderThread();
|
~RenderThread();
|
||||||
|
|
||||||
RenderScene *Scene;
|
RenderScene *Scene;
|
||||||
int X1 = 0;
|
int X1 = 0;
|
||||||
int X2 = MAXWIDTH;
|
int X2 = MAXWIDTH;
|
||||||
|
bool MainThread = false;
|
||||||
|
|
||||||
std::unique_ptr<RenderMemory> FrameMemory;
|
std::unique_ptr<RenderMemory> FrameMemory;
|
||||||
std::unique_ptr<RenderOpaquePass> OpaquePass;
|
std::unique_ptr<RenderOpaquePass> OpaquePass;
|
||||||
|
@ -65,7 +66,11 @@ namespace swrenderer
|
||||||
std::unique_ptr<DrawSegmentList> DrawSegments;
|
std::unique_ptr<DrawSegmentList> DrawSegments;
|
||||||
std::unique_ptr<RenderClipSegment> ClipSegments;
|
std::unique_ptr<RenderClipSegment> ClipSegments;
|
||||||
DrawerCommandQueuePtr DrawQueue;
|
DrawerCommandQueuePtr DrawQueue;
|
||||||
|
|
||||||
|
// VisibleSprite working buffers
|
||||||
|
short clipbot[MAXWIDTH];
|
||||||
|
short cliptop[MAXWIDTH];
|
||||||
|
|
||||||
SWPixelFormatDrawers *Drawers();
|
SWPixelFormatDrawers *Drawers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
EXTERN_CVAR(Bool, r_shadercolormaps)
|
EXTERN_CVAR(Bool, r_shadercolormaps)
|
||||||
EXTERN_CVAR(Int, r_clearbuffer)
|
EXTERN_CVAR(Int, r_clearbuffer)
|
||||||
|
|
||||||
|
CVAR(Bool, r_scene_multithreaded, false, 0);
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles;
|
cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles;
|
||||||
|
@ -100,8 +102,19 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
MainThread()->DrawQueue->Push<ApplySpecialColormapRGBACommand>(CameraLight::Instance()->ShaderColormap(), screen);
|
MainThread()->DrawQueue->Push<ApplySpecialColormapRGBACommand>(CameraLight::Instance()->ShaderColormap(), screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawerThreads::Execute({ MainThread()->DrawQueue });
|
RenderDrawQueues();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderScene::RenderDrawQueues()
|
||||||
|
{
|
||||||
|
// Use reverse order so main thread is drawn last
|
||||||
|
std::vector<DrawerCommandQueuePtr> queues;
|
||||||
|
for (auto it = Threads.rbegin(); it != Threads.rend(); ++it)
|
||||||
|
{
|
||||||
|
queues.push_back((*it)->DrawQueue);
|
||||||
|
}
|
||||||
|
DrawerThreads::Execute(queues);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderScene::RenderActorView(AActor *actor, bool dontmaplines)
|
void RenderScene::RenderActorView(AActor *actor, bool dontmaplines)
|
||||||
|
@ -132,48 +145,7 @@ namespace swrenderer
|
||||||
camera->renderflags |= RF_INVISIBLE;
|
camera->renderflags |= RF_INVISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainThread()->FrameMemory->Clear();
|
RenderThreadSlices();
|
||||||
MainThread()->Clip3DFloors->Cleanup();
|
|
||||||
MainThread()->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
|
|
||||||
MainThread()->Portal->CopyStackedViewParameters();
|
|
||||||
MainThread()->ClipSegments->Clear(0, viewwidth);
|
|
||||||
MainThread()->DrawSegments->Clear();
|
|
||||||
MainThread()->PlaneList->Clear();
|
|
||||||
MainThread()->TranslucentPass->Clear();
|
|
||||||
MainThread()->OpaquePass->ClearClip();
|
|
||||||
MainThread()->OpaquePass->ResetFakingUnderwater(); // [RH] Hack to make windows into underwater areas possible
|
|
||||||
MainThread()->Portal->SetMainPortal();
|
|
||||||
|
|
||||||
// Cull things outside the range seen by this thread
|
|
||||||
if (MainThread()->X1 > 0)
|
|
||||||
MainThread()->ClipSegments->Clip(0, MainThread()->X1, true, [](int, int) { return true; });
|
|
||||||
if (MainThread()->X2 < viewwidth)
|
|
||||||
MainThread()->ClipSegments->Clip(MainThread()->X2, viewwidth, true, [](int, int) { return true; });
|
|
||||||
|
|
||||||
WallCycles.Clock();
|
|
||||||
MainThread()->OpaquePass->RenderScene();
|
|
||||||
MainThread()->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
|
|
||||||
WallCycles.Unclock();
|
|
||||||
|
|
||||||
NetUpdate();
|
|
||||||
|
|
||||||
if (viewactive)
|
|
||||||
{
|
|
||||||
PlaneCycles.Clock();
|
|
||||||
MainThread()->PlaneList->Render();
|
|
||||||
MainThread()->Portal->RenderPlanePortals();
|
|
||||||
PlaneCycles.Unclock();
|
|
||||||
|
|
||||||
MainThread()->Portal->RenderLinePortals();
|
|
||||||
|
|
||||||
NetUpdate();
|
|
||||||
|
|
||||||
MaskedCycles.Clock();
|
|
||||||
MainThread()->TranslucentPass->Render();
|
|
||||||
MaskedCycles.Unclock();
|
|
||||||
|
|
||||||
NetUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
camera->renderflags = savedflags;
|
camera->renderflags = savedflags;
|
||||||
interpolator.RestoreInterpolations();
|
interpolator.RestoreInterpolations();
|
||||||
|
@ -186,6 +158,94 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderScene::RenderThreadSlices()
|
||||||
|
{
|
||||||
|
int numThreads = r_scene_multithreaded ? 8 : 1;
|
||||||
|
|
||||||
|
while (Threads.size() > (size_t)numThreads)
|
||||||
|
{
|
||||||
|
Threads.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (Threads.size() < (size_t)numThreads)
|
||||||
|
{
|
||||||
|
Threads.push_back(std::make_unique<RenderThread>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < numThreads; i++)
|
||||||
|
{
|
||||||
|
Threads[i]->X1 = viewwidth * i / numThreads;
|
||||||
|
Threads[i]->X2 = viewwidth * (i + 1) / numThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < numThreads; i++)
|
||||||
|
{
|
||||||
|
RenderThreadSlice(Threads[i].get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderScene::RenderThreadSlice(RenderThread *thread)
|
||||||
|
{
|
||||||
|
thread->FrameMemory->Clear();
|
||||||
|
thread->Clip3DFloors->Cleanup();
|
||||||
|
thread->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
|
||||||
|
thread->Portal->CopyStackedViewParameters();
|
||||||
|
thread->ClipSegments->Clear(0, viewwidth);
|
||||||
|
thread->DrawSegments->Clear();
|
||||||
|
thread->PlaneList->Clear();
|
||||||
|
thread->TranslucentPass->Clear();
|
||||||
|
thread->OpaquePass->ClearClip();
|
||||||
|
thread->OpaquePass->ResetFakingUnderwater(); // [RH] Hack to make windows into underwater areas possible
|
||||||
|
thread->Portal->SetMainPortal();
|
||||||
|
|
||||||
|
// Cull things outside the range seen by this thread
|
||||||
|
VisibleSegmentRenderer visitor;
|
||||||
|
if (thread->X1 > 0)
|
||||||
|
thread->ClipSegments->Clip(0, thread->X1, true, &visitor);
|
||||||
|
if (thread->X2 < viewwidth)
|
||||||
|
thread->ClipSegments->Clip(thread->X2, viewwidth, true, &visitor);
|
||||||
|
|
||||||
|
if (thread->MainThread)
|
||||||
|
WallCycles.Clock();
|
||||||
|
|
||||||
|
thread->OpaquePass->RenderScene();
|
||||||
|
thread->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
|
||||||
|
|
||||||
|
if (thread == MainThread())
|
||||||
|
WallCycles.Unclock();
|
||||||
|
|
||||||
|
if (thread->MainThread)
|
||||||
|
NetUpdate();
|
||||||
|
|
||||||
|
if (viewactive)
|
||||||
|
{
|
||||||
|
if (thread->MainThread)
|
||||||
|
PlaneCycles.Clock();
|
||||||
|
|
||||||
|
thread->PlaneList->Render();
|
||||||
|
thread->Portal->RenderPlanePortals();
|
||||||
|
|
||||||
|
if (thread->MainThread)
|
||||||
|
PlaneCycles.Unclock();
|
||||||
|
|
||||||
|
thread->Portal->RenderLinePortals();
|
||||||
|
|
||||||
|
if (thread->MainThread)
|
||||||
|
NetUpdate();
|
||||||
|
|
||||||
|
if (thread->MainThread)
|
||||||
|
MaskedCycles.Clock();
|
||||||
|
|
||||||
|
thread->TranslucentPass->Render();
|
||||||
|
|
||||||
|
if (thread->MainThread)
|
||||||
|
MaskedCycles.Unclock();
|
||||||
|
|
||||||
|
if (thread->MainThread)
|
||||||
|
NetUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RenderScene::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines)
|
void RenderScene::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines)
|
||||||
{
|
{
|
||||||
auto viewport = RenderViewport::Instance();
|
auto viewport = RenderViewport::Instance();
|
||||||
|
@ -202,8 +262,7 @@ namespace swrenderer
|
||||||
viewport->SetViewport(width, height, WidescreenRatio);
|
viewport->SetViewport(width, height, WidescreenRatio);
|
||||||
|
|
||||||
RenderActorView(actor, dontmaplines);
|
RenderActorView(actor, dontmaplines);
|
||||||
|
RenderDrawQueues();
|
||||||
DrawerThreads::Execute({ MainThread()->DrawQueue });
|
|
||||||
|
|
||||||
viewport->RenderTarget = screen;
|
viewport->RenderTarget = screen;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,9 @@ namespace swrenderer
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RenderActorView(AActor *actor, bool dontmaplines = false);
|
void RenderActorView(AActor *actor, bool dontmaplines = false);
|
||||||
|
void RenderDrawQueues();
|
||||||
|
void RenderThreadSlices();
|
||||||
|
void RenderThreadSlice(RenderThread *thread);
|
||||||
|
|
||||||
bool dontmaplines = false;
|
bool dontmaplines = false;
|
||||||
int clearcolor = 0;
|
int clearcolor = 0;
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace swrenderer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderClipSegment::Clip(int first, int last, bool solid, VisibleSegmentCallback callback)
|
bool RenderClipSegment::Clip(int first, int last, bool solid, VisibleSegmentRenderer *visitor)
|
||||||
{
|
{
|
||||||
cliprange_t *next, *start;
|
cliprange_t *next, *start;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -104,7 +104,7 @@ namespace swrenderer
|
||||||
if (last <= start->first)
|
if (last <= start->first)
|
||||||
{
|
{
|
||||||
// Post is entirely visible (above start).
|
// Post is entirely visible (above start).
|
||||||
if (!callback(first, last))
|
if (!visitor->RenderWallSegment(first, last))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Insert a new clippost for solid walls.
|
// Insert a new clippost for solid walls.
|
||||||
|
@ -131,7 +131,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a fragment above *start.
|
// There is a fragment above *start.
|
||||||
if (callback(first, start->first) && solid)
|
if (visitor->RenderWallSegment(first, start->first) && solid)
|
||||||
{
|
{
|
||||||
start->first = first; // Adjust the clip size for solid walls
|
start->first = first; // Adjust the clip size for solid walls
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ namespace swrenderer
|
||||||
while (last >= (next + 1)->first)
|
while (last >= (next + 1)->first)
|
||||||
{
|
{
|
||||||
// There is a fragment between two posts.
|
// There is a fragment between two posts.
|
||||||
clipsegment = callback(next->last, (next + 1)->first);
|
clipsegment = visitor->RenderWallSegment(next->last, (next + 1)->first);
|
||||||
next++;
|
next++;
|
||||||
|
|
||||||
if (last <= next->last)
|
if (last <= next->last)
|
||||||
|
@ -158,7 +158,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is a fragment after *next.
|
// There is a fragment after *next.
|
||||||
clipsegment = callback(next->last, last);
|
clipsegment = visitor->RenderWallSegment(next->last, last);
|
||||||
|
|
||||||
crunch:
|
crunch:
|
||||||
if (!clipsegment)
|
if (!clipsegment)
|
||||||
|
|
|
@ -17,11 +17,18 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
typedef bool(*VisibleSegmentCallback)(int x1, int x2);
|
typedef bool(*VisibleSegmentCallback)(int x1, int x2);
|
||||||
|
|
||||||
|
class VisibleSegmentRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~VisibleSegmentRenderer() { }
|
||||||
|
virtual bool RenderWallSegment(int x1, int x2) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
class RenderClipSegment
|
class RenderClipSegment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Clear(short left, short right);
|
void Clear(short left, short right);
|
||||||
bool Clip(int x1, int x2, bool solid, VisibleSegmentCallback callback);
|
bool Clip(int x1, int x2, bool solid, VisibleSegmentRenderer *visitor);
|
||||||
bool Check(int first, int last);
|
bool Check(int first, int last);
|
||||||
bool IsVisible(int x1, int x2);
|
bool IsVisible(int x1, int x2);
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,6 @@ namespace swrenderer
|
||||||
DPSprite* psp;
|
DPSprite* psp;
|
||||||
DPSprite* weapon;
|
DPSprite* weapon;
|
||||||
sector_t* sec = NULL;
|
sector_t* sec = NULL;
|
||||||
static sector_t tempsec;
|
|
||||||
int floorlight, ceilinglight;
|
int floorlight, ceilinglight;
|
||||||
F3DFloor *rover;
|
F3DFloor *rover;
|
||||||
|
|
||||||
|
|
|
@ -88,5 +88,6 @@ namespace swrenderer
|
||||||
enum { BASEYCENTER = 100 };
|
enum { BASEYCENTER = 100 };
|
||||||
|
|
||||||
TArray<HWAccelPlayerSprite> AcceleratedSprites;
|
TArray<HWAccelPlayerSprite> AcceleratedSprites;
|
||||||
|
sector_t tempsec;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,8 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
void VisibleSprite::Render(RenderThread *thread)
|
void VisibleSprite::Render(RenderThread *thread)
|
||||||
{
|
{
|
||||||
static short clipbot[MAXWIDTH];
|
short *clipbot = thread->clipbot;
|
||||||
static short cliptop[MAXWIDTH];
|
short *cliptop = thread->cliptop;
|
||||||
|
|
||||||
VisibleSprite *spr = this;
|
VisibleSprite *spr = this;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue