mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-10 14:52:01 +00:00
- wall sprite WIP.
This commit is contained in:
parent
1dfb2672a8
commit
d0f38d7362
10 changed files with 243 additions and 186 deletions
|
@ -208,13 +208,26 @@ void PlanesAtPoint(const sectortype* sec, float dax, float day, float* pceilz, f
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out)
|
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render)
|
||||||
{
|
{
|
||||||
|
auto tex = tileGetTexture(spr->picnum);
|
||||||
|
|
||||||
|
int width, leftofs;
|
||||||
|
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].h_xsize)
|
||||||
|
{
|
||||||
|
width = TileFiles.tiledata[spr->picnum].h_xsize * spr->xrepeat;
|
||||||
|
leftofs = (TileFiles.tiledata[spr->picnum].h_xoffs + spr->xoffset) * spr->xrepeat;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width = tex->GetTexelWidth() * spr->xrepeat;
|
||||||
|
leftofs = (tex->GetTexelLeftOffset() + spr->xoffset) * spr->xrepeat;
|
||||||
|
}
|
||||||
|
|
||||||
int x = bsin(spr->ang) * spr->xrepeat;
|
int x = bsin(spr->ang) * spr->xrepeat;
|
||||||
int y = -bcos(spr->ang) * spr->xrepeat;
|
int y = -bcos(spr->ang) * spr->xrepeat;
|
||||||
int width = tileWidth(spr->picnum);
|
|
||||||
|
|
||||||
int xoff = tileLeftOffset(spr->picnum) + spr->xoffset;
|
int xoff = leftofs + spr->xoffset;
|
||||||
if (spr->cstat & CSTAT_SPRITE_XFLIP) xoff = -xoff;
|
if (spr->cstat & CSTAT_SPRITE_XFLIP) xoff = -xoff;
|
||||||
int origin = (width >> 1) + xoff;
|
int origin = (width >> 1) + xoff;
|
||||||
|
|
||||||
|
@ -235,19 +248,21 @@ void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool
|
||||||
{
|
{
|
||||||
auto tex = tileGetTexture(spr->picnum);
|
auto tex = tileGetTexture(spr->picnum);
|
||||||
|
|
||||||
int width, height;
|
int width, height, leftofs, topofs;
|
||||||
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].h_xsize)
|
if (render && hw_hightile && TileFiles.tiledata[spr->picnum].h_xsize)
|
||||||
{
|
{
|
||||||
width = TileFiles.tiledata[spr->picnum].h_xsize * spr->xrepeat;
|
width = TileFiles.tiledata[spr->picnum].h_xsize * spr->xrepeat;
|
||||||
height = TileFiles.tiledata[spr->picnum].h_ysize * spr->yrepeat;
|
height = TileFiles.tiledata[spr->picnum].h_ysize * spr->yrepeat;
|
||||||
|
leftofs = (TileFiles.tiledata[spr->picnum].h_xoffs + spr->xoffset) * spr->xrepeat;
|
||||||
|
topofs = (TileFiles.tiledata[spr->picnum].h_yoffs + spr->yoffset) * spr->yrepeat;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = tex->GetTexelWidth() * spr->xrepeat;
|
width = tex->GetTexelWidth() * spr->xrepeat;
|
||||||
height = tex->GetTexelHeight() * spr->yrepeat;
|
height = tex->GetTexelHeight() * spr->yrepeat;
|
||||||
|
leftofs = (tex->GetTexelLeftOffset() + spr->xoffset) * spr->xrepeat;
|
||||||
|
topofs = (tex->GetTexelTopOffset() + spr->yoffset) * spr->yrepeat;
|
||||||
}
|
}
|
||||||
int leftofs = (tex->GetTexelLeftOffset() + spr->xoffset) * spr->xrepeat;
|
|
||||||
int topofs = (tex->GetTexelTopOffset() + spr->yoffset) * spr->yrepeat;
|
|
||||||
|
|
||||||
if (spr->cstat & CSTAT_SPRITE_XFLIP) leftofs = -leftofs;
|
if (spr->cstat & CSTAT_SPRITE_XFLIP) leftofs = -leftofs;
|
||||||
if (spr->cstat & CSTAT_SPRITE_YFLIP) topofs = -topofs;
|
if (spr->cstat & CSTAT_SPRITE_YFLIP) topofs = -topofs;
|
||||||
|
|
|
@ -10,7 +10,7 @@ bool calcChaseCamPos(int* px, int* py, int* pz, spritetype* pspr, short *psectnu
|
||||||
bool spriteIsModelOrVoxel(const spritetype* tspr);
|
bool spriteIsModelOrVoxel(const spritetype* tspr);
|
||||||
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz);
|
void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ceilz, float* florz);
|
||||||
void setWallSectors();
|
void setWallSectors();
|
||||||
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out);
|
void GetWallSpritePosition(const spritetype* 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 spritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
|
||||||
void checkRotatedWalls();
|
void checkRotatedWalls();
|
||||||
|
|
||||||
|
|
|
@ -346,8 +346,11 @@ void HWDrawInfo::DispatchSprites()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
case CSTAT_SPRITE_ALIGNMENT_WALL:
|
||||||
// wall sprite
|
{
|
||||||
|
HWWall wall;
|
||||||
|
wall.ProcessWallSprite(this, tspr, §or[tspr->sectnum]);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
|
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
|
||||||
{
|
{
|
||||||
|
@ -445,20 +448,32 @@ void HWDrawInfo::RenderScene(FRenderState &state)
|
||||||
|
|
||||||
// These lists must be drawn in two passes for color and depth to avoid depth fighting with overlapping entries
|
// These lists must be drawn in two passes for color and depth to avoid depth fighting with overlapping entries
|
||||||
drawlists[GLDL_MASKEDFLATS].SortFlats(this);
|
drawlists[GLDL_MASKEDFLATS].SortFlats(this);
|
||||||
//drawlists[GLDL_MASKEDWALLSV].SortWalls(this);
|
drawlists[GLDL_MASKEDWALLSV].SortWallsVert(this);
|
||||||
//drawlists[GLDL_MASKEDWALLSH].SortWalls(this);
|
drawlists[GLDL_MASKEDWALLSH].SortWallsHorz(this);
|
||||||
|
|
||||||
// these lists are only wall and floor sprites - often attached to walls and floors - so they need to be offset from the plane they may be attached to.
|
// these lists are only wall and floor sprites - often attached to walls and floors - so they need to be offset from the plane they may be attached to.
|
||||||
drawlists[GLDL_MASKEDWALLSS].DrawWalls(this, state, false);
|
drawlists[GLDL_MASKEDWALLSS].DrawWalls(this, state, false);
|
||||||
|
|
||||||
|
// Each list must draw both its passes before the next one to ensure proper depth buffer contents.
|
||||||
state.SetDepthBias(-1, -128);
|
state.SetDepthBias(-1, -128);
|
||||||
state.SetDepthMask(false);
|
state.SetDepthMask(false);
|
||||||
drawlists[GLDL_MASKEDWALLSV].DrawWalls(this, state, false);
|
drawlists[GLDL_MASKEDWALLSV].DrawWalls(this, state, false);
|
||||||
drawlists[GLDL_MASKEDWALLSH].DrawWalls(this, state, false);
|
|
||||||
drawlists[GLDL_MASKEDFLATS].DrawFlats(this, state, false);
|
|
||||||
state.SetDepthMask(true);
|
state.SetDepthMask(true);
|
||||||
state.SetColorMask(false);
|
state.SetColorMask(false);
|
||||||
drawlists[GLDL_MASKEDWALLSV].DrawWalls(this, state, false);
|
drawlists[GLDL_MASKEDWALLSV].DrawWalls(this, state, false);
|
||||||
|
state.SetColorMask(true);
|
||||||
|
|
||||||
|
state.SetDepthMask(false);
|
||||||
drawlists[GLDL_MASKEDWALLSH].DrawWalls(this, state, false);
|
drawlists[GLDL_MASKEDWALLSH].DrawWalls(this, state, false);
|
||||||
|
state.SetDepthMask(true);
|
||||||
|
state.SetColorMask(false);
|
||||||
|
drawlists[GLDL_MASKEDWALLSH].DrawWalls(this, state, false);
|
||||||
|
state.SetColorMask(true);
|
||||||
|
|
||||||
|
state.SetDepthMask(false);
|
||||||
|
drawlists[GLDL_MASKEDFLATS].DrawFlats(this, state, false);
|
||||||
|
state.SetDepthMask(true);
|
||||||
|
state.SetColorMask(false);
|
||||||
drawlists[GLDL_MASKEDFLATS].DrawFlats(this, state, false);
|
drawlists[GLDL_MASKEDFLATS].DrawFlats(this, state, false);
|
||||||
state.SetColorMask(true);
|
state.SetColorMask(true);
|
||||||
state.ClearDepthBias();
|
state.ClearDepthBias();
|
||||||
|
|
|
@ -76,7 +76,6 @@ enum DrawListType
|
||||||
GLDL_MASKEDWALLSV, // vertical wall sprites
|
GLDL_MASKEDWALLSV, // vertical wall sprites
|
||||||
GLDL_MASKEDWALLSH, // horizontal wall sprites. These two lists merely exist for easier sorting.
|
GLDL_MASKEDWALLSH, // horizontal wall sprites. These two lists merely exist for easier sorting.
|
||||||
GLDL_MASKEDFLATS,
|
GLDL_MASKEDFLATS,
|
||||||
GLDL_MASKEDWALLSOFS,
|
|
||||||
GLDL_MODELS,
|
GLDL_MODELS,
|
||||||
|
|
||||||
GLDL_TRANSLUCENT,
|
GLDL_TRANSLUCENT,
|
||||||
|
|
|
@ -703,26 +703,104 @@ void HWDrawList::Sort(HWDrawInfo *di)
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Sorting the drawitems first by texture and then by light level
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void HWDrawList::SortWalls()
|
void HWDrawList::SortWallsVert(HWDrawInfo* di)
|
||||||
{
|
{
|
||||||
|
auto viewy = di->Viewpoint.Pos.Y;
|
||||||
if (drawitems.Size() > 1)
|
if (drawitems.Size() > 1)
|
||||||
{
|
{
|
||||||
std::sort(drawitems.begin(), drawitems.end(), [=](const HWDrawItem &a, const HWDrawItem &b) -> bool
|
TArray<HWDrawItem> list1(drawitems.Size(), false);
|
||||||
|
TArray<HWDrawItem> list2(drawitems.Size(), false);
|
||||||
|
|
||||||
|
for (auto& item : drawitems)
|
||||||
{
|
{
|
||||||
HWWall * w1 = walls[a.index];
|
HWWall* w1 = walls[item.index];
|
||||||
HWWall * w2 = walls[b.index];
|
if (w1->glseg.y1 < viewy) list1.Push(item);
|
||||||
|
else list2.Push(item);
|
||||||
|
}
|
||||||
|
|
||||||
if (w1->texture != w2->texture) return w1->texture < w2->texture;
|
std::sort(list1.begin(), list1.end(), [=](const HWDrawItem& a, const HWDrawItem& b)
|
||||||
return (w1->flags & 3) < (w2->flags & 3);
|
{
|
||||||
|
HWWall* w1 = walls[a.index];
|
||||||
|
HWWall* w2 = walls[b.index];
|
||||||
|
if (w1->glseg.y1 != w2->glseg.y1) return w1->glseg.y1 < w2->glseg.y1;
|
||||||
|
int time1 = w1->sprite ? w1->sprite->time : -1;
|
||||||
|
int time2 = w2->sprite ? w2->sprite->time : -1;
|
||||||
|
return time1 < time2;
|
||||||
|
});
|
||||||
|
|
||||||
});
|
std::sort(list2.begin(), list2.end(), [=](const HWDrawItem& a, const HWDrawItem& b)
|
||||||
|
{
|
||||||
|
HWWall* w1 = walls[a.index];
|
||||||
|
HWWall* w2 = walls[b.index];
|
||||||
|
if (w1->glseg.y1 != w2->glseg.y1) return w1->glseg.y1 > w2->glseg.y1;
|
||||||
|
int time1 = w1->sprite ? w1->sprite->time : -1;
|
||||||
|
int time2 = w2->sprite ? w2->sprite->time : -1;
|
||||||
|
return time1 < time2;
|
||||||
|
});
|
||||||
|
|
||||||
|
drawitems.Clear();
|
||||||
|
drawitems.Append(list1);
|
||||||
|
drawitems.Append(list2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void HWDrawList::SortWallsHorz(HWDrawInfo* di)
|
||||||
|
{
|
||||||
|
auto viewx = di->Viewpoint.Pos.X;
|
||||||
|
if (drawitems.Size() > 1)
|
||||||
|
{
|
||||||
|
TArray<HWDrawItem> list1(drawitems.Size(), false);
|
||||||
|
TArray<HWDrawItem> list2(drawitems.Size(), false);
|
||||||
|
|
||||||
|
for (auto& item : drawitems)
|
||||||
|
{
|
||||||
|
HWWall* w1 = walls[item.index];
|
||||||
|
if (w1->glseg.x1 < viewx) list1.Push(item);
|
||||||
|
else list2.Push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(list1.begin(), list1.end(), [=](const HWDrawItem& a, const HWDrawItem& b)
|
||||||
|
{
|
||||||
|
HWWall* w1 = walls[a.index];
|
||||||
|
HWWall* w2 = walls[b.index];
|
||||||
|
if (w1->glseg.x1 != w2->glseg.x1) return w1->glseg.x1 < w2->glseg.x1;
|
||||||
|
int time1 = w1->sprite ? w1->sprite->time : -1;
|
||||||
|
int time2 = w2->sprite ? w2->sprite->time : -1;
|
||||||
|
return time1 < time2;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::sort(list2.begin(), list2.end(), [=](const HWDrawItem& a, const HWDrawItem& b)
|
||||||
|
{
|
||||||
|
HWWall* w1 = walls[a.index];
|
||||||
|
HWWall* w2 = walls[b.index];
|
||||||
|
if (w1->glseg.x1 != w2->glseg.x1) return w1->glseg.x1 > w2->glseg.x1;
|
||||||
|
int time1 = w1->sprite ? w1->sprite->time : -1;
|
||||||
|
int time2 = w2->sprite ? w2->sprite->time : -1;
|
||||||
|
return time1 < time2;
|
||||||
|
});
|
||||||
|
|
||||||
|
drawitems.Clear();
|
||||||
|
drawitems.Append(list1);
|
||||||
|
drawitems.Append(list2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void HWDrawList::SortFlats(HWDrawInfo* di)
|
void HWDrawList::SortFlats(HWDrawInfo* di)
|
||||||
{
|
{
|
||||||
auto viewz = di->Viewpoint.Pos.Z;
|
auto viewz = di->Viewpoint.Pos.Z;
|
||||||
|
|
|
@ -92,7 +92,8 @@ public:
|
||||||
HWFlat *NewFlat();
|
HWFlat *NewFlat();
|
||||||
HWSprite *NewSprite();
|
HWSprite *NewSprite();
|
||||||
void Reset();
|
void Reset();
|
||||||
void SortWalls();
|
void SortWallsHorz(HWDrawInfo* di);
|
||||||
|
void SortWallsVert(HWDrawInfo* di);
|
||||||
void SortFlats(HWDrawInfo* di);
|
void SortFlats(HWDrawInfo* di);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,14 +50,11 @@ void HWDrawInfo::AddWall(HWWall *wall)
|
||||||
bool masked = wall->type != RENDERWALL_M2S ? false : (wall->texture && wall->texture->isMasked());
|
bool masked = wall->type != RENDERWALL_M2S ? false : (wall->texture && wall->texture->isMasked());
|
||||||
int list;
|
int list;
|
||||||
|
|
||||||
if (wall->flags & HWWall::HWF_SKYHACK && wall->type == RENDERWALL_M2S)
|
if (!masked) list = GLDL_PLAINWALLS;
|
||||||
{
|
else if (sprite == nullptr) list = GLDL_MASKEDWALLS;
|
||||||
list = GLDL_MASKEDWALLSOFS;
|
else if (wall->glseg.x1 == wall->glseg.x2) list = GLDL_MASKEDWALLSV;
|
||||||
}
|
else if (wall->glseg.y1 == wall->glseg.y2) list = GLDL_MASKEDWALLSH;
|
||||||
else
|
else list = GLDL_MASKEDWALLSS;
|
||||||
{
|
|
||||||
list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS;
|
|
||||||
}
|
|
||||||
auto newwall = drawlists[list].NewWall();
|
auto newwall = drawlists[list].NewWall();
|
||||||
*newwall = *wall;
|
*newwall = *wall;
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Process(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector);
|
void Process(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector);
|
||||||
void ProcessWallSprite(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector);
|
void ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* frontsector);
|
||||||
|
|
||||||
float PointOnSide(float x,float y)
|
float PointOnSide(float x,float y)
|
||||||
{
|
{
|
||||||
|
|
|
@ -149,161 +149,6 @@ void polymost_drawsprite(int32_t snum)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // Wall sprite
|
|
||||||
{
|
|
||||||
// Project 3D to 2D
|
|
||||||
if (globalorientation & 4)
|
|
||||||
off.x = -off.x;
|
|
||||||
|
|
||||||
if (globalorientation & 8)
|
|
||||||
off.y = -off.y;
|
|
||||||
|
|
||||||
vec2f_t const extent = { float(tspr->xrepeat * bsinf(tspr->ang, -16)),
|
|
||||||
float(tspr->xrepeat * -bcosf(tspr->ang, -16)) };
|
|
||||||
|
|
||||||
float f = (float)(tsiz.x >> 1) + (float)off.x;
|
|
||||||
|
|
||||||
vec2f_t const vf = { extent.x * f, extent.y * f };
|
|
||||||
|
|
||||||
vec2f_t vec0 = { (float)(pos.x - globalposx) - vf.x,
|
|
||||||
(float)(pos.y - globalposy) - vf.y };
|
|
||||||
|
|
||||||
int32_t const s = tspr->owner;
|
|
||||||
int32_t walldist = 1;
|
|
||||||
int32_t w = (s == -1) ? -1 : wsprinfo[s].wall;
|
|
||||||
|
|
||||||
vec2f_t p0 = { vec0.y * gcosang - vec0.x * gsinang,
|
|
||||||
vec0.x * gcosang2 + vec0.y * gsinang2 };
|
|
||||||
|
|
||||||
vec2f_t const pp = { extent.x * ftsiz.x + vec0.x,
|
|
||||||
extent.y * ftsiz.x + vec0.y };
|
|
||||||
|
|
||||||
vec2f_t p1 = { pp.y * gcosang - pp.x * gsinang,
|
|
||||||
pp.x * gcosang2 + pp.y * gsinang2 };
|
|
||||||
|
|
||||||
if ((p0.y <= SCISDIST) && (p1.y <= SCISDIST))
|
|
||||||
goto _drawsprite_return;
|
|
||||||
|
|
||||||
// Clip to close parallel-screen plane
|
|
||||||
vec2f_t const op0 = p0;
|
|
||||||
|
|
||||||
float t0 = 0.f, t1 = 1.f;
|
|
||||||
|
|
||||||
if (p0.y < SCISDIST)
|
|
||||||
{
|
|
||||||
t0 = (SCISDIST - p0.y) / (p1.y - p0.y);
|
|
||||||
p0 = { (p1.x - p0.x) * t0 + p0.x, SCISDIST };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p1.y < SCISDIST)
|
|
||||||
{
|
|
||||||
t1 = (SCISDIST - op0.y) / (p1.y - op0.y);
|
|
||||||
p1 = { (p1.x - op0.x) * t1 + op0.x, SCISDIST };
|
|
||||||
}
|
|
||||||
|
|
||||||
f = 1.f / p0.y;
|
|
||||||
const float ryp0 = f * gyxscale;
|
|
||||||
float sx0 = ghalfx * p0.x * f + ghalfx;
|
|
||||||
|
|
||||||
f = 1.f / p1.y;
|
|
||||||
const float ryp1 = f * gyxscale;
|
|
||||||
float sx1 = ghalfx * p1.x * f + ghalfx;
|
|
||||||
|
|
||||||
pos.z -= ((off.y * tspr->yrepeat) << 2);
|
|
||||||
|
|
||||||
if (globalorientation & 128)
|
|
||||||
{
|
|
||||||
pos.z += ((tsiz.y * tspr->yrepeat) << 1);
|
|
||||||
|
|
||||||
if (tsiz.y & 1)
|
|
||||||
pos.z += (tspr->yrepeat << 1); // Odd yspans
|
|
||||||
}
|
|
||||||
|
|
||||||
xtex.d = (ryp0 - ryp1) * gxyaspect / (sx0 - sx1);
|
|
||||||
ytex.d = 0;
|
|
||||||
otex.d = ryp0 * gxyaspect - xtex.d * sx0;
|
|
||||||
|
|
||||||
if (globalorientation & 4)
|
|
||||||
{
|
|
||||||
t0 = 1.f - t0;
|
|
||||||
t1 = 1.f - t1;
|
|
||||||
}
|
|
||||||
|
|
||||||
xtex.u = (t0 * ryp0 - t1 * ryp1) * gxyaspect * ftsiz.x / (sx0 - sx1);
|
|
||||||
ytex.u = 0;
|
|
||||||
otex.u = t0 * ryp0 * gxyaspect * ftsiz.x - xtex.u * sx0;
|
|
||||||
|
|
||||||
f = ((float) tspr->yrepeat) * ftsiz.y * 4;
|
|
||||||
|
|
||||||
float sc0 = ((float) (pos.z - globalposz - f)) * ryp0 + ghoriz;
|
|
||||||
float sc1 = ((float) (pos.z - globalposz - f)) * ryp1 + ghoriz;
|
|
||||||
float sf0 = ((float) (pos.z - globalposz)) * ryp0 + ghoriz;
|
|
||||||
float sf1 = ((float) (pos.z - globalposz)) * ryp1 + ghoriz;
|
|
||||||
|
|
||||||
// gvx*sx0 + gvy*sc0 + gvo = 0
|
|
||||||
// gvx*sx1 + gvy*sc1 + gvo = 0
|
|
||||||
// gvx*sx0 + gvy*sf0 + gvo = tsizy*(gdx*sx0 + gdo)
|
|
||||||
f = ftsiz.y * (xtex.d * sx0 + otex.d) / ((sx0 - sx1) * (sc0 - sf0));
|
|
||||||
|
|
||||||
if (!(globalorientation & 8))
|
|
||||||
{
|
|
||||||
xtex.v = (sc0 - sc1) * f;
|
|
||||||
ytex.v = (sx1 - sx0) * f;
|
|
||||||
otex.v = -xtex.v * sx0 - ytex.v * sc0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xtex.v = (sf1 - sf0) * f;
|
|
||||||
ytex.v = (sx0 - sx1) * f;
|
|
||||||
otex.v = -xtex.v * sx0 - ytex.v * sf0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clip sprites to ceilings/floors when no parallaxing
|
|
||||||
if (!(sector[tspr->sectnum].ceilingstat & 1))
|
|
||||||
{
|
|
||||||
if (sector[tspr->sectnum].ceilingz > pos.z - (float)((tspr->yrepeat * tsiz.y) << 2))
|
|
||||||
{
|
|
||||||
sc0 = (float)(sector[tspr->sectnum].ceilingz - globalposz) * ryp0 + ghoriz;
|
|
||||||
sc1 = (float)(sector[tspr->sectnum].ceilingz - globalposz) * ryp1 + ghoriz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!(sector[tspr->sectnum].floorstat & 1))
|
|
||||||
{
|
|
||||||
if (sector[tspr->sectnum].floorz < pos.z)
|
|
||||||
{
|
|
||||||
sf0 = (float)(sector[tspr->sectnum].floorz - globalposz) * ryp0 + ghoriz;
|
|
||||||
sf1 = (float)(sector[tspr->sectnum].floorz - globalposz) * ryp1 + ghoriz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sx0 > sx1)
|
|
||||||
{
|
|
||||||
if (globalorientation & 64)
|
|
||||||
goto _drawsprite_return; // 1-sided sprite
|
|
||||||
|
|
||||||
std::swap(sx0, sx1);
|
|
||||||
std::swap(sc0, sc1);
|
|
||||||
std::swap(sf0, sf1);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2f_t const pxy[4] = { { sx0, sc0 }, { sx1, sc1 }, { sx1, sf1 }, { sx0, sf0 } };
|
|
||||||
|
|
||||||
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
|
|
||||||
pow2xsplit = 0;
|
|
||||||
polymost_drawpoly(pxy, 4, method, tempsiz);
|
|
||||||
|
|
||||||
drawpoly_srepeat = 0;
|
|
||||||
drawpoly_trepeat = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // Floor sprite
|
|
||||||
else
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: // Voxel sprite
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (automapping == 1 && (unsigned)spritenum < MAXSPRITES)
|
if (automapping == 1 && (unsigned)spritenum < MAXSPRITES)
|
||||||
|
|
|
@ -1067,3 +1067,110 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
||||||
globalr = globalg = globalb = 255;
|
globalr = globalg = globalb = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HWWall::ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* sector)
|
||||||
|
{
|
||||||
|
auto tex = tileGetTexture(spr->picnum);
|
||||||
|
if (!tex || !tex->isValid()) return;
|
||||||
|
|
||||||
|
seg = nullptr;
|
||||||
|
sprite = spr;
|
||||||
|
vec2_t pos[2];
|
||||||
|
int sprz = spr->pos.z;
|
||||||
|
|
||||||
|
if (spr->cstat & CSTAT_SPRITE_ONE_SIDED)
|
||||||
|
{
|
||||||
|
DAngle sprang = buildang(spr->ang).asdeg();
|
||||||
|
DAngle lookang = bamang(di->Viewpoint.RotAngle).asdeg();
|
||||||
|
if ((sprang.ToVector() | lookang.ToVector()) >= 0.) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertindex = 0;
|
||||||
|
vertcount = 0;
|
||||||
|
type = RENDERWALL_M2S;
|
||||||
|
frontsector = sector;
|
||||||
|
backsector = sector;
|
||||||
|
texture = tex;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
dynlightindex = -1;
|
||||||
|
shade = spr->shade;
|
||||||
|
palette = spr->pal;
|
||||||
|
fade = lookups.getFade(sector->floorpal); // fog is per sector.
|
||||||
|
visibility = sectorVisibility(sector);
|
||||||
|
|
||||||
|
bool trans = (sprite->cstat & CSTAT_SPRITE_TRANSLUCENT);
|
||||||
|
if (trans)
|
||||||
|
{
|
||||||
|
RenderStyle = GetRenderStyle(0, !!(sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT));
|
||||||
|
alpha = GetAlphaFromBlend((sprite->cstat & CSTAT_SPRITE_TRANSLUCENT_INVERT) ? DAMETH_TRANS2 : DAMETH_TRANS1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||||
|
alpha = 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GetWallSpritePosition(spr, spr->pos.vec2, pos, true);
|
||||||
|
|
||||||
|
int height, topofs;
|
||||||
|
if (hw_hightile && TileFiles.tiledata[spr->picnum].h_xsize)
|
||||||
|
{
|
||||||
|
height = TileFiles.tiledata[spr->picnum].h_ysize;
|
||||||
|
topofs = (TileFiles.tiledata[spr->picnum].h_yoffs + spr->yoffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
height = tex->GetTexelHeight();
|
||||||
|
topofs = (tex->GetTexelTopOffset() + spr->yoffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spr->cstat & CSTAT_SPRITE_YFLIP)
|
||||||
|
topofs = -topofs;
|
||||||
|
|
||||||
|
sprz -= ((topofs * spr->yrepeat) << 2);
|
||||||
|
|
||||||
|
if (spr->cstat & CSTAT_SPRITE_YCENTER)
|
||||||
|
{
|
||||||
|
sprz += ((height * spr->yrepeat) << 1);
|
||||||
|
if (height & 1) sprz += (spr->yrepeat << 1); // Odd yspans (taken from polymost as-is)
|
||||||
|
}
|
||||||
|
|
||||||
|
glseg.fracleft = 0;
|
||||||
|
glseg.fracright = 1;
|
||||||
|
glseg.x1 = pos[0].x * (1 / 16.f);
|
||||||
|
glseg.y1 = pos[0].y * (1 / -16.f);
|
||||||
|
glseg.x2 = pos[1].x * (1 / 16.f);
|
||||||
|
glseg.y2 = pos[1].y * (1 / -16.f);
|
||||||
|
tcs[LOLFT].u = tcs[UPLFT].u = (spr->cstat & CSTAT_SPRITE_XFLIP) ? 1.f : 0.f;
|
||||||
|
tcs[LORGT].u = tcs[UPRGT].u = (spr->cstat & CSTAT_SPRITE_XFLIP) ? 0.f : 1.f;
|
||||||
|
tcs[UPLFT].v = tcs[UPRGT].u = (spr->cstat & CSTAT_SPRITE_YFLIP) ? 0.f : 1.f;
|
||||||
|
tcs[LOLFT].v = tcs[LORGT].u = (spr->cstat & CSTAT_SPRITE_YFLIP) ? 0.f : 1.f;
|
||||||
|
ztop[0] = ztop[1] = (sprz - height) * (1 / -256.);
|
||||||
|
zbottom[0] = zbottom[1] = (sprz) * (1 / -256.);
|
||||||
|
|
||||||
|
|
||||||
|
// Clip sprites to ceilings/floors
|
||||||
|
float origz = ztop[0];
|
||||||
|
float polyh = (zbottom[0] - origz);
|
||||||
|
if (!(sector->ceilingstat & CSTAT_SECTOR_SKY))
|
||||||
|
{
|
||||||
|
float ceilingz = sector->ceilingz * (1 / 256.f);
|
||||||
|
if (ceilingz < ztop[0] && ceilingz > zbottom[0])
|
||||||
|
{
|
||||||
|
float newv = (ceilingz - origz) / polyh;
|
||||||
|
tcs[UPLFT].v = tcs[UPRGT].v = newv;
|
||||||
|
ztop[0] = ztop[1] = ceilingz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(sector->floorstat & CSTAT_SECTOR_SKY))
|
||||||
|
{
|
||||||
|
float floorz = sector->floorz * (1 / 256.f);
|
||||||
|
if (floorz < ztop[0] && floorz > zbottom[0])
|
||||||
|
{
|
||||||
|
float newv = (floorz - origz) / polyh;
|
||||||
|
tcs[LOLFT].v = tcs[LORGT].v = newv;
|
||||||
|
zbottom[0] = zbottom[1] = floorz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue