Move r_bsp into a class

This commit is contained in:
Magnus Norddahl 2017-01-04 15:39:47 +01:00
parent c396e7f949
commit 28732d63d2
12 changed files with 758 additions and 777 deletions

View file

@ -134,7 +134,7 @@ namespace swrenderer
// kg3D - its fake, no transfer_heights
if (!(fake3D & FAKE3D_FAKEBACK))
{ // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
backsector = R_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);
}
doorclosed = false; // killough 4/16/98
@ -447,7 +447,7 @@ namespace swrenderer
// kg3D - backup for mid and fake walls
draw_segment->bkup = R_NewOpening(stop - start);
memcpy(openings + draw_segment->bkup, &ceilingclip[start], sizeof(short)*(stop - start));
memcpy(openings + draw_segment->bkup, &RenderBSP::Instance()->ceilingclip[start], sizeof(short)*(stop - start));
draw_segment->bFogBoundary = IsFogBoundary(frontsector, backsector);
if (sidedef->GetTexture(side_t::mid).isValid() || draw_segment->bFakeBoundary)
@ -559,13 +559,13 @@ namespace swrenderer
if (((draw_segment->silhouette & SIL_TOP) || maskedtexture) && draw_segment->sprtopclip == -1)
{
draw_segment->sprtopclip = R_NewOpening(stop - start);
memcpy(openings + draw_segment->sprtopclip, &ceilingclip[start], sizeof(short)*(stop - start));
memcpy(openings + draw_segment->sprtopclip, &RenderBSP::Instance()->ceilingclip[start], sizeof(short)*(stop - start));
}
if (((draw_segment->silhouette & SIL_BOTTOM) || maskedtexture) && draw_segment->sprbottomclip == -1)
{
draw_segment->sprbottomclip = R_NewOpening(stop - start);
memcpy(openings + draw_segment->sprbottomclip, &floorclip[start], sizeof(short)*(stop - start));
memcpy(openings + draw_segment->sprbottomclip, &RenderBSP::Instance()->floorclip[start], sizeof(short)*(stop - start));
}
if (maskedtexture && curline->sidedef->GetTexture(side_t::mid).isValid())
@ -960,6 +960,8 @@ namespace swrenderer
R_SetColorMapLight(fixedcolormap, 0, 0);
// clip wall to the floor and ceiling
auto ceilingclip = RenderBSP::Instance()->ceilingclip;
auto floorclip = RenderBSP::Instance()->floorclip;
for (x = x1; x < x2; ++x)
{
if (walltop[x] < ceilingclip[x])

View file

@ -474,12 +474,7 @@ namespace swrenderer
if (pl->left >= pl->right)
return;
if (r_drawflat) // no texture mapping
{
drawerargs::ds_color += 4;
R_DrawColoredPlane(pl);
}
else if (pl->picnum == skyflatnum) // sky flat
if (pl->picnum == skyflatnum) // sky flat
{
R_DrawSkyPlane(pl);
}
@ -506,7 +501,7 @@ namespace swrenderer
basecolormap = pl->colormap;
if (r_drawflat || (!pl->height.isSlope() && !tilt))
if (!pl->height.isSlope() && !tilt)
{
R_DrawNormalPlane(pl, xscale, yscale, alpha, additive, masked);
}

View file

@ -103,9 +103,7 @@ static void R_ShutdownRenderer();
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern short *openings;
extern bool r_fakingunderwater;
extern int fuzzviewheight;
extern subsector_t *InSubsector;
// PRIVATE DATA DECLARATIONS -----------------------------------------------
@ -555,24 +553,13 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
R_ClearSprites ();
// opening / clipping determination
// [RH] clip ceiling to console bottom
fillshort(floorclip, viewwidth, viewheight);
fillshort(ceilingclip, viewwidth, !screen->Accel2D && ConBottom > viewwindowy && !bRenderingToCanvas ? (ConBottom - viewwindowy) : 0);
RenderBSP::Instance()->ClearClip();
R_FreeOpenings();
NetUpdate ();
// [RH] Show off segs if r_drawflat is 1
if (r_drawflat)
{
colfunc = &SWPixelFormatDrawers::FillColumn;
spanfunc = &SWPixelFormatDrawers::FillSpan;
}
else
{
colfunc = basecolfunc;
spanfunc = &SWPixelFormatDrawers::DrawSpan;
}
WindowLeft = 0;
WindowRight = viewwidth;
@ -583,7 +570,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
r_dontmaplines = dontmaplines;
// [RH] Hack to make windows into underwater areas possible
r_fakingunderwater = false;
RenderBSP::Instance()->ResetFakingUnderwater();
// [RH] Setup particles for this frame
P_FindParticleSubsectors ();
@ -597,7 +584,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
PO_LinkToSubsectors();
R_RenderScene();
RenderBSP::Instance()->RenderScene();
R_3D_ResetClip(); // reset clips (floor/ceiling)
camera->renderflags = savedflags;
WallCycles.Unclock();

View file

@ -484,6 +484,6 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
sector_t *FSoftwareRenderer::FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel)
{
return R_FakeFlat(sec, tempsec, floorlightlevel, ceilinglightlevel, nullptr, 0, 0, 0, 0);
return RenderBSP::Instance()->FakeFlat(sec, tempsec, floorlightlevel, ceilinglightlevel, nullptr, 0, 0, 0, 0);
}

View file

@ -98,8 +98,8 @@ void R_3D_NewClip()
curr = (ClipStack*)M_Malloc(sizeof(ClipStack));
curr->next = 0;
memcpy(curr->floorclip, floorclip, sizeof(short) * MAXWIDTH);
memcpy(curr->ceilingclip, ceilingclip, sizeof(short) * MAXWIDTH);
memcpy(curr->floorclip, RenderBSP::Instance()->floorclip, sizeof(short) * MAXWIDTH);
memcpy(curr->ceilingclip, RenderBSP::Instance()->ceilingclip, sizeof(short) * MAXWIDTH);
curr->ffloor = fakeFloor;
assert(fakeFloor->floorclip == NULL);
assert(fakeFloor->ceilingclip == NULL);

View file

@ -44,6 +44,7 @@
#include "a_sharedglobal.h"
#include "g_level.h"
#include "p_effect.h"
#include "c_console.h"
// State.
#include "doomstat.h"
@ -54,45 +55,25 @@
#include "po_man.h"
#include "r_data/colormaps.h"
CVAR (Bool, r_drawflat, false, 0) // [RH] Don't texture segs?
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer
{
namespace
RenderBSP *RenderBSP::Instance()
{
subsector_t *InSubsector;
sector_t *frontsector;
uint8_t FakeSide;
SWRenderLine render_line;
static RenderBSP bsp;
return &bsp;
}
bool r_fakingunderwater;
// Clip values are the solid pixel bounding the range.
// floorclip starts out SCREENHEIGHT and is just outside the range
// ceilingclip starts out 0 and is just inside the range
//
short floorclip[MAXWIDTH];
short ceilingclip[MAXWIDTH];
//
// killough 3/7/98: Hack floor/ceiling heights for deep water etc.
//
sector_t *RenderBSP::FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2)
{
// If player's view height is underneath fake floor, lower the
// drawn ceiling to be just under the floor height, and replace
// the drawn floor and ceiling textures, and light level, with
// the control sector's.
//
// Similar for ceiling, only reflected.
//
// killough 4/11/98, 4/13/98: fix bugs, add 'back' parameter
//
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2)
{
// [RH] allow per-plane lighting
if (floorlightlevel != NULL)
{
@ -291,7 +272,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int
// Checks BSP node/subtree bounding box.
// Returns true if some part of the bbox might be visible.
static bool R_CheckBBox (float *bspcoord) // killough 1/28/98: static
bool RenderBSP::CheckBBox(float *bspcoord)
{
static const int checkcoord[12][4] =
{
@ -392,9 +373,7 @@ static bool R_CheckBBox (float *bspcoord) // killough 1/28/98: static
return R_IsWallSegmentVisible(sx1, sx2);
}
void R_Subsector (subsector_t *sub);
static void R_AddPolyobjs(subsector_t *sub)
void RenderBSP::AddPolyobjs(subsector_t *sub)
{
if (sub->BSP == NULL || sub->BSP->bDirty)
{
@ -402,16 +381,16 @@ static void R_AddPolyobjs(subsector_t *sub)
}
if (sub->BSP->Nodes.Size() == 0)
{
R_Subsector(&sub->BSP->Subsectors[0]);
RenderSubsector(&sub->BSP->Subsectors[0]);
}
else
{
R_RenderBSPNode(&sub->BSP->Nodes.Last());
RenderBSPNode(&sub->BSP->Nodes.Last());
}
}
// kg3D - add fake segs, never rendered
void R_FakeDrawLoop(subsector_t *sub, visplane_t *floorplane, visplane_t *ceilingplane)
void RenderBSP::FakeDrawLoop(subsector_t *sub, visplane_t *floorplane, visplane_t *ceilingplane)
{
int count;
seg_t* line;
@ -423,20 +402,18 @@ void R_FakeDrawLoop(subsector_t *sub, visplane_t *floorplane, visplane_t *ceilin
{
if ((line->sidedef) && !(line->sidedef->Flags & WALLF_POLYOBJ))
{
render_line.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane);
renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane);
}
line++;
}
}
//
// R_Subsector
void RenderBSP::RenderSubsector(subsector_t *sub)
{
// Determine floor/ceiling planes.
// Add sprites of things in sector.
// Draw one or more line segments.
//
void R_Subsector (subsector_t *sub)
{
int count;
seg_t* line;
sector_t tempsec; // killough 3/7/98: deep water hack
@ -464,14 +441,14 @@ void R_Subsector (subsector_t *sub)
#ifdef RANGECHECK
if (outersubsector && sub - subsectors >= (ptrdiff_t)numsubsectors)
I_Error ("R_Subsector: ss %ti with numss = %i", sub - subsectors, numsubsectors);
I_Error("RenderSubsector: ss %ti with numss = %i", sub - subsectors, numsubsectors);
#endif
assert(sub->sector != NULL);
if (sub->polys)
{ // Render the polyobjs in the subsector first
R_AddPolyobjs(sub);
AddPolyobjs(sub);
if (outersubsector)
{
InSubsector = NULL;
@ -485,7 +462,7 @@ void R_Subsector (subsector_t *sub)
line = sub->firstline;
// killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, nullptr, 0, 0, 0, 0);
frontsector = FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, nullptr, 0, 0, 0, 0);
fll = floorlightlevel;
cll = ceilinglightlevel;
@ -609,7 +586,8 @@ void R_Subsector (subsector_t *sub)
{
tempsec.SetTexture(sector_t::floor, tempsec.GetTexture(sector_t::ceiling));
position = sector_t::ceiling;
} else position = sector_t::floor;
}
else position = sector_t::floor;
frontsector = &tempsec;
if (fixedlightlev < 0 && sub->sector->e->XFloor.lightlist.Size())
@ -632,7 +610,7 @@ void R_Subsector (subsector_t *sub)
if (floorplane)
R_AddPlaneLights(floorplane, frontsector->lighthead);
R_FakeDrawLoop(sub, floorplane, ceilingplane);
FakeDrawLoop(sub, floorplane, ceilingplane);
fake3D = 0;
frontsector = sub->sector;
}
@ -671,7 +649,8 @@ void R_Subsector (subsector_t *sub)
{
tempsec.SetTexture(sector_t::ceiling, tempsec.GetTexture(sector_t::floor));
position = sector_t::floor;
} else position = sector_t::ceiling;
}
else position = sector_t::ceiling;
frontsector = &tempsec;
tempsec.ceilingplane.ChangeHeight(-1 / 65536.);
@ -696,7 +675,7 @@ void R_Subsector (subsector_t *sub)
if (ceilingplane)
R_AddPlaneLights(ceilingplane, frontsector->lighthead);
R_FakeDrawLoop(sub, floorplane, ceilingplane);
FakeDrawLoop(sub, floorplane, ceilingplane);
fake3D = 0;
frontsector = sub->sector;
}
@ -756,14 +735,14 @@ void R_Subsector (subsector_t *sub)
fakeFloor->validcount = validcount;
R_3D_NewClip();
}
render_line.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane); // fake
renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane); // fake
}
fakeFloor = NULL;
fake3D = 0;
floorplane = backupfp;
ceilingplane = backupcp;
}
render_line.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane); // now real
renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane); // now real
}
line++;
}
@ -773,10 +752,10 @@ void R_Subsector (subsector_t *sub)
}
}
void R_RenderScene()
void RenderBSP::RenderScene()
{
InSubsector = nullptr;
R_RenderBSPNode(nodes + numnodes - 1); // The head node is the last node output.
RenderBSPNode(nodes + numnodes - 1); // The head node is the last node output.
}
//
@ -785,11 +764,11 @@ void R_RenderScene()
// Just call with BSP root and -1.
// killough 5/2/98: reformatted, removed tail recursion
void R_RenderBSPNode (void *node)
void RenderBSP::RenderBSPNode(void *node)
{
if (numnodes == 0)
{
R_Subsector (subsectors);
RenderSubsector(subsectors);
return;
}
while (!((size_t)node & 1)) // Keep going until found a subsector
@ -800,16 +779,22 @@ void R_RenderBSPNode (void *node)
int side = R_PointOnSide(ViewPos, bsp);
// Recursively divide front space (toward the viewer).
R_RenderBSPNode (bsp->children[side]);
RenderBSPNode(bsp->children[side]);
// Possibly divide back space (away from the viewer).
side ^= 1;
if (!R_CheckBBox (bsp->bbox[side]))
if (!CheckBBox(bsp->bbox[side]))
return;
node = bsp->children[side];
}
R_Subsector ((subsector_t *)((BYTE *)node - 1));
RenderSubsector((subsector_t *)((BYTE *)node - 1));
}
void RenderBSP::ClearClip()
{
// clip ceiling to console bottom
fillshort(floorclip, viewwidth, viewheight);
fillshort(ceilingclip, viewwidth, !screen->Accel2D && ConBottom > viewwindowy && !bRenderingToCanvas ? (ConBottom - viewwindowy) : 0);
}
}

View file

@ -1,7 +1,3 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
@ -14,24 +10,16 @@
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// DESCRIPTION:
// Refresh module, BSP traversal and handling.
//
//-----------------------------------------------------------------------------
#ifndef __R_BSP__
#define __R_BSP__
#pragma once
#include "tarray.h"
#include <stddef.h>
#include "r_defs.h"
EXTERN_CVAR (Bool, r_drawflat) // [RH] Don't texture segs?
#include "swrenderer/line/r_line.h"
namespace swrenderer
{
struct visplane_t;
// The 3072 below is just an arbitrary value picked to avoid
@ -46,15 +34,33 @@ enum
FAKED_AboveCeiling
};
void R_RenderScene();
void R_RenderBSPNode (void *node);
class RenderBSP
{
public:
static RenderBSP *Instance();
// killough 4/13/98: fake floors/ceilings for deep water / fake ceilings:
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2);
void ClearClip();
void RenderScene();
extern short floorclip[MAXWIDTH];
extern short ceilingclip[MAXWIDTH];
void ResetFakingUnderwater() { r_fakingunderwater = false; }
sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2);
short floorclip[MAXWIDTH];
short ceilingclip[MAXWIDTH];
private:
void RenderBSPNode(void *node);
void RenderSubsector(subsector_t *sub);
bool CheckBBox(float *bspcoord);
void AddPolyobjs(subsector_t *sub);
void FakeDrawLoop(subsector_t *sub, visplane_t *floorplane, visplane_t *ceilingplane);
subsector_t *InSubsector;
sector_t *frontsector;
uint8_t FakeSide;
bool r_fakingunderwater;
SWRenderLine renderline;
};
}
#endif

View file

@ -204,6 +204,8 @@ namespace swrenderer
WindowLeft = pl->left;
WindowRight = pl->right;
auto ceilingclip = RenderBSP::Instance()->ceilingclip;
auto floorclip = RenderBSP::Instance()->floorclip;
for (i = pl->left; i < pl->right; i++)
{
if (pl->top[i] == 0x7fff)
@ -249,7 +251,7 @@ namespace swrenderer
viewposStack.Push(ViewPos);
visplaneStack.Push(pl);
R_RenderScene();
RenderBSP::Instance()->RenderScene();
R_3D_ResetClip(); // reset clips (floor/ceiling)
R_DrawPlanes();
@ -465,10 +467,12 @@ namespace swrenderer
CurrentPortalInSkybox = false; // first portal in a skybox should set this variable to false for proper clipping in skyboxes.
// first pass, set clipping
auto ceilingclip = RenderBSP::Instance()->ceilingclip;
auto floorclip = RenderBSP::Instance()->floorclip;
memcpy(ceilingclip + pds->x1, &pds->ceilingclip[0], pds->len * sizeof(*ceilingclip));
memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip));
R_RenderScene();
RenderBSP::Instance()->RenderScene();
R_3D_ResetClip(); // reset clips (floor/ceiling)
if (!savedvisibility && camera) camera->renderflags &= ~RF_INVISIBLE;

View file

@ -162,7 +162,7 @@ namespace swrenderer
}
// killough 4/13/98: get correct lightlevel for 2s normal textures
sec = R_FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0);
sec = RenderBSP::Instance()->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0);
basecolormap = sec->ColorMap; // [RH] Set basecolormap

View file

@ -170,7 +170,7 @@ namespace swrenderer
else if (pass == 0)
{
mceilingclip = walltop;
mfloorclip = ceilingclip;
mfloorclip = RenderBSP::Instance()->ceilingclip;
needrepeat = 1;
}
else
@ -186,7 +186,7 @@ namespace swrenderer
goto done;
}
mceilingclip = walltop;
mfloorclip = ceilingclip;
mfloorclip = RenderBSP::Instance()->ceilingclip;
break;
case RF_CLIPMID:
@ -203,7 +203,7 @@ namespace swrenderer
{
goto done;
}
mceilingclip = floorclip;
mceilingclip = RenderBSP::Instance()->floorclip;
mfloorclip = wallbottom;
break;
}
@ -296,7 +296,7 @@ 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 = floorclip;
mceilingclip = RenderBSP::Instance()->floorclip;
mfloorclip = wallbottom;
R_FinishSetPatchStyle();
} while (needrepeat--);

View file

@ -114,6 +114,8 @@ namespace swrenderer
// entered, we don't need to clip it to drawsegs like a normal sprite.
// Clip particles behind walls.
auto ceilingclip = RenderBSP::Instance()->ceilingclip;
auto floorclip = RenderBSP::Instance()->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;

View file

@ -123,7 +123,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 = R_FakeFlat(viewsector, &tempsec, &floorlight, &ceilinglight, nullptr, 0, 0, 0, 0);
sec = RenderBSP::Instance()->FakeFlat(viewsector, &tempsec, &floorlight, &ceilinglight, nullptr, 0, 0, 0, 0);
// [RH] set basecolormap
basecolormap = sec->ColorMap;