mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 18:18:18 +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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
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 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_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
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
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
|
||||
int Width = pCommand->m_Width;
|
||||
int Height = pCommand->m_Height;
|
||||
m_aTextures[pCommand->m_Slot].m_MemSize = Width*Height*pCommand->m_PixelSize;
|
||||
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;
|
||||
|
||||
mem_free(pCommand->m_pData);
|
||||
mem_free(pTexData);
|
||||
}
|
||||
|
||||
void CCommandProcessorFragment_OpenGL::Cmd_Clear(const CCommandBuffer::SCommand_Clear *pCommand)
|
||||
|
|
|
@ -189,6 +189,8 @@ public:
|
|||
|
||||
private:
|
||||
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);
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
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;
|
||||
if(g_Config.m_GfxTextureCompression)
|
||||
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_COMPRESSED;
|
||||
if(g_Config.m_GfxTextureQuality || Flags&TEXLOAD_NORESAMPLE)
|
||||
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_QUALITY;
|
||||
|
||||
// copy texture data
|
||||
int MemSize = Width*Height*Cmd.m_PixelSize;
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
|
||||
TEXFLAG_NOMIPMAPS = 1,
|
||||
TEXFLAG_COMPRESSED = 2,
|
||||
TEXFLAG_QUALITY = 4,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -363,9 +364,6 @@ class CGraphics_Threaded : public IEngineGraphics
|
|||
void AddVertices(int Count);
|
||||
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();
|
||||
|
||||
int IssueInit();
|
||||
|
|
Loading…
Reference in a new issue