Add CImageInfo::PixelSize function, use enum EImageFormat

Use `enum EImageFormat` type for image format literals and variables.

Add `PixelSize` function to get the number of bytes/color channels per pixel for a specified image format.

Remove unused store format argument of texture loading functions. All textures are automatically being stored as RGBA, so the argument was unused. Also remove the therefore unused `FORMAT_AUTO`.

Rename variables consistently to `PixelSize` and use `size_t`, instead of mixing different names like `BPP` and `ColorChannelCount`.

Validate image format loaded from maps using `CImageInfo::ImageFormatFromInt`. Add `FORMAT_ERROR` to represent invalid formats.

Remove redundant `PixelSize` parameter from graphics backends and commands, which can be derived from the texture format.

Fix memory leak when RGB image data is being converted to RGBA format when saving map in editor.
This commit is contained in:
Robert Müller 2023-04-27 17:15:48 +02:00
parent 3ff799770c
commit dde45f7a40
27 changed files with 220 additions and 261 deletions

View file

@ -1,24 +1,17 @@
#include "backend_base.h"
#include <engine/gfx/image_manipulation.h>
size_t CCommandProcessorFragment_GLBase::TexFormatToImageColorChannelCount(int TexFormat)
{
if(TexFormat == CCommandBuffer::TEXFORMAT_RGBA)
return 4;
return 4;
}
void *CCommandProcessorFragment_GLBase::Resize(const unsigned char *pData, int Width, int Height, int NewWidth, int NewHeight, int BPP)
{
return ResizeImage((const uint8_t *)pData, Width, Height, NewWidth, NewHeight, BPP);
}
bool CCommandProcessorFragment_GLBase::Texture2DTo3D(void *pImageBuffer, int ImageWidth, int ImageHeight, int ImageColorChannelCount, int SplitCountWidth, int SplitCountHeight, void *pTarget3DImageData, int &Target3DImageWidth, int &Target3DImageHeight)
bool CCommandProcessorFragment_GLBase::Texture2DTo3D(void *pImageBuffer, int ImageWidth, int ImageHeight, size_t PixelSize, int SplitCountWidth, int SplitCountHeight, void *pTarget3DImageData, int &Target3DImageWidth, int &Target3DImageHeight)
{
Target3DImageWidth = ImageWidth / SplitCountWidth;
Target3DImageHeight = ImageHeight / SplitCountHeight;
size_t FullImageWidth = (size_t)ImageWidth * ImageColorChannelCount;
const size_t FullImageWidth = (size_t)ImageWidth * PixelSize;
for(int Y = 0; Y < SplitCountHeight; ++Y)
{
@ -28,7 +21,7 @@ bool CCommandProcessorFragment_GLBase::Texture2DTo3D(void *pImageBuffer, int Ima
{
int DepthIndex = X + Y * SplitCountWidth;
size_t TargetImageFullWidth = (size_t)Target3DImageWidth * ImageColorChannelCount;
size_t TargetImageFullWidth = (size_t)Target3DImageWidth * PixelSize;
size_t TargetImageFullSize = (size_t)TargetImageFullWidth * Target3DImageHeight;
ptrdiff_t ImageOffset = (ptrdiff_t)(((size_t)Y * FullImageWidth * (size_t)Target3DImageHeight) + ((size_t)Y3D * FullImageWidth) + ((size_t)X * TargetImageFullWidth));
ptrdiff_t TargetImageOffset = (ptrdiff_t)(TargetImageFullSize * (size_t)DepthIndex + ((size_t)Y3D * TargetImageFullWidth));

View file

@ -84,12 +84,11 @@ protected:
SGFXErrorContainer m_Error;
SGFXWarningContainer m_Warning;
static size_t TexFormatToImageColorChannelCount(int TexFormat);
static void *Resize(const unsigned char *pData, int Width, int Height, int NewWidth, int NewHeight, int BPP);
static bool Texture2DTo3D(void *pImageBuffer, int ImageWidth, int ImageHeight, int ImageColorChannelCount, int SplitCountWidth, int SplitCountHeight, void *pTarget3DImageData, int &Target3DImageWidth, int &Target3DImageHeight);
static bool Texture2DTo3D(void *pImageBuffer, int ImageWidth, int ImageHeight, size_t PixelSize, int SplitCountWidth, int SplitCountHeight, void *pTarget3DImageData, int &Target3DImageWidth, int &Target3DImageHeight);
virtual bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData) = 0;
virtual bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData) = 0;
public:
virtual ~CCommandProcessorFragment_GLBase() = default;

View file

@ -5,7 +5,7 @@
class CCommandProcessorFragment_Null : public CCommandProcessorFragment_GLBase
{
bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData) override { return false; };
bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData) override { return false; };
ERunCommandReturnTypes RunCommand(const CCommandBuffer::SCommand *pBaseCommand) override;
bool Cmd_Init(const SCommand_Init *pCommand);
virtual void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand);

View file

@ -49,7 +49,7 @@ int CCommandProcessorFragment_OpenGL::TexFormatToOpenGLFormat(int TexFormat)
return GL_RGBA;
}
size_t CCommandProcessorFragment_OpenGL::GLFormatToImageColorChannelCount(int GLFormat)
size_t CCommandProcessorFragment_OpenGL::GLFormatToPixelSize(int GLFormat)
{
switch(GLFormat)
{
@ -278,7 +278,7 @@ GfxOpenGLMessageCallback(GLenum Source,
}
#endif
bool CCommandProcessorFragment_OpenGL::GetPresentedImageData(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData)
bool CCommandProcessorFragment_OpenGL::GetPresentedImageData(uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData)
{
if(m_CanvasWidth == 0 || m_CanvasHeight == 0)
{
@ -314,7 +314,7 @@ bool CCommandProcessorFragment_OpenGL::InitOpenGL(const SCommand_Init *pCommand)
m_IsOpenGLES = pCommand->m_RequestedBackend == BACKEND_TYPE_OPENGL_ES;
TGLBackendReadPresentedImageData &ReadPresentedImgDataFunc = *pCommand->m_pReadPresentedImageDataFunc;
ReadPresentedImgDataFunc = [this](uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData) { return GetPresentedImageData(Width, Height, Format, vDstData); };
ReadPresentedImgDataFunc = [this](uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData) { return GetPresentedImageData(Width, Height, Format, vDstData); };
const char *pVendorString = (const char *)glGetString(GL_VENDOR);
dbg_msg("opengl", "Vendor string: %s", pVendorString);
@ -644,7 +644,7 @@ void CCommandProcessorFragment_OpenGL::TextureUpdate(int Slot, int X, int Y, int
int ResizedW = (int)(Width * ResizeW);
int ResizedH = (int)(Height * ResizeH);
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), Width, Height, ResizedW, ResizedH, GLFormatToImageColorChannelCount(GLFormat));
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), Width, Height, ResizedW, ResizedH, GLFormatToPixelSize(GLFormat));
free(pTexData);
pTexData = pTmpData;
@ -666,7 +666,7 @@ void CCommandProcessorFragment_OpenGL::TextureUpdate(int Slot, int X, int Y, int
Y /= 2;
}
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), OldWidth, OldHeight, Width, Height, GLFormatToImageColorChannelCount(GLFormat));
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), OldWidth, OldHeight, Width, Height, GLFormatToPixelSize(GLFormat));
free(pTexData);
pTexData = pTmpData;
}
@ -718,7 +718,7 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Destroy(const CCommandBuffer:
DestroyTexture(pCommand->m_Slot);
}
void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int Height, int PixelSize, int GLFormat, int GLStoreFormat, int Flags, void *pTexData)
void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int Height, int GLFormat, int GLStoreFormat, int Flags, void *pTexData)
{
#ifndef BACKEND_GL_MODERN_API
@ -741,7 +741,7 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
int PowerOfTwoHeight = HighestBit(Height);
if(Width != PowerOfTwoWidth || Height != PowerOfTwoHeight)
{
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), Width, Height, PowerOfTwoWidth, PowerOfTwoHeight, GLFormatToImageColorChannelCount(GLFormat));
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), Width, Height, PowerOfTwoWidth, PowerOfTwoHeight, GLFormatToPixelSize(GLFormat));
free(pTexData);
pTexData = pTmpData;
@ -773,7 +773,7 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
if(NeedsResize)
{
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), OldWidth, OldHeight, Width, Height, GLFormatToImageColorChannelCount(GLFormat));
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), OldWidth, OldHeight, Width, Height, GLFormatToPixelSize(GLFormat));
free(pTexData);
pTexData = pTmpData;
}
@ -782,8 +782,7 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
m_vTextures[Slot].m_Height = Height;
m_vTextures[Slot].m_RescaleCount = RescaleCount;
int Oglformat = GLFormat;
int StoreOglformat = GLStoreFormat;
const size_t PixelSize = GLFormatToPixelSize(GLFormat);
if((Flags & CCommandBuffer::TEXFLAG_NO_2D_TEXTURE) == 0)
{
@ -797,7 +796,7 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, Width, Height, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
glTexImage2D(GL_TEXTURE_2D, 0, GLStoreFormat, Width, Height, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData);
}
}
else
@ -813,7 +812,7 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, ((GLfloat)m_OpenGLTextureLodBIAS / 1000.0f));
#endif
glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, Width, Height, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
glTexImage2D(GL_TEXTURE_2D, 0, GLStoreFormat, Width, Height, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData);
}
int Flag2DArrayTexture = (CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE | CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER);
@ -881,14 +880,12 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
glBindSampler(0, 0);
}
int ImageColorChannels = GLFormatToImageColorChannelCount(GLFormat);
uint8_t *p3DImageData = NULL;
bool IsSingleLayer = (Flags & (CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER | CCommandBuffer::TEXFLAG_TO_3D_TEXTURE_SINGLE_LAYER)) != 0;
if(!IsSingleLayer)
p3DImageData = (uint8_t *)malloc((size_t)ImageColorChannels * Width * Height);
p3DImageData = (uint8_t *)malloc((size_t)Width * Height * PixelSize);
int Image3DWidth, Image3DHeight;
int ConvertWidth = Width;
@ -901,7 +898,7 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
dbg_msg("gfx", "3D/2D array texture was resized");
int NewWidth = maximum<int>(HighestBit(ConvertWidth), 16);
int NewHeight = maximum<int>(HighestBit(ConvertHeight), 16);
uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pTexData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, GLFormatToImageColorChannelCount(GLFormat));
uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pTexData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, GLFormatToPixelSize(GLFormat));
ConvertWidth = NewWidth;
ConvertHeight = NewHeight;
@ -911,15 +908,15 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
}
}
if(IsSingleLayer || (Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, ImageColorChannels, 16, 16, p3DImageData, Image3DWidth, Image3DHeight)))
if(IsSingleLayer || (Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DImageData, Image3DWidth, Image3DHeight)))
{
if(IsSingleLayer)
{
glTexImage3D(Target, 0, StoreOglformat, ConvertWidth, ConvertHeight, 1, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
glTexImage3D(Target, 0, GLStoreFormat, ConvertWidth, ConvertHeight, 1, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData);
}
else
{
glTexImage3D(Target, 0, StoreOglformat, Image3DWidth, Image3DHeight, 256, 0, Oglformat, GL_UNSIGNED_BYTE, p3DImageData);
glTexImage3D(Target, 0, GLStoreFormat, Image3DWidth, Image3DHeight, 256, 0, GLFormat, GL_UNSIGNED_BYTE, p3DImageData);
}
}
@ -932,12 +929,12 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
m_vTextures[Slot].m_LastWrapMode = CCommandBuffer::WRAP_REPEAT;
// calculate memory usage
m_vTextures[Slot].m_MemSize = Width * Height * PixelSize;
m_vTextures[Slot].m_MemSize = (size_t)Width * Height * PixelSize;
while(Width > 2 && Height > 2)
{
Width >>= 1;
Height >>= 1;
m_vTextures[Slot].m_MemSize += Width * Height * PixelSize;
m_vTextures[Slot].m_MemSize += (size_t)Width * Height * PixelSize;
}
m_pTextureMemoryUsage->store(m_pTextureMemoryUsage->load(std::memory_order_relaxed) + m_vTextures[Slot].m_MemSize, std::memory_order_relaxed);
@ -947,7 +944,7 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He
void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand)
{
TextureCreate(pCommand->m_Slot, pCommand->m_Width, pCommand->m_Height, pCommand->m_PixelSize, TexFormatToOpenGLFormat(pCommand->m_Format), TexFormatToOpenGLFormat(pCommand->m_StoreFormat), pCommand->m_Flags, pCommand->m_pData);
TextureCreate(pCommand->m_Slot, pCommand->m_Width, pCommand->m_Height, TexFormatToOpenGLFormat(pCommand->m_Format), TexFormatToOpenGLFormat(pCommand->m_StoreFormat), pCommand->m_Flags, pCommand->m_pData);
}
void CCommandProcessorFragment_OpenGL::Cmd_TextTexture_Update(const CCommandBuffer::SCommand_TextTexture_Update *pCommand)
@ -963,10 +960,8 @@ void CCommandProcessorFragment_OpenGL::Cmd_TextTextures_Destroy(const CCommandBu
void CCommandProcessorFragment_OpenGL::Cmd_TextTextures_Create(const CCommandBuffer::SCommand_TextTextures_Create *pCommand)
{
void *pTextData = pCommand->m_pTextData;
void *pTextOutlineData = pCommand->m_pTextOutlineData;
TextureCreate(pCommand->m_Slot, pCommand->m_Width, pCommand->m_Height, 1, GL_ALPHA, GL_ALPHA, CCommandBuffer::TEXFLAG_NOMIPMAPS, pTextData);
TextureCreate(pCommand->m_SlotOutline, pCommand->m_Width, pCommand->m_Height, 1, GL_ALPHA, GL_ALPHA, CCommandBuffer::TEXFLAG_NOMIPMAPS, pTextOutlineData);
TextureCreate(pCommand->m_Slot, pCommand->m_Width, pCommand->m_Height, GL_ALPHA, GL_ALPHA, CCommandBuffer::TEXFLAG_NOMIPMAPS, pCommand->m_pTextData);
TextureCreate(pCommand->m_SlotOutline, pCommand->m_Width, pCommand->m_Height, GL_ALPHA, GL_ALPHA, CCommandBuffer::TEXFLAG_NOMIPMAPS, pCommand->m_pTextOutlineData);
}
void CCommandProcessorFragment_OpenGL::Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand)

View file

@ -80,13 +80,13 @@ protected:
virtual bool IsNewApi() { return false; }
void DestroyTexture(int Slot);
bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData) override;
bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData) override;
static int TexFormatToOpenGLFormat(int TexFormat);
static size_t GLFormatToImageColorChannelCount(int GLFormat);
static size_t GLFormatToPixelSize(int GLFormat);
void TextureUpdate(int Slot, int X, int Y, int Width, int Height, int GLFormat, void *pTexData);
void TextureCreate(int Slot, int Width, int Height, int PixelSize, int GLFormat, int GLStoreFormat, int Flags, void *pTexData);
void TextureCreate(int Slot, int Width, int Height, int GLFormat, int GLStoreFormat, int Flags, void *pTexData);
virtual bool Cmd_Init(const SCommand_Init *pCommand);
virtual void Cmd_Shutdown(const SCommand_Shutdown *pCommand) {}

View file

@ -555,7 +555,7 @@ void CCommandProcessorFragment_OpenGL3_3::TextureUpdate(int Slot, int X, int Y,
Y /= 2;
}
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), Width, Height, Width, Height, GLFormatToImageColorChannelCount(GLFormat));
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), Width, Height, Width, Height, GLFormatToPixelSize(GLFormat));
free(pTexData);
pTexData = pTmpData;
}
@ -577,7 +577,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Texture_Destroy(const CCommandBuff
DestroyTexture(pCommand->m_Slot);
}
void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int Height, int PixelSize, int GLFormat, int GLStoreFormat, int Flags, void *pTexData)
void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int Height, int GLFormat, int GLStoreFormat, int Flags, void *pTexData)
{
if(Slot >= (int)m_vTextures.size())
m_vTextures.resize(m_vTextures.size() * 2);
@ -595,7 +595,7 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
++RescaleCount;
} while(Width > m_MaxTexSize || Height > m_MaxTexSize);
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), Width, Height, Width, Height, GLFormatToImageColorChannelCount(GLFormat));
void *pTmpData = Resize(static_cast<const unsigned char *>(pTexData), Width, Height, Width, Height, GLFormatToPixelSize(GLFormat));
free(pTexData);
pTexData = pTmpData;
}
@ -604,10 +604,9 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
m_vTextures[Slot].m_Height = Height;
m_vTextures[Slot].m_RescaleCount = RescaleCount;
int Oglformat = GLFormat;
int StoreOglformat = GLStoreFormat;
if(StoreOglformat == GL_RED)
StoreOglformat = GL_R8;
if(GLStoreFormat == GL_RED)
GLStoreFormat = GL_R8;
const size_t PixelSize = GLFormatToPixelSize(GLFormat);
int SamplerSlot = 0;
@ -628,7 +627,7 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glSamplerParameteri(m_vTextures[Slot].m_Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glSamplerParameteri(m_vTextures[Slot].m_Sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, Width, Height, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
glTexImage2D(GL_TEXTURE_2D, 0, GLStoreFormat, Width, Height, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData);
}
}
else
@ -649,7 +648,7 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5.f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5);
}
glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, Width, Height, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
glTexImage2D(GL_TEXTURE_2D, 0, GLStoreFormat, Width, Height, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData);
glGenerateMipmap(GL_TEXTURE_2D);
}
@ -671,14 +670,12 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
glSamplerParameterf(m_vTextures[Slot].m_Sampler2DArray, GL_TEXTURE_LOD_BIAS, ((GLfloat)m_OpenGLTextureLodBIAS / 1000.0f));
#endif
int ImageColorChannels = GLFormatToImageColorChannelCount(GLFormat);
uint8_t *p3DImageData = NULL;
bool IsSingleLayer = (Flags & CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER) != 0;
if(!IsSingleLayer)
p3DImageData = (uint8_t *)malloc((size_t)ImageColorChannels * Width * Height);
p3DImageData = (uint8_t *)malloc((size_t)Width * Height * PixelSize);
int Image3DWidth, Image3DHeight;
int ConvertWidth = Width;
@ -691,7 +688,7 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
dbg_msg("gfx", "3D/2D array texture was resized");
int NewWidth = maximum<int>(HighestBit(ConvertWidth), 16);
int NewHeight = maximum<int>(HighestBit(ConvertHeight), 16);
uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pTexData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, GLFormatToImageColorChannelCount(GLFormat));
uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pTexData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, GLFormatToPixelSize(GLFormat));
ConvertWidth = NewWidth;
ConvertHeight = NewHeight;
@ -701,15 +698,15 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
}
}
if(IsSingleLayer || (Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, ImageColorChannels, 16, 16, p3DImageData, Image3DWidth, Image3DHeight)))
if(IsSingleLayer || (Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DImageData, Image3DWidth, Image3DHeight)))
{
if(IsSingleLayer)
{
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, StoreOglformat, ConvertWidth, ConvertHeight, 1, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GLStoreFormat, ConvertWidth, ConvertHeight, 1, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData);
}
else
{
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, StoreOglformat, Image3DWidth, Image3DHeight, 256, 0, Oglformat, GL_UNSIGNED_BYTE, p3DImageData);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GLStoreFormat, Image3DWidth, Image3DHeight, 256, 0, GLFormat, GL_UNSIGNED_BYTE, p3DImageData);
}
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
}
@ -723,12 +720,12 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
m_vTextures[Slot].m_LastWrapMode = CCommandBuffer::WRAP_REPEAT;
// calculate memory usage
m_vTextures[Slot].m_MemSize = Width * Height * PixelSize;
m_vTextures[Slot].m_MemSize = (size_t)Width * Height * PixelSize;
while(Width > 2 && Height > 2)
{
Width >>= 1;
Height >>= 1;
m_vTextures[Slot].m_MemSize += Width * Height * PixelSize;
m_vTextures[Slot].m_MemSize += (size_t)Width * Height * PixelSize;
}
m_pTextureMemoryUsage->store(m_pTextureMemoryUsage->load(std::memory_order_relaxed) + m_vTextures[Slot].m_MemSize, std::memory_order_relaxed);
@ -737,7 +734,7 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int
void CCommandProcessorFragment_OpenGL3_3::Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand)
{
TextureCreate(pCommand->m_Slot, pCommand->m_Width, pCommand->m_Height, pCommand->m_PixelSize, TexFormatToOpenGLFormat(pCommand->m_Format), TexFormatToOpenGLFormat(pCommand->m_StoreFormat), pCommand->m_Flags, pCommand->m_pData);
TextureCreate(pCommand->m_Slot, pCommand->m_Width, pCommand->m_Height, TexFormatToOpenGLFormat(pCommand->m_Format), TexFormatToOpenGLFormat(pCommand->m_StoreFormat), pCommand->m_Flags, pCommand->m_pData);
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_TextTexture_Update(const CCommandBuffer::SCommand_TextTexture_Update *pCommand)
@ -753,10 +750,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_TextTextures_Destroy(const CComman
void CCommandProcessorFragment_OpenGL3_3::Cmd_TextTextures_Create(const CCommandBuffer::SCommand_TextTextures_Create *pCommand)
{
void *pTextData = pCommand->m_pTextData;
void *pTextOutlineData = pCommand->m_pTextOutlineData;
TextureCreate(pCommand->m_Slot, pCommand->m_Width, pCommand->m_Height, 1, GL_RED, GL_RED, CCommandBuffer::TEXFLAG_NOMIPMAPS, pTextData);
TextureCreate(pCommand->m_SlotOutline, pCommand->m_Width, pCommand->m_Height, 1, GL_RED, GL_RED, CCommandBuffer::TEXFLAG_NOMIPMAPS, pTextOutlineData);
TextureCreate(pCommand->m_Slot, pCommand->m_Width, pCommand->m_Height, GL_RED, GL_RED, CCommandBuffer::TEXFLAG_NOMIPMAPS, pCommand->m_pTextData);
TextureCreate(pCommand->m_SlotOutline, pCommand->m_Width, pCommand->m_Height, GL_RED, GL_RED, CCommandBuffer::TEXFLAG_NOMIPMAPS, pCommand->m_pTextOutlineData);
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand)

View file

@ -83,7 +83,7 @@ protected:
void RenderText(const CCommandBuffer::SState &State, int DrawNum, int TextTextureIndex, int TextOutlineTextureIndex, int TextureSize, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor);
void TextureUpdate(int Slot, int X, int Y, int Width, int Height, int GLFormat, void *pTexData);
void TextureCreate(int Slot, int Width, int Height, int PixelSize, int GLFormat, int GLStoreFormat, int Flags, void *pTexData);
void TextureCreate(int Slot, int Width, int Height, int GLFormat, int GLStoreFormat, int Flags, void *pTexData);
bool Cmd_Init(const SCommand_Init *pCommand) override;
void Cmd_Shutdown(const SCommand_Shutdown *pCommand) override;

View file

@ -1385,7 +1385,7 @@ protected:
}
}
[[nodiscard]] bool GetPresentedImageDataImpl(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData, bool FlipImgData, bool ResetAlpha)
[[nodiscard]] bool GetPresentedImageDataImpl(uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData, bool FlipImgData, bool ResetAlpha)
{
bool IsB8G8R8A8 = m_VKSurfFormat.format == VK_FORMAT_B8G8R8A8_UNORM;
bool UsesRGBALikeFormat = m_VKSurfFormat.format == VK_FORMAT_R8G8B8A8_UNORM || IsB8G8R8A8;
@ -1396,7 +1396,7 @@ protected:
Height = Viewport.height;
Format = CImageInfo::FORMAT_RGBA;
size_t ImageTotalSize = (size_t)Width * Height * 4;
const size_t ImageTotalSize = (size_t)Width * Height * CImageInfo::PixelSize(Format);
uint8_t *pResImageData;
if(!PreparePresentedImageDataImage(pResImageData, Width, Height))
@ -1552,7 +1552,7 @@ protected:
}
}
[[nodiscard]] bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData) override
[[nodiscard]] bool GetPresentedImageData(uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData) override
{
return GetPresentedImageDataImpl(Width, Height, Format, vDstData, false, false);
}
@ -2509,7 +2509,7 @@ protected:
* TEXTURES
************************/
size_t VulkanFormatToImageColorChannelCount(VkFormat Format)
size_t VulkanFormatToPixelSize(VkFormat Format)
{
if(Format == VK_FORMAT_R8G8B8_UNORM)
return 3;
@ -2520,9 +2520,9 @@ protected:
return 4;
}
[[nodiscard]] bool UpdateTexture(size_t TextureSlot, VkFormat Format, void *&pData, int64_t XOff, int64_t YOff, size_t Width, size_t Height, size_t ColorChannelCount)
[[nodiscard]] bool UpdateTexture(size_t TextureSlot, VkFormat Format, void *&pData, int64_t XOff, int64_t YOff, size_t Width, size_t Height)
{
size_t ImageSize = Width * Height * ColorChannelCount;
const size_t ImageSize = Width * Height * VulkanFormatToPixelSize(Format);
SMemoryBlock<s_StagingBufferImageCacheID> StagingBuffer;
if(!GetStagingBufferImage(StagingBuffer, pData, ImageSize))
return false;
@ -2540,7 +2540,7 @@ protected:
YOff /= 2;
}
void *pTmpData = Resize((const uint8_t *)pData, Width, Height, Width, Height, VulkanFormatToImageColorChannelCount(Format));
void *pTmpData = Resize((const uint8_t *)pData, Width, Height, Width, Height, VulkanFormatToPixelSize(Format));
free(pData);
pData = pTmpData;
}
@ -2570,14 +2570,13 @@ protected:
int Slot,
int Width,
int Height,
int PixelSize,
VkFormat Format,
VkFormat StoreFormat,
int Flags,
void *&pData)
{
size_t ImageIndex = (size_t)Slot;
int ImageColorChannels = VulkanFormatToImageColorChannelCount(Format);
const size_t PixelSize = VulkanFormatToPixelSize(Format);
while(ImageIndex >= m_vTextures.size())
{
@ -2595,7 +2594,7 @@ protected:
++RescaleCount;
} while((size_t)Width > m_MaxTextureSize || (size_t)Height > m_MaxTextureSize);
void *pTmpData = Resize((const uint8_t *)(pData), Width, Height, Width, Height, ImageColorChannels);
void *pTmpData = Resize((const uint8_t *)(pData), Width, Height, Width, Height, PixelSize);
free(pData);
pData = pTmpData;
}
@ -2653,7 +2652,7 @@ protected:
dbg_msg("vulkan", "3D/2D array texture was resized");
int NewWidth = maximum<int>(HighestBit(ConvertWidth), 16);
int NewHeight = maximum<int>(HighestBit(ConvertHeight), 16);
uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, ImageColorChannels);
uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, PixelSize);
ConvertWidth = NewWidth;
ConvertHeight = NewHeight;
@ -2667,8 +2666,8 @@ protected:
bool Needs3DTexDel = false;
if(!Is2DTextureSingleLayer)
{
p3DTexData = malloc((size_t)ImageColorChannels * ConvertWidth * ConvertHeight);
if(!Texture2DTo3D(pData, ConvertWidth, ConvertHeight, ImageColorChannels, 16, 16, p3DTexData, Image3DWidth, Image3DHeight))
p3DTexData = malloc((size_t)PixelSize * ConvertWidth * ConvertHeight);
if(!Texture2DTo3D(pData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DTexData, Image3DWidth, Image3DHeight))
{
free(p3DTexData);
p3DTexData = nullptr;
@ -6581,7 +6580,7 @@ public:
m_MultiSamplingCount = (g_Config.m_GfxFsaaSamples & 0xFFFFFFFE); // ignore the uneven bit, only even multi sampling works
TGLBackendReadPresentedImageData &ReadPresentedImgDataFunc = *pCommand->m_pReadPresentedImageDataFunc;
ReadPresentedImgDataFunc = [this](uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData) { return GetPresentedImageData(Width, Height, Format, vDstData); };
ReadPresentedImgDataFunc = [this](uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData) { return GetPresentedImageData(Width, Height, Format, vDstData); };
m_pWindow = pCommand->m_pWindow;
@ -6656,7 +6655,7 @@ public:
void *pData = pCommand->m_pData;
if(!UpdateTexture(IndexTex, VK_FORMAT_B8G8R8A8_UNORM, pData, pCommand->m_X, pCommand->m_Y, pCommand->m_Width, pCommand->m_Height, TexFormatToImageColorChannelCount(pCommand->m_Format)))
if(!UpdateTexture(IndexTex, VK_FORMAT_B8G8R8A8_UNORM, pData, pCommand->m_X, pCommand->m_Y, pCommand->m_Width, pCommand->m_Height))
return false;
free(pData);
@ -6681,13 +6680,12 @@ public:
int Slot = pCommand->m_Slot;
int Width = pCommand->m_Width;
int Height = pCommand->m_Height;
int PixelSize = pCommand->m_PixelSize;
int Format = pCommand->m_Format;
int StoreFormat = pCommand->m_StoreFormat;
int Flags = pCommand->m_Flags;
void *pData = pCommand->m_pData;
if(!CreateTextureCMD(Slot, Width, Height, PixelSize, TextureFormatToVulkanFormat(Format), TextureFormatToVulkanFormat(StoreFormat), Flags, pData))
if(!CreateTextureCMD(Slot, Width, Height, TextureFormatToVulkanFormat(Format), TextureFormatToVulkanFormat(StoreFormat), Flags, pData))
return false;
free(pData);
@ -6705,9 +6703,9 @@ public:
void *pTmpData = pCommand->m_pTextData;
void *pTmpData2 = pCommand->m_pTextOutlineData;
if(!CreateTextureCMD(Slot, Width, Height, 1, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, CCommandBuffer::TEXFLAG_NOMIPMAPS, pTmpData))
if(!CreateTextureCMD(Slot, Width, Height, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, CCommandBuffer::TEXFLAG_NOMIPMAPS, pTmpData))
return false;
if(!CreateTextureCMD(SlotOutline, Width, Height, 1, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, CCommandBuffer::TEXFLAG_NOMIPMAPS, pTmpData2))
if(!CreateTextureCMD(SlotOutline, Width, Height, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, CCommandBuffer::TEXFLAG_NOMIPMAPS, pTmpData2))
return false;
if(!CreateNewTextDescriptorSets(Slot, SlotOutline))
@ -6740,7 +6738,7 @@ public:
void *pData = pCommand->m_pData;
if(!UpdateTexture(IndexTex, VK_FORMAT_R8_UNORM, pData, pCommand->m_X, pCommand->m_Y, pCommand->m_Width, pCommand->m_Height, 1))
if(!UpdateTexture(IndexTex, VK_FORMAT_R8_UNORM, pData, pCommand->m_X, pCommand->m_Y, pCommand->m_Width, pCommand->m_Height))
return false;
free(pData);
@ -6814,7 +6812,7 @@ public:
uint32_t Width;
uint32_t Height;
uint32_t Format;
CImageInfo::EImageFormat Format;
if(GetPresentedImageDataImpl(Width, Height, Format, m_vScreenshotHelper, false, true))
{
size_t ImgSize = (size_t)Width * (size_t)Height * (size_t)4;
@ -6827,7 +6825,7 @@ public:
}
pCommand->m_pImage->m_Width = (int)Width;
pCommand->m_pImage->m_Height = (int)Height;
pCommand->m_pImage->m_Format = (int)Format;
pCommand->m_pImage->m_Format = Format;
return true;
}

View file

@ -974,7 +974,7 @@ void CClient::ServerInfoRequest()
void CClient::LoadDebugFont()
{
m_DebugFont = Graphics()->LoadTexture("debug_font.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_DebugFont = Graphics()->LoadTexture("debug_font.png", IStorage::TYPE_ALL);
}
// ---

View file

@ -305,27 +305,17 @@ int CGraphics_Threaded::UnloadTexture(CTextureHandle *pIndex)
return 0;
}
static int ImageFormatToPixelSize(int Format)
{
switch(Format)
{
case CImageInfo::FORMAT_RGB: return 3;
case CImageInfo::FORMAT_SINGLE_COMPONENT: return 1;
default: return 4;
}
}
static bool ConvertToRGBA(uint8_t *pDest, const uint8_t *pSrc, size_t SrcWidth, size_t SrcHeight, int SrcFormat)
static bool ConvertToRGBA(uint8_t *pDest, const uint8_t *pSrc, size_t SrcWidth, size_t SrcHeight, CImageInfo::EImageFormat SrcFormat)
{
if(SrcFormat == CImageInfo::FORMAT_RGBA)
{
mem_copy(pDest, pSrc, SrcWidth * SrcHeight * 4);
mem_copy(pDest, pSrc, SrcWidth * SrcHeight * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA));
return true;
}
else
{
size_t SrcChannelCount = ImageFormatToPixelSize(SrcFormat);
size_t DstChannelCount = 4;
const size_t SrcChannelCount = CImageInfo::PixelSize(SrcFormat);
const size_t DstChannelCount = CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
for(size_t Y = 0; Y < SrcHeight; ++Y)
{
for(size_t X = 0; X < SrcWidth; ++X)
@ -333,12 +323,12 @@ static bool ConvertToRGBA(uint8_t *pDest, const uint8_t *pSrc, size_t SrcWidth,
size_t ImgOffsetSrc = (Y * SrcWidth * SrcChannelCount) + (X * SrcChannelCount);
size_t ImgOffsetDest = (Y * SrcWidth * DstChannelCount) + (X * DstChannelCount);
size_t CopySize = SrcChannelCount;
if(SrcChannelCount == 3)
if(SrcFormat == CImageInfo::FORMAT_RGB)
{
mem_copy(&pDest[ImgOffsetDest], &pSrc[ImgOffsetSrc], CopySize);
pDest[ImgOffsetDest + 3] = 255;
}
else if(SrcChannelCount == 1)
else if(SrcFormat == CImageInfo::FORMAT_SINGLE_COMPONENT)
{
pDest[ImgOffsetDest + 0] = 255;
pDest[ImgOffsetDest + 1] = 255;
@ -351,7 +341,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, int Format, const void *pData)
int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureID, int x, int y, size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData)
{
dbg_assert(TextureID.IsValid(), "Invalid texture handle used with LoadTextureRawSub.");
@ -364,7 +354,7 @@ int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureID, int x, int y
Cmd.m_Format = CCommandBuffer::TEXFORMAT_RGBA;
// calculate memory usage
const size_t MemSize = Width * Height * 4;
const size_t MemSize = Width * Height * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
// copy texture data
void *pTmpData = malloc(MemSize);
@ -377,7 +367,7 @@ int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureID, int x, int y
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTextureImpl(CImageInfo &FromImageInfo, int x, int y, size_t w, size_t h)
{
const size_t PixelSize = ImageFormatToPixelSize(FromImageInfo.m_Format);
const size_t PixelSize = FromImageInfo.PixelSize();
m_vSpriteHelper.resize(w * h * PixelSize);
CopyTextureFromTextureBufferSub(m_vSpriteHelper.data(), w, h, (uint8_t *)FromImageInfo.m_pData, FromImageInfo.m_Width, FromImageInfo.m_Height, PixelSize, x, y, w, h);
return LoadTextureRaw(w, h, FromImageInfo.m_Format, m_vSpriteHelper.data(), FromImageInfo.m_Format, 0);
@ -410,13 +400,13 @@ bool CGraphics_Threaded::IsImageSubFullyTransparent(CImageInfo &FromImageInfo, i
if(FromImageInfo.m_Format == CImageInfo::FORMAT_SINGLE_COMPONENT || FromImageInfo.m_Format == CImageInfo::FORMAT_RGBA)
{
uint8_t *pImgData = (uint8_t *)FromImageInfo.m_pData;
int bpp = ImageFormatToPixelSize(FromImageInfo.m_Format);
const size_t PixelSize = FromImageInfo.PixelSize();
for(int iy = 0; iy < h; ++iy)
{
for(int ix = 0; ix < w; ++ix)
{
int RealOffset = (x + ix) * bpp + (y + iy) * bpp * FromImageInfo.m_Width;
if(pImgData[RealOffset + (bpp - 1)] > 0)
const size_t RealOffset = (x + ix) * PixelSize + (y + iy) * PixelSize * FromImageInfo.m_Width;
if(pImgData[RealOffset + (PixelSize - 1)] > 0)
return false;
}
}
@ -438,7 +428,7 @@ bool CGraphics_Threaded::IsSpriteTextureFullyTransparent(CImageInfo &FromImageIn
return IsImageSubFullyTransparent(FromImageInfo, x, y, w, h);
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_t Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName)
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *pData, int Flags, const char *pTexName)
{
// don't waste memory on texture if we are stress testing
#ifdef CONF_DEBUG
@ -472,7 +462,6 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_
Cmd.m_Slot = TextureHandle.Id();
Cmd.m_Width = Width;
Cmd.m_Height = Height;
Cmd.m_PixelSize = 4;
Cmd.m_Format = CCommandBuffer::TEXFORMAT_RGBA;
Cmd.m_StoreFormat = CCommandBuffer::TEXFORMAT_RGBA;
@ -492,7 +481,7 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NO_2D_TEXTURE;
// copy texture data
const size_t MemSize = Width * Height * Cmd.m_PixelSize;
const size_t MemSize = Width * Height * CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
void *pTmpData = malloc(MemSize);
if(!ConvertToRGBA((uint8_t *)pTmpData, (const uint8_t *)pData, Width, Height, Format))
{
@ -505,17 +494,14 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_
}
// simple uncompressed RGBA loaders
IGraphics::CTextureHandle CGraphics_Threaded::LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags)
IGraphics::CTextureHandle CGraphics_Threaded::LoadTexture(const char *pFilename, int StorageType, int Flags)
{
dbg_assert(pFilename[0] != '\0', "Cannot load texture from file with empty filename"); // would cause Valgrind to crash otherwise
CImageInfo Img;
if(LoadPNG(&Img, pFilename, StorageType))
{
if(StoreFormat == CImageInfo::FORMAT_AUTO)
StoreFormat = Img.m_Format;
IGraphics::CTextureHandle ID = LoadTextureRaw(Img.m_Width, Img.m_Height, Img.m_Format, Img.m_pData, StoreFormat, Flags, pFilename);
IGraphics::CTextureHandle ID = LoadTextureRaw(Img.m_Width, Img.m_Height, Img.m_Format, Img.m_pData, Flags, pFilename);
free(Img.m_pData);
if(ID.Id() != m_InvalidTexture.Id() && g_Config.m_Debug)
dbg_msg("graphics/texture", "loaded %s", pFilename);
@ -696,15 +682,7 @@ bool CGraphics_Threaded::CheckImageDivisibility(const char *pFileName, CImageInf
NewWidth = (NewHeight / DivY) * DivX;
}
int ColorChannelCount = 4;
if(Img.m_Format == CImageInfo::FORMAT_SINGLE_COMPONENT)
ColorChannelCount = 1;
else if(Img.m_Format == CImageInfo::FORMAT_RGB)
ColorChannelCount = 3;
else if(Img.m_Format == CImageInfo::FORMAT_RGBA)
ColorChannelCount = 4;
uint8_t *pNewImg = ResizeImage((uint8_t *)Img.m_pData, Img.m_Width, Img.m_Height, NewWidth, NewHeight, ColorChannelCount);
uint8_t *pNewImg = ResizeImage((uint8_t *)Img.m_pData, Img.m_Width, Img.m_Height, NewWidth, NewHeight, Img.PixelSize());
free(Img.m_pData);
Img.m_pData = pNewImg;
Img.m_Width = NewWidth;
@ -734,23 +712,23 @@ 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 ColorChannelCount, size_t SubOffsetX, size_t SubOffsetY, size_t SubCopyWidth, size_t SubCopyHeight)
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)
{
for(size_t Y = 0; Y < SubCopyHeight; ++Y)
{
const size_t ImgOffset = ((SubOffsetY + Y) * FullWidth * ColorChannelCount) + (SubOffsetX * ColorChannelCount);
const size_t CopySize = SubCopyWidth * ColorChannelCount;
const size_t ImgOffset = ((SubOffsetY + Y) * FullWidth * PixelSize) + (SubOffsetX * PixelSize);
const size_t CopySize = SubCopyWidth * PixelSize;
mem_copy(&pDestBuffer[ImgOffset], &pSourceBuffer[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 ColorChannelCount, 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, uint8_t *pSourceBuffer, size_t SrcWidth, size_t SrcHeight, size_t PixelSize, size_t SrcSubOffsetX, size_t SrcSubOffsetY, size_t SrcSubCopyWidth, size_t SrcSubCopyHeight)
{
for(size_t Y = 0; Y < SrcSubCopyHeight; ++Y)
{
const size_t SrcImgOffset = ((SrcSubOffsetY + Y) * SrcWidth * ColorChannelCount) + (SrcSubOffsetX * ColorChannelCount);
const size_t DstImgOffset = (Y * DestWidth * ColorChannelCount);
const size_t CopySize = SrcSubCopyWidth * ColorChannelCount;
const size_t SrcImgOffset = ((SrcSubOffsetY + Y) * SrcWidth * PixelSize) + (SrcSubOffsetX * PixelSize);
const size_t DstImgOffset = (Y * DestWidth * PixelSize);
const size_t CopySize = SrcSubCopyWidth * PixelSize;
mem_copy(&pDestBuffer[DstImgOffset], &pSourceBuffer[SrcImgOffset], CopySize);
}
}
@ -2671,7 +2649,7 @@ int CGraphics_Threaded::Init()
}
const int TextureLoadFlags = HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
m_InvalidTexture.Invalidate();
m_InvalidTexture = LoadTextureRaw(InvalidTextureDimension, InvalidTextureDimension, CImageInfo::FORMAT_RGBA, aNullTextureData, CImageInfo::FORMAT_RGBA, TextureLoadFlags);
m_InvalidTexture = LoadTextureRaw(InvalidTextureDimension, InvalidTextureDimension, CImageInfo::FORMAT_RGBA, aNullTextureData, TextureLoadFlags);
}
ColorRGBA GPUInfoPrintColor{0.6f, 0.5f, 1.0f, 1.0f};

View file

@ -535,7 +535,6 @@ public:
size_t m_Width;
size_t m_Height;
int m_PixelSize;
int m_Format;
int m_StoreFormat;
int m_Flags;
@ -967,8 +966,8 @@ public:
IGraphics::CTextureHandle FindFreeTextureIndex();
void FreeTextureIndex(CTextureHandle *pIndex);
int UnloadTexture(IGraphics::CTextureHandle *pIndex) override;
IGraphics::CTextureHandle LoadTextureRaw(size_t Width, size_t Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL) override;
int LoadTextureRawSub(IGraphics::CTextureHandle TextureID, int x, int y, size_t Width, size_t Height, int Format, const void *pData) override;
IGraphics::CTextureHandle LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *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 void *pData) override;
IGraphics::CTextureHandle InvalidTexture() const override;
bool LoadTextTextures(size_t Width, size_t Height, CTextureHandle &TextTexture, CTextureHandle &TextOutlineTexture, void *pTextData, void *pTextOutlineData) override;
@ -983,15 +982,15 @@ public:
bool IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) override;
// simple uncompressed RGBA loaders
IGraphics::CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) override;
IGraphics::CTextureHandle LoadTexture(const char *pFilename, int StorageType, int Flags = 0) override;
int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) override;
void FreePNG(CImageInfo *pImg) override;
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 ColorChannelCount, 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 ColorChannelCount, size_t SrcSubOffsetX, size_t SrcSubOffsetY, size_t SrcSubCopyWidth, size_t SrcSubCopyHeight) 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;
bool ScreenshotDirect();

View file

@ -729,7 +729,7 @@ public:
return vec2(0.0f, 0.0f);
}
void UploadEntityLayerText(void *pTexBuff, size_t ImageColorChannelCount, int TexWidth, int TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize)
void UploadEntityLayerText(void *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)
{
if(FontSize < 1)
return;
@ -777,11 +777,11 @@ 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 * ImageColorChannelCount) + ImgOffX * ImageColorChannelCount;
const size_t ImageOffset = ImgOffY * (TexWidth * PixelSize) + ImgOffX * PixelSize;
const size_t GlyphOffset = OffY * pBitmap->width + OffX;
for(size_t i = 0; i < ImageColorChannelCount; ++i)
for(size_t i = 0; i < PixelSize; ++i)
{
if(i != ImageColorChannelCount - 1)
if(i != PixelSize - 1)
{
*(pImageBuff + ImageOffset + i) = 255;
}
@ -2139,9 +2139,9 @@ public:
return TextContainer.m_BoundingBox;
}
void UploadEntityLayerText(void *pTexBuff, size_t ImageColorChannelCount, int TexWidth, int TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize) override
void UploadEntityLayerText(void *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
{
m_pGlyphMap->UploadEntityLayerText(pTexBuff, ImageColorChannelCount, TexWidth, TexHeight, TexSubWidth, TexSubHeight, pText, Length, x, y, FontSize);
m_pGlyphMap->UploadEntityLayerText(pTexBuff, PixelSize, TexWidth, TexHeight, TexSubWidth, TexSubHeight, pText, Length, x, y, FontSize);
}
int AdjustFontSize(const char *pText, int TextLength, int MaxSize, int MaxWidth) const override

View file

@ -585,7 +585,7 @@ void CVideo::ReadRGBFromGL(size_t ThreadIndex)
{
uint32_t Width;
uint32_t Height;
uint32_t Format;
CImageInfo::EImageFormat Format;
m_pGraphics->GetReadPresentedImageDataFuncUnsafe()(Width, Height, Format, m_vPixelHelper[ThreadIndex]);
}

View file

@ -66,29 +66,54 @@ struct SGraphicTileTexureCoords
class CImageInfo
{
public:
enum
enum EImageFormat
{
FORMAT_AUTO = -1,
FORMAT_ERROR = -1,
FORMAT_RGB = 0,
FORMAT_RGBA = 1,
FORMAT_SINGLE_COMPONENT = 2,
};
/* Variable: width
Contains the width of the image */
/**
* Contains the width of the image
*/
int m_Width = 0;
/* Variable: height
Contains the height of the image */
/**
* Contains the height of the image
*/
int m_Height = 0;
/* Variable: format
Contains the format of the image. See <Image Formats> for more information. */
int m_Format = FORMAT_RGB;
/**
* Contains the format of the image.
*
* @see EImageFormat
*/
EImageFormat m_Format = FORMAT_ERROR;
/* Variable: data
Pointer to the image data. */
/**
* Pointer to the image data.
*/
void *m_pData = nullptr;
static size_t PixelSize(EImageFormat Format)
{
dbg_assert(Format != FORMAT_ERROR, "Format invalid");
static const size_t s_aSizes[] = {3, 4, 1};
return s_aSizes[(int)Format];
}
size_t PixelSize() const
{
return PixelSize(m_Format);
}
static EImageFormat ImageFormatFromInt(int Format)
{
if(Format < (int)FORMAT_RGB || Format > (int)FORMAT_SINGLE_COMPONENT)
return FORMAT_ERROR;
return (EImageFormat)Format;
}
};
/*
@ -207,7 +232,7 @@ namespace client_data7 {
struct CDataSprite; // NOLINT(bugprone-forward-declaration-namespace)
}
typedef std::function<bool(uint32_t &Width, uint32_t &Height, uint32_t &Format, std::vector<uint8_t> &vDstData)> TGLBackendReadPresentedImageData;
typedef std::function<bool(uint32_t &Width, uint32_t &Height, CImageInfo::EImageFormat &Format, std::vector<uint8_t> &vDstData)> TGLBackendReadPresentedImageData;
class IGraphics : public IInterface
{
@ -307,15 +332,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 ColorChannelCount, size_t SubOffsetX, size_t SubOffsetY, size_t SubCopyWidth, size_t SubCopyHeight) = 0;
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;
// 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 ColorChannelCount, 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, 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 int UnloadTexture(CTextureHandle *pIndex) = 0;
virtual CTextureHandle LoadTextureRaw(size_t Width, size_t Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = nullptr) = 0;
virtual int LoadTextureRawSub(CTextureHandle TextureID, int x, int y, size_t Width, size_t Height, int Format, const void *pData) = 0;
virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) = 0;
virtual CTextureHandle LoadTextureRaw(size_t Width, size_t Height, CImageInfo::EImageFormat Format, const void *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 void *pData) = 0;
virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int Flags = 0) = 0;
virtual CTextureHandle InvalidTexture() const = 0;
virtual void TextureSet(CTextureHandle Texture) = 0;
void TextureClear() { TextureSet(CTextureHandle()); }

View file

@ -281,7 +281,7 @@ public:
virtual STextBoundingBox GetBoundingBoxTextContainer(STextContainerIndex TextContainerIndex) = 0;
virtual void UploadEntityLayerText(void *pTexBuff, size_t ImageColorChannelCount, int TexWidth, int TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontSize) = 0;
virtual void UploadEntityLayerText(void *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 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()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0, aOrigin);
CountryFlag.m_Texture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, 0, aOrigin);
Graphics()->FreePNG(&Info);
if(g_Config.m_Debug)

View file

@ -106,13 +106,13 @@ void CMapImages::OnMapLoadImpl(class CLayers *pLayers, IMap *pMap)
{
int LoadFlag = (((m_aTextureUsedByTileOrQuadLayerFlag[i] & 1) != 0) ? TextureLoadFlag : 0) | (((m_aTextureUsedByTileOrQuadLayerFlag[i] & 2) != 0) ? 0 : (Graphics()->IsTileBufferingEnabled() ? IGraphics::TEXLOAD_NO_2D_TEXTURE : 0));
const CMapItemImage_v2 *pImg = (CMapItemImage_v2 *)pMap->GetItem(Start + i);
const int Format = pImg->m_Version < CMapItemImage_v2::CURRENT_VERSION ? CImageInfo::FORMAT_RGBA : pImg->m_Format;
const CImageInfo::EImageFormat Format = pImg->m_Version < CMapItemImage_v2::CURRENT_VERSION ? CImageInfo::FORMAT_RGBA : CImageInfo::ImageFormatFromInt(pImg->m_Format);
if(pImg->m_External)
{
char aPath[IO_MAX_PATH_LENGTH];
char *pName = (char *)pMap->GetData(pImg->m_ImageName);
str_format(aPath, sizeof(aPath), "mapres/%s.png", pName);
m_aTextures[i] = Graphics()->LoadTexture(aPath, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, LoadFlag);
m_aTextures[i] = Graphics()->LoadTexture(aPath, IStorage::TYPE_ALL, LoadFlag);
pMap->UnloadData(pImg->m_ImageName);
}
else if(Format != CImageInfo::FORMAT_RGBA)
@ -126,7 +126,7 @@ void CMapImages::OnMapLoadImpl(class CLayers *pLayers, IMap *pMap)
char *pName = (char *)pMap->GetData(pImg->m_ImageName);
char aTexName[128];
str_format(aTexName, sizeof(aTexName), "%s %s", "embedded:", pName);
m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, Format, pData, CImageInfo::FORMAT_RGBA, LoadFlag, aTexName);
m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, Format, pData, LoadFlag, aTexName);
pMap->UnloadData(pImg->m_ImageName);
pMap->UnloadData(pImg->m_ImageData);
}
@ -241,15 +241,8 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit
if(ImagePNGLoaded && ImgInfo.m_Width > 0 && ImgInfo.m_Height > 0)
{
int ColorChannelCount = 4;
if(ImgInfo.m_Format == CImageInfo::FORMAT_SINGLE_COMPONENT)
ColorChannelCount = 1;
else if(ImgInfo.m_Format == CImageInfo::FORMAT_RGB)
ColorChannelCount = 3;
else if(ImgInfo.m_Format == CImageInfo::FORMAT_RGBA)
ColorChannelCount = 4;
int BuildImageSize = ColorChannelCount * ImgInfo.m_Width * ImgInfo.m_Height;
const size_t PixelSize = ImgInfo.PixelSize();
const size_t BuildImageSize = (size_t)ImgInfo.m_Width * ImgInfo.m_Height * PixelSize;
uint8_t *pTmpImgData = (uint8_t *)ImgInfo.m_pData;
uint8_t *pBuildImgData = (uint8_t *)malloc(BuildImageSize);
@ -318,11 +311,11 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit
int CopyHeight = ImgInfo.m_Height / 16;
if(ValidTile)
{
Graphics()->CopyTextureBufferSub(pBuildImgData, pTmpImgData, ImgInfo.m_Width, ImgInfo.m_Height, ColorChannelCount, (size_t)X * CopyWidth, (size_t)Y * CopyHeight, CopyWidth, CopyHeight);
Graphics()->CopyTextureBufferSub(pBuildImgData, pTmpImgData, ImgInfo.m_Width, ImgInfo.m_Height, PixelSize, (size_t)X * CopyWidth, (size_t)Y * CopyHeight, CopyWidth, CopyHeight);
}
}
m_aaEntitiesTextures[(EntitiesModType * 2) + (int)EntitiesAreMasked][n] = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, pBuildImgData, ImgInfo.m_Format, TextureLoadFlag, aPath);
m_aaEntitiesTextures[(EntitiesModType * 2) + (int)EntitiesAreMasked][n] = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, pBuildImgData, TextureLoadFlag, aPath);
}
else
{
@ -331,7 +324,7 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit
// set everything transparent
mem_zero(pBuildImgData, BuildImageSize);
m_TransparentTexture = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, pBuildImgData, ImgInfo.m_Format, TextureLoadFlag, aPath);
m_TransparentTexture = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, pBuildImgData, TextureLoadFlag, aPath);
}
m_aaEntitiesTextures[(EntitiesModType * 2) + (int)EntitiesAreMasked][n] = m_TransparentTexture;
}
@ -351,7 +344,7 @@ IGraphics::CTextureHandle CMapImages::GetSpeedupArrow()
if(!m_SpeedupArrowIsLoaded)
{
int TextureLoadFlag = (Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER : IGraphics::TEXLOAD_TO_3D_TEXTURE_SINGLE_LAYER) | IGraphics::TEXLOAD_NO_2D_TEXTURE;
m_SpeedupArrowTexture = Graphics()->LoadTexture(g_pData->m_aImages[IMAGE_SPEEDUP_ARROW].m_pFilename, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
m_SpeedupArrowTexture = Graphics()->LoadTexture(g_pData->m_aImages[IMAGE_SPEEDUP_ARROW].m_pFilename, IStorage::TYPE_ALL, TextureLoadFlag);
m_SpeedupArrowIsLoaded = true;
}
@ -428,20 +421,24 @@ int CMapImages::GetTextureScale()
IGraphics::CTextureHandle CMapImages::UploadEntityLayerText(int TextureSize, int MaxWidth, int YOffset)
{
void *pMem = calloc(1024 * 1024 * 4, 1);
const size_t Width = 1024;
const size_t Height = 1024;
const size_t PixelSize = CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
UpdateEntityLayerText(pMem, 4, 1024, 1024, TextureSize, MaxWidth, YOffset, 0);
UpdateEntityLayerText(pMem, 4, 1024, 1024, TextureSize, MaxWidth, YOffset, 1);
UpdateEntityLayerText(pMem, 4, 1024, 1024, TextureSize, MaxWidth, YOffset, 2, 255);
void *pMem = calloc(Width * Height * PixelSize, 1);
int TextureLoadFlag = (Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE;
IGraphics::CTextureHandle Texture = Graphics()->LoadTextureRaw(1024, 1024, CImageInfo::FORMAT_RGBA, pMem, CImageInfo::FORMAT_RGBA, TextureLoadFlag);
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);
const int TextureLoadFlag = (Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE;
IGraphics::CTextureHandle Texture = Graphics()->LoadTextureRaw(Width, Height, CImageInfo::FORMAT_RGBA, pMem, TextureLoadFlag);
free(pMem);
return Texture;
}
void CMapImages::UpdateEntityLayerText(void *pTexBuffer, int ImageColorChannelCount, int TexWidth, int TexHeight, int TextureSize, int MaxWidth, int YOffset, int NumbersPower, int MaxNumber)
void CMapImages::UpdateEntityLayerText(void *pTexBuffer, size_t PixelSize, size_t TexWidth, size_t TexHeight, int TextureSize, int MaxWidth, int YOffset, int NumbersPower, int MaxNumber)
{
char aBuf[4];
int DigitsCount = NumbersPower + 1;
@ -468,7 +465,7 @@ void CMapImages::UpdateEntityLayerText(void *pTexBuffer, int ImageColorChannelCo
int ApproximateTextWidth = TextRender()->CalculateTextWidth(aBuf, DigitsCount, 0, UniversalSuitableFontSize);
int XOffSet = (MaxWidth - clamp(ApproximateTextWidth, 0, MaxWidth)) / 2;
TextRender()->UploadEntityLayerText(pTexBuffer, ImageColorChannelCount, TexWidth, TexHeight, (TexWidth / 16) - XOffSet, (TexHeight / 16) - YOffset, aBuf, DigitsCount, x + XOffSet, y + YOffset, UniversalSuitableFontSize);
TextRender()->UploadEntityLayerText(pTexBuffer, PixelSize, TexWidth, TexHeight, (TexWidth / 16) - XOffSet, (TexHeight / 16) - YOffset, aBuf, DigitsCount, x + XOffSet, y + YOffset, UniversalSuitableFontSize);
}
}

View file

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

View file

@ -864,7 +864,7 @@ void CMenus::OnInit()
Console()->Chain("cl_asset_hud", ConchainAssetHud, this);
Console()->Chain("cl_asset_extras", ConchainAssetExtras, this);
m_TextureBlob = Graphics()->LoadTexture("blob.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_TextureBlob = Graphics()->LoadTexture("blob.png", IStorage::TYPE_ALL);
// setup load amount
const int NumMenuImages = 5;
@ -2173,10 +2173,9 @@ int CMenus::MenuImageScan(const char *pName, int IsDir, int DirType, void *pUser
MenuImage.m_OrgTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
unsigned char *pData = (unsigned char *)Info.m_pData;
//int Pitch = Info.m_Width*4;
// create colorless version
int Step = Info.m_Format == CImageInfo::FORMAT_RGBA ? 4 : 3;
const size_t Step = Info.PixelSize();
// make the texture gray scale
for(int i = 0; i < Info.m_Width * Info.m_Height; i++)

View file

@ -305,7 +305,7 @@ void CGameClient::OnInit()
else if(g_pData->m_aImages[i].m_pFilename[0] == '\0') // handle special null image without filename
g_pData->m_aImages[i].m_Id = IGraphics::CTextureHandle();
else
g_pData->m_aImages[i].m_Id = Graphics()->LoadTexture(g_pData->m_aImages[i].m_pFilename, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
g_pData->m_aImages[i].m_Id = Graphics()->LoadTexture(g_pData->m_aImages[i].m_pFilename, IStorage::TYPE_ALL);
m_Menus.RenderLoading(pLoadingDDNetCaption, Localize("Initializing assets"), 1);
}

View file

@ -3860,18 +3860,14 @@ bool CEditor::ReplaceImage(const char *pFileName, int StorageType, bool CheckDup
if(!pImg->m_External && g_Config.m_ClEditorDilate == 1 && pImg->m_Format == CImageInfo::FORMAT_RGBA)
{
int ColorChannelCount = 0;
if(ImgInfo.m_Format == CImageInfo::FORMAT_RGBA)
ColorChannelCount = 4;
DilateImage((unsigned char *)ImgInfo.m_pData, ImgInfo.m_Width, ImgInfo.m_Height, ColorChannelCount);
DilateImage((unsigned char *)ImgInfo.m_pData, ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.PixelSize());
}
pImg->m_AutoMapper.Load(pImg->m_aName);
int TextureLoadFlag = Graphics()->HasTextureArrays() ? 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, CImageInfo::FORMAT_AUTO, TextureLoadFlag, pFileName);
pImg->m_Texture = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, pFileName);
ImgInfo.m_pData = nullptr;
SortImages();
for(size_t i = 0; i < m_Map.m_vpImages.size(); ++i)
@ -3924,17 +3920,13 @@ bool CEditor::AddImage(const char *pFileName, int StorageType, void *pUser)
if(!pImg->m_External && g_Config.m_ClEditorDilate == 1 && pImg->m_Format == CImageInfo::FORMAT_RGBA)
{
int ColorChannelCount = 0;
if(ImgInfo.m_Format == CImageInfo::FORMAT_RGBA)
ColorChannelCount = 4;
DilateImage((unsigned char *)ImgInfo.m_pData, ImgInfo.m_Width, ImgInfo.m_Height, ColorChannelCount);
DilateImage((unsigned char *)ImgInfo.m_pData, ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.PixelSize());
}
int TextureLoadFlag = pEditor->Graphics()->HasTextureArrays() ? 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, CImageInfo::FORMAT_AUTO, TextureLoadFlag, pFileName);
pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, pFileName);
ImgInfo.m_pData = nullptr;
str_copy(pImg->m_aName, aBuf);
pImg->m_AutoMapper.Load(pImg->m_aName);
@ -4618,7 +4610,7 @@ void CEditor::RenderFileDialog()
if(Graphics()->LoadPNG(&m_FilePreviewImageInfo, aBuffer, m_vpFilteredFileList[m_FilesSelectedIndex]->m_StorageType))
{
Graphics()->UnloadTexture(&m_FilePreviewImage);
m_FilePreviewImage = Graphics()->LoadTextureRaw(m_FilePreviewImageInfo.m_Width, m_FilePreviewImageInfo.m_Height, m_FilePreviewImageInfo.m_Format, m_FilePreviewImageInfo.m_pData, m_FilePreviewImageInfo.m_Format, 0);
m_FilePreviewImage = Graphics()->LoadTextureRaw(m_FilePreviewImageInfo.m_Width, m_FilePreviewImageInfo.m_Height, m_FilePreviewImageInfo.m_Format, m_FilePreviewImageInfo.m_pData, 0);
Graphics()->FreePNG(&m_FilePreviewImageInfo);
m_FilePreviewState = PREVIEW_LOADED;
}
@ -7443,42 +7435,42 @@ int CEditor::GetTextureUsageFlag()
IGraphics::CTextureHandle CEditor::GetFrontTexture()
{
if(!m_FrontTexture.IsValid())
m_FrontTexture = Graphics()->LoadTexture("editor/front.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, GetTextureUsageFlag());
m_FrontTexture = Graphics()->LoadTexture("editor/front.png", IStorage::TYPE_ALL, GetTextureUsageFlag());
return m_FrontTexture;
}
IGraphics::CTextureHandle CEditor::GetTeleTexture()
{
if(!m_TeleTexture.IsValid())
m_TeleTexture = Graphics()->LoadTexture("editor/tele.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, GetTextureUsageFlag());
m_TeleTexture = Graphics()->LoadTexture("editor/tele.png", IStorage::TYPE_ALL, GetTextureUsageFlag());
return m_TeleTexture;
}
IGraphics::CTextureHandle CEditor::GetSpeedupTexture()
{
if(!m_SpeedupTexture.IsValid())
m_SpeedupTexture = Graphics()->LoadTexture("editor/speedup.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, GetTextureUsageFlag());
m_SpeedupTexture = Graphics()->LoadTexture("editor/speedup.png", IStorage::TYPE_ALL, GetTextureUsageFlag());
return m_SpeedupTexture;
}
IGraphics::CTextureHandle CEditor::GetSwitchTexture()
{
if(!m_SwitchTexture.IsValid())
m_SwitchTexture = Graphics()->LoadTexture("editor/switch.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, GetTextureUsageFlag());
m_SwitchTexture = Graphics()->LoadTexture("editor/switch.png", IStorage::TYPE_ALL, GetTextureUsageFlag());
return m_SwitchTexture;
}
IGraphics::CTextureHandle CEditor::GetTuneTexture()
{
if(!m_TuneTexture.IsValid())
m_TuneTexture = Graphics()->LoadTexture("editor/tune.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, GetTextureUsageFlag());
m_TuneTexture = Graphics()->LoadTexture("editor/tune.png", IStorage::TYPE_ALL, GetTextureUsageFlag());
return m_TuneTexture;
}
IGraphics::CTextureHandle CEditor::GetEntitiesTexture()
{
if(!m_EntitiesTexture.IsValid())
m_EntitiesTexture = Graphics()->LoadTexture("editor/entities/DDNet.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, GetTextureUsageFlag());
m_EntitiesTexture = Graphics()->LoadTexture("editor/entities/DDNet.png", IStorage::TYPE_ALL, GetTextureUsageFlag());
return m_EntitiesTexture;
}
@ -7506,9 +7498,9 @@ void CEditor::Init()
for(CEditorComponent &Component : m_vComponents)
Component.Init(this);
m_CheckerTexture = Graphics()->LoadTexture("editor/checker.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_BackgroundTexture = Graphics()->LoadTexture("editor/background.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_CursorTexture = Graphics()->LoadTexture("editor/cursor.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_CheckerTexture = Graphics()->LoadTexture("editor/checker.png", IStorage::TYPE_ALL);
m_BackgroundTexture = Graphics()->LoadTexture("editor/background.png", IStorage::TYPE_ALL);
m_CursorTexture = Graphics()->LoadTexture("editor/cursor.png", IStorage::TYPE_ALL);
m_pTilesetPicker = std::make_shared<CLayerTiles>(16, 16);
m_pTilesetPicker->m_pEditor = this;

View file

@ -123,24 +123,26 @@ bool CEditorMap::Save(const char *pFileName)
}
else
{
const size_t PixelSize = CImageInfo::PixelSize(CImageInfo::FORMAT_RGBA);
const size_t DataSize = (size_t)Item.m_Width * Item.m_Height * PixelSize;
if(pImg->m_Format == CImageInfo::FORMAT_RGB)
{
// Convert to RGBA
unsigned char *pDataRGBA = (unsigned char *)malloc((size_t)Item.m_Width * Item.m_Height * 4);
unsigned char *pDataRGBA = (unsigned char *)malloc(DataSize);
unsigned char *pDataRGB = (unsigned char *)pImg->m_pData;
for(int j = 0; j < Item.m_Width * Item.m_Height; j++)
{
pDataRGBA[j * 4] = pDataRGB[j * 3];
pDataRGBA[j * 4 + 1] = pDataRGB[j * 3 + 1];
pDataRGBA[j * 4 + 2] = pDataRGB[j * 3 + 2];
pDataRGBA[j * 4 + 3] = 255;
pDataRGBA[j * PixelSize] = pDataRGB[j * 3];
pDataRGBA[j * PixelSize + 1] = pDataRGB[j * 3 + 1];
pDataRGBA[j * PixelSize + 2] = pDataRGB[j * 3 + 2];
pDataRGBA[j * PixelSize + 3] = 255;
}
Item.m_ImageData = Writer.AddData(Item.m_Width * Item.m_Height * 4, pDataRGBA);
Item.m_ImageData = Writer.AddData(DataSize, pDataRGBA);
free(pDataRGBA);
}
else
{
Item.m_ImageData = Writer.AddData(Item.m_Width * Item.m_Height * 4, pImg->m_pData);
Item.m_ImageData = Writer.AddData(DataSize, pImg->m_pData);
}
}
Writer.AddItem(MAPITEMTYPE_IMAGE, i, sizeof(Item), &Item);
@ -487,7 +489,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
std::shared_ptr<CEditorImage> pImg = std::make_shared<CEditorImage>(m_pEditor);
pImg->m_External = pItem->m_External;
const int Format = pItem->m_Version < CMapItemImage_v2::CURRENT_VERSION ? CImageInfo::FORMAT_RGBA : pItem->m_Format;
const CImageInfo::EImageFormat Format = pItem->m_Version < CMapItemImage_v2::CURRENT_VERSION ? CImageInfo::FORMAT_RGBA : CImageInfo::ImageFormatFromInt(pItem->m_Format);
if(pImg->m_External || (Format != CImageInfo::FORMAT_RGB && Format != CImageInfo::FORMAT_RGBA))
{
char aBuf[IO_MAX_PATH_LENGTH];
@ -501,7 +503,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? 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, CImageInfo::FORMAT_AUTO, TextureLoadFlag, aBuf);
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, aBuf);
ImgInfo.m_pData = nullptr;
pImg->m_External = 1;
}
@ -514,13 +516,13 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio
// copy image data
void *pData = DataFile.GetData(pItem->m_ImageData);
const size_t DataSize = (size_t)pImg->m_Width * pImg->m_Height * 4;
const size_t DataSize = (size_t)pImg->m_Width * pImg->m_Height * CImageInfo::PixelSize(Format);
pImg->m_pData = malloc(DataSize);
mem_copy(pImg->m_pData, pData, DataSize);
int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? 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, CImageInfo::FORMAT_AUTO, TextureLoadFlag);
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, TextureLoadFlag);
}
// copy image name

View file

@ -2418,7 +2418,7 @@ CUI::EPopupMenuFunctionResult CEditor::PopupEntities(void *pContext, CUIRect Vie
char aBuf[IO_MAX_PATH_LENGTH];
str_format(aBuf, sizeof(aBuf), "editor/entities/%s.png", pName);
pEditor->m_EntitiesTexture = pEditor->Graphics()->LoadTexture(aBuf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, pEditor->GetTextureUsageFlag());
pEditor->m_EntitiesTexture = pEditor->Graphics()->LoadTexture(aBuf, IStorage::TYPE_ALL, pEditor->GetTextureUsageFlag());
return CUI::POPUP_CLOSE_CURRENT;
}
}

View file

@ -16,27 +16,14 @@ bool operator<(const ColorRGBA &Left, const ColorRGBA &Right)
return Left.a < Right.a;
}
static int GetNumColorChannels(const CImageInfo &Image)
{
switch(Image.m_Format)
{
case CImageInfo::FORMAT_RGB:
return 3;
case CImageInfo::FORMAT_SINGLE_COMPONENT:
return 1;
default:
return 4;
}
}
static ColorRGBA GetPixelColor(const CImageInfo &Image, int x, int y)
static ColorRGBA GetPixelColor(const CImageInfo &Image, size_t x, size_t y)
{
uint8_t *pData = static_cast<uint8_t *>(Image.m_pData);
int NumColorChannels = GetNumColorChannels(Image);
int PixelStartIndex = x * NumColorChannels + (Image.m_Width * NumColorChannels * y);
const size_t PixelSize = Image.PixelSize();
const size_t PixelStartIndex = x * PixelSize + (Image.m_Width * PixelSize * y);
ColorRGBA Color = {255, 255, 255, 255};
if(NumColorChannels == 1)
if(PixelSize == 1)
{
Color.a = pData[PixelStartIndex];
}
@ -46,20 +33,20 @@ static ColorRGBA GetPixelColor(const CImageInfo &Image, int x, int y)
Color.g = pData[PixelStartIndex + 1];
Color.b = pData[PixelStartIndex + 2];
if(NumColorChannels == 4)
if(PixelSize == 4)
Color.a = pData[PixelStartIndex + 3];
}
return Color;
}
static void SetPixelColor(CImageInfo *pImage, int x, int y, ColorRGBA Color)
static void SetPixelColor(CImageInfo *pImage, size_t x, size_t y, ColorRGBA Color)
{
uint8_t *pData = static_cast<uint8_t *>(pImage->m_pData);
int NumColorChannels = GetNumColorChannels(*pImage);
int PixelStartIndex = x * NumColorChannels + (pImage->m_Width * NumColorChannels * y);
const size_t PixelSize = pImage->PixelSize();
const size_t PixelStartIndex = x * PixelSize + (pImage->m_Width * PixelSize * y);
if(NumColorChannels == 1)
if(PixelSize == 1)
{
pData[PixelStartIndex] = Color.a;
}
@ -69,7 +56,7 @@ static void SetPixelColor(CImageInfo *pImage, int x, int y, ColorRGBA Color)
pData[PixelStartIndex + 1] = Color.g;
pData[PixelStartIndex + 2] = Color.b;
if(NumColorChannels == 4)
if(PixelSize == 4)
pData[PixelStartIndex + 3] = Color.a;
}
}
@ -168,7 +155,7 @@ static std::shared_ptr<CEditorImage> ImageInfoToEditorImage(CEditor *pEditor, co
pEditorImage->m_pData = Image.m_pData;
int TextureLoadFlag = pEditor->Graphics()->HasTextureArrays() ? 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, CImageInfo::FORMAT_AUTO, TextureLoadFlag, pName);
pEditorImage->m_Texture = pEditor->Graphics()->LoadTextureRaw(Image.m_Width, Image.m_Height, Image.m_Format, Image.m_pData, TextureLoadFlag, pName);
pEditorImage->m_External = 0;
str_copy(pEditorImage->m_aName, pName);

View file

@ -124,7 +124,7 @@ void *ReplaceImageItem(CMapItemImage *pImgItem, CMapItemImage *pNewImgItem)
pNewImgItem->m_ImageData = g_NextDataItemID++;
g_apNewData[g_Index] = ImgInfo.m_pData;
g_aNewDataSize[g_Index] = ImgInfo.m_Width * ImgInfo.m_Height * 4;
g_aNewDataSize[g_Index] = (size_t)ImgInfo.m_Width * ImgInfo.m_Height * ImgInfo.PixelSize();
g_Index++;
return (void *)pNewImgItem;

View file

@ -220,9 +220,9 @@ bool GetPixelClamped(const CImageInfo &Img, int x, int y, uint8_t aPixel[4])
aPixel[2] = 255;
aPixel[3] = 255;
int BPP = Img.m_Format == CImageInfo::FORMAT_RGB ? 3 : 4;
for(int i = 0; i < BPP; i++)
aPixel[i] = ((uint8_t *)Img.m_pData)[x * BPP + (Img.m_Width * BPP * y) + i];
const size_t PixelSize = Img.PixelSize();
for(size_t i = 0; i < PixelSize; i++)
aPixel[i] = ((uint8_t *)Img.m_pData)[x * PixelSize + (Img.m_Width * PixelSize * y) + i];
return aPixel[3] > 0;
}

View file

@ -95,7 +95,7 @@ void *ReplaceImageItem(CMapItemImage *pImgItem, const char *pImgName, const char
IStorage::StripPathAndExtension(pImgFile, g_aNewName, sizeof(g_aNewName));
g_NewDataID = pImgItem->m_ImageData;
g_pNewData = ImgInfo.m_pData;
g_NewDataSize = ImgInfo.m_Width * ImgInfo.m_Height * 4;
g_NewDataSize = (size_t)ImgInfo.m_Width * ImgInfo.m_Height * ImgInfo.PixelSize();
return (void *)pNewImgItem;
}