mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Drop non RGBA images
This commit is contained in:
parent
883c17cd2c
commit
76064bd1c8
|
@ -610,6 +610,25 @@ bool CGraphics_Threaded::CheckImageDivisibility(const char *pFileName, CImageInf
|
|||
return ImageIsValid;
|
||||
}
|
||||
|
||||
bool CGraphics_Threaded::CheckImageFormatRGBA(const char *pFileName, CImageInfo &Img)
|
||||
{
|
||||
if(Img.m_Format != CImageInfo::FORMAT_RGBA && Img.m_Format != CImageInfo::FORMAT_ALPHA)
|
||||
{
|
||||
SWarning NewWarning;
|
||||
char aText[128];
|
||||
aText[0] = '\0';
|
||||
if(pFileName)
|
||||
{
|
||||
str_format(aText, sizeof(aText), "\"%s\"", pFileName);
|
||||
}
|
||||
str_format(NewWarning.m_aWarningMsg, sizeof(NewWarning.m_aWarningMsg),
|
||||
Localize("The format of texture %s is not RGBA which will cause visual bugs."), aText);
|
||||
m_Warnings.emplace_back(NewWarning);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight)
|
||||
{
|
||||
for(int Y = 0; Y < SubCopyHeight; ++Y)
|
||||
|
|
|
@ -900,6 +900,7 @@ public:
|
|||
void FreePNG(CImageInfo *pImg) override;
|
||||
|
||||
bool CheckImageDivisibility(const char *pFileName, CImageInfo &Img, int DivX, int DivY, bool AllowResize) override;
|
||||
bool CheckImageFormatRGBA(const char *pFileName, CImageInfo &Img) override;
|
||||
|
||||
void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) override;
|
||||
void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, int DestWidth, int DestHeight, uint8_t *pSourceBuffer, int SrcWidth, int SrcHeight, int ColorChannelCount, int SrcSubOffsetX, int SrcSubOffsetY, int SrcSubCopyWidth, int SrcSubCopyHeight) override;
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
void FreePNG(CImageInfo *pImg) override{};
|
||||
|
||||
bool CheckImageDivisibility(const char *pFileName, CImageInfo &Img, int DivX, int DivY, bool AllowResize) override { return false; };
|
||||
bool CheckImageFormatRGBA(const char *pFileName, CImageInfo &Img) override { return false; };
|
||||
|
||||
void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) override{};
|
||||
void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, int DestWidth, int DestHeight, uint8_t *pSourceBuffer, int SrcWidth, int SrcHeight, int ColorChannelCount, int SrcSubOffsetX, int SrcSubOffsetY, int SrcSubCopyWidth, int SrcSubCopyHeight) override{};
|
||||
|
|
|
@ -241,6 +241,7 @@ public:
|
|||
virtual void FreePNG(CImageInfo *pImg) = 0;
|
||||
|
||||
virtual bool CheckImageDivisibility(const char *pFileName, CImageInfo &Img, int DivX, int DivY, bool AllowResize) = 0;
|
||||
virtual bool CheckImageFormatRGBA(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, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) = 0;
|
||||
|
|
|
@ -133,6 +133,12 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info)
|
|||
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
|
||||
return 0;
|
||||
}
|
||||
if(!Graphics()->CheckImageFormatRGBA(pName, Info))
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "skin format is not RGBA: %s", pName);
|
||||
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSkin Skin;
|
||||
Skin.m_IsVanilla = IsVanillaSkin(pName);
|
||||
|
@ -175,7 +181,8 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info)
|
|||
if(BodyWidth > Info.m_Width || BodyHeight > Info.m_Height)
|
||||
return 0;
|
||||
unsigned char *d = (unsigned char *)Info.m_pData;
|
||||
int Pitch = Info.m_Width * 4;
|
||||
const int PixelStep = 4;
|
||||
int Pitch = Info.m_Width * PixelStep;
|
||||
|
||||
// dig out blood color
|
||||
{
|
||||
|
@ -183,12 +190,12 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info)
|
|||
for(int y = 0; y < BodyHeight; y++)
|
||||
for(int x = 0; x < BodyWidth; x++)
|
||||
{
|
||||
uint8_t AlphaValue = d[y * Pitch + x * 4 + 3];
|
||||
uint8_t AlphaValue = d[y * Pitch + x * PixelStep + 3];
|
||||
if(AlphaValue > 128)
|
||||
{
|
||||
aColors[0] += d[y * Pitch + x * 4 + 0];
|
||||
aColors[1] += d[y * Pitch + x * 4 + 1];
|
||||
aColors[2] += d[y * Pitch + x * 4 + 2];
|
||||
aColors[0] += d[y * Pitch + x * PixelStep + 0];
|
||||
aColors[1] += d[y * Pitch + x * PixelStep + 1];
|
||||
aColors[2] += d[y * Pitch + x * PixelStep + 2];
|
||||
}
|
||||
}
|
||||
if(aColors[0] != 0 && aColors[1] != 0 && aColors[2] != 0)
|
||||
|
@ -208,16 +215,13 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info)
|
|||
// get feet outline size
|
||||
CheckMetrics(Skin.m_Metrics.m_Feet, d, Pitch, FeetOutlineOffsetX, FeetOutlineOffsetY, FeetOutlineWidth, FeetOutlineHeight);
|
||||
|
||||
// create colorless version
|
||||
int Step = Info.m_Format == CImageInfo::FORMAT_RGBA ? 4 : 3;
|
||||
|
||||
// make the texture gray scale
|
||||
for(int i = 0; i < Info.m_Width * Info.m_Height; i++)
|
||||
{
|
||||
int v = (d[i * Step] + d[i * Step + 1] + d[i * Step + 2]) / 3;
|
||||
d[i * Step] = v;
|
||||
d[i * Step + 1] = v;
|
||||
d[i * Step + 2] = v;
|
||||
int v = (d[i * PixelStep] + d[i * PixelStep + 1] + d[i * PixelStep + 2]) / 3;
|
||||
d[i * PixelStep] = v;
|
||||
d[i * PixelStep + 1] = v;
|
||||
d[i * PixelStep + 2] = v;
|
||||
}
|
||||
|
||||
int Freq[256] = {0};
|
||||
|
@ -228,8 +232,8 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info)
|
|||
for(int y = 0; y < BodyHeight; y++)
|
||||
for(int x = 0; x < BodyWidth; x++)
|
||||
{
|
||||
if(d[y * Pitch + x * 4 + 3] > 128)
|
||||
Freq[d[y * Pitch + x * 4]]++;
|
||||
if(d[y * Pitch + x * PixelStep + 3] > 128)
|
||||
Freq[d[y * Pitch + x * PixelStep]]++;
|
||||
}
|
||||
|
||||
for(int i = 1; i < 256; i++)
|
||||
|
@ -244,7 +248,7 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info)
|
|||
for(int y = 0; y < BodyHeight; y++)
|
||||
for(int x = 0; x < BodyWidth; x++)
|
||||
{
|
||||
int v = d[y * Pitch + x * 4];
|
||||
int v = d[y * Pitch + x * PixelStep];
|
||||
if(v <= OrgWeight && OrgWeight == 0)
|
||||
v = 0;
|
||||
else if(v <= OrgWeight)
|
||||
|
@ -253,9 +257,9 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info)
|
|||
v = NewWeight;
|
||||
else
|
||||
v = (int)(((v - OrgWeight) / (float)InvOrgWeight) * InvNewWeight + NewWeight);
|
||||
d[y * Pitch + x * 4] = v;
|
||||
d[y * Pitch + x * 4 + 1] = v;
|
||||
d[y * Pitch + x * 4 + 2] = v;
|
||||
d[y * Pitch + x * PixelStep] = v;
|
||||
d[y * Pitch + x * PixelStep + 1] = v;
|
||||
d[y * Pitch + x * PixelStep + 2] = v;
|
||||
}
|
||||
|
||||
Skin.m_ColorableSkin.m_Body = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY]);
|
||||
|
|
|
@ -2747,7 +2747,9 @@ void CGameClient::LoadGameSkin(const char *pPath, bool AsDir)
|
|||
else
|
||||
LoadGameSkin(pPath, true);
|
||||
}
|
||||
else if(PngLoaded && Graphics()->CheckImageDivisibility(aPath, ImgInfo, g_pData->m_aSprites[SPRITE_HEALTH_FULL].m_pSet->m_Gridx, g_pData->m_aSprites[SPRITE_HEALTH_FULL].m_pSet->m_Gridy, true))
|
||||
else if(PngLoaded
|
||||
&& Graphics()->CheckImageDivisibility(aPath, ImgInfo, g_pData->m_aSprites[SPRITE_HEALTH_FULL].m_pSet->m_Gridx, g_pData->m_aSprites[SPRITE_HEALTH_FULL].m_pSet->m_Gridy, true)
|
||||
&& Graphics()->CheckImageFormatRGBA(aPath, ImgInfo))
|
||||
{
|
||||
m_GameSkin.m_SpriteHealthFull = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HEALTH_FULL]);
|
||||
m_GameSkin.m_SpriteHealthEmpty = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HEALTH_EMPTY]);
|
||||
|
@ -2900,7 +2902,9 @@ void CGameClient::LoadEmoticonsSkin(const char *pPath, bool AsDir)
|
|||
else
|
||||
LoadEmoticonsSkin(pPath, true);
|
||||
}
|
||||
else if(PngLoaded && Graphics()->CheckImageDivisibility(aPath, ImgInfo, g_pData->m_aSprites[SPRITE_OOP].m_pSet->m_Gridx, g_pData->m_aSprites[SPRITE_OOP].m_pSet->m_Gridy, true))
|
||||
else if(PngLoaded
|
||||
&& Graphics()->CheckImageDivisibility(aPath, ImgInfo, g_pData->m_aSprites[SPRITE_OOP].m_pSet->m_Gridx, g_pData->m_aSprites[SPRITE_OOP].m_pSet->m_Gridy, true)
|
||||
&& Graphics()->CheckImageFormatRGBA(aPath, ImgInfo))
|
||||
{
|
||||
for(int i = 0; i < 16; ++i)
|
||||
m_EmoticonsSkin.m_SpriteEmoticons[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_OOP + i]);
|
||||
|
@ -2954,7 +2958,9 @@ void CGameClient::LoadParticlesSkin(const char *pPath, bool AsDir)
|
|||
else
|
||||
LoadParticlesSkin(pPath, true);
|
||||
}
|
||||
else if(PngLoaded && Graphics()->CheckImageDivisibility(aPath, ImgInfo, g_pData->m_aSprites[SPRITE_PART_SLICE].m_pSet->m_Gridx, g_pData->m_aSprites[SPRITE_PART_SLICE].m_pSet->m_Gridy, true))
|
||||
else if(PngLoaded
|
||||
&& Graphics()->CheckImageDivisibility(aPath, ImgInfo, g_pData->m_aSprites[SPRITE_PART_SLICE].m_pSet->m_Gridx, g_pData->m_aSprites[SPRITE_PART_SLICE].m_pSet->m_Gridy, true)
|
||||
&& Graphics()->CheckImageFormatRGBA(aPath, ImgInfo))
|
||||
{
|
||||
m_ParticlesSkin.m_SpriteParticleSlice = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SLICE]);
|
||||
m_ParticlesSkin.m_SpriteParticleBall = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_BALL]);
|
||||
|
|
Loading…
Reference in a new issue