Convert r_3dfloors to a class

This commit is contained in:
Magnus Norddahl 2017-01-04 18:54:14 +01:00
parent 28732d63d2
commit 5f8075f726
12 changed files with 404 additions and 399 deletions

View file

@ -112,7 +112,9 @@ namespace swrenderer
WallT.InitFromLine(v1->fPos() - ViewPos, v2->fPos() - ViewPos); WallT.InitFromLine(v1->fPos() - ViewPos, v2->fPos() - ViewPos);
} }
if (!(fake3D & FAKE3D_FAKEBACK)) Clip3DFloors *clip3d = Clip3DFloors::Instance();
if (!(clip3d->fake3D & FAKE3D_FAKEBACK))
{ {
backsector = line->backsector; backsector = line->backsector;
} }
@ -132,7 +134,7 @@ namespace swrenderer
else else
{ {
// kg3D - its fake, no transfer_heights // kg3D - its fake, no transfer_heights
if (!(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 = RenderBSP::Instance()->FakeFlat(backsector, &tempsec, nullptr, nullptr, curline, WallC.sx1, WallC.sx2, rw_frontcz1, rw_frontcz2); backsector = RenderBSP::Instance()->FakeFlat(backsector, &tempsec, nullptr, nullptr, curline, WallC.sx1, WallC.sx2, rw_frontcz1, rw_frontcz2);
} }
@ -143,15 +145,15 @@ namespace swrenderer
rw_backcz2 = backsector->ceilingplane.ZatPoint(line->v2); rw_backcz2 = backsector->ceilingplane.ZatPoint(line->v2);
rw_backfz2 = backsector->floorplane.ZatPoint(line->v2); rw_backfz2 = backsector->floorplane.ZatPoint(line->v2);
if (fake3D & FAKE3D_FAKEBACK) if (clip3d->fake3D & FAKE3D_FAKEBACK)
{ {
if (rw_frontfz1 >= rw_backfz1 && rw_frontfz2 >= rw_backfz2) if (rw_frontfz1 >= rw_backfz1 && rw_frontfz2 >= rw_backfz2)
{ {
fake3D |= FAKE3D_CLIPBOTFRONT; clip3d->fake3D |= FAKE3D_CLIPBOTFRONT;
} }
if (rw_frontcz1 <= rw_backcz1 && rw_frontcz2 <= rw_backcz2) if (rw_frontcz1 <= rw_backcz1 && rw_frontcz2 <= rw_backcz2)
{ {
fake3D |= FAKE3D_CLIPTOPFRONT; clip3d->fake3D |= FAKE3D_CLIPTOPFRONT;
} }
} }
@ -355,7 +357,9 @@ namespace swrenderer
draw_segment->curline = curline; draw_segment->curline = curline;
draw_segment->bFogBoundary = false; draw_segment->bFogBoundary = false;
draw_segment->bFakeBoundary = false; draw_segment->bFakeBoundary = false;
if (fake3D & 7) draw_segment->fake = 1;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
if (clip3d->fake3D & FAKE3D_FAKEMASK) draw_segment->fake = 1;
else draw_segment->fake = 0; else draw_segment->fake = 0;
draw_segment->sprtopclip = draw_segment->sprbottomclip = draw_segment->maskedtexturecol = draw_segment->bkup = draw_segment->swall = -1; draw_segment->sprtopclip = draw_segment->sprbottomclip = draw_segment->maskedtexturecol = draw_segment->bkup = draw_segment->swall = -1;
@ -551,8 +555,8 @@ namespace swrenderer
RenderWallSegmentTextures(start, stop); RenderWallSegmentTextures(start, stop);
if (fake3D & 7) { if (clip3d->fake3D & FAKE3D_FAKEMASK) {
return (fake3D & FAKE3D_FAKEMASK) == 0; return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0;
} }
// save sprite clipping info // save sprite clipping info
@ -609,7 +613,7 @@ namespace swrenderer
WallPortals.Push(pds); WallPortals.Push(pds);
} }
return (fake3D & FAKE3D_FAKEMASK) == 0; return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0;
} }
void SWRenderLine::SetWallVariables(bool needlights) void SWRenderLine::SetWallVariables(bool needlights)
@ -974,12 +978,14 @@ namespace swrenderer
} }
} }
Clip3DFloors *clip3d = Clip3DFloors::Instance();
// mark ceiling areas // mark ceiling areas
if (markceiling) if (markceiling)
{ {
for (x = x1; x < x2; ++x) for (x = x1; x < x2; ++x)
{ {
short top = (fakeFloor && fake3D & 2) ? fakeFloor->ceilingclip[x] : ceilingclip[x]; short top = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKECEILING) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x];
short bottom = MIN(walltop[x], floorclip[x]); short bottom = MIN(walltop[x], floorclip[x]);
if (top < bottom) if (top < bottom)
{ {
@ -995,7 +1001,7 @@ namespace swrenderer
for (x = x1; x < x2; ++x) for (x = x1; x < x2; ++x)
{ {
short top = MAX(wallbottom[x], ceilingclip[x]); short top = MAX(wallbottom[x], ceilingclip[x]);
short bottom = (fakeFloor && fake3D & 1) ? fakeFloor->floorclip[x] : floorclip[x]; short bottom = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKEFLOOR) ? clip3d->fakeFloor->floorclip[x] : floorclip[x];
if (top < bottom) if (top < bottom)
{ {
assert(bottom <= viewheight); assert(bottom <= viewheight);
@ -1006,11 +1012,11 @@ namespace swrenderer
} }
// kg3D - fake planes clipping // kg3D - fake planes clipping
if (fake3D & FAKE3D_REFRESHCLIP) if (clip3d->fake3D & FAKE3D_REFRESHCLIP)
{ {
if (fake3D & FAKE3D_CLIPBOTFRONT) if (clip3d->fake3D & FAKE3D_CLIPBOTFRONT)
{ {
memcpy(fakeFloor->floorclip + x1, wallbottom + x1, (x2 - x1) * sizeof(short)); memcpy(clip3d->fakeFloor->floorclip + x1, wallbottom + x1, (x2 - x1) * sizeof(short));
} }
else else
{ {
@ -1018,11 +1024,11 @@ namespace swrenderer
{ {
walllower[x] = MIN(MAX(walllower[x], ceilingclip[x]), wallbottom[x]); walllower[x] = MIN(MAX(walllower[x], ceilingclip[x]), wallbottom[x]);
} }
memcpy(fakeFloor->floorclip + x1, walllower + x1, (x2 - x1) * sizeof(short)); memcpy(clip3d->fakeFloor->floorclip + x1, walllower + x1, (x2 - x1) * sizeof(short));
} }
if (fake3D & FAKE3D_CLIPTOPFRONT) if (clip3d->fake3D & FAKE3D_CLIPTOPFRONT)
{ {
memcpy(fakeFloor->ceilingclip + x1, walltop + x1, (x2 - x1) * sizeof(short)); memcpy(clip3d->fakeFloor->ceilingclip + x1, walltop + x1, (x2 - x1) * sizeof(short));
} }
else else
{ {
@ -1030,10 +1036,10 @@ namespace swrenderer
{ {
wallupper[x] = MAX(MIN(wallupper[x], floorclip[x]), walltop[x]); wallupper[x] = MAX(MIN(wallupper[x], floorclip[x]), walltop[x]);
} }
memcpy(fakeFloor->ceilingclip + x1, wallupper + x1, (x2 - x1) * sizeof(short)); memcpy(clip3d->fakeFloor->ceilingclip + x1, wallupper + x1, (x2 - x1) * sizeof(short));
} }
} }
if (fake3D & 7) return; if (clip3d->fake3D & FAKE3D_FAKEMASK) return;
FLightNode *light_list = (curline && curline->sidedef) ? curline->sidedef->lighthead : nullptr; FLightNode *light_list = (curline && curline->sidedef) ? curline->sidedef->lighthead : nullptr;

View file

@ -577,13 +577,14 @@ namespace swrenderer
double frontfz2 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v2); double frontfz2 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v2);
double top = MAX(frontcz1, frontcz2); double top = MAX(frontcz1, frontcz2);
double bot = MIN(frontfz1, frontfz2); double bot = MIN(frontfz1, frontfz2);
if (fake3D & FAKE3D_CLIPTOP) Clip3DFloors *clip3d = Clip3DFloors::Instance();
if (clip3d->fake3D & FAKE3D_CLIPTOP)
{ {
top = MIN(top, sclipTop); top = MIN(top, clip3d->sclipTop);
} }
if (fake3D & FAKE3D_CLIPBOTTOM) if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
{ {
bot = MAX(bot, sclipBottom); bot = MAX(bot, clip3d->sclipBottom);
} }
ProcessWallNP2(frontsector, curline, WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, top, bot, wallshade, xoffset, light, lightstep, true); ProcessWallNP2(frontsector, curline, WallC, x1, x2, uwal, dwal, swal, lwal, yrepeat, top, bot, wallshade, xoffset, light, lightstep, true);
} }

View file

@ -241,7 +241,8 @@ 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
if (fake3D & (FAKE3D_FAKEFLOOR | FAKE3D_FAKECEILING)) sky = 0x80000000 | fakeAlpha; Clip3DFloors *clip3d = Clip3DFloors::Instance();
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;
alpha = OPAQUE; alpha = OPAQUE;
@ -299,7 +300,7 @@ namespace swrenderer
sky == check->sky && sky == check->sky &&
CurrentPortalUniq == check->CurrentPortalUniq && CurrentPortalUniq == check->CurrentPortalUniq &&
MirrorFlags == check->MirrorFlags && MirrorFlags == check->MirrorFlags &&
CurrentSkybox == check->CurrentSkybox && Clip3DFloors::Instance()->CurrentSkybox == check->CurrentSkybox &&
ViewPos == check->viewpos ViewPos == check->viewpos
) )
{ {
@ -326,7 +327,7 @@ namespace swrenderer
check->Additive = additive; check->Additive = additive;
check->CurrentPortalUniq = CurrentPortalUniq; check->CurrentPortalUniq = CurrentPortalUniq;
check->MirrorFlags = MirrorFlags; check->MirrorFlags = MirrorFlags;
check->CurrentSkybox = CurrentSkybox; check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox;
fillshort(check->top, viewwidth, 0x7fff); fillshort(check->top, viewwidth, 0x7fff);
@ -426,7 +427,7 @@ namespace swrenderer
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 != CurrentPortalUniq || pl->CurrentSkybox != CurrentSkybox) if (pl->CurrentPortalUniq != CurrentPortalUniq || pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox)
continue; continue;
// kg3D - draw only real planes now // kg3D - draw only real planes now
if (pl->sky >= 0) { if (pl->sky >= 0) {
@ -452,7 +453,7 @@ namespace swrenderer
{ {
for (pl = visplanes[i]; pl; pl = pl->next) for (pl = visplanes[i]; pl; pl = pl->next)
{ {
if (pl->CurrentSkybox != CurrentSkybox || pl->CurrentPortalUniq != CurrentPortalUniq) if (pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox || pl->CurrentPortalUniq != CurrentPortalUniq)
continue; continue;
if (pl->sky < 0 && pl->height.Zat0() == height) if (pl->sky < 0 && pl->height.Zat0() == height)

View file

@ -390,7 +390,7 @@ static void R_ShutdownRenderer()
{ {
R_DeinitSprites(); R_DeinitSprites();
R_DeinitPlanes(); R_DeinitPlanes();
fakeActive = 0; Clip3DFloors::Instance()->Cleanup();
// Free openings // Free openings
if (openings != NULL) if (openings != NULL)
{ {
@ -540,8 +540,9 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
MaskedCycles.Reset(); MaskedCycles.Reset();
WallScanCycles.Reset(); WallScanCycles.Reset();
fakeActive = 0; // kg3D - reset fake floor indicator Clip3DFloors *clip3d = Clip3DFloors::Instance();
R_3D_ResetClip(); // reset clips (floor/ceiling) clip3d->fakeActive = false; // kg3D - reset fake floor indicator
clip3d->ResetClip(); // reset clips (floor/ceiling)
R_SetupBuffer (); R_SetupBuffer ();
R_SetupFrame (actor); R_SetupFrame (actor);
@ -585,7 +586,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
// 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();
RenderBSP::Instance()->RenderScene(); RenderBSP::Instance()->RenderScene();
R_3D_ResetClip(); // reset clips (floor/ceiling) Clip3DFloors::Instance()->ResetClip(); // reset clips (floor/ceiling)
camera->renderflags = savedflags; camera->renderflags = savedflags;
WallCycles.Unclock(); WallCycles.Unclock();

View file

@ -345,15 +345,7 @@ void FSoftwareRenderer::OnModeSet ()
void FSoftwareRenderer::ErrorCleanup () void FSoftwareRenderer::ErrorCleanup ()
{ {
fakeActive = 0; Clip3DFloors::Instance()->Cleanup();
fake3D = 0;
while (CurrentSkybox)
{
R_3D_DeleteHeights();
R_3D_LeaveSkybox();
}
R_3D_ResetClip();
R_3D_DeleteHeights();
} }
//=========================================================================== //===========================================================================

View file

@ -18,118 +18,125 @@ CVAR(Int, r_3dfloors, true, 0);
namespace swrenderer namespace swrenderer
{ {
Clip3DFloors *Clip3DFloors::Instance()
{
static Clip3DFloors clip;
return &clip;
}
// external variables void Clip3DFloors::Cleanup()
int fake3D; {
F3DFloor *fakeFloor; fakeActive = false;
fixed_t fakeHeight; fake3D = 0;
fixed_t fakeAlpha; while (CurrentSkybox)
int fakeActive = 0; {
double sclipBottom; DeleteHeights();
double sclipTop; LeaveSkybox();
HeightLevel *height_top = NULL; }
HeightLevel *height_cur = NULL; ResetClip();
int CurrentMirror = 0; DeleteHeights();
int CurrentSkybox = 0; }
// private variables void Clip3DFloors::DeleteHeights()
int height_max = -1; {
TArray<HeightStack> toplist;
ClipStack *clip_top = NULL;
ClipStack *clip_cur = NULL;
void R_3D_DeleteHeights()
{
height_cur = height_top; height_cur = height_top;
while(height_cur) { while (height_cur)
{
height_top = height_cur; height_top = height_cur;
height_cur = height_cur->next; height_cur = height_cur->next;
M_Free(height_top); M_Free(height_top);
} }
height_max = -1; height_max = -1;
height_top = height_cur = NULL; height_top = height_cur = nullptr;
} }
void R_3D_AddHeight(secplane_t *add, sector_t *sec) void Clip3DFloors::AddHeight(secplane_t *add, sector_t *sec)
{ {
HeightLevel *near; HeightLevel *near;
HeightLevel *curr; HeightLevel *curr;
double height = add->ZatPoint(ViewPos); double height = add->ZatPoint(ViewPos);
if(height >= sec->CenterCeiling()) return; if (height >= sec->CenterCeiling()) return;
if(height <= sec->CenterFloor()) return; if (height <= sec->CenterFloor()) return;
fakeActive = 1; fakeActive = true;
if(height_max >= 0) { if (height_max >= 0)
{
near = height_top; near = height_top;
while(near && near->height < height) near = near->next; while (near && near->height < height) near = near->next;
if(near) { if (near)
if(near->height == height) return; {
if (near->height == height) return;
curr = (HeightLevel*)M_Malloc(sizeof(HeightLevel)); curr = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
curr->height = height; curr->height = height;
curr->prev = near->prev; curr->prev = near->prev;
curr->next = near; curr->next = near;
if(near->prev) near->prev->next = curr; if (near->prev) near->prev->next = curr;
else height_top = curr; else height_top = curr;
near->prev = curr; near->prev = curr;
} else { }
else
{
curr = (HeightLevel*)M_Malloc(sizeof(HeightLevel)); curr = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
curr->height = height; curr->height = height;
curr->prev = height_cur; curr->prev = height_cur;
curr->next = NULL; curr->next = nullptr;
height_cur->next = curr; height_cur->next = curr;
height_cur = curr; height_cur = curr;
} }
} else { }
else
{
height_top = height_cur = (HeightLevel*)M_Malloc(sizeof(HeightLevel)); height_top = height_cur = (HeightLevel*)M_Malloc(sizeof(HeightLevel));
height_top->height = height; height_top->height = height;
height_top->prev = NULL; height_top->prev = nullptr;
height_top->next = NULL; height_top->next = nullptr;
} }
height_max++; height_max++;
} }
void R_3D_NewClip() void Clip3DFloors::NewClip()
{ {
ClipStack *curr; ClipStack *curr;
// extern short floorclip[MAXWIDTH];
// extern short ceilingclip[MAXWIDTH];
curr = (ClipStack*)M_Malloc(sizeof(ClipStack)); curr = (ClipStack*)M_Malloc(sizeof(ClipStack));
curr->next = 0; curr->next = 0;
memcpy(curr->floorclip, RenderBSP::Instance()->floorclip, sizeof(short) * MAXWIDTH); memcpy(curr->floorclip, RenderBSP::Instance()->floorclip, sizeof(short) * MAXWIDTH);
memcpy(curr->ceilingclip, RenderBSP::Instance()->ceilingclip, sizeof(short) * MAXWIDTH); memcpy(curr->ceilingclip, RenderBSP::Instance()->ceilingclip, sizeof(short) * MAXWIDTH);
curr->ffloor = fakeFloor; curr->ffloor = fakeFloor;
assert(fakeFloor->floorclip == NULL); assert(fakeFloor->floorclip == nullptr);
assert(fakeFloor->ceilingclip == NULL); assert(fakeFloor->ceilingclip == nullptr);
fakeFloor->floorclip = curr->floorclip; fakeFloor->floorclip = curr->floorclip;
fakeFloor->ceilingclip = curr->ceilingclip; fakeFloor->ceilingclip = curr->ceilingclip;
if(clip_top) { if (clip_top)
{
clip_cur->next = curr; clip_cur->next = curr;
clip_cur = curr; clip_cur = curr;
} else { }
else
{
clip_top = clip_cur = curr; clip_top = clip_cur = curr;
} }
} }
void R_3D_ResetClip() void Clip3DFloors::ResetClip()
{
clip_cur = clip_top;
while(clip_cur)
{ {
assert(clip_cur->ffloor->floorclip != NULL); clip_cur = clip_top;
assert(clip_cur->ffloor->ceilingclip != NULL); while (clip_cur)
clip_cur->ffloor->ceilingclip = clip_cur->ffloor->floorclip = NULL; {
assert(clip_cur->ffloor->floorclip != nullptr);
assert(clip_cur->ffloor->ceilingclip != nullptr);
clip_cur->ffloor->ceilingclip = clip_cur->ffloor->floorclip = nullptr;
clip_top = clip_cur; clip_top = clip_cur;
clip_cur = clip_cur->next; clip_cur = clip_cur->next;
M_Free(clip_top); M_Free(clip_top);
} }
clip_cur = clip_top = NULL; clip_cur = clip_top = nullptr;
} }
void R_3D_EnterSkybox() void Clip3DFloors::EnterSkybox()
{ {
HeightStack current; HeightStack current;
current.height_top = height_top; current.height_top = height_top;
@ -138,19 +145,19 @@ void R_3D_EnterSkybox()
toplist.Push(current); toplist.Push(current);
height_top = NULL; height_top = nullptr;
height_cur = NULL; height_cur = nullptr;
height_max = -1; height_max = -1;
CurrentSkybox++; CurrentSkybox++;
} }
void R_3D_LeaveSkybox() void Clip3DFloors::LeaveSkybox()
{ {
HeightStack current; HeightStack current;
current.height_top = NULL; current.height_top = nullptr;
current.height_cur = NULL; current.height_cur = nullptr;
current.height_max = -1; current.height_max = -1;
toplist.Pop(current); toplist.Pop(current);
@ -160,6 +167,5 @@ void R_3D_LeaveSkybox()
height_max = current.height_max; height_max = current.height_max;
CurrentSkybox--; CurrentSkybox--;
} }
} }

View file

@ -1,5 +1,5 @@
#ifndef SOFT_FAKE3D_H
#define SOFT_FAKE3D_H #pragma once
#include "p_3dfloors.h" #include "p_3dfloors.h"
@ -7,70 +7,77 @@ EXTERN_CVAR(Int, r_3dfloors);
namespace swrenderer namespace swrenderer
{ {
struct HeightLevel
// special types {
struct HeightLevel
{
double height; double height;
struct HeightLevel *prev; struct HeightLevel *prev;
struct HeightLevel *next; struct HeightLevel *next;
}; };
struct HeightStack struct HeightStack
{ {
HeightLevel *height_top; HeightLevel *height_top;
HeightLevel *height_cur; HeightLevel *height_cur;
int height_max; int height_max;
}; };
struct ClipStack struct ClipStack
{ {
short floorclip[MAXWIDTH]; short floorclip[MAXWIDTH];
short ceilingclip[MAXWIDTH]; short ceilingclip[MAXWIDTH];
F3DFloor *ffloor; F3DFloor *ffloor;
ClipStack *next; ClipStack *next;
}; };
// external varialbes enum Fake3DOpaque
{
// fake3D flags:
enum
{
// BSP stage: // BSP stage:
FAKE3D_FAKEFLOOR = 1, // fake floor, mark seg as FAKE FAKE3D_FAKEFLOOR = 1, // fake floor, mark seg as FAKE
FAKE3D_FAKECEILING = 2, // fake ceiling, mark seg as FAKE FAKE3D_FAKECEILING = 2, // fake ceiling, mark seg as FAKE
FAKE3D_FAKEBACK = 4, // R_AddLine with fake backsector, mark seg as FAKE FAKE3D_FAKEBACK = 4, // RenderLine with fake backsector, mark seg as FAKE
FAKE3D_FAKEMASK = 7, FAKE3D_FAKEMASK = 7,
FAKE3D_CLIPBOTFRONT = 8, // use front sector clipping info (bottom) FAKE3D_CLIPBOTFRONT = 8, // use front sector clipping info (bottom)
FAKE3D_CLIPTOPFRONT = 16, // use front sector clipping info (top) FAKE3D_CLIPTOPFRONT = 16, // use front sector clipping info (top)
};
enum Fake3DTranslucent
{
// sorting stage: // sorting stage:
FAKE3D_CLIPBOTTOM = 1, // clip bottom FAKE3D_CLIPBOTTOM = 1, // clip bottom
FAKE3D_CLIPTOP = 2, // clip top FAKE3D_CLIPTOP = 2, // clip top
FAKE3D_REFRESHCLIP = 4, // refresh clip info FAKE3D_REFRESHCLIP = 4, // refresh clip info
FAKE3D_DOWN2UP = 8, // rendering from down to up (floors) FAKE3D_DOWN2UP = 8, // rendering from down to up (floors)
}; };
extern int fake3D; class Clip3DFloors
extern F3DFloor *fakeFloor; {
extern fixed_t fakeAlpha; public:
extern int fakeActive; static Clip3DFloors *Instance();
extern double sclipBottom;
extern double sclipTop;
extern HeightLevel *height_top;
extern HeightLevel *height_cur;
extern int CurrentMirror;
extern int CurrentSkybox;
// functions void Cleanup();
void R_3D_DeleteHeights();
void R_3D_AddHeight(secplane_t *add, sector_t *sec);
void R_3D_NewClip();
void R_3D_ResetClip();
void R_3D_EnterSkybox();
void R_3D_LeaveSkybox();
void DeleteHeights();
void AddHeight(secplane_t *add, sector_t *sec);
void NewClip();
void ResetClip();
void EnterSkybox();
void LeaveSkybox();
int fake3D = 0;
F3DFloor *fakeFloor = nullptr;
fixed_t fakeAlpha = 0;
bool fakeActive = false;
double sclipBottom = 0;
double sclipTop = 0;
HeightLevel *height_top = nullptr;
HeightLevel *height_cur = nullptr;
int CurrentSkybox = 0;
private:
int height_max = -1;
TArray<HeightStack> toplist;
ClipStack *clip_top = nullptr;
ClipStack *clip_cur = nullptr;
};
} }
#endif

View file

@ -554,35 +554,38 @@ namespace swrenderer
{ {
backupfp = floorplane; backupfp = floorplane;
backupcp = ceilingplane; backupcp = ceilingplane;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
// 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++)
{ {
fakeFloor = frontsector->e->XFloor.ffloors[i]; clip3d->fakeFloor = frontsector->e->XFloor.ffloors[i];
if (!(fakeFloor->flags & FF_EXISTS)) continue; if (!(clip3d->fakeFloor->flags & FF_EXISTS)) continue;
if (!fakeFloor->model) continue; if (!clip3d->fakeFloor->model) continue;
if (fakeFloor->bottom.plane->isSlope()) continue; if (clip3d->fakeFloor->bottom.plane->isSlope()) continue;
if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES))) if (!(clip3d->fakeFloor->flags & FF_NOSHADE) || (clip3d->fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES)))
{ {
R_3D_AddHeight(fakeFloor->top.plane, frontsector); clip3d->AddHeight(clip3d->fakeFloor->top.plane, frontsector);
} }
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue; if (!(clip3d->fakeFloor->flags & FF_RENDERPLANES)) continue;
if (fakeFloor->alpha == 0) continue; if (clip3d->fakeFloor->alpha == 0) continue;
if (fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR) continue; if (clip3d->fakeFloor->flags & FF_THISINSIDE && clip3d->fakeFloor->flags & FF_INVERTSECTOR) continue;
fakeAlpha = MIN<fixed_t>(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE); clip3d->fakeAlpha = MIN<fixed_t>(Scale(clip3d->fakeFloor->alpha, OPAQUE, 255), OPAQUE);
if (fakeFloor->validcount != validcount) if (clip3d->fakeFloor->validcount != validcount)
{ {
fakeFloor->validcount = validcount; clip3d->fakeFloor->validcount = validcount;
R_3D_NewClip(); clip3d->NewClip();
} }
double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot); double fakeHeight = clip3d->fakeFloor->top.plane->ZatPoint(frontsector->centerspot);
if (fakeHeight < ViewPos.Z && if (fakeHeight < ViewPos.Z &&
fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot)) fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot))
{ {
fake3D = FAKE3D_FAKEFLOOR; clip3d->fake3D = FAKE3D_FAKEFLOOR;
tempsec = *fakeFloor->model; tempsec = *clip3d->fakeFloor->model;
tempsec.floorplane = *fakeFloor->top.plane; tempsec.floorplane = *clip3d->fakeFloor->top.plane;
tempsec.ceilingplane = *fakeFloor->bottom.plane; tempsec.ceilingplane = *clip3d->fakeFloor->bottom.plane;
if (!(fakeFloor->flags & FF_THISINSIDE) && !(fakeFloor->flags & FF_INVERTSECTOR)) if (!(clip3d->fakeFloor->flags & FF_THISINSIDE) && !(clip3d->fakeFloor->flags & FF_INVERTSECTOR))
{ {
tempsec.SetTexture(sector_t::floor, tempsec.GetTexture(sector_t::ceiling)); tempsec.SetTexture(sector_t::floor, tempsec.GetTexture(sector_t::ceiling));
position = sector_t::ceiling; position = sector_t::ceiling;
@ -602,7 +605,7 @@ namespace swrenderer
frontsector->GetTexture(sector_t::floor), frontsector->GetTexture(sector_t::floor),
floorlightlevel + r_actualextralight, // killough 3/16/98 floorlightlevel + r_actualextralight, // killough 3/16/98
frontsector->GetAlpha(sector_t::floor), frontsector->GetAlpha(sector_t::floor),
!!(fakeFloor->flags & FF_ADDITIVETRANS), !!(clip3d->fakeFloor->flags & FF_ADDITIVETRANS),
frontsector->planes[position].xform, frontsector->planes[position].xform,
frontsector->sky, frontsector->sky,
NULL); NULL);
@ -611,41 +614,41 @@ namespace swrenderer
R_AddPlaneLights(floorplane, frontsector->lighthead); R_AddPlaneLights(floorplane, frontsector->lighthead);
FakeDrawLoop(sub, floorplane, ceilingplane); FakeDrawLoop(sub, floorplane, ceilingplane);
fake3D = 0; clip3d->fake3D = 0;
frontsector = sub->sector; frontsector = sub->sector;
} }
} }
// and now ceilings // and now ceilings
for (unsigned int i = 0; i < frontsector->e->XFloor.ffloors.Size(); i++) for (unsigned int i = 0; i < frontsector->e->XFloor.ffloors.Size(); i++)
{ {
fakeFloor = frontsector->e->XFloor.ffloors[i]; clip3d->fakeFloor = frontsector->e->XFloor.ffloors[i];
if (!(fakeFloor->flags & FF_EXISTS)) continue; if (!(clip3d->fakeFloor->flags & FF_EXISTS)) continue;
if (!fakeFloor->model) continue; if (!clip3d->fakeFloor->model) continue;
if (fakeFloor->top.plane->isSlope()) continue; if (clip3d->fakeFloor->top.plane->isSlope()) continue;
if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES))) if (!(clip3d->fakeFloor->flags & FF_NOSHADE) || (clip3d->fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES)))
{ {
R_3D_AddHeight(fakeFloor->bottom.plane, frontsector); clip3d->AddHeight(clip3d->fakeFloor->bottom.plane, frontsector);
} }
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue; if (!(clip3d->fakeFloor->flags & FF_RENDERPLANES)) continue;
if (fakeFloor->alpha == 0) continue; if (clip3d->fakeFloor->alpha == 0) continue;
if (!(fakeFloor->flags & FF_THISINSIDE) && (fakeFloor->flags & (FF_SWIMMABLE | FF_INVERTSECTOR)) == (FF_SWIMMABLE | FF_INVERTSECTOR)) continue; if (!(clip3d->fakeFloor->flags & FF_THISINSIDE) && (clip3d->fakeFloor->flags & (FF_SWIMMABLE | FF_INVERTSECTOR)) == (FF_SWIMMABLE | FF_INVERTSECTOR)) continue;
fakeAlpha = MIN<fixed_t>(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE); clip3d->fakeAlpha = MIN<fixed_t>(Scale(clip3d->fakeFloor->alpha, OPAQUE, 255), OPAQUE);
if (fakeFloor->validcount != validcount) if (clip3d->fakeFloor->validcount != validcount)
{ {
fakeFloor->validcount = validcount; clip3d->fakeFloor->validcount = validcount;
R_3D_NewClip(); clip3d->NewClip();
} }
double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot); double fakeHeight = clip3d->fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot);
if (fakeHeight > ViewPos.Z && if (fakeHeight > ViewPos.Z &&
fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot)) fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot))
{ {
fake3D = FAKE3D_FAKECEILING; clip3d->fake3D = FAKE3D_FAKECEILING;
tempsec = *fakeFloor->model; tempsec = *clip3d->fakeFloor->model;
tempsec.floorplane = *fakeFloor->top.plane; tempsec.floorplane = *clip3d->fakeFloor->top.plane;
tempsec.ceilingplane = *fakeFloor->bottom.plane; tempsec.ceilingplane = *clip3d->fakeFloor->bottom.plane;
if ((!(fakeFloor->flags & FF_THISINSIDE) && !(fakeFloor->flags & FF_INVERTSECTOR)) || if ((!(clip3d->fakeFloor->flags & FF_THISINSIDE) && !(clip3d->fakeFloor->flags & FF_INVERTSECTOR)) ||
(fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR)) (clip3d->fakeFloor->flags & FF_THISINSIDE && clip3d->fakeFloor->flags & FF_INVERTSECTOR))
{ {
tempsec.SetTexture(sector_t::ceiling, tempsec.GetTexture(sector_t::floor)); tempsec.SetTexture(sector_t::ceiling, tempsec.GetTexture(sector_t::floor));
position = sector_t::floor; position = sector_t::floor;
@ -667,7 +670,7 @@ namespace swrenderer
frontsector->GetTexture(sector_t::ceiling), frontsector->GetTexture(sector_t::ceiling),
ceilinglightlevel + r_actualextralight, // killough 4/11/98 ceilinglightlevel + r_actualextralight, // killough 4/11/98
frontsector->GetAlpha(sector_t::ceiling), frontsector->GetAlpha(sector_t::ceiling),
!!(fakeFloor->flags & FF_ADDITIVETRANS), !!(clip3d->fakeFloor->flags & FF_ADDITIVETRANS),
frontsector->planes[position].xform, frontsector->planes[position].xform,
frontsector->sky, frontsector->sky,
NULL); NULL);
@ -676,11 +679,11 @@ namespace swrenderer
R_AddPlaneLights(ceilingplane, frontsector->lighthead); R_AddPlaneLights(ceilingplane, frontsector->lighthead);
FakeDrawLoop(sub, floorplane, ceilingplane); FakeDrawLoop(sub, floorplane, ceilingplane);
fake3D = 0; clip3d->fake3D = 0;
frontsector = sub->sector; frontsector = sub->sector;
} }
} }
fakeFloor = NULL; clip3d->fakeFloor = NULL;
floorplane = backupfp; floorplane = backupfp;
ceilingplane = backupcp; ceilingplane = backupcp;
} }
@ -720,25 +723,26 @@ namespace swrenderer
backupcp = ceilingplane; backupcp = ceilingplane;
floorplane = NULL; floorplane = NULL;
ceilingplane = NULL; ceilingplane = NULL;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
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++)
{ {
fakeFloor = line->backsector->e->XFloor.ffloors[i]; clip3d->fakeFloor = line->backsector->e->XFloor.ffloors[i];
if (!(fakeFloor->flags & FF_EXISTS)) continue; if (!(clip3d->fakeFloor->flags & FF_EXISTS)) continue;
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue; if (!(clip3d->fakeFloor->flags & FF_RENDERPLANES)) continue;
if (!fakeFloor->model) continue; if (!clip3d->fakeFloor->model) continue;
fake3D = FAKE3D_FAKEBACK; clip3d->fake3D = FAKE3D_FAKEBACK;
tempsec = *fakeFloor->model; tempsec = *clip3d->fakeFloor->model;
tempsec.floorplane = *fakeFloor->top.plane; tempsec.floorplane = *clip3d->fakeFloor->top.plane;
tempsec.ceilingplane = *fakeFloor->bottom.plane; tempsec.ceilingplane = *clip3d->fakeFloor->bottom.plane;
if (fakeFloor->validcount != validcount) if (clip3d->fakeFloor->validcount != validcount)
{ {
fakeFloor->validcount = validcount; clip3d->fakeFloor->validcount = validcount;
R_3D_NewClip(); clip3d->NewClip();
} }
renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane); // fake renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane); // fake
} }
fakeFloor = NULL; clip3d->fakeFloor = NULL;
fake3D = 0; clip3d->fake3D = 0;
floorplane = backupfp; floorplane = backupfp;
ceilingplane = backupcp; ceilingplane = backupcp;
} }

View file

@ -17,6 +17,7 @@
#include <stddef.h> #include <stddef.h>
#include "r_defs.h" #include "r_defs.h"
#include "swrenderer/line/r_line.h" #include "swrenderer/line/r_line.h"
#include "swrenderer/scene/r_3dfloors.h"
namespace swrenderer namespace swrenderer
{ {

View file

@ -117,7 +117,7 @@ namespace swrenderer
if (visplanes[MAXVISPLANES] == nullptr) if (visplanes[MAXVISPLANES] == nullptr)
return; return;
R_3D_EnterSkybox(); Clip3DFloors::Instance()->EnterSkybox();
CurrentPortalInSkybox = true; CurrentPortalInSkybox = true;
int savedextralight = extralight; int savedextralight = extralight;
@ -252,7 +252,7 @@ namespace swrenderer
visplaneStack.Push(pl); visplaneStack.Push(pl);
RenderBSP::Instance()->RenderScene(); RenderBSP::Instance()->RenderScene();
R_3D_ResetClip(); // reset clips (floor/ceiling) Clip3DFloors::Instance()->ResetClip(); // reset clips (floor/ceiling)
R_DrawPlanes(); R_DrawPlanes();
port->mFlags &= ~PORTSF_INSKYBOX; port->mFlags &= ~PORTSF_INSKYBOX;
@ -303,9 +303,9 @@ namespace swrenderer
R_SetViewAngle(); R_SetViewAngle();
CurrentPortalInSkybox = false; CurrentPortalInSkybox = false;
R_3D_LeaveSkybox(); Clip3DFloors::Instance()->LeaveSkybox();
if (fakeActive) return; if (Clip3DFloors::Instance()->fakeActive) return;
for (*freehead = visplanes[MAXVISPLANES], visplanes[MAXVISPLANES] = nullptr; *freehead; ) for (*freehead = visplanes[MAXVISPLANES], visplanes[MAXVISPLANES] = nullptr; *freehead; )
freehead = &(*freehead)->next; freehead = &(*freehead)->next;
@ -463,7 +463,7 @@ namespace swrenderer
} }
// some portals have height differences, account for this here // some portals have height differences, account for this here
R_3D_EnterSkybox(); // push 3D floor height map Clip3DFloors::Instance()->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
@ -473,7 +473,7 @@ namespace swrenderer
memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip)); memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip));
RenderBSP::Instance()->RenderScene(); RenderBSP::Instance()->RenderScene();
R_3D_ResetClip(); // reset clips (floor/ceiling) Clip3DFloors::Instance()->ResetClip(); // reset clips (floor/ceiling)
if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE; if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE;
PlaneCycles.Clock(); PlaneCycles.Clock();
@ -501,7 +501,7 @@ namespace swrenderer
NetUpdate(); NetUpdate();
R_3D_LeaveSkybox(); // pop 3D floor height map Clip3DFloors::Instance()->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

View file

@ -1315,12 +1315,14 @@ void R_DrawSprite (vissprite_t *spr)
F3DFloor *rover; F3DFloor *rover;
FDynamicColormap *mybasecolormap; FDynamicColormap *mybasecolormap;
Clip3DFloors *clip3d = Clip3DFloors::Instance();
// [RH] Check for particles // [RH] Check for particles
if (!spr->bIsVoxel && spr->pic == NULL) if (!spr->bIsVoxel && spr->pic == NULL)
{ {
// kg3D - reject invisible parts // kg3D - reject invisible parts
if ((fake3D & FAKE3D_CLIPBOTTOM) && spr->gpos.Z <= sclipBottom) return; if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gpos.Z <= clip3d->sclipBottom) return;
if ((fake3D & FAKE3D_CLIPTOP) && spr->gpos.Z >= sclipTop) return; if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gpos.Z >= clip3d->sclipTop) return;
R_DrawParticle (spr); R_DrawParticle (spr);
return; return;
} }
@ -1337,25 +1339,25 @@ void R_DrawSprite (vissprite_t *spr)
return; return;
// kg3D - reject invisible parts // kg3D - reject invisible parts
if ((fake3D & FAKE3D_CLIPBOTTOM) && spr->gzt <= sclipBottom) return; if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gzt <= clip3d->sclipBottom) return;
if ((fake3D & FAKE3D_CLIPTOP) && spr->gzb >= sclipTop) return; if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gzb >= clip3d->sclipTop) return;
// kg3D - correct colors now // kg3D - correct colors now
if (!fixedcolormap && fixedlightlev < 0 && spr->sector->e && spr->sector->e->XFloor.lightlist.Size()) if (!fixedcolormap && fixedlightlev < 0 && spr->sector->e && spr->sector->e->XFloor.lightlist.Size())
{ {
if (!(fake3D & FAKE3D_CLIPTOP)) if (!(clip3d->fake3D & FAKE3D_CLIPTOP))
{ {
sclipTop = spr->sector->ceilingplane.ZatPoint(ViewPos); clip3d->sclipTop = spr->sector->ceilingplane.ZatPoint(ViewPos);
} }
sector_t *sec = NULL; sector_t *sec = NULL;
for (i = spr->sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) for (i = spr->sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
{ {
if (sclipTop <= spr->sector->e->XFloor.lightlist[i].plane.Zat0()) if (clip3d->sclipTop <= spr->sector->e->XFloor.lightlist[i].plane.Zat0())
{ {
rover = spr->sector->e->XFloor.lightlist[i].caster; rover = spr->sector->e->XFloor.lightlist[i].caster;
if (rover) if (rover)
{ {
if (rover->flags & FF_DOUBLESHADOW && sclipTop <= rover->bottom.plane->Zat0()) if (rover->flags & FF_DOUBLESHADOW && clip3d->sclipTop <= rover->bottom.plane->Zat0())
{ {
break; break;
} }
@ -1501,15 +1503,15 @@ void R_DrawSprite (vissprite_t *spr)
} }
} }
if (fake3D & FAKE3D_CLIPBOTTOM) if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
{ {
if (!spr->bIsVoxel) if (!spr->bIsVoxel)
{ {
double hz = sclipBottom; double hz = clip3d->sclipBottom;
if (spr->fakefloor) if (spr->fakefloor)
{ {
double floorz = spr->fakefloor->top.plane->Zat0(); double floorz = spr->fakefloor->top.plane->Zat0();
if (ViewPos.Z > floorz && floorz == sclipBottom ) if (ViewPos.Z > floorz && floorz == clip3d->sclipBottom )
{ {
hz = spr->fakefloor->bottom.plane->Zat0(); hz = spr->fakefloor->bottom.plane->Zat0();
} }
@ -1520,17 +1522,17 @@ void R_DrawSprite (vissprite_t *spr)
botclip = MAX<short>(0, h); botclip = MAX<short>(0, h);
} }
} }
hzb = MAX(hzb, sclipBottom); hzb = MAX(hzb, clip3d->sclipBottom);
} }
if (fake3D & FAKE3D_CLIPTOP) if (clip3d->fake3D & FAKE3D_CLIPTOP)
{ {
if (!spr->bIsVoxel) if (!spr->bIsVoxel)
{ {
double hz = sclipTop; double hz = clip3d->sclipTop;
if (spr->fakeceiling != NULL) if (spr->fakeceiling != NULL)
{ {
double ceilingZ = spr->fakeceiling->bottom.plane->Zat0(); double ceilingZ = spr->fakeceiling->bottom.plane->Zat0();
if (ViewPos.Z < ceilingZ && ceilingZ == sclipTop) if (ViewPos.Z < ceilingZ && ceilingZ == clip3d->sclipTop)
{ {
hz = spr->fakeceiling->top.plane->Zat0(); hz = spr->fakeceiling->top.plane->Zat0();
} }
@ -1541,31 +1543,9 @@ void R_DrawSprite (vissprite_t *spr)
topclip = short(MIN(h, viewheight)); topclip = short(MIN(h, viewheight));
} }
} }
hzt = MIN(hzt, sclipTop); hzt = MIN(hzt, clip3d->sclipTop);
} }
#if 0
// [RH] Sprites that were split by a drawseg should also be clipped
// by the sector's floor and ceiling. (Not sure how/if to handle this
// with fake floors, since those already do clipping.)
if (spr->bSplitSprite &&
(spr->heightsec == NULL || (spr->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)))
{
fixed_t h = spr->sector->floorplane.ZatPoint (spr->gx, spr->gy);
h = (centeryfrac - FixedMul (h-viewz, scale)) >> FRACBITS;
if (h < botclip)
{
botclip = MAX<short> (0, h);
}
h = spr->sector->ceilingplane.ZatPoint (spr->gx, spr->gy);
h = (centeryfrac - FixedMul (h-viewz, scale)) >> FRACBITS;
if (h > topclip)
{
topclip = short(MIN(h, viewheight));
}
}
#endif
if (topclip >= botclip) if (topclip >= botclip)
{ {
spr->Style.BaseColormap = colormap; spr->Style.BaseColormap = colormap;
@ -1752,7 +1732,7 @@ void R_DrawMaskedSingle (bool renew)
if (renew) if (renew)
{ {
fake3D |= FAKE3D_REFRESHCLIP; Clip3DFloors::Instance()->fake3D |= FAKE3D_REFRESHCLIP;
} }
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
{ {
@ -1775,7 +1755,8 @@ void R_DrawMasked (void)
R_CollectPortals(); R_CollectPortals();
R_SortVisSprites (DrewAVoxel ? sv_compare2d : sv_compare, firstvissprite - vissprites); R_SortVisSprites (DrewAVoxel ? sv_compare2d : sv_compare, firstvissprite - vissprites);
if (height_top == NULL) Clip3DFloors *clip3d = Clip3DFloors::Instance();
if (clip3d->height_top == NULL)
{ // kg3D - no visible 3D floors, normal rendering { // kg3D - no visible 3D floors, normal rendering
R_DrawMaskedSingle(false); R_DrawMaskedSingle(false);
} }
@ -1784,44 +1765,44 @@ void R_DrawMasked (void)
HeightLevel *hl; HeightLevel *hl;
// ceilings // ceilings
for (hl = height_cur; hl != NULL && hl->height >= ViewPos.Z; hl = hl->prev) for (hl = clip3d->height_cur; hl != NULL && hl->height >= ViewPos.Z; hl = hl->prev)
{ {
if (hl->next) if (hl->next)
{ {
fake3D = FAKE3D_CLIPBOTTOM | FAKE3D_CLIPTOP; clip3d->fake3D = FAKE3D_CLIPBOTTOM | FAKE3D_CLIPTOP;
sclipTop = hl->next->height; clip3d->sclipTop = hl->next->height;
} }
else else
{ {
fake3D = FAKE3D_CLIPBOTTOM; clip3d->fake3D = FAKE3D_CLIPBOTTOM;
} }
sclipBottom = hl->height; clip3d->sclipBottom = hl->height;
R_DrawMaskedSingle(true); R_DrawMaskedSingle(true);
R_DrawHeightPlanes(hl->height); R_DrawHeightPlanes(hl->height);
} }
// floors // floors
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP; clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP;
sclipTop = height_top->height; clip3d->sclipTop = clip3d->height_top->height;
R_DrawMaskedSingle(true); R_DrawMaskedSingle(true);
hl = height_top; hl = clip3d->height_top;
for (hl = height_top; hl != NULL && hl->height < ViewPos.Z; hl = hl->next) for (hl = clip3d->height_top; hl != NULL && hl->height < ViewPos.Z; hl = hl->next)
{ {
R_DrawHeightPlanes(hl->height); R_DrawHeightPlanes(hl->height);
if (hl->next) if (hl->next)
{ {
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP | FAKE3D_CLIPBOTTOM; clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP | FAKE3D_CLIPBOTTOM;
sclipTop = hl->next->height; clip3d->sclipTop = hl->next->height;
} }
else else
{ {
fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPBOTTOM; clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPBOTTOM;
} }
sclipBottom = hl->height; clip3d->sclipBottom = hl->height;
R_DrawMaskedSingle(true); R_DrawMaskedSingle(true);
} }
R_3D_DeleteHeights(); clip3d->DeleteHeights();
fake3D = 0; clip3d->fake3D = 0;
} }
R_DrawPlayerSprites(); R_DrawPlayerSprites();
} }

View file

@ -170,15 +170,17 @@ 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();
if (fixedlightlev < 0) if (fixedlightlev < 0)
{ {
if (!(fake3D & FAKE3D_CLIPTOP)) if (!(clip3d->fake3D & FAKE3D_CLIPTOP))
{ {
sclipTop = sec->ceilingplane.ZatPoint(ViewPos); clip3d->sclipTop = sec->ceilingplane.ZatPoint(ViewPos);
} }
for (i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) for (i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
{ {
if (sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0()) if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0())
{ {
lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; lightlist_t *lit = &frontsector->e->XFloor.lightlist[i];
basecolormap = lit->extra_colormap; basecolormap = lit->extra_colormap;
@ -277,12 +279,12 @@ namespace swrenderer
goto clearfog; goto clearfog;
} }
if ((fake3D & FAKE3D_CLIPBOTTOM) && textop < sclipBottom - ViewPos.Z) if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && textop < clip3d->sclipBottom - ViewPos.Z)
{ {
notrelevant = true; notrelevant = true;
goto clearfog; goto clearfog;
} }
if ((fake3D & FAKE3D_CLIPTOP) && textop - texheight > sclipTop - ViewPos.Z) if ((clip3d->fake3D & FAKE3D_CLIPTOP) && textop - texheight > clip3d->sclipTop - ViewPos.Z)
{ {
notrelevant = true; notrelevant = true;
goto clearfog; goto clearfog;
@ -293,17 +295,17 @@ namespace swrenderer
WallC.sx1 = ds->sx1; WallC.sx1 = ds->sx1;
WallC.sx2 = ds->sx2; WallC.sx2 = ds->sx2;
if (fake3D & FAKE3D_CLIPTOP) if (clip3d->fake3D & FAKE3D_CLIPTOP)
{ {
R_CreateWallSegmentY(wallupper, textop < sclipTop - ViewPos.Z ? textop : sclipTop - ViewPos.Z, &WallC); R_CreateWallSegmentY(wallupper, textop < clip3d->sclipTop - ViewPos.Z ? textop : clip3d->sclipTop - ViewPos.Z, &WallC);
} }
else else
{ {
R_CreateWallSegmentY(wallupper, textop, &WallC); R_CreateWallSegmentY(wallupper, textop, &WallC);
} }
if (fake3D & FAKE3D_CLIPBOTTOM) if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
{ {
R_CreateWallSegmentY(walllower, textop - texheight > sclipBottom - ViewPos.Z ? textop - texheight : sclipBottom - ViewPos.Z, &WallC); R_CreateWallSegmentY(walllower, textop - texheight > clip3d->sclipBottom - ViewPos.Z ? textop - texheight : clip3d->sclipBottom - ViewPos.Z, &WallC);
} }
else else
{ {
@ -321,7 +323,7 @@ namespace swrenderer
walllower[i] = mfloorclip[i]; walllower[i] = mfloorclip[i];
} }
if (CurrentSkybox) if (clip3d->CurrentSkybox)
{ // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor { // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor
// or above the ceiling, so the appropriate end won't be clipped automatically when adding // or above the ceiling, so the appropriate end won't be clipped automatically when adding
// this drawseg. // this drawseg.
@ -379,7 +381,7 @@ namespace swrenderer
WallC.sx1 = ds->sx1; WallC.sx1 = ds->sx1;
WallC.sx2 = ds->sx2; WallC.sx2 = ds->sx2;
if (CurrentSkybox) if (clip3d->CurrentSkybox)
{ // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor { // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor
// or above the ceiling, so the appropriate end won't be clipped automatically when adding // or above the ceiling, so the appropriate end won't be clipped automatically when adding
// this drawseg. // this drawseg.
@ -390,9 +392,9 @@ namespace swrenderer
} }
} }
if (fake3D & FAKE3D_CLIPTOP) if (clip3d->fake3D & FAKE3D_CLIPTOP)
{ {
R_CreateWallSegmentY(wallupper, sclipTop - ViewPos.Z, &WallC); R_CreateWallSegmentY(wallupper, clip3d->sclipTop - ViewPos.Z, &WallC);
for (i = x1; i < x2; i++) for (i = x1; i < x2; i++)
{ {
if (wallupper[i] < mceilingclip[i]) if (wallupper[i] < mceilingclip[i])
@ -400,9 +402,9 @@ namespace swrenderer
} }
mceilingclip = wallupper; mceilingclip = wallupper;
} }
if (fake3D & FAKE3D_CLIPBOTTOM) if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
{ {
R_CreateWallSegmentY(walllower, sclipBottom - ViewPos.Z, &WallC); R_CreateWallSegmentY(walllower, clip3d->sclipBottom - ViewPos.Z, &WallC);
for (i = x1; i < x2; i++) for (i = x1; i < x2; i++)
{ {
if (walllower[i] > mfloorclip[i]) if (walllower[i] > mfloorclip[i])
@ -424,7 +426,7 @@ namespace swrenderer
} }
if (!notrelevant) if (!notrelevant)
{ {
if (fake3D & FAKE3D_REFRESHCLIP) if (clip3d->fake3D & FAKE3D_REFRESHCLIP)
{ {
if (!wrap) if (!wrap)
{ {
@ -524,8 +526,9 @@ namespace swrenderer
WallC.tright.Y = ds->cy + ds->cdy; WallC.tright.Y = ds->cy + ds->cdy;
WallT = ds->tmapvals; WallT = ds->tmapvals;
R_CreateWallSegmentY(wallupper, sclipTop - ViewPos.Z, &WallC); Clip3DFloors *clip3d = Clip3DFloors::Instance();
R_CreateWallSegmentY(walllower, sclipBottom - ViewPos.Z, &WallC); R_CreateWallSegmentY(wallupper, clip3d->sclipTop - ViewPos.Z, &WallC);
R_CreateWallSegmentY(walllower, clip3d->sclipBottom - ViewPos.Z, &WallC);
for (i = x1; i < x2; i++) for (i = x1; i < x2; i++)
{ {
@ -573,15 +576,17 @@ namespace swrenderer
floorHeight = backsector->CenterFloor(); floorHeight = backsector->CenterFloor();
ceilingHeight = backsector->CenterCeiling(); ceilingHeight = backsector->CenterCeiling();
Clip3DFloors *clip3d = Clip3DFloors::Instance();
// maybe fix clipheights // maybe fix clipheights
if (!(fake3D & FAKE3D_CLIPBOTTOM)) sclipBottom = floorHeight; if (!(clip3d->fake3D & FAKE3D_CLIPBOTTOM)) clip3d->sclipBottom = floorHeight;
if (!(fake3D & FAKE3D_CLIPTOP)) sclipTop = ceilingHeight; if (!(clip3d->fake3D & FAKE3D_CLIPTOP)) clip3d->sclipTop = ceilingHeight;
// maybe not visible // maybe not visible
if (sclipBottom >= frontsector->CenterCeiling()) return; if (clip3d->sclipBottom >= frontsector->CenterCeiling()) return;
if (sclipTop <= frontsector->CenterFloor()) return; if (clip3d->sclipTop <= frontsector->CenterFloor()) return;
if (fake3D & FAKE3D_DOWN2UP) if (clip3d->fake3D & FAKE3D_DOWN2UP)
{ // bottom to viewz { // bottom to viewz
last = 0; last = 0;
for (i = backsector->e->XFloor.ffloors.Size() - 1; i >= 0; i--) for (i = backsector->e->XFloor.ffloors.Size() - 1; i >= 0; i--)
@ -592,7 +597,7 @@ namespace swrenderer
// visible? // visible?
passed = 0; passed = 0;
if (!(rover->flags & FF_RENDERSIDES) || rover->top.plane->isSlope() || rover->bottom.plane->isSlope() || if (!(rover->flags & FF_RENDERSIDES) || rover->top.plane->isSlope() || rover->bottom.plane->isSlope() ||
rover->top.plane->Zat0() <= sclipBottom || rover->top.plane->Zat0() <= clip3d->sclipBottom ||
rover->bottom.plane->Zat0() >= ceilingHeight || rover->bottom.plane->Zat0() >= ceilingHeight ||
rover->top.plane->Zat0() <= floorHeight) rover->top.plane->Zat0() <= floorHeight)
{ {
@ -607,7 +612,7 @@ namespace swrenderer
} }
rw_pic = nullptr; rw_pic = nullptr;
if (rover->bottom.plane->Zat0() >= sclipTop || passed) if (rover->bottom.plane->Zat0() >= clip3d->sclipTop || passed)
{ {
if (last) if (last)
{ {
@ -629,8 +634,8 @@ namespace swrenderer
if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue;
// visible? // visible?
if (fover->top.plane->Zat0() <= sclipBottom) continue; // no if (fover->top.plane->Zat0() <= clip3d->sclipBottom) continue; // no
if (fover->bottom.plane->Zat0() >= sclipTop) if (fover->bottom.plane->Zat0() >= clip3d->sclipTop)
{ // no, last possible { // no, last possible
fover = nullptr; fover = nullptr;
break; break;
@ -682,8 +687,8 @@ namespace swrenderer
if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue;
// visible? // visible?
if (fover->top.plane->Zat0() <= sclipBottom) continue; // no if (fover->top.plane->Zat0() <= clip3d->sclipBottom) continue; // no
if (fover->bottom.plane->Zat0() >= sclipTop) if (fover->bottom.plane->Zat0() >= clip3d->sclipTop)
{ // visible, last possible { // visible, last possible
fover = nullptr; fover = nullptr;
break; break;
@ -733,7 +738,7 @@ namespace swrenderer
{ {
for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--)
{ {
if (sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) if (clip3d->sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0())
{ {
lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; lightlist_t *lit = &backsector->e->XFloor.lightlist[j];
basecolormap = lit->extra_colormap; basecolormap = lit->extra_colormap;
@ -746,7 +751,7 @@ namespace swrenderer
{ {
for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--)
{ {
if (sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0())
{ {
lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; lightlist_t *lit = &frontsector->e->XFloor.lightlist[j];
basecolormap = lit->extra_colormap; basecolormap = lit->extra_colormap;
@ -775,7 +780,7 @@ namespace swrenderer
passed = 0; passed = 0;
if (!(rover->flags & FF_RENDERSIDES) || if (!(rover->flags & FF_RENDERSIDES) ||
rover->top.plane->isSlope() || rover->bottom.plane->isSlope() || rover->top.plane->isSlope() || rover->bottom.plane->isSlope() ||
rover->bottom.plane->Zat0() >= sclipTop || rover->bottom.plane->Zat0() >= clip3d->sclipTop ||
rover->top.plane->Zat0() <= floorHeight || rover->top.plane->Zat0() <= floorHeight ||
rover->bottom.plane->Zat0() >= ceilingHeight) rover->bottom.plane->Zat0() >= ceilingHeight)
{ {
@ -789,7 +794,7 @@ namespace swrenderer
} }
} }
rw_pic = nullptr; rw_pic = nullptr;
if (rover->top.plane->Zat0() <= sclipBottom || passed) if (rover->top.plane->Zat0() <= clip3d->sclipBottom || passed)
{ // maybe wall from inside rendering? { // maybe wall from inside rendering?
fover = nullptr; fover = nullptr;
for (j = 0; j < (int)frontsector->e->XFloor.ffloors.Size(); j++) for (j = 0; j < (int)frontsector->e->XFloor.ffloors.Size(); j++)
@ -806,8 +811,8 @@ namespace swrenderer
if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue;
// visible? // visible?
if (fover->bottom.plane->Zat0() >= sclipTop) continue; // no if (fover->bottom.plane->Zat0() >= clip3d->sclipTop) continue; // no
if (fover->top.plane->Zat0() <= sclipBottom) if (fover->top.plane->Zat0() <= clip3d->sclipBottom)
{ // no, last possible { // no, last possible
fover = nullptr; fover = nullptr;
break; break;
@ -858,8 +863,8 @@ namespace swrenderer
if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue;
// visible? // visible?
if (fover->bottom.plane->Zat0() >= sclipTop) continue; // no if (fover->bottom.plane->Zat0() >= clip3d->sclipTop) continue; // no
if (fover->top.plane->Zat0() <= sclipBottom) if (fover->top.plane->Zat0() <= clip3d->sclipBottom)
{ // visible, last possible { // visible, last possible
fover = nullptr; fover = nullptr;
break; break;
@ -907,7 +912,7 @@ namespace swrenderer
{ {
for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--)
{ {
if (sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) if (clip3d->sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0())
{ {
lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; lightlist_t *lit = &backsector->e->XFloor.lightlist[j];
basecolormap = lit->extra_colormap; basecolormap = lit->extra_colormap;
@ -920,7 +925,7 @@ namespace swrenderer
{ {
for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--)
{ {
if (sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0())
{ {
lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; lightlist_t *lit = &frontsector->e->XFloor.lightlist[j];
basecolormap = lit->extra_colormap; basecolormap = lit->extra_colormap;