- allocate the sprite positioning info on demand only.

For most textures this is never needed and it can easily be put in the memory arena being used for image sources.
This commit is contained in:
Christoph Oelckers 2020-04-16 18:46:31 +02:00
parent c5e81c54a2
commit 095a5e2c0a
5 changed files with 71 additions and 70 deletions

View file

@ -41,7 +41,7 @@
#include "cmdlib.h" #include "cmdlib.h"
#include "palettecontainer.h" #include "palettecontainer.h"
FMemArena FImageSource::ImageArena(32768); FMemArena ImageArena(32768);
TArray<FImageSource *>FImageSource::ImageForLump; TArray<FImageSource *>FImageSource::ImageForLump;
int FImageSource::NextID; int FImageSource::NextID;
static PrecacheInfo precacheInfo; static PrecacheInfo precacheInfo;

View file

@ -7,6 +7,7 @@
class FImageSource; class FImageSource;
using PrecacheInfo = TMap<int, std::pair<int, int>>; using PrecacheInfo = TMap<int, std::pair<int, int>>;
extern FMemArena ImageArena;
// Doom patch format header // Doom patch format header
struct patch_t struct patch_t
@ -38,7 +39,6 @@ class FImageSource
friend class FBrightmapTexture; friend class FBrightmapTexture;
protected: protected:
static FMemArena ImageArena;
static TArray<FImageSource *>ImageForLump; static TArray<FImageSource *>ImageForLump;
static int NextID; static int NextID;

View file

@ -737,29 +737,6 @@ TArray<uint8_t> FTexture::Get8BitPixels(bool alphatex)
return Pixels; return Pixels;
} }
//===========================================================================
//
// Sets up the sprite positioning data for this texture
//
//===========================================================================
void FTexture::SetupSpriteData()
{
spi.mSpriteU[0] = spi.mSpriteV[0] = 0.f;
spi.mSpriteU[1] = spi.mSpriteV[1] = 1.f;
spi.spriteWidth = GetTexelWidth();
spi.spriteHeight = GetTexelHeight();
if (ShouldExpandSprite())
{
if (mTrimResult == -1) mTrimResult = !!TrimBorders(spi.trim); // get the trim size before adding the empty frame
spi.spriteWidth += 2;
spi.spriteHeight += 2;
}
else mTrimResult = 0;
SetSpriteRect();
}
//=========================================================================== //===========================================================================
// //
// Checks if a sprite may be expanded with an empty frame // Checks if a sprite may be expanded with an empty frame
@ -875,54 +852,90 @@ outl:
} }
//=========================================================================== //===========================================================================
//
// Sets up the sprite positioning data for this texture
// //
// Set the sprite rectangle //===========================================================================
void FTexture::SetupSpriteData()
{
// Since this is only needed for real sprites it gets allocated on demand.
// It also allocates from the image memory arena because it has the same lifetime and to reduce maintenance.
if (spi == nullptr) spi = (SpritePositioningInfo*)ImageArena.Alloc(2 * sizeof(SpritePositioningInfo));
for (int i = 0; i < 2; i++)
{
auto& spi = this->spi[i];
spi.mSpriteU[0] = spi.mSpriteV[0] = 0.f;
spi.mSpriteU[1] = spi.mSpriteV[1] = 1.f;
spi.spriteWidth = GetTexelWidth();
spi.spriteHeight = GetTexelHeight();
if (i == 1 && ShouldExpandSprite())
{
spi.mTrimResult = TrimBorders(spi.trim); // get the trim size before adding the empty frame
spi.spriteWidth += 2;
spi.spriteHeight += 2;
}
}
SetSpriteRect();
}
//===========================================================================
//
// Set the sprite rectangle. This is separate because it may be called by a CVAR, too.
// //
//=========================================================================== //===========================================================================
void FTexture::SetSpriteRect() void FTexture::SetSpriteRect()
{ {
if (!spi) return;
auto leftOffset = GetLeftOffsetHW(); auto leftOffset = GetLeftOffsetHW();
auto topOffset = GetTopOffsetHW(); auto topOffset = GetTopOffsetHW();
float fxScale = (float)Scale.X; float fxScale = (float)Scale.X;
float fyScale = (float)Scale.Y; float fyScale = (float)Scale.Y;
// mSpriteRect is for positioning the sprite in the scene. for (int i = 0; i < 2; i++)
spi.mSpriteRect.left = -leftOffset / fxScale;
spi.mSpriteRect.top = -topOffset / fyScale;
spi.mSpriteRect.width = spi.spriteWidth / fxScale;
spi.mSpriteRect.height = spi.spriteHeight / fyScale;
if (bExpandSprite)
{ {
// a little adjustment to make sprites look better with texture filtering: auto& spi = this->spi[i];
// create a 1 pixel wide empty frame around them.
int oldwidth = spi.spriteWidth - 2; // mSpriteRect is for positioning the sprite in the scene.
int oldheight = spi.spriteHeight - 2; spi.mSpriteRect.left = -leftOffset / fxScale;
spi.mSpriteRect.top = -topOffset / fyScale;
spi.mSpriteRect.width = spi.spriteWidth / fxScale;
spi.mSpriteRect.height = spi.spriteHeight / fyScale;
leftOffset += 1; if (i == 1 && ShouldExpandSprite())
topOffset += 1;
// Reposition the sprite with the frame considered
spi.mSpriteRect.left = -(float)leftOffset / fxScale;
spi.mSpriteRect.top = -(float)topOffset / fyScale;
spi.mSpriteRect.width = (float)spi.spriteWidth / fxScale;
spi.mSpriteRect.height = (float)spi.spriteHeight / fyScale;
if (mTrimResult > 0)
{ {
spi.mSpriteRect.left += (float)spi.trim[0] / fxScale; // a little adjustment to make sprites look better with texture filtering:
spi.mSpriteRect.top += (float)spi.trim[1] / fyScale; // create a 1 pixel wide empty frame around them.
spi.mSpriteRect.width -= float(oldwidth - spi.trim[2]) / fxScale; int oldwidth = spi.spriteWidth - 2;
spi.mSpriteRect.height -= float(oldheight - spi.trim[3]) / fyScale; int oldheight = spi.spriteHeight - 2;
spi.mSpriteU[0] = (float)spi.trim[0] / (float)spi.spriteWidth; leftOffset += 1;
spi.mSpriteV[0] = (float)spi.trim[1] / (float)spi.spriteHeight; topOffset += 1;
spi.mSpriteU[1] -= float(oldwidth - spi.trim[0] - spi.trim[2]) / (float)spi.spriteWidth;
spi.mSpriteV[1] -= float(oldheight - spi.trim[1] - spi.trim[3]) / (float)spi.spriteHeight; // Reposition the sprite with the frame considered
spi.mSpriteRect.left = -(float)leftOffset / fxScale;
spi.mSpriteRect.top = -(float)topOffset / fyScale;
spi.mSpriteRect.width = (float)spi.spriteWidth / fxScale;
spi.mSpriteRect.height = (float)spi.spriteHeight / fyScale;
if (spi.mTrimResult > 0)
{
spi.mSpriteRect.left += (float)spi.trim[0] / fxScale;
spi.mSpriteRect.top += (float)spi.trim[1] / fyScale;
spi.mSpriteRect.width -= float(oldwidth - spi.trim[2]) / fxScale;
spi.mSpriteRect.height -= float(oldheight - spi.trim[3]) / fyScale;
spi.mSpriteU[0] = (float)spi.trim[0] / (float)spi.spriteWidth;
spi.mSpriteV[0] = (float)spi.trim[1] / (float)spi.spriteHeight;
spi.mSpriteU[1] -= float(oldwidth - spi.trim[0] - spi.trim[2]) / (float)spi.spriteWidth;
spi.mSpriteV[1] -= float(oldheight - spi.trim[1] - spi.trim[3]) / (float)spi.spriteHeight;
}
} }
} }
} }

View file

@ -1488,9 +1488,3 @@ FTextureID FTextureID::operator +(int offset) throw()
if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1); if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1);
return FTextureID(texnum + offset); return FTextureID(texnum + offset);
} }
CCMD(texinfo)
{
Printf("Sizeof texture = %d\n", sizeof(FTexture));
}

View file

@ -229,6 +229,7 @@ struct SpritePositioningInfo
int spriteWidth, spriteHeight; int spriteWidth, spriteHeight;
float mSpriteU[2], mSpriteV[2]; float mSpriteU[2], mSpriteV[2];
FloatRect mSpriteRect; FloatRect mSpriteRect;
uint8_t mTrimResult;
float GetSpriteUL() const { return mSpriteU[0]; } float GetSpriteUL() const { return mSpriteU[0]; }
float GetSpriteVT() const { return mSpriteV[0]; } float GetSpriteVT() const { return mSpriteV[0]; }
@ -255,8 +256,7 @@ class FTexture
public: public:
SpritePositioningInfo spi; SpritePositioningInfo *spi = nullptr;
int8_t mTrimResult = -1;
IHardwareTexture* GetHardwareTexture(int translation, bool expanded); IHardwareTexture* GetHardwareTexture(int translation, bool expanded);
static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype);
@ -375,12 +375,6 @@ public:
protected: protected:
ISoftwareTexture *SoftwareTexture = nullptr; ISoftwareTexture *SoftwareTexture = nullptr;
// None of the following pointers are owned by this texture, they are all controlled by the texture manager.
// Offset-less version for COMPATF_MASKEDMIDTEX
FGameTexture *OffsetLess = nullptr;
// Front sky layer variant where color 0 is transparent
FGameTexture* FrontSkyLayer = nullptr;
public: public:
// Material layers // Material layers
FTexture *Brightmap = nullptr; FTexture *Brightmap = nullptr;
@ -736,7 +730,7 @@ public:
void SetDisplaySize(float w, float h) { wrapped.SetSize((int)w, (int)h); } void SetDisplaySize(float w, float h) { wrapped.SetSize((int)w, (int)h); }
void SetSpriteRect() { wrapped.SetSpriteRect(); } void SetSpriteRect() { wrapped.SetSpriteRect(); }
const SpritePositioningInfo& GetSpritePositioning(int which) { /* todo: keep two sets of positioning infd*/ if (wrapped.mTrimResult == -1) wrapped.SetupSpriteData(); return wrapped.spi; } const SpritePositioningInfo& GetSpritePositioning(int which) { if (wrapped.spi == nullptr) wrapped.SetupSpriteData(); return wrapped.spi[which]; }
int GetAreas(FloatRect** pAreas) const { return wrapped.GetAreas(pAreas); } int GetAreas(FloatRect** pAreas) const { return wrapped.GetAreas(pAreas); }
PalEntry GetSkyCapColor(bool bottom) { return wrapped.GetSkyCapColor(bottom); } PalEntry GetSkyCapColor(bool bottom) { return wrapped.GetSkyCapColor(bottom); }