readded texture resampling

This commit is contained in:
oy 2012-10-07 11:22:49 +02:00
parent 71af97a5e3
commit df5ab998c2
4 changed files with 76 additions and 43 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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();