mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 01:11:28 +00:00
dddf48fd3e
Content was reordered so that the file can contain the inlines belonging to the map data types that previously had to be stored elsewhere. Also moved out of the Build folder because virtually everything in here can be traced to content available in Duke Nukem 3D's and Shadow Warrior's source releases.
437 lines
12 KiB
C++
437 lines
12 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:
|
|
static const char passflag[];
|
|
|
|
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;
|
|
int 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
|
|
int * planemirror; // for plane mirrors
|
|
spritetype* teleport; // SW's teleport-views
|
|
};
|
|
|
|
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 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);
|
|
|
|
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);
|
|
|
|
};
|
|
|
|
//==========================================================================
|
|
//
|
|
// One flat plane in the draw list
|
|
//
|
|
//==========================================================================
|
|
|
|
class HWFlat
|
|
{
|
|
public:
|
|
int section;
|
|
sectortype * sec;
|
|
tspritetype* Sprite; // for flat sprites.
|
|
FGameTexture *texture;
|
|
|
|
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;
|
|
FVector2 geoofs;
|
|
//int vboheight;
|
|
|
|
int plane;
|
|
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();
|
|
|
|
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:
|
|
|
|
tspritetype* Sprite;
|
|
PalEntry fade;
|
|
int shade, palette;
|
|
float visibility;
|
|
float alpha;
|
|
FRenderStyle RenderStyle;
|
|
int modelframe; // : sprite, 1: model, -1:voxel
|
|
voxmodel_t* voxel;
|
|
|
|
int index;
|
|
float depth;
|
|
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;
|
|
|
|
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(tileGetTexture(wall->picnum)->GetID(), wall->pal);
|
|
}
|
|
|
|
inline bool spriteHasTranslucency(const tspritetype* tspr)
|
|
{
|
|
if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || //(tspr->clipdist & TSPR_FLAGS_DRAW_LAST) ||
|
|
(tspr->ownerActor->sx().alpha))
|
|
return true;
|
|
|
|
return checkTranslucentReplacement(tileGetTexture(tspr->picnum)->GetID(), 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->sx().alpha;
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
//
|
|
//
|
|
//==========================================================================
|
|
extern PalEntry GlobalMapFog;
|
|
extern float GlobalFogDensity;
|
|
|
|
__forceinline void SetLightAndFog(FRenderState& state, PalEntry fade, int palette, int shade, float visibility, float alpha)
|
|
{
|
|
// Fog must be done before the texture so that the texture selector can override it.
|
|
bool foggy = (GlobalMapFog || (fade & 0xffffff));
|
|
auto ShadeDiv = lookups.tables[palette].ShadeFactor;
|
|
if (shade == 127) state.SetObjectColor(0xff000000); // 127 is generally used for shadow objects that must be black, even in foggy areas.
|
|
|
|
// Disable brightmaps if non-black fog is used.
|
|
if (ShadeDiv >= 1 / 1000.f && foggy)
|
|
{
|
|
state.EnableFog(1);
|
|
float density = GlobalMapFog ? GlobalFogDensity : 350.f - Scale(numshades - shade, 150, numshades);
|
|
state.SetFog((GlobalMapFog) ? GlobalMapFog : fade, density * hw_density);
|
|
state.SetSoftLightLevel(255);
|
|
state.SetLightParms(128.f, 1 / 1000.f);
|
|
}
|
|
else
|
|
{
|
|
state.EnableFog(0);
|
|
state.SetFog(0, 0);
|
|
state.SetSoftLightLevel(gl_fogmode != 0 && ShadeDiv >= 1 / 1000.f ? max(0, 255 - Scale(shade, 255, numshades)) : 255);
|
|
state.SetLightParms(visibility, ShadeDiv / (numshades - 2));
|
|
}
|
|
|
|
// The shade rgb from the tint is ignored here.
|
|
state.SetColor(globalr * (1 / 255.f), globalg * (1 / 255.f), globalb * (1 / 255.f), alpha);
|
|
}
|
|
|