mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-13 03:28:19 +00:00
readded texture resampling
This commit is contained in:
parent
71af97a5e3
commit
df5ab998c2
|
@ -100,6 +100,41 @@ int CCommandProcessorFragment_OpenGL::TexFormatToOpenGLFormat(int TexFormat)
|
||||||
return GL_RGBA;
|
return GL_RGBA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char CCommandProcessorFragment_OpenGL::Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp)
|
||||||
|
{
|
||||||
|
int Value = 0;
|
||||||
|
for(int x = 0; x < ScaleW; x++)
|
||||||
|
for(int y = 0; y < ScaleH; y++)
|
||||||
|
Value += pData[((v+y)*w+(u+x))*Bpp+Offset];
|
||||||
|
return Value/(ScaleW*ScaleH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *CCommandProcessorFragment_OpenGL::Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData)
|
||||||
|
{
|
||||||
|
unsigned char *pTmpData;
|
||||||
|
int ScaleW = Width/NewWidth;
|
||||||
|
int ScaleH = Height/NewHeight;
|
||||||
|
|
||||||
|
int Bpp = 3;
|
||||||
|
if(Format == CCommandBuffer::TEXFORMAT_RGBA)
|
||||||
|
Bpp = 4;
|
||||||
|
|
||||||
|
pTmpData = (unsigned char *)mem_alloc(NewWidth*NewHeight*Bpp, 1);
|
||||||
|
|
||||||
|
int c = 0;
|
||||||
|
for(int y = 0; y < NewHeight; y++)
|
||||||
|
for(int x = 0; x < NewWidth; x++, c++)
|
||||||
|
{
|
||||||
|
pTmpData[c*Bpp] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 0, ScaleW, ScaleH, Bpp);
|
||||||
|
pTmpData[c*Bpp+1] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 1, ScaleW, ScaleH, Bpp);
|
||||||
|
pTmpData[c*Bpp+2] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 2, ScaleW, ScaleH, Bpp);
|
||||||
|
if(Bpp == 4)
|
||||||
|
pTmpData[c*Bpp+3] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 3, ScaleW, ScaleH, Bpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pTmpData;
|
||||||
|
}
|
||||||
|
|
||||||
void CCommandProcessorFragment_OpenGL::SetState(const CCommandBuffer::SState &State)
|
void CCommandProcessorFragment_OpenGL::SetState(const CCommandBuffer::SState &State)
|
||||||
{
|
{
|
||||||
// blend
|
// blend
|
||||||
|
@ -179,6 +214,39 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Destroy(const CCommandBuffer:
|
||||||
|
|
||||||
void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand)
|
void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand)
|
||||||
{
|
{
|
||||||
|
int Width = pCommand->m_Width;
|
||||||
|
int Height = pCommand->m_Height;
|
||||||
|
void *pTexData = pCommand->m_pData;
|
||||||
|
|
||||||
|
// resample if needed
|
||||||
|
if(pCommand->m_Format == CCommandBuffer::TEXFORMAT_RGBA || pCommand->m_Format == CCommandBuffer::TEXFORMAT_RGB)
|
||||||
|
{
|
||||||
|
int MaxTexSize;
|
||||||
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTexSize);
|
||||||
|
if(Width > MaxTexSize || Height > MaxTexSize)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Width>>=1;
|
||||||
|
Height>>=1;
|
||||||
|
}
|
||||||
|
while(Width > MaxTexSize || Height > MaxTexSize);
|
||||||
|
|
||||||
|
void *pTmpData = Rescale(pCommand->m_Width, pCommand->m_Height, Width, Height, pCommand->m_Format, static_cast<const unsigned char *>(pCommand->m_pData));
|
||||||
|
mem_free(pTexData);
|
||||||
|
pTexData = pTmpData;
|
||||||
|
}
|
||||||
|
else if(Width > 16 && Height > 16 && (pCommand->m_Flags&CCommandBuffer::TEXFLAG_QUALITY) == 0)
|
||||||
|
{
|
||||||
|
Width>>=1;
|
||||||
|
Height>>=1;
|
||||||
|
|
||||||
|
void *pTmpData = Rescale(pCommand->m_Width, pCommand->m_Height, Width, Height, pCommand->m_Format, static_cast<const unsigned char *>(pCommand->m_pData));
|
||||||
|
mem_free(pTexData);
|
||||||
|
pTexData = pTmpData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Oglformat = TexFormatToOpenGLFormat(pCommand->m_Format);
|
int Oglformat = TexFormatToOpenGLFormat(pCommand->m_Format);
|
||||||
int StoreOglformat = TexFormatToOpenGLFormat(pCommand->m_StoreFormat);
|
int StoreOglformat = TexFormatToOpenGLFormat(pCommand->m_StoreFormat);
|
||||||
|
|
||||||
|
@ -199,18 +267,16 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::
|
||||||
{
|
{
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, pCommand->m_Width, pCommand->m_Height, 0, Oglformat, GL_UNSIGNED_BYTE, pCommand->m_pData);
|
glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, Width, Height, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||||
gluBuild2DMipmaps(GL_TEXTURE_2D, StoreOglformat, pCommand->m_Width, pCommand->m_Height, Oglformat, GL_UNSIGNED_BYTE, pCommand->m_pData);
|
gluBuild2DMipmaps(GL_TEXTURE_2D, StoreOglformat, Width, Height, Oglformat, GL_UNSIGNED_BYTE, pTexData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate memory usage
|
// calculate memory usage
|
||||||
int Width = pCommand->m_Width;
|
|
||||||
int Height = pCommand->m_Height;
|
|
||||||
m_aTextures[pCommand->m_Slot].m_MemSize = Width*Height*pCommand->m_PixelSize;
|
m_aTextures[pCommand->m_Slot].m_MemSize = Width*Height*pCommand->m_PixelSize;
|
||||||
while(Width > 2 && Height > 2)
|
while(Width > 2 && Height > 2)
|
||||||
{
|
{
|
||||||
|
@ -220,7 +286,7 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::
|
||||||
}
|
}
|
||||||
*m_pTextureMemoryUsage += m_aTextures[pCommand->m_Slot].m_MemSize;
|
*m_pTextureMemoryUsage += m_aTextures[pCommand->m_Slot].m_MemSize;
|
||||||
|
|
||||||
mem_free(pCommand->m_pData);
|
mem_free(pTexData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCommandProcessorFragment_OpenGL::Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand)
|
void CCommandProcessorFragment_OpenGL::Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand)
|
||||||
|
|
|
@ -189,6 +189,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int TexFormatToOpenGLFormat(int TexFormat);
|
static int TexFormatToOpenGLFormat(int TexFormat);
|
||||||
|
static unsigned char Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp);
|
||||||
|
static void *Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData);
|
||||||
|
|
||||||
void SetState(const CCommandBuffer::SState &State);
|
void SetState(const CCommandBuffer::SState &State);
|
||||||
|
|
||||||
|
|
|
@ -107,41 +107,6 @@ void CGraphics_Threaded::Rotate4(const CCommandBuffer::SPoint &rCenter, CCommand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char CGraphics_Threaded::Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp)
|
|
||||||
{
|
|
||||||
int Value = 0;
|
|
||||||
for(int x = 0; x < ScaleW; x++)
|
|
||||||
for(int y = 0; y < ScaleH; y++)
|
|
||||||
Value += pData[((v+y)*w+(u+x))*Bpp+Offset];
|
|
||||||
return Value/(ScaleW*ScaleH);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *CGraphics_Threaded::Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData)
|
|
||||||
{
|
|
||||||
unsigned char *pTmpData;
|
|
||||||
int ScaleW = Width/NewWidth;
|
|
||||||
int ScaleH = Height/NewHeight;
|
|
||||||
|
|
||||||
int Bpp = 3;
|
|
||||||
if(Format == CImageInfo::FORMAT_RGBA)
|
|
||||||
Bpp = 4;
|
|
||||||
|
|
||||||
pTmpData = (unsigned char *)mem_alloc(NewWidth*NewHeight*Bpp, 1);
|
|
||||||
|
|
||||||
int c = 0;
|
|
||||||
for(int y = 0; y < NewHeight; y++)
|
|
||||||
for(int x = 0; x < NewWidth; x++, c++)
|
|
||||||
{
|
|
||||||
pTmpData[c*Bpp] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 0, ScaleW, ScaleH, Bpp);
|
|
||||||
pTmpData[c*Bpp+1] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 1, ScaleW, ScaleH, Bpp);
|
|
||||||
pTmpData[c*Bpp+2] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 2, ScaleW, ScaleH, Bpp);
|
|
||||||
if(Bpp == 4)
|
|
||||||
pTmpData[c*Bpp+3] = Sample(Width, Height, pData, x*ScaleW, y*ScaleH, 3, ScaleW, ScaleH, Bpp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pTmpData;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGraphics_Threaded::CGraphics_Threaded()
|
CGraphics_Threaded::CGraphics_Threaded()
|
||||||
{
|
{
|
||||||
m_State.m_ScreenTL.x = 0;
|
m_State.m_ScreenTL.x = 0;
|
||||||
|
@ -365,6 +330,8 @@ int CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const
|
||||||
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NOMIPMAPS;
|
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NOMIPMAPS;
|
||||||
if(g_Config.m_GfxTextureCompression)
|
if(g_Config.m_GfxTextureCompression)
|
||||||
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_COMPRESSED;
|
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_COMPRESSED;
|
||||||
|
if(g_Config.m_GfxTextureQuality || Flags&TEXLOAD_NORESAMPLE)
|
||||||
|
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_QUALITY;
|
||||||
|
|
||||||
// copy texture data
|
// copy texture data
|
||||||
int MemSize = Width*Height*Cmd.m_PixelSize;
|
int MemSize = Width*Height*Cmd.m_PixelSize;
|
||||||
|
|
|
@ -96,6 +96,7 @@ public:
|
||||||
|
|
||||||
TEXFLAG_NOMIPMAPS = 1,
|
TEXFLAG_NOMIPMAPS = 1,
|
||||||
TEXFLAG_COMPRESSED = 2,
|
TEXFLAG_COMPRESSED = 2,
|
||||||
|
TEXFLAG_QUALITY = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -363,9 +364,6 @@ class CGraphics_Threaded : public IEngineGraphics
|
||||||
void AddVertices(int Count);
|
void AddVertices(int Count);
|
||||||
void Rotate4(const CCommandBuffer::SPoint &rCenter, CCommandBuffer::SVertex *pPoints);
|
void Rotate4(const CCommandBuffer::SPoint &rCenter, CCommandBuffer::SVertex *pPoints);
|
||||||
|
|
||||||
static unsigned char Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp);
|
|
||||||
static unsigned char *Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData);
|
|
||||||
|
|
||||||
void KickCommandBuffer();
|
void KickCommandBuffer();
|
||||||
|
|
||||||
int IssueInit();
|
int IssueInit();
|
||||||
|
|
Loading…
Reference in a new issue