mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-29 07:22:07 +00:00
Split r_visibleplane into more files
This commit is contained in:
parent
2988a5fe87
commit
c80860cd5d
16 changed files with 636 additions and 500 deletions
|
@ -865,7 +865,9 @@ set( FASTMATH_PCH_SOURCES
|
||||||
swrenderer/things/r_wallsprite.cpp
|
swrenderer/things/r_wallsprite.cpp
|
||||||
swrenderer/things/r_decal.cpp
|
swrenderer/things/r_decal.cpp
|
||||||
swrenderer/plane/r_visibleplane.cpp
|
swrenderer/plane/r_visibleplane.cpp
|
||||||
|
swrenderer/plane/r_visibleplanelist.cpp
|
||||||
swrenderer/plane/r_skyplane.cpp
|
swrenderer/plane/r_skyplane.cpp
|
||||||
|
swrenderer/plane/r_planerenderer.cpp
|
||||||
swrenderer/plane/r_flatplane.cpp
|
swrenderer/plane/r_flatplane.cpp
|
||||||
swrenderer/plane/r_slopeplane.cpp
|
swrenderer/plane/r_slopeplane.cpp
|
||||||
polyrenderer/poly_renderer.cpp
|
polyrenderer/poly_renderer.cpp
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "swrenderer/segments/r_clipsegment.h"
|
#include "swrenderer/segments/r_clipsegment.h"
|
||||||
#include "swrenderer/segments/r_drawsegment.h"
|
#include "swrenderer/segments/r_drawsegment.h"
|
||||||
#include "swrenderer/plane/r_visibleplane.h"
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplanelist.h"
|
||||||
#include "swrenderer/things/r_decal.h"
|
#include "swrenderer/things/r_decal.h"
|
||||||
|
|
||||||
CVAR(Bool, r_fogboundary, true, 0)
|
CVAR(Bool, r_fogboundary, true, 0)
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "swrenderer/segments/r_clipsegment.h"
|
#include "swrenderer/segments/r_clipsegment.h"
|
||||||
#include "swrenderer/segments/r_drawsegment.h"
|
#include "swrenderer/segments/r_drawsegment.h"
|
||||||
#include "swrenderer/scene/r_portal.h"
|
#include "swrenderer/scene/r_portal.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
#include "swrenderer/r_memory.h"
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
|
|
|
@ -13,10 +13,12 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "r_visibleplane.h"
|
#include "r_planerenderer.h"
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
|
struct visplane_light;
|
||||||
|
|
||||||
class RenderFlatPlane : PlaneRenderer
|
class RenderFlatPlane : PlaneRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
99
src/swrenderer/plane/r_planerenderer.cpp
Normal file
99
src/swrenderer/plane/r_planerenderer.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
//
|
||||||
|
// This source is available for distribution and/or modification
|
||||||
|
// only under the terms of the DOOM Source Code License as
|
||||||
|
// published by id Software. All rights reserved.
|
||||||
|
//
|
||||||
|
// The source is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#include "templates.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#include "stats.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "a_sharedglobal.h"
|
||||||
|
#include "c_console.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "g_level.h"
|
||||||
|
#include "gl/dynlights/gl_dynlight.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
|
#include "swrenderer/plane/r_planerenderer.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
void PlaneRenderer::RenderLines(visplane_t *pl)
|
||||||
|
{
|
||||||
|
// t1/b1 are at x
|
||||||
|
// t2/b2 are at x+1
|
||||||
|
// spanend[y] is at the right edge
|
||||||
|
|
||||||
|
int x = pl->right - 1;
|
||||||
|
int t2 = pl->top[x];
|
||||||
|
int b2 = pl->bottom[x];
|
||||||
|
|
||||||
|
if (b2 > t2)
|
||||||
|
{
|
||||||
|
fillshort(spanend + t2, b2 - t2, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (--x; x >= pl->left; --x)
|
||||||
|
{
|
||||||
|
int t1 = pl->top[x];
|
||||||
|
int b1 = pl->bottom[x];
|
||||||
|
const int xr = x + 1;
|
||||||
|
int stop;
|
||||||
|
|
||||||
|
// Draw any spans that have just closed
|
||||||
|
stop = MIN(t1, b2);
|
||||||
|
while (t2 < stop)
|
||||||
|
{
|
||||||
|
int y = t2++;
|
||||||
|
int x2 = spanend[y];
|
||||||
|
RenderLine(y, xr, x2);
|
||||||
|
}
|
||||||
|
stop = MAX(b1, t2);
|
||||||
|
while (b2 > stop)
|
||||||
|
{
|
||||||
|
int y = --b2;
|
||||||
|
int x2 = spanend[y];
|
||||||
|
RenderLine(y, xr, x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark any spans that have just opened
|
||||||
|
stop = MIN(t2, b1);
|
||||||
|
while (t1 < stop)
|
||||||
|
{
|
||||||
|
spanend[t1++] = x;
|
||||||
|
}
|
||||||
|
stop = MAX(b2, t2);
|
||||||
|
while (b1 > stop)
|
||||||
|
{
|
||||||
|
spanend[--b1] = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
t2 = pl->top[x];
|
||||||
|
b2 = pl->bottom[x];
|
||||||
|
|
||||||
|
StepColumn();
|
||||||
|
}
|
||||||
|
// Draw any spans that are still open
|
||||||
|
while (t2 < b2)
|
||||||
|
{
|
||||||
|
int y = --b2;
|
||||||
|
int x2 = spanend[y];
|
||||||
|
RenderLine(y, pl->left, x2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/swrenderer/plane/r_planerenderer.h
Normal file
34
src/swrenderer/plane/r_planerenderer.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
//
|
||||||
|
// This source is available for distribution and/or modification
|
||||||
|
// only under the terms of the DOOM Source Code License as
|
||||||
|
// published by id Software. All rights reserved.
|
||||||
|
//
|
||||||
|
// The source is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "r_defs.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
struct visplane_t;
|
||||||
|
|
||||||
|
class PlaneRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void RenderLines(visplane_t *pl);
|
||||||
|
|
||||||
|
virtual void RenderLine(int y, int x1, int x2) = 0;
|
||||||
|
virtual void StepColumn() { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
short spanend[MAXHEIGHT];
|
||||||
|
};
|
||||||
|
}
|
|
@ -38,6 +38,7 @@
|
||||||
#include "swrenderer/segments/r_drawsegment.h"
|
#include "swrenderer/segments/r_drawsegment.h"
|
||||||
#include "swrenderer/scene/r_portal.h"
|
#include "swrenderer/scene/r_portal.h"
|
||||||
#include "swrenderer/r_memory.h"
|
#include "swrenderer/r_memory.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4244)
|
#pragma warning(disable:4244)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "r_visibleplane.h"
|
#include "r_planerenderer.h"
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,463 +123,4 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
NetUpdate();
|
NetUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
VisiblePlaneList *VisiblePlaneList::Instance()
|
|
||||||
{
|
|
||||||
static VisiblePlaneList instance;
|
|
||||||
return &instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
VisiblePlaneList::VisiblePlaneList()
|
|
||||||
{
|
|
||||||
for (auto &plane : visplanes)
|
|
||||||
plane = nullptr;
|
|
||||||
freehead = &freetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisiblePlaneList::Deinit()
|
|
||||||
{
|
|
||||||
// do not use R_ClearPlanes because at this point the screen pointer is no longer valid.
|
|
||||||
for (int i = 0; i <= MAXVISPLANES; i++) // new code -- killough
|
|
||||||
{
|
|
||||||
for (*freehead = visplanes[i], visplanes[i] = nullptr; *freehead; )
|
|
||||||
{
|
|
||||||
freehead = &(*freehead)->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (visplane_t *pl = freetail; pl != nullptr; )
|
|
||||||
{
|
|
||||||
visplane_t *next = pl->next;
|
|
||||||
free(pl);
|
|
||||||
pl = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visplane_t *VisiblePlaneList::Add(unsigned hash)
|
|
||||||
{
|
|
||||||
visplane_t *check = freetail;
|
|
||||||
|
|
||||||
if (check == nullptr)
|
|
||||||
{
|
|
||||||
check = (visplane_t *)M_Malloc(sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH * 2));
|
|
||||||
memset(check, 0, sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH * 2));
|
|
||||||
check->bottom = check->top + MAXWIDTH + 2;
|
|
||||||
}
|
|
||||||
else if (nullptr == (freetail = freetail->next))
|
|
||||||
{
|
|
||||||
freehead = &freetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
check->lights = nullptr;
|
|
||||||
|
|
||||||
check->next = visplanes[hash];
|
|
||||||
visplanes[hash] = check;
|
|
||||||
return check;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisiblePlaneList::Init()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
visplane_t *pl;
|
|
||||||
|
|
||||||
// Free all visplanes and let them be re-allocated as needed.
|
|
||||||
pl = freetail;
|
|
||||||
|
|
||||||
while (pl)
|
|
||||||
{
|
|
||||||
visplane_t *next = pl->next;
|
|
||||||
M_Free(pl);
|
|
||||||
pl = next;
|
|
||||||
}
|
|
||||||
freetail = nullptr;
|
|
||||||
freehead = &freetail;
|
|
||||||
|
|
||||||
for (i = 0; i < MAXVISPLANES; i++)
|
|
||||||
{
|
|
||||||
pl = visplanes[i];
|
|
||||||
visplanes[i] = nullptr;
|
|
||||||
while (pl)
|
|
||||||
{
|
|
||||||
visplane_t *next = pl->next;
|
|
||||||
M_Free(pl);
|
|
||||||
pl = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisiblePlaneList::Clear(bool fullclear)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Don't clear fake planes if not doing a full clear.
|
|
||||||
if (!fullclear)
|
|
||||||
{
|
|
||||||
for (i = 0; i <= MAXVISPLANES - 1; i++) // new code -- killough
|
|
||||||
{
|
|
||||||
for (visplane_t **probe = &visplanes[i]; *probe != nullptr; )
|
|
||||||
{
|
|
||||||
if ((*probe)->sky < 0)
|
|
||||||
{ // fake: move past it
|
|
||||||
probe = &(*probe)->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // not fake: move to freelist
|
|
||||||
visplane_t *vis = *probe;
|
|
||||||
*freehead = vis;
|
|
||||||
*probe = vis->next;
|
|
||||||
vis->next = nullptr;
|
|
||||||
freehead = &vis->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i <= MAXVISPLANES; i++) // new code -- killough
|
|
||||||
{
|
|
||||||
for (*freehead = visplanes[i], visplanes[i] = nullptr; *freehead; )
|
|
||||||
{
|
|
||||||
freehead = &(*freehead)->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
visplane_t *VisiblePlaneList::FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal)
|
|
||||||
{
|
|
||||||
secplane_t plane;
|
|
||||||
visplane_t *check;
|
|
||||||
unsigned hash; // killough
|
|
||||||
bool isskybox;
|
|
||||||
const FTransform *xform = &xxform;
|
|
||||||
fixed_t alpha = FLOAT2FIXED(Alpha);
|
|
||||||
//angle_t angle = (xform.Angle + xform.baseAngle).BAMs();
|
|
||||||
|
|
||||||
FTransform nulltransform;
|
|
||||||
|
|
||||||
if (picnum == skyflatnum) // killough 10/98
|
|
||||||
{ // most skies map together
|
|
||||||
lightlevel = 0;
|
|
||||||
xform = &nulltransform;
|
|
||||||
nulltransform.xOffs = nulltransform.yOffs = nulltransform.baseyOffs = 0;
|
|
||||||
nulltransform.xScale = nulltransform.yScale = 1;
|
|
||||||
nulltransform.Angle = nulltransform.baseAngle = 0.0;
|
|
||||||
additive = false;
|
|
||||||
// [RH] Map floor skies and ceiling skies to separate visplanes. This isn't
|
|
||||||
// always necessary, but it is needed if a floor and ceiling sky are in the
|
|
||||||
// same column but separated by a wall. If they both try to reside in the
|
|
||||||
// same visplane, then only the floor sky will be drawn.
|
|
||||||
plane.set(0., 0., height.fC(), 0.);
|
|
||||||
isskybox = portal != nullptr && !(portal->mFlags & PORTSF_INSKYBOX);
|
|
||||||
}
|
|
||||||
else if (portal != nullptr && !(portal->mFlags & PORTSF_INSKYBOX))
|
|
||||||
{
|
|
||||||
plane = height;
|
|
||||||
isskybox = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plane = height;
|
|
||||||
isskybox = false;
|
|
||||||
// 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();
|
|
||||||
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;
|
|
||||||
alpha = OPAQUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// New visplane algorithm uses hash table -- killough
|
|
||||||
hash = isskybox ? MAXVISPLANES : CalcHash(picnum.GetIndex(), lightlevel, height);
|
|
||||||
|
|
||||||
RenderPortal *renderportal = RenderPortal::Instance();
|
|
||||||
|
|
||||||
for (check = visplanes[hash]; check; check = check->next) // killough
|
|
||||||
{
|
|
||||||
if (isskybox)
|
|
||||||
{
|
|
||||||
if (portal == check->portal && plane == check->height)
|
|
||||||
{
|
|
||||||
if (portal->mType != PORTS_SKYVIEWPOINT)
|
|
||||||
{ // This skybox is really a stacked sector, so we need to
|
|
||||||
// check even more.
|
|
||||||
if (check->extralight == renderportal->stacked_extralight &&
|
|
||||||
check->visibility == renderportal->stacked_visibility &&
|
|
||||||
check->viewpos == renderportal->stacked_viewpos &&
|
|
||||||
(
|
|
||||||
// headache inducing logic... :(
|
|
||||||
(portal->mType != PORTS_STACKEDSECTORTHING) ||
|
|
||||||
(
|
|
||||||
check->Alpha == alpha &&
|
|
||||||
check->Additive == additive &&
|
|
||||||
(alpha == 0 || // if alpha is > 0 everything needs to be checked
|
|
||||||
(plane == check->height &&
|
|
||||||
picnum == check->picnum &&
|
|
||||||
lightlevel == check->lightlevel &&
|
|
||||||
basecolormap == check->colormap && // [RH] Add more checks
|
|
||||||
*xform == check->xform
|
|
||||||
)
|
|
||||||
) &&
|
|
||||||
check->viewangle == renderportal->stacked_angle
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return check;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return check;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (plane == check->height &&
|
|
||||||
picnum == check->picnum &&
|
|
||||||
lightlevel == check->lightlevel &&
|
|
||||||
basecolormap == check->colormap && // [RH] Add more checks
|
|
||||||
*xform == check->xform &&
|
|
||||||
sky == check->sky &&
|
|
||||||
renderportal->CurrentPortalUniq == check->CurrentPortalUniq &&
|
|
||||||
renderportal->MirrorFlags == check->MirrorFlags &&
|
|
||||||
Clip3DFloors::Instance()->CurrentSkybox == check->CurrentSkybox &&
|
|
||||||
ViewPos == check->viewpos
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return check;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check = Add(hash); // killough
|
|
||||||
|
|
||||||
check->height = plane;
|
|
||||||
check->picnum = picnum;
|
|
||||||
check->lightlevel = lightlevel;
|
|
||||||
check->xform = *xform;
|
|
||||||
check->colormap = basecolormap; // [RH] Save colormap
|
|
||||||
check->sky = sky;
|
|
||||||
check->portal = portal;
|
|
||||||
check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98
|
|
||||||
check->right = 0;
|
|
||||||
check->extralight = renderportal->stacked_extralight;
|
|
||||||
check->visibility = renderportal->stacked_visibility;
|
|
||||||
check->viewpos = renderportal->stacked_viewpos;
|
|
||||||
check->viewangle = renderportal->stacked_angle;
|
|
||||||
check->Alpha = alpha;
|
|
||||||
check->Additive = additive;
|
|
||||||
check->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
|
||||||
check->MirrorFlags = renderportal->MirrorFlags;
|
|
||||||
check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox;
|
|
||||||
|
|
||||||
fillshort(check->top, viewwidth, 0x7fff);
|
|
||||||
|
|
||||||
return check;
|
|
||||||
}
|
|
||||||
|
|
||||||
visplane_t *VisiblePlaneList::GetRange(visplane_t *pl, int start, int stop)
|
|
||||||
{
|
|
||||||
int intrl, intrh;
|
|
||||||
int unionl, unionh;
|
|
||||||
int x;
|
|
||||||
|
|
||||||
assert(start >= 0 && start < viewwidth);
|
|
||||||
assert(stop > start && stop <= viewwidth);
|
|
||||||
|
|
||||||
if (start < pl->left)
|
|
||||||
{
|
|
||||||
intrl = pl->left;
|
|
||||||
unionl = start;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unionl = pl->left;
|
|
||||||
intrl = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stop > pl->right)
|
|
||||||
{
|
|
||||||
intrh = pl->right;
|
|
||||||
unionh = stop;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unionh = pl->right;
|
|
||||||
intrh = stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x = intrl; x < intrh && pl->top[x] == 0x7fff; x++)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (x >= intrh)
|
|
||||||
{
|
|
||||||
// use the same visplane
|
|
||||||
pl->left = unionl;
|
|
||||||
pl->right = unionh;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// make a new visplane
|
|
||||||
unsigned hash;
|
|
||||||
|
|
||||||
if (pl->portal != nullptr && !(pl->portal->mFlags & PORTSF_INSKYBOX) && viewactive)
|
|
||||||
{
|
|
||||||
hash = MAXVISPLANES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hash = CalcHash(pl->picnum.GetIndex(), pl->lightlevel, pl->height);
|
|
||||||
}
|
|
||||||
visplane_t *new_pl = Add(hash);
|
|
||||||
|
|
||||||
new_pl->height = pl->height;
|
|
||||||
new_pl->picnum = pl->picnum;
|
|
||||||
new_pl->lightlevel = pl->lightlevel;
|
|
||||||
new_pl->xform = pl->xform;
|
|
||||||
new_pl->colormap = pl->colormap;
|
|
||||||
new_pl->portal = pl->portal;
|
|
||||||
new_pl->extralight = pl->extralight;
|
|
||||||
new_pl->visibility = pl->visibility;
|
|
||||||
new_pl->viewpos = pl->viewpos;
|
|
||||||
new_pl->viewangle = pl->viewangle;
|
|
||||||
new_pl->sky = pl->sky;
|
|
||||||
new_pl->Alpha = pl->Alpha;
|
|
||||||
new_pl->Additive = pl->Additive;
|
|
||||||
new_pl->CurrentPortalUniq = pl->CurrentPortalUniq;
|
|
||||||
new_pl->MirrorFlags = pl->MirrorFlags;
|
|
||||||
new_pl->CurrentSkybox = pl->CurrentSkybox;
|
|
||||||
new_pl->lights = pl->lights;
|
|
||||||
pl = new_pl;
|
|
||||||
pl->left = start;
|
|
||||||
pl->right = stop;
|
|
||||||
fillshort(pl->top, viewwidth, 0x7fff);
|
|
||||||
}
|
|
||||||
return pl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int VisiblePlaneList::Render()
|
|
||||||
{
|
|
||||||
visplane_t *pl;
|
|
||||||
int i;
|
|
||||||
int vpcount = 0;
|
|
||||||
|
|
||||||
drawerargs::ds_color = 3;
|
|
||||||
|
|
||||||
RenderPortal *renderportal = RenderPortal::Instance();
|
|
||||||
|
|
||||||
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)
|
|
||||||
continue;
|
|
||||||
// kg3D - draw only real planes now
|
|
||||||
if (pl->sky >= 0) {
|
|
||||||
vpcount++;
|
|
||||||
pl->Render(OPAQUE, false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vpcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisiblePlaneList::RenderHeight(double height)
|
|
||||||
{
|
|
||||||
visplane_t *pl;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
drawerargs::ds_color = 3;
|
|
||||||
|
|
||||||
DVector3 oViewPos = ViewPos;
|
|
||||||
DAngle oViewAngle = ViewAngle;
|
|
||||||
|
|
||||||
RenderPortal *renderportal = RenderPortal::Instance();
|
|
||||||
|
|
||||||
for (i = 0; i < MAXVISPLANES; i++)
|
|
||||||
{
|
|
||||||
for (pl = visplanes[i]; pl; pl = pl->next)
|
|
||||||
{
|
|
||||||
if (pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox || pl->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (pl->sky < 0 && pl->height.Zat0() == height)
|
|
||||||
{
|
|
||||||
ViewPos = pl->viewpos;
|
|
||||||
ViewAngle = pl->viewangle;
|
|
||||||
renderportal->MirrorFlags = pl->MirrorFlags;
|
|
||||||
|
|
||||||
pl->Render(pl->sky & 0x7FFFFFFF, pl->Additive, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ViewPos = oViewPos;
|
|
||||||
ViewAngle = oViewAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlaneRenderer::RenderLines(visplane_t *pl)
|
|
||||||
{
|
|
||||||
// t1/b1 are at x
|
|
||||||
// t2/b2 are at x+1
|
|
||||||
// spanend[y] is at the right edge
|
|
||||||
|
|
||||||
int x = pl->right - 1;
|
|
||||||
int t2 = pl->top[x];
|
|
||||||
int b2 = pl->bottom[x];
|
|
||||||
|
|
||||||
if (b2 > t2)
|
|
||||||
{
|
|
||||||
fillshort(spanend + t2, b2 - t2, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (--x; x >= pl->left; --x)
|
|
||||||
{
|
|
||||||
int t1 = pl->top[x];
|
|
||||||
int b1 = pl->bottom[x];
|
|
||||||
const int xr = x + 1;
|
|
||||||
int stop;
|
|
||||||
|
|
||||||
// Draw any spans that have just closed
|
|
||||||
stop = MIN(t1, b2);
|
|
||||||
while (t2 < stop)
|
|
||||||
{
|
|
||||||
int y = t2++;
|
|
||||||
int x2 = spanend[y];
|
|
||||||
RenderLine(y, xr, x2);
|
|
||||||
}
|
|
||||||
stop = MAX(b1, t2);
|
|
||||||
while (b2 > stop)
|
|
||||||
{
|
|
||||||
int y = --b2;
|
|
||||||
int x2 = spanend[y];
|
|
||||||
RenderLine(y, xr, x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark any spans that have just opened
|
|
||||||
stop = MIN(t2, b1);
|
|
||||||
while (t1 < stop)
|
|
||||||
{
|
|
||||||
spanend[t1++] = x;
|
|
||||||
}
|
|
||||||
stop = MAX(b2, t2);
|
|
||||||
while (b1 > stop)
|
|
||||||
{
|
|
||||||
spanend[--b1] = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
t2 = pl->top[x];
|
|
||||||
b2 = pl->bottom[x];
|
|
||||||
|
|
||||||
StepColumn();
|
|
||||||
}
|
|
||||||
// Draw any spans that are still open
|
|
||||||
while (t2 < b2)
|
|
||||||
{
|
|
||||||
int y = --b2;
|
|
||||||
int x2 = spanend[y];
|
|
||||||
RenderLine(y, pl->left, x2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,43 +68,4 @@ namespace swrenderer
|
||||||
void AddLights(FLightNode *node);
|
void AddLights(FLightNode *node);
|
||||||
void Render(fixed_t alpha, bool additive, bool masked);
|
void Render(fixed_t alpha, bool additive, bool masked);
|
||||||
};
|
};
|
||||||
|
|
||||||
class VisiblePlaneList
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static VisiblePlaneList *Instance();
|
|
||||||
|
|
||||||
void Init();
|
|
||||||
void Deinit();
|
|
||||||
void Clear(bool fullclear);
|
|
||||||
|
|
||||||
visplane_t *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal);
|
|
||||||
visplane_t *GetRange(visplane_t *pl, int start, int stop);
|
|
||||||
|
|
||||||
int Render();
|
|
||||||
void RenderHeight(double height);
|
|
||||||
|
|
||||||
enum { MAXVISPLANES = 128 }; // must be a power of 2
|
|
||||||
visplane_t *visplanes[MAXVISPLANES + 1];
|
|
||||||
visplane_t *freetail = nullptr;
|
|
||||||
visplane_t **freehead = nullptr;
|
|
||||||
|
|
||||||
private:
|
|
||||||
VisiblePlaneList();
|
|
||||||
visplane_t *Add(unsigned hash);
|
|
||||||
|
|
||||||
static unsigned CalcHash(int picnum, int lightlevel, const secplane_t &height) { return (unsigned)((picnum) * 3 + (lightlevel)+(FLOAT2FIXED((height).fD())) * 7) & (MAXVISPLANES - 1); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class PlaneRenderer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void RenderLines(visplane_t *pl);
|
|
||||||
|
|
||||||
virtual void RenderLine(int y, int x1, int x2) = 0;
|
|
||||||
virtual void StepColumn() { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
short spanend[MAXHEIGHT];
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
439
src/swrenderer/plane/r_visibleplanelist.cpp
Normal file
439
src/swrenderer/plane/r_visibleplanelist.cpp
Normal file
|
@ -0,0 +1,439 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
//
|
||||||
|
// This source is available for distribution and/or modification
|
||||||
|
// only under the terms of the DOOM Source Code License as
|
||||||
|
// published by id Software. All rights reserved.
|
||||||
|
//
|
||||||
|
// The source is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#include "templates.h"
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#include "stats.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "a_sharedglobal.h"
|
||||||
|
#include "c_console.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
#include "d_net.h"
|
||||||
|
#include "g_level.h"
|
||||||
|
#include "gl/dynlights/gl_dynlight.h"
|
||||||
|
#include "swrenderer/r_main.h"
|
||||||
|
#include "swrenderer/r_memory.h"
|
||||||
|
#include "swrenderer/scene/r_opaque_pass.h"
|
||||||
|
#include "swrenderer/scene/r_3dfloors.h"
|
||||||
|
#include "swrenderer/scene/r_portal.h"
|
||||||
|
#include "swrenderer/plane/r_flatplane.h"
|
||||||
|
#include "swrenderer/plane/r_slopeplane.h"
|
||||||
|
#include "swrenderer/plane/r_skyplane.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplanelist.h"
|
||||||
|
#include "swrenderer/drawers/r_draw.h"
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
VisiblePlaneList *VisiblePlaneList::Instance()
|
||||||
|
{
|
||||||
|
static VisiblePlaneList instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
VisiblePlaneList::VisiblePlaneList()
|
||||||
|
{
|
||||||
|
for (auto &plane : visplanes)
|
||||||
|
plane = nullptr;
|
||||||
|
freehead = &freetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisiblePlaneList::Deinit()
|
||||||
|
{
|
||||||
|
// do not use R_ClearPlanes because at this point the screen pointer is no longer valid.
|
||||||
|
for (int i = 0; i <= MAXVISPLANES; i++) // new code -- killough
|
||||||
|
{
|
||||||
|
for (*freehead = visplanes[i], visplanes[i] = nullptr; *freehead; )
|
||||||
|
{
|
||||||
|
freehead = &(*freehead)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (visplane_t *pl = freetail; pl != nullptr; )
|
||||||
|
{
|
||||||
|
visplane_t *next = pl->next;
|
||||||
|
free(pl);
|
||||||
|
pl = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visplane_t *VisiblePlaneList::Add(unsigned hash)
|
||||||
|
{
|
||||||
|
visplane_t *check = freetail;
|
||||||
|
|
||||||
|
if (check == nullptr)
|
||||||
|
{
|
||||||
|
check = (visplane_t *)M_Malloc(sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH * 2));
|
||||||
|
memset(check, 0, sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH * 2));
|
||||||
|
check->bottom = check->top + MAXWIDTH + 2;
|
||||||
|
}
|
||||||
|
else if (nullptr == (freetail = freetail->next))
|
||||||
|
{
|
||||||
|
freehead = &freetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
check->lights = nullptr;
|
||||||
|
|
||||||
|
check->next = visplanes[hash];
|
||||||
|
visplanes[hash] = check;
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisiblePlaneList::Init()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
visplane_t *pl;
|
||||||
|
|
||||||
|
// Free all visplanes and let them be re-allocated as needed.
|
||||||
|
pl = freetail;
|
||||||
|
|
||||||
|
while (pl)
|
||||||
|
{
|
||||||
|
visplane_t *next = pl->next;
|
||||||
|
M_Free(pl);
|
||||||
|
pl = next;
|
||||||
|
}
|
||||||
|
freetail = nullptr;
|
||||||
|
freehead = &freetail;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXVISPLANES; i++)
|
||||||
|
{
|
||||||
|
pl = visplanes[i];
|
||||||
|
visplanes[i] = nullptr;
|
||||||
|
while (pl)
|
||||||
|
{
|
||||||
|
visplane_t *next = pl->next;
|
||||||
|
M_Free(pl);
|
||||||
|
pl = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisiblePlaneList::Clear(bool fullclear)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Don't clear fake planes if not doing a full clear.
|
||||||
|
if (!fullclear)
|
||||||
|
{
|
||||||
|
for (i = 0; i <= MAXVISPLANES - 1; i++) // new code -- killough
|
||||||
|
{
|
||||||
|
for (visplane_t **probe = &visplanes[i]; *probe != nullptr; )
|
||||||
|
{
|
||||||
|
if ((*probe)->sky < 0)
|
||||||
|
{ // fake: move past it
|
||||||
|
probe = &(*probe)->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // not fake: move to freelist
|
||||||
|
visplane_t *vis = *probe;
|
||||||
|
*freehead = vis;
|
||||||
|
*probe = vis->next;
|
||||||
|
vis->next = nullptr;
|
||||||
|
freehead = &vis->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i <= MAXVISPLANES; i++) // new code -- killough
|
||||||
|
{
|
||||||
|
for (*freehead = visplanes[i], visplanes[i] = nullptr; *freehead; )
|
||||||
|
{
|
||||||
|
freehead = &(*freehead)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visplane_t *VisiblePlaneList::FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal)
|
||||||
|
{
|
||||||
|
secplane_t plane;
|
||||||
|
visplane_t *check;
|
||||||
|
unsigned hash; // killough
|
||||||
|
bool isskybox;
|
||||||
|
const FTransform *xform = &xxform;
|
||||||
|
fixed_t alpha = FLOAT2FIXED(Alpha);
|
||||||
|
//angle_t angle = (xform.Angle + xform.baseAngle).BAMs();
|
||||||
|
|
||||||
|
FTransform nulltransform;
|
||||||
|
|
||||||
|
if (picnum == skyflatnum) // killough 10/98
|
||||||
|
{ // most skies map together
|
||||||
|
lightlevel = 0;
|
||||||
|
xform = &nulltransform;
|
||||||
|
nulltransform.xOffs = nulltransform.yOffs = nulltransform.baseyOffs = 0;
|
||||||
|
nulltransform.xScale = nulltransform.yScale = 1;
|
||||||
|
nulltransform.Angle = nulltransform.baseAngle = 0.0;
|
||||||
|
additive = false;
|
||||||
|
// [RH] Map floor skies and ceiling skies to separate visplanes. This isn't
|
||||||
|
// always necessary, but it is needed if a floor and ceiling sky are in the
|
||||||
|
// same column but separated by a wall. If they both try to reside in the
|
||||||
|
// same visplane, then only the floor sky will be drawn.
|
||||||
|
plane.set(0., 0., height.fC(), 0.);
|
||||||
|
isskybox = portal != nullptr && !(portal->mFlags & PORTSF_INSKYBOX);
|
||||||
|
}
|
||||||
|
else if (portal != nullptr && !(portal->mFlags & PORTSF_INSKYBOX))
|
||||||
|
{
|
||||||
|
plane = height;
|
||||||
|
isskybox = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plane = height;
|
||||||
|
isskybox = false;
|
||||||
|
// 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();
|
||||||
|
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;
|
||||||
|
alpha = OPAQUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// New visplane algorithm uses hash table -- killough
|
||||||
|
hash = isskybox ? MAXVISPLANES : CalcHash(picnum.GetIndex(), lightlevel, height);
|
||||||
|
|
||||||
|
RenderPortal *renderportal = RenderPortal::Instance();
|
||||||
|
|
||||||
|
for (check = visplanes[hash]; check; check = check->next) // killough
|
||||||
|
{
|
||||||
|
if (isskybox)
|
||||||
|
{
|
||||||
|
if (portal == check->portal && plane == check->height)
|
||||||
|
{
|
||||||
|
if (portal->mType != PORTS_SKYVIEWPOINT)
|
||||||
|
{ // This skybox is really a stacked sector, so we need to
|
||||||
|
// check even more.
|
||||||
|
if (check->extralight == renderportal->stacked_extralight &&
|
||||||
|
check->visibility == renderportal->stacked_visibility &&
|
||||||
|
check->viewpos == renderportal->stacked_viewpos &&
|
||||||
|
(
|
||||||
|
// headache inducing logic... :(
|
||||||
|
(portal->mType != PORTS_STACKEDSECTORTHING) ||
|
||||||
|
(
|
||||||
|
check->Alpha == alpha &&
|
||||||
|
check->Additive == additive &&
|
||||||
|
(alpha == 0 || // if alpha is > 0 everything needs to be checked
|
||||||
|
(plane == check->height &&
|
||||||
|
picnum == check->picnum &&
|
||||||
|
lightlevel == check->lightlevel &&
|
||||||
|
basecolormap == check->colormap && // [RH] Add more checks
|
||||||
|
*xform == check->xform
|
||||||
|
)
|
||||||
|
) &&
|
||||||
|
check->viewangle == renderportal->stacked_angle
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (plane == check->height &&
|
||||||
|
picnum == check->picnum &&
|
||||||
|
lightlevel == check->lightlevel &&
|
||||||
|
basecolormap == check->colormap && // [RH] Add more checks
|
||||||
|
*xform == check->xform &&
|
||||||
|
sky == check->sky &&
|
||||||
|
renderportal->CurrentPortalUniq == check->CurrentPortalUniq &&
|
||||||
|
renderportal->MirrorFlags == check->MirrorFlags &&
|
||||||
|
Clip3DFloors::Instance()->CurrentSkybox == check->CurrentSkybox &&
|
||||||
|
ViewPos == check->viewpos
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check = Add(hash); // killough
|
||||||
|
|
||||||
|
check->height = plane;
|
||||||
|
check->picnum = picnum;
|
||||||
|
check->lightlevel = lightlevel;
|
||||||
|
check->xform = *xform;
|
||||||
|
check->colormap = basecolormap; // [RH] Save colormap
|
||||||
|
check->sky = sky;
|
||||||
|
check->portal = portal;
|
||||||
|
check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98
|
||||||
|
check->right = 0;
|
||||||
|
check->extralight = renderportal->stacked_extralight;
|
||||||
|
check->visibility = renderportal->stacked_visibility;
|
||||||
|
check->viewpos = renderportal->stacked_viewpos;
|
||||||
|
check->viewangle = renderportal->stacked_angle;
|
||||||
|
check->Alpha = alpha;
|
||||||
|
check->Additive = additive;
|
||||||
|
check->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||||
|
check->MirrorFlags = renderportal->MirrorFlags;
|
||||||
|
check->CurrentSkybox = Clip3DFloors::Instance()->CurrentSkybox;
|
||||||
|
|
||||||
|
fillshort(check->top, viewwidth, 0x7fff);
|
||||||
|
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
|
||||||
|
visplane_t *VisiblePlaneList::GetRange(visplane_t *pl, int start, int stop)
|
||||||
|
{
|
||||||
|
int intrl, intrh;
|
||||||
|
int unionl, unionh;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
assert(start >= 0 && start < viewwidth);
|
||||||
|
assert(stop > start && stop <= viewwidth);
|
||||||
|
|
||||||
|
if (start < pl->left)
|
||||||
|
{
|
||||||
|
intrl = pl->left;
|
||||||
|
unionl = start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unionl = pl->left;
|
||||||
|
intrl = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stop > pl->right)
|
||||||
|
{
|
||||||
|
intrh = pl->right;
|
||||||
|
unionh = stop;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unionh = pl->right;
|
||||||
|
intrh = stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = intrl; x < intrh && pl->top[x] == 0x7fff; x++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (x >= intrh)
|
||||||
|
{
|
||||||
|
// use the same visplane
|
||||||
|
pl->left = unionl;
|
||||||
|
pl->right = unionh;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// make a new visplane
|
||||||
|
unsigned hash;
|
||||||
|
|
||||||
|
if (pl->portal != nullptr && !(pl->portal->mFlags & PORTSF_INSKYBOX) && viewactive)
|
||||||
|
{
|
||||||
|
hash = MAXVISPLANES;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hash = CalcHash(pl->picnum.GetIndex(), pl->lightlevel, pl->height);
|
||||||
|
}
|
||||||
|
visplane_t *new_pl = Add(hash);
|
||||||
|
|
||||||
|
new_pl->height = pl->height;
|
||||||
|
new_pl->picnum = pl->picnum;
|
||||||
|
new_pl->lightlevel = pl->lightlevel;
|
||||||
|
new_pl->xform = pl->xform;
|
||||||
|
new_pl->colormap = pl->colormap;
|
||||||
|
new_pl->portal = pl->portal;
|
||||||
|
new_pl->extralight = pl->extralight;
|
||||||
|
new_pl->visibility = pl->visibility;
|
||||||
|
new_pl->viewpos = pl->viewpos;
|
||||||
|
new_pl->viewangle = pl->viewangle;
|
||||||
|
new_pl->sky = pl->sky;
|
||||||
|
new_pl->Alpha = pl->Alpha;
|
||||||
|
new_pl->Additive = pl->Additive;
|
||||||
|
new_pl->CurrentPortalUniq = pl->CurrentPortalUniq;
|
||||||
|
new_pl->MirrorFlags = pl->MirrorFlags;
|
||||||
|
new_pl->CurrentSkybox = pl->CurrentSkybox;
|
||||||
|
new_pl->lights = pl->lights;
|
||||||
|
pl = new_pl;
|
||||||
|
pl->left = start;
|
||||||
|
pl->right = stop;
|
||||||
|
fillshort(pl->top, viewwidth, 0x7fff);
|
||||||
|
}
|
||||||
|
return pl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int VisiblePlaneList::Render()
|
||||||
|
{
|
||||||
|
visplane_t *pl;
|
||||||
|
int i;
|
||||||
|
int vpcount = 0;
|
||||||
|
|
||||||
|
drawerargs::ds_color = 3;
|
||||||
|
|
||||||
|
RenderPortal *renderportal = RenderPortal::Instance();
|
||||||
|
|
||||||
|
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)
|
||||||
|
continue;
|
||||||
|
// kg3D - draw only real planes now
|
||||||
|
if (pl->sky >= 0) {
|
||||||
|
vpcount++;
|
||||||
|
pl->Render(OPAQUE, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vpcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VisiblePlaneList::RenderHeight(double height)
|
||||||
|
{
|
||||||
|
visplane_t *pl;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
drawerargs::ds_color = 3;
|
||||||
|
|
||||||
|
DVector3 oViewPos = ViewPos;
|
||||||
|
DAngle oViewAngle = ViewAngle;
|
||||||
|
|
||||||
|
RenderPortal *renderportal = RenderPortal::Instance();
|
||||||
|
|
||||||
|
for (i = 0; i < MAXVISPLANES; i++)
|
||||||
|
{
|
||||||
|
for (pl = visplanes[i]; pl; pl = pl->next)
|
||||||
|
{
|
||||||
|
if (pl->CurrentSkybox != Clip3DFloors::Instance()->CurrentSkybox || pl->CurrentPortalUniq != renderportal->CurrentPortalUniq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pl->sky < 0 && pl->height.Zat0() == height)
|
||||||
|
{
|
||||||
|
ViewPos = pl->viewpos;
|
||||||
|
ViewAngle = pl->viewangle;
|
||||||
|
renderportal->MirrorFlags = pl->MirrorFlags;
|
||||||
|
|
||||||
|
pl->Render(pl->sky & 0x7FFFFFFF, pl->Additive, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ViewPos = oViewPos;
|
||||||
|
ViewAngle = oViewAngle;
|
||||||
|
}
|
||||||
|
}
|
51
src/swrenderer/plane/r_visibleplanelist.h
Normal file
51
src/swrenderer/plane/r_visibleplanelist.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
//
|
||||||
|
// This source is available for distribution and/or modification
|
||||||
|
// only under the terms of the DOOM Source Code License as
|
||||||
|
// published by id Software. All rights reserved.
|
||||||
|
//
|
||||||
|
// The source is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||||
|
// for more details.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "r_defs.h"
|
||||||
|
|
||||||
|
struct FSectorPortal;
|
||||||
|
|
||||||
|
namespace swrenderer
|
||||||
|
{
|
||||||
|
struct visplane_t;
|
||||||
|
|
||||||
|
class VisiblePlaneList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static VisiblePlaneList *Instance();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Deinit();
|
||||||
|
void Clear(bool fullclear);
|
||||||
|
|
||||||
|
visplane_t *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal);
|
||||||
|
visplane_t *GetRange(visplane_t *pl, int start, int stop);
|
||||||
|
|
||||||
|
int Render();
|
||||||
|
void RenderHeight(double height);
|
||||||
|
|
||||||
|
enum { MAXVISPLANES = 128 }; // must be a power of 2
|
||||||
|
visplane_t *visplanes[MAXVISPLANES + 1];
|
||||||
|
visplane_t *freetail = nullptr;
|
||||||
|
visplane_t **freehead = nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VisiblePlaneList();
|
||||||
|
visplane_t *Add(unsigned hash);
|
||||||
|
|
||||||
|
static unsigned CalcHash(int picnum, int lightlevel, const secplane_t &height) { return (unsigned)((picnum) * 3 + (lightlevel)+(FLOAT2FIXED((height).fD())) * 7) & (MAXVISPLANES - 1); }
|
||||||
|
};
|
||||||
|
}
|
|
@ -69,6 +69,7 @@
|
||||||
#include "c_console.h"
|
#include "c_console.h"
|
||||||
#include "r_memory.h"
|
#include "r_memory.h"
|
||||||
#include "swrenderer/things/r_playersprite.h"
|
#include "swrenderer/things/r_playersprite.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplanelist.h"
|
||||||
|
|
||||||
CVAR (String, r_viewsize, "", CVAR_NOSET)
|
CVAR (String, r_viewsize, "", CVAR_NOSET)
|
||||||
CVAR (Bool, r_shadercolormaps, true, CVAR_ARCHIVE)
|
CVAR (Bool, r_shadercolormaps, true, CVAR_ARCHIVE)
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "swrenderer/r_main.h"
|
#include "swrenderer/r_main.h"
|
||||||
#include "swrenderer/drawers/r_draw.h"
|
#include "swrenderer/drawers/r_draw.h"
|
||||||
#include "swrenderer/plane/r_visibleplane.h"
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplanelist.h"
|
||||||
#include "swrenderer/things/r_sprite.h"
|
#include "swrenderer/things/r_sprite.h"
|
||||||
#include "swrenderer/things/r_wallsprite.h"
|
#include "swrenderer/things/r_wallsprite.h"
|
||||||
#include "swrenderer/things/r_voxel.h"
|
#include "swrenderer/things/r_voxel.h"
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "swrenderer/segments/r_clipsegment.h"
|
#include "swrenderer/segments/r_clipsegment.h"
|
||||||
#include "swrenderer/segments/r_drawsegment.h"
|
#include "swrenderer/segments/r_drawsegment.h"
|
||||||
#include "swrenderer/plane/r_visibleplane.h"
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplanelist.h"
|
||||||
#include "swrenderer/things/r_visiblesprite.h"
|
#include "swrenderer/things/r_visiblesprite.h"
|
||||||
#include "swrenderer/scene/r_opaque_pass.h"
|
#include "swrenderer/scene/r_opaque_pass.h"
|
||||||
#include "swrenderer/scene/r_translucent_pass.h"
|
#include "swrenderer/scene/r_translucent_pass.h"
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "swrenderer/scene/r_portal.h"
|
#include "swrenderer/scene/r_portal.h"
|
||||||
#include "swrenderer/scene/r_translucent_pass.h"
|
#include "swrenderer/scene/r_translucent_pass.h"
|
||||||
#include "swrenderer/plane/r_visibleplane.h"
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplanelist.h"
|
||||||
#include "swrenderer/r_memory.h"
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Int, r_drawfuzz)
|
EXTERN_CVAR(Int, r_drawfuzz)
|
||||||
|
|
Loading…
Reference in a new issue