Move renderer singletons into a RenderThread class

This commit is contained in:
Magnus Norddahl 2017-02-04 00:25:37 +01:00
parent 4fadc4e9a3
commit 627a388d57
51 changed files with 468 additions and 258 deletions

View file

@ -848,6 +848,7 @@ set( NOT_COMPILED_SOURCE_FILES
set( FASTMATH_PCH_SOURCES set( FASTMATH_PCH_SOURCES
swrenderer/r_swrenderer.cpp swrenderer/r_swrenderer.cpp
swrenderer/r_memory.cpp swrenderer/r_memory.cpp
swrenderer/r_renderthread.cpp
swrenderer/drawers/r_draw.cpp swrenderer/drawers/r_draw.cpp
swrenderer/drawers/r_draw_pal.cpp swrenderer/drawers/r_draw_pal.cpp
swrenderer/drawers/r_draw_rgba.cpp swrenderer/drawers/r_draw_rgba.cpp

View file

@ -49,6 +49,7 @@
#include "swrenderer/plane/r_visibleplane.h" #include "swrenderer/plane/r_visibleplane.h"
#include "swrenderer/plane/r_visibleplanelist.h" #include "swrenderer/plane/r_visibleplanelist.h"
#include "swrenderer/things/r_decal.h" #include "swrenderer/things/r_decal.h"
#include "swrenderer/r_renderthread.h"
CVAR(Bool, r_fogboundary, true, 0) CVAR(Bool, r_fogboundary, true, 0)
CVAR(Bool, r_drawmirrors, true, 0) CVAR(Bool, r_drawmirrors, true, 0)
@ -56,6 +57,11 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer namespace swrenderer
{ {
SWRenderLine::SWRenderLine(RenderThread *thread)
{
Thread = thread;
}
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 static sector_t tempsec; // killough 3/8/98: ceiling/water hack
@ -79,17 +85,17 @@ namespace swrenderer
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0) if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
return; return;
if (WallC.Init(pt1, pt2, 32.0 / (1 << 12))) if (WallC.Init(Thread, pt1, pt2, 32.0 / (1 << 12)))
return; return;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
if (WallC.sx1 >= renderportal->WindowRight || WallC.sx2 <= renderportal->WindowLeft) if (WallC.sx1 >= renderportal->WindowRight || WallC.sx2 <= renderportal->WindowLeft)
return; return;
if (line->linedef == NULL) if (line->linedef == NULL)
{ {
if (RenderClipSegment::Instance()->Check(WallC.sx1, WallC.sx2)) if (Thread->ClipSegments->Check(WallC.sx1, WallC.sx2))
{ {
InSubsector->flags |= SSECF_DRAWN; InSubsector->flags |= SSECF_DRAWN;
} }
@ -107,7 +113,7 @@ namespace swrenderer
if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2)) if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2))
{ // The seg is the entire wall. { // The seg is the entire wall.
WallT.InitFromWallCoords(&WallC); WallT.InitFromWallCoords(Thread, &WallC);
} }
else else
{ // The seg is only part of the wall. { // The seg is only part of the wall.
@ -115,10 +121,10 @@ namespace swrenderer
{ {
swapvalues(v1, v2); swapvalues(v1, v2);
} }
WallT.InitFromLine(v1->fPos() - ViewPos, v2->fPos() - ViewPos); WallT.InitFromLine(Thread, v1->fPos() - ViewPos, v2->fPos() - ViewPos);
} }
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
if (!(clip3d->fake3D & FAKE3D_FAKEBACK)) if (!(clip3d->fake3D & FAKE3D_FAKEBACK))
{ {
@ -142,7 +148,7 @@ namespace swrenderer
// kg3D - its fake, no transfer_heights // kg3D - its fake, no transfer_heights
if (!(clip3d->fake3D & FAKE3D_FAKEBACK)) if (!(clip3d->fake3D & FAKE3D_FAKEBACK))
{ // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water { // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
backsector = RenderOpaquePass::Instance()->FakeFlat(backsector, &tempsec, nullptr, nullptr, curline, WallC.sx1, WallC.sx2, rw_frontcz1, rw_frontcz2); backsector = Thread->OpaquePass->FakeFlat(backsector, &tempsec, nullptr, nullptr, curline, WallC.sx1, WallC.sx2, rw_frontcz1, rw_frontcz2);
} }
doorclosed = false; // killough 4/16/98 doorclosed = false; // killough 4/16/98
@ -255,7 +261,7 @@ namespace swrenderer
// mark their subsectors as visible for automap texturing. // mark their subsectors as visible for automap texturing.
if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN)) if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN))
{ {
if (RenderClipSegment::Instance()->Check(WallC.sx1, WallC.sx2)) if (Thread->ClipSegments->Check(WallC.sx1, WallC.sx2))
{ {
InSubsector->flags |= SSECF_DRAWN; InSubsector->flags |= SSECF_DRAWN;
} }
@ -279,7 +285,7 @@ namespace swrenderer
} }
static SWRenderLine *self = this; static SWRenderLine *self = this;
bool visible = RenderClipSegment::Instance()->Clip(WallC.sx1, WallC.sx2, solid, [](int x1, int x2) -> bool bool visible = Thread->ClipSegments->Clip(WallC.sx1, WallC.sx2, solid, [](int x1, int x2) -> bool
{ {
return self->RenderWallSegment(x1, x2); return self->RenderWallSegment(x1, x2);
}); });
@ -327,10 +333,10 @@ namespace swrenderer
rw_offset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); rw_offset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1); rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1);
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
DrawSegment *draw_segment = RenderMemory::NewObject<DrawSegment>(); DrawSegment *draw_segment = RenderMemory::NewObject<DrawSegment>();
DrawSegmentList::Instance()->Push(draw_segment); Thread->DrawSegments->Push(draw_segment);
draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq; draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq;
draw_segment->sx1 = WallC.sx1; draw_segment->sx1 = WallC.sx1;
@ -351,7 +357,7 @@ namespace swrenderer
draw_segment->bFakeBoundary = false; draw_segment->bFakeBoundary = false;
draw_segment->foggy = foggy; draw_segment->foggy = foggy;
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
if (clip3d->fake3D & FAKE3D_FAKEMASK) draw_segment->fake = 1; if (clip3d->fake3D & FAKE3D_FAKEMASK) draw_segment->fake = 1;
else draw_segment->fake = 0; else draw_segment->fake = 0;
@ -448,7 +454,7 @@ namespace swrenderer
// kg3D - backup for mid and fake walls // kg3D - backup for mid and fake walls
draw_segment->bkup = RenderMemory::AllocMemory<short>(stop - start); draw_segment->bkup = RenderMemory::AllocMemory<short>(stop - start);
memcpy(draw_segment->bkup, &RenderOpaquePass::Instance()->ceilingclip[start], sizeof(short)*(stop - start)); memcpy(draw_segment->bkup, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start));
draw_segment->bFogBoundary = IsFogBoundary(frontsector, backsector); draw_segment->bFogBoundary = IsFogBoundary(frontsector, backsector);
if (sidedef->GetTexture(side_t::mid).isValid() || draw_segment->bFakeBoundary) if (sidedef->GetTexture(side_t::mid).isValid() || draw_segment->bFakeBoundary)
@ -517,7 +523,7 @@ namespace swrenderer
if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr) if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr)
{ {
DrawSegmentList::Instance()->PushInteresting(draw_segment); Thread->DrawSegments->PushInteresting(draw_segment);
} }
} }
} }
@ -527,7 +533,7 @@ namespace swrenderer
{ {
if (ceilingplane) if (ceilingplane)
{ // killough 4/11/98: add NULL ptr checks { // killough 4/11/98: add NULL ptr checks
ceilingplane = VisiblePlaneList::Instance()->GetRange(ceilingplane, start, stop); ceilingplane = Thread->PlaneList->GetRange(ceilingplane, start, stop);
} }
else else
{ {
@ -539,7 +545,7 @@ namespace swrenderer
{ {
if (floorplane) if (floorplane)
{ // killough 4/11/98: add NULL ptr checks { // killough 4/11/98: add NULL ptr checks
floorplane = VisiblePlaneList::Instance()->GetRange(floorplane, start, stop); floorplane = Thread->PlaneList->GetRange(floorplane, start, stop);
} }
else else
{ {
@ -558,13 +564,13 @@ namespace swrenderer
if (((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == nullptr) if (((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == nullptr)
{ {
draw_segment->sprtopclip = RenderMemory::AllocMemory<short>(stop - start); draw_segment->sprtopclip = RenderMemory::AllocMemory<short>(stop - start);
memcpy(draw_segment->sprtopclip, &RenderOpaquePass::Instance()->ceilingclip[start], sizeof(short)*(stop - start)); memcpy(draw_segment->sprtopclip, &Thread->OpaquePass->ceilingclip[start], sizeof(short)*(stop - start));
} }
if (((draw_segment->silhouette & SIL_BOTTOM) || maskedtexture) && draw_segment->sprbottomclip == nullptr) if (((draw_segment->silhouette & SIL_BOTTOM) || maskedtexture) && draw_segment->sprbottomclip == nullptr)
{ {
draw_segment->sprbottomclip = RenderMemory::AllocMemory<short>(stop - start); draw_segment->sprbottomclip = RenderMemory::AllocMemory<short>(stop - start);
memcpy(draw_segment->sprbottomclip, &RenderOpaquePass::Instance()->floorclip[start], sizeof(short)*(stop - start)); memcpy(draw_segment->sprbottomclip, &Thread->OpaquePass->floorclip[start], sizeof(short)*(stop - start));
} }
if (maskedtexture && curline->sidedef->GetTexture(side_t::mid).isValid()) if (maskedtexture && curline->sidedef->GetTexture(side_t::mid).isValid())
@ -576,12 +582,12 @@ namespace swrenderer
// [ZZ] Only if not an active mirror // [ZZ] Only if not an active mirror
if (!rw_markportal) if (!rw_markportal)
{ {
RenderDecal::RenderDecals(curline->sidedef, draw_segment, wallshade, rw_lightleft, rw_lightstep, curline, WallC, foggy, basecolormap, walltop.ScreenY, wallbottom.ScreenY); RenderDecal::RenderDecals(Thread, curline->sidedef, draw_segment, wallshade, rw_lightleft, rw_lightstep, curline, WallC, foggy, basecolormap, walltop.ScreenY, wallbottom.ScreenY);
} }
if (rw_markportal) if (rw_markportal)
{ {
RenderPortal::Instance()->AddLinePortal(curline->linedef, draw_segment->x1, draw_segment->x2, draw_segment->sprtopclip, draw_segment->sprbottomclip); Thread->Portal->AddLinePortal(curline->linedef, draw_segment->x1, draw_segment->x2, draw_segment->sprtopclip, draw_segment->sprbottomclip);
} }
return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0; return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0;
@ -598,7 +604,7 @@ namespace swrenderer
linedef = curline->linedef; linedef = curline->linedef;
// mark the segment as visible for auto map // mark the segment as visible for auto map
if (!RenderScene::Instance()->DontMapLines()) linedef->flags |= ML_MAPPED; if (!Thread->Scene->DontMapLines()) linedef->flags |= ML_MAPPED;
midtexture = toptexture = bottomtexture = 0; midtexture = toptexture = bottomtexture = 0;
@ -686,8 +692,7 @@ namespace swrenderer
// wall but nothing to draw for it. // wall but nothing to draw for it.
// Recalculate walltop so that the wall is clipped by the back sector's // Recalculate walltop so that the wall is clipped by the back sector's
// ceiling instead of the front sector's ceiling. // ceiling instead of the front sector's ceiling.
RenderPortal *renderportal = RenderPortal::Instance(); walltop.Project(backsector->ceilingplane, &WallC, curline, Thread->Portal->MirrorFlags & RF_XFLIP);
walltop.Project(backsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
} }
// Putting sky ceilings on the front and back of a line alters the way unpegged // Putting sky ceilings on the front and back of a line alters the way unpegged
// positioning works. // positioning works.
@ -941,8 +946,8 @@ namespace swrenderer
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0); drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
// clip wall to the floor and ceiling // clip wall to the floor and ceiling
auto ceilingclip = RenderOpaquePass::Instance()->ceilingclip; auto ceilingclip = Thread->OpaquePass->ceilingclip;
auto floorclip = RenderOpaquePass::Instance()->floorclip; auto floorclip = Thread->OpaquePass->floorclip;
for (x = x1; x < x2; ++x) for (x = x1; x < x2; ++x)
{ {
if (walltop.ScreenY[x] < ceilingclip[x]) if (walltop.ScreenY[x] < ceilingclip[x])
@ -955,7 +960,7 @@ namespace swrenderer
} }
} }
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
// mark ceiling areas // mark ceiling areas
if (markceiling) if (markceiling)
@ -1046,7 +1051,7 @@ namespace swrenderer
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
RenderWallPart renderWallpart; RenderWallPart renderWallpart(Thread);
renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, rw_midtexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, rw_midtexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
} }
fillshort(ceilingclip + x1, x2 - x1, viewheight); fillshort(ceilingclip + x1, x2 - x1, viewheight);
@ -1083,7 +1088,7 @@ namespace swrenderer
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
RenderWallPart renderWallpart; RenderWallPart renderWallpart(Thread);
renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, rw_toptexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, rw_toptexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
} }
memcpy(ceilingclip + x1, wallupper.ScreenY + x1, (x2 - x1) * sizeof(short)); memcpy(ceilingclip + x1, wallupper.ScreenY + x1, (x2 - x1) * sizeof(short));
@ -1123,7 +1128,7 @@ namespace swrenderer
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
RenderWallPart renderWallpart; RenderWallPart renderWallpart(Thread);
renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, rw_bottomtexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, rw_bottomtexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
} }
memcpy(floorclip + x1, walllower.ScreenY + x1, (x2 - x1) * sizeof(short)); memcpy(floorclip + x1, walllower.ScreenY + x1, (x2 - x1) * sizeof(short));
@ -1139,7 +1144,7 @@ namespace swrenderer
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Transform and clip coordinates. Returns true if it was clipped away // Transform and clip coordinates. Returns true if it was clipped away
bool FWallCoords::Init(const DVector2 &pt1, const DVector2 &pt2, double too_close) bool FWallCoords::Init(RenderThread *thread, const DVector2 &pt1, const DVector2 &pt2, double too_close)
{ {
tleft.X = float(pt1.X * ViewSin - pt1.Y * ViewCos); tleft.X = float(pt1.X * ViewSin - pt1.Y * ViewCos);
tright.X = float(pt2.X * ViewSin - pt2.Y * ViewCos); tright.X = float(pt2.X * ViewSin - pt2.Y * ViewCos);
@ -1147,7 +1152,7 @@ namespace swrenderer
tleft.Y = float(pt1.X * ViewTanCos + pt1.Y * ViewTanSin); tleft.Y = float(pt1.X * ViewTanCos + pt1.Y * ViewTanSin);
tright.Y = float(pt2.X * ViewTanCos + pt2.Y * ViewTanSin); tright.Y = float(pt2.X * ViewTanCos + pt2.Y * ViewTanSin);
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = thread->Portal.get();
auto viewport = RenderViewport::Instance(); auto viewport = RenderViewport::Instance();
if (renderportal->MirrorFlags & RF_XFLIP) if (renderportal->MirrorFlags & RF_XFLIP)
@ -1201,12 +1206,12 @@ namespace swrenderer
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc) void FWallTmapVals::InitFromWallCoords(RenderThread *thread, const FWallCoords *wallc)
{ {
const FVector2 *left = &wallc->tleft; const FVector2 *left = &wallc->tleft;
const FVector2 *right = &wallc->tright; const FVector2 *right = &wallc->tright;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP) if (renderportal->MirrorFlags & RF_XFLIP)
{ {
@ -1218,7 +1223,7 @@ namespace swrenderer
InvZstep = right->Y - left->Y; InvZstep = right->Y - left->Y;
} }
void FWallTmapVals::InitFromLine(const DVector2 &left, const DVector2 &right) void FWallTmapVals::InitFromLine(RenderThread *thread, const DVector2 &left, const DVector2 &right)
{ {
// Coordinates should have already had viewx,viewy subtracted // Coordinates should have already had viewx,viewy subtracted
@ -1227,7 +1232,7 @@ namespace swrenderer
double fully1 = left.X * ViewTanCos + left.Y * ViewTanSin; double fully1 = left.X * ViewTanCos + left.Y * ViewTanSin;
double fully2 = right.X * ViewTanCos + right.Y * ViewTanSin; double fully2 = right.X * ViewTanCos + right.Y * ViewTanSin;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP) if (renderportal->MirrorFlags & RF_XFLIP)
{ {

View file

@ -25,6 +25,7 @@ struct FDynamicColormap;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
struct VisiblePlane; struct VisiblePlane;
struct FWallCoords struct FWallCoords
@ -35,7 +36,7 @@ namespace swrenderer
float sz1, sz2; // depth at left, right of wall in screen space yb1,yb2 float sz1, sz2; // depth at left, right of wall in screen space yb1,yb2
short sx1, sx2; // x coords at left, right of wall in screen space xb1,xb2 short sx1, sx2; // x coords at left, right of wall in screen space xb1,xb2
bool Init(const DVector2 &pt1, const DVector2 &pt2, double too_close); bool Init(RenderThread *thread, const DVector2 &pt1, const DVector2 &pt2, double too_close);
}; };
struct FWallTmapVals struct FWallTmapVals
@ -43,15 +44,18 @@ namespace swrenderer
float UoverZorg, UoverZstep; float UoverZorg, UoverZstep;
float InvZorg, InvZstep; float InvZorg, InvZstep;
void InitFromWallCoords(const FWallCoords *wallc); void InitFromWallCoords(RenderThread *thread, const FWallCoords *wallc);
void InitFromLine(const DVector2 &left, const DVector2 &right); void InitFromLine(RenderThread *thread, const DVector2 &left, const DVector2 &right);
}; };
class SWRenderLine class SWRenderLine
{ {
public: public:
SWRenderLine(RenderThread *thread);
void Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap); void Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap);
RenderThread *Thread = nullptr;
private: private:
bool RenderWallSegment(int x1, int x2); bool RenderWallSegment(int x1, int x2);
void SetWallVariables(bool needlights); void SetWallVariables(bool needlights);

View file

@ -29,6 +29,7 @@
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "d_net.h" #include "d_net.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include "swrenderer/drawers/r_draw.h" #include "swrenderer/drawers/r_draw.h"
#include "swrenderer/scene/r_3dfloors.h" #include "swrenderer/scene/r_3dfloors.h"
#include "swrenderer/scene/r_opaque_pass.h" #include "swrenderer/scene/r_opaque_pass.h"
@ -47,6 +48,11 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer namespace swrenderer
{ {
RenderDrawSegment::RenderDrawSegment(RenderThread *thread)
{
Thread = thread;
}
void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2) void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2)
{ {
auto viewport = RenderViewport::Instance(); auto viewport = RenderViewport::Instance();
@ -95,7 +101,7 @@ namespace swrenderer
} }
// killough 4/13/98: get correct lightlevel for 2s normal textures // killough 4/13/98: get correct lightlevel for 2s normal textures
sec = RenderOpaquePass::Instance()->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0); sec = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0);
FDynamicColormap *basecolormap = sec->ColorMap; // [RH] Set basecolormap FDynamicColormap *basecolormap = sec->ColorMap; // [RH] Set basecolormap
@ -103,7 +109,7 @@ namespace swrenderer
rw_lightstep = ds->lightstep; rw_lightstep = ds->lightstep;
rw_light = ds->light + (x1 - ds->x1) * rw_lightstep; rw_light = ds->light + (x1 - ds->x1) * rw_lightstep;
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
CameraLight *cameraLight = CameraLight::Instance(); CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->FixedLightLevel() < 0) if (cameraLight->FixedLightLevel() < 0)
@ -361,7 +367,7 @@ namespace swrenderer
double top, bot; double top, bot;
GetMaskedWallTopBottom(ds, top, bot); GetMaskedWallTopBottom(ds, top, bot);
RenderWallPart renderWallpart; RenderWallPart renderWallpart(Thread);
renderWallpart.Render(walldrawerargs, frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); renderWallpart.Render(walldrawerargs, frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
} }
@ -471,7 +477,7 @@ namespace swrenderer
WallC.tright.Y = ds->cy + ds->cdy; WallC.tright.Y = ds->cy + ds->cdy;
WallT = ds->tmapvals; WallT = ds->tmapvals;
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
wallupper.Project(clip3d->sclipTop - ViewPos.Z, &WallC); wallupper.Project(clip3d->sclipTop - ViewPos.Z, &WallC);
walllower.Project(clip3d->sclipBottom - ViewPos.Z, &WallC); walllower.Project(clip3d->sclipBottom - ViewPos.Z, &WallC);
@ -492,7 +498,7 @@ namespace swrenderer
double top, bot; double top, bot;
GetMaskedWallTopBottom(ds, top, bot); GetMaskedWallTopBottom(ds, top, bot);
RenderWallPart renderWallpart; RenderWallPart renderWallpart(Thread);
renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
} }
@ -525,7 +531,7 @@ namespace swrenderer
floorHeight = backsector->CenterFloor(); floorHeight = backsector->CenterFloor();
ceilingHeight = backsector->CenterCeiling(); ceilingHeight = backsector->CenterCeiling();
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
// maybe fix clipheights // maybe fix clipheights
if (!(clip3d->fake3D & FAKE3D_CLIPBOTTOM)) clip3d->sclipBottom = floorHeight; if (!(clip3d->fake3D & FAKE3D_CLIPBOTTOM)) clip3d->sclipBottom = floorHeight;
@ -906,7 +912,7 @@ namespace swrenderer
{ {
ProjectedWallLine most; ProjectedWallLine most;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
most.Project(curline->frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP); most.Project(curline->frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
for (int i = x1; i < x2; ++i) for (int i = x1; i < x2; ++i)
@ -931,7 +937,7 @@ namespace swrenderer
top = MAX(frontcz1, frontcz2); top = MAX(frontcz1, frontcz2);
bot = MIN(frontfz1, frontfz2); bot = MIN(frontfz1, frontfz2);
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
if (clip3d->fake3D & FAKE3D_CLIPTOP) if (clip3d->fake3D & FAKE3D_CLIPTOP)
{ {
top = MIN(top, clip3d->sclipTop); top = MIN(top, clip3d->sclipTop);

View file

@ -17,11 +17,16 @@
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
class RenderDrawSegment class RenderDrawSegment
{ {
public: public:
RenderDrawSegment(RenderThread *thread);
void Render(DrawSegment *ds, int x1, int x2); void Render(DrawSegment *ds, int x1, int x2);
RenderThread *Thread = nullptr;
private: private:
void ClipMidtex(int x1, int x2); void ClipMidtex(int x1, int x2);
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap); void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap);

View file

@ -40,6 +40,7 @@
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#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"
namespace swrenderer namespace swrenderer
{ {
@ -376,7 +377,7 @@ namespace swrenderer
assert(WallC.sx1 <= x1); assert(WallC.sx1 <= x1);
assert(WallC.sx2 >= x2); assert(WallC.sx2 >= x2);
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
// kg3D - fake floors instead of zdoom light list // kg3D - fake floors instead of zdoom light list
for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++) for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++)
@ -520,4 +521,9 @@ namespace swrenderer
ProcessWall(walltop, wallbottom, texturemid, swall, lwall); ProcessWall(walltop, wallbottom, texturemid, swall, lwall);
} }
} }
RenderWallPart::RenderWallPart(RenderThread *thread)
{
Thread = thread;
}
} }

View file

@ -24,6 +24,7 @@ struct FDynamicColormap;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
struct DrawSegment; struct DrawSegment;
struct FWallCoords; struct FWallCoords;
class ProjectedWallLine; class ProjectedWallLine;
@ -33,6 +34,8 @@ namespace swrenderer
class RenderWallPart class RenderWallPart
{ {
public: public:
RenderWallPart(RenderThread *thread);
void Render( void Render(
const WallDrawerArgs &drawerargs, const WallDrawerArgs &drawerargs,
sector_t *frontsector, sector_t *frontsector,
@ -58,6 +61,8 @@ namespace swrenderer
bool foggy, bool foggy,
FDynamicColormap *basecolormap); FDynamicColormap *basecolormap);
RenderThread *Thread = nullptr;
private: private:
void ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, double top, double bot); void ProcessWallNP2(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal, double top, double bot);
void ProcessWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal); void ProcessWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal);

View file

@ -41,9 +41,15 @@
#include "swrenderer/plane/r_visibleplane.h" #include "swrenderer/plane/r_visibleplane.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
namespace swrenderer namespace swrenderer
{ {
RenderFlatPlane::RenderFlatPlane(RenderThread *thread)
{
Thread = thread;
}
void RenderFlatPlane::Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *colormap, FTexture *texture) void RenderFlatPlane::Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *colormap, FTexture *texture)
{ {
if (alpha <= 0) if (alpha <= 0)
@ -85,7 +91,7 @@ namespace swrenderer
ystep = -sin(planeang) / viewport->FocalLengthX; ystep = -sin(planeang) / viewport->FocalLengthX;
// [RH] flip for mirrors // [RH] flip for mirrors
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP) if (renderportal->MirrorFlags & RF_XFLIP)
{ {
xstep = -xstep; xstep = -xstep;

View file

@ -18,15 +18,19 @@
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
struct VisiblePlaneLight; struct VisiblePlaneLight;
class RenderFlatPlane : PlaneRenderer class RenderFlatPlane : PlaneRenderer
{ {
public: public:
RenderFlatPlane(RenderThread *thread);
void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FTexture *texture); void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FTexture *texture);
static void SetupSlope(); static void SetupSlope();
RenderThread *Thread = nullptr;
private: private:
void RenderLine(int y, int x1, int x2) override; void RenderLine(int y, int x1, int x2) override;
void StepColumn() override; void StepColumn() override;

View file

@ -42,6 +42,7 @@
#include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include "g_levellocals.h" #include "g_levellocals.h"
CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
@ -49,6 +50,11 @@ EXTERN_CVAR(Int, r_skymode)
namespace swrenderer namespace swrenderer
{ {
RenderSkyPlane::RenderSkyPlane(RenderThread *thread)
{
Thread = thread;
}
void RenderSkyPlane::Render(VisiblePlane *pl) void RenderSkyPlane::Render(VisiblePlane *pl)
{ {
FTextureID sky1tex, sky2tex; FTextureID sky1tex, sky2tex;
@ -162,7 +168,7 @@ namespace swrenderer
void RenderSkyPlane::DrawSkyColumnStripe(int start_x, int y1, int y2, double scale, double texturemid, double yrepeat) void RenderSkyPlane::DrawSkyColumnStripe(int start_x, int y1, int y2, double scale, double texturemid, double yrepeat)
{ {
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
auto viewport = RenderViewport::Instance(); auto viewport = RenderViewport::Instance();
uint32_t height = frontskytex->GetHeight(); uint32_t height = frontskytex->GetHeight();

View file

@ -21,8 +21,12 @@ namespace swrenderer
class RenderSkyPlane class RenderSkyPlane
{ {
public: public:
RenderSkyPlane(RenderThread *thread);
void Render(VisiblePlane *pl); void Render(VisiblePlane *pl);
RenderThread *Thread = nullptr;
private: private:
void DrawSky(VisiblePlane *pl); void DrawSky(VisiblePlane *pl);
void DrawSkyColumnStripe(int start_x, int y1, int y2, double scale, double texturemid, double yrepeat); void DrawSkyColumnStripe(int start_x, int y1, int y2, double scale, double texturemid, double yrepeat);

View file

@ -39,8 +39,9 @@
#include "swrenderer/scene/r_scene.h" #include "swrenderer/scene/r_scene.h"
#include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/plane/r_visibleplane.h" #include "swrenderer/plane/r_visibleplane.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable:4244) #pragma warning(disable:4244)
@ -48,6 +49,11 @@
namespace swrenderer namespace swrenderer
{ {
RenderSlopePlane::RenderSlopePlane(RenderThread *thread)
{
Thread = thread;
}
void RenderSlopePlane::Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *colormap, FTexture *texture) void RenderSlopePlane::Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *colormap, FTexture *texture)
{ {
static const float ifloatpow2[16] = static const float ifloatpow2[16] =
@ -138,7 +144,7 @@ namespace swrenderer
plane_su *= 4294967296.f; plane_su *= 4294967296.f;
plane_sv *= 4294967296.f; plane_sv *= 4294967296.f;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP) if (renderportal->MirrorFlags & RF_XFLIP)
{ {
plane_su[0] = -plane_su[0]; plane_su[0] = -plane_su[0];

View file

@ -18,11 +18,16 @@
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
class RenderSlopePlane : PlaneRenderer class RenderSlopePlane : PlaneRenderer
{ {
public: public:
RenderSlopePlane(RenderThread *thread);
void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FTexture *texture); void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FTexture *texture);
RenderThread *Thread = nullptr;
private: private:
void RenderLine(int y, int x1, int x2) override; void RenderLine(int y, int x1, int x2) override;

View file

@ -87,14 +87,14 @@ namespace swrenderer
} }
} }
void VisiblePlane::Render(fixed_t alpha, bool additive, bool masked) void VisiblePlane::Render(RenderThread *thread, fixed_t alpha, bool additive, bool masked)
{ {
if (left >= right) if (left >= right)
return; return;
if (picnum == skyflatnum) // sky flat if (picnum == skyflatnum) // sky flat
{ {
RenderSkyPlane renderer; RenderSkyPlane renderer(thread);
renderer.Render(this); renderer.Render(this);
} }
else // regular flat else // regular flat
@ -119,12 +119,12 @@ namespace swrenderer
if (!height.isSlope() && !tilt) if (!height.isSlope() && !tilt)
{ {
RenderFlatPlane renderer; RenderFlatPlane renderer(thread);
renderer.Render(this, xscale, yscale, alpha, additive, masked, colormap, tex); renderer.Render(this, xscale, yscale, alpha, additive, masked, colormap, tex);
} }
else else
{ {
RenderSlopePlane renderer; RenderSlopePlane renderer(thread);
renderer.Render(this, xscale, yscale, alpha, additive, masked, colormap, tex); renderer.Render(this, xscale, yscale, alpha, additive, masked, colormap, tex);
} }
} }

View file

@ -25,6 +25,8 @@ struct FSectorPortal;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
struct VisiblePlaneLight struct VisiblePlaneLight
{ {
ADynamicLight *lightsource; ADynamicLight *lightsource;
@ -36,7 +38,7 @@ namespace swrenderer
VisiblePlane(); VisiblePlane();
void AddLights(FLightNode *node); void AddLights(FLightNode *node);
void Render(fixed_t alpha, bool additive, bool masked); void Render(RenderThread *thread, fixed_t alpha, bool additive, bool masked);
VisiblePlane *next = nullptr; // Next visplane in hash chain -- killough VisiblePlane *next = nullptr; // Next visplane in hash chain -- killough

View file

@ -41,13 +41,13 @@
#include "swrenderer/plane/r_visibleplanelist.h" #include "swrenderer/plane/r_visibleplanelist.h"
#include "swrenderer/drawers/r_draw.h" #include "swrenderer/drawers/r_draw.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_renderthread.h"
namespace swrenderer namespace swrenderer
{ {
VisiblePlaneList *VisiblePlaneList::Instance() VisiblePlaneList::VisiblePlaneList(RenderThread *thread)
{ {
static VisiblePlaneList instance; Thread = thread;
return &instance;
} }
VisiblePlaneList::VisiblePlaneList() VisiblePlaneList::VisiblePlaneList()
@ -129,7 +129,7 @@ namespace swrenderer
// kg3D - hack, store alpha in sky // kg3D - hack, store alpha in sky
// i know there is ->alpha, but this also allows to identify fake plane // i know there is ->alpha, but this also allows to identify fake plane
// and ->alpha is for stacked sectors // and ->alpha is for stacked sectors
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
if (clip3d->fake3D & (FAKE3D_FAKEFLOOR | FAKE3D_FAKECEILING)) sky = 0x80000000 | clip3d->fakeAlpha; if (clip3d->fake3D & (FAKE3D_FAKEFLOOR | FAKE3D_FAKECEILING)) sky = 0x80000000 | clip3d->fakeAlpha;
else sky = 0; // not skyflatnum so it can't be a sky else sky = 0; // not skyflatnum so it can't be a sky
portal = nullptr; portal = nullptr;
@ -139,7 +139,7 @@ namespace swrenderer
// New visplane algorithm uses hash table -- killough // New visplane algorithm uses hash table -- killough
hash = isskybox ? ((unsigned)MAXVISPLANES) : CalcHash(picnum.GetIndex(), lightlevel, height); hash = isskybox ? ((unsigned)MAXVISPLANES) : CalcHash(picnum.GetIndex(), lightlevel, height);
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
for (check = visplanes[hash]; check; check = check->next) // killough for (check = visplanes[hash]; check; check = check->next) // killough
{ {
@ -190,7 +190,7 @@ namespace swrenderer
sky == check->sky && sky == check->sky &&
renderportal->CurrentPortalUniq == check->CurrentPortalUniq && renderportal->CurrentPortalUniq == check->CurrentPortalUniq &&
renderportal->MirrorFlags == check->MirrorFlags && renderportal->MirrorFlags == check->MirrorFlags &&
Clip3DFloors::Instance()->CurrentSkybox == check->CurrentSkybox && Thread->Clip3DFloors->CurrentSkybox == check->CurrentSkybox &&
ViewPos == check->viewpos ViewPos == check->viewpos
) )
{ {
@ -215,7 +215,7 @@ namespace swrenderer
check->Additive = additive; check->Additive = additive;
check->CurrentPortalUniq = renderportal->CurrentPortalUniq; check->CurrentPortalUniq = renderportal->CurrentPortalUniq;
check->MirrorFlags = renderportal->MirrorFlags; check->MirrorFlags = renderportal->MirrorFlags;
check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox; check->CurrentSkybox = Thread->Clip3DFloors->CurrentSkybox;
return check; return check;
} }
@ -326,19 +326,19 @@ namespace swrenderer
int i; int i;
int vpcount = 0; int vpcount = 0;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
for (i = 0; i < MAXVISPLANES; i++) for (i = 0; i < MAXVISPLANES; i++)
{ {
for (pl = visplanes[i]; pl; pl = pl->next) for (pl = visplanes[i]; pl; pl = pl->next)
{ {
// kg3D - draw only correct planes // kg3D - draw only correct planes
if (pl->CurrentPortalUniq != renderportal->CurrentPortalUniq || pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox) if (pl->CurrentPortalUniq != renderportal->CurrentPortalUniq || pl->CurrentSkybox != Thread->Clip3DFloors->CurrentSkybox)
continue; continue;
// kg3D - draw only real planes now // kg3D - draw only real planes now
if (pl->sky >= 0) { if (pl->sky >= 0) {
vpcount++; vpcount++;
pl->Render(OPAQUE, false, false); pl->Render(Thread, OPAQUE, false, false);
} }
} }
} }
@ -353,13 +353,13 @@ namespace swrenderer
DVector3 oViewPos = ViewPos; DVector3 oViewPos = ViewPos;
DAngle oViewAngle = ViewAngle; DAngle oViewAngle = ViewAngle;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
for (i = 0; i < MAXVISPLANES; i++) for (i = 0; i < MAXVISPLANES; i++)
{ {
for (pl = visplanes[i]; pl; pl = pl->next) for (pl = visplanes[i]; pl; pl = pl->next)
{ {
if (pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox || pl->CurrentPortalUniq != renderportal->CurrentPortalUniq) if (pl->CurrentSkybox != Thread->Clip3DFloors->CurrentSkybox || pl->CurrentPortalUniq != renderportal->CurrentPortalUniq)
continue; continue;
if (pl->sky < 0 && pl->height.Zat0() == height) if (pl->sky < 0 && pl->height.Zat0() == height)
@ -368,7 +368,7 @@ namespace swrenderer
ViewAngle = pl->viewangle; ViewAngle = pl->viewangle;
renderportal->MirrorFlags = pl->MirrorFlags; renderportal->MirrorFlags = pl->MirrorFlags;
pl->Render(pl->sky & 0x7FFFFFFF, pl->Additive, true); pl->Render(Thread, pl->sky & 0x7FFFFFFF, pl->Additive, true);
} }
} }
} }

View file

@ -20,12 +20,13 @@ struct FSectorPortal;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
struct VisiblePlane; struct VisiblePlane;
class VisiblePlaneList class VisiblePlaneList
{ {
public: public:
static VisiblePlaneList *Instance(); VisiblePlaneList(RenderThread *thread);
void Clear(); void Clear();
void ClearKeepFakePlanes(); void ClearKeepFakePlanes();
@ -40,6 +41,8 @@ namespace swrenderer
int Render(); int Render();
void RenderHeight(double height); void RenderHeight(double height);
RenderThread *Thread = nullptr;
private: private:
VisiblePlaneList(); VisiblePlaneList();
VisiblePlane *Add(unsigned hash); VisiblePlane *Add(unsigned hash);

View file

@ -0,0 +1,70 @@
/*
** Renderer multithreading framework
** Copyright (c) 2016 Magnus Norddahl
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#include <stdlib.h>
#include "templates.h"
#include "doomdef.h"
#include "m_bbox.h"
#include "i_system.h"
#include "p_lnspec.h"
#include "p_setup.h"
#include "a_sharedglobal.h"
#include "g_level.h"
#include "p_effect.h"
#include "doomstat.h"
#include "r_state.h"
#include "v_palette.h"
#include "r_sky.h"
#include "po_man.h"
#include "r_data/colormaps.h"
#include "r_renderthread.h"
#include "swrenderer/things/r_visiblespritelist.h"
#include "swrenderer/scene/r_portal.h"
#include "swrenderer/scene/r_opaque_pass.h"
#include "swrenderer/scene/r_translucent_pass.h"
#include "swrenderer/scene/r_3dfloors.h"
#include "swrenderer/scene/r_scene.h"
#include "swrenderer/things/r_playersprite.h"
#include "swrenderer/plane/r_visibleplanelist.h"
#include "swrenderer/segments/r_drawsegment.h"
#include "swrenderer/segments/r_clipsegment.h"
namespace swrenderer
{
RenderThread::RenderThread()
{
OpaquePass = std::make_unique<RenderOpaquePass>(this);
TranslucentPass = std::make_unique<RenderTranslucentPass>(this);
SpriteList = std::make_unique<VisibleSpriteList>();
Portal = std::make_unique<RenderPortal>(this);
Clip3DFloors = std::make_unique<swrenderer::Clip3DFloors>(this);
PlayerSprites = std::make_unique<RenderPlayerSprites>(this);
PlaneList = std::make_unique<VisiblePlaneList>(this);
Scene = std::make_unique<RenderScene>(this);
DrawSegments = std::make_unique<DrawSegmentList>(this);
ClipSegments = std::make_unique<RenderClipSegment>();
}
RenderThread::~RenderThread()
{
}
}

View file

@ -0,0 +1,57 @@
/*
** Renderer multithreading framework
** Copyright (c) 2016 Magnus Norddahl
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#pragma once
#include <memory>
namespace swrenderer
{
class VisibleSpriteList;
class RenderPortal;
class RenderOpaquePass;
class RenderTranslucentPass;
class RenderPlayerSprites;
class RenderScene;
class Clip3DFloors;
class VisiblePlaneList;
class DrawSegmentList;
class RenderClipSegment;
class RenderThread
{
public:
RenderThread();
~RenderThread();
std::unique_ptr<RenderOpaquePass> OpaquePass;
std::unique_ptr<RenderTranslucentPass> TranslucentPass;
std::unique_ptr<VisibleSpriteList> SpriteList;
std::unique_ptr<RenderPortal> Portal;
std::unique_ptr<Clip3DFloors> Clip3DFloors;
std::unique_ptr<RenderPlayerSprites> PlayerSprites;
std::unique_ptr<VisiblePlaneList> PlaneList;
std::unique_ptr<RenderScene> Scene;
std::unique_ptr<DrawSegmentList> DrawSegments;
std::unique_ptr<RenderClipSegment> ClipSegments;
};
}

View file

@ -88,7 +88,7 @@ void FSoftwareRenderer::Init()
{ {
gl_ParseDefs(); gl_ParseDefs();
RenderScene::Instance()->Init(); mMainThread.Scene->Init();
} }
bool FSoftwareRenderer::UsesColormap() const bool FSoftwareRenderer::UsesColormap() const
@ -178,7 +178,7 @@ void FSoftwareRenderer::RenderView(player_t *player)
if (r_polyrenderer) if (r_polyrenderer)
PolyRenderer::Instance()->RenderView(player); PolyRenderer::Instance()->RenderView(player);
else else
RenderScene::Instance()->RenderView(player); mMainThread.Scene->RenderView(player);
FCanvasTextureInfo::UpdateAll(); FCanvasTextureInfo::UpdateAll();
} }
@ -202,7 +202,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi
if (r_polyrenderer) if (r_polyrenderer)
PolyRenderer::Instance()->RenderViewToCanvas(player->mo, pic, 0, 0, width, height, true); PolyRenderer::Instance()->RenderViewToCanvas(player->mo, pic, 0, 0, width, height, true);
else else
RenderScene::Instance()->RenderViewToCanvas (player->mo, pic, 0, 0, width, height); mMainThread.Scene->RenderViewToCanvas (player->mo, pic, 0, 0, width, height);
screen->GetFlashedPalette (palette); screen->GetFlashedPalette (palette);
M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch()); M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch());
pic->Unlock (); pic->Unlock ();
@ -215,7 +215,7 @@ void FSoftwareRenderer::DrawRemainingPlayerSprites()
{ {
if (!r_polyrenderer) if (!r_polyrenderer)
{ {
RenderPlayerSprites::Instance()->RenderRemaining(); mMainThread.PlayerSprites->RenderRemaining();
} }
else else
{ {
@ -237,12 +237,12 @@ bool FSoftwareRenderer::RequireGLNodes()
void FSoftwareRenderer::OnModeSet () void FSoftwareRenderer::OnModeSet ()
{ {
RenderScene::Instance()->ScreenResized(); mMainThread.Scene->ScreenResized();
} }
void FSoftwareRenderer::SetClearColor(int color) void FSoftwareRenderer::SetClearColor(int color)
{ {
RenderScene::Instance()->SetClearColor(color); mMainThread.Scene->SetClearColor(color);
} }
void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov)
@ -262,7 +262,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
if (r_polyrenderer) if (r_polyrenderer)
PolyRenderer::Instance()->RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); PolyRenderer::Instance()->RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate);
else else
RenderScene::Instance()->RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); mMainThread.Scene->RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate);
R_SetFOV (savedfov); R_SetFOV (savedfov);
@ -319,7 +319,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
sector_t *FSoftwareRenderer::FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel) sector_t *FSoftwareRenderer::FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel)
{ {
return RenderOpaquePass::Instance()->FakeFlat(sec, tempsec, floorlightlevel, ceilinglightlevel, nullptr, 0, 0, 0, 0); return mMainThread.OpaquePass->FakeFlat(sec, tempsec, floorlightlevel, ceilinglightlevel, nullptr, 0, 0, 0, 0);
} }
void FSoftwareRenderer::StateChanged(AActor *actor) void FSoftwareRenderer::StateChanged(AActor *actor)

View file

@ -2,6 +2,7 @@
#pragma once #pragma once
#include "r_renderer.h" #include "r_renderer.h"
#include "r_renderthread.h"
struct FSoftwareRenderer : public FRenderer struct FSoftwareRenderer : public FRenderer
{ {
@ -41,4 +42,6 @@ struct FSoftwareRenderer : public FRenderer
private: private:
void PrecacheTexture(FTexture *tex, int cache); void PrecacheTexture(FTexture *tex, int cache);
swrenderer::RenderThread mMainThread;
}; };

View file

@ -13,15 +13,15 @@
#include "c_cvars.h" #include "c_cvars.h"
#include "r_3dfloors.h" #include "r_3dfloors.h"
#include "r_utility.h" #include "r_utility.h"
#include "swrenderer/r_renderthread.h"
CVAR(Int, r_3dfloors, true, 0); CVAR(Int, r_3dfloors, true, 0);
namespace swrenderer namespace swrenderer
{ {
Clip3DFloors *Clip3DFloors::Instance() Clip3DFloors::Clip3DFloors(RenderThread *thread)
{ {
static Clip3DFloors clip; Thread = thread;
return &clip;
} }
void Clip3DFloors::Cleanup() void Clip3DFloors::Cleanup()
@ -102,8 +102,8 @@ namespace swrenderer
curr = (ClipStack*)M_Malloc(sizeof(ClipStack)); curr = (ClipStack*)M_Malloc(sizeof(ClipStack));
curr->next = 0; curr->next = 0;
memcpy(curr->floorclip, RenderOpaquePass::Instance()->floorclip, sizeof(short) * MAXWIDTH); memcpy(curr->floorclip, Thread->OpaquePass->floorclip, sizeof(short) * MAXWIDTH);
memcpy(curr->ceilingclip, RenderOpaquePass::Instance()->ceilingclip, sizeof(short) * MAXWIDTH); memcpy(curr->ceilingclip, Thread->OpaquePass->ceilingclip, sizeof(short) * MAXWIDTH);
curr->ffloor = fakeFloor; curr->ffloor = fakeFloor;
assert(fakeFloor->floorclip == nullptr); assert(fakeFloor->floorclip == nullptr);
assert(fakeFloor->ceilingclip == nullptr); assert(fakeFloor->ceilingclip == nullptr);

View file

@ -7,6 +7,8 @@ EXTERN_CVAR(Int, r_3dfloors);
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
struct HeightLevel struct HeightLevel
{ {
double height; double height;
@ -52,7 +54,7 @@ namespace swrenderer
class Clip3DFloors class Clip3DFloors
{ {
public: public:
static Clip3DFloors *Instance(); Clip3DFloors(RenderThread *thread);
void Cleanup(); void Cleanup();
@ -63,6 +65,8 @@ namespace swrenderer
void EnterSkybox(); void EnterSkybox();
void LeaveSkybox(); void LeaveSkybox();
RenderThread *Thread = nullptr;
int fake3D = 0; int fake3D = 0;
F3DFloor *fakeFloor = nullptr; F3DFloor *fakeFloor = nullptr;

View file

@ -44,6 +44,7 @@
#include "swrenderer/scene/r_scene.h" #include "swrenderer/scene/r_scene.h"
#include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_renderthread.h"
#include "r_3dfloors.h" #include "r_3dfloors.h"
#include "r_portal.h" #include "r_portal.h"
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
@ -67,10 +68,9 @@ EXTERN_CVAR(Bool, r_drawvoxels);
namespace swrenderer namespace swrenderer
{ {
RenderOpaquePass *RenderOpaquePass::Instance() RenderOpaquePass::RenderOpaquePass(RenderThread *thread) : renderline(thread)
{ {
static RenderOpaquePass instance; Thread = thread;
return &instance;
} }
sector_t *RenderOpaquePass::FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2) sector_t *RenderOpaquePass::FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2)
@ -341,7 +341,7 @@ namespace swrenderer
ry1 = x1 * ViewTanCos + y1 * ViewTanSin; ry1 = x1 * ViewTanCos + y1 * ViewTanSin;
ry2 = x2 * ViewTanCos + y2 * ViewTanSin; ry2 = x2 * ViewTanCos + y2 * ViewTanSin;
if (RenderPortal::Instance()->MirrorFlags & RF_XFLIP) if (Thread->Portal->MirrorFlags & RF_XFLIP)
{ {
double t = -rx1; double t = -rx1;
rx1 = -rx2; rx1 = -rx2;
@ -380,7 +380,7 @@ namespace swrenderer
// Find the first clippost that touches the source post // Find the first clippost that touches the source post
// (adjacent pixels are touching). // (adjacent pixels are touching).
return RenderClipSegment::Instance()->IsVisible(sx1, sx2); return Thread->ClipSegments->IsVisible(sx1, sx2);
} }
void RenderOpaquePass::AddPolyobjs(subsector_t *sub) void RenderOpaquePass::AddPolyobjs(subsector_t *sub)
@ -507,7 +507,7 @@ namespace swrenderer
(frontsector->heightsec && (frontsector->heightsec &&
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ? frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ?
VisiblePlaneList::Instance()->FindPlane(frontsector->ceilingplane, // killough 3/8/98 Thread->PlaneList->FindPlane(frontsector->ceilingplane, // killough 3/8/98
frontsector->GetTexture(sector_t::ceiling), frontsector->GetTexture(sector_t::ceiling),
ceilinglightlevel + R_ActualExtraLight(foggy), // killough 4/11/98 ceilinglightlevel + R_ActualExtraLight(foggy), // killough 4/11/98
frontsector->GetAlpha(sector_t::ceiling), frontsector->GetAlpha(sector_t::ceiling),
@ -548,7 +548,7 @@ namespace swrenderer
(frontsector->heightsec && (frontsector->heightsec &&
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ? frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
VisiblePlaneList::Instance()->FindPlane(frontsector->floorplane, Thread->PlaneList->FindPlane(frontsector->floorplane,
frontsector->GetTexture(sector_t::floor), frontsector->GetTexture(sector_t::floor),
floorlightlevel + R_ActualExtraLight(foggy), // killough 3/16/98 floorlightlevel + R_ActualExtraLight(foggy), // killough 3/16/98
frontsector->GetAlpha(sector_t::floor), frontsector->GetAlpha(sector_t::floor),
@ -568,7 +568,7 @@ namespace swrenderer
backupfp = floorplane; backupfp = floorplane;
backupcp = ceilingplane; backupcp = ceilingplane;
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
// first check all floors // first check all floors
for (int i = 0; i < (int)frontsector->e->XFloor.ffloors.Size(); i++) for (int i = 0; i < (int)frontsector->e->XFloor.ffloors.Size(); i++)
@ -614,7 +614,7 @@ namespace swrenderer
} }
ceilingplane = nullptr; ceilingplane = nullptr;
floorplane = VisiblePlaneList::Instance()->FindPlane(frontsector->floorplane, floorplane = Thread->PlaneList->FindPlane(frontsector->floorplane,
frontsector->GetTexture(sector_t::floor), frontsector->GetTexture(sector_t::floor),
floorlightlevel + R_ActualExtraLight(foggy), // killough 3/16/98 floorlightlevel + R_ActualExtraLight(foggy), // killough 3/16/98
frontsector->GetAlpha(sector_t::floor), frontsector->GetAlpha(sector_t::floor),
@ -680,7 +680,7 @@ namespace swrenderer
tempsec.ceilingplane.ChangeHeight(1 / 65536.); tempsec.ceilingplane.ChangeHeight(1 / 65536.);
floorplane = nullptr; floorplane = nullptr;
ceilingplane = VisiblePlaneList::Instance()->FindPlane(frontsector->ceilingplane, // killough 3/8/98 ceilingplane = Thread->PlaneList->FindPlane(frontsector->ceilingplane, // killough 3/8/98
frontsector->GetTexture(sector_t::ceiling), frontsector->GetTexture(sector_t::ceiling),
ceilinglightlevel + R_ActualExtraLight(foggy), // killough 4/11/98 ceilinglightlevel + R_ActualExtraLight(foggy), // killough 4/11/98
frontsector->GetAlpha(sector_t::ceiling), frontsector->GetAlpha(sector_t::ceiling),
@ -720,7 +720,7 @@ namespace swrenderer
int shade = LIGHT2SHADE((floorlightlevel + ceilinglightlevel) / 2 + R_ActualExtraLight(foggy)); int shade = LIGHT2SHADE((floorlightlevel + ceilinglightlevel) / 2 + R_ActualExtraLight(foggy));
for (WORD i = ParticlesInSubsec[(unsigned int)(sub - subsectors)]; i != NO_PARTICLE; i = Particles[i].snext) for (WORD i = ParticlesInSubsec[(unsigned int)(sub - subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
{ {
RenderParticle::Project(Particles + i, subsectors[sub - subsectors].sector, shade, FakeSide, foggy); RenderParticle::Project(Thread, Particles + i, subsectors[sub - subsectors].sector, shade, FakeSide, foggy);
} }
} }
@ -738,7 +738,7 @@ namespace swrenderer
backupcp = ceilingplane; backupcp = ceilingplane;
floorplane = nullptr; floorplane = nullptr;
ceilingplane = nullptr; ceilingplane = nullptr;
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
for (unsigned int i = 0; i < line->backsector->e->XFloor.ffloors.Size(); i++) for (unsigned int i = 0; i < line->backsector->e->XFloor.ffloors.Size(); i++)
{ {
clip3d->fakeFloor = line->backsector->e->XFloor.ffloors[i]; clip3d->fakeFloor = line->backsector->e->XFloor.ffloors[i];
@ -886,15 +886,15 @@ namespace swrenderer
if ((sprite.renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) if ((sprite.renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
{ {
RenderWallSprite::Project(thing, sprite.pos, sprite.picnum, sprite.spriteScale, sprite.renderflags, thingShade, foggy, thingColormap); RenderWallSprite::Project(Thread, thing, sprite.pos, sprite.picnum, sprite.spriteScale, sprite.renderflags, thingShade, foggy, thingColormap);
} }
else if (sprite.voxel) else if (sprite.voxel)
{ {
RenderVoxel::Project(thing, sprite.pos, sprite.voxel, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap); RenderVoxel::Project(Thread, thing, sprite.pos, sprite.voxel, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap);
} }
else else
{ {
RenderSprite::Project(thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap); RenderSprite::Project(Thread, thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap);
} }
} }
} }
@ -915,7 +915,7 @@ namespace swrenderer
// [ZZ] Or less definitely not visible (hue) // [ZZ] Or less definitely not visible (hue)
// [ZZ] 10.01.2016: don't try to clip stuff inside a skybox against the current portal. // [ZZ] 10.01.2016: don't try to clip stuff inside a skybox against the current portal.
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), renderportal->CurrentPortal->dst)) if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), renderportal->CurrentPortal->dst))
return false; return false;

View file

@ -23,6 +23,7 @@ struct FVoxelDef;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
struct VisiblePlane; struct VisiblePlane;
// The 3072 below is just an arbitrary value picked to avoid // The 3072 below is just an arbitrary value picked to avoid
@ -51,7 +52,7 @@ namespace swrenderer
class RenderOpaquePass class RenderOpaquePass
{ {
public: public:
static RenderOpaquePass *Instance(); RenderOpaquePass(RenderThread *thread);
void ClearClip(); void ClearClip();
void RenderScene(); void RenderScene();
@ -62,6 +63,8 @@ namespace swrenderer
short floorclip[MAXWIDTH]; short floorclip[MAXWIDTH];
short ceilingclip[MAXWIDTH]; short ceilingclip[MAXWIDTH];
RenderThread *Thread = nullptr;
private: private:
void RenderBSPNode(void *node); void RenderBSPNode(void *node);
void RenderSubsector(subsector_t *sub); void RenderSubsector(subsector_t *sub);
@ -72,7 +75,7 @@ namespace swrenderer
void AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside, bool foggy, FDynamicColormap *basecolormap); void AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside, bool foggy, FDynamicColormap *basecolormap);
static bool IsPotentiallyVisible(AActor *thing); bool IsPotentiallyVisible(AActor *thing);
static bool GetThingSprite(AActor *thing, ThingSprite &sprite); static bool GetThingSprite(AActor *thing, ThingSprite &sprite);
subsector_t *InSubsector = nullptr; subsector_t *InSubsector = nullptr;

View file

@ -57,6 +57,7 @@
#include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
CVAR(Int, r_portal_recursions, 4, CVAR_ARCHIVE) CVAR(Int, r_portal_recursions, 4, CVAR_ARCHIVE)
CVAR(Bool, r_highlight_portals, false, CVAR_ARCHIVE) CVAR(Bool, r_highlight_portals, false, CVAR_ARCHIVE)
@ -67,10 +68,9 @@ CVAR(Bool, r_skyboxes, true, 0)
namespace swrenderer namespace swrenderer
{ {
RenderPortal *RenderPortal::Instance() RenderPortal::RenderPortal(RenderThread *thread)
{ {
static RenderPortal renderportal; Thread = thread;
return &renderportal;
} }
// Draws any recorded sky boxes and then frees them. // Draws any recorded sky boxes and then frees them.
@ -92,13 +92,13 @@ namespace swrenderer
{ {
numskyboxes = 0; numskyboxes = 0;
VisiblePlaneList *planes = VisiblePlaneList::Instance(); VisiblePlaneList *planes = Thread->PlaneList.get();
DrawSegmentList *drawseglist = DrawSegmentList::Instance(); DrawSegmentList *drawseglist = Thread->DrawSegments.get();
if (!planes->HasPortalPlanes()) if (!planes->HasPortalPlanes())
return; return;
Clip3DFloors::Instance()->EnterSkybox(); Thread->Clip3DFloors->EnterSkybox();
CurrentPortalInSkybox = true; CurrentPortalInSkybox = true;
int savedextralight = extralight; int savedextralight = extralight;
@ -112,7 +112,7 @@ namespace swrenderer
{ {
if (pl->right < pl->left || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES || pl->portal == nullptr) if (pl->right < pl->left || !r_skyboxes || numskyboxes == MAX_SKYBOX_PLANES || pl->portal == nullptr)
{ {
pl->Render(OPAQUE, false, false); pl->Render(Thread, OPAQUE, false, false);
continue; continue;
} }
@ -151,7 +151,7 @@ namespace swrenderer
// not implemented yet // not implemented yet
default: default:
pl->Render(OPAQUE, false, false); pl->Render(Thread, OPAQUE, false, false);
numskyboxes--; numskyboxes--;
continue; continue;
} }
@ -165,12 +165,12 @@ namespace swrenderer
validcount++; // Make sure we see all sprites validcount++; // Make sure we see all sprites
planes->ClearKeepFakePlanes(); planes->ClearKeepFakePlanes();
RenderClipSegment::Instance()->Clear(pl->left, pl->right); Thread->ClipSegments->Clear(pl->left, pl->right);
WindowLeft = pl->left; WindowLeft = pl->left;
WindowRight = pl->right; WindowRight = pl->right;
auto ceilingclip = RenderOpaquePass::Instance()->ceilingclip; auto ceilingclip = Thread->OpaquePass->ceilingclip;
auto floorclip = RenderOpaquePass::Instance()->floorclip; auto floorclip = Thread->OpaquePass->floorclip;
for (int i = pl->left; i < pl->right; i++) for (int i = pl->left; i < pl->right; i++)
{ {
if (pl->top[i] == 0x7fff) if (pl->top[i] == 0x7fff)
@ -208,12 +208,12 @@ namespace swrenderer
drawseglist->Push(draw_segment); drawseglist->Push(draw_segment);
drawseglist->PushPortal(); drawseglist->PushPortal();
VisibleSpriteList::Instance()->PushPortal(); Thread->SpriteList->PushPortal();
viewposStack.Push(ViewPos); viewposStack.Push(ViewPos);
visplaneStack.Push(pl); visplaneStack.Push(pl);
RenderOpaquePass::Instance()->RenderScene(); Thread->OpaquePass->RenderScene();
Clip3DFloors::Instance()->ResetClip(); // reset clips (floor/ceiling) Thread->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
planes->Render(); planes->Render();
port->mFlags &= ~PORTSF_INSKYBOX; port->mFlags &= ~PORTSF_INSKYBOX;
@ -228,16 +228,16 @@ namespace swrenderer
// Masked textures and planes need the view coordinates restored for proper positioning. // Masked textures and planes need the view coordinates restored for proper positioning.
viewposStack.Pop(ViewPos); viewposStack.Pop(ViewPos);
RenderTranslucentPass::Instance()->Render(); Thread->TranslucentPass->Render();
VisiblePlane *pl; VisiblePlane *pl;
visplaneStack.Pop(pl); visplaneStack.Pop(pl);
if (pl->Alpha > 0 && pl->picnum != skyflatnum) if (pl->Alpha > 0 && pl->picnum != skyflatnum)
{ {
pl->Render(pl->Alpha, pl->Additive, true); pl->Render(Thread, pl->Alpha, pl->Additive, true);
} }
VisibleSpriteList::Instance()->PopPortal(); Thread->SpriteList->PopPortal();
drawseglist->PopPortal(); drawseglist->PopPortal();
} }
@ -250,9 +250,9 @@ namespace swrenderer
R_SetViewAngle(); R_SetViewAngle();
CurrentPortalInSkybox = false; CurrentPortalInSkybox = false;
Clip3DFloors::Instance()->LeaveSkybox(); Thread->Clip3DFloors->LeaveSkybox();
if (Clip3DFloors::Instance()->fakeActive) return; if (Thread->Clip3DFloors->fakeActive) return;
planes->ClearPortalPlanes(); planes->ClearPortalPlanes();
} }
@ -395,8 +395,8 @@ namespace swrenderer
PortalDrawseg* prevpds = CurrentPortal; PortalDrawseg* prevpds = CurrentPortal;
CurrentPortal = pds; CurrentPortal = pds;
VisiblePlaneList::Instance()->ClearKeepFakePlanes(); Thread->PlaneList->ClearKeepFakePlanes();
RenderClipSegment::Instance()->Clear(pds->x1, pds->x2); Thread->ClipSegments->Clear(pds->x1, pds->x2);
WindowLeft = pds->x1; WindowLeft = pds->x1;
WindowRight = pds->x2; WindowRight = pds->x2;
@ -411,21 +411,21 @@ namespace swrenderer
} }
// some portals have height differences, account for this here // some portals have height differences, account for this here
Clip3DFloors::Instance()->EnterSkybox(); // push 3D floor height map Thread->Clip3DFloors->EnterSkybox(); // push 3D floor height map
CurrentPortalInSkybox = false; // first portal in a skybox should set this variable to false for proper clipping in skyboxes. CurrentPortalInSkybox = false; // first portal in a skybox should set this variable to false for proper clipping in skyboxes.
// first pass, set clipping // first pass, set clipping
auto ceilingclip = RenderOpaquePass::Instance()->ceilingclip; auto ceilingclip = Thread->OpaquePass->ceilingclip;
auto floorclip = RenderOpaquePass::Instance()->floorclip; auto floorclip = Thread->OpaquePass->floorclip;
memcpy(ceilingclip + pds->x1, &pds->ceilingclip[0], pds->len * sizeof(*ceilingclip)); memcpy(ceilingclip + pds->x1, &pds->ceilingclip[0], pds->len * sizeof(*ceilingclip));
memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip)); memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip));
RenderOpaquePass::Instance()->RenderScene(); Thread->OpaquePass->RenderScene();
Clip3DFloors::Instance()->ResetClip(); // reset clips (floor/ceiling) Thread->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE; if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE;
PlaneCycles.Clock(); PlaneCycles.Clock();
VisiblePlaneList::Instance()->Render(); Thread->PlaneList->Render();
RenderPlanePortals(); RenderPlanePortals();
PlaneCycles.Unclock(); PlaneCycles.Unclock();
@ -444,12 +444,12 @@ namespace swrenderer
NetUpdate(); NetUpdate();
MaskedCycles.Clock(); // [ZZ] count sprites in portals/mirrors along with normal ones. MaskedCycles.Clock(); // [ZZ] count sprites in portals/mirrors along with normal ones.
RenderTranslucentPass::Instance()->Render(); // this is required since with portals there often will be cases when more than 80% of the view is inside a portal. Thread->TranslucentPass->Render(); // this is required since with portals there often will be cases when more than 80% of the view is inside a portal.
MaskedCycles.Unclock(); MaskedCycles.Unclock();
NetUpdate(); NetUpdate();
Clip3DFloors::Instance()->LeaveSkybox(); // pop 3D floor height map Thread->Clip3DFloors->LeaveSkybox(); // pop 3D floor height map
CurrentPortalUniq = prevuniq2; CurrentPortalUniq = prevuniq2;
// draw a red line around a portal if it's being highlighted // draw a red line around a portal if it's being highlighted
@ -529,10 +529,11 @@ namespace swrenderer
WallPortals.Push(RenderMemory::NewObject<PortalDrawseg>(linedef, x1, x2, topclip, bottomclip)); WallPortals.Push(RenderMemory::NewObject<PortalDrawseg>(linedef, x1, x2, topclip, bottomclip));
} }
} }
/*
ADD_STAT(skyboxes) ADD_STAT(skyboxes)
{ {
FString out; FString out;
out.Format("%d skybox planes", swrenderer::RenderPortal::Instance()->numskyboxes); out.Format("%d skybox planes", swrenderer::RenderPortal::Instance()->numskyboxes);
return out; return out;
} }
*/

View file

@ -17,12 +17,13 @@
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
struct VisiblePlane; struct VisiblePlane;
class RenderPortal class RenderPortal
{ {
public: public:
static RenderPortal *Instance(); RenderPortal(RenderThread *thread);
void SetMainPortal(); void SetMainPortal();
void CopyStackedViewParameters(); void CopyStackedViewParameters();
@ -32,6 +33,8 @@ namespace swrenderer
void AddLinePortal(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip); void AddLinePortal(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip);
RenderThread *Thread = nullptr;
int WindowLeft = 0; int WindowLeft = 0;
int WindowRight = 0; int WindowRight = 0;
uint16_t MirrorFlags = 0; uint16_t MirrorFlags = 0;

View file

@ -47,6 +47,7 @@
#include "swrenderer/drawers/r_draw_rgba.h" #include "swrenderer/drawers/r_draw_rgba.h"
#include "swrenderer/drawers/r_thread.h" #include "swrenderer/drawers/r_thread.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Bool, r_shadercolormaps)
EXTERN_CVAR(Int, r_clearbuffer) EXTERN_CVAR(Int, r_clearbuffer)
@ -55,10 +56,9 @@ namespace swrenderer
{ {
cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles; cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles;
RenderScene *RenderScene::Instance() RenderScene::RenderScene(RenderThread *thread)
{ {
static RenderScene instance; Thread = thread;
return &instance;
} }
void RenderScene::SetClearColor(int color) void RenderScene::SetClearColor(int color)
@ -115,7 +115,7 @@ namespace swrenderer
RenderMemory::Clear(); RenderMemory::Clear();
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
clip3d->Cleanup(); clip3d->Cleanup();
clip3d->ResetClip(); // reset clips (floor/ceiling) clip3d->ResetClip(); // reset clips (floor/ceiling)
@ -123,25 +123,25 @@ namespace swrenderer
CameraLight::Instance()->SetCamera(actor); CameraLight::Instance()->SetCamera(actor);
RenderViewport::Instance()->SetupFreelook(); RenderViewport::Instance()->SetupFreelook();
RenderPortal::Instance()->CopyStackedViewParameters(); Thread->Portal->CopyStackedViewParameters();
// Clear buffers. // Clear buffers.
RenderClipSegment::Instance()->Clear(0, viewwidth); Thread->ClipSegments->Clear(0, viewwidth);
DrawSegmentList::Instance()->Clear(); Thread->DrawSegments->Clear();
VisiblePlaneList::Instance()->Clear(); Thread->PlaneList->Clear();
RenderTranslucentPass::Instance()->Clear(); Thread->TranslucentPass->Clear();
// opening / clipping determination // opening / clipping determination
RenderOpaquePass::Instance()->ClearClip(); Thread->OpaquePass->ClearClip();
NetUpdate(); NetUpdate();
RenderPortal::Instance()->SetMainPortal(); Thread->Portal->SetMainPortal();
this->dontmaplines = dontmaplines; this->dontmaplines = dontmaplines;
// [RH] Hack to make windows into underwater areas possible // [RH] Hack to make windows into underwater areas possible
RenderOpaquePass::Instance()->ResetFakingUnderwater(); Thread->OpaquePass->ResetFakingUnderwater();
// [RH] Setup particles for this frame // [RH] Setup particles for this frame
P_FindParticleSubsectors(); P_FindParticleSubsectors();
@ -155,8 +155,8 @@ namespace swrenderer
} }
// Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function // Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function
PO_LinkToSubsectors(); PO_LinkToSubsectors();
RenderOpaquePass::Instance()->RenderScene(); Thread->OpaquePass->RenderScene();
Clip3DFloors::Instance()->ResetClip(); // reset clips (floor/ceiling) Thread->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
camera->renderflags = savedflags; camera->renderflags = savedflags;
WallCycles.Unclock(); WallCycles.Unclock();
@ -165,16 +165,16 @@ namespace swrenderer
if (viewactive) if (viewactive)
{ {
PlaneCycles.Clock(); PlaneCycles.Clock();
VisiblePlaneList::Instance()->Render(); Thread->PlaneList->Render();
RenderPortal::Instance()->RenderPlanePortals(); Thread->Portal->RenderPlanePortals();
PlaneCycles.Unclock(); PlaneCycles.Unclock();
RenderPortal::Instance()->RenderLinePortals(); Thread->Portal->RenderLinePortals();
NetUpdate(); NetUpdate();
MaskedCycles.Clock(); MaskedCycles.Clock();
RenderTranslucentPass::Instance()->Render(); Thread->TranslucentPass->Render();
MaskedCycles.Unclock(); MaskedCycles.Unclock();
NetUpdate(); NetUpdate();
@ -237,7 +237,6 @@ namespace swrenderer
void RenderScene::Init() void RenderScene::Init()
{ {
atterm([]() { RenderScene::Instance()->Deinit(); });
// viewwidth / viewheight are set by the defaults // viewwidth / viewheight are set by the defaults
fillshort(zeroarray, MAXWIDTH, 0); fillshort(zeroarray, MAXWIDTH, 0);
@ -246,8 +245,8 @@ namespace swrenderer
void RenderScene::Deinit() void RenderScene::Deinit()
{ {
RenderTranslucentPass::Instance()->Deinit(); Thread->TranslucentPass->Deinit();
Clip3DFloors::Instance()->Cleanup(); Thread->Clip3DFloors->Cleanup();
} }
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////

View file

@ -23,10 +23,12 @@ namespace swrenderer
{ {
extern cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles; extern cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles;
class RenderThread;
class RenderScene class RenderScene
{ {
public: public:
static RenderScene *Instance(); RenderScene(RenderThread *thread);
void Init(); void Init();
void ScreenResized(); void ScreenResized();
@ -39,6 +41,8 @@ namespace swrenderer
bool DontMapLines() const { return dontmaplines; } bool DontMapLines() const { return dontmaplines; }
RenderThread *Thread = nullptr;
private: private:
void RenderActorView(AActor *actor, bool dontmaplines = false); void RenderActorView(AActor *actor, bool dontmaplines = false);

View file

@ -38,6 +38,7 @@
#include "swrenderer/line/r_renderdrawsegment.h" #include "swrenderer/line/r_renderdrawsegment.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Int, r_drawfuzz) EXTERN_CVAR(Int, r_drawfuzz)
EXTERN_CVAR(Bool, r_drawvoxels) EXTERN_CVAR(Bool, r_drawvoxels)
@ -47,10 +48,9 @@ CVAR(Bool, r_fullbrightignoresectorcolor, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG
namespace swrenderer namespace swrenderer
{ {
RenderTranslucentPass *RenderTranslucentPass::Instance() RenderTranslucentPass::RenderTranslucentPass(RenderThread *thread)
{ {
static RenderTranslucentPass instance; Thread = thread;
return &instance;
} }
void RenderTranslucentPass::Deinit() void RenderTranslucentPass::Deinit()
@ -60,7 +60,7 @@ namespace swrenderer
void RenderTranslucentPass::Clear() void RenderTranslucentPass::Clear()
{ {
VisibleSpriteList::Instance()->Clear(); Thread->SpriteList->Clear();
} }
void RenderTranslucentPass::CollectPortals() void RenderTranslucentPass::CollectPortals()
@ -71,7 +71,7 @@ namespace swrenderer
// a) exit early if no relevant info is found and // a) exit early if no relevant info is found and
// b) skip most of the collected drawsegs which have no portal attached. // b) skip most of the collected drawsegs which have no portal attached.
portaldrawsegs.Clear(); portaldrawsegs.Clear();
DrawSegmentList *drawseglist = DrawSegmentList::Instance(); DrawSegmentList *drawseglist = Thread->DrawSegments.get();
for (auto index = drawseglist->BeginIndex(); index != drawseglist->EndIndex(); index++) for (auto index = drawseglist->BeginIndex(); index != drawseglist->EndIndex(); index++)
{ {
DrawSegment *seg = drawseglist->Segment(index); DrawSegment *seg = drawseglist->Segment(index);
@ -98,7 +98,7 @@ namespace swrenderer
bool RenderTranslucentPass::ClipSpriteColumnWithPortals(int x, VisibleSprite *spr) bool RenderTranslucentPass::ClipSpriteColumnWithPortals(int x, VisibleSprite *spr)
{ {
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
// [ZZ] 10.01.2016: don't clip sprites from the root of a skybox. // [ZZ] 10.01.2016: don't clip sprites from the root of a skybox.
if (renderportal->CurrentPortalInSkybox) if (renderportal->CurrentPortalInSkybox)
@ -126,14 +126,14 @@ namespace swrenderer
void RenderTranslucentPass::DrawMaskedSingle(bool renew) void RenderTranslucentPass::DrawMaskedSingle(bool renew)
{ {
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = Thread->Portal.get();
auto &sortedSprites = VisibleSpriteList::Instance()->SortedSprites; auto &sortedSprites = Thread->SpriteList->SortedSprites;
for (int i = sortedSprites.Size(); i > 0; i--) for (int i = sortedSprites.Size(); i > 0; i--)
{ {
if (sortedSprites[i - 1]->IsCurrentPortalUniq(renderportal->CurrentPortalUniq)) if (sortedSprites[i - 1]->IsCurrentPortalUniq(renderportal->CurrentPortalUniq))
{ {
sortedSprites[i - 1]->Render(); sortedSprites[i - 1]->Render(Thread);
} }
} }
@ -141,10 +141,10 @@ namespace swrenderer
if (renew) if (renew)
{ {
Clip3DFloors::Instance()->fake3D |= FAKE3D_REFRESHCLIP; Thread->Clip3DFloors->fake3D |= FAKE3D_REFRESHCLIP;
} }
DrawSegmentList *drawseglist = DrawSegmentList::Instance(); DrawSegmentList *drawseglist = Thread->DrawSegments.get();
for (auto index = drawseglist->BeginIndex(); index != drawseglist->EndIndex(); index++) for (auto index = drawseglist->BeginIndex(); index != drawseglist->EndIndex(); index++)
{ {
DrawSegment *ds = drawseglist->Segment(index); DrawSegment *ds = drawseglist->Segment(index);
@ -156,7 +156,7 @@ namespace swrenderer
if (ds->fake) continue; if (ds->fake) continue;
if (ds->maskedtexturecol != nullptr || ds->bFogBoundary) if (ds->maskedtexturecol != nullptr || ds->bFogBoundary)
{ {
RenderDrawSegment renderer; RenderDrawSegment renderer(Thread);
renderer.Render(ds, ds->x1, ds->x2); renderer.Render(ds, ds->x1, ds->x2);
} }
} }
@ -165,9 +165,9 @@ namespace swrenderer
void RenderTranslucentPass::Render() void RenderTranslucentPass::Render()
{ {
CollectPortals(); CollectPortals();
VisibleSpriteList::Instance()->Sort(); Thread->SpriteList->Sort();
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
if (clip3d->height_top == nullptr) if (clip3d->height_top == nullptr)
{ // kg3D - no visible 3D floors, normal rendering { // kg3D - no visible 3D floors, normal rendering
DrawMaskedSingle(false); DrawMaskedSingle(false);
@ -188,7 +188,7 @@ namespace swrenderer
} }
clip3d->sclipBottom = hl->height; clip3d->sclipBottom = hl->height;
DrawMaskedSingle(true); DrawMaskedSingle(true);
VisiblePlaneList::Instance()->RenderHeight(hl->height); Thread->PlaneList->RenderHeight(hl->height);
} }
// floors // floors
@ -197,7 +197,7 @@ namespace swrenderer
DrawMaskedSingle(true); DrawMaskedSingle(true);
for (HeightLevel *hl = clip3d->height_top; hl != nullptr && hl->height < ViewPos.Z; hl = hl->next) for (HeightLevel *hl = clip3d->height_top; hl != nullptr && hl->height < ViewPos.Z; hl = hl->next)
{ {
VisiblePlaneList::Instance()->RenderHeight(hl->height); Thread->PlaneList->RenderHeight(hl->height);
if (hl->next) if (hl->next)
{ {
clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP | FAKE3D_CLIPBOTTOM; clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP | FAKE3D_CLIPBOTTOM;
@ -214,6 +214,6 @@ namespace swrenderer
clip3d->fake3D = 0; clip3d->fake3D = 0;
} }
RenderPlayerSprites::Instance()->Render(); Thread->PlayerSprites->Render();
} }
} }

View file

@ -22,13 +22,14 @@ struct FVoxel;
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
class VisibleSprite; class VisibleSprite;
struct DrawSegment; struct DrawSegment;
class RenderTranslucentPass class RenderTranslucentPass
{ {
public: public:
static RenderTranslucentPass *Instance(); RenderTranslucentPass(RenderThread *thread);
void Deinit(); void Deinit();
void Clear(); void Clear();
@ -36,6 +37,8 @@ namespace swrenderer
bool ClipSpriteColumnWithPortals(int x, VisibleSprite *spr); bool ClipSpriteColumnWithPortals(int x, VisibleSprite *spr);
RenderThread *Thread = nullptr;
private: private:
void CollectPortals(); void CollectPortals();
void DrawMaskedSingle(bool renew); void DrawMaskedSingle(bool renew);

View file

@ -34,12 +34,6 @@
namespace swrenderer namespace swrenderer
{ {
RenderClipSegment *RenderClipSegment::Instance()
{
static RenderClipSegment instance;
return &instance;
}
void RenderClipSegment::Clear(short left, short right) void RenderClipSegment::Clear(short left, short right)
{ {
solidsegs[0].first = -0x7fff; solidsegs[0].first = -0x7fff;

View file

@ -20,8 +20,6 @@ namespace swrenderer
class RenderClipSegment class RenderClipSegment
{ {
public: public:
static RenderClipSegment *Instance();
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, VisibleSegmentCallback callback);
bool Check(int first, int last); bool Check(int first, int last);

View file

@ -43,10 +43,9 @@
namespace swrenderer namespace swrenderer
{ {
DrawSegmentList *DrawSegmentList::Instance() DrawSegmentList::DrawSegmentList(RenderThread *thread)
{ {
static DrawSegmentList instance; Thread = thread;
return &instance;
} }
void DrawSegmentList::Clear() void DrawSegmentList::Clear()

View file

@ -50,7 +50,7 @@ namespace swrenderer
class DrawSegmentList class DrawSegmentList
{ {
public: public:
static DrawSegmentList *Instance(); DrawSegmentList(RenderThread *thread);
unsigned int BeginIndex() const { return StartIndices.Last(); } unsigned int BeginIndex() const { return StartIndices.Last(); }
unsigned int EndIndex() const { return Segments.Size(); } unsigned int EndIndex() const { return Segments.Size(); }
@ -66,6 +66,8 @@ namespace swrenderer
void Push(DrawSegment *segment); void Push(DrawSegment *segment);
void PushInteresting(DrawSegment *segment); void PushInteresting(DrawSegment *segment);
RenderThread *Thread = nullptr;
private: private:
TArray<DrawSegment *> Segments; TArray<DrawSegment *> Segments;
TArray<unsigned int> StartIndices; TArray<unsigned int> StartIndices;

View file

@ -43,16 +43,17 @@
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/viewport/r_spritedrawer.h" #include "swrenderer/viewport/r_spritedrawer.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer namespace swrenderer
{ {
void RenderDecal::RenderDecals(side_t *sidedef, DrawSegment *draw_segment, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom) void RenderDecal::RenderDecals(RenderThread *thread, side_t *sidedef, DrawSegment *draw_segment, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom)
{ {
for (DBaseDecal *decal = sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext) for (DBaseDecal *decal = sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext)
{ {
Render(sidedef, decal, draw_segment, wallshade, lightleft, lightstep, curline, wallC, foggy, basecolormap, walltop, wallbottom, 0); Render(thread, sidedef, decal, draw_segment, wallshade, lightleft, lightstep, curline, wallC, foggy, basecolormap, walltop, wallbottom, 0);
} }
} }
@ -60,7 +61,7 @@ namespace swrenderer
// = 1: drawing masked textures (including sprites) // = 1: drawing masked textures (including sprites)
// Currently, only pass = 0 is done or used // Currently, only pass = 0 is done or used
void RenderDecal::Render(side_t *wall, DBaseDecal *decal, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &savecoord, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, int pass) void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &savecoord, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, int pass)
{ {
DVector2 decal_left, decal_right, decal_pos; DVector2 decal_left, decal_right, decal_pos;
int x1, x2; int x1, x2;
@ -150,7 +151,7 @@ namespace swrenderer
double texturemid; double texturemid;
FWallCoords WallC; FWallCoords WallC;
if (WallC.Init(decal_left, decal_right, TOO_CLOSE_Z)) if (WallC.Init(thread, decal_left, decal_right, TOO_CLOSE_Z))
return; return;
x1 = WallC.sx1; x1 = WallC.sx1;
@ -160,7 +161,7 @@ namespace swrenderer
return; return;
FWallTmapVals WallT; FWallTmapVals WallT;
WallT.InitFromWallCoords(&WallC); WallT.InitFromWallCoords(thread, &WallC);
// Get the top and bottom clipping arrays // Get the top and bottom clipping arrays
switch (decal->RenderFlags & RF_CLIPMASK) switch (decal->RenderFlags & RF_CLIPMASK)
@ -178,7 +179,7 @@ namespace swrenderer
else if (pass == 0) else if (pass == 0)
{ {
mceilingclip = walltop; mceilingclip = walltop;
mfloorclip = RenderOpaquePass::Instance()->ceilingclip; mfloorclip = thread->OpaquePass->ceilingclip;
needrepeat = 1; needrepeat = 1;
} }
else else
@ -194,7 +195,7 @@ namespace swrenderer
return; return;
} }
mceilingclip = walltop; mceilingclip = walltop;
mfloorclip = RenderOpaquePass::Instance()->ceilingclip; mfloorclip = thread->OpaquePass->ceilingclip;
break; break;
case RF_CLIPMID: case RF_CLIPMID:
@ -211,7 +212,7 @@ namespace swrenderer
{ {
return; return;
} }
mceilingclip = RenderOpaquePass::Instance()->floorclip; mceilingclip = thread->OpaquePass->floorclip;
mfloorclip = wallbottom; mfloorclip = wallbottom;
break; break;
} }
@ -302,7 +303,7 @@ namespace swrenderer
{ // calculate lighting { // calculate lighting
drawerargs.SetLight(usecolormap, light, wallshade); drawerargs.SetLight(usecolormap, light, wallshade);
} }
DrawColumn(drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip); DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip);
light += lightstep; light += lightstep;
x++; x++;
} }
@ -311,12 +312,12 @@ namespace swrenderer
// If this sprite is RF_CLIPFULL on a two-sided line, needrepeat will // If this sprite is RF_CLIPFULL on a two-sided line, needrepeat will
// be set 1 if we need to draw on the lower wall. In all other cases, // be set 1 if we need to draw on the lower wall. In all other cases,
// needrepeat will be 0, and the while will fail. // needrepeat will be 0, and the while will fail.
mceilingclip = RenderOpaquePass::Instance()->floorclip; mceilingclip = thread->OpaquePass->floorclip;
mfloorclip = wallbottom; mfloorclip = wallbottom;
} while (needrepeat--); } while (needrepeat--);
} }
void RenderDecal::DrawColumn(SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip) void RenderDecal::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
{ {
auto viewport = RenderViewport::Instance(); auto viewport = RenderViewport::Instance();

View file

@ -25,10 +25,10 @@ namespace swrenderer
class RenderDecal class RenderDecal
{ {
public: public:
static void RenderDecals(side_t *wall, DrawSegment *draw_segment, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom); static void RenderDecals(RenderThread *thread, side_t *wall, DrawSegment *draw_segment, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom);
private: private:
static void Render(side_t *wall, DBaseDecal *first, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, int pass); static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, int pass);
static void DrawColumn(SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip); static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
}; };
} }

View file

@ -55,12 +55,13 @@
#include "swrenderer/drawers/r_draw_rgba.h" #include "swrenderer/drawers/r_draw_rgba.h"
#include "swrenderer/drawers/r_draw_pal.h" #include "swrenderer/drawers/r_draw_pal.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer namespace swrenderer
{ {
void RenderParticle::Project(particle_t *particle, const sector_t *sector, int shade, WaterFakeSide fakeside, bool foggy) void RenderParticle::Project(RenderThread *thread, particle_t *particle, const sector_t *sector, int shade, WaterFakeSide fakeside, bool foggy)
{ {
double tr_x, tr_y; double tr_x, tr_y;
double tx, ty; double tx, ty;
@ -69,7 +70,7 @@ namespace swrenderer
int x1, x2, y1, y2; int x1, x2, y1, y2;
sector_t* heightsec = NULL; sector_t* heightsec = NULL;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = thread->Portal.get();
// [ZZ] Particle not visible through the portal plane // [ZZ] Particle not visible through the portal plane
if (renderportal->CurrentPortal && !!P_PointOnLineSide(particle->Pos, renderportal->CurrentPortal->dst)) if (renderportal->CurrentPortal && !!P_PointOnLineSide(particle->Pos, renderportal->CurrentPortal->dst))
@ -120,8 +121,8 @@ namespace swrenderer
// entered, we don't need to clip it to drawsegs like a normal sprite. // entered, we don't need to clip it to drawsegs like a normal sprite.
// Clip particles behind walls. // Clip particles behind walls.
auto ceilingclip = RenderOpaquePass::Instance()->ceilingclip; auto ceilingclip = thread->OpaquePass->ceilingclip;
auto floorclip = RenderOpaquePass::Instance()->floorclip; auto floorclip = thread->OpaquePass->floorclip;
if (y1 < ceilingclip[x1]) y1 = ceilingclip[x1]; if (y1 < ceilingclip[x1]) y1 = ceilingclip[x1];
if (y1 < ceilingclip[x2 - 1]) y1 = ceilingclip[x2 - 1]; if (y1 < ceilingclip[x2 - 1]) y1 = ceilingclip[x2 - 1];
if (y2 >= floorclip[x1]) y2 = floorclip[x1] - 1; if (y2 >= floorclip[x1]) y2 = floorclip[x1] - 1;
@ -205,10 +206,10 @@ namespace swrenderer
vis->Light.SetColormap(tiz * LightVisibility::Instance()->ParticleGlobVis(), shade, map, particle->bright != 0, false, false); vis->Light.SetColormap(tiz * LightVisibility::Instance()->ParticleGlobVis(), shade, map, particle->bright != 0, false, false);
VisibleSpriteList::Instance()->Push(vis); thread->SpriteList->Push(vis);
} }
void RenderParticle::Render(short *cliptop, short *clipbottom, int minZ, int maxZ) void RenderParticle::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ)
{ {
auto vis = this; auto vis = this;
@ -222,7 +223,7 @@ namespace swrenderer
if (ycount <= 0 || countbase <= 0) if (ycount <= 0 || countbase <= 0)
return; return;
DrawMaskedSegsBehindParticle(); DrawMaskedSegsBehindParticle(thread);
uint32_t fg = LightBgra::shade_pal_index_simple(color, LightBgra::calc_light_multiplier(LIGHTSCALE(0, vis->Light.ColormapNum << FRACBITS))); uint32_t fg = LightBgra::shade_pal_index_simple(color, LightBgra::calc_light_multiplier(LIGHTSCALE(0, vis->Light.ColormapNum << FRACBITS)));
@ -237,7 +238,7 @@ namespace swrenderer
uint32_t fracstepx = PARTICLE_TEXTURE_SIZE * FRACUNIT / countbase; uint32_t fracstepx = PARTICLE_TEXTURE_SIZE * FRACUNIT / countbase;
uint32_t fracposx = fracstepx / 2; uint32_t fracposx = fracstepx / 2;
RenderTranslucentPass *translucentPass = RenderTranslucentPass::Instance(); RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
if (viewport->RenderTarget->IsBgra()) if (viewport->RenderTarget->IsBgra())
{ {
@ -261,11 +262,11 @@ namespace swrenderer
} }
} }
void RenderParticle::DrawMaskedSegsBehindParticle() void RenderParticle::DrawMaskedSegsBehindParticle(RenderThread *thread)
{ {
// Draw any masked textures behind this particle so that when the // Draw any masked textures behind this particle so that when the
// particle is drawn, it will be in front of them. // particle is drawn, it will be in front of them.
DrawSegmentList *segmentlist = DrawSegmentList::Instance(); DrawSegmentList *segmentlist = thread->DrawSegments.get();
for (unsigned int index = segmentlist->BeginInterestingIndex(); index != segmentlist->EndInterestingIndex(); index++) for (unsigned int index = segmentlist->BeginInterestingIndex(); index != segmentlist->EndInterestingIndex(); index++)
{ {
DrawSegment *ds = segmentlist->InterestingSegment(index); DrawSegment *ds = segmentlist->InterestingSegment(index);
@ -281,7 +282,7 @@ namespace swrenderer
// [ZZ] only draw stuff that's inside the same portal as the particle, other portals will care for themselves // [ZZ] only draw stuff that's inside the same portal as the particle, other portals will care for themselves
if (ds->CurrentPortalUniq == CurrentPortalUniq) if (ds->CurrentPortalUniq == CurrentPortalUniq)
{ {
RenderDrawSegment renderer; RenderDrawSegment renderer(thread);
renderer.Render(ds, MAX<int>(ds->x1, x1), MIN<int>(ds->x2, x2)); renderer.Render(ds, MAX<int>(ds->x1, x1), MIN<int>(ds->x2, x2));
} }
} }

View file

@ -23,14 +23,14 @@ namespace swrenderer
class RenderParticle : public VisibleSprite class RenderParticle : public VisibleSprite
{ {
public: public:
static void Project(particle_t *, const sector_t *sector, int shade, WaterFakeSide fakeside, bool foggy); static void Project(RenderThread *thread, particle_t *, const sector_t *sector, int shade, WaterFakeSide fakeside, bool foggy);
protected: protected:
bool IsParticle() const override { return true; } bool IsParticle() const override { return true; }
void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
private: private:
void DrawMaskedSegsBehindParticle(); void DrawMaskedSegsBehindParticle(RenderThread *thread);
fixed_t xscale = 0; fixed_t xscale = 0;
fixed_t startfrac = 0; // horizontal position of x1 fixed_t startfrac = 0; // horizontal position of x1

View file

@ -55,6 +55,7 @@
#include "swrenderer/things/r_sprite.h" #include "swrenderer/things/r_sprite.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include "g_levellocals.h" #include "g_levellocals.h"
EXTERN_CVAR(Bool, st_scale) EXTERN_CVAR(Bool, st_scale)
@ -65,10 +66,9 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
namespace swrenderer namespace swrenderer
{ {
RenderPlayerSprites *RenderPlayerSprites::Instance() RenderPlayerSprites::RenderPlayerSprites(RenderThread *thread)
{ {
static RenderPlayerSprites instance; Thread = thread;
return &instance;
} }
void RenderPlayerSprites::Render() void RenderPlayerSprites::Render()
@ -121,7 +121,7 @@ namespace swrenderer
else else
{ // This used to use camera->Sector but due to interpolation that can be incorrect { // This used to use camera->Sector but due to interpolation that can be incorrect
// when the interpolated viewpoint is in a different sector than the camera. // when the interpolated viewpoint is in a different sector than the camera.
sec = RenderOpaquePass::Instance()->FakeFlat(viewsector, &tempsec, &floorlight, &ceilinglight, nullptr, 0, 0, 0, 0); sec = Thread->OpaquePass->FakeFlat(viewsector, &tempsec, &floorlight, &ceilinglight, nullptr, 0, 0, 0, 0);
// [RH] set basecolormap // [RH] set basecolormap
basecolormap = sec->ColorMap; basecolormap = sec->ColorMap;

View file

@ -74,11 +74,13 @@ namespace swrenderer
class RenderPlayerSprites class RenderPlayerSprites
{ {
public: public:
static RenderPlayerSprites *Instance(); RenderPlayerSprites(RenderThread *thread);
void Render(); void Render();
void RenderRemaining(); void RenderRemaining();
RenderThread *Thread = nullptr;
private: private:
void RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy); void RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy);

View file

@ -55,12 +55,13 @@
#include "swrenderer/things/r_sprite.h" #include "swrenderer/things/r_sprite.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
namespace swrenderer namespace swrenderer
{ {
void RenderSprite::Project(AActor *thing, const DVector3 &pos, FTexture *tex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap) void RenderSprite::Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *tex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap)
{ {
// transform the origin point // transform the origin point
double tr_x = pos.X - ViewPos.X; double tr_x = pos.X - ViewPos.X;
@ -75,7 +76,7 @@ namespace swrenderer
double tx = tr_x * ViewSin - tr_y * ViewCos; double tx = tr_x * ViewSin - tr_y * ViewCos;
// [RH] Flip for mirrors // [RH] Flip for mirrors
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP) if (renderportal->MirrorFlags & RF_XFLIP)
{ {
tx = -tx; tx = -tx;
@ -227,10 +228,10 @@ namespace swrenderer
vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
VisibleSpriteList::Instance()->Push(vis); thread->SpriteList->Push(vis);
} }
void RenderSprite::Render(short *mfloorclip, short *mceilingclip, int, int) void RenderSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int)
{ {
auto vis = this; auto vis = this;
@ -285,7 +286,7 @@ namespace swrenderer
if (x < x2) if (x < x2)
{ {
RenderTranslucentPass *translucentPass = RenderTranslucentPass::Instance(); RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
while (x < x2) while (x < x2)
{ {

View file

@ -20,10 +20,10 @@ namespace swrenderer
class RenderSprite : public VisibleSprite class RenderSprite : public VisibleSprite
{ {
public: public:
static void Project(AActor *thing, const DVector3 &pos, FTexture *tex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap); static void Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *tex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap);
protected: protected:
void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
private: private:
fixed_t xscale = 0; fixed_t xscale = 0;

View file

@ -35,12 +35,13 @@
#include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer namespace swrenderer
{ {
void VisibleSprite::Render() void VisibleSprite::Render(RenderThread *thread)
{ {
static short clipbot[MAXWIDTH]; static short clipbot[MAXWIDTH];
static short cliptop[MAXWIDTH]; static short cliptop[MAXWIDTH];
@ -56,7 +57,7 @@ namespace swrenderer
int colormapnum = spr->Light.ColormapNum; int colormapnum = spr->Light.ColormapNum;
F3DFloor *rover; F3DFloor *rover;
Clip3DFloors *clip3d = Clip3DFloors::Instance(); Clip3DFloors *clip3d = thread->Clip3DFloors.get();
// [RH] Check for particles // [RH] Check for particles
if (spr->IsParticle()) if (spr->IsParticle())
@ -65,7 +66,7 @@ namespace swrenderer
if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gpos.Z <= clip3d->sclipBottom) return; if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gpos.Z <= clip3d->sclipBottom) return;
if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gpos.Z >= clip3d->sclipTop) return; if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gpos.Z >= clip3d->sclipTop) return;
spr->Render(nullptr, nullptr, 0, 0); spr->Render(thread, nullptr, nullptr, 0, 0);
return; return;
} }
@ -279,7 +280,7 @@ namespace swrenderer
// Scan drawsegs from end to start for obscuring segs. // Scan drawsegs from end to start for obscuring segs.
// The first drawseg that is closer than the sprite is the clip seg. // The first drawseg that is closer than the sprite is the clip seg.
DrawSegmentList *segmentlist = DrawSegmentList::Instance(); DrawSegmentList *segmentlist = thread->DrawSegments.get();
for (unsigned int index = segmentlist->BeginIndex(); index != segmentlist->EndIndex(); index++) for (unsigned int index = segmentlist->BeginIndex(); index != segmentlist->EndIndex(); index++)
{ {
DrawSegment *ds = segmentlist->Segment(index); DrawSegment *ds = segmentlist->Segment(index);
@ -322,13 +323,13 @@ namespace swrenderer
(spr->gpos.Y - ds->curline->v1->fY()) * (ds->curline->v2->fX() - ds->curline->v1->fX()) - (spr->gpos.Y - ds->curline->v1->fY()) * (ds->curline->v2->fX() - ds->curline->v1->fX()) -
(spr->gpos.X - ds->curline->v1->fX()) * (ds->curline->v2->fY() - ds->curline->v1->fY()) <= 0)) (spr->gpos.X - ds->curline->v1->fX()) * (ds->curline->v2->fY() - ds->curline->v1->fY()) <= 0))
{ {
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = thread->Portal.get();
// seg is behind sprite, so draw the mid texture if it has one // seg is behind sprite, so draw the mid texture if it has one
if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here
(ds->maskedtexturecol != nullptr || ds->bFogBoundary)) (ds->maskedtexturecol != nullptr || ds->bFogBoundary))
{ {
RenderDrawSegment renderer; RenderDrawSegment renderer(thread);
renderer.Render(ds, r1, r2); renderer.Render(ds, r1, r2);
} }
@ -373,7 +374,7 @@ namespace swrenderer
if (!spr->IsVoxel()) if (!spr->IsVoxel())
{ {
spr->Render(clipbot, cliptop, 0, 0); spr->Render(thread, clipbot, cliptop, 0, 0);
} }
else else
{ {
@ -406,7 +407,7 @@ namespace swrenderer
} }
int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale); int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale);
int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale); int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale);
spr->Render(cliptop, clipbot, minvoxely, maxvoxely); spr->Render(thread, cliptop, clipbot, minvoxely, maxvoxely);
} }
spr->Light.BaseColormap = colormap; spr->Light.BaseColormap = colormap;
spr->Light.ColormapNum = colormapnum; spr->Light.ColormapNum = colormapnum;

View file

@ -22,13 +22,15 @@
namespace swrenderer namespace swrenderer
{ {
class RenderThread;
class VisibleSprite class VisibleSprite
{ {
public: public:
VisibleSprite() { RenderStyle = STYLE_Normal; } VisibleSprite() { RenderStyle = STYLE_Normal; }
virtual ~VisibleSprite() { } virtual ~VisibleSprite() { }
void Render(); void Render(RenderThread *thread);
bool IsCurrentPortalUniq(int portalUniq) const { return CurrentPortalUniq == portalUniq; } bool IsCurrentPortalUniq(int portalUniq) const { return CurrentPortalUniq == portalUniq; }
const FVector3 &WorldPos() const { return gpos; } const FVector3 &WorldPos() const { return gpos; }
@ -41,7 +43,7 @@ namespace swrenderer
virtual bool IsVoxel() const { return false; } virtual bool IsVoxel() const { return false; }
virtual bool IsWallSprite() const { return false; } virtual bool IsWallSprite() const { return false; }
virtual void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) = 0; virtual void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) = 0;
FTexture *pic = nullptr; FTexture *pic = nullptr;

View file

@ -28,12 +28,6 @@
namespace swrenderer namespace swrenderer
{ {
VisibleSpriteList *VisibleSpriteList::Instance()
{
static VisibleSpriteList instance;
return &instance;
}
void VisibleSpriteList::Clear() void VisibleSpriteList::Clear()
{ {
Sprites.Clear(); Sprites.Clear();

View file

@ -21,8 +21,6 @@ namespace swrenderer
class VisibleSpriteList class VisibleSpriteList
{ {
public: public:
static VisibleSpriteList *Instance();
void Clear(); void Clear();
void PushPortal(); void PushPortal();
void PopPortal(); void PopPortal();

View file

@ -43,12 +43,13 @@
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/viewport/r_spritedrawer.h" #include "swrenderer/viewport/r_spritedrawer.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
namespace swrenderer namespace swrenderer
{ {
void RenderVoxel::Project(AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap) void RenderVoxel::Project(RenderThread *thread, AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap)
{ {
// transform the origin point // transform the origin point
double tr_x = pos.X - ViewPos.X; double tr_x = pos.X - ViewPos.X;
@ -58,7 +59,7 @@ namespace swrenderer
double tx = tr_x * ViewSin - tr_y * ViewCos; double tx = tr_x * ViewSin - tr_y * ViewCos;
// [RH] Flip for mirrors // [RH] Flip for mirrors
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP) if (renderportal->MirrorFlags & RF_XFLIP)
{ {
tx = -tx; tx = -tx;
@ -178,10 +179,10 @@ namespace swrenderer
vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
VisibleSpriteList::Instance()->Push(vis, true); thread->SpriteList->Push(vis, true);
} }
void RenderVoxel::Render(short *cliptop, short *clipbottom, int minZ, int maxZ) void RenderVoxel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ)
{ {
auto sprite = this; auto sprite = this;
auto viewport = RenderViewport::Instance(); auto viewport = RenderViewport::Instance();

View file

@ -58,13 +58,13 @@ namespace swrenderer
class RenderVoxel : public VisibleSprite class RenderVoxel : public VisibleSprite
{ {
public: public:
static void Project(AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap); static void Project(RenderThread *thread, AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap);
static void Deinit(); static void Deinit();
protected: protected:
bool IsVoxel() const override { return true; } bool IsVoxel() const override { return true; }
void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
private: private:
struct posang struct posang

View file

@ -57,12 +57,13 @@
#include "swrenderer/line/r_walldraw.h" #include "swrenderer/line/r_walldraw.h"
#include "swrenderer/viewport/r_viewport.h" #include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h" #include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer namespace swrenderer
{ {
void RenderWallSprite::Project(AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, int renderflags, int spriteshade, bool foggy, FDynamicColormap *basecolormap) void RenderWallSprite::Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, int renderflags, int spriteshade, bool foggy, FDynamicColormap *basecolormap)
{ {
FWallCoords wallc; FWallCoords wallc;
double x1, x2; double x1, x2;
@ -87,10 +88,10 @@ namespace swrenderer
right.Y = right.Y + x2 * angsin; right.Y = right.Y + x2 * angsin;
// Is it off-screen? // Is it off-screen?
if (wallc.Init(left, right, TOO_CLOSE_Z)) if (wallc.Init(thread, left, right, TOO_CLOSE_Z))
return; return;
RenderPortal *renderportal = RenderPortal::Instance(); RenderPortal *renderportal = thread->Portal.get();
if (wallc.sx1 >= renderportal->WindowRight || wallc.sx2 <= renderportal->WindowLeft) if (wallc.sx1 >= renderportal->WindowRight || wallc.sx2 <= renderportal->WindowLeft)
return; return;
@ -134,10 +135,10 @@ namespace swrenderer
vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, false, false, false); vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, false, false, false);
VisibleSpriteList::Instance()->Push(vis); thread->SpriteList->Push(vis);
} }
void RenderWallSprite::Render(short *mfloorclip, short *mceilingclip, int, int) void RenderWallSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int)
{ {
auto spr = this; auto spr = this;
@ -151,7 +152,7 @@ namespace swrenderer
return; return;
FWallTmapVals WallT; FWallTmapVals WallT;
WallT.InitFromWallCoords(&spr->wallc); WallT.InitFromWallCoords(thread, &spr->wallc);
ProjectedWallTexcoords walltexcoords; ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(spr->pic->GetWidth() << FRACBITS, x1, x2, WallT); walltexcoords.Project(spr->pic->GetWidth() << FRACBITS, x1, x2, WallT);
@ -229,7 +230,7 @@ namespace swrenderer
} }
else else
{ {
RenderTranslucentPass *translucentPass = RenderTranslucentPass::Instance(); RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
while (x < x2) while (x < x2)
{ {

View file

@ -23,11 +23,11 @@ namespace swrenderer
class RenderWallSprite : public VisibleSprite class RenderWallSprite : public VisibleSprite
{ {
public: public:
static void Project(AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, int renderflags, int spriteshade, bool foggy, FDynamicColormap *basecolormap); static void Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTextureID picnum, const DVector2 &scale, int renderflags, int spriteshade, bool foggy, FDynamicColormap *basecolormap);
protected: protected:
bool IsWallSprite() const override { return true; } bool IsWallSprite() const override { return true; }
void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override;
private: private:
static void DrawColumn(SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip); static void DrawColumn(SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);