From 0a89ad4f301cccd78b9df4380f6d80133a6f1bdf Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Tue, 9 Dec 2025 10:57:10 +0800 Subject: [PATCH] [Feat] (MG_State/Texture): separate mipmap from TextureObjectBase --- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 5 +- MobileGL/MG_Backend/DirectGLES/Managers.cpp | 162 +++++++++--------- .../MG_Impl/GLImpl/Texture/GL_Texture.cpp | 85 +++++++-- .../FramebufferState/FramebufferObject.cpp | 4 +- .../GLState/TextureState/TextureEnum.h | 5 + .../GLState/TextureState/TextureObject.h | 40 ++--- .../TextureState/TextureObject2DCube.cpp | 2 +- .../TextureState/TextureObject2DCube.h | 2 +- 8 files changed, 189 insertions(+), 116 deletions(-) diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index e36da553..dfedf9be 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -750,7 +750,10 @@ namespace MobileGL::MG_Backend::DirectGLES { auto textureObject = bindingSlot.GetBoundObject(); textureObject->SetInternalFormat(mglInternalFormat); - textureObject->AllocateStorage(TextureUploadTarget::Texture2D, level, {{width, height, 1}, 0}); + MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), + "Texture object here should always be an object with mipmap"); + auto textureMipmapObject = static_cast(textureObject.get()); + textureMipmapObject->AllocateStorage(TextureUploadTarget::Texture2D, level, {{width, height, 1}, 0}); } void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index dc75d9c3..cf0168e3 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -289,58 +289,103 @@ namespace MobileGL::MG_Backend::DirectGLES { errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); - - const auto mipmapCount = stateTextureObject->GetMipmapLevelCount(); const auto baseSize = stateTextureObject->GetBaseSize(); StateTextureBasicInfo currentTextureInfo = { stateTextureObject->GetFormat(), static_cast(baseSize.x()), static_cast(baseSize.y()), - static_cast(baseSize.z()), mipmapCount}; + static_cast(baseSize.z()), 0}; + switch (stateTextureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + auto* textureMipmapObject = static_cast(stateTextureObject.get()); + const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount(); + currentTextureInfo.mipmapLevels = mipmapCount; - Bool needsRegeneration = !m_isInitialized || (currentTextureInfo != m_prevTextureInfo); + Bool needsRegeneration = !m_isInitialized || (currentTextureInfo != m_prevTextureInfo); - MGLOG_D("%s: Got texture info: %dx%dx%d, mips %d, format %s", __func__, baseSize.x(), baseSize.y(), - baseSize.z(), mipmapCount, - MG_Util::ConvertTextureInternalFormatToString(stateTextureObject->GetFormat()).c_str()); + MGLOG_D("%s: Got texture info: %dx%dx%d, mips %d, format %s", __func__, baseSize.x(), baseSize.y(), + baseSize.z(), mipmapCount, + MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str()); - if (needsRegeneration) { - MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u", - m_backendTextureId); + if (needsRegeneration) { + MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u", + m_backendTextureId); - // Regenerate all mipmap levels - GLenum glInternalFormat, glType, glFormat; - TextureImpl::GenerateTextureFormatInfo(stateTextureObject->GetFormat(), &glInternalFormat, &glType, - &glFormat); + // Regenerate all mipmap levels + GLenum glInternalFormat, glType, glFormat; + TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, &glType, + &glFormat); - const auto& uploadTargets = stateTextureObject->GetUploadTargets(); - for (auto uploadTarget : uploadTargets) { - for (SizeT level = 0; level < mipmapCount; ++level) { - auto levelTexelSize = stateTextureObject->GetMipmapTexelSize(uploadTarget, level); - auto levelByteSize = stateTextureObject->GetMipmapByteSize(uploadTarget, level); - bool levelDirty = stateTextureObject->IsStorageDirty(uploadTarget, 0); - auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget); - auto* pData = (levelDirty && levelByteSize != 0) - ? stateTextureObject->MapMipmapData(uploadTarget, level) - : nullptr; - MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p", __func__, - MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), level, - levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData); - BufferImpl::BackendBufferBindingProtector pixelUnpackProtector = - BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER); - errorLopper.Clear(); - MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - MG_External::GLES::glTexImage2D(glUploadTarget, static_cast(level), glInternalFormat, - static_cast(levelTexelSize.x()), - static_cast(levelTexelSize.y()), 0, glFormat, glType, - pData); + const auto& uploadTargets = textureMipmapObject->GetUploadTargets(); + for (auto uploadTarget : uploadTargets) { + for (SizeT level = 0; level < mipmapCount; ++level) { + auto levelTexelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level); + auto levelByteSize = textureMipmapObject->GetMipmapByteSize(uploadTarget, level); + bool levelDirty = textureMipmapObject->IsStorageDirty(uploadTarget, 0); + auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget); + auto* pData = (levelDirty && levelByteSize != 0) + ? textureMipmapObject->MapMipmapData(uploadTarget, level) + : nullptr; + MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p", __func__, + MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), level, + levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData); + BufferImpl::BackendBufferBindingProtector pixelUnpackProtector = + BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER); + errorLopper.Clear(); + MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + MG_External::GLES::glTexImage2D(glUploadTarget, static_cast(level), glInternalFormat, + static_cast(levelTexelSize.x()), + static_cast(levelTexelSize.y()), 0, glFormat, glType, + pData); - // TODO: handle more texture types + // TODO: handle more texture types - MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level, m_backendTextureId); - stateTextureObject->MarkStorageDirty(uploadTarget, level, false); + MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level, m_backendTextureId); + textureMipmapObject->MarkStorageDirty(uploadTarget, level, false); + } + } + + m_isInitialized = true; } - } - m_isInitialized = true; + { // Update all dirty mipmap levels + const auto mipmapCount = textureMipmapObject->GetMipmapLevelCount(); + GLenum glInternalFormat, glType, glFormat; + TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, &glType, + &glFormat); + const auto& uploadTargets = textureMipmapObject->GetUploadTargets(); + for (auto uploadTarget : uploadTargets) { + for (SizeT level = 0; level < mipmapCount; ++level) { + if (!textureMipmapObject->IsStorageDirty(uploadTarget, level)) { + continue; + } + + auto byteSize = textureMipmapObject->GetMipmapByteSize(uploadTarget, level); + if (byteSize == 0) { + MGLOG_W("Mipmap level %d has no data, skipping update.", level); + continue; + } + + auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget); + + BufferImpl::BackendBufferBindingProtector pixelUnpackProtector = + BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER); + MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { + MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, + MG_Util::ConvertGLEnumToString(err).c_str()); + }); + auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level); + MG_External::GLES::glTexSubImage2D(glUploadTarget, static_cast(level), 0, 0, + static_cast(texelSize.x()), + static_cast(texelSize.y()), glFormat, glType, + textureMipmapObject->MapMipmapData(uploadTarget, level)); + + textureMipmapObject->MarkStorageDirty(uploadTarget, level, false); + } + } + } + break; + } + default: THROW_UNIMPL_EXCEPTION; } { // Update built-in sampler parameters @@ -448,43 +493,6 @@ namespace MobileGL::MG_Backend::DirectGLES { } } - { // Update all dirty mipmap levels - const auto mipmapCount = stateTextureObject->GetMipmapLevelCount(); - GLenum glInternalFormat, glType, glFormat; - TextureImpl::GenerateTextureFormatInfo(stateTextureObject->GetFormat(), &glInternalFormat, &glType, - &glFormat); - const auto& uploadTargets = stateTextureObject->GetUploadTargets(); - for (auto uploadTarget : uploadTargets) { - for (SizeT level = 0; level < mipmapCount; ++level) { - if (!stateTextureObject->IsStorageDirty(uploadTarget, level)) { - continue; - } - - auto byteSize = stateTextureObject->GetMipmapByteSize(uploadTarget, level); - if (byteSize == 0) { - MGLOG_W("Mipmap level %d has no data, skipping update.", level); - continue; - } - - auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget); - - BufferImpl::BackendBufferBindingProtector pixelUnpackProtector = - BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER); - MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { - MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, - MG_Util::ConvertGLEnumToString(err).c_str()); - }); - auto texelSize = stateTextureObject->GetMipmapTexelSize(uploadTarget, level); - MG_External::GLES::glTexSubImage2D(glUploadTarget, static_cast(level), 0, 0, - static_cast(texelSize.x()), - static_cast(texelSize.y()), glFormat, glType, - stateTextureObject->MapMipmapData(uploadTarget, level)); - - stateTextureObject->MarkStorageDirty(uploadTarget, level, false); - } - } - } errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) { MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); diff --git a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp index 811c4fc5..baea89f0 100644 --- a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp +++ b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp @@ -64,9 +64,14 @@ namespace MobileGL { if (!TextureImpl::ValidateTextureSubImageOffsets(textureObject, xoffset, width, yoffset, height)) return; // ======================= Processing ================================ - // auto& mipmap = textureObject->GetMipmap(level); - // Vector& data = mipmap.data; - auto texelSize = textureObject->GetMipmapTexelSize(textureUploadingTarget, level); + // Texture object here should always be an object with mipmap + // Assert this for extra safety. + // This should automatically compiled out in release, + // so that we don't take the perf hit of dyn-cast. + MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), + "Texture object here should always be an object with mipmap"); + auto textureMipmapObject = static_cast(textureObject.get()); + auto texelSize = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level); SizeT imageSize = 0; const SizeT bytesPerPixel = MG_Util::GetInputBytesPerPixel(textureInternalFormat, texturePixelDataType); @@ -107,7 +112,7 @@ namespace MobileGL { } const auto* srcData = static_cast(processedPixels); - Uint8* destData = (Uint8*)textureObject->MapMipmapData(textureUploadingTarget, level); + Uint8* destData = (Uint8*)textureMipmapObject->MapMipmapData(textureUploadingTarget, level); // No allocation should be done here // if (data.empty()) { // SizeT totalSize = texelSize.x() * texelSize.y() * bytesPerPixel; @@ -122,7 +127,7 @@ namespace MobileGL { free(processedPixels); - textureObject->MarkStorageDirty(textureUploadingTarget, level, true); + textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true); // mipmap.dirty = true; // mipmap.hasData = true; } @@ -398,8 +403,13 @@ namespace MobileGL { reinterpret_cast(pixels); } + MOBILEGL_ASSERT(nullptr != dynamic_cast(textureObject.get()), + "Texture object here should always be an object with mipmap"); + auto textureMipmapObject = static_cast(textureObject.get()); + + // Allocate in TextureObject - textureObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, totalBytes}); + textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, totalBytes}); if (!originalPixels) { MGLOG_D("TexImage2D_State: No input pixel and no PBO bound, no pixel transfer"); @@ -420,7 +430,7 @@ namespace MobileGL { const SizeT copySize = std::min(imageSize, totalBytes); DataPtr texelInput{processedPixels, copySize}; - textureObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput); + textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput); } free(processedPixels); @@ -648,17 +658,41 @@ namespace MobileGL { switch (pname) { case GL_TEXTURE_WIDTH: if (params) { - *params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).x(); + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } break; case GL_TEXTURE_HEIGHT: if (params) { - *params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).y(); + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } break; case GL_TEXTURE_DEPTH: if (params) { - *params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).z(); + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } break; case GL_TEXTURE_INTERNAL_FORMAT: @@ -714,18 +748,41 @@ namespace MobileGL { switch (pname) { case GL_TEXTURE_WIDTH: if (params) { - *params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).x(); + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } break; case GL_TEXTURE_HEIGHT: if (params) { - *params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).y(); + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } break; case GL_TEXTURE_DEPTH: if (params) { - *params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).z(); - } + switch (textureObject->GetStorageType()) { + case TextureStorageType::Mipmap: { + const auto textureMipmapObject = static_cast(textureObject.get()); + *params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z(); + break; + } + default: + THROW_UNIMPL_EXCEPTION; + } } break; case GL_TEXTURE_INTERNAL_FORMAT: if (params) { diff --git a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp index b5c91dcf..68482117 100644 --- a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp +++ b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp @@ -52,7 +52,9 @@ namespace MobileGL { IntVec3 FramebufferAttachment::GetSize() const { if (IsTexture()) { // TODO: get correct upload target - return m_texture->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel); + MOBILEGL_ASSERT(nullptr != dynamic_cast(m_texture.get()), "Texture object here should always be an object with mipmap"); + auto textureMipmapObject = static_cast(m_texture.get()); + return textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel); } else if (IsRenderbuffer()) { // TODO } diff --git a/MobileGL/MG_State/GLState/TextureState/TextureEnum.h b/MobileGL/MG_State/GLState/TextureState/TextureEnum.h index c71517ee..25d75b13 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureEnum.h +++ b/MobileGL/MG_State/GLState/TextureState/TextureEnum.h @@ -49,6 +49,11 @@ namespace MobileGL { Unknown = -1 }; + enum class TextureStorageType { + Mipmap, + Buffer + }; + enum class TextureInputFormat { Red, RG, diff --git a/MobileGL/MG_State/GLState/TextureState/TextureObject.h b/MobileGL/MG_State/GLState/TextureState/TextureObject.h index e7c5854b..eecfefe8 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureObject.h +++ b/MobileGL/MG_State/GLState/TextureState/TextureObject.h @@ -14,14 +14,7 @@ namespace MobileGL { using TargetEnum = TextureTarget; virtual ~ITextureObject() = default; - virtual Uint GetMipmapLevelCount() const = 0; - virtual const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const = 0; - virtual const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const = 0; - virtual void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) = 0; - virtual void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0; - virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0; - virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty) = 0; - virtual bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0; + virtual TextureStorageType GetStorageType() const = 0; virtual TextureInternalFormat GetFormat() const = 0; virtual TextureTarget GetTarget() const = 0; @@ -49,17 +42,6 @@ namespace MobileGL { TextureObjectBase(TextureTarget target, Uint externalIndex); virtual ~TextureObjectBase() = default; - // Mipmap ops - // Uint GetMipmapLevelCount() const = 0; - // const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const = - // 0; const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const = - // 0; void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, - // MipmapInput input) = 0; void UpdateMipmapSubData(TextureUploadTarget uploadTarget, - // Uint mipmapLevel, DataPtr input) = 0; void* MapMipmapData(TextureUploadTarget - // uploadTarget, Uint mipmapLevel) = 0; void MarkStorageDirty(TextureUploadTarget - // uploadTarget, Uint mipmapLevel, bool dirty) = 0; bool - // IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0; - TextureInternalFormat GetFormat() const override; TextureTarget GetTarget() const override; IntVec3 GetBaseSize() const override; @@ -87,10 +69,26 @@ namespace MobileGL { UintVec2 m_levelRange = {0, 1000}; }; - class TextureObjectWithOneMipmap : public TextureObjectBase { + class TextureMipmapObject : public TextureObjectBase { + public: + TextureMipmapObject(TextureTarget target, Uint externalIndex): TextureObjectBase(target, externalIndex) {} + + TextureStorageType GetStorageType() const override { return TextureStorageType::Mipmap; } + + virtual Uint GetMipmapLevelCount() const = 0; + virtual const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const = 0; + virtual const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const = 0; + virtual void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) = 0; + virtual void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0; + virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0; + virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty) = 0; + virtual bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0; + }; + + class TextureObjectWithOneMipmap : public TextureMipmapObject { public: TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex) - : TextureObjectBase(target, externalIndex) {} + : TextureMipmapObject(target, externalIndex) {} virtual ~TextureObjectWithOneMipmap() = default; Uint GetMipmapLevelCount() const override; diff --git a/MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.cpp b/MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.cpp index 1d10506c..6521138e 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.cpp +++ b/MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.cpp @@ -4,7 +4,7 @@ namespace MobileGL { namespace MG_State { namespace GLState { TextureObject2DCube::TextureObject2DCube(Uint externalIndex) - : TextureObjectBase(TextureTarget::TextureCubeMap, externalIndex) {} + : TextureMipmapObject(TextureTarget::TextureCubeMap, externalIndex) {} Uint TextureObject2DCube::GetMipmapLevelCount() const { return m_textureStorage.GetLevelCount(); diff --git a/MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.h b/MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.h index a5c6207e..3c31b125 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.h +++ b/MobileGL/MG_State/GLState/TextureState/TextureObject2DCube.h @@ -4,7 +4,7 @@ namespace MobileGL { namespace MG_State { namespace GLState { - class TextureObject2DCube : public TextureObjectBase { + class TextureObject2DCube : public TextureMipmapObject { public: explicit TextureObject2DCube(Uint externalIndex);