raze/source/core/rendering/scene/hw_drawstructs.h
Christoph Oelckers 71ca2c4677 - eliminate the last remaining references to the tile manager in the core renderer files.
The only thing left is the sky which needs more refactoring first and the tileUpdatePicnum call for sprites which cannot be resolved by the texture manager because Blood has a randomization factor included here.
2022-12-11 19:44:01 +01:00

422 lines
11 KiB
C++

#pragma once
//==========================================================================
//
// One wall segment in the draw list
//
//==========================================================================
#include "renderstyle.h"
#include "textures.h"
#include "fcolormap.h"
#include "build.h"
#include "gamefuncs.h"
#include "render.h"
#include "matrix.h"
#include "gamecontrol.h"
#include "hw_renderstate.h"
#include "hw_cvars.h"
#include "coreactor.h"
#ifdef _MSC_VER
#pragma warning(disable:4244) // this gets a bit annoying in the renderer...
#endif
struct HWHorizonInfo;
struct HWSkyInfo;
class FMaterial;
struct FTexCoordInfo;
struct FSectorPortalGroup;
struct FFlatVertex;
struct FDynLightData;
class VSMatrix;
struct FSpriteModelFrame;
class FRenderState;
struct voxmodel_t;
struct Section;
struct HWSectorPlane
{
FTextureID texture;
//secplane_t plane;
float Texheight;
float Angle;
FVector2 Offs;
FVector2 Scale;
void GetFromSector(sectortype* sec, int ceiling)
{
/*
Offs.X = (float)sec->GetXOffset(ceiling);
Offs.Y = (float)sec->GetYOffset(ceiling);
Scale.X = (float)sec->GetXScale(ceiling);
Scale.Y = (float)sec->GetYScale(ceiling);
Angle = (float)sec->GetAngle(ceiling).Degrees;
texture = sec->GetTexture(ceiling);
plane = sec->GetSecPlane(ceiling);
Texheight = (float)((ceiling == sector_t::ceiling) ? plane.fD() : -plane.fD());
*/
}
};
enum HWRenderStyle
{
STYLEHW_Normal, // default
STYLEHW_Solid, // drawn solid (needs special treatment for sprites)
STYLEHW_NoAlphaTest, // disable alpha test
};
enum WallTypes
{
RENDERWALL_NONE,
RENDERWALL_TOP,
RENDERWALL_M1S,
RENDERWALL_M2S,
RENDERWALL_BOTTOM,
RENDERWALL_FOGBOUNDARY,
RENDERWALL_MIRRORSURFACE,
RENDERWALL_M2SNF,
RENDERWALL_COLOR,
// Insert new types at the end!
};
enum PortalTypes
{
PORTALTYPE_SKY,
PORTALTYPE_HORIZON,
PORTALTYPE_SKYBOX,
PORTALTYPE_SECTORSTACK,
PORTALTYPE_PLANEMIRROR,
PORTALTYPE_MIRROR,
PORTALTYPE_LINETOLINE,
PORTALTYPE_LINETOSPRITE,
};
//==========================================================================
//
// One sector plane, still in fixed point
//
//==========================================================================
struct HWSeg
{
float x1,x2;
float y1,y2;
float fracleft, fracright;
FVector3 Normal() const
{
// we do not use the vector math inlines here because they are not optimized for speed but accuracy in the playsim and this is called quite frequently.
float x = y2 - y1;
float y = x1 - x2;
float ilength = 1.f / sqrtf(x*x + y*y);
return FVector3(x * ilength, 0, y * ilength);
}
};
struct texcoord
{
float u,v;
};
struct HWDrawInfo;
class HWWall
{
public:
enum
{
HWF_CLAMPX=1,
HWF_CLAMPY=2,
HWF_SKYHACK=4,
HWF_NOSPLIT=64,
HWF_TRANSLUCENT = 128,
};
enum
{
RWF_BLANK = 0,
RWF_TEXTURED = 1, // actually not being used anymore because with buffers it's even less efficient not writing the texture coordinates - but leave it here
RWF_TRANS = 2,
RWF_NORENDER = 8,
};
enum
{
LOLFT,
UPLFT,
UPRGT,
LORGT,
};
friend struct HWDrawList;
friend class HWPortal;
FGameTexture *texture;
HWSeg glseg;
float ztop[2],zbottom[2];
texcoord tcs[4];
float alpha;
FRenderStyle RenderStyle;
float ViewDistance;
float visibility;
walltype* walldist;
short shade, palette;
PalEntry fade;
uint16_t flags;
uint8_t type;
int dynlightindex;
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
PortalDesc * portal; // stacked sector portals
const double * planemirror; // for plane mirrors
};
unsigned int vertindex;
unsigned int vertcount;
public:
walltype* seg;
tspritetype* Sprite;
sectortype* frontsector, * backsector;
//private:
void PutWall(HWDrawInfo *di, bool translucent);
void PutPortal(HWDrawInfo *di, int ptype, int plane);
void CheckTexturePosition();
void SetupLights(HWDrawInfo *di, FDynLightData &lightdata);
void MakeVertices(HWDrawInfo *di, bool nosplit);
void SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowmirror);
void SkyLine(HWDrawInfo *di, sectortype *sec, walltype *line);
void SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v2, float fch1, float fch2, float ffh1, float ffh2);
void SkyTop(HWDrawInfo* di, walltype* seg, sectortype* fs, sectortype* bs, FVector2& v1, FVector2& v2, float fch1, float fch2);
void SkyBottom(HWDrawInfo* di, walltype* seg, sectortype* fs, sectortype* bs, FVector2& v1, FVector2& v2, float ffh1, float ffh2);
bool DoHorizon(HWDrawInfo *di, walltype * seg,sectortype * fs, DVector2& v1, DVector2& v2);
bool SetWallCoordinates(walltype* seg, float topleft, float topright, float bottomleft, float bottomright);
void DoTexture(HWDrawInfo* di, walltype* wal, walltype* refwall, float yref, float topleft, float topright, float bottomleft, float bottomright);
void DoOneSidedTexture(HWDrawInfo *di, walltype * seg, sectortype* frontsector, sectortype* backsector, float topleft,float topright, float bottomleft,float bottomright);
void DoUpperTexture(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector, float topleft, float topright, float bottomleft, float bottomright);
void DoLowerTexture(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector, float topleft, float topright, float bottomleft, float bottomright);
void DoMidTexture(HWDrawInfo *di, walltype * seg,
sectortype * front, sectortype * back,
float fch1, float fch2, float ffh1, float ffh2,
float bch1, float bch2, float bfh1, float bfh2);
int CreateVertices(FFlatVertex *&ptr, bool nosplit);
int CountVertices();
void SplitLeftEdge(FFlatVertex*& ptr);
void SplitRightEdge(FFlatVertex*& ptr);
void CountLeftEdge(unsigned& ptr);
void CountRightEdge(unsigned& ptr);
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);
int CheckWallSprite(tspritetype* spr, tspritetype* last);
public:
void Process(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector);
void ProcessWallSprite(HWDrawInfo* di, tspritetype* spr, sectortype* frontsector);
float PointOnSide(float x,float y)
{
return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1));
}
void DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent);
};
//==========================================================================
//
// Common fields needed by the sprite sorter.
//
//==========================================================================
class HWFlatOrSprite
{
public:
float depth;
tspritetype* Sprite; // for flat sprites.
};
//==========================================================================
//
// One flat plane in the draw list
//
//==========================================================================
class HWFlat : public HWFlatOrSprite
{
public:
sectortype* sec;
FGameTexture* texture;
int section;
float z; // the z position of the flat (only valid for non-sloped planes)
PalEntry fade;
int shade, palette;
float visibility;
float alpha;
FRenderStyle RenderStyle;
int iboindex;
bool stack;
uint8_t plane;
short slopecount;
FVector2 geoofs;
FVector3 normal;
//int vboheight;
int slopeindex;
int vertindex, vertcount; // this should later use a static vertex buffer, but that'd hinder the development phase, so for now vertex data gets created on the fly.
void MakeVertices(HWDrawInfo* di);
int dynlightindex;
void CreateSkyboxVertices(FFlatVertex *buffer);
//void SetupLights(HWDrawInfo *di, FLightNode *head, FDynLightData &lightdata, int portalgroup);
void PutFlat(HWDrawInfo* di, int whichplane);
void ProcessSector(HWDrawInfo *di, sectortype * frontsector, int sectionnum, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies.
void ProcessFlatSprite(HWDrawInfo* di, tspritetype* sprite, sectortype* sector);
void DrawSubsectors(HWDrawInfo *di, FRenderState &state);
void DrawFlat(HWDrawInfo* di, FRenderState& state, bool translucent);
};
//==========================================================================
//
// One sprite in the draw list
//
//==========================================================================
class HWSprite : public HWFlatOrSprite
{
public:
PalEntry fade;
int shade, palette;
float visibility;
float alpha;
FRenderStyle RenderStyle;
int modelframe; // : sprite, 1: model, -1:voxel
voxmodel_t* voxel;
int index;
int vertexindex;
float x,y,z; // needed for sorting!
union
{
struct
{
float ul, ur;
float vt, vb;
float x1, y1, z1;
float x2, y2, z2;
};
VSMatrix rotmat;
};
int dynlightindex;
float alphaThreshold;
FGameTexture *texture;
DRotator Angles;
void CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp);
public:
void CreateVertices(HWDrawInfo* di);
void PutSprite(HWDrawInfo *di, bool translucent);
void Process(HWDrawInfo *di, tspritetype* thing,sectortype * sector, int thruportal = false);
bool ProcessVoxel(HWDrawInfo* di, voxmodel_t* voxel, tspritetype* tspr, sectortype* sector, bool rotate);
void DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent);
};
inline float Dist2(float x1,float y1,float x2,float y2)
{
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
//void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata);
extern const float LARGE_VALUE;
struct FDynLightData;
struct FDynamicLight;
bool GetLight(FDynLightData& dld, int group, Plane& p, FDynamicLight* light, bool checkside);
void AddLightToList(FDynLightData &dld, int group, FDynamicLight* light, bool forceAttenuate);
inline float sectorVisibility(sectortype* sec)
{
// Beware of wraparound madness...
int v = sec->visibility;
return v ? ((uint8_t)(v + 16)) / 16.f : 1.f;
}
inline const float hw_density = 0.35f;
int checkTranslucentReplacement(FTextureID picnum, int pal);
inline bool maskWallHasTranslucency(const walltype* wall)
{
return (wall->cstat & CSTAT_WALL_TRANSLUCENT) || checkTranslucentReplacement(wall->walltexture(), wall->pal);
}
inline bool spriteHasTranslucency(const tspritetype* tspr)
{
if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || //(tspr->clipdist & TSPR_FLAGS_DRAW_LAST) ||
(tspr->ownerActor->sprext.alpha))
return true;
return checkTranslucentReplacement(tspr->spritetexture(), tspr->pal);
}
inline void SetSpriteTranslucency(const tspritetype* sprite, float& alpha, FRenderStyle& RenderStyle)
{
bool trans = (sprite->cstat & CSTAT_SPRITE_TRANSLUCENT);
if (trans)
{
RenderStyle = GetRenderStyle(0, !!(sprite->cstat & CSTAT_SPRITE_TRANS_FLIP));
alpha = GetAlphaFromBlend((sprite->cstat & CSTAT_SPRITE_TRANS_FLIP) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
}
else
{
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
alpha = 1.f;
}
alpha *= 1.f - sprite->ownerActor->sprext.alpha;
}
extern PalEntry GlobalMapFog;
extern float GlobalFogDensity;
void SetLightAndFog(HWDrawInfo* di, FRenderState& state, PalEntry fade, int palette, int shade, float visibility, float alpha);