mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
rewrite of HWWalls to allow grabbing the output from the render item generator.
This commit is contained in:
parent
d65d1a3b82
commit
9cd57faec1
8 changed files with 431 additions and 299 deletions
|
@ -42,6 +42,7 @@
|
|||
#include "hw_clock.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hw_vertexbuilder.h"
|
||||
#include "hw_walldispatcher.h"
|
||||
|
||||
#ifdef ARCH_IA32
|
||||
#include <immintrin.h>
|
||||
|
@ -105,6 +106,7 @@ static RenderJobQueue jobQueue; // One static queue is sufficient here. This cod
|
|||
void HWDrawInfo::WorkerThread()
|
||||
{
|
||||
sector_t *front, *back;
|
||||
HWWallDispatcher disp(this);
|
||||
|
||||
WTTotal.Clock();
|
||||
isWorkerThread = true; // for adding asserts in GL API code. The worker thread may never call any GL API.
|
||||
|
@ -169,7 +171,7 @@ void HWDrawInfo::WorkerThread()
|
|||
}
|
||||
else back = nullptr;
|
||||
|
||||
wall.Process(this, job->seg, front, back);
|
||||
wall.Process(&disp, job->seg, front, back);
|
||||
rendered_lines++;
|
||||
SetupWall.Unclock();
|
||||
break;
|
||||
|
@ -348,9 +350,10 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
|
|||
else
|
||||
{
|
||||
HWWall wall;
|
||||
HWWallDispatcher disp(this);
|
||||
SetupWall.Clock();
|
||||
wall.sub = seg->Subsector;
|
||||
wall.Process(this, seg, currentsector, backsector);
|
||||
wall.Process(&disp, seg, currentsector, backsector);
|
||||
rendered_lines++;
|
||||
SetupWall.Unclock();
|
||||
}
|
||||
|
|
|
@ -214,7 +214,6 @@ private:
|
|||
int CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor);
|
||||
PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor);
|
||||
float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
|
||||
bool CheckFog(sector_t *frontsector, sector_t *backsector);
|
||||
WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos);
|
||||
|
||||
void PreparePlayerSprites2D(sector_t * viewsector, area_t in_area);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
bool CheckFog(FLevelLocals* Level, sector_t* frontsector, sector_t* backsector, ELightMode lightmode);
|
||||
|
||||
struct HWHorizonInfo;
|
||||
struct HWSkyInfo;
|
||||
struct F3DFloor;
|
||||
|
@ -113,6 +115,11 @@ struct texcoord
|
|||
};
|
||||
|
||||
struct HWDrawInfo;
|
||||
class HWWall;
|
||||
|
||||
// this only exists to keep HWWallDispatcher trivial
|
||||
|
||||
struct HWWallDispatcher;
|
||||
|
||||
class HWWall
|
||||
{
|
||||
|
@ -121,13 +128,13 @@ public:
|
|||
|
||||
enum
|
||||
{
|
||||
HWF_CLAMPX=1,
|
||||
HWF_CLAMPY=2,
|
||||
HWF_SKYHACK=4,
|
||||
HWF_GLOW=8, // illuminated by glowing flats
|
||||
HWF_NOSPLITUPPER=16,
|
||||
HWF_NOSPLITLOWER=32,
|
||||
HWF_NOSPLIT=64,
|
||||
HWF_CLAMPX = 1,
|
||||
HWF_CLAMPY = 2,
|
||||
HWF_SKYHACK = 4,
|
||||
HWF_GLOW = 8, // illuminated by glowing flats
|
||||
HWF_NOSPLITUPPER = 16,
|
||||
HWF_NOSPLITLOWER = 32,
|
||||
HWF_NOSPLIT = 64,
|
||||
HWF_TRANSLUCENT = 128,
|
||||
HWF_NOSLICE = 256
|
||||
};
|
||||
|
@ -151,13 +158,13 @@ public:
|
|||
friend struct HWDrawList;
|
||||
friend class HWPortal;
|
||||
|
||||
vertex_t * vertexes[2]; // required for polygon splitting
|
||||
FGameTexture *texture;
|
||||
TArray<lightlist_t> *lightlist;
|
||||
LightmapSurface *lightmap;
|
||||
vertex_t* vertexes[2]; // required for polygon splitting
|
||||
FGameTexture* texture;
|
||||
TArray<lightlist_t>* lightlist;
|
||||
LightmapSurface* lightmap;
|
||||
|
||||
HWSeg glseg;
|
||||
float ztop[2],zbottom[2];
|
||||
float ztop[2], zbottom[2];
|
||||
texcoord tcs[4];
|
||||
texcoord lightuv[4];
|
||||
float lindex;
|
||||
|
@ -165,7 +172,7 @@ public:
|
|||
|
||||
FColormap Colormap;
|
||||
ERenderStyle RenderStyle;
|
||||
|
||||
|
||||
float ViewDistance;
|
||||
|
||||
short lightlevel;
|
||||
|
@ -181,12 +188,17 @@ public:
|
|||
union
|
||||
{
|
||||
// it's either one of them but never more!
|
||||
FSectorPortal *secportal; // sector portal (formerly skybox)
|
||||
HWSkyInfo * sky; // for normal sky
|
||||
HWHorizonInfo * horizon; // for horizon information
|
||||
FSectorPortalGroup * portal; // stacked sector portals
|
||||
secplane_t * planemirror; // for plane mirrors
|
||||
FLinePortalSpan *lineportal; // line-to-line portals
|
||||
FSectorPortal* secportal; // sector portal (formerly skybox)
|
||||
HWSkyInfo* sky; // for normal sky
|
||||
HWHorizonInfo* horizon; // for horizon information
|
||||
FSectorPortalGroup* portal; // stacked sector portals
|
||||
secplane_t* planemirror; // for plane mirrors
|
||||
FLinePortalSpan* lineportal; // line-to-line portals
|
||||
struct
|
||||
{
|
||||
int portaltype; // for the mesh builder. Real portals can only be assigned when being rendered.
|
||||
int portalplane;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -199,92 +211,92 @@ public:
|
|||
unsigned int vertcount;
|
||||
|
||||
public:
|
||||
seg_t * seg; // this gives the easiest access to all other structs involved
|
||||
subsector_t * sub; // For polyobjects
|
||||
sector_t *frontsector, *backsector;
|
||||
//private:
|
||||
seg_t* seg; // this gives the easiest access to all other structs involved
|
||||
subsector_t* sub; // For polyobjects
|
||||
sector_t* frontsector, * backsector;
|
||||
//private:
|
||||
|
||||
void PutWall(HWDrawInfo *di, bool translucent);
|
||||
void PutPortal(HWDrawInfo *di, int ptype, int plane);
|
||||
void CheckTexturePosition(FTexCoordInfo *tci);
|
||||
void PutWall(HWWallDispatcher* di, bool translucent);
|
||||
void PutPortal(HWWallDispatcher* di, int ptype, int plane);
|
||||
void CheckTexturePosition(FTexCoordInfo* tci);
|
||||
|
||||
void Put3DWall(HWDrawInfo *di, lightlist_t * lightlist, bool translucent);
|
||||
bool SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright);
|
||||
void SplitWall(HWDrawInfo *di, sector_t * frontsector, bool translucent);
|
||||
void Put3DWall(HWWallDispatcher* di, lightlist_t* lightlist, bool translucent);
|
||||
bool SplitWallComplex(HWWallDispatcher* di, sector_t* frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright);
|
||||
void SplitWall(HWWallDispatcher* di, sector_t* frontsector, bool translucent);
|
||||
|
||||
void SetupLights(HWDrawInfo *di, FDynLightData &lightdata);
|
||||
void SetupLights(HWDrawInfo* di, FDynLightData& lightdata);
|
||||
|
||||
void MakeVertices(HWDrawInfo *di, bool nosplit);
|
||||
void MakeVertices(HWDrawInfo* di, bool nosplit);
|
||||
|
||||
void SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowmirror);
|
||||
void SkyLine(HWDrawInfo *di, sector_t *sec, line_t *line);
|
||||
void SkyNormal(HWDrawInfo *di, sector_t * fs,vertex_t * v1,vertex_t * v2);
|
||||
void SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
|
||||
void SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
|
||||
void SkyPlane(HWWallDispatcher* di, sector_t* sector, int plane, bool allowmirror);
|
||||
void SkyLine(HWWallDispatcher* di, sector_t* sec, line_t* line);
|
||||
void SkyNormal(HWWallDispatcher* di, sector_t* fs, vertex_t* v1, vertex_t* v2);
|
||||
void SkyTop(HWWallDispatcher* di, seg_t* seg, sector_t* fs, sector_t* bs, vertex_t* v1, vertex_t* v2);
|
||||
void SkyBottom(HWWallDispatcher* di, seg_t* seg, sector_t* fs, sector_t* bs, vertex_t* v1, vertex_t* v2);
|
||||
|
||||
bool DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2);
|
||||
bool DoHorizon(HWWallDispatcher* di, seg_t* seg, sector_t* fs, vertex_t* v1, vertex_t* v2);
|
||||
|
||||
bool SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float ceilingrefheight,
|
||||
bool SetWallCoordinates(seg_t* seg, FTexCoordInfo* tci, float ceilingrefheight,
|
||||
float topleft, float topright, float bottomleft, float bottomright, float t_ofs);
|
||||
|
||||
void DoTexture(HWDrawInfo *di, int type,seg_t * seg,int peg,
|
||||
float ceilingrefheight, float floorrefheight,
|
||||
float CeilingHeightstart,float CeilingHeightend,
|
||||
float FloorHeightstart,float FloorHeightend,
|
||||
float v_offset);
|
||||
void DoTexture(HWWallDispatcher* di, int type, seg_t* seg, int peg,
|
||||
float ceilingrefheight, float floorrefheight,
|
||||
float CeilingHeightstart, float CeilingHeightend,
|
||||
float FloorHeightstart, float FloorHeightend,
|
||||
float v_offset);
|
||||
|
||||
void DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary,
|
||||
sector_t * front, sector_t * back,
|
||||
sector_t * realfront, sector_t * realback,
|
||||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
float bch1, float bch2, float bfh1, float bfh2, float zalign);
|
||||
void DoMidTexture(HWWallDispatcher* di, seg_t* seg, bool drawfogboundary,
|
||||
sector_t* front, sector_t* back,
|
||||
sector_t* realfront, sector_t* realback,
|
||||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
float bch1, float bch2, float bfh1, float bfh2, float zalign);
|
||||
|
||||
void GetPlanePos(F3DFloor::planeref * planeref, float & left, float & right);
|
||||
void GetPlanePos(F3DFloor::planeref* planeref, float& left, float& right);
|
||||
|
||||
void BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, int roverIndex,
|
||||
float ff_topleft, float ff_topright,
|
||||
float ff_bottomleft, float ff_bottomright);
|
||||
void InverseFloors(HWDrawInfo *di, seg_t * seg, sector_t * frontsector,
|
||||
float topleft, float topright,
|
||||
float bottomleft, float bottomright);
|
||||
void ClipFFloors(HWDrawInfo *di, seg_t * seg, F3DFloor * ffloor, int ffloorIndex, sector_t * frontsector,
|
||||
float topleft, float topright,
|
||||
float bottomleft, float bottomright);
|
||||
void DoFFloorBlocks(HWDrawInfo *di, seg_t * seg, sector_t * frontsector, sector_t * backsector,
|
||||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
float bch1, float bch2, float bfh1, float bfh2);
|
||||
void BuildFFBlock(HWWallDispatcher* di, seg_t* seg, F3DFloor* rover, int roverIndex,
|
||||
float ff_topleft, float ff_topright,
|
||||
float ff_bottomleft, float ff_bottomright);
|
||||
void InverseFloors(HWWallDispatcher* di, seg_t* seg, sector_t* frontsector,
|
||||
float topleft, float topright,
|
||||
float bottomleft, float bottomright);
|
||||
void ClipFFloors(HWWallDispatcher* di, seg_t* seg, F3DFloor* ffloor, int ffloorIndex, sector_t* frontsector,
|
||||
float topleft, float topright,
|
||||
float bottomleft, float bottomright);
|
||||
void DoFFloorBlocks(HWWallDispatcher* di, seg_t* seg, sector_t* frontsector, sector_t* backsector,
|
||||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
float bch1, float bch2, float bfh1, float bfh2);
|
||||
|
||||
void ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &normal);
|
||||
void ProcessDecals(HWDrawInfo *di);
|
||||
void ProcessDecal(HWDrawInfo* di, DBaseDecal* decal, const FVector3& normal);
|
||||
void ProcessDecals(HWDrawInfo* di);
|
||||
|
||||
int CreateVertices(FFlatVertex *&ptr, bool nosplit);
|
||||
void SplitLeftEdge (FFlatVertex *&ptr);
|
||||
void SplitRightEdge(FFlatVertex *&ptr);
|
||||
void SplitUpperEdge(FFlatVertex *&ptr);
|
||||
void SplitLowerEdge(FFlatVertex *&ptr);
|
||||
int CreateVertices(FFlatVertex*& ptr, bool nosplit);
|
||||
void SplitLeftEdge(FFlatVertex*& ptr);
|
||||
void SplitRightEdge(FFlatVertex*& ptr);
|
||||
void SplitUpperEdge(FFlatVertex*& ptr);
|
||||
void SplitLowerEdge(FFlatVertex*& ptr);
|
||||
|
||||
void CountLeftEdge (unsigned &ptr);
|
||||
void CountRightEdge(unsigned &ptr);
|
||||
void CountLeftEdge(unsigned& ptr);
|
||||
void CountRightEdge(unsigned& ptr);
|
||||
|
||||
int CountVertices();
|
||||
|
||||
void RenderWall(HWDrawInfo *di, FRenderState &state, int textured);
|
||||
void RenderFogBoundary(HWDrawInfo *di, FRenderState &state);
|
||||
void RenderMirrorSurface(HWDrawInfo *di, FRenderState &state);
|
||||
void RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags);
|
||||
void RenderTranslucentWall(HWDrawInfo *di, FRenderState &state);
|
||||
void DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<HWDecal *> &decals);
|
||||
void RenderWall(HWDrawInfo* di, FRenderState& state, int textured);
|
||||
void RenderFogBoundary(HWDrawInfo* di, FRenderState& state);
|
||||
void RenderMirrorSurface(HWDrawInfo* di, FRenderState& state);
|
||||
void RenderTexturedWall(HWDrawInfo* di, FRenderState& state, int rflags);
|
||||
void RenderTranslucentWall(HWDrawInfo* di, FRenderState& state);
|
||||
void DrawDecalsForMirror(HWDrawInfo* di, FRenderState& state, TArray<HWDecal*>& decals);
|
||||
|
||||
public:
|
||||
void Process(HWDrawInfo *di, seg_t *seg, sector_t *frontsector, sector_t *backsector);
|
||||
void ProcessLowerMiniseg(HWDrawInfo *di, seg_t *seg, sector_t *frontsector, sector_t *backsector);
|
||||
void Process(HWWallDispatcher* di, seg_t* seg, sector_t* frontsector, sector_t* backsector);
|
||||
void ProcessLowerMiniseg(HWWallDispatcher* di, seg_t* seg, sector_t* frontsector, sector_t* backsector);
|
||||
|
||||
float PointOnSide(float x,float y)
|
||||
float PointOnSide(float x, float y)
|
||||
{
|
||||
return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1));
|
||||
return -((y - glseg.y1) * (glseg.x2 - glseg.x1) - (x - glseg.x1) * (glseg.y2 - glseg.y1));
|
||||
}
|
||||
|
||||
void DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||
void DrawWall(HWDrawInfo* di, FRenderState& state, bool translucent);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ float HWDrawInfo::GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfog
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool HWDrawInfo::CheckFog(sector_t *frontsector, sector_t *backsector)
|
||||
bool CheckFog(FLevelLocals* Level, sector_t *frontsector, sector_t *backsector, ELightMode lightmode)
|
||||
{
|
||||
if (frontsector == backsector) return false; // there can't be a boundary if both sides are in the same sector.
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "hw_lightbuffer.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "hw_fakeflat.h"
|
||||
#include "hw_walldispatcher.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -1117,7 +1118,8 @@ void HWDrawInfo::ProcessLowerMinisegs(TArray<seg_t *> &lowersegs)
|
|||
{
|
||||
seg_t * seg=lowersegs[j];
|
||||
HWWall wall;
|
||||
wall.ProcessLowerMiniseg(this, seg, seg->Subsector->render_sector, seg->PartnerSeg->Subsector->render_sector);
|
||||
HWWallDispatcher disp(this);
|
||||
wall.ProcessLowerMiniseg(&disp, seg, seg->Subsector->render_sector, seg->PartnerSeg->Subsector->render_sector);
|
||||
rendered_lines++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "hw_lighting.h"
|
||||
#include "hw_material.h"
|
||||
#include "hw_walldispatcher.h"
|
||||
|
||||
CVAR(Bool,gl_noskyboxes, false, 0)
|
||||
|
||||
|
@ -111,7 +112,7 @@ void HWSkyInfo::init(HWDrawInfo *di, int sky1, PalEntry FadeColor)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowreflect)
|
||||
void HWWall::SkyPlane(HWWallDispatcher *di, sector_t *sector, int plane, bool allowreflect)
|
||||
{
|
||||
int ptype = -1;
|
||||
|
||||
|
@ -121,10 +122,13 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref
|
|||
// Either a regular sky or a skybox with skyboxes disabled
|
||||
if ((sportal == nullptr && sector->GetTexture(plane) == skyflatnum) || (gl_noskyboxes && sportal != nullptr && sportal->mType == PORTS_SKYVIEWPOINT))
|
||||
{
|
||||
HWSkyInfo skyinfo;
|
||||
skyinfo.init(di, sector->sky, Colormap.FadeColor);
|
||||
ptype = PORTALTYPE_SKY;
|
||||
sky = &skyinfo;
|
||||
if (di->di)
|
||||
{
|
||||
HWSkyInfo skyinfo;
|
||||
skyinfo.init(di->di, sector->sky, Colormap.FadeColor);
|
||||
ptype = PORTALTYPE_SKY;
|
||||
sky = &skyinfo;
|
||||
}
|
||||
PutPortal(di, ptype, plane);
|
||||
}
|
||||
else if (sportal != nullptr)
|
||||
|
@ -140,7 +144,7 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref
|
|||
{
|
||||
if (sector->PortalBlocksView(plane)) return;
|
||||
|
||||
if (screen->instack[1 - plane]) return;
|
||||
if (di->di && screen->instack[1 - plane]) return;
|
||||
ptype = PORTALTYPE_SECTORSTACK;
|
||||
portal = glport;
|
||||
}
|
||||
|
@ -157,11 +161,14 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref
|
|||
}
|
||||
else if (allowreflect && sector->GetReflect(plane) > 0 && !(di->Level->ib_compatflags & BCOMPATF_NOMIRRORS))
|
||||
{
|
||||
auto vpz = di->Viewpoint.Pos.Z;
|
||||
if ((plane == sector_t::ceiling && vpz > sector->ceilingplane.fD()) ||
|
||||
(plane == sector_t::floor && vpz < -sector->floorplane.fD())) return;
|
||||
if (di->di)
|
||||
{
|
||||
auto vpz = di->di->Viewpoint.Pos.Z;
|
||||
if ((plane == sector_t::ceiling && vpz > sector->ceilingplane.fD()) ||
|
||||
(plane == sector_t::floor && vpz < -sector->floorplane.fD())) return;
|
||||
planemirror = plane == sector_t::ceiling ? §or->ceilingplane : §or->floorplane;
|
||||
}
|
||||
ptype = PORTALTYPE_PLANEMIRROR;
|
||||
planemirror = plane == sector_t::ceiling ? §or->ceilingplane : §or->floorplane;
|
||||
}
|
||||
if (ptype != -1)
|
||||
{
|
||||
|
@ -176,7 +183,7 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SkyLine(HWDrawInfo *di, sector_t *fs, line_t *line)
|
||||
void HWWall::SkyLine(HWWallDispatcher *di, sector_t *fs, line_t *line)
|
||||
{
|
||||
FSectorPortal *secport = line->GetTransferredPortal();
|
||||
HWSkyInfo skyinfo;
|
||||
|
@ -192,7 +199,7 @@ void HWWall::SkyLine(HWDrawInfo *di, sector_t *fs, line_t *line)
|
|||
}
|
||||
else
|
||||
{
|
||||
skyinfo.init(di, fs->sky, Colormap.FadeColor);
|
||||
if (di->di) skyinfo.init(di->di, fs->sky, Colormap.FadeColor);
|
||||
ptype = PORTALTYPE_SKY;
|
||||
sky = &skyinfo;
|
||||
}
|
||||
|
@ -210,7 +217,7 @@ void HWWall::SkyLine(HWDrawInfo *di, sector_t *fs, line_t *line)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SkyNormal(HWDrawInfo *di, sector_t * fs,vertex_t * v1,vertex_t * v2)
|
||||
void HWWall::SkyNormal(HWWallDispatcher *di, sector_t * fs,vertex_t * v1,vertex_t * v2)
|
||||
{
|
||||
ztop[0]=ztop[1]=32768.0f;
|
||||
zbottom[0]=zceil[0];
|
||||
|
@ -229,7 +236,7 @@ void HWWall::SkyNormal(HWDrawInfo *di, sector_t * fs,vertex_t * v1,vertex_t * v2
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2)
|
||||
void HWWall::SkyTop(HWWallDispatcher *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2)
|
||||
{
|
||||
if (fs->GetTexture(sector_t::ceiling)==skyflatnum)
|
||||
{
|
||||
|
@ -323,7 +330,7 @@ void HWWall::SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vert
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2)
|
||||
void HWWall::SkyBottom(HWWallDispatcher *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2)
|
||||
{
|
||||
if (fs->GetTexture(sector_t::floor)==skyflatnum)
|
||||
{
|
||||
|
@ -343,8 +350,8 @@ void HWWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,v
|
|||
}
|
||||
else
|
||||
{
|
||||
// Special hack for Vrack2b
|
||||
if (bs->floorplane.ZatPoint(di->Viewpoint.Pos) > di->Viewpoint.Pos.Z) return;
|
||||
// Special hack for Vrack2b. For mesh based rendering this check needs to be done in the actual render pass!
|
||||
if (di->di && bs->floorplane.ZatPoint(di->di->Viewpoint.Pos) > di->di->Viewpoint.Pos.Z) return;
|
||||
}
|
||||
}
|
||||
zbottom[0]=zbottom[1]=-32768.0f;
|
||||
|
|
80
src/rendering/hwrenderer/scene/hw_walldispatcher.h
Normal file
80
src/rendering/hwrenderer/scene/hw_walldispatcher.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
#pragma once
|
||||
|
||||
struct HWMissing
|
||||
{
|
||||
side_t* side;
|
||||
subsector_t* sub;
|
||||
double plane;
|
||||
};
|
||||
|
||||
struct HWMeshHelper
|
||||
{
|
||||
TArray<HWWall> list;
|
||||
TArray<HWWall> translucent;
|
||||
TArray<HWWall> portals;
|
||||
TArray<HWMissing> lower;
|
||||
TArray<HWMissing> upper;
|
||||
};
|
||||
|
||||
|
||||
struct HWWallDispatcher
|
||||
{
|
||||
FLevelLocals* Level;
|
||||
HWDrawInfo* di;
|
||||
HWMeshHelper* mh;
|
||||
ELightMode lightmode;
|
||||
|
||||
HWWallDispatcher(HWDrawInfo* info)
|
||||
{
|
||||
Level = info->Level;
|
||||
di = info;
|
||||
mh = nullptr;
|
||||
lightmode = info->lightmode;
|
||||
}
|
||||
|
||||
HWWallDispatcher(FLevelLocals* lev, HWMeshHelper* help, ELightMode lm)
|
||||
{
|
||||
Level = lev;
|
||||
di = nullptr;
|
||||
mh = help;
|
||||
lightmode = lm;
|
||||
}
|
||||
|
||||
void AddUpperMissingTexture(side_t* side, subsector_t* sub, float height)
|
||||
{
|
||||
if (di) di->AddUpperMissingTexture(side, sub, height);
|
||||
else
|
||||
{
|
||||
mh->upper.Reserve(1);
|
||||
mh->upper.Last() = { side, sub, height };
|
||||
}
|
||||
}
|
||||
void AddLowerMissingTexture(side_t* side, subsector_t* sub, float height)
|
||||
{
|
||||
if (di) di->AddUpperMissingTexture(side, sub, height);
|
||||
else
|
||||
{
|
||||
mh->lower.Reserve(1);
|
||||
mh->lower.Last() = { side, sub, height };
|
||||
}
|
||||
}
|
||||
|
||||
bool isFullbrightScene()
|
||||
{
|
||||
// The mesh builder cannot know this and must treat everything as not fullbright.
|
||||
return di && di->isFullbrightScene();
|
||||
}
|
||||
|
||||
void AddWall(HWWall* wal)
|
||||
{
|
||||
if (di) di->AddWall(wal);
|
||||
else if (!(wal->flags & HWWall::HWF_TRANSLUCENT)) mh->list.Push(*wal);
|
||||
else mh->translucent.Push(*wal);
|
||||
}
|
||||
|
||||
void AddPortal(HWWall* wal)
|
||||
{
|
||||
mh->portals.Push(*wal);
|
||||
}
|
||||
|
||||
};
|
|
@ -43,6 +43,7 @@
|
|||
#include "hw_lightbuffer.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "hw_skydome.h"
|
||||
#include "hw_walldispatcher.h"
|
||||
|
||||
|
||||
void SetGlowPlanes(FRenderState &state, const secplane_t& top, const secplane_t& bottom)
|
||||
|
@ -80,7 +81,7 @@ void SetSplitPlanes(FRenderState& state, const secplane_t& top, const secplane_t
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::RenderWall(HWDrawInfo *di, FRenderState &state, int textured)
|
||||
void HWWall::RenderWall(HWDrawInfo*di, FRenderState &state, int textured)
|
||||
{
|
||||
assert(vertcount > 0);
|
||||
state.SetLightIndex(dynlightindex);
|
||||
|
@ -94,7 +95,7 @@ void HWWall::RenderWall(HWDrawInfo *di, FRenderState &state, int textured)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state)
|
||||
void HWWall::RenderFogBoundary(HWDrawInfo*di, FRenderState &state)
|
||||
{
|
||||
if (gl_fogmode && !di->isFullbrightScene())
|
||||
{
|
||||
|
@ -117,7 +118,7 @@ void HWWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state)
|
||||
void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state)
|
||||
{
|
||||
if (!TexMan.mirrorTexture.isValid()) return;
|
||||
|
||||
|
@ -179,7 +180,7 @@ static const uint8_t renderwalltotier[] =
|
|||
CVAR(Bool, hw_npottest, false, 0)
|
||||
#endif
|
||||
|
||||
void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
||||
void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags)
|
||||
{
|
||||
int tmode = state.GetTextureMode();
|
||||
int rel = rellight + getExtraLight();
|
||||
|
@ -312,7 +313,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state)
|
||||
void HWWall::RenderTranslucentWall(HWDrawInfo*di, FRenderState &state)
|
||||
{
|
||||
state.SetRenderStyle(RenderStyle);
|
||||
if (texture)
|
||||
|
@ -338,7 +339,7 @@ void HWWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||
void HWWall::DrawWall(HWDrawInfo*di, FRenderState &state, bool translucent)
|
||||
{
|
||||
if (screen->BuffersArePersistent())
|
||||
{
|
||||
|
@ -379,7 +380,7 @@ void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::SetupLights(HWDrawInfo *di, FDynLightData &lightdata)
|
||||
void HWWall::SetupLights(HWDrawInfo*di, FDynLightData &lightdata)
|
||||
{
|
||||
lightdata.Clear();
|
||||
|
||||
|
@ -493,58 +494,67 @@ const char HWWall::passflag[] = {
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::PutWall(HWDrawInfo *di, bool translucent)
|
||||
void HWWall::PutWall(HWWallDispatcher *di, bool translucent)
|
||||
{
|
||||
if (texture && texture->GetTranslucency() && passflag[type] == 2)
|
||||
{
|
||||
translucent = true;
|
||||
}
|
||||
|
||||
auto ddi = di->di;
|
||||
if (translucent)
|
||||
{
|
||||
flags |= HWF_TRANSLUCENT;
|
||||
ViewDistance = (di->Viewpoint.Pos - (seg->linedef->v1->fPos() + seg->linedef->Delta() / 2)).XY().LengthSquared();
|
||||
}
|
||||
|
||||
if (di->isFullbrightScene())
|
||||
|
||||
if (di->di)
|
||||
{
|
||||
// light planes don't get drawn with fullbright rendering
|
||||
if (texture == NULL) return;
|
||||
Colormap.Clear();
|
||||
}
|
||||
|
||||
if (di->isFullbrightScene() || (Colormap.LightColor.isWhite() && lightlevel == 255))
|
||||
{
|
||||
flags &= ~HWF_GLOW;
|
||||
}
|
||||
|
||||
if (!screen->BuffersArePersistent())
|
||||
{
|
||||
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr)
|
||||
if (translucent)
|
||||
{
|
||||
SetupLights(di, lightdata);
|
||||
ViewDistance = (ddi->Viewpoint.Pos - (seg->linedef->v1->fPos() + seg->linedef->Delta() / 2)).XY().LengthSquared();
|
||||
}
|
||||
MakeVertices(di, translucent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool solid;
|
||||
if (passflag[type] == 1) solid = true;
|
||||
else if (type == RENDERWALL_FFBLOCK) solid = texture && !texture->isMasked();
|
||||
else solid = false;
|
||||
|
||||
bool hasDecals = solid && seg->sidedef && seg->sidedef->AttachedDecals;
|
||||
if (hasDecals)
|
||||
{
|
||||
// If we want to use the light infos for the decal we cannot delay the creation until the render pass.
|
||||
if (screen->BuffersArePersistent())
|
||||
if (ddi->isFullbrightScene())
|
||||
{
|
||||
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr)
|
||||
// light planes don't get drawn with fullbright rendering
|
||||
if (texture == NULL) return;
|
||||
Colormap.Clear();
|
||||
}
|
||||
|
||||
if (ddi->isFullbrightScene() || (Colormap.LightColor.isWhite() && lightlevel == 255))
|
||||
{
|
||||
flags &= ~HWF_GLOW;
|
||||
}
|
||||
|
||||
if (!screen->BuffersArePersistent())
|
||||
{
|
||||
if (ddi->Level->HasDynamicLights && !ddi->isFullbrightScene() && texture != nullptr)
|
||||
{
|
||||
SetupLights(di, lightdata);
|
||||
SetupLights(ddi, lightdata);
|
||||
}
|
||||
MakeVertices(ddi, translucent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool solid;
|
||||
if (passflag[type] == 1) solid = true;
|
||||
else if (type == RENDERWALL_FFBLOCK) solid = texture && !texture->isMasked();
|
||||
else solid = false;
|
||||
|
||||
bool hasDecals = solid && seg->sidedef && seg->sidedef->AttachedDecals;
|
||||
if (hasDecals)
|
||||
{
|
||||
// If we want to use the light infos for the decal we cannot delay the creation until the render pass.
|
||||
if (screen->BuffersArePersistent())
|
||||
{
|
||||
if (ddi->Level->HasDynamicLights && !ddi->isFullbrightScene() && texture != nullptr)
|
||||
{
|
||||
SetupLights(ddi, lightdata);
|
||||
}
|
||||
}
|
||||
ProcessDecals(ddi);
|
||||
}
|
||||
ProcessDecals(di);
|
||||
}
|
||||
|
||||
|
||||
|
@ -563,113 +573,123 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane)
|
||||
void HWWall::PutPortal(HWWallDispatcher *di, int ptype, int plane)
|
||||
{
|
||||
HWPortal * portal = nullptr;
|
||||
|
||||
MakeVertices(di, false);
|
||||
switch (ptype)
|
||||
auto ddi = di->di;
|
||||
if (ddi)
|
||||
{
|
||||
// portals don't go into the draw list.
|
||||
// Instead they are added to the portal manager
|
||||
case PORTALTYPE_HORIZON:
|
||||
horizon = portalState.UniqueHorizons.Get(horizon);
|
||||
portal = di->FindPortal(horizon);
|
||||
if (!portal)
|
||||
MakeVertices(ddi, false);
|
||||
switch (ptype)
|
||||
{
|
||||
portal = new HWHorizonPortal(&portalState, horizon, di->Viewpoint);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKYBOX:
|
||||
portal = di->FindPortal(secportal);
|
||||
if (!portal)
|
||||
{
|
||||
// either a regular skybox or an Eternity-style horizon
|
||||
if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new HWEEHorizonPortal(&portalState, secportal);
|
||||
else
|
||||
{
|
||||
portal = new HWSkyboxPortal(&portalState, secportal);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SECTORSTACK:
|
||||
portal = di->FindPortal(this->portal);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWSectorStackPortal(&portalState, this->portal);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_PLANEMIRROR:
|
||||
if (portalState.PlaneMirrorMode * planemirror->fC() <= 0)
|
||||
{
|
||||
planemirror = portalState.UniquePlaneMirrors.Get(planemirror);
|
||||
portal = di->FindPortal(planemirror);
|
||||
// portals don't go into the draw list.
|
||||
// Instead they are added to the portal manager
|
||||
case PORTALTYPE_HORIZON:
|
||||
horizon = portalState.UniqueHorizons.Get(horizon);
|
||||
portal = ddi->FindPortal(horizon);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWPlaneMirrorPortal(&portalState, planemirror);
|
||||
di->Portals.Push(portal);
|
||||
portal = new HWHorizonPortal(&portalState, horizon, ddi->Viewpoint);
|
||||
ddi->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case PORTALTYPE_MIRROR:
|
||||
portal = di->FindPortal(seg->linedef);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWMirrorPortal(&portalState, seg->linedef);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
if (gl_mirror_envmap)
|
||||
{
|
||||
// draw a reflective layer over the mirror
|
||||
di->AddMirrorSurface(this);
|
||||
}
|
||||
break;
|
||||
|
||||
case PORTALTYPE_LINETOLINE:
|
||||
if (!lineportal)
|
||||
return;
|
||||
portal = di->FindPortal(lineportal);
|
||||
if (!portal)
|
||||
{
|
||||
line_t *otherside = lineportal->lines[0]->mDestination;
|
||||
if (otherside != nullptr && otherside->portalindex < di->Level->linePortals.Size())
|
||||
case PORTALTYPE_SKYBOX:
|
||||
portal = ddi->FindPortal(secportal);
|
||||
if (!portal)
|
||||
{
|
||||
di->ProcessActorsInPortal(otherside->getPortal()->mGroup, di->in_area);
|
||||
// either a regular skybox or an Eternity-style horizon
|
||||
if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new HWEEHorizonPortal(&portalState, secportal);
|
||||
else
|
||||
{
|
||||
portal = new HWSkyboxPortal(&portalState, secportal);
|
||||
ddi->Portals.Push(portal);
|
||||
}
|
||||
}
|
||||
portal = new HWLineToLinePortal(&portalState, lineportal);
|
||||
di->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKY:
|
||||
sky = portalState.UniqueSkies.Get(sky);
|
||||
portal = di->FindPortal(sky);
|
||||
if (!portal)
|
||||
case PORTALTYPE_SECTORSTACK:
|
||||
portal = ddi->FindPortal(this->portal);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWSectorStackPortal(&portalState, this->portal);
|
||||
ddi->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_PLANEMIRROR:
|
||||
if (portalState.PlaneMirrorMode * planemirror->fC() <= 0)
|
||||
{
|
||||
planemirror = portalState.UniquePlaneMirrors.Get(planemirror);
|
||||
portal = ddi->FindPortal(planemirror);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWPlaneMirrorPortal(&portalState, planemirror);
|
||||
ddi->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
}
|
||||
break;
|
||||
|
||||
case PORTALTYPE_MIRROR:
|
||||
portal = ddi->FindPortal(seg->linedef);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWMirrorPortal(&portalState, seg->linedef);
|
||||
ddi->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
if (gl_mirror_envmap)
|
||||
{
|
||||
// draw a reflective layer over the mirror
|
||||
ddi->AddMirrorSurface(this);
|
||||
}
|
||||
break;
|
||||
|
||||
case PORTALTYPE_LINETOLINE:
|
||||
if (!lineportal)
|
||||
return;
|
||||
portal = ddi->FindPortal(lineportal);
|
||||
if (!portal)
|
||||
{
|
||||
line_t* otherside = lineportal->lines[0]->mDestination;
|
||||
if (otherside != nullptr && otherside->portalindex < ddi->Level->linePortals.Size())
|
||||
{
|
||||
ddi->ProcessActorsInPortal(otherside->getPortal()->mGroup, ddi->in_area);
|
||||
}
|
||||
portal = new HWLineToLinePortal(&portalState, lineportal);
|
||||
ddi->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKY:
|
||||
sky = portalState.UniqueSkies.Get(sky);
|
||||
portal = ddi->FindPortal(sky);
|
||||
if (!portal)
|
||||
{
|
||||
portal = new HWSkyPortal(screen->mSkyData, &portalState, sky);
|
||||
ddi->Portals.Push(portal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
}
|
||||
vertcount = 0;
|
||||
|
||||
if (plane != -1 && portal)
|
||||
{
|
||||
portal = new HWSkyPortal(screen->mSkyData, &portalState, sky);
|
||||
di->Portals.Push(portal);
|
||||
portal->planesused |= (1 << plane);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
}
|
||||
vertcount = 0;
|
||||
|
||||
if (plane != -1 && portal)
|
||||
else
|
||||
{
|
||||
portal->planesused |= (1<<plane);
|
||||
portaltype = ptype;
|
||||
portalplane = plane;
|
||||
di->AddPortal(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -679,7 +699,7 @@ void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::Put3DWall(HWDrawInfo *di, lightlist_t * lightlist, bool translucent)
|
||||
void HWWall::Put3DWall(HWWallDispatcher *di, lightlist_t * lightlist, bool translucent)
|
||||
{
|
||||
// only modify the light di->Level-> if it doesn't originate from the seg's frontsector. This is to account for light transferring effects
|
||||
if (lightlist->p_lightlevel != &seg->sidedef->sector->lightlevel)
|
||||
|
@ -699,7 +719,7 @@ void HWWall::Put3DWall(HWDrawInfo *di, lightlist_t * lightlist, bool translucent
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool HWWall::SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright)
|
||||
bool HWWall::SplitWallComplex(HWWallDispatcher *di, sector_t * frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright)
|
||||
{
|
||||
// check for an intersection with the upper plane
|
||||
if ((maplightbottomleft<ztop[0] && maplightbottomright>ztop[1]) ||
|
||||
|
@ -793,7 +813,7 @@ bool HWWall::SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool trans
|
|||
return false;
|
||||
}
|
||||
|
||||
void HWWall::SplitWall(HWDrawInfo *di, sector_t * frontsector, bool translucent)
|
||||
void HWWall::SplitWall(HWWallDispatcher *di, sector_t * frontsector, bool translucent)
|
||||
{
|
||||
float maplightbottomleft;
|
||||
float maplightbottomright;
|
||||
|
@ -908,7 +928,7 @@ out:
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
bool HWWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
|
||||
bool HWWall::DoHorizon(HWWallDispatcher *di, seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
|
||||
{
|
||||
HWHorizonInfo hi;
|
||||
lightlist_t * light;
|
||||
|
@ -917,64 +937,73 @@ bool HWWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,
|
|||
ztop[1] = ztop[0] = fs->GetPlaneTexZ(sector_t::ceiling);
|
||||
zbottom[1] = zbottom[0] = fs->GetPlaneTexZ(sector_t::floor);
|
||||
|
||||
auto vpz = di->Viewpoint.Pos.Z;
|
||||
if (vpz < fs->GetPlaneTexZ(sector_t::ceiling))
|
||||
auto ddi = di->di;
|
||||
if (ddi)
|
||||
{
|
||||
auto vpz = ddi->Viewpoint.Pos.Z;
|
||||
if (vpz < fs->GetPlaneTexZ(sector_t::ceiling))
|
||||
{
|
||||
if (vpz > fs->GetPlaneTexZ(sector_t::floor))
|
||||
zbottom[1] = zbottom[0] = vpz;
|
||||
|
||||
if (fs->GetTexture(sector_t::ceiling) == skyflatnum)
|
||||
{
|
||||
SkyPlane(di, fs, sector_t::ceiling, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, sector_t::ceiling);
|
||||
hi.lightlevel = hw_ClampLight(fs->GetCeilingLight());
|
||||
hi.colormap = fs->Colormap;
|
||||
hi.specialcolor = fs->SpecialColors[sector_t::ceiling];
|
||||
|
||||
if (fs->e->XFloor.ffloors.Size())
|
||||
{
|
||||
light = P_GetPlaneLight(fs, &fs->ceilingplane, true);
|
||||
|
||||
if (!(fs->GetFlags(sector_t::ceiling) & PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
hi.colormap.CopyLight(light->extra_colormap);
|
||||
}
|
||||
|
||||
if (ddi->isFullbrightScene()) hi.colormap.Clear();
|
||||
horizon = &hi;
|
||||
PutPortal(di, PORTALTYPE_HORIZON, -1);
|
||||
}
|
||||
ztop[1] = ztop[0] = zbottom[0];
|
||||
}
|
||||
|
||||
if (vpz > fs->GetPlaneTexZ(sector_t::floor))
|
||||
zbottom[1] = zbottom[0] = vpz;
|
||||
|
||||
if (fs->GetTexture(sector_t::ceiling) == skyflatnum)
|
||||
{
|
||||
SkyPlane(di, fs, sector_t::ceiling, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, sector_t::ceiling);
|
||||
hi.lightlevel = hw_ClampLight(fs->GetCeilingLight());
|
||||
hi.colormap = fs->Colormap;
|
||||
hi.specialcolor = fs->SpecialColors[sector_t::ceiling];
|
||||
|
||||
if (fs->e->XFloor.ffloors.Size())
|
||||
zbottom[1] = zbottom[0] = fs->GetPlaneTexZ(sector_t::floor);
|
||||
if (fs->GetTexture(sector_t::floor) == skyflatnum)
|
||||
{
|
||||
light = P_GetPlaneLight(fs, &fs->ceilingplane, true);
|
||||
|
||||
if(!(fs->GetFlags(sector_t::ceiling)&PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
hi.colormap.CopyLight(light->extra_colormap);
|
||||
SkyPlane(di, fs, sector_t::floor, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, sector_t::floor);
|
||||
hi.lightlevel = hw_ClampLight(fs->GetFloorLight());
|
||||
hi.colormap = fs->Colormap;
|
||||
hi.specialcolor = fs->SpecialColors[sector_t::floor];
|
||||
|
||||
if (di->isFullbrightScene()) hi.colormap.Clear();
|
||||
horizon = &hi;
|
||||
PutPortal(di, PORTALTYPE_HORIZON, -1);
|
||||
if (fs->e->XFloor.ffloors.Size())
|
||||
{
|
||||
light = P_GetPlaneLight(fs, &fs->floorplane, false);
|
||||
|
||||
if (!(fs->GetFlags(sector_t::floor) & PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
hi.colormap.CopyLight(light->extra_colormap);
|
||||
}
|
||||
|
||||
if (ddi->isFullbrightScene()) hi.colormap.Clear();
|
||||
horizon = &hi;
|
||||
PutPortal(di, PORTALTYPE_HORIZON, -1);
|
||||
}
|
||||
}
|
||||
ztop[1] = ztop[0] = zbottom[0];
|
||||
}
|
||||
|
||||
if (vpz > fs->GetPlaneTexZ(sector_t::floor))
|
||||
}
|
||||
else
|
||||
{
|
||||
zbottom[1] = zbottom[0] = fs->GetPlaneTexZ(sector_t::floor);
|
||||
if (fs->GetTexture(sector_t::floor) == skyflatnum)
|
||||
{
|
||||
SkyPlane(di, fs, sector_t::floor, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, sector_t::floor);
|
||||
hi.lightlevel = hw_ClampLight(fs->GetFloorLight());
|
||||
hi.colormap = fs->Colormap;
|
||||
hi.specialcolor = fs->SpecialColors[sector_t::floor];
|
||||
|
||||
if (fs->e->XFloor.ffloors.Size())
|
||||
{
|
||||
light = P_GetPlaneLight(fs, &fs->floorplane, false);
|
||||
|
||||
if(!(fs->GetFlags(sector_t::floor)&PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
hi.colormap.CopyLight(light->extra_colormap);
|
||||
}
|
||||
|
||||
if (di->isFullbrightScene()) hi.colormap.Clear();
|
||||
horizon = &hi;
|
||||
PutPortal(di, PORTALTYPE_HORIZON, -1);
|
||||
}
|
||||
// we cannot build the real portal yet, the mesh builder just needs a generic 'horizon' portal that needs to be filled in in the render pass.
|
||||
PutPortal(di, PORTALTYPE_HORIZON, -1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1225,7 +1254,7 @@ static void GetTexCoordInfo(FGameTexture *tex, FTexCoordInfo *tci, side_t *side,
|
|||
// Handle one sided walls, upper and lower texture
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::DoTexture(HWDrawInfo *di, int _type,seg_t * seg, int peg,
|
||||
void HWWall::DoTexture(HWWallDispatcher *di, int _type,seg_t * seg, int peg,
|
||||
float ceilingrefheight,float floorrefheight,
|
||||
float topleft,float topright,
|
||||
float bottomleft,float bottomright,
|
||||
|
@ -1284,7 +1313,7 @@ void HWWall::DoTexture(HWDrawInfo *di, int _type,seg_t * seg, int peg,
|
|||
|
||||
// Add this wall to the render list
|
||||
sector_t * sec = sub ? sub->sector : seg->frontsector;
|
||||
if (sec->e->XFloor.lightlist.Size()==0 || di->isFullbrightScene()) PutWall(di, false);
|
||||
if (sec->e->XFloor.lightlist.Size()==0 || di->isFullbrightScene()) PutWall(di, false);
|
||||
else SplitWall(di, sec, false);
|
||||
}
|
||||
|
||||
|
@ -1299,7 +1328,7 @@ void HWWall::DoTexture(HWDrawInfo *di, int _type,seg_t * seg, int peg,
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary,
|
||||
void HWWall::DoMidTexture(HWWallDispatcher *di, seg_t * seg, bool drawfogboundary,
|
||||
sector_t * front, sector_t * back,
|
||||
sector_t * realfront, sector_t * realback,
|
||||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
|
@ -1634,7 +1663,7 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary,
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, int roverIndex,
|
||||
void HWWall::BuildFFBlock(HWWallDispatcher *di, seg_t * seg, F3DFloor * rover, int roverIndex,
|
||||
float ff_topleft, float ff_topright,
|
||||
float ff_bottomleft, float ff_bottomright)
|
||||
{
|
||||
|
@ -1788,7 +1817,7 @@ __forceinline void HWWall::GetPlanePos(F3DFloor::planeref *planeref, float &left
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::InverseFloors(HWDrawInfo *di, seg_t * seg, sector_t * frontsector,
|
||||
void HWWall::InverseFloors(HWWallDispatcher *di, seg_t * seg, sector_t * frontsector,
|
||||
float topleft, float topright,
|
||||
float bottomleft, float bottomright)
|
||||
{
|
||||
|
@ -1839,7 +1868,7 @@ void HWWall::InverseFloors(HWDrawInfo *di, seg_t * seg, sector_t * frontsector,
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::ClipFFloors(HWDrawInfo *di, seg_t * seg, F3DFloor * ffloor, int ffloorIndex, sector_t * frontsector,
|
||||
void HWWall::ClipFFloors(HWWallDispatcher *di, seg_t * seg, F3DFloor * ffloor, int ffloorIndex, sector_t * frontsector,
|
||||
float topleft, float topright,
|
||||
float bottomleft, float bottomright)
|
||||
{
|
||||
|
@ -1913,7 +1942,7 @@ done:
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::DoFFloorBlocks(HWDrawInfo *di, seg_t * seg, sector_t * frontsector, sector_t * backsector,
|
||||
void HWWall::DoFFloorBlocks(HWWallDispatcher *di, seg_t * seg, sector_t * frontsector, sector_t * backsector,
|
||||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
float bch1, float bch2, float bfh1, float bfh2)
|
||||
|
||||
|
@ -2018,7 +2047,7 @@ inline int CalcRelLight(int lightlevel, int orglightlevel, int rel)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||
void HWWall::Process(HWWallDispatcher *di, seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||
{
|
||||
vertex_t * v1, *v2;
|
||||
float fch1;
|
||||
|
@ -2273,7 +2302,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
|||
/* mid texture */
|
||||
sector_t *backsec = isportal? seg->linedef->getPortalDestination()->frontsector : backsector;
|
||||
|
||||
bool drawfogboundary = !di->isFullbrightScene() && di->CheckFog(frontsector, backsec);
|
||||
bool drawfogboundary = !di->isFullbrightScene() && CheckFog(di->Level, frontsector, backsec, di->lightmode);
|
||||
auto tex = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::mid), true);
|
||||
if (tex != NULL && tex->isValid())
|
||||
{
|
||||
|
@ -2378,7 +2407,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void HWWall::ProcessLowerMiniseg(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||
void HWWall::ProcessLowerMiniseg(HWWallDispatcher *di, seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||
{
|
||||
if (frontsector->GetTexture(sector_t::floor) == skyflatnum) return;
|
||||
lightlist = NULL;
|
||||
|
|
Loading…
Reference in a new issue