mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-15 08:52:04 +00:00
- copied line portal code from portal branch and made some adjustments to make it compile. Portal rendering is not yet working.
This commit is contained in:
parent
25f1dc86d5
commit
297cf52ac9
5 changed files with 177 additions and 15 deletions
|
@ -95,6 +95,7 @@ bool GLPortal::inskybox;
|
|||
UniqueList<GLSkyInfo> UniqueSkies;
|
||||
UniqueList<GLHorizonInfo> UniqueHorizons;
|
||||
UniqueList<secplane_t> UniquePlaneMirrors;
|
||||
UniqueList<GLLineToLineInfo> UniqueLineToLines;
|
||||
|
||||
|
||||
|
||||
|
@ -109,6 +110,7 @@ void GLPortal::BeginScene()
|
|||
UniqueSkies.Clear();
|
||||
UniqueHorizons.Clear();
|
||||
UniquePlaneMirrors.Clear();
|
||||
UniqueLineToLines.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -216,7 +218,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
else if (gl_noquery) doquery = false;
|
||||
|
||||
// If occlusion query is supported let's use it to avoid rendering portals that aren't visible
|
||||
if (!QueryObject) glGenQueries(1, &QueryObject);
|
||||
if (!QueryObject && doquery) glGenQueries(1, &QueryObject);
|
||||
if (QueryObject)
|
||||
{
|
||||
glBeginQuery(GL_SAMPLES_PASSED, QueryObject);
|
||||
|
@ -244,15 +246,18 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
|
||||
GLuint sampleCount;
|
||||
|
||||
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount);
|
||||
|
||||
if (sampleCount == 0) // not visible
|
||||
if (QueryObject)
|
||||
{
|
||||
// restore default stencil op.
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, recursion, ~0); // draw sky into stencil
|
||||
PortalAll.Unclock();
|
||||
return false;
|
||||
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount);
|
||||
|
||||
if (sampleCount == 0) // not visible
|
||||
{
|
||||
// restore default stencil op.
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, recursion, ~0); // draw sky into stencil
|
||||
PortalAll.Unclock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FDrawInfo::StartDrawInfo();
|
||||
}
|
||||
|
@ -969,6 +974,86 @@ int GLMirrorPortal::ClipPoint(fixed_t x, fixed_t y)
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// Line to line Portal
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void GLLineToLinePortal::DrawContents()
|
||||
{
|
||||
// TODO: Handle recursion more intelligently
|
||||
if (renderdepth>r_mirror_recursions)
|
||||
{
|
||||
ClearScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
GLRenderer->mCurrentPortal = this;
|
||||
|
||||
viewx += l2l->xDisplacement;
|
||||
viewy += l2l->yDisplacement;
|
||||
SaveMapSection();
|
||||
|
||||
for (unsigned i = 0; i < lines.Size(); i++)
|
||||
{
|
||||
ASkyViewpoint *pt = lines[i].seg->linedef->skybox;
|
||||
int mapsection = lines[i].seg->Subsector->mapsection;
|
||||
currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
|
||||
}
|
||||
|
||||
GLRenderer->mViewActor = NULL;
|
||||
validcount++;
|
||||
GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
||||
ClearClipper();
|
||||
GLRenderer->DrawScene();
|
||||
RestoreMapSection();
|
||||
}
|
||||
|
||||
|
||||
int GLLineToLinePortal::ClipSeg(seg_t *seg)
|
||||
{
|
||||
line_t *masterline = lines[0].seg->linedef->getPortalDestination();
|
||||
// this seg is completely behind the portal
|
||||
if (P_PointOnLineSide(seg->v1->x, seg->v1->y, masterline) &&
|
||||
P_PointOnLineSide(seg->v2->x, seg->v2->y, masterline))
|
||||
{
|
||||
return PClip_InFront;
|
||||
}
|
||||
return PClip_Inside;
|
||||
}
|
||||
|
||||
int GLLineToLinePortal::ClipSubsector(subsector_t *sub)
|
||||
{
|
||||
line_t *masterline = lines[0].seg->linedef->getPortalDestination();
|
||||
|
||||
for(unsigned int i=0;i<sub->numlines;i++)
|
||||
{
|
||||
if (P_PointOnLineSide(sub->firstline[i].v1->x, sub->firstline[i].v1->y, masterline) == 0) return PClip_Inside;
|
||||
}
|
||||
return PClip_InFront;
|
||||
}
|
||||
|
||||
int GLLineToLinePortal::ClipPoint(fixed_t x, fixed_t y)
|
||||
{
|
||||
line_t *masterline = lines[0].seg->linedef->getPortalDestination();
|
||||
if (P_PointOnLineSide(x, y, masterline))
|
||||
{
|
||||
return PClip_InFront;
|
||||
}
|
||||
return PClip_Inside;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -1165,6 +1250,7 @@ const char *GLSkyboxPortal::GetName() { return "Skybox"; }
|
|||
const char *GLSectorStackPortal::GetName() { return "Sectorstack"; }
|
||||
const char *GLPlaneMirrorPortal::GetName() { return "Planemirror"; }
|
||||
const char *GLMirrorPortal::GetName() { return "Mirror"; }
|
||||
const char *GLLineToLinePortal::GetName() { return "LineToLine"; }
|
||||
const char *GLHorizonPortal::GetName() { return "Horizon"; }
|
||||
const char *GLEEHorizonPortal::GetName() { return "EEHorizon"; }
|
||||
|
||||
|
|
|
@ -51,6 +51,17 @@ struct GLHorizonInfo
|
|||
FColormap colormap;
|
||||
};
|
||||
|
||||
struct GLLineToLineInfo
|
||||
{
|
||||
fixed_t xDisplacement;
|
||||
fixed_t yDisplacement;
|
||||
fixed_t turnangle;
|
||||
fixed_t angle;
|
||||
fixed_t x0;
|
||||
fixed_t y0;
|
||||
void init(line_t *line);
|
||||
};
|
||||
|
||||
struct GLSkyInfo
|
||||
{
|
||||
float x_offset[2];
|
||||
|
@ -76,6 +87,7 @@ struct GLSkyInfo
|
|||
extern UniqueList<GLSkyInfo> UniqueSkies;
|
||||
extern UniqueList<GLHorizonInfo> UniqueHorizons;
|
||||
extern UniqueList<secplane_t> UniquePlaneMirrors;
|
||||
extern UniqueList<GLLineToLineInfo> UniqueLineToLines;
|
||||
struct GLEEHorizonPortal;
|
||||
|
||||
class GLPortal
|
||||
|
@ -195,6 +207,28 @@ public:
|
|||
};
|
||||
|
||||
|
||||
struct GLLineToLinePortal : public GLPortal
|
||||
{
|
||||
GLLineToLineInfo *l2l;
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void * GetSource() const { return l2l; }
|
||||
virtual const char *GetName();
|
||||
|
||||
public:
|
||||
|
||||
GLLineToLinePortal(GLLineToLineInfo *ll)
|
||||
{
|
||||
l2l=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);
|
||||
};
|
||||
|
||||
|
||||
struct GLSkyboxPortal : public GLPortal
|
||||
{
|
||||
AActor * origin;
|
||||
|
|
|
@ -129,6 +129,23 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor)
|
|||
|
||||
}
|
||||
|
||||
|
||||
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 };
|
||||
xDisplacement = line->skybox->scaleX;
|
||||
yDisplacement = line->skybox->scaleY;
|
||||
angle = R_PointToAnglePrecise(line->v1->x, line->v1->y, line->v2->x, line->v2->y);
|
||||
|
||||
divline_t divl;
|
||||
P_MakeDivline(line, &divl);
|
||||
x0 = P_InterceptVector(&divlx, &divl);
|
||||
y0 = P_InterceptVector(&divly, &divl);
|
||||
*/
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Calculate sky texture for ceiling or floor
|
||||
|
@ -188,23 +205,30 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SkyLine(line_t *line)
|
||||
void GLWall::SkyLine(sector_t *fs, line_t *line)
|
||||
{
|
||||
ASkyViewpoint * skyboxx = line->skybox;
|
||||
GLSkyInfo skyinfo;
|
||||
GLLineToLineInfo llinfo;
|
||||
int ptype;
|
||||
|
||||
// JUSTHIT is used as an indicator that a skybox is in use.
|
||||
// This is to avoid recursion
|
||||
|
||||
if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor != skyboxx && !(skyboxx->flags&MF_JUSTHIT))
|
||||
if (line->isVisualPortal())
|
||||
{
|
||||
ptype = PORTALTYPE_LINETOLINE;
|
||||
llinfo.init(line);
|
||||
l2l = UniqueLineToLines.Get(&llinfo);
|
||||
}
|
||||
else if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor != skyboxx && !(skyboxx->flags&MF_JUSTHIT))
|
||||
{
|
||||
ptype = PORTALTYPE_SKYBOX;
|
||||
skybox = skyboxx;
|
||||
}
|
||||
else
|
||||
{
|
||||
skyinfo.init(line->frontsector->sky, Colormap.FadeColor);
|
||||
skyinfo.init(fs->sky, Colormap.FadeColor);
|
||||
ptype = PORTALTYPE_SKY;
|
||||
sky = UniqueSkies.Get(&skyinfo);
|
||||
}
|
||||
|
@ -231,7 +255,7 @@ void GLWall::SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2)
|
|||
ztop[1] = zceil[1];
|
||||
zbottom[0] = zfloor[0];
|
||||
zbottom[1] = zfloor[1];
|
||||
SkyLine(seg->linedef);
|
||||
SkyLine(fs, seg->linedef);
|
||||
}
|
||||
|
||||
ztop[0]=zfloor[0];
|
||||
|
|
|
@ -21,6 +21,7 @@ struct GLSkyInfo;
|
|||
struct FTexCoordInfo;
|
||||
struct FPortal;
|
||||
struct FFlatVertex;
|
||||
struct GLLineToLineInfo;
|
||||
|
||||
|
||||
enum WallTypes
|
||||
|
@ -46,6 +47,7 @@ enum PortalTypes
|
|||
PORTALTYPE_SECTORSTACK,
|
||||
PORTALTYPE_PLANEMIRROR,
|
||||
PORTALTYPE_MIRROR,
|
||||
PORTALTYPE_LINETOLINE,
|
||||
};
|
||||
|
||||
struct GLSeg
|
||||
|
@ -147,6 +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
|
||||
};
|
||||
|
||||
|
||||
|
@ -178,7 +181,7 @@ private:
|
|||
void FloodPlane(int pass);
|
||||
|
||||
void SkyPlane(sector_t *sector, int plane, bool allowmirror);
|
||||
void SkyLine(line_t *line);
|
||||
void SkyLine(sector_t *sec, line_t *line);
|
||||
void SkyNormal(sector_t * fs,vertex_t * v1,vertex_t * v2);
|
||||
void SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
|
||||
void SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
|
||||
|
|
|
@ -209,6 +209,12 @@ void GLWall::PutPortal(int ptype)
|
|||
}
|
||||
break;
|
||||
|
||||
case PORTALTYPE_LINETOLINE:
|
||||
portal=GLPortal::FindPortal(l2l);
|
||||
if (!portal) portal=new GLLineToLinePortal(l2l);
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKY:
|
||||
portal=GLPortal::FindPortal(sky);
|
||||
if (!portal) portal=new GLSkyPortal(sky);
|
||||
|
@ -1582,7 +1588,16 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||
}
|
||||
|
||||
if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
||||
if (seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0])
|
||||
{
|
||||
ztop[0] = FIXED2FLOAT(bch1);
|
||||
ztop[1] = FIXED2FLOAT(bch2);
|
||||
zbottom[0] = FIXED2FLOAT(bfh1);
|
||||
zbottom[1] = FIXED2FLOAT(bfh2);
|
||||
|
||||
//SkyLine(frontsector, seg->linedef);
|
||||
}
|
||||
else if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
||||
{
|
||||
DoFFloorBlocks(seg, frontsector, backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue