Pass arguments as CImageInfo to graphics functions

Pass `CImageInfo` arguments to various graphics and text render functions instead of passing the components (data pointer, width, height, format/pixel size) of the image info separately.

Pass texture/file name to loading functions when available to improve error/warning messages.
This commit is contained in:
Robert Müller 2024-03-24 13:27:31 +01:00
parent 8218dbb6f8
commit 2b8af7f40f
13 changed files with 134 additions and 126 deletions

View file

@ -301,35 +301,35 @@ int CGraphics_Threaded::UnloadTexture(CTextureHandle *pIndex)
return 0;
}
static bool ConvertToRGBA(uint8_t *pDest, const uint8_t *pSrc, size_t SrcWidth, size_t SrcHeight, CImageInfo::EImageFormat SrcFormat)
static bool ConvertToRGBA(uint8_t *pDest, const CImageInfo &SrcImage)
{
if(SrcFormat == CImageInfo::FORMAT_RGBA)
if(SrcImage.m_Format == CImageInfo::FORMAT_RGBA)
{
mem_copy(pDest, pSrc, SrcWidth * SrcHeight * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA));
mem_copy(pDest, SrcImage.m_pData, SrcImage.DataSize());
return true;
}
else
{
const size_t SrcChannelCount = CImageInfo::PixelSize(SrcFormat);
const size_t SrcChannelCount = CImageInfo::PixelSize(SrcImage.m_Format);
const size_t DstChannelCount = CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
for(size_t Y = 0; Y < SrcHeight; ++Y)
for(size_t Y = 0; Y < (size_t)SrcImage.m_Height; ++Y)
{
for(size_t X = 0; X < SrcWidth; ++X)
for(size_t X = 0; X < (size_t)SrcImage.m_Width; ++X)
{
size_t ImgOffsetSrc = (Y * SrcWidth * SrcChannelCount) + (X * SrcChannelCount);
size_t ImgOffsetDest = (Y * SrcWidth * DstChannelCount) + (X * DstChannelCount);
size_t ImgOffsetSrc = (Y * SrcImage.m_Width * SrcChannelCount) + (X * SrcChannelCount);
size_t ImgOffsetDest = (Y * SrcImage.m_Width * DstChannelCount) + (X * DstChannelCount);
size_t CopySize = SrcChannelCount;
if(SrcFormat == CImageInfo::FORMAT_RGB)
if(SrcImage.m_Format == CImageInfo::FORMAT_RGB)
{
mem_copy(&pDest[ImgOffsetDest], &pSrc[ImgOffsetSrc], CopySize);
mem_copy(&pDest[ImgOffsetDest], &SrcImage.m_pData[ImgOffsetSrc], CopySize);
pDest[ImgOffsetDest + 3] = 255;
}
else if(SrcFormat == CImageInfo::FORMAT_SINGLE_COMPONENT)
else if(SrcImage.m_Format == CImageInfo::FORMAT_SINGLE_COMPONENT)
{
pDest[ImgOffsetDest + 0] = 255;
pDest[ImgOffsetDest + 1] = 255;
pDest[ImgOffsetDest + 2] = 255;
pDest[ImgOffsetDest + 3] = pSrc[ImgOffsetSrc];
pDest[ImgOffsetDest + 3] = SrcImage.m_pData[ImgOffsetSrc];
}
}
}
@ -337,7 +337,7 @@ static bool ConvertToRGBA(uint8_t *pDest, const uint8_t *pSrc, size_t SrcWidth,
}
}
int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureId, int x, int y, size_t Width, size_t Height, CImageInfo::EImageFormat Format, const uint8_t *pData)
int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureId, int x, int y, const CImageInfo &Image)
{
dbg_assert(TextureId.IsValid(), "Invalid texture handle used with LoadTextureRawSub.");
@ -345,42 +345,42 @@ int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureId, int x, int y
Cmd.m_Slot = TextureId.Id();
Cmd.m_X = x;
Cmd.m_Y = y;
Cmd.m_Width = Width;
Cmd.m_Height = Height;
Cmd.m_Width = Image.m_Width;
Cmd.m_Height = Image.m_Height;
Cmd.m_Format = CCommandBuffer::TEXFORMAT_RGBA;
// calculate memory usage
const size_t MemSize = Width * Height * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
// copy texture data
uint8_t *pTmpData = static_cast<uint8_t *>(malloc(MemSize));
ConvertToRGBA(pTmpData, pData, Width, Height, Format);
uint8_t *pTmpData = static_cast<uint8_t *>(malloc((size_t)Image.m_Width * Image.m_Height * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA)));
ConvertToRGBA(pTmpData, Image);
Cmd.m_pData = pTmpData;
AddCmd(Cmd);
return 0;
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTextureImpl(CImageInfo &FromImageInfo, int x, int y, size_t w, size_t h)
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTextureImpl(const CImageInfo &FromImageInfo, int x, int y, size_t w, size_t h, const char *pName)
{
const size_t PixelSize = FromImageInfo.PixelSize();
m_vSpriteHelper.resize(w * h * PixelSize);
CopyTextureFromTextureBufferSub(m_vSpriteHelper.data(), w, h, FromImageInfo.m_pData, FromImageInfo.m_Width, FromImageInfo.m_Height, PixelSize, x, y, w, h);
return LoadTextureRaw(w, h, FromImageInfo.m_Format, m_vSpriteHelper.data(), 0);
m_vSpriteHelper.resize(w * h * FromImageInfo.PixelSize());
CopyTextureFromTextureBufferSub(m_vSpriteHelper.data(), w, h, FromImageInfo, x, y, w, h);
CImageInfo SpriteInfo;
SpriteInfo.m_Width = w;
SpriteInfo.m_Height = h;
SpriteInfo.m_Format = FromImageInfo.m_Format;
SpriteInfo.m_pData = m_vSpriteHelper.data();
return LoadTextureRaw(SpriteInfo, 0, pName);
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTexture(CImageInfo &FromImageInfo, CDataSprite *pSprite)
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTexture(const CImageInfo &FromImageInfo, const CDataSprite *pSprite)
{
int imggx = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int imggy = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * imggx;
int y = pSprite->m_Y * imggy;
int w = pSprite->m_W * imggx;
int h = pSprite->m_H * imggy;
return LoadSpriteTextureImpl(FromImageInfo, x, y, w, h);
int ImageGridX = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int ImageGridY = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * ImageGridX;
int y = pSprite->m_Y * ImageGridY;
int w = pSprite->m_W * ImageGridX;
int h = pSprite->m_H * ImageGridY;
return LoadSpriteTextureImpl(FromImageInfo, x, y, w, h, pSprite->m_pName);
}
bool CGraphics_Threaded::IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h)
bool CGraphics_Threaded::IsImageSubFullyTransparent(const CImageInfo &FromImageInfo, int x, int y, int w, int h)
{
if(FromImageInfo.m_Format == CImageInfo::FORMAT_SINGLE_COMPONENT || FromImageInfo.m_Format == CImageInfo::FORMAT_RGBA)
{
@ -401,15 +401,14 @@ bool CGraphics_Threaded::IsImageSubFullyTransparent(CImageInfo &FromImageInfo, i
return false;
}
bool CGraphics_Threaded::IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, CDataSprite *pSprite)
bool CGraphics_Threaded::IsSpriteTextureFullyTransparent(const CImageInfo &FromImageInfo, const CDataSprite *pSprite)
{
int imggx = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int imggy = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * imggx;
int y = pSprite->m_Y * imggy;
int w = pSprite->m_W * imggx;
int h = pSprite->m_H * imggy;
int ImageGridX = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int ImageGridY = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * ImageGridX;
int y = pSprite->m_Y * ImageGridY;
int w = pSprite->m_W * ImageGridX;
int h = pSprite->m_H * ImageGridY;
return IsImageSubFullyTransparent(FromImageInfo, x, y, w, h);
}
@ -450,20 +449,19 @@ static CCommandBuffer::SCommand_Texture_Create LoadTextureCreateCommand(int Text
return Cmd;
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const uint8_t *pData, int Flags, const char *pTexName)
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(const CImageInfo &Image, int Flags, const char *pTexName)
{
LoadTextureAddWarning(Width, Height, Flags, pTexName, m_vWarnings);
LoadTextureAddWarning(Image.m_Width, Image.m_Height, Flags, pTexName, m_vWarnings);
if(Width == 0 || Height == 0)
if(Image.m_Width == 0 || Image.m_Height == 0)
return IGraphics::CTextureHandle();
IGraphics::CTextureHandle TextureHandle = FindFreeTextureIndex();
CCommandBuffer::SCommand_Texture_Create Cmd = LoadTextureCreateCommand(TextureHandle.Id(), Width, Height, Flags);
CCommandBuffer::SCommand_Texture_Create Cmd = LoadTextureCreateCommand(TextureHandle.Id(), Image.m_Width, Image.m_Height, Flags);
// Copy texture data and convert if necessary
const size_t MemSize = Width * Height * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
uint8_t *pTmpData = static_cast<uint8_t *>(malloc(MemSize));
if(!ConvertToRGBA(pTmpData, pData, Width, Height, Format))
uint8_t *pTmpData = static_cast<uint8_t *>(malloc((size_t)Image.m_Width * Image.m_Height * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA)));
if(!ConvertToRGBA(pTmpData, Image))
{
dbg_msg("graphics", "converted image '%s' to RGBA, consider making its file format RGBA", pTexName ? pTexName : "(no name)");
}
@ -474,24 +472,23 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_
return TextureHandle;
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRawMove(size_t Width, size_t Height, CImageInfo::EImageFormat Format, uint8_t *pData, int Flags, const char *pTexName)
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRawMove(CImageInfo &Image, int Flags, const char *pTexName)
{
if(Format != CImageInfo::FORMAT_RGBA)
if(Image.m_Format != CImageInfo::FORMAT_RGBA)
{
// Moving not possible, texture needs to be converted
return LoadTextureRaw(Width, Height, Format, pData, Flags, pTexName);
return LoadTextureRaw(Image, Flags, pTexName);
}
LoadTextureAddWarning(Width, Height, Flags, pTexName, m_vWarnings);
LoadTextureAddWarning(Image.m_Width, Image.m_Height, Flags, pTexName, m_vWarnings);
if(Width == 0 || Height == 0)
if(Image.m_Width == 0 || Image.m_Height == 0)
return IGraphics::CTextureHandle();
IGraphics::CTextureHandle TextureHandle = FindFreeTextureIndex();
CCommandBuffer::SCommand_Texture_Create Cmd = LoadTextureCreateCommand(TextureHandle.Id(), Width, Height, Flags);
Cmd.m_pData = pData;
CCommandBuffer::SCommand_Texture_Create Cmd = LoadTextureCreateCommand(TextureHandle.Id(), Image.m_Width, Image.m_Height, Flags);
Cmd.m_pData = Image.m_pData;
Image.m_pData = nullptr;
AddCmd(Cmd);
return TextureHandle;
@ -505,7 +502,7 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTexture(const char *pFilename,
CImageInfo Img;
if(LoadPNG(&Img, pFilename, StorageType))
{
CTextureHandle Id = LoadTextureRawMove(Img.m_Width, Img.m_Height, Img.m_Format, Img.m_pData, Flags, pFilename);
CTextureHandle Id = LoadTextureRawMove(Img, Flags, pFilename);
if(Id.IsValid())
{
if(g_Config.m_Debug)
@ -565,10 +562,7 @@ bool CGraphics_Threaded::UpdateTextTexture(CTextureHandle TextureId, int x, int
Cmd.m_Width = Width;
Cmd.m_Height = Height;
// calculate memory usage
const size_t MemSize = Width * Height;
// copy texture data
uint8_t *pTmpData = static_cast<uint8_t *>(malloc(MemSize));
mem_copy(pTmpData, pData, MemSize);
Cmd.m_pData = pTmpData;
@ -718,24 +712,26 @@ bool CGraphics_Threaded::IsImageFormatRGBA(const char *pFileName, CImageInfo &Im
return true;
}
void CGraphics_Threaded::CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, size_t FullWidth, size_t FullHeight, size_t PixelSize, size_t SubOffsetX, size_t SubOffsetY, size_t SubCopyWidth, size_t SubCopyHeight)
void CGraphics_Threaded::CopyTextureBufferSub(uint8_t *pDestBuffer, const CImageInfo &SourceImage, size_t SubOffsetX, size_t SubOffsetY, size_t SubCopyWidth, size_t SubCopyHeight)
{
const size_t PixelSize = SourceImage.PixelSize();
for(size_t Y = 0; Y < SubCopyHeight; ++Y)
{
const size_t ImgOffset = ((SubOffsetY + Y) * FullWidth * PixelSize) + (SubOffsetX * PixelSize);
const size_t ImgOffset = ((SubOffsetY + Y) * SourceImage.m_Width * PixelSize) + (SubOffsetX * PixelSize);
const size_t CopySize = SubCopyWidth * PixelSize;
mem_copy(&pDestBuffer[ImgOffset], &pSourceBuffer[ImgOffset], CopySize);
mem_copy(&pDestBuffer[ImgOffset], &SourceImage.m_pData[ImgOffset], CopySize);
}
}
void CGraphics_Threaded::CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, size_t DestWidth, size_t DestHeight, uint8_t *pSourceBuffer, size_t SrcWidth, size_t SrcHeight, size_t PixelSize, size_t SrcSubOffsetX, size_t SrcSubOffsetY, size_t SrcSubCopyWidth, size_t SrcSubCopyHeight)
void CGraphics_Threaded::CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, size_t DestWidth, size_t DestHeight, const CImageInfo &SourceImage, size_t SrcSubOffsetX, size_t SrcSubOffsetY, size_t SrcSubCopyWidth, size_t SrcSubCopyHeight)
{
const size_t PixelSize = SourceImage.PixelSize();
for(size_t Y = 0; Y < SrcSubCopyHeight; ++Y)
{
const size_t SrcImgOffset = ((SrcSubOffsetY + Y) * SrcWidth * PixelSize) + (SrcSubOffsetX * PixelSize);
const size_t SrcImgOffset = ((SrcSubOffsetY + Y) * SourceImage.m_Width * PixelSize) + (SrcSubOffsetX * PixelSize);
const size_t DstImgOffset = (Y * DestWidth * PixelSize);
const size_t CopySize = SrcSubCopyWidth * PixelSize;
mem_copy(&pDestBuffer[DstImgOffset], &pSourceBuffer[SrcImgOffset], CopySize);
mem_copy(&pDestBuffer[DstImgOffset], &SourceImage.m_pData[SrcImgOffset], CopySize);
}
}
@ -2551,9 +2547,14 @@ int CGraphics_Threaded::Init()
mem_copy(&aNullTextureData[(y * NullTextureDimension + x) * PixelSize], pColor, PixelSize);
}
}
CImageInfo NullTextureInfo;
NullTextureInfo.m_Width = NullTextureDimension;
NullTextureInfo.m_Height = NullTextureDimension;
NullTextureInfo.m_Format = CImageInfo::FORMAT_RGBA;
NullTextureInfo.m_pData = aNullTextureData;
const int TextureLoadFlags = Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
m_NullTexture.Invalidate();
m_NullTexture = LoadTextureRaw(NullTextureDimension, NullTextureDimension, CImageInfo::FORMAT_RGBA, aNullTextureData, TextureLoadFlags);
m_NullTexture = LoadTextureRaw(NullTextureInfo, TextureLoadFlags, "null-texture");
dbg_assert(m_NullTexture.IsNullTexture(), "Null texture invalid");
}

View file

@ -965,20 +965,20 @@ public:
IGraphics::CTextureHandle FindFreeTextureIndex();
void FreeTextureIndex(CTextureHandle *pIndex);
int UnloadTexture(IGraphics::CTextureHandle *pIndex) override;
IGraphics::CTextureHandle LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const uint8_t *pData, int Flags, const char *pTexName = nullptr) override;
IGraphics::CTextureHandle LoadTextureRawMove(size_t Width, size_t Height, CImageInfo::EImageFormat Format, uint8_t *pData, int Flags, const char *pTexName = nullptr) override;
int LoadTextureRawSub(IGraphics::CTextureHandle TextureId, int x, int y, size_t Width, size_t Height, CImageInfo::EImageFormat Format, const uint8_t *pData) override;
IGraphics::CTextureHandle LoadTextureRaw(const CImageInfo &Image, int Flags, const char *pTexName = nullptr) override;
IGraphics::CTextureHandle LoadTextureRawMove(CImageInfo &Image, int Flags, const char *pTexName = nullptr) override;
int LoadTextureRawSub(IGraphics::CTextureHandle TextureId, int x, int y, const CImageInfo &Image) override;
IGraphics::CTextureHandle NullTexture() const override;
bool LoadTextTextures(size_t Width, size_t Height, CTextureHandle &TextTexture, CTextureHandle &TextOutlineTexture, uint8_t *pTextData, uint8_t *pTextOutlineData) override;
bool UnloadTextTextures(CTextureHandle &TextTexture, CTextureHandle &TextOutlineTexture) override;
bool UpdateTextTexture(CTextureHandle TextureId, int x, int y, size_t Width, size_t Height, const uint8_t *pData) override;
CTextureHandle LoadSpriteTextureImpl(CImageInfo &FromImageInfo, int x, int y, size_t w, size_t h);
CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct CDataSprite *pSprite) override;
CTextureHandle LoadSpriteTextureImpl(const CImageInfo &FromImageInfo, int x, int y, size_t w, size_t h, const char *pName);
CTextureHandle LoadSpriteTexture(const CImageInfo &FromImageInfo, const struct CDataSprite *pSprite) override;
bool IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h) override;
bool IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, struct CDataSprite *pSprite) override;
bool IsImageSubFullyTransparent(const CImageInfo &FromImageInfo, int x, int y, int w, int h) override;
bool IsSpriteTextureFullyTransparent(const CImageInfo &FromImageInfo, const struct CDataSprite *pSprite) override;
// simple uncompressed RGBA loaders
IGraphics::CTextureHandle LoadTexture(const char *pFilename, int StorageType, int Flags = 0) override;
@ -987,8 +987,8 @@ public:
bool CheckImageDivisibility(const char *pFileName, CImageInfo &Img, int DivX, int DivY, bool AllowResize) override;
bool IsImageFormatRGBA(const char *pFileName, CImageInfo &Img) override;
void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, size_t FullWidth, size_t FullHeight, size_t PixelSize, size_t SubOffsetX, size_t SubOffsetY, size_t SubCopyWidth, size_t SubCopyHeight) override;
void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, size_t DestWidth, size_t DestHeight, uint8_t *pSourceBuffer, size_t SrcWidth, size_t SrcHeight, size_t PixelSize, size_t SrcSubOffsetX, size_t SrcSubOffsetY, size_t SrcSubCopyWidth, size_t SrcSubCopyHeight) override;
void CopyTextureBufferSub(uint8_t *pDestBuffer, const CImageInfo &SourceImage, size_t SubOffsetX, size_t SubOffsetY, size_t SubCopyWidth, size_t SubCopyHeight) override;
void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, size_t DestWidth, size_t DestHeight, const CImageInfo &SourceImage, size_t SrcSubOffsetX, size_t SrcSubOffsetY, size_t SrcSubCopyWidth, size_t SrcSubCopyHeight) override;
void TextureSet(CTextureHandle TextureId) override;

View file

@ -729,11 +729,12 @@ public:
return vec2(0.0f, 0.0f);
}
void UploadEntityLayerText(uint8_t *pTexBuff, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize)
void UploadEntityLayerText(const CImageInfo &TextImage, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize)
{
if(FontSize < 1)
return;
const size_t PixelSize = TextImage.PixelSize();
const char *pCurrent = pText;
const char *pEnd = pCurrent + Length;
int WidthLastChars = 0;
@ -776,17 +777,17 @@ public:
{
const int ImgOffX = clamp(x + OffX + WidthLastChars, x, (x + TexSubWidth) - 1);
const int ImgOffY = clamp(y + OffY, y, (y + TexSubHeight) - 1);
const size_t ImageOffset = ImgOffY * (TexWidth * PixelSize) + ImgOffX * PixelSize;
const size_t ImageOffset = ImgOffY * (TextImage.m_Width * PixelSize) + ImgOffX * PixelSize;
const size_t GlyphOffset = OffY * pBitmap->width + OffX;
for(size_t i = 0; i < PixelSize; ++i)
{
if(i != PixelSize - 1)
{
*(pTexBuff + ImageOffset + i) = 255;
*(TextImage.m_pData + ImageOffset + i) = 255;
}
else
{
*(pTexBuff + ImageOffset + i) = *(m_aaGlyphData[FONT_TEXTURE_FILL] + GlyphOffset);
*(TextImage.m_pData + ImageOffset + i) = *(m_aaGlyphData[FONT_TEXTURE_FILL] + GlyphOffset);
}
}
}
@ -2180,9 +2181,9 @@ public:
return TextContainer.m_BoundingBox;
}
void UploadEntityLayerText(uint8_t *pTexBuff, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize) override
void UploadEntityLayerText(const CImageInfo &TextImage, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize) override
{
m_pGlyphMap->UploadEntityLayerText(pTexBuff, PixelSize, TexWidth, TexHeight, TexSubWidth, TexSubHeight, pText, Length, x, y, FontSize);
m_pGlyphMap->UploadEntityLayerText(TextImage, TexSubWidth, TexSubHeight, pText, Length, x, y, FontSize);
}
int AdjustFontSize(const char *pText, int TextLength, int MaxSize, int MaxWidth) const override

View file

@ -341,15 +341,15 @@ public:
virtual bool IsImageFormatRGBA(const char *pFileName, CImageInfo &Img) = 0;
// destination and source buffer require to have the same width and height
virtual void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, size_t FullWidth, size_t FullHeight, size_t PixelSize, size_t SubOffsetX, size_t SubOffsetY, size_t SubCopyWidth, size_t SubCopyHeight) = 0;
virtual void CopyTextureBufferSub(uint8_t *pDestBuffer, const CImageInfo &SourceImage, size_t SubOffsetX, size_t SubOffsetY, size_t SubCopyWidth, size_t SubCopyHeight) = 0;
// destination width must be equal to the subwidth of the source
virtual void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, size_t DestWidth, size_t DestHeight, uint8_t *pSourceBuffer, size_t SrcWidth, size_t SrcHeight, size_t PixelSize, size_t SrcSubOffsetX, size_t SrcSubOffsetY, size_t SrcSubCopyWidth, size_t SrcSubCopyHeight) = 0;
virtual void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, size_t DestWidth, size_t DestHeight, const CImageInfo &SourceImage, size_t SrcSubOffsetX, size_t SrcSubOffsetY, size_t SrcSubCopyWidth, size_t SrcSubCopyHeight) = 0;
virtual int UnloadTexture(CTextureHandle *pIndex) = 0;
virtual CTextureHandle LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const uint8_t *pData, int Flags, const char *pTexName = nullptr) = 0;
virtual CTextureHandle LoadTextureRawMove(size_t Width, size_t Height, CImageInfo::EImageFormat Format, uint8_t *pData, int Flags, const char *pTexName = nullptr) = 0;
virtual int LoadTextureRawSub(CTextureHandle TextureId, int x, int y, size_t Width, size_t Height, CImageInfo::EImageFormat Format, const uint8_t *pData) = 0;
virtual CTextureHandle LoadTextureRaw(const CImageInfo &Image, int Flags, const char *pTexName = nullptr) = 0;
virtual CTextureHandle LoadTextureRawMove(CImageInfo &Image, int Flags, const char *pTexName = nullptr) = 0;
virtual int LoadTextureRawSub(CTextureHandle TextureId, int x, int y, const CImageInfo &Image) = 0;
virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int Flags = 0) = 0;
virtual CTextureHandle NullTexture() const = 0;
virtual void TextureSet(CTextureHandle Texture) = 0;
@ -360,10 +360,10 @@ public:
virtual bool UnloadTextTextures(CTextureHandle &TextTexture, CTextureHandle &TextOutlineTexture) = 0;
virtual bool UpdateTextTexture(CTextureHandle TextureId, int x, int y, size_t Width, size_t Height, const uint8_t *pData) = 0;
virtual CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct CDataSprite *pSprite) = 0;
virtual CTextureHandle LoadSpriteTexture(const CImageInfo &FromImageInfo, const struct CDataSprite *pSprite) = 0;
virtual bool IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h) = 0;
virtual bool IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, struct CDataSprite *pSprite) = 0;
virtual bool IsImageSubFullyTransparent(const CImageInfo &FromImageInfo, int x, int y, int w, int h) = 0;
virtual bool IsSpriteTextureFullyTransparent(const CImageInfo &FromImageInfo, const struct CDataSprite *pSprite) = 0;
virtual void FlushVertices(bool KeepVertices = false) = 0;
virtual void FlushVerticesTex3D() = 0;

View file

@ -344,7 +344,7 @@ public:
virtual STextBoundingBox GetBoundingBoxTextContainer(STextContainerIndex TextContainerIndex) = 0;
virtual void UploadEntityLayerText(uint8_t *pTexBuff, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize) = 0;
virtual void UploadEntityLayerText(const CImageInfo &TextImage, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize) = 0;
virtual int AdjustFontSize(const char *pText, int TextLength, int MaxSize, int MaxWidth) const = 0;
virtual float GetGlyphOffsetX(int FontSize, char TextCharacter) const = 0;
virtual int CalculateTextWidth(const char *pText, int TextLength, int FontWidth, int FontSize) const = 0;

View file

@ -75,7 +75,7 @@ void CCountryFlags::LoadCountryflagsIndexfile()
CCountryFlag CountryFlag;
CountryFlag.m_CountryCode = CountryCode;
str_copy(CountryFlag.m_aCountryCodeString, aOrigin);
CountryFlag.m_Texture = Graphics()->LoadTextureRawMove(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0, aOrigin);
CountryFlag.m_Texture = Graphics()->LoadTextureRawMove(Info, 0, aBuf);
if(g_Config.m_Debug)
{

View file

@ -131,10 +131,14 @@ void CMapImages::OnMapLoadImpl(class CLayers *pLayers, IMap *pMap)
}
else if(Format == CImageInfo::FORMAT_RGBA)
{
const uint8_t *pData = static_cast<uint8_t *>(pMap->GetData(pImg->m_ImageData));
CImageInfo ImageInfo;
ImageInfo.m_Width = pImg->m_Width;
ImageInfo.m_Height = pImg->m_Height;
ImageInfo.m_Format = Format;
ImageInfo.m_pData = static_cast<uint8_t *>(pMap->GetData(pImg->m_ImageData));
char aTexName[IO_MAX_PATH_LENGTH];
str_format(aTexName, sizeof(aTexName), "embedded: %s", pName);
m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, Format, pData, LoadFlag, aTexName);
m_aTextures[i] = Graphics()->LoadTextureRaw(ImageInfo, LoadFlag, aTexName);
pMap->UnloadData(pImg->m_ImageData);
}
pMap->UnloadData(pImg->m_ImageName);
@ -254,9 +258,11 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit
if(ImgInfo.m_pData != nullptr)
{
const size_t PixelSize = ImgInfo.PixelSize();
const size_t BuildImageSize = (size_t)ImgInfo.m_Width * ImgInfo.m_Height * PixelSize;
uint8_t *pBuildImgData = static_cast<uint8_t *>(malloc(BuildImageSize));
CImageInfo BuildImageInfo;
BuildImageInfo.m_Width = ImgInfo.m_Width;
BuildImageInfo.m_Height = ImgInfo.m_Height;
BuildImageInfo.m_Format = ImgInfo.m_Format;
BuildImageInfo.m_pData = static_cast<uint8_t *>(malloc(BuildImageInfo.DataSize()));
// build game layer
for(int LayerType = 0; LayerType < MAP_IMAGE_ENTITY_LAYER_TYPE_COUNT; ++LayerType)
@ -264,7 +270,7 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit
dbg_assert(!m_aaEntitiesTextures[(EntitiesModType * 2) + (int)EntitiesAreMasked][LayerType].IsValid(), "entities texture already loaded when it should not be");
// set everything transparent
mem_zero(pBuildImgData, BuildImageSize);
mem_zero(BuildImageInfo.m_pData, BuildImageInfo.DataSize());
for(int i = 0; i < 256; ++i)
{
@ -280,14 +286,14 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit
const size_t CopyHeight = ImgInfo.m_Height / 16;
const size_t OffsetX = (size_t)(TileIndex % 16) * CopyWidth;
const size_t OffsetY = (size_t)(TileIndex / 16) * CopyHeight;
Graphics()->CopyTextureBufferSub(pBuildImgData, ImgInfo.m_pData, ImgInfo.m_Width, ImgInfo.m_Height, PixelSize, OffsetX, OffsetY, CopyWidth, CopyHeight);
Graphics()->CopyTextureBufferSub(BuildImageInfo.m_pData, ImgInfo, OffsetX, OffsetY, CopyWidth, CopyHeight);
}
}
m_aaEntitiesTextures[(EntitiesModType * 2) + (int)EntitiesAreMasked][LayerType] = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, pBuildImgData, TextureLoadFlag, aPath);
m_aaEntitiesTextures[(EntitiesModType * 2) + (int)EntitiesAreMasked][LayerType] = Graphics()->LoadTextureRaw(BuildImageInfo, TextureLoadFlag, aPath);
}
free(pBuildImgData);
BuildImageInfo.Free();
ImgInfo.Free();
}
}
@ -377,21 +383,21 @@ int CMapImages::GetTextureScale() const
IGraphics::CTextureHandle CMapImages::UploadEntityLayerText(int TextureSize, int MaxWidth, int YOffset)
{
const size_t Width = 1024;
const size_t Height = 1024;
const size_t PixelSize = CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
CImageInfo TextImage;
TextImage.m_Width = 1024;
TextImage.m_Height = 1024;
TextImage.m_Format = CImageInfo::FORMAT_RGBA;
TextImage.m_pData = static_cast<uint8_t *>(calloc(TextImage.DataSize(), sizeof(uint8_t)));
uint8_t *pMem = static_cast<uint8_t *>(calloc(Width * Height * PixelSize, 1));
UpdateEntityLayerText(pMem, PixelSize, Width, Height, TextureSize, MaxWidth, YOffset, 0);
UpdateEntityLayerText(pMem, PixelSize, Width, Height, TextureSize, MaxWidth, YOffset, 1);
UpdateEntityLayerText(pMem, PixelSize, Width, Height, TextureSize, MaxWidth, YOffset, 2, 255);
UpdateEntityLayerText(TextImage, TextureSize, MaxWidth, YOffset, 0);
UpdateEntityLayerText(TextImage, TextureSize, MaxWidth, YOffset, 1);
UpdateEntityLayerText(TextImage, TextureSize, MaxWidth, YOffset, 2, 255);
const int TextureLoadFlag = (Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE;
return Graphics()->LoadTextureRawMove(Width, Height, CImageInfo::FORMAT_RGBA, pMem, TextureLoadFlag);
return Graphics()->LoadTextureRawMove(TextImage, TextureLoadFlag);
}
void CMapImages::UpdateEntityLayerText(uint8_t *pTexBuffer, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TextureSize, int MaxWidth, int YOffset, int NumbersPower, int MaxNumber)
void CMapImages::UpdateEntityLayerText(CImageInfo &TextImage, int TextureSize, int MaxWidth, int YOffset, int NumbersPower, int MaxNumber)
{
char aBuf[4];
int DigitsCount = NumbersPower + 1;
@ -418,7 +424,7 @@ void CMapImages::UpdateEntityLayerText(uint8_t *pTexBuffer, size_t PixelSize, si
int ApproximateTextWidth = TextRender()->CalculateTextWidth(aBuf, DigitsCount, 0, UniversalSuitableFontSize);
int XOffSet = (MaxWidth - clamp(ApproximateTextWidth, 0, MaxWidth)) / 2;
TextRender()->UploadEntityLayerText(pTexBuffer, PixelSize, TexWidth, TexHeight, (TexWidth / 16) - XOffSet, (TexHeight / 16) - YOffset, aBuf, DigitsCount, x + XOffSet, y + YOffset, UniversalSuitableFontSize);
TextRender()->UploadEntityLayerText(TextImage, (TextImage.m_Width / 16) - XOffSet, (TextImage.m_Height / 16) - YOffset, aBuf, DigitsCount, x + XOffSet, y + YOffset, UniversalSuitableFontSize);
}
}

View file

@ -80,7 +80,7 @@ private:
void InitOverlayTextures();
IGraphics::CTextureHandle UploadEntityLayerText(int TextureSize, int MaxWidth, int YOffset);
void UpdateEntityLayerText(uint8_t *pTexBuffer, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TextureSize, int MaxWidth, int YOffset, int NumbersPower, int MaxNumber = -1);
void UpdateEntityLayerText(CImageInfo &TextImage, int TextureSize, int MaxWidth, int YOffset, int NumbersPower, int MaxNumber = -1);
};
#endif

View file

@ -2320,7 +2320,7 @@ int CMenus::MenuImageScan(const char *pName, int IsDir, int DirType, void *pUser
return 0;
}
MenuImage.m_OrgTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0);
MenuImage.m_OrgTexture = pSelf->Graphics()->LoadTextureRaw(Info, 0, aPath);
// create gray scale version
unsigned char *pData = static_cast<unsigned char *>(Info.m_pData);
@ -2332,7 +2332,7 @@ int CMenus::MenuImageScan(const char *pName, int IsDir, int DirType, void *pUser
pData[i * Step + 1] = v;
pData[i * Step + 2] = v;
}
MenuImage.m_GreyTexture = pSelf->Graphics()->LoadTextureRawMove(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0);
MenuImage.m_GreyTexture = pSelf->Graphics()->LoadTextureRawMove(Info, 0, aPath);
str_truncate(MenuImage.m_aName, sizeof(MenuImage.m_aName), pName, str_length(pName) - str_length(pExtension));
pSelf->m_vMenuImages.push_back(MenuImage);

View file

@ -2022,7 +2022,7 @@ void CMenus::LoadCommunityIconFinish(const char *pCommunityId, CImageInfo &Info,
SCommunityIcon CommunityIcon;
str_copy(CommunityIcon.m_aCommunityId, pCommunityId);
CommunityIcon.m_Sha256 = Sha256;
CommunityIcon.m_OrgTexture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0);
CommunityIcon.m_OrgTexture = Graphics()->LoadTextureRaw(Info, 0, pCommunityId);
// create gray scale version
unsigned char *pData = static_cast<unsigned char *>(Info.m_pData);
@ -2034,7 +2034,7 @@ void CMenus::LoadCommunityIconFinish(const char *pCommunityId, CImageInfo &Info,
pData[i * Step + 1] = v;
pData[i * Step + 2] = v;
}
CommunityIcon.m_GreyTexture = Graphics()->LoadTextureRawMove(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0);
CommunityIcon.m_GreyTexture = Graphics()->LoadTextureRawMove(Info, 0, pCommunityId);
Info.m_pData = nullptr;
auto ExistingIcon = std::find_if(m_vCommunityIcons.begin(), m_vCommunityIcons.end(), [pCommunityId](const SCommunityIcon &Element) {

View file

@ -4383,7 +4383,7 @@ bool CEditor::ReplaceImage(const char *pFileName, int StorageType, bool CheckDup
int TextureLoadFlag = Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0)
TextureLoadFlag = 0;
pImg->m_Texture = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, pFileName);
pImg->m_Texture = Graphics()->LoadTextureRaw(ImgInfo, TextureLoadFlag, pFileName);
ImgInfo.m_pData = nullptr;
SortImages();
for(size_t i = 0; i < m_Map.m_vpImages.size(); ++i)
@ -4442,7 +4442,7 @@ bool CEditor::AddImage(const char *pFileName, int StorageType, void *pUser)
int TextureLoadFlag = pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0)
TextureLoadFlag = 0;
pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, pFileName);
pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo, TextureLoadFlag, pFileName);
ImgInfo.m_pData = nullptr;
str_copy(pImg->m_aName, aBuf);
pImg->m_AutoMapper.Load(pImg->m_aName);
@ -5142,7 +5142,7 @@ void CEditor::RenderFileDialog()
if(Graphics()->LoadPNG(&m_FilePreviewImageInfo, aBuffer, m_vpFilteredFileList[m_FilesSelectedIndex]->m_StorageType))
{
Graphics()->UnloadTexture(&m_FilePreviewImage);
m_FilePreviewImage = Graphics()->LoadTextureRawMove(m_FilePreviewImageInfo.m_Width, m_FilePreviewImageInfo.m_Height, m_FilePreviewImageInfo.m_Format, m_FilePreviewImageInfo.m_pData, 0);
m_FilePreviewImage = Graphics()->LoadTextureRawMove(m_FilePreviewImageInfo, 0, aBuffer);
m_FilePreviewImageInfo.m_pData = nullptr;
m_FilePreviewState = PREVIEW_LOADED;
}

View file

@ -525,7 +525,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
int TextureLoadFlag = m_pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0)
TextureLoadFlag = 0;
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, aBuf);
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo, TextureLoadFlag, aBuf);
ImgInfo.m_pData = nullptr;
pImg->m_External = 1;
}
@ -544,7 +544,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
int TextureLoadFlag = m_pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
if(pImg->m_Width % 16 != 0 || pImg->m_Height % 16 != 0)
TextureLoadFlag = 0;
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, TextureLoadFlag);
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(*pImg, TextureLoadFlag, pImg->m_aName);
}
// load auto mapper file

View file

@ -154,7 +154,7 @@ static std::shared_ptr<CEditorImage> ImageInfoToEditorImage(CEditor *pEditor, co
pEditorImage->m_pData = Image.m_pData;
int TextureLoadFlag = pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
pEditorImage->m_Texture = pEditor->Graphics()->LoadTextureRaw(Image.m_Width, Image.m_Height, Image.m_Format, Image.m_pData, TextureLoadFlag, pName);
pEditorImage->m_Texture = pEditor->Graphics()->LoadTextureRaw(Image, TextureLoadFlag, pName);
pEditorImage->m_External = 0;
str_copy(pEditorImage->m_aName, pName);