From 031f677486e6d704fc3ea70699365cd04f16d903 Mon Sep 17 00:00:00 2001 From: rogerman Date: Mon, 28 Nov 2016 13:55:46 -0800 Subject: [PATCH] OpenGL Renderer: Refactor and use the same coding style for texture loading as SoftRasterizer. --- desmume/src/OGLRender.cpp | 404 +++++++++++++++++----------------- desmume/src/OGLRender.h | 22 +- desmume/src/OGLRender_3_2.cpp | 121 ++-------- desmume/src/render3D.cpp | 43 +--- desmume/src/render3D.h | 5 +- 5 files changed, 241 insertions(+), 354 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index e758bb588..341bbb0c9 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -30,6 +30,9 @@ #include "NDSSystem.h" #include "texcache.h" +#include "./filter/filter.h" +#include "./filter/xbrz.h" + #ifdef ENABLE_SSE2 #include #include "./utils/colorspacehandler/colorspacehandler_SSE2.h" @@ -636,21 +639,24 @@ static void OGLGetDriverVersion(const char *oglVersionString, } } -OpenGLTexture::OpenGLTexture() -{ - _cacheSize = GetUnpackSizeUsingFormat(TexFormat_32bpp); - _invSizeS = 0.0f; - _invSizeT = 0.0f; - - glGenTextures(1, &_texID); -} - OpenGLTexture::OpenGLTexture(u32 texAttributes, u32 palAttributes) : TextureStore(texAttributes, palAttributes) { _cacheSize = GetUnpackSizeUsingFormat(TexFormat_32bpp); _invSizeS = 1.0f / (float)_sizeS; _invSizeT = 1.0f / (float)_sizeT; + _useDeposterize = false; + _scalingFactor = 1; + + memset(&_deposterizeSrcSurface, 0, sizeof(_deposterizeSrcSurface)); + memset(&_deposterizeDstSurface, 0, sizeof(_deposterizeDstSurface)); + + _deposterizeSrcSurface.Width = _deposterizeDstSurface.Width = _sizeS; + _deposterizeSrcSurface.Height = _deposterizeDstSurface.Height = _sizeT; + _deposterizeSrcSurface.Pitch = _deposterizeDstSurface.Pitch = 1; + + _upscaleBuffer = NULL; + glGenTextures(1, &_texID); } @@ -659,6 +665,110 @@ OpenGLTexture::~OpenGLTexture() glDeleteTextures(1, &this->_texID); } +template +void OpenGLTexture::_Upscale() +{ + if ( (SCALEFACTOR != 2) && (SCALEFACTOR != 4) ) + { + return; + } + + u32 *src = (u32 *)this->_deposterizeSrcSurface.Surface; + + if ( (this->_packFormat == TEXMODE_A3I5) || (this->_packFormat == TEXMODE_A5I3) ) + { + xbrz::scale(src, this->_upscaleBuffer, this->_sizeS, this->_sizeT); + } + else + { + xbrz::scale(src, this->_upscaleBuffer, this->_sizeS, this->_sizeT); + } +} + +void OpenGLTexture::Load(bool isNewTexture) +{ + u32 *textureSrc = (u32 *)this->_deposterizeSrcSurface.Surface; + + this->Unpack(textureSrc); + + if (this->_useDeposterize) + { + RenderDeposterize(this->_deposterizeSrcSurface, this->_deposterizeDstSurface); + } + + glBindTexture(GL_TEXTURE_2D, this->_texID); + + switch (this->_scalingFactor) + { + case 1: + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + if (isNewTexture) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_sizeS, this->_sizeT, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); + } + else + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_sizeS, this->_sizeT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); + } + break; + } + + case 2: + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + + this->_Upscale<2>(); + + if (isNewTexture) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_sizeS*2, this->_sizeT*2, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_upscaleBuffer); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, this->_sizeS*1, this->_sizeT*1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); + } + else + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_sizeS*2, this->_sizeT*2, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_upscaleBuffer); + glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, this->_sizeS*1, this->_sizeT*1, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); + } + break; + } + + case 4: + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); + + this->_Upscale<4>(); + + if (isNewTexture) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_sizeS*4, this->_sizeT*4, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_upscaleBuffer); + + this->_Upscale<2>(); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, this->_sizeS*2, this->_sizeT*2, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_upscaleBuffer); + + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, this->_sizeS*1, this->_sizeT*1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); + } + else + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, this->_sizeS*4, this->_sizeT*4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_upscaleBuffer); + + this->_Upscale<2>(); + glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, this->_sizeS*2, this->_sizeT*2, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_upscaleBuffer); + + glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, this->_sizeS*1, this->_sizeT*1, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); + } + break; + } + + default: + break; + } +} + GLuint OpenGLTexture::GetID() const { return this->_texID; @@ -674,6 +784,42 @@ GLfloat OpenGLTexture::GetInvHeight() const return this->_invSizeT; } +bool OpenGLTexture::IsUsingDeposterize() const +{ + return this->_useDeposterize; +} + +void OpenGLTexture::SetUseDeposterize(bool willDeposterize) +{ + this->_useDeposterize = willDeposterize; +} + +size_t OpenGLTexture::GetScalingFactor() const +{ + return this->_scalingFactor; +} + +void OpenGLTexture::SetScalingFactor(size_t scalingFactor) +{ + this->_scalingFactor = ( (scalingFactor == 2) || (scalingFactor == 4) ) ? scalingFactor : 1; +} + +void OpenGLTexture::SetUnpackBuffer(void *unpackBuffer) +{ + this->_deposterizeSrcSurface.Surface = (unsigned char *)unpackBuffer; +} + +void OpenGLTexture::SetDeposterizeBuffer(void *dstBuffer, void *workingBuffer) +{ + this->_deposterizeDstSurface.Surface = (unsigned char *)dstBuffer; + this->_deposterizeDstSurface.workingSurface[0] = (unsigned char *)workingBuffer; +} + +void OpenGLTexture::SetUpscalingBuffer(void *upscaleBuffer) +{ + this->_upscaleBuffer = (u32 *)upscaleBuffer; +} + template static Render3D* OpenGLRendererCreate() { @@ -2955,9 +3101,20 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT if (isNewTexture) { theTexture = new OpenGLTexture(thePoly.texParam, thePoly.texPalette); + theTexture->SetUnpackBuffer(this->_workingTextureUnpackBuffer); + theTexture->SetDeposterizeBuffer(this->_workingTextureUnpackBuffer, this->_textureDeposterizeDstSurface.workingSurface[0]); + theTexture->SetUpscalingBuffer(this->_textureUpscaleBuffer); + texCache.Add(theTexture); } + if (theTexture->IsLoadNeeded()) + { + theTexture->SetUseDeposterize(this->_textureDeposterize); + theTexture->SetScalingFactor(this->_textureScalingFactor); + theTexture->Load(isNewTexture); + } + const NDSTextureFormat packFormat = theTexture->GetPackFormat(); // Enable textures if they weren't already enabled @@ -2979,106 +3136,17 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE)); - if (theTexture->IsLoadNeeded()) + if (this->_textureSmooth) { - theTexture->Load(this->_workingTextureUnpackBuffer); - - const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer; - size_t texWidth = theTexture->GetWidth(); - size_t texHeight = theTexture->GetHeight(); - - if (this->_textureDeposterizeDstSurface.Surface != NULL) - { - this->TextureDeposterize(textureSrc, texWidth, texHeight); - textureSrc = (u32 *)this->_textureDeposterizeDstSurface.Surface; - } - - switch (this->_textureScalingFactor) - { - case 1: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - case 2: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - case 4: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); - - this->TextureUpscale<4>(packFormat, textureSrc, texWidth, texHeight); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - texWidth = theTexture->GetWidth(); - texHeight = theTexture->GetHeight(); - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - texWidth = theTexture->GetWidth(); - texHeight = theTexture->GetHeight(); - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - default: - break; - } - - if (this->_textureSmooth) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); - } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); } theTexture->ResetCacheAge(); @@ -4632,9 +4700,20 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT if (isNewTexture) { theTexture = new OpenGLTexture(thePoly.texParam, thePoly.texPalette); + theTexture->SetUnpackBuffer(this->_workingTextureUnpackBuffer); + theTexture->SetDeposterizeBuffer(this->_workingTextureUnpackBuffer, this->_textureDeposterizeDstSurface.workingSurface[0]); + theTexture->SetUpscalingBuffer(this->_textureUpscaleBuffer); + texCache.Add(theTexture); } + if (theTexture->IsLoadNeeded()) + { + theTexture->SetUseDeposterize(this->_textureDeposterize); + theTexture->SetScalingFactor(this->_textureScalingFactor); + theTexture->Load(isNewTexture); + } + const NDSTextureFormat packFormat = theTexture->GetPackFormat(); glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE); @@ -4645,106 +4724,17 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); - if (theTexture->IsLoadNeeded()) + if (this->_textureSmooth) { - theTexture->Load(this->_workingTextureUnpackBuffer); - - const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer; - size_t texWidth = theTexture->GetWidth(); - size_t texHeight = theTexture->GetHeight(); - - if (this->_textureDeposterizeDstSurface.Surface != NULL) - { - this->TextureDeposterize(textureSrc, texWidth, texHeight); - textureSrc = (u32 *)this->_textureDeposterizeDstSurface.Surface; - } - - switch (this->_textureScalingFactor) - { - case 1: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - case 2: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - case 4: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); - - this->TextureUpscale<4>(packFormat, textureSrc, texWidth, texHeight); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - texWidth = theTexture->GetWidth(); - texHeight = theTexture->GetHeight(); - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - texWidth = theTexture->GetWidth(); - texHeight = theTexture->GetHeight(); - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - default: - break; - } - - if (this->_textureSmooth) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); - } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); } theTexture->ResetCacheAge(); diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 976a811d0..f895d9ca3 100644 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -562,14 +562,34 @@ private: GLfloat _invSizeS; GLfloat _invSizeT; + bool _useDeposterize; + size_t _scalingFactor; + + SSurface _deposterizeSrcSurface; + SSurface _deposterizeDstSurface; + u32 *_upscaleBuffer; + + template void _Upscale(); + public: - OpenGLTexture(); OpenGLTexture(u32 texAttributes, u32 palAttributes); virtual ~OpenGLTexture(); + virtual void Load(bool isNewTexture); + GLuint GetID() const; GLfloat GetInvWidth() const; GLfloat GetInvHeight() const; + + bool IsUsingDeposterize() const; + void SetUseDeposterize(bool willDeposterize); + + size_t GetScalingFactor() const; + void SetScalingFactor(size_t scalingFactor); + + void SetUnpackBuffer(void *unpackBuffer); + void SetDeposterizeBuffer(void *dstBuffer, void *workingBuffer); + void SetUpscalingBuffer(void *upscaleBuffer); }; #if defined(ENABLE_SSE2) diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index e4a0f7226..45e0979a1 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -1699,114 +1699,35 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT if (isNewTexture) { theTexture = new OpenGLTexture(thePoly.texParam, thePoly.texPalette); + theTexture->SetUnpackBuffer(this->_workingTextureUnpackBuffer); + theTexture->SetDeposterizeBuffer(this->_workingTextureUnpackBuffer, this->_textureDeposterizeDstSurface.workingSurface[0]); + theTexture->SetUpscalingBuffer(this->_textureUpscaleBuffer); + texCache.Add(theTexture); } + if (theTexture->IsLoadNeeded()) + { + theTexture->SetUseDeposterize(this->_textureDeposterize); + theTexture->SetScalingFactor(this->_textureScalingFactor); + theTexture->Load(isNewTexture); + } + glBindTexture(GL_TEXTURE_2D, theTexture->GetID()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); - if (theTexture->IsLoadNeeded()) + if (this->_textureSmooth) { - theTexture->Load(this->_workingTextureUnpackBuffer); - - const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer; - const NDSTextureFormat packFormat = theTexture->GetPackFormat(); - size_t texWidth = theTexture->GetWidth(); - size_t texHeight = theTexture->GetHeight(); - - if (this->_textureDeposterizeDstSurface.Surface != NULL) - { - this->TextureDeposterize(textureSrc, texWidth, texHeight); - textureSrc = (u32 *)this->_textureDeposterizeDstSurface.Surface; - } - - switch (this->_textureScalingFactor) - { - case 1: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - case 2: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - case 4: - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); - - this->TextureUpscale<4>(packFormat, textureSrc, texWidth, texHeight); - - if (isNewTexture) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - texWidth = theTexture->GetWidth(); - texHeight = theTexture->GetHeight(); - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - else - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - texWidth = theTexture->GetWidth(); - texHeight = theTexture->GetHeight(); - this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight); - glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer); - - glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc); - } - break; - } - - default: - break; - } - - if (this->_textureSmooth) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); - } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (this->_textureScalingFactor > 1) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->_deviceInfo.maxAnisotropy); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); } theTexture->ResetCacheAge(); diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index faa8cbd4e..bda3cbfd4 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -382,12 +382,7 @@ void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDep needTexCacheReset = true; } - if (willSmooth != this->_textureSmooth) - { - this->_textureSmooth = willSmooth; - - needTexCacheReset = true; - } + this->_textureSmooth = willSmooth; if (needTexCacheReset) { @@ -395,39 +390,6 @@ void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDep } } -Render3DError Render3D::TextureDeposterize(const u32 *src, const size_t srcTexWidth, const size_t srcTexHeight) -{ - this->_textureDeposterizeSrcSurface.Width = this->_textureDeposterizeDstSurface.Width = srcTexWidth; - this->_textureDeposterizeSrcSurface.Height = this->_textureDeposterizeDstSurface.Height = srcTexHeight; - this->_textureDeposterizeSrcSurface.Surface = (unsigned char *)src; - - RenderDeposterize(this->_textureDeposterizeSrcSurface, this->_textureDeposterizeDstSurface); - - return RENDER3DERROR_NOERR; -} - -template -Render3DError Render3D::TextureUpscale(const NDSTextureFormat texFormat, const u32 *src, size_t &outTexWidth, size_t &outTexHeight) -{ - if ( (SCALEFACTOR != 2) && (SCALEFACTOR != 4) ) - { - return RENDER3DERROR_NOERR; - } - - if (texFormat == TEXMODE_A3I5 || texFormat == TEXMODE_A5I3) - { - xbrz::scale(src, this->_textureUpscaleBuffer, outTexWidth, outTexHeight); - } - else - { - xbrz::scale(src, this->_textureUpscaleBuffer, outTexWidth, outTexHeight); - } - - outTexWidth *= SCALEFACTOR; - outTexHeight *= SCALEFACTOR; - return RENDER3DERROR_NOERR; -} - Render3DError Render3D::BeginRender(const GFX3D &engine) { return RENDER3DERROR_NOERR; @@ -851,6 +813,3 @@ Render3DError Render3D_SSE2::ClearFramebuffer(const GFX3D_State &renderState) } #endif // ENABLE_SSE2 - -template Render3DError Render3D::TextureUpscale<2>(const NDSTextureFormat texFormat, const u32 *src, size_t &outTexWidth, size_t &outTexHeight); -template Render3DError Render3D::TextureUpscale<4>(const NDSTextureFormat texFormat, const u32 *src, size_t &outTexWidth, size_t &outTexHeight); diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index 6774b64e0..45d75e370 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -142,10 +142,7 @@ protected: CACHE_ALIGN u32 clearImageDepthBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; CACHE_ALIGN u8 clearImageFogBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; CACHE_ALIGN u8 clearImagePolyIDBuffer[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT]; - - Render3DError TextureDeposterize(const u32 *src, const size_t srcTexWidth, const size_t srcTexHeight); - template Render3DError TextureUpscale(const NDSTextureFormat texFormat, const u32 *src, size_t &outTexWidth, size_t &outTexHeight); - + virtual Render3DError BeginRender(const GFX3D &engine); virtual Render3DError RenderGeometry(const GFX3D_State &renderState, const POLYLIST *polyList, const INDEXLIST *indexList); virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias);