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
swrenderer/r_swrenderer.cpp
swrenderer/r_memory.cpp
swrenderer/r_renderthread.cpp
swrenderer/drawers/r_draw.cpp
swrenderer/drawers/r_draw_pal.cpp
swrenderer/drawers/r_draw_rgba.cpp

View File

@ -49,6 +49,7 @@
#include "swrenderer/plane/r_visibleplane.h"
#include "swrenderer/plane/r_visibleplanelist.h"
#include "swrenderer/things/r_decal.h"
#include "swrenderer/r_renderthread.h"
CVAR(Bool, r_fogboundary, true, 0)
CVAR(Bool, r_drawmirrors, true, 0)
@ -56,6 +57,11 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
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)
{
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)
return;
if (WallC.Init(pt1, pt2, 32.0 / (1 << 12)))
if (WallC.Init(Thread, pt1, pt2, 32.0 / (1 << 12)))
return;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
if (WallC.sx1 >= renderportal->WindowRight || WallC.sx2 <= renderportal->WindowLeft)
return;
if (line->linedef == NULL)
{
if (RenderClipSegment::Instance()->Check(WallC.sx1, WallC.sx2))
if (Thread->ClipSegments->Check(WallC.sx1, WallC.sx2))
{
InSubsector->flags |= SSECF_DRAWN;
}
@ -107,7 +113,7 @@ namespace swrenderer
if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2))
{ // The seg is the entire wall.
WallT.InitFromWallCoords(&WallC);
WallT.InitFromWallCoords(Thread, &WallC);
}
else
{ // The seg is only part of the wall.
@ -115,10 +121,10 @@ namespace swrenderer
{
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))
{
@ -142,7 +148,7 @@ namespace swrenderer
// kg3D - its fake, no transfer_heights
if (!(clip3d->fake3D & FAKE3D_FAKEBACK))
{ // 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
@ -255,7 +261,7 @@ namespace swrenderer
// mark their subsectors as visible for automap texturing.
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;
}
@ -279,7 +285,7 @@ namespace swrenderer
}
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);
});
@ -327,10 +333,10 @@ namespace swrenderer
rw_offset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
rw_light = rw_lightleft + rw_lightstep * (start - WallC.sx1);
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
DrawSegment *draw_segment = RenderMemory::NewObject<DrawSegment>();
DrawSegmentList::Instance()->Push(draw_segment);
Thread->DrawSegments->Push(draw_segment);
draw_segment->CurrentPortalUniq = renderportal->CurrentPortalUniq;
draw_segment->sx1 = WallC.sx1;
@ -351,7 +357,7 @@ namespace swrenderer
draw_segment->bFakeBoundary = false;
draw_segment->foggy = foggy;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
if (clip3d->fake3D & FAKE3D_FAKEMASK) draw_segment->fake = 1;
else draw_segment->fake = 0;
@ -448,7 +454,7 @@ namespace swrenderer
// kg3D - backup for mid and fake walls
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);
if (sidedef->GetTexture(side_t::mid).isValid() || draw_segment->bFakeBoundary)
@ -517,7 +523,7 @@ namespace swrenderer
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)
{ // killough 4/11/98: add NULL ptr checks
ceilingplane = VisiblePlaneList::Instance()->GetRange(ceilingplane, start, stop);
ceilingplane = Thread->PlaneList->GetRange(ceilingplane, start, stop);
}
else
{
@ -539,7 +545,7 @@ namespace swrenderer
{
if (floorplane)
{ // killough 4/11/98: add NULL ptr checks
floorplane = VisiblePlaneList::Instance()->GetRange(floorplane, start, stop);
floorplane = Thread->PlaneList->GetRange(floorplane, start, stop);
}
else
{
@ -558,13 +564,13 @@ namespace swrenderer
if (((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == nullptr)
{
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)
{
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())
@ -576,12 +582,12 @@ namespace swrenderer
// [ZZ] Only if not an active mirror
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)
{
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;
@ -598,7 +604,7 @@ namespace swrenderer
linedef = curline->linedef;
// 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;
@ -686,8 +692,7 @@ namespace swrenderer
// wall but nothing to draw for it.
// Recalculate walltop so that the wall is clipped by the back sector's
// ceiling instead of the front sector's ceiling.
RenderPortal *renderportal = RenderPortal::Instance();
walltop.Project(backsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
walltop.Project(backsector->ceilingplane, &WallC, curline, Thread->Portal->MirrorFlags & RF_XFLIP);
}
// Putting sky ceilings on the front and back of a line alters the way unpegged
// positioning works.
@ -941,8 +946,8 @@ namespace swrenderer
drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
// clip wall to the floor and ceiling
auto ceilingclip = RenderOpaquePass::Instance()->ceilingclip;
auto floorclip = RenderOpaquePass::Instance()->floorclip;
auto ceilingclip = Thread->OpaquePass->ceilingclip;
auto floorclip = Thread->OpaquePass->floorclip;
for (x = x1; x < x2; ++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
if (markceiling)
@ -1046,7 +1051,7 @@ namespace swrenderer
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);
}
fillshort(ceilingclip + x1, x2 - x1, viewheight);
@ -1083,7 +1088,7 @@ namespace swrenderer
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);
}
memcpy(ceilingclip + x1, wallupper.ScreenY + x1, (x2 - x1) * sizeof(short));
@ -1123,7 +1128,7 @@ namespace swrenderer
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);
}
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
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);
tright.X = float(pt2.X * ViewSin - pt2.Y * ViewCos);
@ -1147,7 +1152,7 @@ namespace swrenderer
tleft.Y = float(pt1.X * ViewTanCos + pt1.Y * ViewTanSin);
tright.Y = float(pt2.X * ViewTanCos + pt2.Y * ViewTanSin);
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = thread->Portal.get();
auto viewport = RenderViewport::Instance();
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 *right = &wallc->tright;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP)
{
@ -1218,7 +1223,7 @@ namespace swrenderer
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
@ -1227,7 +1232,7 @@ namespace swrenderer
double fully1 = left.X * ViewTanCos + left.Y * ViewTanSin;
double fully2 = right.X * ViewTanCos + right.Y * ViewTanSin;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP)
{

View File

@ -25,6 +25,7 @@ struct FDynamicColormap;
namespace swrenderer
{
class RenderThread;
struct VisiblePlane;
struct FWallCoords
@ -35,7 +36,7 @@ namespace swrenderer
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
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
@ -43,15 +44,18 @@ namespace swrenderer
float UoverZorg, UoverZstep;
float InvZorg, InvZstep;
void InitFromWallCoords(const FWallCoords *wallc);
void InitFromLine(const DVector2 &left, const DVector2 &right);
void InitFromWallCoords(RenderThread *thread, const FWallCoords *wallc);
void InitFromLine(RenderThread *thread, const DVector2 &left, const DVector2 &right);
};
class SWRenderLine
{
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);
RenderThread *Thread = nullptr;
private:
bool RenderWallSegment(int x1, int x2);
void SetWallVariables(bool needlights);

View File

@ -29,6 +29,7 @@
#include "r_data/colormaps.h"
#include "d_net.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include "swrenderer/drawers/r_draw.h"
#include "swrenderer/scene/r_3dfloors.h"
#include "swrenderer/scene/r_opaque_pass.h"
@ -47,6 +48,11 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer
{
RenderDrawSegment::RenderDrawSegment(RenderThread *thread)
{
Thread = thread;
}
void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2)
{
auto viewport = RenderViewport::Instance();
@ -95,7 +101,7 @@ namespace swrenderer
}
// 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
@ -103,7 +109,7 @@ namespace swrenderer
rw_lightstep = ds->lightstep;
rw_light = ds->light + (x1 - ds->x1) * rw_lightstep;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->FixedLightLevel() < 0)
@ -361,7 +367,7 @@ namespace swrenderer
double 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);
}
@ -471,7 +477,7 @@ namespace swrenderer
WallC.tright.Y = ds->cy + ds->cdy;
WallT = ds->tmapvals;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
wallupper.Project(clip3d->sclipTop - ViewPos.Z, &WallC);
walllower.Project(clip3d->sclipBottom - ViewPos.Z, &WallC);
@ -492,7 +498,7 @@ namespace swrenderer
double 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);
}
@ -525,7 +531,7 @@ namespace swrenderer
floorHeight = backsector->CenterFloor();
ceilingHeight = backsector->CenterCeiling();
Clip3DFloors *clip3d = Clip3DFloors::Instance();
Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
// maybe fix clipheights
if (!(clip3d->fake3D & FAKE3D_CLIPBOTTOM)) clip3d->sclipBottom = floorHeight;
@ -906,7 +912,7 @@ namespace swrenderer
{
ProjectedWallLine most;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
most.Project(curline->frontsector->ceilingplane, &WallC, curline, renderportal->MirrorFlags & RF_XFLIP);
for (int i = x1; i < x2; ++i)
@ -931,7 +937,7 @@ namespace swrenderer
top = MAX(frontcz1, frontcz2);
bot = MIN(frontfz1, frontfz2);
Clip3DFloors *clip3d = Clip3DFloors::Instance();
Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
if (clip3d->fake3D & FAKE3D_CLIPTOP)
{
top = MIN(top, clip3d->sclipTop);

View File

@ -17,11 +17,16 @@
namespace swrenderer
{
class RenderThread;
class RenderDrawSegment
{
public:
RenderDrawSegment(RenderThread *thread);
void Render(DrawSegment *ds, int x1, int x2);
RenderThread *Thread = nullptr;
private:
void ClipMidtex(int x1, int x2);
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/line/r_walldraw.h"
#include "swrenderer/line/r_wallsetup.h"
#include "swrenderer/r_renderthread.h"
namespace swrenderer
{
@ -376,7 +377,7 @@ namespace swrenderer
assert(WallC.sx1 <= x1);
assert(WallC.sx2 >= x2);
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
// kg3D - fake floors instead of zdoom light list
for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++)
@ -520,4 +521,9 @@ namespace swrenderer
ProcessWall(walltop, wallbottom, texturemid, swall, lwall);
}
}
RenderWallPart::RenderWallPart(RenderThread *thread)
{
Thread = thread;
}
}

View File

@ -24,6 +24,7 @@ struct FDynamicColormap;
namespace swrenderer
{
class RenderThread;
struct DrawSegment;
struct FWallCoords;
class ProjectedWallLine;
@ -33,6 +34,8 @@ namespace swrenderer
class RenderWallPart
{
public:
RenderWallPart(RenderThread *thread);
void Render(
const WallDrawerArgs &drawerargs,
sector_t *frontsector,
@ -58,6 +61,8 @@ namespace swrenderer
bool foggy,
FDynamicColormap *basecolormap);
RenderThread *Thread = nullptr;
private:
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);

View File

@ -41,9 +41,15 @@
#include "swrenderer/plane/r_visibleplane.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
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)
{
if (alpha <= 0)
@ -85,7 +91,7 @@ namespace swrenderer
ystep = -sin(planeang) / viewport->FocalLengthX;
// [RH] flip for mirrors
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP)
{
xstep = -xstep;

View File

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

View File

@ -42,6 +42,7 @@
#include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include "g_levellocals.h"
CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
@ -49,6 +50,11 @@ EXTERN_CVAR(Int, r_skymode)
namespace swrenderer
{
RenderSkyPlane::RenderSkyPlane(RenderThread *thread)
{
Thread = thread;
}
void RenderSkyPlane::Render(VisiblePlane *pl)
{
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)
{
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
auto viewport = RenderViewport::Instance();
uint32_t height = frontskytex->GetHeight();

View File

@ -21,8 +21,12 @@ namespace swrenderer
class RenderSkyPlane
{
public:
RenderSkyPlane(RenderThread *thread);
void Render(VisiblePlane *pl);
RenderThread *Thread = nullptr;
private:
void DrawSky(VisiblePlane *pl);
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_light.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/plane/r_visibleplane.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#ifdef _MSC_VER
#pragma warning(disable:4244)
@ -48,6 +49,11 @@
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)
{
static const float ifloatpow2[16] =
@ -138,7 +144,7 @@ namespace swrenderer
plane_su *= 4294967296.f;
plane_sv *= 4294967296.f;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP)
{
plane_su[0] = -plane_su[0];

View File

@ -18,11 +18,16 @@
namespace swrenderer
{
class RenderThread;
class RenderSlopePlane : PlaneRenderer
{
public:
RenderSlopePlane(RenderThread *thread);
void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FTexture *texture);
RenderThread *Thread = nullptr;
private:
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)
return;
if (picnum == skyflatnum) // sky flat
{
RenderSkyPlane renderer;
RenderSkyPlane renderer(thread);
renderer.Render(this);
}
else // regular flat
@ -119,12 +119,12 @@ namespace swrenderer
if (!height.isSlope() && !tilt)
{
RenderFlatPlane renderer;
RenderFlatPlane renderer(thread);
renderer.Render(this, xscale, yscale, alpha, additive, masked, colormap, tex);
}
else
{
RenderSlopePlane renderer;
RenderSlopePlane renderer(thread);
renderer.Render(this, xscale, yscale, alpha, additive, masked, colormap, tex);
}
}

View File

@ -25,6 +25,8 @@ struct FSectorPortal;
namespace swrenderer
{
class RenderThread;
struct VisiblePlaneLight
{
ADynamicLight *lightsource;
@ -36,7 +38,7 @@ namespace swrenderer
VisiblePlane();
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

View File

@ -41,13 +41,13 @@
#include "swrenderer/plane/r_visibleplanelist.h"
#include "swrenderer/drawers/r_draw.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_renderthread.h"
namespace swrenderer
{
VisiblePlaneList *VisiblePlaneList::Instance()
VisiblePlaneList::VisiblePlaneList(RenderThread *thread)
{
static VisiblePlaneList instance;
return &instance;
Thread = thread;
}
VisiblePlaneList::VisiblePlaneList()
@ -129,7 +129,7 @@ namespace swrenderer
// kg3D - hack, store alpha in sky
// i know there is ->alpha, but this also allows to identify fake plane
// 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;
else sky = 0; // not skyflatnum so it can't be a sky
portal = nullptr;
@ -139,7 +139,7 @@ namespace swrenderer
// New visplane algorithm uses hash table -- killough
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
{
@ -190,7 +190,7 @@ namespace swrenderer
sky == check->sky &&
renderportal->CurrentPortalUniq == check->CurrentPortalUniq &&
renderportal->MirrorFlags == check->MirrorFlags &&
Clip3DFloors::Instance()->CurrentSkybox == check->CurrentSkybox &&
Thread->Clip3DFloors->CurrentSkybox == check->CurrentSkybox &&
ViewPos == check->viewpos
)
{
@ -215,7 +215,7 @@ namespace swrenderer
check->Additive = additive;
check->CurrentPortalUniq = renderportal->CurrentPortalUniq;
check->MirrorFlags = renderportal->MirrorFlags;
check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox;
check->CurrentSkybox = Thread->Clip3DFloors->CurrentSkybox;
return check;
}
@ -326,19 +326,19 @@ namespace swrenderer
int i;
int vpcount = 0;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
for (i = 0; i < MAXVISPLANES; i++)
{
for (pl = visplanes[i]; pl; pl = pl->next)
{
// 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;
// kg3D - draw only real planes now
if (pl->sky >= 0) {
vpcount++;
pl->Render(OPAQUE, false, false);
pl->Render(Thread, OPAQUE, false, false);
}
}
}
@ -353,13 +353,13 @@ namespace swrenderer
DVector3 oViewPos = ViewPos;
DAngle oViewAngle = ViewAngle;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = Thread->Portal.get();
for (i = 0; i < MAXVISPLANES; i++)
{
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;
if (pl->sky < 0 && pl->height.Zat0() == height)
@ -368,7 +368,7 @@ namespace swrenderer
ViewAngle = pl->viewangle;
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
{
class RenderThread;
struct VisiblePlane;
class VisiblePlaneList
{
public:
static VisiblePlaneList *Instance();
VisiblePlaneList(RenderThread *thread);
void Clear();
void ClearKeepFakePlanes();
@ -40,6 +41,8 @@ namespace swrenderer
int Render();
void RenderHeight(double height);
RenderThread *Thread = nullptr;
private:
VisiblePlaneList();
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();
RenderScene::Instance()->Init();
mMainThread.Scene->Init();
}
bool FSoftwareRenderer::UsesColormap() const
@ -178,7 +178,7 @@ void FSoftwareRenderer::RenderView(player_t *player)
if (r_polyrenderer)
PolyRenderer::Instance()->RenderView(player);
else
RenderScene::Instance()->RenderView(player);
mMainThread.Scene->RenderView(player);
FCanvasTextureInfo::UpdateAll();
}
@ -202,7 +202,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi
if (r_polyrenderer)
PolyRenderer::Instance()->RenderViewToCanvas(player->mo, pic, 0, 0, width, height, true);
else
RenderScene::Instance()->RenderViewToCanvas (player->mo, pic, 0, 0, width, height);
mMainThread.Scene->RenderViewToCanvas (player->mo, pic, 0, 0, width, height);
screen->GetFlashedPalette (palette);
M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch());
pic->Unlock ();
@ -215,7 +215,7 @@ void FSoftwareRenderer::DrawRemainingPlayerSprites()
{
if (!r_polyrenderer)
{
RenderPlayerSprites::Instance()->RenderRemaining();
mMainThread.PlayerSprites->RenderRemaining();
}
else
{
@ -237,12 +237,12 @@ bool FSoftwareRenderer::RequireGLNodes()
void FSoftwareRenderer::OnModeSet ()
{
RenderScene::Instance()->ScreenResized();
mMainThread.Scene->ScreenResized();
}
void FSoftwareRenderer::SetClearColor(int color)
{
RenderScene::Instance()->SetClearColor(color);
mMainThread.Scene->SetClearColor(color);
}
void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov)
@ -262,7 +262,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
if (r_polyrenderer)
PolyRenderer::Instance()->RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate);
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);
@ -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)
{
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)

View File

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

View File

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

View File

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

View File

@ -44,6 +44,7 @@
#include "swrenderer/scene/r_scene.h"
#include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_renderthread.h"
#include "r_3dfloors.h"
#include "r_portal.h"
#include "a_sharedglobal.h"
@ -67,10 +68,9 @@ EXTERN_CVAR(Bool, r_drawvoxels);
namespace swrenderer
{
RenderOpaquePass *RenderOpaquePass::Instance()
RenderOpaquePass::RenderOpaquePass(RenderThread *thread) : renderline(thread)
{
static RenderOpaquePass instance;
return &instance;
Thread = thread;
}
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;
ry2 = x2 * ViewTanCos + y2 * ViewTanSin;
if (RenderPortal::Instance()->MirrorFlags & RF_XFLIP)
if (Thread->Portal->MirrorFlags & RF_XFLIP)
{
double t = -rx1;
rx1 = -rx2;
@ -380,7 +380,7 @@ namespace swrenderer
// Find the first clippost that touches the source post
// (adjacent pixels are touching).
return RenderClipSegment::Instance()->IsVisible(sx1, sx2);
return Thread->ClipSegments->IsVisible(sx1, sx2);
}
void RenderOpaquePass::AddPolyobjs(subsector_t *sub)
@ -507,7 +507,7 @@ namespace swrenderer
(frontsector->heightsec &&
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
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),
ceilinglightlevel + R_ActualExtraLight(foggy), // killough 4/11/98
frontsector->GetAlpha(sector_t::ceiling),
@ -548,7 +548,7 @@ namespace swrenderer
(frontsector->heightsec &&
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
VisiblePlaneList::Instance()->FindPlane(frontsector->floorplane,
Thread->PlaneList->FindPlane(frontsector->floorplane,
frontsector->GetTexture(sector_t::floor),
floorlightlevel + R_ActualExtraLight(foggy), // killough 3/16/98
frontsector->GetAlpha(sector_t::floor),
@ -568,7 +568,7 @@ namespace swrenderer
backupfp = floorplane;
backupcp = ceilingplane;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
Clip3DFloors *clip3d = Thread->Clip3DFloors.get();
// first check all floors
for (int i = 0; i < (int)frontsector->e->XFloor.ffloors.Size(); i++)
@ -614,7 +614,7 @@ namespace swrenderer
}
ceilingplane = nullptr;
floorplane = VisiblePlaneList::Instance()->FindPlane(frontsector->floorplane,
floorplane = Thread->PlaneList->FindPlane(frontsector->floorplane,
frontsector->GetTexture(sector_t::floor),
floorlightlevel + R_ActualExtraLight(foggy), // killough 3/16/98
frontsector->GetAlpha(sector_t::floor),
@ -680,7 +680,7 @@ namespace swrenderer
tempsec.ceilingplane.ChangeHeight(1 / 65536.);
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),
ceilinglightlevel + R_ActualExtraLight(foggy), // killough 4/11/98
frontsector->GetAlpha(sector_t::ceiling),
@ -720,7 +720,7 @@ namespace swrenderer
int shade = LIGHT2SHADE((floorlightlevel + ceilinglightlevel) / 2 + R_ActualExtraLight(foggy));
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;
floorplane = 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++)
{
clip3d->fakeFloor = line->backsector->e->XFloor.ffloors[i];
@ -886,15 +886,15 @@ namespace swrenderer
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)
{
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
{
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] 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))
return false;

View File

@ -23,6 +23,7 @@ struct FVoxelDef;
namespace swrenderer
{
class RenderThread;
struct VisiblePlane;
// The 3072 below is just an arbitrary value picked to avoid
@ -51,7 +52,7 @@ namespace swrenderer
class RenderOpaquePass
{
public:
static RenderOpaquePass *Instance();
RenderOpaquePass(RenderThread *thread);
void ClearClip();
void RenderScene();
@ -62,6 +63,8 @@ namespace swrenderer
short floorclip[MAXWIDTH];
short ceilingclip[MAXWIDTH];
RenderThread *Thread = nullptr;
private:
void RenderBSPNode(void *node);
void RenderSubsector(subsector_t *sub);
@ -72,7 +75,7 @@ namespace swrenderer
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);
subsector_t *InSubsector = nullptr;

View File

@ -57,6 +57,7 @@
#include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
CVAR(Int, r_portal_recursions, 4, CVAR_ARCHIVE)
CVAR(Bool, r_highlight_portals, false, CVAR_ARCHIVE)
@ -67,10 +68,9 @@ CVAR(Bool, r_skyboxes, true, 0)
namespace swrenderer
{
RenderPortal *RenderPortal::Instance()
RenderPortal::RenderPortal(RenderThread *thread)
{
static RenderPortal renderportal;
return &renderportal;
Thread = thread;
}
// Draws any recorded sky boxes and then frees them.
@ -92,13 +92,13 @@ namespace swrenderer
{
numskyboxes = 0;
VisiblePlaneList *planes = VisiblePlaneList::Instance();
DrawSegmentList *drawseglist = DrawSegmentList::Instance();
VisiblePlaneList *planes = Thread->PlaneList.get();
DrawSegmentList *drawseglist = Thread->DrawSegments.get();
if (!planes->HasPortalPlanes())
return;
Clip3DFloors::Instance()->EnterSkybox();
Thread->Clip3DFloors->EnterSkybox();
CurrentPortalInSkybox = true;
int savedextralight = extralight;
@ -112,7 +112,7 @@ namespace swrenderer
{
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;
}
@ -151,7 +151,7 @@ namespace swrenderer
// not implemented yet
default:
pl->Render(OPAQUE, false, false);
pl->Render(Thread, OPAQUE, false, false);
numskyboxes--;
continue;
}
@ -165,12 +165,12 @@ namespace swrenderer
validcount++; // Make sure we see all sprites
planes->ClearKeepFakePlanes();
RenderClipSegment::Instance()->Clear(pl->left, pl->right);
Thread->ClipSegments->Clear(pl->left, pl->right);
WindowLeft = pl->left;
WindowRight = pl->right;
auto ceilingclip = RenderOpaquePass::Instance()->ceilingclip;
auto floorclip = RenderOpaquePass::Instance()->floorclip;
auto ceilingclip = Thread->OpaquePass->ceilingclip;
auto floorclip = Thread->OpaquePass->floorclip;
for (int i = pl->left; i < pl->right; i++)
{
if (pl->top[i] == 0x7fff)
@ -208,12 +208,12 @@ namespace swrenderer
drawseglist->Push(draw_segment);
drawseglist->PushPortal();
VisibleSpriteList::Instance()->PushPortal();
Thread->SpriteList->PushPortal();
viewposStack.Push(ViewPos);
visplaneStack.Push(pl);
RenderOpaquePass::Instance()->RenderScene();
Clip3DFloors::Instance()->ResetClip(); // reset clips (floor/ceiling)
Thread->OpaquePass->RenderScene();
Thread->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
planes->Render();
port->mFlags &= ~PORTSF_INSKYBOX;
@ -228,16 +228,16 @@ namespace swrenderer
// Masked textures and planes need the view coordinates restored for proper positioning.
viewposStack.Pop(ViewPos);
RenderTranslucentPass::Instance()->Render();
Thread->TranslucentPass->Render();
VisiblePlane *pl;
visplaneStack.Pop(pl);
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();
}
@ -250,9 +250,9 @@ namespace swrenderer
R_SetViewAngle();
CurrentPortalInSkybox = false;
Clip3DFloors::Instance()->LeaveSkybox();
Thread->Clip3DFloors->LeaveSkybox();
if (Clip3DFloors::Instance()->fakeActive) return;
if (Thread->Clip3DFloors->fakeActive) return;
planes->ClearPortalPlanes();
}
@ -395,8 +395,8 @@ namespace swrenderer
PortalDrawseg* prevpds = CurrentPortal;
CurrentPortal = pds;
VisiblePlaneList::Instance()->ClearKeepFakePlanes();
RenderClipSegment::Instance()->Clear(pds->x1, pds->x2);
Thread->PlaneList->ClearKeepFakePlanes();
Thread->ClipSegments->Clear(pds->x1, pds->x2);
WindowLeft = pds->x1;
WindowRight = pds->x2;
@ -411,21 +411,21 @@ namespace swrenderer
}
// 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.
// first pass, set clipping
auto ceilingclip = RenderOpaquePass::Instance()->ceilingclip;
auto floorclip = RenderOpaquePass::Instance()->floorclip;
auto ceilingclip = Thread->OpaquePass->ceilingclip;
auto floorclip = Thread->OpaquePass->floorclip;
memcpy(ceilingclip + pds->x1, &pds->ceilingclip[0], pds->len * sizeof(*ceilingclip));
memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip));
RenderOpaquePass::Instance()->RenderScene();
Clip3DFloors::Instance()->ResetClip(); // reset clips (floor/ceiling)
Thread->OpaquePass->RenderScene();
Thread->Clip3DFloors->ResetClip(); // reset clips (floor/ceiling)
if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE;
PlaneCycles.Clock();
VisiblePlaneList::Instance()->Render();
Thread->PlaneList->Render();
RenderPlanePortals();
PlaneCycles.Unclock();
@ -444,12 +444,12 @@ namespace swrenderer
NetUpdate();
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();
NetUpdate();
Clip3DFloors::Instance()->LeaveSkybox(); // pop 3D floor height map
Thread->Clip3DFloors->LeaveSkybox(); // pop 3D floor height map
CurrentPortalUniq = prevuniq2;
// 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));
}
}
/*
ADD_STAT(skyboxes)
{
FString out;
out.Format("%d skybox planes", swrenderer::RenderPortal::Instance()->numskyboxes);
return out;
}
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,8 +20,6 @@ namespace swrenderer
class RenderClipSegment
{
public:
static RenderClipSegment *Instance();
void Clear(short left, short right);
bool Clip(int x1, int x2, bool solid, VisibleSegmentCallback callback);
bool Check(int first, int last);

View File

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

View File

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

View File

@ -43,16 +43,17 @@
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/viewport/r_spritedrawer.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
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)
{
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)
// 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;
int x1, x2;
@ -150,7 +151,7 @@ namespace swrenderer
double texturemid;
FWallCoords WallC;
if (WallC.Init(decal_left, decal_right, TOO_CLOSE_Z))
if (WallC.Init(thread, decal_left, decal_right, TOO_CLOSE_Z))
return;
x1 = WallC.sx1;
@ -160,7 +161,7 @@ namespace swrenderer
return;
FWallTmapVals WallT;
WallT.InitFromWallCoords(&WallC);
WallT.InitFromWallCoords(thread, &WallC);
// Get the top and bottom clipping arrays
switch (decal->RenderFlags & RF_CLIPMASK)
@ -178,7 +179,7 @@ namespace swrenderer
else if (pass == 0)
{
mceilingclip = walltop;
mfloorclip = RenderOpaquePass::Instance()->ceilingclip;
mfloorclip = thread->OpaquePass->ceilingclip;
needrepeat = 1;
}
else
@ -194,7 +195,7 @@ namespace swrenderer
return;
}
mceilingclip = walltop;
mfloorclip = RenderOpaquePass::Instance()->ceilingclip;
mfloorclip = thread->OpaquePass->ceilingclip;
break;
case RF_CLIPMID:
@ -211,7 +212,7 @@ namespace swrenderer
{
return;
}
mceilingclip = RenderOpaquePass::Instance()->floorclip;
mceilingclip = thread->OpaquePass->floorclip;
mfloorclip = wallbottom;
break;
}
@ -302,7 +303,7 @@ namespace swrenderer
{ // calculate lighting
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;
x++;
}
@ -311,12 +312,12 @@ namespace swrenderer
// 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,
// needrepeat will be 0, and the while will fail.
mceilingclip = RenderOpaquePass::Instance()->floorclip;
mceilingclip = thread->OpaquePass->floorclip;
mfloorclip = wallbottom;
} 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();

View File

@ -25,10 +25,10 @@ namespace swrenderer
class RenderDecal
{
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:
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 DrawColumn(SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
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(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_pal.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
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 tx, ty;
@ -69,7 +70,7 @@ namespace swrenderer
int x1, x2, y1, y2;
sector_t* heightsec = NULL;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = thread->Portal.get();
// [ZZ] Particle not visible through the portal plane
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.
// Clip particles behind walls.
auto ceilingclip = RenderOpaquePass::Instance()->ceilingclip;
auto floorclip = RenderOpaquePass::Instance()->floorclip;
auto ceilingclip = thread->OpaquePass->ceilingclip;
auto floorclip = thread->OpaquePass->floorclip;
if (y1 < ceilingclip[x1]) y1 = ceilingclip[x1];
if (y1 < ceilingclip[x2 - 1]) y1 = ceilingclip[x2 - 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);
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;
@ -222,7 +223,7 @@ namespace swrenderer
if (ycount <= 0 || countbase <= 0)
return;
DrawMaskedSegsBehindParticle();
DrawMaskedSegsBehindParticle(thread);
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 fracposx = fracstepx / 2;
RenderTranslucentPass *translucentPass = RenderTranslucentPass::Instance();
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
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
// 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++)
{
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
if (ds->CurrentPortalUniq == CurrentPortalUniq)
{
RenderDrawSegment renderer;
RenderDrawSegment renderer(thread);
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
{
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:
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:
void DrawMaskedSegsBehindParticle();
void DrawMaskedSegsBehindParticle(RenderThread *thread);
fixed_t xscale = 0;
fixed_t startfrac = 0; // horizontal position of x1

View File

@ -55,6 +55,7 @@
#include "swrenderer/things/r_sprite.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include "g_levellocals.h"
EXTERN_CVAR(Bool, st_scale)
@ -65,10 +66,9 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
namespace swrenderer
{
RenderPlayerSprites *RenderPlayerSprites::Instance()
RenderPlayerSprites::RenderPlayerSprites(RenderThread *thread)
{
static RenderPlayerSprites instance;
return &instance;
Thread = thread;
}
void RenderPlayerSprites::Render()
@ -121,7 +121,7 @@ namespace swrenderer
else
{ // 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.
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
basecolormap = sec->ColorMap;

View File

@ -74,11 +74,13 @@ namespace swrenderer
class RenderPlayerSprites
{
public:
static RenderPlayerSprites *Instance();
RenderPlayerSprites(RenderThread *thread);
void Render();
void RenderRemaining();
RenderThread *Thread = nullptr;
private:
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/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
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
double tr_x = pos.X - ViewPos.X;
@ -75,7 +76,7 @@ namespace swrenderer
double tx = tr_x * ViewSin - tr_y * ViewCos;
// [RH] Flip for mirrors
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP)
{
tx = -tx;
@ -227,10 +228,10 @@ namespace swrenderer
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;
@ -285,7 +286,7 @@ namespace swrenderer
if (x < x2)
{
RenderTranslucentPass *translucentPass = RenderTranslucentPass::Instance();
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
while (x < x2)
{

View File

@ -20,10 +20,10 @@ namespace swrenderer
class RenderSprite : public VisibleSprite
{
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:
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:
fixed_t xscale = 0;

View File

@ -35,12 +35,13 @@
#include "swrenderer/scene/r_light.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer
{
void VisibleSprite::Render()
void VisibleSprite::Render(RenderThread *thread)
{
static short clipbot[MAXWIDTH];
static short cliptop[MAXWIDTH];
@ -56,7 +57,7 @@ namespace swrenderer
int colormapnum = spr->Light.ColormapNum;
F3DFloor *rover;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
Clip3DFloors *clip3d = thread->Clip3DFloors.get();
// [RH] Check for particles
if (spr->IsParticle())
@ -65,7 +66,7 @@ namespace swrenderer
if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gpos.Z <= clip3d->sclipBottom) 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;
}
@ -279,7 +280,7 @@ namespace swrenderer
// Scan drawsegs from end to start for obscuring segs.
// 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++)
{
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.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
if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here
(ds->maskedtexturecol != nullptr || ds->bFogBoundary))
{
RenderDrawSegment renderer;
RenderDrawSegment renderer(thread);
renderer.Render(ds, r1, r2);
}
@ -373,7 +374,7 @@ namespace swrenderer
if (!spr->IsVoxel())
{
spr->Render(clipbot, cliptop, 0, 0);
spr->Render(thread, clipbot, cliptop, 0, 0);
}
else
{
@ -406,7 +407,7 @@ namespace swrenderer
}
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);
spr->Render(cliptop, clipbot, minvoxely, maxvoxely);
spr->Render(thread, cliptop, clipbot, minvoxely, maxvoxely);
}
spr->Light.BaseColormap = colormap;
spr->Light.ColormapNum = colormapnum;

View File

@ -22,13 +22,15 @@
namespace swrenderer
{
class RenderThread;
class VisibleSprite
{
public:
VisibleSprite() { RenderStyle = STYLE_Normal; }
virtual ~VisibleSprite() { }
void Render();
void Render(RenderThread *thread);
bool IsCurrentPortalUniq(int portalUniq) const { return CurrentPortalUniq == portalUniq; }
const FVector3 &WorldPos() const { return gpos; }
@ -41,7 +43,7 @@ namespace swrenderer
virtual bool IsVoxel() 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;

View File

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

View File

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

View File

@ -43,12 +43,13 @@
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/viewport/r_spritedrawer.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
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
double tr_x = pos.X - ViewPos.X;
@ -58,7 +59,7 @@ namespace swrenderer
double tx = tr_x * ViewSin - tr_y * ViewCos;
// [RH] Flip for mirrors
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = thread->Portal.get();
if (renderportal->MirrorFlags & RF_XFLIP)
{
tx = -tx;
@ -178,10 +179,10 @@ namespace swrenderer
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 viewport = RenderViewport::Instance();

View File

@ -58,13 +58,13 @@ namespace swrenderer
class RenderVoxel : public VisibleSprite
{
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();
protected:
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:
struct posang

View File

@ -57,12 +57,13 @@
#include "swrenderer/line/r_walldraw.h"
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
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;
double x1, x2;
@ -87,10 +88,10 @@ namespace swrenderer
right.Y = right.Y + x2 * angsin;
// Is it off-screen?
if (wallc.Init(left, right, TOO_CLOSE_Z))
if (wallc.Init(thread, left, right, TOO_CLOSE_Z))
return;
RenderPortal *renderportal = RenderPortal::Instance();
RenderPortal *renderportal = thread->Portal.get();
if (wallc.sx1 >= renderportal->WindowRight || wallc.sx2 <= renderportal->WindowLeft)
return;
@ -134,10 +135,10 @@ namespace swrenderer
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;
@ -151,7 +152,7 @@ namespace swrenderer
return;
FWallTmapVals WallT;
WallT.InitFromWallCoords(&spr->wallc);
WallT.InitFromWallCoords(thread, &spr->wallc);
ProjectedWallTexcoords walltexcoords;
walltexcoords.Project(spr->pic->GetWidth() << FRACBITS, x1, x2, WallT);
@ -229,7 +230,7 @@ namespace swrenderer
}
else
{
RenderTranslucentPass *translucentPass = RenderTranslucentPass::Instance();
RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();
while (x < x2)
{

View File

@ -23,11 +23,11 @@ namespace swrenderer
class RenderWallSprite : public VisibleSprite
{
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:
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:
static void DrawColumn(SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);