mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 17:01:28 +00:00
- add slope sprite support to the new renderer.
Some fudging was needed to avoid positioning problems as the renderer is more sensitive to this than Polymost.
This commit is contained in:
parent
6fd4d6d550
commit
beddf1e1ca
6 changed files with 85 additions and 35 deletions
|
@ -1499,7 +1499,7 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
|
|||
|
||||
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
|
||||
{
|
||||
int32_t x3, y3, x4, y4, zz;
|
||||
int32_t x3, y3, x4, y4;
|
||||
int32_t const heinum = spriteGetSlope(spr);
|
||||
int32_t const dax = (heinum * sintable[(spr->ang + 1024) & 2047]) << 1;
|
||||
int32_t const day = (heinum * sintable[(spr->ang + 512) & 2047]) << 1;
|
||||
|
|
|
@ -2635,24 +2635,6 @@ static int32_t polymost_lintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static inline int16_t tspriteGetSlope(tspriteptr_t const tspr)
|
||||
{
|
||||
if (!(tspr->cstat2 & CSTAT2_SPRITE_SLOPE))
|
||||
return 0;
|
||||
return uint8_t(tspr->xoffset) + (uint8_t(tspr->yoffset) << 8);
|
||||
}
|
||||
|
||||
static inline int32_t tspriteGetZOfSlope(tspriteptr_t const tspr, int32_t dax, int32_t day)
|
||||
{
|
||||
int16_t const heinum = tspriteGetSlope(tspr);
|
||||
if (heinum == 0)
|
||||
return tspr->z;
|
||||
|
||||
int const j = DMulScale(bsin(tspr->ang + 1024), day - tspr->y, -bsin(tspr->ang + 512), dax - tspr->x, 4);
|
||||
return tspr->z + MulScale(heinum, j, 18);
|
||||
}
|
||||
|
||||
static inline float tspriteGetZOfSlopeFloat(tspriteptr_t const tspr, float dax, float day)
|
||||
{
|
||||
int16_t const heinum = tspriteGetSlope(tspr);
|
||||
|
@ -3700,7 +3682,7 @@ void renderDrawMasks(void)
|
|||
if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR)
|
||||
{
|
||||
numpts = 4;
|
||||
GetFlatSpritePosition(tspr, tspr->pos.vec2, pp);
|
||||
GetFlatSpritePosition(tspr, tspr->pos.vec2, pp, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -274,12 +274,13 @@ void GetWallSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
template<class sprt>
|
||||
void TGetFlatSpritePosition(const sprt* spr, vec2_t pos, vec2_t* out, bool render)
|
||||
void TGetFlatSpritePosition(const spritetypebase* spr, vec2_t pos, vec2_t* out, int* outz, int heinum, bool render)
|
||||
{
|
||||
auto tex = tileGetTexture(spr->picnum);
|
||||
|
||||
int width, height, leftofs, topofs;
|
||||
int ratio = ksqrt(heinum * heinum + 4096 * 4096);
|
||||
|
||||
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].hiofs.xsize)
|
||||
{
|
||||
width = TileFiles.tiledata[spr->picnum].hiofs.xsize * spr->xrepeat;
|
||||
|
@ -303,26 +304,40 @@ void TGetFlatSpritePosition(const sprt* spr, vec2_t pos, vec2_t* out, bool rende
|
|||
|
||||
int cosang = bcos(spr->ang);
|
||||
int sinang = bsin(spr->ang);
|
||||
int cosangslope = DivScale(cosang, ratio, 12);
|
||||
int sinangslope = DivScale(sinang, ratio, 12);
|
||||
|
||||
out[0].x = pos.x + DMulScale(sinang, sprcenterx, cosang, sprcentery, 16);
|
||||
out[0].y = pos.y + DMulScale(sinang, sprcentery, -cosang, sprcenterx, 16);
|
||||
out[0].x = pos.x + DMulScale(sinang, sprcenterx, cosangslope, sprcentery, 16);
|
||||
out[0].y = pos.y + DMulScale(sinangslope, sprcentery, -cosang, sprcenterx, 16);
|
||||
|
||||
out[1].x = out[0].x - MulScale(sinang, width, 16);
|
||||
out[1].y = out[0].y + MulScale(cosang, width, 16);
|
||||
|
||||
vec2_t sub = { MulScale(cosang, height, 16), MulScale(sinang, height, 16) };
|
||||
vec2_t sub = { MulScale(cosangslope, height, 16), MulScale(sinangslope, height, 16) };
|
||||
out[2] = out[1] - sub;
|
||||
out[3] = out[0] - sub;
|
||||
if (outz)
|
||||
{
|
||||
if (!heinum) outz[3] = outz[2] = outz[1] = outz[0] = 0;
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int spos = DMulScale(-sinang, out[i].y - spr->y, -cosang, out[i].x - spr->x, 4);
|
||||
outz[i] = MulScale(heinum, spos, 18);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render)
|
||||
{
|
||||
TGetFlatSpritePosition(spr, pos, out, render);
|
||||
TGetFlatSpritePosition(spr, pos, out, nullptr, spriteGetSlope(spr), render);
|
||||
}
|
||||
|
||||
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool render)
|
||||
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, int* outz, bool render)
|
||||
{
|
||||
TGetFlatSpritePosition(spr, pos, out, render);
|
||||
TGetFlatSpritePosition(spr, pos, out, outz, tspriteGetSlope(spr), render);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -126,8 +126,8 @@ int getslopeval(sectortype* sect, int x, int y, int z, int planez);
|
|||
|
||||
void setWallSectors();
|
||||
void GetWallSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
|
||||
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
|
||||
void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
|
||||
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, int* outz = nullptr, bool render = false);
|
||||
void checkRotatedWalls();
|
||||
bool sectorsConnected(int sect1, int sect2);
|
||||
|
||||
|
@ -265,6 +265,22 @@ inline int spriteGetSlope(const spritetype* spr)
|
|||
return ((spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLOPE) ? 0 : uint8_t(spr->xoffset) + (uint8_t(spr->yoffset) << 8);
|
||||
}
|
||||
|
||||
// same stuff, different flag...
|
||||
inline int tspriteGetSlope(const tspritetype* spr)
|
||||
{
|
||||
return !(spr->cstat2 & CSTAT2_SPRITE_SLOPE) ? 0 : uint8_t(spr->xoffset) + (uint8_t(spr->yoffset) << 8);
|
||||
}
|
||||
|
||||
inline int32_t tspriteGetZOfSlope(const tspritetype* tspr, int dax, int day)
|
||||
{
|
||||
int heinum = tspriteGetSlope(tspr);
|
||||
if (heinum == 0) return tspr->z;
|
||||
|
||||
int const j = DMulScale(bsin(tspr->ang + 1024), day - tspr->y, -bsin(tspr->ang + 512), dax - tspr->x, 4);
|
||||
return tspr->z + MulScale(heinum, j, 18);
|
||||
}
|
||||
|
||||
|
||||
inline int I_GetBuildTime()
|
||||
{
|
||||
return I_GetTime(120);
|
||||
|
|
|
@ -272,7 +272,7 @@ public:
|
|||
|
||||
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();
|
||||
void MakeVertices(HWDrawInfo* di);
|
||||
|
||||
int dynlightindex;
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ void HWFlat::SetupLights(HWDrawInfo *di, FLightNode * node, FDynLightData &light
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void HWFlat::MakeVertices()
|
||||
void HWFlat::MakeVertices(HWDrawInfo* di)
|
||||
{
|
||||
if (vertcount > 0) return;
|
||||
bool canvas = texture->isHardwareCanvas();
|
||||
|
@ -120,17 +120,54 @@ void HWFlat::MakeVertices()
|
|||
else
|
||||
{
|
||||
vec2_t pos[4];
|
||||
GetFlatSpritePosition(Sprite, Sprite->pos.vec2, pos, true);
|
||||
int ofsz[4];
|
||||
GetFlatSpritePosition(Sprite, Sprite->pos.vec2, pos, ofsz, true);
|
||||
|
||||
auto ret = screen->mVertexData->AllocVertices(6);
|
||||
auto vp = ret.first;
|
||||
float x = !(Sprite->cstat & CSTAT_SPRITE_XFLIP) ? 0.f : 1.f;
|
||||
float y = !(Sprite->cstat & CSTAT_SPRITE_YFLIP) ? 0.f : 1.f;
|
||||
if (Sprite->cstat2 & CSTAT2_SPRITE_SLOPE)
|
||||
{
|
||||
|
||||
int posx = int(di->Viewpoint.Pos.X * 16.f);
|
||||
int posy = int(di->Viewpoint.Pos.Y * -16.f);
|
||||
int posz = int(di->Viewpoint.Pos.Z * -256.f);
|
||||
|
||||
// Make adjustments for poorly aligned slope sprites on floors or ceilings
|
||||
constexpr float ONPLANE_THRESHOLD = 3.f;
|
||||
if (tspriteGetZOfSlope(Sprite, posx, posy) < posz)
|
||||
{
|
||||
float maxofs = -FLT_MAX, minofs = FLT_MAX;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float vz = getceilzofslopeptr(Sprite->sectp, pos[i].x, pos[i].y) * (1 / -256.f);
|
||||
float sz = z + ofsz[i] * (1 / -256.f);
|
||||
int diff = vz - sz;
|
||||
if (diff > maxofs) maxofs = diff;
|
||||
if (diff < minofs) minofs = diff;
|
||||
}
|
||||
if (maxofs > 0 && minofs >= -ONPLANE_THRESHOLD && maxofs <= ONPLANE_THRESHOLD) z -= maxofs;
|
||||
}
|
||||
else
|
||||
{
|
||||
float maxofs = -FLT_MAX, minofs = FLT_MAX;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float vz = getflorzofslopeptr(Sprite->sectp, pos[i].x, pos[i].y) * (1 / -256.f);
|
||||
float sz = z + ofsz[i] * (1 / -256.f);
|
||||
int diff = vz - sz;
|
||||
if (diff > maxofs) maxofs = diff;
|
||||
if (diff < minofs) minofs = diff;
|
||||
}
|
||||
if (minofs < 0 && maxofs <= -ONPLANE_THRESHOLD && minofs >= ONPLANE_THRESHOLD) z -= minofs;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
const static unsigned indices[] = { 0, 1, 2, 0, 2, 3 };
|
||||
int j = indices[i];
|
||||
vp->SetVertex(pos[j].x * (1 / 16.f), z, pos[j].y * (1 / -16.f));
|
||||
vp->SetVertex(pos[j].x * (1 / 16.f), z + ofsz[j] * (1 / -256.f), pos[j].y * (1 / -16.f));
|
||||
if (!canvas) vp->SetTexCoord(j == 1 || j == 2 ? 1.f - x : x, j == 2 || j == 3 ? 1.f - y : y);
|
||||
else vp->SetTexCoord(j == 1 || j == 2 ? 1.f - x : x, j == 2 || j == 3 ? y : 1.f - y);
|
||||
vp++;
|
||||
|
@ -149,7 +186,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
|||
{
|
||||
if (screen->BuffersArePersistent() && !Sprite)
|
||||
{
|
||||
MakeVertices();
|
||||
MakeVertices(di);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -228,7 +265,7 @@ void HWFlat::PutFlat(HWDrawInfo *di, int whichplane)
|
|||
SetupLights(di, section->lighthead, lightdata, sector->PortalGroup);
|
||||
}
|
||||
#endif
|
||||
MakeVertices();
|
||||
MakeVertices(di);
|
||||
}
|
||||
di->AddFlat(this);
|
||||
rendered_flats++;
|
||||
|
|
Loading…
Reference in a new issue