mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-12-11 12:51:27 +00:00
- implement Eternity-Style flat and horizon portals. Not tested yet due to lack of material to work with.
This commit is contained in:
parent
ab1bf2bca3
commit
ef7bcb3a66
7 changed files with 1426 additions and 1263 deletions
2392
src/actor.h
2392
src/actor.h
File diff suppressed because it is too large
Load diff
|
@ -45,6 +45,7 @@
|
|||
#include "c_dispatch.h"
|
||||
#include "doomstat.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "r_sky.h"
|
||||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
|
@ -533,7 +534,7 @@ void GLPortal::EndFrame()
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Renders one sky portal without a stencil.
|
||||
// In more complex scenes using a stencil for skies can severly stall
|
||||
// In more complex scenes using a stencil for skies can severely stall
|
||||
// the GPU and there's rarely more than one sky visible at a time.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1080,6 +1081,69 @@ void GLHorizonPortal::DrawContents()
|
|||
gl_RenderState.EnableTextureMatrix(false);
|
||||
PortalAll.Unclock();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// Eternity-style horizon portal
|
||||
//
|
||||
// To the rest of the engine these masquerade as a skybox portal
|
||||
// Internally they need to draw two horizon or sky portals
|
||||
// and will use the respective classes to achieve that.
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLEEHorizonPortal::DrawContents()
|
||||
{
|
||||
PortalAll.Clock();
|
||||
if (origin->Sector->GetTexture(sector_t::floor) == skyflatnum ||
|
||||
origin->Sector->GetTexture(sector_t::ceiling) == skyflatnum)
|
||||
{
|
||||
GLSkyInfo skyinfo;
|
||||
skyinfo.init(origin->Sector->sky, 0);
|
||||
GLSkyPortal sky(&skyinfo, true);
|
||||
sky.DrawContents();
|
||||
}
|
||||
if (origin->Sector->GetTexture(sector_t::ceiling) != skyflatnum)
|
||||
{
|
||||
GLHorizonInfo horz;
|
||||
horz.plane.GetFromSector(origin->Sector, true);
|
||||
horz.lightlevel = gl_ClampLight(origin->Sector->GetCeilingLight());
|
||||
horz.colormap = origin->Sector->ColorMap;
|
||||
if (origin->flags & MF_FLOAT)
|
||||
{
|
||||
horz.plane.texheight = viewz + abs(horz.plane.texheight);
|
||||
}
|
||||
GLHorizonPortal ceil(&horz, true);
|
||||
ceil.DrawContents();
|
||||
}
|
||||
if (origin->Sector->GetTexture(sector_t::floor) != skyflatnum)
|
||||
{
|
||||
GLHorizonInfo horz;
|
||||
horz.plane.GetFromSector(origin->Sector, false);
|
||||
horz.lightlevel = gl_ClampLight(origin->Sector->GetFloorLight());
|
||||
horz.colormap = origin->Sector->ColorMap;
|
||||
if (origin->flags & MF_FLOAT)
|
||||
{
|
||||
horz.plane.texheight = viewz - abs(horz.plane.texheight);
|
||||
}
|
||||
GLHorizonPortal floor(&horz, true);
|
||||
floor.DrawContents();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
const char *GLSkyPortal::GetName() { return "Sky"; }
|
||||
|
@ -1088,3 +1152,5 @@ const char *GLSectorStackPortal::GetName() { return "Sectorstack"; }
|
|||
const char *GLPlaneMirrorPortal::GetName() { return "Planemirror"; }
|
||||
const char *GLMirrorPortal::GetName() { return "Mirror"; }
|
||||
const char *GLHorizonPortal::GetName() { return "Horizon"; }
|
||||
const char *GLEEHorizonPortal::GetName() { return "EEHorizon"; }
|
||||
|
||||
|
|
|
@ -70,11 +70,13 @@ struct GLSkyInfo
|
|||
{
|
||||
return !!memcmp(this, &inf, sizeof(*this));
|
||||
}
|
||||
void init(int sky1, PalEntry fadecolor);
|
||||
};
|
||||
|
||||
extern UniqueList<GLSkyInfo> UniqueSkies;
|
||||
extern UniqueList<GLHorizonInfo> UniqueHorizons;
|
||||
extern UniqueList<secplane_t> UniquePlaneMirrors;
|
||||
struct GLEEHorizonPortal;
|
||||
|
||||
class GLPortal
|
||||
{
|
||||
|
@ -110,7 +112,7 @@ protected:
|
|||
TArray<GLWall> lines;
|
||||
int level;
|
||||
|
||||
GLPortal() { portals.Push(this); }
|
||||
GLPortal(bool local = false) { if (!local) portals.Push(this); }
|
||||
virtual ~GLPortal() { }
|
||||
|
||||
bool Start(bool usestencil, bool doquery);
|
||||
|
@ -215,6 +217,7 @@ public:
|
|||
struct GLSkyPortal : public GLPortal
|
||||
{
|
||||
GLSkyInfo * origin;
|
||||
friend struct GLEEHorizonPortal;
|
||||
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
|
@ -226,7 +229,8 @@ protected:
|
|||
public:
|
||||
|
||||
|
||||
GLSkyPortal(GLSkyInfo * pt)
|
||||
GLSkyPortal(GLSkyInfo * pt, bool local = false)
|
||||
: GLPortal(local)
|
||||
{
|
||||
origin=pt;
|
||||
}
|
||||
|
@ -281,6 +285,7 @@ public:
|
|||
struct GLHorizonPortal : public GLPortal
|
||||
{
|
||||
GLHorizonInfo * origin;
|
||||
friend struct GLEEHorizonPortal;
|
||||
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
|
@ -291,7 +296,28 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
GLHorizonPortal(GLHorizonInfo * pt)
|
||||
GLHorizonPortal(GLHorizonInfo * pt, bool local = false)
|
||||
: GLPortal(local)
|
||||
{
|
||||
origin=pt;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct GLEEHorizonPortal : public GLPortal
|
||||
{
|
||||
AActor * origin;
|
||||
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void * GetSource() const { return origin; }
|
||||
virtual bool NeedDepthBuffer() { return false; }
|
||||
virtual bool NeedCap() { return false; }
|
||||
virtual const char *GetName();
|
||||
|
||||
public:
|
||||
|
||||
GLEEHorizonPortal(AActor *pt)
|
||||
{
|
||||
origin=pt;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,72 @@ enum
|
|||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Set up the skyinfo struct
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSkyInfo::init(int sky1, PalEntry FadeColor)
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
if ((sky1 & PL_SKYFLAT) && (sky1 & (PL_SKYFLAT - 1)))
|
||||
{
|
||||
const line_t *l = &lines[(sky1&(PL_SKYFLAT - 1)) - 1];
|
||||
const side_t *s = l->sidedef[0];
|
||||
int pos;
|
||||
|
||||
if (level.flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom).isValid())
|
||||
{
|
||||
pos = side_t::bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = side_t::top;
|
||||
}
|
||||
|
||||
FTextureID texno = s->GetTexture(pos);
|
||||
texture[0] = FMaterial::ValidateTexture(texno, false, true);
|
||||
if (!texture[0] || texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky;
|
||||
skytexno1 = texno;
|
||||
x_offset[0] = ANGLE_TO_FLOAT(s->GetTextureXOffset(pos));
|
||||
y_offset = FIXED2FLOAT(s->GetTextureYOffset(pos));
|
||||
mirrored = !l->args[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
normalsky:
|
||||
if (level.flags&LEVEL_DOUBLESKY)
|
||||
{
|
||||
texture[1] = FMaterial::ValidateTexture(sky1texture, false, true);
|
||||
x_offset[1] = GLRenderer->mSky1Pos;
|
||||
doublesky = true;
|
||||
}
|
||||
|
||||
if ((level.flags&LEVEL_SWAPSKIES || (sky1 == PL_SKYFLAT) || (level.flags&LEVEL_DOUBLESKY)) &&
|
||||
sky2texture != sky1texture) // If both skies are equal use the scroll offset of the first!
|
||||
{
|
||||
texture[0] = FMaterial::ValidateTexture(sky2texture, false, true);
|
||||
skytexno1 = sky2texture;
|
||||
sky2 = true;
|
||||
x_offset[0] = GLRenderer->mSky2Pos;
|
||||
}
|
||||
else if (!doublesky)
|
||||
{
|
||||
texture[0] = FMaterial::ValidateTexture(sky1texture, false, true);
|
||||
skytexno1 = sky1texture;
|
||||
x_offset[0] = GLRenderer->mSky1Pos;
|
||||
}
|
||||
}
|
||||
if (skyfog > 0)
|
||||
{
|
||||
fadecolor = FadeColor;
|
||||
fadecolor.a = 0;
|
||||
}
|
||||
else fadecolor = 0;
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Calculate sky texture
|
||||
|
@ -92,64 +158,8 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
|
|||
}
|
||||
else
|
||||
{
|
||||
int sky1 = sector->sky;
|
||||
memset(&skyinfo, 0, sizeof(skyinfo));
|
||||
if ((sky1 & PL_SKYFLAT) && (sky1 & (PL_SKYFLAT-1)))
|
||||
{
|
||||
const line_t *l = &lines[(sky1&(PL_SKYFLAT-1))-1];
|
||||
const side_t *s = l->sidedef[0];
|
||||
int pos;
|
||||
|
||||
if (level.flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom).isValid())
|
||||
{
|
||||
pos = side_t::bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = side_t::top;
|
||||
}
|
||||
|
||||
FTextureID texno = s->GetTexture(pos);
|
||||
skyinfo.texture[0] = FMaterial::ValidateTexture(texno, false, true);
|
||||
if (!skyinfo.texture[0] || skyinfo.texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky;
|
||||
skyinfo.skytexno1 = texno;
|
||||
skyinfo.x_offset[0] = ANGLE_TO_FLOAT(s->GetTextureXOffset(pos));
|
||||
skyinfo.y_offset = FIXED2FLOAT(s->GetTextureYOffset(pos));
|
||||
skyinfo.mirrored = !l->args[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
normalsky:
|
||||
if (level.flags&LEVEL_DOUBLESKY)
|
||||
{
|
||||
skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, false, true);
|
||||
skyinfo.x_offset[1] = GLRenderer->mSky1Pos;
|
||||
skyinfo.doublesky = true;
|
||||
}
|
||||
|
||||
if ((level.flags&LEVEL_SWAPSKIES || (sky1==PL_SKYFLAT) || (level.flags&LEVEL_DOUBLESKY)) &&
|
||||
sky2texture!=sky1texture) // If both skies are equal use the scroll offset of the first!
|
||||
{
|
||||
skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, false, true);
|
||||
skyinfo.skytexno1=sky2texture;
|
||||
skyinfo.sky2 = true;
|
||||
skyinfo.x_offset[0] = GLRenderer->mSky2Pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, false, true);
|
||||
skyinfo.skytexno1=sky1texture;
|
||||
skyinfo.x_offset[0] = GLRenderer->mSky1Pos;
|
||||
}
|
||||
}
|
||||
if (skyfog>0)
|
||||
{
|
||||
skyinfo.fadecolor=Colormap.FadeColor;
|
||||
skyinfo.fadecolor.a=0;
|
||||
}
|
||||
else skyinfo.fadecolor=0;
|
||||
|
||||
type=RENDERWALL_SKY;
|
||||
skyinfo.init(sector->sky, Colormap.FadeColor);
|
||||
type = RENDERWALL_SKY;
|
||||
sky=UniqueSkies.Get(&skyinfo);
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +204,7 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex
|
|||
{
|
||||
if (fs->GetTexture(sector_t::ceiling)==skyflatnum)
|
||||
{
|
||||
if ((bs->special&0xff) == NoSkyDraw) return;
|
||||
if (bs->special == NoSkyDraw) return;
|
||||
if (bs->GetTexture(sector_t::ceiling)==skyflatnum)
|
||||
{
|
||||
// if the back sector is closed the sky must be drawn!
|
||||
|
@ -285,7 +295,7 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver
|
|||
{
|
||||
if (fs->GetTexture(sector_t::floor)==skyflatnum)
|
||||
{
|
||||
if ((bs->special&0xff) == NoSkyDraw) return;
|
||||
if (bs->special == NoSkyDraw) return;
|
||||
FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::bottom));
|
||||
|
||||
// For lower skies the normal logic only applies to walls with no lower texture!
|
||||
|
|
|
@ -176,8 +176,13 @@ void GLWall::PutWall(bool translucent)
|
|||
break;
|
||||
|
||||
case RENDERWALL_SKYBOX:
|
||||
portal=GLPortal::FindPortal(skybox);
|
||||
if (!portal) portal=new GLSkyboxPortal(skybox);
|
||||
portal = GLPortal::FindPortal(skybox);
|
||||
if (!portal)
|
||||
{
|
||||
// either a regulat skybox or an Eternity-style horizon
|
||||
if (skybox->flags7 & MF7_HANDLENODELAY) portal = new GLEEHorizonPortal(skybox);
|
||||
else portal = new GLSkyboxPortal(skybox);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
|
||||
// State.
|
||||
#include "r_state.h"
|
||||
#include "r_sky.h"
|
||||
|
||||
#include "c_console.h"
|
||||
|
||||
|
@ -986,7 +987,7 @@ void P_SetupPortals()
|
|||
}
|
||||
}
|
||||
|
||||
inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t alpha)
|
||||
inline void SetPortal(sector_t *sector, int plane, ASkyViewpoint *portal, fixed_t alpha)
|
||||
{
|
||||
// plane: 0=floor, 1=ceiling, 2=both
|
||||
if (plane > 0)
|
||||
|
@ -996,6 +997,8 @@ inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t
|
|||
sector->CeilingSkyBox = portal;
|
||||
if (sector->GetAlpha(sector_t::ceiling) == OPAQUE)
|
||||
sector->SetAlpha(sector_t::ceiling, alpha);
|
||||
|
||||
if (!portal->bAlways) sector->SetTexture(sector_t::ceiling, skyflatnum);
|
||||
}
|
||||
}
|
||||
if (plane == 2 || plane == 0)
|
||||
|
@ -1006,6 +1009,8 @@ inline void SetPortal(sector_t *sector, int plane, AStackPoint *portal, fixed_t
|
|||
}
|
||||
if (sector->GetAlpha(sector_t::floor) == OPAQUE)
|
||||
sector->SetAlpha(sector_t::floor, alpha);
|
||||
|
||||
if (!portal->bAlways) sector->SetTexture(sector_t::floor, skyflatnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1076,6 +1081,47 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha)
|
|||
}
|
||||
|
||||
|
||||
void P_SpawnHorizon(line_t *line)
|
||||
{
|
||||
ASkyViewpoint *origin = Spawn<ASkyViewpoint>(0, 0, 0, NO_REPLACE);
|
||||
origin->Sector = line->frontsector;
|
||||
origin->flags7 |= MF7_HANDLENODELAY; // mark as 'special'
|
||||
if (line->args[1] == 3) origin->flags |= MF_FLOAT; // well, it actually does 'float'... :P
|
||||
|
||||
|
||||
int s;
|
||||
FSectorTagIterator itr(line->args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
SetPortal(§ors[s], line->args[2], origin, 0);
|
||||
}
|
||||
|
||||
for (int j=0;j<numlines;j++)
|
||||
{
|
||||
// Check if this portal needs to be copied to other sectors
|
||||
// This must be done here to ensure that it gets done only after the portal is set up
|
||||
if (lines[j].special == Sector_SetPortal &&
|
||||
lines[j].args[1] == 1 &&
|
||||
(lines[j].args[2] == line->args[2] || lines[j].args[2] == 3) &&
|
||||
lines[j].args[3] == line->args[0])
|
||||
{
|
||||
if (lines[j].args[0] == 0)
|
||||
{
|
||||
SetPortal(lines[j].frontsector, line->args[2], origin, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
FSectorTagIterator itr(lines[j].args[0]);
|
||||
while ((s = itr.Next()) >= 0)
|
||||
{
|
||||
SetPortal(§ors[s], line->args[2], origin, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_SetSectorDamage
|
||||
//
|
||||
|
@ -1408,6 +1454,8 @@ void P_SpawnSpecials (void)
|
|||
// - 0: normal (handled here)
|
||||
// - 1: copy (handled by the portal they copy)
|
||||
// - 2: EE-style skybox (handled by the camera object)
|
||||
// - 3: EE-style flat portal (HW renderer only for now)
|
||||
// - 4: EE-style horizon portal (HW renderer only for now)
|
||||
// other values reserved for later use
|
||||
// arg 2 = 0:floor, 1:ceiling, 2:both
|
||||
// arg 3 = 0: anchor, 1: reference line
|
||||
|
@ -1416,6 +1464,10 @@ void P_SpawnSpecials (void)
|
|||
{
|
||||
P_SpawnPortal(&lines[i], lines[i].args[0], lines[i].args[2], lines[i].args[4]);
|
||||
}
|
||||
else if (lines[i].args[1] == 3 || lines[i].args[1] == 4)
|
||||
{
|
||||
P_SpawnHorizon(&lines[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
// [RH] ZDoom Static_Init settings
|
||||
|
|
|
@ -1088,6 +1088,7 @@ void R_Subsector (subsector_t *sub)
|
|||
}
|
||||
|
||||
skybox = frontsector->GetSkyBox(sector_t::ceiling);
|
||||
if (skybox->flags7 & MF7_HANDLENODELAY) skybox = NULL; // HW renderer only.
|
||||
|
||||
ceilingplane = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) > 0 ||
|
||||
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
|
||||
|
@ -1128,7 +1129,10 @@ void R_Subsector (subsector_t *sub)
|
|||
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
|
||||
// killough 3/16/98: add floorlightlevel
|
||||
// killough 10/98: add support for skies transferred from sidedefs
|
||||
|
||||
skybox = frontsector->GetSkyBox(sector_t::floor);
|
||||
if (skybox->flags7 & MF7_HANDLENODELAY) skybox = NULL; // HW renderer only.
|
||||
|
||||
floorplane = frontsector->floorplane.PointOnSide(viewx, viewy, viewz) > 0 || // killough 3/7/98
|
||||
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
|
||||
(skybox != NULL && skybox->bAlways) ||
|
||||
|
|
Loading…
Reference in a new issue