mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 08:52:00 +00:00
- better handling for Duke's scrolling cloudy skies.
* Using the Doom-style dome here because it looks better. * this necessitated changes to the backend to allow both types of sky domes at the same time * do not clamp panning fields for cloudy sky with the new renderer because this makes the texture jump.
This commit is contained in:
parent
39c457bbf2
commit
c303884274
9 changed files with 113 additions and 36 deletions
|
@ -3,7 +3,7 @@
|
|||
|
||||
//ceilingstat/floorstat:
|
||||
// bit 0: 1 = parallaxing, 0 = not "P"
|
||||
// bit 1: 1 = groudraw, 0 = not
|
||||
// bit 1: 1 = sloped, 0 = not
|
||||
// bit 2: 1 = swap x&y, 0 = not "F"
|
||||
// bit 3: 1 = double smooshiness "E"
|
||||
// bit 4: 1 = x-flip "F"
|
||||
|
@ -17,7 +17,8 @@
|
|||
// bit 9: 1 = blocking ceiling/floor
|
||||
// bit 10: 1 = YAX'ed ceiling/floor
|
||||
// bit 11: 1 = hitscan-sensitive ceiling/floor
|
||||
// bits 12-15: reserved
|
||||
// bits 12-14: reserved
|
||||
// bit 15: SW: block FAF hitscans
|
||||
|
||||
//////////////////// Version 7 map format ////////////////////
|
||||
enum
|
||||
|
@ -32,6 +33,8 @@ enum
|
|||
CSTAT_SECTOR_TRANS = 128,
|
||||
CSTAT_SECTOR_TRANS_INVERT = 256,
|
||||
CSTAT_SECTOR_METHOD = 384,
|
||||
|
||||
SECTOREX_CLOUDSCROLL = 1,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -67,6 +70,7 @@ struct sectortype
|
|||
int16_t extra;
|
||||
|
||||
uint8_t dirty;
|
||||
uint8_t exflags;
|
||||
float ceilingxpan_, ceilingypan_, floorxpan_, floorypan_;
|
||||
uint8_t portalflags;
|
||||
int8_t portalnum;
|
||||
|
|
|
@ -140,11 +140,11 @@ FSkyVertexBuffer::~FSkyVertexBuffer()
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// todo: make both available at the same time.
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef BUILD_SKY
|
||||
void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip)
|
||||
|
||||
void FSkyVertexBuffer::SkyVertexDoom(int r, int c, bool zflip)
|
||||
{
|
||||
static const FAngle maxSideAngle = 60.f;
|
||||
static const float scale = 10000.;
|
||||
|
@ -180,8 +180,14 @@ void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip)
|
|||
|
||||
mVertices.Push(vert);
|
||||
}
|
||||
#else
|
||||
void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::SkyVertexBuild(int r, int c, bool zflip)
|
||||
{
|
||||
static const FAngle maxSideAngle = 60.f;
|
||||
static const float scale = 10000.;
|
||||
|
@ -206,34 +212,65 @@ void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip)
|
|||
|
||||
mVertices.Push(vert);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::CreateSkyHemisphere(int hemi)
|
||||
void FSkyVertexBuffer::CreateSkyHemisphereDoom(int hemi)
|
||||
{
|
||||
int r, c;
|
||||
bool zflip = !!(hemi & SKYHEMI_LOWER);
|
||||
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
mPrimStartDoom.Push(mVertices.Size());
|
||||
|
||||
for (c = 0; c < mColumns; c++)
|
||||
{
|
||||
SkyVertex(1, c, zflip);
|
||||
SkyVertexDoom(1, c, zflip);
|
||||
}
|
||||
|
||||
// The total number of triangles per hemisphere can be calculated
|
||||
// as follows: rows * columns * 2 + 2 (for the top cap).
|
||||
for (r = 0; r < mRows; r++)
|
||||
{
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
mPrimStartDoom.Push(mVertices.Size());
|
||||
for (c = 0; c <= mColumns; c++)
|
||||
{
|
||||
SkyVertex(r + zflip, c, zflip);
|
||||
SkyVertex(r + 1 - zflip, c, zflip);
|
||||
SkyVertexDoom(r + zflip, c, zflip);
|
||||
SkyVertexDoom(r + 1 - zflip, c, zflip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::CreateSkyHemisphereBuild(int hemi)
|
||||
{
|
||||
int r, c;
|
||||
bool zflip = !!(hemi & SKYHEMI_LOWER);
|
||||
|
||||
mPrimStartBuild.Push(mVertices.Size());
|
||||
|
||||
for (c = 0; c < mColumns; c++)
|
||||
{
|
||||
SkyVertexBuild(1, c, zflip);
|
||||
}
|
||||
|
||||
// The total number of triangles per hemisphere can be calculated
|
||||
// as follows: rows * columns * 2 + 2 (for the top cap).
|
||||
for (r = 0; r < mRows; r++)
|
||||
{
|
||||
mPrimStartBuild.Push(mVertices.Size());
|
||||
for (c = 0; c <= mColumns; c++)
|
||||
{
|
||||
SkyVertexBuild(r + zflip, c, zflip);
|
||||
SkyVertexBuild(r + 1 - zflip, c, zflip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -267,9 +304,13 @@ void FSkyVertexBuffer::CreateDome()
|
|||
|
||||
mColumns = 128;
|
||||
mRows = 4;
|
||||
CreateSkyHemisphere(SKYHEMI_UPPER);
|
||||
CreateSkyHemisphere(SKYHEMI_LOWER);
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
CreateSkyHemisphereDoom(SKYHEMI_UPPER);
|
||||
CreateSkyHemisphereDoom(SKYHEMI_LOWER);
|
||||
mPrimStartDoom.Push(mVertices.Size());
|
||||
|
||||
CreateSkyHemisphereBuild(SKYHEMI_UPPER);
|
||||
CreateSkyHemisphereBuild(SKYHEMI_LOWER);
|
||||
mPrimStartBuild.Push(mVertices.Size());
|
||||
|
||||
mSideStart = mVertices.Size();
|
||||
mFaceStart[0] = mSideStart + 10;
|
||||
|
@ -401,7 +442,7 @@ void FSkyVertexBuffer::SetupMatrices(FGameTexture *tex, float x_offset, float y_
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::RenderRow(FRenderState& state, EDrawType prim, int row, bool apply)
|
||||
void FSkyVertexBuffer::RenderRow(FRenderState& state, EDrawType prim, int row, TArray<unsigned int>& mPrimStart, bool apply)
|
||||
{
|
||||
state.Draw(prim, mPrimStart[row], mPrimStart[row + 1] - mPrimStart[row]);
|
||||
}
|
||||
|
@ -412,8 +453,9 @@ void FSkyVertexBuffer::RenderRow(FRenderState& state, EDrawType prim, int row, b
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::RenderDome(FRenderState& state, FGameTexture* tex, int mode)
|
||||
void FSkyVertexBuffer::RenderDome(FRenderState& state, FGameTexture* tex, int mode, bool which)
|
||||
{
|
||||
auto& primStart = which ? mPrimStartBuild : mPrimStartDoom;
|
||||
if (tex && tex->isValid())
|
||||
{
|
||||
state.SetMaterial(tex, UF_Texture, 0, CLAMP_NONE, 0, -1);
|
||||
|
@ -429,17 +471,17 @@ void FSkyVertexBuffer::RenderDome(FRenderState& state, FGameTexture* tex, int mo
|
|||
auto& col = R_GetSkyCapColor(tex);
|
||||
state.SetObjectColor(col.first);
|
||||
state.EnableTexture(false);
|
||||
RenderRow(state, DT_TriangleFan, 0);
|
||||
RenderRow(state, DT_TriangleFan, 0, primStart);
|
||||
|
||||
state.SetObjectColor(col.second);
|
||||
RenderRow(state, DT_TriangleFan, rc);
|
||||
RenderRow(state, DT_TriangleFan, rc, primStart);
|
||||
state.EnableTexture(true);
|
||||
}
|
||||
state.SetObjectColor(0xffffffff);
|
||||
for (int i = 1; i <= mRows; i++)
|
||||
{
|
||||
RenderRow(state, DT_TriangleStrip, i, i == 1);
|
||||
RenderRow(state, DT_TriangleStrip, rc + i, false);
|
||||
RenderRow(state, DT_TriangleStrip, i, primStart, i == 1);
|
||||
RenderRow(state, DT_TriangleStrip, rc + i, primStart, false);
|
||||
}
|
||||
|
||||
state.EnableTextureMatrix(false);
|
||||
|
@ -449,7 +491,7 @@ void FSkyVertexBuffer::RenderDome(FRenderState& state, FGameTexture* tex, int mo
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// This is only for Doom-style skies.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -459,7 +501,7 @@ void FSkyVertexBuffer::RenderDome(FRenderState& state, FGameTexture* tex, float
|
|||
{
|
||||
SetupMatrices(tex, x_offset, y_offset, mirror, mode, state.mModelMatrix, state.mTextureMatrix, tiled, xscale, yscale);
|
||||
}
|
||||
RenderDome(state, tex, mode);
|
||||
RenderDome(state, tex, mode, false);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ public:
|
|||
IVertexBuffer *mVertexBuffer;
|
||||
|
||||
TArray<FSkyVertex> mVertices;
|
||||
TArray<unsigned int> mPrimStart;
|
||||
TArray<unsigned int> mPrimStartDoom;
|
||||
TArray<unsigned int> mPrimStartBuild;
|
||||
|
||||
int mRows, mColumns;
|
||||
|
||||
|
@ -69,8 +70,10 @@ public:
|
|||
int mFaceStart[7];
|
||||
int mSideStart;
|
||||
|
||||
void SkyVertex(int r, int c, bool yflip);
|
||||
void CreateSkyHemisphere(int hemi);
|
||||
void SkyVertexDoom(int r, int c, bool yflip);
|
||||
void SkyVertexBuild(int r, int c, bool yflip);
|
||||
void CreateSkyHemisphereDoom(int hemi);
|
||||
void CreateSkyHemisphereBuild(int hemi);
|
||||
void CreateDome();
|
||||
|
||||
public:
|
||||
|
@ -89,8 +92,8 @@ public:
|
|||
else return mSideStart;
|
||||
}
|
||||
|
||||
void RenderRow(FRenderState& state, EDrawType prim, int row, bool apply = true);
|
||||
void RenderDome(FRenderState& state, FGameTexture* tex, int mode);
|
||||
void RenderRow(FRenderState& state, EDrawType prim, int row, TArray<unsigned int>& mPrimStart, bool apply = true);
|
||||
void RenderDome(FRenderState& state, FGameTexture* tex, int mode, bool which);
|
||||
void RenderDome(FRenderState& state, FGameTexture* tex, float x_offset, float y_offset, bool mirror, int mode, bool tiled, float xscale = 0, float yscale = 0);
|
||||
void RenderBox(FRenderState& state, FSkyBox* tex, float x_offset, bool sky2, float stretch, const FVector3& skyrotatevector, const FVector3& skyrotatevector2);
|
||||
|
||||
|
|
|
@ -483,6 +483,7 @@ void setWallSectors()
|
|||
for (int i = 0; i < numsectors; i++)
|
||||
{
|
||||
sector[i].dirty = 255;
|
||||
sector[i].exflags = 0;
|
||||
for (int w = 0; w < sector[i].wallnum; w++)
|
||||
{
|
||||
wall[sector[i].wallptr + w].sector = i;
|
||||
|
|
|
@ -23,6 +23,7 @@ struct HWSkyInfo
|
|||
float y_offset;
|
||||
float y_scale;
|
||||
int shade;
|
||||
bool cloudy;
|
||||
FGameTexture * texture;
|
||||
PalEntry fadecolor;
|
||||
|
||||
|
|
|
@ -63,11 +63,21 @@ void initSkyInfo(HWDrawInfo *di, HWSkyInfo* sky, sectortype* sector, int plane,
|
|||
}
|
||||
|
||||
float xpanning = plane == plane_ceiling ? sector->ceilingxpan_ : sector->floorxpan_;
|
||||
float ypanning = plane == plane_ceiling ? sector->ceilingypan_ : sector->floorypan_;
|
||||
|
||||
// dapyscale is not relvant for a sky dome.
|
||||
sky->y_scale = FixedToFloat(daptileyscale);
|
||||
sky->y_offset = dapyoffs*1.5;
|
||||
sky->x_offset = xpanning / (1 << (realskybits - dapskybits));
|
||||
sky->cloudy = !!(sector->exflags & SECTOREX_CLOUDSCROLL);
|
||||
if (!sky->cloudy)
|
||||
{
|
||||
sky->y_offset = dapyoffs * 1.5;
|
||||
sky->x_offset = xpanning / (1 << (realskybits - dapskybits));
|
||||
}
|
||||
else
|
||||
{
|
||||
sky->y_offset = ypanning;
|
||||
sky->x_offset = 2 * xpanning / (1 << (realskybits - dapskybits));
|
||||
}
|
||||
sky->fadecolor = FadeColor;
|
||||
sky->shade = 0;// clamp(plane == plane_ceiling ? sector->ceilingshade : sector->floorshade, 0, numshades - 1);
|
||||
sky->texture = skytex;
|
||||
|
|
|
@ -58,7 +58,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
|
|||
{
|
||||
vertexBuffer->RenderBox(state, skybox, origin->x_offset, false, /*di->Level->info->pixelstretch*/1, { 0, 0, 1 }, { 0, 0, 1 });
|
||||
}
|
||||
else
|
||||
else if (!origin->cloudy)
|
||||
{
|
||||
auto tex = origin->texture;
|
||||
float texw = tex->GetDisplayWidth();
|
||||
|
@ -81,9 +81,13 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
|
|||
textureMatrix.loadIdentity();
|
||||
state.EnableTextureMatrix(true);
|
||||
textureMatrix.scale(1.f, repeat_fac, 1.f);
|
||||
vertexBuffer->RenderDome(state, origin->texture, FSkyVertexBuffer::SKYMODE_MAINLAYER);
|
||||
vertexBuffer->RenderDome(state, origin->texture, FSkyVertexBuffer::SKYMODE_MAINLAYER, true);
|
||||
state.EnableTextureMatrix(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
vertexBuffer->RenderDome(state, origin->texture, -origin->x_offset, origin->y_offset, false, FSkyVertexBuffer::SKYMODE_MAINLAYER, true);
|
||||
}
|
||||
state.SetTextureMode(TM_NORMAL);
|
||||
if (origin->fadecolor & 0xffffff)
|
||||
{
|
||||
|
|
|
@ -660,6 +660,8 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
|
|||
pSector->floorypan_ = load.floorypanning;
|
||||
pSector->visibility = load.visibility;
|
||||
qsector_filler[i] = load.fogpal;
|
||||
pSector->dirty = 255;
|
||||
pSector->exflags = 0;
|
||||
pSector->fogpal = 0;
|
||||
|
||||
if (sector[i].extra > 0)
|
||||
|
|
|
@ -1271,8 +1271,18 @@ void moveclouds(double smoothratio)
|
|||
cloudy += ps[screenpeek].angle.ang.fsin() * 0.5f;
|
||||
for (int i = 0; i < numclouds; i++)
|
||||
{
|
||||
sector[clouds[i]].setceilingxpan(cloudx);
|
||||
sector[clouds[i]].setceilingypan(cloudy);
|
||||
if (!testnewrenderer)
|
||||
{
|
||||
sector[clouds[i]].setceilingxpan(cloudx);
|
||||
sector[clouds[i]].setceilingypan(cloudy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no clamping here!
|
||||
sector[clouds[i]].ceilingxpan_ = cloudx;
|
||||
sector[clouds[i]].ceilingypan_ = cloudy;
|
||||
}
|
||||
sector[clouds[i]].exflags |= SECTOREX_CLOUDSCROLL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue