mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-30 07:41:22 +00:00
- 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:
parent
c5e81c54a2
commit
095a5e2c0a
5 changed files with 71 additions and 70 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue