- started adding a SceneDrawer class to the OpenGL renderer.

This will eventually hold all the global variables for the rendering.
This commit is contained in:
Christoph Oelckers 2017-03-12 00:19:20 +01:00
parent 8e2ebe15fe
commit 0aa0db637c
11 changed files with 149 additions and 145 deletions

View file

@ -2143,7 +2143,6 @@ void AM_showSS()
{
AM_drawSeg(sub->firstline + i, yellow);
}
PO_LinkToSubsectors();
for (int i = 0; i <po_NumPolyobjs; i++)
{

View file

@ -168,7 +168,6 @@ public:
void Initialize(int width, int height);
void CreateScene();
void RenderMultipassStuff();
void RenderScene(int recursion);
void RenderTranslucent();

View file

@ -38,31 +38,26 @@
#include "gl/renderer/gl_renderer.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/scene/gl_clipper.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/scene/gl_portal.h"
#include "gl/scene/gl_wall.h"
#include "gl/utility/gl_clock.h"
EXTERN_CVAR(Bool, gl_render_segs)
Clipper clipper;
CVAR(Bool, gl_render_things, true, 0)
CVAR(Bool, gl_render_walls, true, 0)
CVAR(Bool, gl_render_flats, true, 0)
extern fixed_t viewx, viewy;
static void UnclipSubsector(subsector_t *sub)
void GLSceneDrawer::UnclipSubsector(subsector_t *sub)
{
int count = sub->numlines;
seg_t * seg = sub->firstline;
while (count--)
{
angle_t startAngle = seg->v2->GetClipAngle();
angle_t endAngle = seg->v1->GetClipAngle();
angle_t startAngle = clipper.GetClipAngle(seg->v2);
angle_t endAngle = clipper.GetClipAngle(seg->v1);
// Back side, i.e. backface culling - read: endAngle >= startAngle!
if (startAngle-endAngle >= ANGLE_180)
@ -82,11 +77,7 @@ static void UnclipSubsector(subsector_t *sub)
//
//==========================================================================
// making these 2 variables global instead of passing them as function parameters is faster.
static subsector_t *currentsubsector;
static sector_t *currentsector;
static void AddLine (seg_t *seg, bool portalclip)
void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
{
#ifdef _DEBUG
if (seg->linedef->Index() == 38)
@ -95,7 +86,6 @@ static void AddLine (seg_t *seg, bool portalclip)
}
#endif
angle_t startAngle, endAngle;
sector_t * backsector = NULL;
sector_t bs;
@ -105,8 +95,8 @@ static void AddLine (seg_t *seg, bool portalclip)
if (clipres == GLPortal::PClip_InFront) return;
}
startAngle = seg->v2->GetClipAngle();
endAngle = seg->v1->GetClipAngle();
angle_t startAngle = clipper.GetClipAngle(seg->v2);
angle_t endAngle = clipper.GetClipAngle(seg->v1);
// Back side, i.e. backface culling - read: endAngle >= startAngle!
if (startAngle-endAngle<ANGLE_180)
@ -202,7 +192,7 @@ static void AddLine (seg_t *seg, bool portalclip)
//
//==========================================================================
static void PolySubsector(subsector_t * sub)
void GLSceneDrawer::PolySubsector(subsector_t * sub)
{
int count = sub->numlines;
seg_t * line = sub->firstline;
@ -226,7 +216,7 @@ static void PolySubsector(subsector_t * sub)
//
//==========================================================================
static void RenderPolyBSPNode (void *node)
void GLSceneDrawer::RenderPolyBSPNode (void *node)
{
while (!((size_t)node & 1)) // Keep going until found a subsector
{
@ -259,7 +249,7 @@ static void RenderPolyBSPNode (void *node)
//
//==========================================================================
static void AddPolyobjs(subsector_t *sub)
void GLSceneDrawer::AddPolyobjs(subsector_t *sub)
{
if (sub->BSP == NULL || sub->BSP->bDirty)
{
@ -287,7 +277,7 @@ static void AddPolyobjs(subsector_t *sub)
//
//==========================================================================
static inline void AddLines(subsector_t * sub, sector_t * sector)
void GLSceneDrawer::AddLines(subsector_t * sub, sector_t * sector)
{
currentsector = sector;
currentsubsector = sub;
@ -331,7 +321,7 @@ inline bool PointOnLine(const DVector2 &pos, const line_t *line)
return fabs(v) <= EQUAL_EPSILON;
}
static inline void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line)
void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line)
{
currentsector = sector;
currentsubsector = sub;
@ -359,9 +349,8 @@ static inline void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, l
//
//==========================================================================
static inline void RenderThings(subsector_t * sub, sector_t * sector)
void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
{
SetupSprite.Clock();
sector_t * sec=sub->sector;
// Handle all things in sector.
@ -414,7 +403,7 @@ static inline void RenderThings(subsector_t * sub, sector_t * sector)
//
//==========================================================================
static void DoSubsector(subsector_t * sub)
void GLSceneDrawer::DoSubsector(subsector_t * sub)
{
unsigned int i;
sector_t * sector;
@ -559,7 +548,7 @@ static void DoSubsector(subsector_t * sub)
//
//==========================================================================
void gl_RenderBSPNode (void *node)
void GLSceneDrawer::RenderBSPNode (void *node)
{
if (numnodes == 0)
{
@ -574,7 +563,7 @@ void gl_RenderBSPNode (void *node)
int side = R_PointOnSide(viewx, viewy, bsp);
// Recursively divide front space (toward the viewer).
gl_RenderBSPNode (bsp->children[side]);
RenderBSPNode (bsp->children[side]);
// Possibly divide back space (away from the viewer).
side ^= 1;

View file

@ -36,28 +36,12 @@
*/
#include "gl/scene/gl_clipper.h"
#include "g_levellocals.h"
ClipNode * ClipNode::freelist;
int Clipper::anglecache;
//-----------------------------------------------------------------------------
//
// Destructor
//
//-----------------------------------------------------------------------------
Clipper::~Clipper()
Clipper::Clipper()
{
Clear();
while (ClipNode::freelist != NULL)
{
ClipNode * node = ClipNode::freelist;
ClipNode::freelist = node->next;
delete node;
}
starttime = I_MSTime();
}
//-----------------------------------------------------------------------------
@ -78,7 +62,7 @@ void Clipper::RemoveRange(ClipNode * range)
if (range->next) range->next->prev = range->prev;
}
range->Free();
Free(range);
}
//-----------------------------------------------------------------------------
@ -97,7 +81,7 @@ void Clipper::Clear()
{
temp = node;
node = node->next;
temp->Free();
Free(temp);
}
node = silhouette;
@ -105,12 +89,12 @@ void Clipper::Clear()
{
temp = node;
node = node->next;
temp->Free();
Free(temp);
}
cliphead = NULL;
silhouette = NULL;
anglecache++;
starttime = I_MSTime();
}
//-----------------------------------------------------------------------------
@ -126,7 +110,7 @@ void Clipper::SetSilhouette()
while (node != NULL)
{
ClipNode *snode = ClipNode::NewRange(node->start, node->end);
ClipNode *snode = NewRange(node->start, node->end);
if (silhouette == NULL) silhouette = snode;
snode->prev = last;
if (last != NULL) last->next = snode;
@ -135,7 +119,6 @@ void Clipper::SetSilhouette()
}
}
//-----------------------------------------------------------------------------
//
// IsRangeVisible
@ -227,7 +210,7 @@ void Clipper::AddClipRange(angle_t start, angle_t end)
//just add range
node = cliphead;
prevNode = NULL;
temp = ClipNode::NewRange(start, end);
temp = NewRange(start, end);
while (node != NULL && node->start < end)
{
@ -259,7 +242,7 @@ void Clipper::AddClipRange(angle_t start, angle_t end)
}
else
{
temp = ClipNode::NewRange(start, end);
temp = NewRange(start, end);
cliphead = temp;
return;
}
@ -343,7 +326,7 @@ void Clipper::DoRemoveClipRange(angle_t start, angle_t end)
}
else if (node->start < start && node->end > end)
{
temp=ClipNode::NewRange(end, node->end);
temp = NewRange(end, node->end);
node->end=start;
temp->next=node->next;
temp->prev=node;
@ -389,14 +372,6 @@ angle_t Clipper::AngleToPseudo(angle_t ang)
//
//-----------------------------------------------------------------------------
fixed_t viewx, viewy;
void R_SetView()
{
viewx = FLOAT2FIXED(ViewPos.X);
viewy = FLOAT2FIXED(ViewPos.Y);
}
angle_t R_PointToPseudoAngle(double x, double y)
{
double vecx = x - ViewPos.X;
@ -411,7 +386,7 @@ angle_t R_PointToPseudoAngle(double x, double y)
double result = vecy / (fabs(vecx) + fabs(vecy));
if (vecx < 0)
{
result = 2.f - result;
result = 2. - result;
}
return xs_Fix<30>::ToFix(result);
}

View file

@ -4,57 +4,41 @@
#include "doomtype.h"
#include "xs_Float.h"
#include "r_utility.h"
#include "memarena.h"
angle_t R_PointToPseudoAngle(double x, double y);
// Used to speed up angle calculations during clipping
inline angle_t vertex_t::GetClipAngle()
{
return R_PointToPseudoAngle(p.X, p.Y);
}
class ClipNode
{
friend class Clipper;
friend class ClipNodesFreer;
ClipNode *prev, *next;
angle_t start, end;
static ClipNode * freelist;
bool operator== (const ClipNode &other)
{
return other.start == start && other.end == end;
}
void Free()
{
next=freelist;
freelist=this;
}
static ClipNode * GetNew()
{
if (freelist)
{
ClipNode * p=freelist;
freelist=p->next;
return p;
}
else return new ClipNode;
}
static ClipNode * NewRange(angle_t start, angle_t end)
{
ClipNode * c=GetNew();
c->start=start;
c->end=end;
c->next=c->prev=NULL;
return c;
}
};
class Clipper
{
ClipNode * clipnodes;
ClipNode * cliphead;
ClipNode * silhouette; // will be preserved even when RemoveClipRange is called
bool blocked;
unsigned starttime;
TStaticArray<angle_t> anglecache;
FMemArena nodearena;
ClipNode * freelist = nullptr;
ClipNode * clipnodes = nullptr;
ClipNode * cliphead = nullptr;
ClipNode * silhouette = nullptr; // will be preserved even when RemoveClipRange is called
bool blocked = false;
static angle_t AngleToPseudo(angle_t ang);
bool IsRangeVisible(angle_t startangle, angle_t endangle);
@ -65,18 +49,36 @@ class Clipper
public:
static int anglecache;
Clipper()
{
blocked = false;
clipnodes=cliphead=NULL;
}
~Clipper();
Clipper();
void Clear();
void Free(ClipNode *node)
{
node->next = freelist;
freelist = node;
}
ClipNode * GetNew()
{
if (freelist)
{
ClipNode * p = freelist;
freelist = p->next;
return p;
}
else return (ClipNode*)nodearena.Alloc(sizeof(ClipNode));
}
ClipNode * NewRange(angle_t start, angle_t end)
{
ClipNode * c = GetNew();
c->start = start;
c->end = end;
c->next = c->prev = NULL;
return c;
}
void SetSilhouette();
@ -142,18 +144,13 @@ public:
}
bool CheckBox(const float *bspcoord);
// Used to speed up angle calculations during clipping
inline angle_t GetClipAngle(vertex_t *v)
{
return v->angletime == starttime ? v->viewangle : (v->angletime = starttime, v->viewangle = R_PointToPseudoAngle(v->p.X, v->p.Y));
}
};
extern Clipper clipper;
angle_t R_PointToPseudoAngle(double x, double y);
void R_SetView();
// Used to speed up angle calculations during clipping
inline angle_t vertex_t::GetClipAngle()
{
return angletime == Clipper::anglecache? viewangle : (angletime = Clipper::anglecache, viewangle = R_PointToPseudoAngle(p.X, p.Y));
}
#endif

View file

@ -51,6 +51,7 @@
#include "gl/scene/gl_clipper.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/shaders/gl_shader.h"
#include "gl/stereo3d/scoped_color_mask.h"
#include "gl/textures/gl_material.h"
@ -74,6 +75,7 @@ EXTERN_CVAR(Int, r_mirror_recursions)
extern bool r_showviewer;
GLSceneDrawer *GLPortal::drawer;
TArray<GLPortal *> GLPortal::portals;
TArray<float> GLPortal::planestack;
int GLPortal::recursion;
@ -310,12 +312,12 @@ inline void GLPortal::ClearClipper()
{
DAngle angleOffset = deltaangle(savedAngle, ViewAngle);
clipper.Clear();
drawer->clipper.Clear();
static int call=0;
// Set the clipper to the minimal visible area
clipper.SafeAddClipRange(0,0xffffffff);
drawer->clipper.SafeAddClipRange(0,0xffffffff);
for (unsigned int i = 0; i < lines.Size(); i++)
{
DAngle startAngle = (DVector2(lines[i].glseg.x2, lines[i].glseg.y2) - savedViewPos).Angle() + angleOffset;
@ -323,16 +325,16 @@ inline void GLPortal::ClearClipper()
if (deltaangle(endAngle, startAngle) < 0)
{
clipper.SafeRemoveClipRangeRealAngles(startAngle.BAMs(), endAngle.BAMs());
drawer->clipper.SafeRemoveClipRangeRealAngles(startAngle.BAMs(), endAngle.BAMs());
}
}
// and finally clip it to the visible area
angle_t a1 = GLRenderer->FrustumAngle();
if (a1 < ANGLE_180) clipper.SafeAddClipRangeRealAngles(ViewAngle.BAMs() + a1, ViewAngle.BAMs() - a1);
if (a1 < ANGLE_180) drawer->clipper.SafeAddClipRangeRealAngles(ViewAngle.BAMs() + a1, ViewAngle.BAMs() - a1);
// lock the parts that have just been clipped out.
clipper.SetSilhouette();
drawer->clipper.SetSilhouette();
}
//-----------------------------------------------------------------------------
@ -754,8 +756,8 @@ void GLSectorStackPortal::DrawContents()
subsector_t *sub = R_PointInSubsector(ViewPos);
if (!(gl_drawinfo->ss_renderflags[sub - ::subsectors] & SSRF_SEEN))
{
clipper.SafeAddClipRange(0, ANGLE_MAX);
clipper.SetBlocked(true);
drawer->clipper.SafeAddClipRange(0, ANGLE_MAX);
drawer->clipper.SetBlocked(true);
}
GLRenderer->DrawScene(DM_PORTAL);
@ -969,14 +971,14 @@ void GLMirrorPortal::DrawContents()
MirrorFlag++;
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
clipper.Clear();
drawer->clipper.Clear();
angle_t af = GLRenderer->FrustumAngle();
if (af<ANGLE_180) clipper.SafeAddClipRangeRealAngles(ViewAngle.BAMs()+af, ViewAngle.BAMs()-af);
if (af<ANGLE_180) drawer->clipper.SafeAddClipRangeRealAngles(ViewAngle.BAMs()+af, ViewAngle.BAMs()-af);
angle_t a2 = linedef->v1->GetClipAngle();
angle_t a1 = linedef->v2->GetClipAngle();
clipper.SafeAddClipRange(a1,a2);
drawer->clipper.SafeAddClipRange(a1,a2);
gl_RenderState.SetClipLine(linedef);
gl_RenderState.EnableClipLine(true);

View file

@ -77,6 +77,7 @@ extern UniqueList<GLHorizonInfo> UniqueHorizons;
extern UniqueList<secplane_t> UniquePlaneMirrors;
extern UniqueList<FGLLinePortal> UniqueLineToLines;
struct GLEEHorizonPortal;
class GLSceneDrawer;
class GLPortal
{
@ -90,6 +91,7 @@ protected:
static int renderdepth;
public:
static GLSceneDrawer *drawer;
static int PlaneMirrorMode;
static int inupperstack;
static int instack[2];

View file

@ -60,6 +60,7 @@
#include "gl/scene/gl_clipper.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/shaders/gl_shader.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/stereo3d/scoped_view_shifter.h"
@ -267,22 +268,25 @@ void FGLRenderer::SetupView(float vx, float vy, float vz, DAngle va, bool mirror
//
//-----------------------------------------------------------------------------
void FGLRenderer::CreateScene()
void GLSceneDrawer::CreateScene()
{
angle_t a1 = GLRenderer->FrustumAngle();
InitClipper(ViewAngle.BAMs() + a1, ViewAngle.BAMs() - a1);
GLPortal::drawer = this; // NOTE THAT THIS DOES NOT WORK YET!!! (only good to let it compile without further changes.)
// reset the portal manager
GLPortal::StartFrame();
PO_LinkToSubsectors();
ProcessAll.Clock();
// clip the scene and fill the drawlists
for(unsigned i=0;i<portals.Size(); i++) portals[i]->glportal = NULL;
gl_spriteindex=0;
GLRenderer->gl_spriteindex=0;
Bsp.Clock();
GLRenderer->mVBO->Map();
R_SetView();
SetView();
validcount++; // used for processing sidedefs only once by the renderer.
gl_RenderBSPNode (nodes + numnodes - 1);
RenderBSPNode (nodes + numnodes - 1);
if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached();
Bsp.Unclock();
@ -497,15 +501,17 @@ void FGLRenderer::DrawScene(int drawmode)
ssao_portals_available--;
}
GLSceneDrawer drawer;
if (camera != nullptr)
{
ActorRenderFlags savedflags = camera->renderflags;
CreateScene();
drawer.CreateScene();
camera->renderflags = savedflags;
}
else
{
CreateScene();
drawer.CreateScene();
}
GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place.
@ -854,10 +860,6 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
SetViewMatrix(ViewPos.X, ViewPos.Y, ViewPos.Z, false, false);
gl_RenderState.ApplyMatrices();
clipper.Clear();
angle_t a1 = FrustumAngle();
clipper.SafeAddClipRangeRealAngles(ViewAngle.BAMs() + a1, ViewAngle.BAMs() - a1);
ProcessScene(toscreen);
if (mainview && toscreen) EndDrawScene(lviewsector); // do not call this for camera textures.
if (mainview && FGLRenderBuffers::IsEnabled())

View file

@ -0,0 +1,40 @@
#pragma once
#include "r_defs.h"
#include "m_fixed.h"
#include "gl_clipper.h"
class GLSceneDrawer
{
fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster.
subsector_t *currentsubsector; // used by the line processing code.
sector_t *currentsector;
void UnclipSubsector(subsector_t *sub);
void AddLine (seg_t *seg, bool portalclip);
void PolySubsector(subsector_t * sub);
void RenderPolyBSPNode (void *node);
void AddPolyobjs(subsector_t *sub);
void AddLines(subsector_t * sub, sector_t * sector);
void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line);
void RenderThings(subsector_t * sub, sector_t * sector);
void DoSubsector(subsector_t * sub);
void RenderBSPNode(void *node);
public:
Clipper clipper;
void CreateScene();
void InitClipper(angle_t a1, angle_t a2)
{
clipper.SafeAddClipRangeRealAngles(a1, a2);
}
void SetView()
{
viewx = FLOAT2FIXED(ViewPos.X);
viewy = FLOAT2FIXED(ViewPos.Y);
}
};

View file

@ -684,6 +684,8 @@ void R_SetupFrame (AActor *actor)
I_Error ("Tried to render from a NULL actor.");
}
PO_LinkToSubsectors();
player_t *player = actor->player;
unsigned int newblend;
InterpolationViewer *iview;

View file

@ -143,9 +143,6 @@ namespace swrenderer
// [RH] Setup particles for this frame
P_FindParticleSubsectors();
// Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function
PO_LinkToSubsectors();
ActorRenderFlags savedflags = camera->renderflags;
// Never draw the player unless in chasecam mode
if (!r_showviewer)