mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-28 06:32:29 +00:00
- refactoring of portal grouping for the renderer, to allow more efficient clipping.
This commit is contained in:
parent
af1b70376b
commit
dbd89c2702
6 changed files with 151 additions and 74 deletions
|
@ -54,7 +54,17 @@ struct FPortal
|
|||
GLSectorStackPortal *GetGLPortal();
|
||||
};
|
||||
|
||||
struct FGLLinePortal
|
||||
{
|
||||
// defines the complete span of this portal
|
||||
vertex_t *v1, *v2; // vertices, from v1 to v2
|
||||
fixed_t dx, dy; // precalculated v2 - v1 for side checking
|
||||
FLinePortal *reference; // one of the associated line portals, for retrieving translation info etc.
|
||||
};
|
||||
|
||||
extern TArray<FPortal *> portals;
|
||||
extern TArray<FGLLinePortal*> linePortalToGL;
|
||||
|
||||
extern TArray<BYTE> currentmapsection;
|
||||
|
||||
void gl_InitPortals();
|
||||
|
|
|
@ -87,6 +87,8 @@ typedef TArray<FPortalSector> FPortalSectors;
|
|||
typedef TMap<FPortalID, FPortalSectors> FPortalMap;
|
||||
|
||||
TArray<FPortal *> portals;
|
||||
TArray<FGLLinePortal*> linePortalToGL;
|
||||
TArray<FGLLinePortal> glLinePortals;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -426,6 +428,77 @@ void gl_InitPortals()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now group the line portals (each group must be a continuous set of colinear linedefs with no gaps)
|
||||
glLinePortals.Clear();
|
||||
linePortalToGL.Clear();
|
||||
TArray<int> tempindex;
|
||||
|
||||
tempindex.Reserve(linePortals.Size());
|
||||
memset(&tempindex[0], -1, linePortals.Size() * sizeof(int));
|
||||
|
||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||
{
|
||||
auto port = linePortals[i];
|
||||
bool gotsome;
|
||||
|
||||
if (tempindex[i] == -1)
|
||||
{
|
||||
tempindex[i] = glLinePortals.Size();
|
||||
line_t *pSrcLine = linePortals[i].mOrigin;
|
||||
line_t *pLine = linePortals[i].mDestination;
|
||||
FGLLinePortal glport = { pLine->v1, pLine->v2, 0, 0, &linePortals[i] };
|
||||
glLinePortals.Push(glport);
|
||||
|
||||
// We cannot do this grouping for non-linked portals because they can be changed at run time.
|
||||
if (linePortals[i].mType == PORTT_LINKED)
|
||||
do
|
||||
{
|
||||
// now collect all other colinear lines connected to this one. We run this loop as long as it still finds a match
|
||||
gotsome = false;
|
||||
for (unsigned j = 0; j < linePortals.Size(); j++)
|
||||
{
|
||||
if (tempindex[j] == -1)
|
||||
{
|
||||
line_t *pSrcLine2 = linePortals[j].mOrigin;
|
||||
line_t *pLine2 = linePortals[j].mDestination;
|
||||
// angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical portals aren't found here.)
|
||||
angle_t srcang = RAD2ANGLE(atan2(pSrcLine->dy, pSrcLine->dx));
|
||||
angle_t dstang = RAD2ANGLE(atan2(pLine->dy, pLine->dx));
|
||||
if ((pSrcLine->v2 == pSrcLine2->v1 && pLine->v1 == pLine2->v2) ||
|
||||
(pSrcLine->v1 == pSrcLine2->v2 && pLine->v2 == pLine2->v1))
|
||||
{
|
||||
// The line connects, now check the translation
|
||||
fixed_t srcang2 = RAD2ANGLE(atan2(pSrcLine2->dy, pSrcLine2->dx));
|
||||
fixed_t dstang2 = RAD2ANGLE(atan2(pLine2->dy, pLine2->dx));
|
||||
if (srcang == srcang2 && dstang == dstang2)
|
||||
{
|
||||
// The lines connect and both source and destination are colinear, so this is a match
|
||||
gotsome = true;
|
||||
tempindex[j] = tempindex[i];
|
||||
if (pLine->v1 == pLine2->v2) glLinePortals[tempindex[i]].v1 = pLine2->v1;
|
||||
else glLinePortals[tempindex[i]].v2 = pLine2->v2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (gotsome);
|
||||
}
|
||||
}
|
||||
for (auto glport : glLinePortals)
|
||||
{
|
||||
glport.dx = glport.v2->x - glport.v1->x;
|
||||
glport.dy = glport.v2->y - glport.v1->y;
|
||||
}
|
||||
linePortalToGL.Resize(linePortals.Size());
|
||||
for (unsigned i = 0; i < linePortals.Size(); i++)
|
||||
{
|
||||
linePortalToGL[i] = &glLinePortals[tempindex[i]];
|
||||
/*
|
||||
Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n",
|
||||
int(linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->x / 65536., linePortalToGL[i]->v1->y / 65536., linePortalToGL[i]->v2->x / 65536., linePortalToGL[i]->v2->y / 65536.);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
CCMD(dumpportals)
|
||||
|
|
|
@ -100,7 +100,7 @@ bool GLPortal::inskybox;
|
|||
UniqueList<GLSkyInfo> UniqueSkies;
|
||||
UniqueList<GLHorizonInfo> UniqueHorizons;
|
||||
UniqueList<secplane_t> UniquePlaneMirrors;
|
||||
UniqueList<GLLineToLineInfo> UniqueLineToLines;
|
||||
UniqueList<FGLLinePortal> UniqueLineToLines;
|
||||
|
||||
|
||||
|
||||
|
@ -950,24 +950,24 @@ void GLMirrorPortal::DrawContents()
|
|||
}
|
||||
|
||||
|
||||
int GLMirrorPortal::ClipSeg(seg_t *seg)
|
||||
int GLLinePortal::ClipSeg(seg_t *seg)
|
||||
{
|
||||
return P_ClipLineToPortal(seg->linedef, linedef, viewx, viewy) ? PClip_InFront : PClip_Inside;
|
||||
return PClip_Inside;// P_ClipLineToPortal(seg->linedef, line(), viewx, viewy) ? PClip_InFront : PClip_Inside;
|
||||
}
|
||||
|
||||
int GLMirrorPortal::ClipSubsector(subsector_t *sub)
|
||||
int GLLinePortal::ClipSubsector(subsector_t *sub)
|
||||
{
|
||||
// this seg is completely behind the mirror!
|
||||
for(unsigned int i=0;i<sub->numlines;i++)
|
||||
{
|
||||
if (P_PointOnLineSidePrecise(sub->firstline[i].v1->x, sub->firstline[i].v1->y, linedef) == 0) return PClip_Inside;
|
||||
if (P_PointOnLineSidePrecise(sub->firstline[i].v1->x, sub->firstline[i].v1->y, line()) == 0) return PClip_Inside;
|
||||
}
|
||||
return PClip_InFront;
|
||||
}
|
||||
|
||||
int GLMirrorPortal::ClipPoint(fixed_t x, fixed_t y)
|
||||
int GLLinePortal::ClipPoint(fixed_t x, fixed_t y)
|
||||
{
|
||||
if (P_PointOnLineSidePrecise(x, y, linedef))
|
||||
if (P_PointOnLineSidePrecise(x, y, line()))
|
||||
{
|
||||
return PClip_InFront;
|
||||
}
|
||||
|
@ -985,29 +985,6 @@ int GLMirrorPortal::ClipPoint(fixed_t x, fixed_t y)
|
|||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLLineToLineInfo::init(line_t *line)
|
||||
{
|
||||
static const divline_t divlx = { 0, 0, 128 * FRACUNIT, 0 };
|
||||
static const divline_t divly = { 0, 0, 0, 128 * FRACUNIT };
|
||||
|
||||
// store some info about the portal line
|
||||
divline_t divl;
|
||||
P_MakeDivline(line, &divl);
|
||||
x0 = P_InterceptVector(&divlx, &divl);
|
||||
y0 = P_InterceptVector(&divly, &divl);
|
||||
lineangle = R_PointToAnglePrecise(line->v1->x, line->v1->y, line->v2->x, line->v2->y);
|
||||
|
||||
// and some info about the viewpoint translation
|
||||
viewx = ::viewx;
|
||||
viewy = ::viewy;
|
||||
viewz = ::viewz;
|
||||
viewangle = ::viewangle;
|
||||
P_TranslatePortalXY(line, viewx, viewy);
|
||||
P_TranslatePortalAngle(line, viewangle);
|
||||
P_TranslatePortalZ(line, viewz);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
@ -1024,10 +1001,11 @@ void GLLineToLinePortal::DrawContents()
|
|||
|
||||
GLRenderer->mCurrentPortal = this;
|
||||
|
||||
viewx = l2l->viewx;
|
||||
viewy = l2l->viewy;
|
||||
viewz = l2l->viewz;
|
||||
viewangle = l2l->viewangle;
|
||||
line_t *origin = glport->reference->mOrigin;
|
||||
P_TranslatePortalXY(origin, viewx, viewy);
|
||||
P_TranslatePortalAngle(origin, viewangle);
|
||||
P_TranslatePortalZ(origin, viewz);
|
||||
|
||||
SaveMapSection();
|
||||
|
||||
for (unsigned i = 0; i < lines.Size(); i++)
|
||||
|
@ -1051,6 +1029,7 @@ void GLLineToLinePortal::DrawContents()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
int GLLineToLinePortal::ClipSeg(seg_t *seg)
|
||||
{
|
||||
line_t *linedef = lines[0].seg->linedef->getPortalDestination();
|
||||
|
@ -1086,6 +1065,7 @@ int GLLineToLinePortal::ClipPoint(fixed_t x, fixed_t y)
|
|||
}
|
||||
return PClip_Inside;
|
||||
}
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -41,9 +41,11 @@
|
|||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
|
||||
class ASkyViewpoint;
|
||||
|
||||
|
||||
struct GLHorizonInfo
|
||||
{
|
||||
GLSectorPlane plane;
|
||||
|
@ -51,18 +53,6 @@ struct GLHorizonInfo
|
|||
FColormap colormap;
|
||||
};
|
||||
|
||||
struct GLLineToLineInfo
|
||||
{
|
||||
angle_t viewangle;
|
||||
fixed_t viewx;
|
||||
fixed_t viewy;
|
||||
fixed_t viewz;
|
||||
fixed_t x0, y0;
|
||||
angle_t lineangle;
|
||||
|
||||
void init(line_t *line);
|
||||
};
|
||||
|
||||
struct GLSkyInfo
|
||||
{
|
||||
float x_offset[2];
|
||||
|
@ -88,7 +78,7 @@ struct GLSkyInfo
|
|||
extern UniqueList<GLSkyInfo> UniqueSkies;
|
||||
extern UniqueList<GLHorizonInfo> UniqueHorizons;
|
||||
extern UniqueList<secplane_t> UniquePlaneMirrors;
|
||||
extern UniqueList<GLLineToLineInfo> UniqueLineToLines;
|
||||
extern UniqueList<FGLLinePortal> UniqueLineToLines;
|
||||
struct GLEEHorizonPortal;
|
||||
|
||||
class GLPortal
|
||||
|
@ -184,8 +174,44 @@ public:
|
|||
static GLPortal * FindPortal(const void * src);
|
||||
};
|
||||
|
||||
struct GLLinePortal : public GLPortal
|
||||
{
|
||||
// this must be the same as at the start of line_t, so that we can pass in this structure directly to P_ClipLineToPortal.
|
||||
vertex_t *v1, *v2; // vertices, from v1 to v2
|
||||
fixed_t dx, dy; // precalculated v2 - v1 for side checking
|
||||
|
||||
struct GLMirrorPortal : public GLPortal
|
||||
angle_t angv1, angv2; // for quick comparisons with a line or subsector
|
||||
|
||||
GLLinePortal(line_t *line)
|
||||
{
|
||||
v1 = line->v1;
|
||||
v2 = line->v2;
|
||||
dx = line->dx;
|
||||
dy = line->dy;
|
||||
}
|
||||
|
||||
GLLinePortal(FGLLinePortal *line)
|
||||
{
|
||||
v1 = line->v1;
|
||||
v2 = line->v2;
|
||||
dx = line->dx;
|
||||
dy = line->dy;
|
||||
}
|
||||
|
||||
line_t *line()
|
||||
{
|
||||
vertex_t **pv = &v1;
|
||||
return reinterpret_cast<line_t*>(pv);
|
||||
}
|
||||
|
||||
virtual int ClipSeg(seg_t *seg);
|
||||
virtual int ClipSubsector(subsector_t *sub);
|
||||
virtual int ClipPoint(fixed_t x, fixed_t y);
|
||||
virtual bool NeedCap() { return false; }
|
||||
};
|
||||
|
||||
|
||||
struct GLMirrorPortal : public GLLinePortal
|
||||
{
|
||||
// mirror portals always consist of single linedefs!
|
||||
line_t * linedef;
|
||||
|
@ -198,36 +224,28 @@ protected:
|
|||
public:
|
||||
|
||||
GLMirrorPortal(line_t * line)
|
||||
: GLLinePortal(line)
|
||||
{
|
||||
linedef=line;
|
||||
}
|
||||
|
||||
virtual bool NeedCap() { return false; }
|
||||
virtual int ClipSeg(seg_t *seg);
|
||||
virtual int ClipSubsector(subsector_t *sub);
|
||||
virtual int ClipPoint(fixed_t x, fixed_t y);
|
||||
};
|
||||
|
||||
|
||||
struct GLLineToLinePortal : public GLPortal
|
||||
struct GLLineToLinePortal : public GLLinePortal
|
||||
{
|
||||
GLLineToLineInfo *l2l;
|
||||
FGLLinePortal *glport;
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void * GetSource() const { return l2l; }
|
||||
virtual void * GetSource() const { return glport; }
|
||||
virtual const char *GetName();
|
||||
|
||||
public:
|
||||
|
||||
GLLineToLinePortal(GLLineToLineInfo *ll)
|
||||
GLLineToLinePortal(FGLLinePortal *ll)
|
||||
: GLLinePortal(ll)
|
||||
{
|
||||
l2l=ll;
|
||||
glport = ll;
|
||||
}
|
||||
|
||||
virtual bool NeedCap() { return false; }
|
||||
virtual int ClipSeg(seg_t *seg);
|
||||
virtual int ClipSubsector(subsector_t *sub);
|
||||
virtual int ClipPoint(fixed_t x, fixed_t y);
|
||||
};
|
||||
|
||||
|
||||
|
@ -238,7 +256,7 @@ struct GLSkyboxPortal : public GLPortal
|
|||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void * GetSource() const { return origin; }
|
||||
virtual bool IsSky() { return true; } // later!
|
||||
virtual bool IsSky() { return true; }
|
||||
virtual const char *GetName();
|
||||
|
||||
public:
|
||||
|
|
|
@ -21,7 +21,7 @@ struct GLSkyInfo;
|
|||
struct FTexCoordInfo;
|
||||
struct FPortal;
|
||||
struct FFlatVertex;
|
||||
struct GLLineToLineInfo;
|
||||
struct FGLLinePortal;
|
||||
|
||||
|
||||
enum WallTypes
|
||||
|
@ -149,7 +149,7 @@ public:
|
|||
GLHorizonInfo * horizon; // for horizon information
|
||||
FPortal * portal; // stacked sector portals
|
||||
secplane_t * planemirror; // for plane mirrors
|
||||
GLLineToLineInfo *l2l; // line-to-line portals
|
||||
FGLLinePortal *lineportal; // line-to-line portals
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -214,8 +214,8 @@ void GLWall::PutPortal(int ptype)
|
|||
break;
|
||||
|
||||
case PORTALTYPE_LINETOLINE:
|
||||
portal=GLPortal::FindPortal(l2l);
|
||||
if (!portal) portal=new GLLineToLinePortal(l2l);
|
||||
portal=GLPortal::FindPortal(lineportal);
|
||||
if (!portal) portal=new GLLineToLinePortal(lineportal);
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
|
@ -1493,13 +1493,11 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
|
||||
if (seg->linedef->isVisualPortal())
|
||||
{
|
||||
GLLineToLineInfo llinfo;
|
||||
lineportal = linePortalToGL[seg->linedef->portalindex];
|
||||
ztop[0] = zceil[0];
|
||||
ztop[1] = zceil[1];
|
||||
zbottom[0] = zfloor[0];
|
||||
zbottom[1] = zfloor[1];
|
||||
llinfo.init(seg->linedef);
|
||||
l2l = UniqueLineToLines.Get(&llinfo);
|
||||
PutPortal(PORTALTYPE_LINETOLINE);
|
||||
}
|
||||
else if (seg->linedef->skybox == NULL && !seg->linedef->isVisualPortal())
|
||||
|
@ -1617,13 +1615,11 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
|
||||
if (seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0])
|
||||
{
|
||||
GLLineToLineInfo llinfo;
|
||||
lineportal = linePortalToGL[seg->linedef->portalindex];
|
||||
ztop[0] = FIXED2FLOAT(bch1);
|
||||
ztop[1] = FIXED2FLOAT(bch2);
|
||||
zbottom[0] = FIXED2FLOAT(bfh1);
|
||||
zbottom[1] = FIXED2FLOAT(bfh2);
|
||||
llinfo.init(seg->linedef);
|
||||
l2l = UniqueLineToLines.Get(&llinfo);
|
||||
PutPortal(PORTALTYPE_LINETOLINE);
|
||||
}
|
||||
else if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
||||
|
|
Loading…
Reference in a new issue