mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Feat] (MG_State/Texture): separate mipmap from TextureObjectBase
This commit is contained in:
@@ -750,7 +750,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
auto textureObject = bindingSlot.GetBoundObject();
|
auto textureObject = bindingSlot.GetBoundObject();
|
||||||
|
|
||||||
textureObject->SetInternalFormat(mglInternalFormat);
|
textureObject->SetInternalFormat(mglInternalFormat);
|
||||||
textureObject->AllocateStorage(TextureUploadTarget::Texture2D, level, {{width, height, 1}, 0});
|
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get()),
|
||||||
|
"Texture object here should always be an object with mipmap");
|
||||||
|
auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(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,
|
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
|
||||||
|
|||||||
@@ -289,58 +289,103 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
|
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());
|
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();
|
const auto baseSize = stateTextureObject->GetBaseSize();
|
||||||
StateTextureBasicInfo currentTextureInfo = {
|
StateTextureBasicInfo currentTextureInfo = {
|
||||||
stateTextureObject->GetFormat(), static_cast<SizeT>(baseSize.x()), static_cast<SizeT>(baseSize.y()),
|
stateTextureObject->GetFormat(), static_cast<SizeT>(baseSize.x()), static_cast<SizeT>(baseSize.y()),
|
||||||
static_cast<SizeT>(baseSize.z()), mipmapCount};
|
static_cast<SizeT>(baseSize.z()), 0};
|
||||||
|
switch (stateTextureObject->GetStorageType()) {
|
||||||
|
case TextureStorageType::Mipmap: {
|
||||||
|
auto* textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(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(),
|
MGLOG_D("%s: Got texture info: %dx%dx%d, mips %d, format %s", __func__, baseSize.x(), baseSize.y(),
|
||||||
baseSize.z(), mipmapCount,
|
baseSize.z(), mipmapCount,
|
||||||
MG_Util::ConvertTextureInternalFormatToString(stateTextureObject->GetFormat()).c_str());
|
MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str());
|
||||||
|
|
||||||
if (needsRegeneration) {
|
if (needsRegeneration) {
|
||||||
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u",
|
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u",
|
||||||
m_backendTextureId);
|
m_backendTextureId);
|
||||||
|
|
||||||
// Regenerate all mipmap levels
|
// Regenerate all mipmap levels
|
||||||
GLenum glInternalFormat, glType, glFormat;
|
GLenum glInternalFormat, glType, glFormat;
|
||||||
TextureImpl::GenerateTextureFormatInfo(stateTextureObject->GetFormat(), &glInternalFormat, &glType,
|
TextureImpl::GenerateTextureFormatInfo(textureMipmapObject->GetFormat(), &glInternalFormat, &glType,
|
||||||
&glFormat);
|
&glFormat);
|
||||||
|
|
||||||
const auto& uploadTargets = stateTextureObject->GetUploadTargets();
|
const auto& uploadTargets = textureMipmapObject->GetUploadTargets();
|
||||||
for (auto uploadTarget : uploadTargets) {
|
for (auto uploadTarget : uploadTargets) {
|
||||||
for (SizeT level = 0; level < mipmapCount; ++level) {
|
for (SizeT level = 0; level < mipmapCount; ++level) {
|
||||||
auto levelTexelSize = stateTextureObject->GetMipmapTexelSize(uploadTarget, level);
|
auto levelTexelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level);
|
||||||
auto levelByteSize = stateTextureObject->GetMipmapByteSize(uploadTarget, level);
|
auto levelByteSize = textureMipmapObject->GetMipmapByteSize(uploadTarget, level);
|
||||||
bool levelDirty = stateTextureObject->IsStorageDirty(uploadTarget, 0);
|
bool levelDirty = textureMipmapObject->IsStorageDirty(uploadTarget, 0);
|
||||||
auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget);
|
auto glUploadTarget = MG_Util::ConvertTextureUploadTargetToGLEnum(uploadTarget);
|
||||||
auto* pData = (levelDirty && levelByteSize != 0)
|
auto* pData = (levelDirty && levelByteSize != 0)
|
||||||
? stateTextureObject->MapMipmapData(uploadTarget, level)
|
? textureMipmapObject->MapMipmapData(uploadTarget, level)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p", __func__,
|
MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p", __func__,
|
||||||
MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), level,
|
MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), level,
|
||||||
levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData);
|
levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData);
|
||||||
BufferImpl::BackendBufferBindingProtector pixelUnpackProtector =
|
BufferImpl::BackendBufferBindingProtector pixelUnpackProtector =
|
||||||
BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER);
|
BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER);
|
||||||
errorLopper.Clear();
|
errorLopper.Clear();
|
||||||
MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
MG_External::GLES::glTexImage2D(glUploadTarget, static_cast<GLint>(level), glInternalFormat,
|
MG_External::GLES::glTexImage2D(glUploadTarget, static_cast<GLint>(level), glInternalFormat,
|
||||||
static_cast<GLsizei>(levelTexelSize.x()),
|
static_cast<GLsizei>(levelTexelSize.x()),
|
||||||
static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType,
|
static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType,
|
||||||
pData);
|
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);
|
MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level, m_backendTextureId);
|
||||||
stateTextureObject->MarkStorageDirty(uploadTarget, level, false);
|
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<GLint>(level), 0, 0,
|
||||||
|
static_cast<GLsizei>(texelSize.x()),
|
||||||
|
static_cast<GLsizei>(texelSize.y()), glFormat, glType,
|
||||||
|
textureMipmapObject->MapMipmapData(uploadTarget, level));
|
||||||
|
|
||||||
|
textureMipmapObject->MarkStorageDirty(uploadTarget, level, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: THROW_UNIMPL_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Update built-in sampler parameters
|
{ // 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<GLint>(level), 0, 0,
|
|
||||||
static_cast<GLsizei>(texelSize.x()),
|
|
||||||
static_cast<GLsizei>(texelSize.y()), glFormat, glType,
|
|
||||||
stateTextureObject->MapMipmapData(uploadTarget, level));
|
|
||||||
|
|
||||||
stateTextureObject->MarkStorageDirty(uploadTarget, level, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
|
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());
|
MGLOG_D("%s(%s:%d) ES error: %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -64,9 +64,14 @@ namespace MobileGL {
|
|||||||
if (!TextureImpl::ValidateTextureSubImageOffsets(textureObject, xoffset, width, yoffset, height)) return;
|
if (!TextureImpl::ValidateTextureSubImageOffsets(textureObject, xoffset, width, yoffset, height)) return;
|
||||||
|
|
||||||
// ======================= Processing ================================
|
// ======================= Processing ================================
|
||||||
// auto& mipmap = textureObject->GetMipmap(level);
|
// Texture object here should always be an object with mipmap
|
||||||
// Vector<Uint8>& data = mipmap.data;
|
// Assert this for extra safety.
|
||||||
auto texelSize = textureObject->GetMipmapTexelSize(textureUploadingTarget, level);
|
// This should automatically compiled out in release,
|
||||||
|
// so that we don't take the perf hit of dyn-cast.
|
||||||
|
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get()),
|
||||||
|
"Texture object here should always be an object with mipmap");
|
||||||
|
auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get());
|
||||||
|
auto texelSize = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level);
|
||||||
|
|
||||||
SizeT imageSize = 0;
|
SizeT imageSize = 0;
|
||||||
const SizeT bytesPerPixel = MG_Util::GetInputBytesPerPixel(textureInternalFormat, texturePixelDataType);
|
const SizeT bytesPerPixel = MG_Util::GetInputBytesPerPixel(textureInternalFormat, texturePixelDataType);
|
||||||
@@ -107,7 +112,7 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto* srcData = static_cast<const Uint8*>(processedPixels);
|
const auto* srcData = static_cast<const Uint8*>(processedPixels);
|
||||||
Uint8* destData = (Uint8*)textureObject->MapMipmapData(textureUploadingTarget, level);
|
Uint8* destData = (Uint8*)textureMipmapObject->MapMipmapData(textureUploadingTarget, level);
|
||||||
// No allocation should be done here
|
// No allocation should be done here
|
||||||
// if (data.empty()) {
|
// if (data.empty()) {
|
||||||
// SizeT totalSize = texelSize.x() * texelSize.y() * bytesPerPixel;
|
// SizeT totalSize = texelSize.x() * texelSize.y() * bytesPerPixel;
|
||||||
@@ -122,7 +127,7 @@ namespace MobileGL {
|
|||||||
|
|
||||||
free(processedPixels);
|
free(processedPixels);
|
||||||
|
|
||||||
textureObject->MarkStorageDirty(textureUploadingTarget, level, true);
|
textureMipmapObject->MarkStorageDirty(textureUploadingTarget, level, true);
|
||||||
// mipmap.dirty = true;
|
// mipmap.dirty = true;
|
||||||
// mipmap.hasData = true;
|
// mipmap.hasData = true;
|
||||||
}
|
}
|
||||||
@@ -398,8 +403,13 @@ namespace MobileGL {
|
|||||||
reinterpret_cast<SizeT>(pixels);
|
reinterpret_cast<SizeT>(pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get()),
|
||||||
|
"Texture object here should always be an object with mipmap");
|
||||||
|
auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get());
|
||||||
|
|
||||||
|
|
||||||
// Allocate in TextureObject
|
// Allocate in TextureObject
|
||||||
textureObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, totalBytes});
|
textureMipmapObject->AllocateStorage(textureUploadingTarget, level, {{width, height, 1}, totalBytes});
|
||||||
|
|
||||||
if (!originalPixels) {
|
if (!originalPixels) {
|
||||||
MGLOG_D("TexImage2D_State: No input pixel and no PBO bound, no pixel transfer");
|
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);
|
const SizeT copySize = std::min(imageSize, totalBytes);
|
||||||
DataPtr texelInput{processedPixels, copySize};
|
DataPtr texelInput{processedPixels, copySize};
|
||||||
textureObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput);
|
textureMipmapObject->UpdateMipmapSubData(textureUploadingTarget, level, texelInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(processedPixels);
|
free(processedPixels);
|
||||||
@@ -648,17 +658,41 @@ namespace MobileGL {
|
|||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_TEXTURE_WIDTH:
|
case GL_TEXTURE_WIDTH:
|
||||||
if (params) {
|
if (params) {
|
||||||
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).x();
|
switch (textureObject->GetStorageType()) {
|
||||||
|
case TextureStorageType::Mipmap: {
|
||||||
|
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get());
|
||||||
|
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
THROW_UNIMPL_EXCEPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_TEXTURE_HEIGHT:
|
case GL_TEXTURE_HEIGHT:
|
||||||
if (params) {
|
if (params) {
|
||||||
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).y();
|
switch (textureObject->GetStorageType()) {
|
||||||
|
case TextureStorageType::Mipmap: {
|
||||||
|
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get());
|
||||||
|
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
THROW_UNIMPL_EXCEPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_TEXTURE_DEPTH:
|
case GL_TEXTURE_DEPTH:
|
||||||
if (params) {
|
if (params) {
|
||||||
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).z();
|
switch (textureObject->GetStorageType()) {
|
||||||
|
case TextureStorageType::Mipmap: {
|
||||||
|
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get());
|
||||||
|
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
THROW_UNIMPL_EXCEPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_TEXTURE_INTERNAL_FORMAT:
|
case GL_TEXTURE_INTERNAL_FORMAT:
|
||||||
@@ -714,18 +748,41 @@ namespace MobileGL {
|
|||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_TEXTURE_WIDTH:
|
case GL_TEXTURE_WIDTH:
|
||||||
if (params) {
|
if (params) {
|
||||||
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).x();
|
switch (textureObject->GetStorageType()) {
|
||||||
|
case TextureStorageType::Mipmap: {
|
||||||
|
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get());
|
||||||
|
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).x();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
THROW_UNIMPL_EXCEPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_TEXTURE_HEIGHT:
|
case GL_TEXTURE_HEIGHT:
|
||||||
if (params) {
|
if (params) {
|
||||||
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).y();
|
switch (textureObject->GetStorageType()) {
|
||||||
|
case TextureStorageType::Mipmap: {
|
||||||
|
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get());
|
||||||
|
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).y();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
THROW_UNIMPL_EXCEPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_TEXTURE_DEPTH:
|
case GL_TEXTURE_DEPTH:
|
||||||
if (params) {
|
if (params) {
|
||||||
*params = textureObject->GetMipmapTexelSize(textureUploadingTarget, level).z();
|
switch (textureObject->GetStorageType()) {
|
||||||
}
|
case TextureStorageType::Mipmap: {
|
||||||
|
const auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(textureObject.get());
|
||||||
|
*params = textureMipmapObject->GetMipmapTexelSize(textureUploadingTarget, level).z();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
THROW_UNIMPL_EXCEPTION;
|
||||||
|
} }
|
||||||
break;
|
break;
|
||||||
case GL_TEXTURE_INTERNAL_FORMAT:
|
case GL_TEXTURE_INTERNAL_FORMAT:
|
||||||
if (params) {
|
if (params) {
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ namespace MobileGL {
|
|||||||
IntVec3 FramebufferAttachment::GetSize() const {
|
IntVec3 FramebufferAttachment::GetSize() const {
|
||||||
if (IsTexture()) {
|
if (IsTexture()) {
|
||||||
// TODO: get correct upload target
|
// TODO: get correct upload target
|
||||||
return m_texture->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
|
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureMipmapObject*>(m_texture.get()), "Texture object here should always be an object with mipmap");
|
||||||
|
auto textureMipmapObject = static_cast<MG_State::GLState::TextureMipmapObject*>(m_texture.get());
|
||||||
|
return textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
|
||||||
} else if (IsRenderbuffer()) {
|
} else if (IsRenderbuffer()) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ namespace MobileGL {
|
|||||||
Unknown = -1
|
Unknown = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class TextureStorageType {
|
||||||
|
Mipmap,
|
||||||
|
Buffer
|
||||||
|
};
|
||||||
|
|
||||||
enum class TextureInputFormat {
|
enum class TextureInputFormat {
|
||||||
Red,
|
Red,
|
||||||
RG,
|
RG,
|
||||||
|
|||||||
@@ -14,14 +14,7 @@ namespace MobileGL {
|
|||||||
using TargetEnum = TextureTarget;
|
using TargetEnum = TextureTarget;
|
||||||
virtual ~ITextureObject() = default;
|
virtual ~ITextureObject() = default;
|
||||||
|
|
||||||
virtual Uint GetMipmapLevelCount() const = 0;
|
virtual TextureStorageType GetStorageType() 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 TextureInternalFormat GetFormat() const = 0;
|
virtual TextureInternalFormat GetFormat() const = 0;
|
||||||
virtual TextureTarget GetTarget() const = 0;
|
virtual TextureTarget GetTarget() const = 0;
|
||||||
@@ -49,17 +42,6 @@ namespace MobileGL {
|
|||||||
TextureObjectBase(TextureTarget target, Uint externalIndex);
|
TextureObjectBase(TextureTarget target, Uint externalIndex);
|
||||||
virtual ~TextureObjectBase() = default;
|
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;
|
TextureInternalFormat GetFormat() const override;
|
||||||
TextureTarget GetTarget() const override;
|
TextureTarget GetTarget() const override;
|
||||||
IntVec3 GetBaseSize() const override;
|
IntVec3 GetBaseSize() const override;
|
||||||
@@ -87,10 +69,26 @@ namespace MobileGL {
|
|||||||
UintVec2 m_levelRange = {0, 1000};
|
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:
|
public:
|
||||||
TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex)
|
TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex)
|
||||||
: TextureObjectBase(target, externalIndex) {}
|
: TextureMipmapObject(target, externalIndex) {}
|
||||||
virtual ~TextureObjectWithOneMipmap() = default;
|
virtual ~TextureObjectWithOneMipmap() = default;
|
||||||
|
|
||||||
Uint GetMipmapLevelCount() const override;
|
Uint GetMipmapLevelCount() const override;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace MobileGL {
|
|||||||
namespace MG_State {
|
namespace MG_State {
|
||||||
namespace GLState {
|
namespace GLState {
|
||||||
TextureObject2DCube::TextureObject2DCube(Uint externalIndex)
|
TextureObject2DCube::TextureObject2DCube(Uint externalIndex)
|
||||||
: TextureObjectBase(TextureTarget::TextureCubeMap, externalIndex) {}
|
: TextureMipmapObject(TextureTarget::TextureCubeMap, externalIndex) {}
|
||||||
|
|
||||||
Uint TextureObject2DCube::GetMipmapLevelCount() const {
|
Uint TextureObject2DCube::GetMipmapLevelCount() const {
|
||||||
return m_textureStorage.GetLevelCount();
|
return m_textureStorage.GetLevelCount();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
namespace MobileGL {
|
namespace MobileGL {
|
||||||
namespace MG_State {
|
namespace MG_State {
|
||||||
namespace GLState {
|
namespace GLState {
|
||||||
class TextureObject2DCube : public TextureObjectBase {
|
class TextureObject2DCube : public TextureMipmapObject {
|
||||||
public:
|
public:
|
||||||
explicit TextureObject2DCube(Uint externalIndex);
|
explicit TextureObject2DCube(Uint externalIndex);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user