mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 00:41:55 +00:00
- do the handling of 90° rotated wall textures in the renderer instead of duplicating the texture.
Aside from less resource use this also works with hires replacement - which the old code was incapable of.
This commit is contained in:
parent
6a690849e6
commit
faeb19a485
6 changed files with 24 additions and 113 deletions
|
@ -344,36 +344,6 @@ EClose IsCloseToWall(const DVector2& point, walltype* wal, double maxdist)
|
|||
return IsCloseToLine(point, wal->pos, wal->point2Wall()->pos, maxdist);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Check if some walls are set to use rotated textures.
|
||||
// Ideally this should just have been done with texture rotation,
|
||||
// but the effects on the render code would be too severe due to the alignment mess.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void checkRotatedWalls()
|
||||
{
|
||||
for (auto& w : wall)
|
||||
{
|
||||
if (w.cstat & CSTAT_WALL_ROTATE_90)
|
||||
{
|
||||
int picnum = w.picnum;
|
||||
tileUpdatePicnum(&picnum);
|
||||
auto& tile = RotTile(picnum);
|
||||
|
||||
if (tile.newtile == -1 && tile.owner == -1)
|
||||
{
|
||||
tile.newtile = TileFiles.tileCreateRotated(picnum);
|
||||
assert(tile.newtile != -1);
|
||||
|
||||
RotTile(tile.newtile).owner = picnum;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// check if two sectors share a wall connection
|
||||
|
|
|
@ -298,7 +298,6 @@ enum class EClose
|
|||
EClose IsCloseToLine(const DVector2& vect, const DVector2& start, const DVector2& end, double walldist);
|
||||
EClose IsCloseToWall(const DVector2& vect, walltype* wal, double walldist);
|
||||
|
||||
void checkRotatedWalls();
|
||||
bool sectorsConnected(int sect1, int sect2);
|
||||
int32_t inside(double x, double y, const sectortype* sect);
|
||||
int insidePoly(double x, double y, const DVector2* points, int count);
|
||||
|
|
|
@ -307,8 +307,6 @@ void animatecamsprite(double s);
|
|||
|
||||
void render_drawrooms(DCoreActor* playersprite, const DVector3& position, sectortype* sect, const DRotator& angles, double interpfrac, float fov)
|
||||
{
|
||||
checkRotatedWalls();
|
||||
|
||||
updatesector(position.XY(), §);
|
||||
if (sect == nullptr) return;
|
||||
|
||||
|
|
|
@ -197,13 +197,16 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
|||
state.EnableTexture(false);
|
||||
}
|
||||
|
||||
int h = (int)texture->GetDisplayHeight();
|
||||
int h2 = 1 << sizeToBits(h);
|
||||
if (h2 < h) h2 *= 2;
|
||||
if (h != h2)
|
||||
if (!(seg->cstat & CSTAT_WALL_ROTATE_90))
|
||||
{
|
||||
float xOffset = 1.f / texture->GetDisplayWidth();
|
||||
state.SetNpotEmulation(float(h2) / h, xOffset);
|
||||
int h = (int)texture->GetDisplayHeight();
|
||||
int h2 = 1 << sizeToBits(h);
|
||||
if (h2 < h) h2 *= 2;
|
||||
if (h != h2)
|
||||
{
|
||||
float xOffset = 1.f / texture->GetDisplayWidth();
|
||||
state.SetNpotEmulation(float(h2) / h, xOffset);
|
||||
}
|
||||
}
|
||||
RenderWall(di, state, rflags);
|
||||
}
|
||||
|
@ -412,6 +415,15 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent)
|
|||
ViewDistance = (di->Viewpoint.Pos.XY() - DVector2((glseg.x1 + glseg.x2) * 0.5f, (glseg.y1 + glseg.y2) * 0.5f)).LengthSquared();
|
||||
}
|
||||
|
||||
if (seg && (seg->cstat & CSTAT_WALL_ROTATE_90))
|
||||
{
|
||||
float f;
|
||||
// rotate 90° clockwise. The coordinates have already been set up in rotated space, so all we need to do here is swap u and v and then negate the new v.
|
||||
f = tcs[UPLFT].u; tcs[UPLFT].u = tcs[UPLFT].v; tcs[UPLFT].v = 1.f - f;
|
||||
f = tcs[LOLFT].u; tcs[LOLFT].u = tcs[LOLFT].v; tcs[LOLFT].v = 1.f - f;
|
||||
f = tcs[UPRGT].u; tcs[UPRGT].u = tcs[UPRGT].v; tcs[UPRGT].v = 1.f - f;
|
||||
f = tcs[LORGT].u; tcs[LORGT].u = tcs[LORGT].v; tcs[LORGT].v = 1.f - f;
|
||||
}
|
||||
if (texture->isHardwareCanvas())
|
||||
{
|
||||
tcs[UPLFT].v = 1.f - tcs[UPLFT].v;
|
||||
|
@ -743,6 +755,7 @@ void HWWall::DoTexture(HWDrawInfo* di, walltype* wal, walltype* refwall, float r
|
|||
|
||||
float tw = texture->GetDisplayWidth();
|
||||
float th = texture->GetDisplayHeight();
|
||||
if (wal->cstat & CSTAT_WALL_ROTATE_90) std::swap(tw, th);
|
||||
int pow2size = 1 << sizeToBits(th);
|
||||
if (pow2size < th) pow2size *= 2;
|
||||
float ypanning = refwall->ypan_ ? pow2size * refwall->ypan_ / (256.0f * th) : 0;
|
||||
|
@ -999,7 +1012,7 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
|||
|
||||
int tilenum = ((wal->cstat & CSTAT_WALL_1WAY) && wal->nextwall != -1) ? wal->overpicnum : wal->picnum;
|
||||
gotpic.Set(tilenum);
|
||||
tileUpdatePicnum(&tilenum, (wal->cstat & CSTAT_WALL_ROTATE_90));
|
||||
tileUpdatePicnum(&tilenum);
|
||||
texture = tileGetTexture(tilenum);
|
||||
if (texture && texture->isValid())
|
||||
{
|
||||
|
@ -1037,7 +1050,7 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
|||
{
|
||||
int tilenum = wal->picnum;
|
||||
gotpic.Set(tilenum);
|
||||
tileUpdatePicnum(&tilenum, (wal->cstat & CSTAT_WALL_ROTATE_90));
|
||||
tileUpdatePicnum(&tilenum);
|
||||
texture = tileGetTexture(tilenum);
|
||||
if (texture && texture->isValid())
|
||||
{
|
||||
|
@ -1050,7 +1063,7 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
|||
{
|
||||
int tilenum = wal->overpicnum;
|
||||
gotpic.Set(tilenum);
|
||||
tileUpdatePicnum(&tilenum, (wal->cstat & CSTAT_WALL_ROTATE_90));
|
||||
tileUpdatePicnum(&tilenum);
|
||||
texture = tileGetTexture(tilenum);
|
||||
if (texture && texture->isValid())
|
||||
{
|
||||
|
@ -1076,7 +1089,7 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
|
|||
auto w = (wal->cstat & CSTAT_WALL_BOTTOM_SWAP) ? backwall : wal;
|
||||
int tilenum = w->picnum;
|
||||
gotpic.Set(tilenum);
|
||||
tileUpdatePicnum(&tilenum, (w->cstat & CSTAT_WALL_ROTATE_90));
|
||||
tileUpdatePicnum(&tilenum);
|
||||
texture = tileGetTexture(tilenum);
|
||||
if (texture && texture->isValid())
|
||||
{
|
||||
|
|
|
@ -143,7 +143,6 @@ void BuildTiles::Init()
|
|||
{
|
||||
tile.texture = Placeholder;
|
||||
tile.picanm = {};
|
||||
tile.RotTile = { -1,-1 };
|
||||
tile.replacement = ReplacementType::Art;
|
||||
tile.alphaThreshold = 0.5;
|
||||
tile.hiofs = {};
|
||||
|
@ -604,7 +603,7 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
|
|||
pixel = remap[pixel];
|
||||
}
|
||||
}
|
||||
tex = MakeGameTexture(new FImageTexture(new FLooseTile(buffer, tex->GetTexelWidth(), tex->GetTexelHeight())), "", ETextureType::Any);
|
||||
tex = MakeGameTexture(new FImageTexture(new FLooseTile(buffer, tex->GetTexelWidth(), tex->GetTexelHeight())), FStringf("#%05d", tile), ETextureType::Any);
|
||||
picanm = &TileFiles.tiledata[tile].picanm;
|
||||
TileFiles.AddTile(tile, tex);
|
||||
}
|
||||
|
@ -655,61 +654,6 @@ void tileSetDummy(int tile, int width, int height)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int BuildTiles::findUnusedTile(void)
|
||||
{
|
||||
static int lastUnusedTile = MAXUSERTILES - 1;
|
||||
|
||||
for (; lastUnusedTile >= 0; --lastUnusedTile)
|
||||
{
|
||||
auto tex = tileGetTexture(lastUnusedTile);
|
||||
if (!tex || !tex->isValid()) return lastUnusedTile;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// fixme: This *really* needs to be done by rotating the texture coordinates,
|
||||
// not by creating an entirely new texture.
|
||||
// Unfortunately it's in all the wrong place in the rendering code so it
|
||||
// has to wait for later.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int BuildTiles::tileCreateRotated(int tileNum)
|
||||
{
|
||||
if ((unsigned)tileNum >= MAXTILES) return tileNum;
|
||||
auto tex = tileGetTexture(tileNum);
|
||||
if (!tex || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return tileNum;
|
||||
TArray<uint8_t> buffer = tex->GetTexture()->Get8BitPixels(false);
|
||||
TArray<uint8_t> dbuffer(tex->GetTexelWidth() * tex->GetTexelHeight(), true);
|
||||
|
||||
auto src = buffer.Data();
|
||||
auto dst = dbuffer.Data();
|
||||
|
||||
auto width = tex->GetTexelWidth();
|
||||
auto height = tex->GetTexelHeight();
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
int xofs = width - x - 1;
|
||||
int yofs = height * x;
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
*(dst + y * width + xofs) = *(src + y + yofs);
|
||||
}
|
||||
|
||||
auto dtex = MakeGameTexture(new FImageTexture(new FLooseTile(dbuffer, tex->GetTexelHeight(), tex->GetTexelWidth())), "", ETextureType::Override);
|
||||
int index = findUnusedTile();
|
||||
TileFiles.AddTile(index, dtex);
|
||||
return index;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void BuildTiles::CloseAll()
|
||||
{
|
||||
ArtFiles.DeleteAndClear();
|
||||
|
|
|
@ -278,7 +278,6 @@ struct TileDesc
|
|||
FGameTexture* texture; // the currently active tile
|
||||
RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time.
|
||||
picanm_t picanm; // animation descriptor
|
||||
rottile_t RotTile;// = { -1,-1 };
|
||||
ReplacementType replacement;
|
||||
float alphaThreshold;
|
||||
int tileflags;
|
||||
|
@ -370,8 +369,6 @@ struct BuildTiles
|
|||
uint8_t* tileMakeWritable(int num);
|
||||
uint8_t* tileCreate(int tilenum, int width, int height);
|
||||
uint8_t* tileGet(int tilenum);
|
||||
int findUnusedTile(void);
|
||||
int tileCreateRotated(int owner);
|
||||
void InvalidateTile(int num);
|
||||
void MakeCanvas(int tilenum, int width, int height);
|
||||
};
|
||||
|
@ -455,13 +452,6 @@ inline int tileTopOffset(int num)
|
|||
return (int)TileFiles.tiledata[num].texture->GetDisplayTopOffset();
|
||||
}
|
||||
|
||||
inline rottile_t& RotTile(int tile)
|
||||
{
|
||||
assert(tile < MAXTILES);
|
||||
return TileFiles.tiledata[tile].RotTile;
|
||||
}
|
||||
|
||||
|
||||
int tileAnimateOfs(int tilenum, int randomize = -1);
|
||||
|
||||
inline void tileUpdatePicnum(int* const tileptr, bool mayrotate = false, int randomize = -1)
|
||||
|
@ -470,9 +460,6 @@ inline void tileUpdatePicnum(int* const tileptr, bool mayrotate = false, int ran
|
|||
|
||||
if (picanm[tile].type())
|
||||
tile += tileAnimateOfs(tile, randomize);
|
||||
|
||||
if (mayrotate && RotTile(tile).newtile != -1)
|
||||
tile = RotTile(tile).newtile;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue