mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Fix] (MG_Util/TextureMetrics, MG_State/Texture): reimplement TextureMetrics, attempting to fix glTexSubImage2D
This commit is contained in:
@@ -59,12 +59,14 @@ namespace MobileGL {
|
|||||||
|
|
||||||
// ======================= Processing ================================
|
// ======================= Processing ================================
|
||||||
SizeT imageSize =
|
SizeT imageSize =
|
||||||
MG_Util::CalculateTextureImageSize(textureInternalFormat, texturePixelDataType, {width, height, 1});
|
MG_Util::CalculateInputTextureImageSize(textureInternalFormat,
|
||||||
|
texturePixelDataType,
|
||||||
|
{width, height, 1});
|
||||||
auto& mipmap = textureObject->GetMipmap(level);
|
auto& mipmap = textureObject->GetMipmap(level);
|
||||||
Vector<Uint8>& data = mipmap.data;
|
Vector<Uint8>& data = mipmap.data;
|
||||||
|
|
||||||
SizeT bytesPerPixel = MG_Util::GetTexturePixelSize(textureInternalFormat) *
|
SizeT bytesPerPixel =
|
||||||
MG_Util::GetTexturePixelDataTypeSize(texturePixelDataType);
|
MG_Util::GetInputBytesPerPixel(textureInternalFormat, texturePixelDataType);
|
||||||
SizeT rowStride = mipmap.size.x() * bytesPerPixel;
|
SizeT rowStride = mipmap.size.x() * bytesPerPixel;
|
||||||
|
|
||||||
const Uint8* srcData = reinterpret_cast<const Uint8*>(pixels);
|
const Uint8* srcData = reinterpret_cast<const Uint8*>(pixels);
|
||||||
@@ -74,13 +76,17 @@ namespace MobileGL {
|
|||||||
|
|
||||||
for (GLint row = 0; row < height; ++row) {
|
for (GLint row = 0; row < height; ++row) {
|
||||||
SizeT dstOffset = ((yoffset + row) * mipmap.size.x() + xoffset) * bytesPerPixel;
|
SizeT dstOffset = ((yoffset + row) * mipmap.size.x() + xoffset) * bytesPerPixel;
|
||||||
|
// Should take states from glPixelStorei/glPixelStoref into account
|
||||||
SizeT srcOffset = row * width * bytesPerPixel;
|
SizeT srcOffset = row * width * bytesPerPixel;
|
||||||
|
|
||||||
if (dstOffset + width * bytesPerPixel <= data.size()) {
|
if (dstOffset + width * bytesPerPixel < data.size()) {
|
||||||
Copy(reinterpret_cast<const Uint8*>(srcData + srcOffset),
|
Memcpy(srcData + srcOffset, data.data() + dstOffset, width * bytesPerPixel);
|
||||||
reinterpret_cast<Uint8*>(&data[dstOffset]), width * bytesPerPixel);
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation,
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"Copy failed. Dest image does not have sufficient space."));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +301,9 @@ namespace MobileGL {
|
|||||||
|
|
||||||
// ======================= Processing ================================
|
// ======================= Processing ================================
|
||||||
SizeT imageSize =
|
SizeT imageSize =
|
||||||
MG_Util::CalculateTextureImageSize(textureInternalFormat, texturePixelDataType, {width, height, 1});
|
MG_Util::CalculateInputTextureImageSize(textureInternalFormat,
|
||||||
|
texturePixelDataType,
|
||||||
|
{width, height, 1});
|
||||||
|
|
||||||
textureObject->SetInternalFormat(textureInternalFormat);
|
textureObject->SetInternalFormat(textureInternalFormat);
|
||||||
MG_State::GLState::MipmapLevelInput mipmap = MG_State::GLState::MipmapLevelInput(
|
MG_State::GLState::MipmapLevelInput mipmap = MG_State::GLState::MipmapLevelInput(
|
||||||
|
|||||||
@@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
namespace MobileGL {
|
namespace MobileGL {
|
||||||
namespace MG_Util {
|
namespace MG_Util {
|
||||||
SizeT GetTexturePixelSize(TextureInternalFormat internal) {
|
SizeT GetSizedInternalFormatSizeInBytes(TextureInternalFormat internal) {
|
||||||
switch (internal) {
|
switch (internal) {
|
||||||
case TextureInternalFormat::R8:
|
case TextureInternalFormat::R8:
|
||||||
case TextureInternalFormat::R8Snorm:
|
case TextureInternalFormat::R8Snorm:
|
||||||
case TextureInternalFormat::R8I:
|
case TextureInternalFormat::R8I:
|
||||||
case TextureInternalFormat::R8UI:
|
case TextureInternalFormat::R8UI:
|
||||||
return 1;
|
case TextureInternalFormat::R3G3B2:
|
||||||
|
return 1;
|
||||||
|
|
||||||
case TextureInternalFormat::R16:
|
case TextureInternalFormat::R16:
|
||||||
case TextureInternalFormat::R16Snorm:
|
case TextureInternalFormat::R16Snorm:
|
||||||
@@ -22,7 +23,6 @@ namespace MobileGL {
|
|||||||
case TextureInternalFormat::RG8UI:
|
case TextureInternalFormat::RG8UI:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case TextureInternalFormat::R3G3B2:
|
|
||||||
case TextureInternalFormat::RGB4:
|
case TextureInternalFormat::RGB4:
|
||||||
case TextureInternalFormat::RGB5:
|
case TextureInternalFormat::RGB5:
|
||||||
case TextureInternalFormat::RGB8:
|
case TextureInternalFormat::RGB8:
|
||||||
@@ -83,46 +83,143 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SizeT GetTexturePixelDataTypeSize(TexturePixelDataType type) {
|
SizeT GetBaseInternalFormatComponentCount(TextureInternalFormat format) {
|
||||||
switch (type) {
|
switch (format) {
|
||||||
case TexturePixelDataType::UnsignedByte:
|
case TextureInternalFormat::DepthComponent:
|
||||||
case TexturePixelDataType::Byte:
|
case TextureInternalFormat::DepthStencil:
|
||||||
case TexturePixelDataType::UnsignedByte332:
|
// Depth stencil is actually 2 components
|
||||||
case TexturePixelDataType::UnsignedByte233Rev:
|
// tho real formats always gives byte size in whole
|
||||||
return 1;
|
// so we count this as one here
|
||||||
case TexturePixelDataType::UnsignedShort:
|
case TextureInternalFormat::Red:
|
||||||
case TexturePixelDataType::Short:
|
case TextureInternalFormat::R8:
|
||||||
case TexturePixelDataType::UnsignedShort565:
|
case TextureInternalFormat::R8Snorm:
|
||||||
case TexturePixelDataType::UnsignedShort565Rev:
|
case TextureInternalFormat::R8I:
|
||||||
case TexturePixelDataType::UnsignedShort4444:
|
case TextureInternalFormat::R8UI:
|
||||||
case TexturePixelDataType::UnsignedShort4444Rev:
|
case TextureInternalFormat::R16:
|
||||||
case TexturePixelDataType::UnsignedShort5551:
|
case TextureInternalFormat::R16Snorm:
|
||||||
case TexturePixelDataType::UnsignedShort1555Rev:
|
case TextureInternalFormat::R16I:
|
||||||
return 2;
|
case TextureInternalFormat::R16UI:
|
||||||
case TexturePixelDataType::UnsignedInt:
|
case TextureInternalFormat::R16F:
|
||||||
case TexturePixelDataType::Int:
|
return 1;
|
||||||
case TexturePixelDataType::Float:
|
case TextureInternalFormat::RG:
|
||||||
case TexturePixelDataType::UnsignedInt8888:
|
case TextureInternalFormat::RG8:
|
||||||
case TexturePixelDataType::UnsignedInt8888Rev:
|
case TextureInternalFormat::RG8Snorm:
|
||||||
case TexturePixelDataType::UnsignedInt1010102:
|
case TextureInternalFormat::RG8I:
|
||||||
case TexturePixelDataType::UnsignedInt2101010Rev:
|
case TextureInternalFormat::RG8UI:
|
||||||
case TexturePixelDataType::UnsignedInt101111Rev:
|
case TextureInternalFormat::RG16:
|
||||||
case TexturePixelDataType::UnsignedInt5999Rev:
|
case TextureInternalFormat::RG16Snorm:
|
||||||
return 4;
|
case TextureInternalFormat::RG16I:
|
||||||
default:
|
case TextureInternalFormat::RG16UI:
|
||||||
return 0;
|
case TextureInternalFormat::RG16F:
|
||||||
|
case TextureInternalFormat::RG32F:
|
||||||
|
case TextureInternalFormat::RG32I:
|
||||||
|
case TextureInternalFormat::RG32UI:
|
||||||
|
return 2;
|
||||||
|
case TextureInternalFormat::RGB:
|
||||||
|
case TextureInternalFormat::RGB4:
|
||||||
|
case TextureInternalFormat::RGB5:
|
||||||
|
case TextureInternalFormat::RGB8:
|
||||||
|
case TextureInternalFormat::RGB8Snorm:
|
||||||
|
case TextureInternalFormat::SRGB8:
|
||||||
|
case TextureInternalFormat::RGB8I:
|
||||||
|
case TextureInternalFormat::RGB8UI:
|
||||||
|
case TextureInternalFormat::RGB16F:
|
||||||
|
case TextureInternalFormat::RGB32F:
|
||||||
|
case TextureInternalFormat::RGB16I:
|
||||||
|
case TextureInternalFormat::RGB16UI:
|
||||||
|
case TextureInternalFormat::RGB32I:
|
||||||
|
case TextureInternalFormat::RGB32UI:
|
||||||
|
case TextureInternalFormat::R11FG11FB10F:
|
||||||
|
case TextureInternalFormat::RGB9E5:
|
||||||
|
return 3;
|
||||||
|
case TextureInternalFormat::RGBA:
|
||||||
|
case TextureInternalFormat::RGBA2:
|
||||||
|
case TextureInternalFormat::RGBA4:
|
||||||
|
case TextureInternalFormat::RGBA8:
|
||||||
|
case TextureInternalFormat::RGBA8Snorm:
|
||||||
|
case TextureInternalFormat::RGBA8I:
|
||||||
|
case TextureInternalFormat::RGBA8UI:
|
||||||
|
case TextureInternalFormat::RGBA12:
|
||||||
|
case TextureInternalFormat::RGBA16:
|
||||||
|
case TextureInternalFormat::RGBA16I:
|
||||||
|
case TextureInternalFormat::RGBA16UI:
|
||||||
|
case TextureInternalFormat::RGBA16F:
|
||||||
|
case TextureInternalFormat::RGBA32F:
|
||||||
|
case TextureInternalFormat::RGBA32I:
|
||||||
|
case TextureInternalFormat::RGBA32UI:
|
||||||
|
case TextureInternalFormat::RGB10A2:
|
||||||
|
case TextureInternalFormat::RGB10A2UI:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SizeT CalculateTextureImageSize(TextureInternalFormat internalFormat, TexturePixelDataType pixelDataType,
|
SizeT GetSizedTexturePixelDataTypeSize(TexturePixelDataType type) {
|
||||||
IntVec3 size) {
|
switch (type) {
|
||||||
SizeT pixelSize = GetTexturePixelSize(internalFormat);
|
case TexturePixelDataType::UnsignedByte332:
|
||||||
if (pixelSize == 0) return 0;
|
case TexturePixelDataType::UnsignedByte233Rev:
|
||||||
|
return 1;
|
||||||
|
case TexturePixelDataType::UnsignedShort565:
|
||||||
|
case TexturePixelDataType::UnsignedShort565Rev:
|
||||||
|
case TexturePixelDataType::UnsignedShort4444:
|
||||||
|
case TexturePixelDataType::UnsignedShort4444Rev:
|
||||||
|
case TexturePixelDataType::UnsignedShort5551:
|
||||||
|
case TexturePixelDataType::UnsignedShort1555Rev:
|
||||||
|
return 2;
|
||||||
|
case TexturePixelDataType::UnsignedInt8888:
|
||||||
|
case TexturePixelDataType::UnsignedInt8888Rev:
|
||||||
|
case TexturePixelDataType::UnsignedInt1010102:
|
||||||
|
case TexturePixelDataType::UnsignedInt2101010Rev:
|
||||||
|
case TexturePixelDataType::UnsignedInt101111Rev:
|
||||||
|
case TexturePixelDataType::UnsignedInt5999Rev:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SizeT dataTypeSize = GetTexturePixelDataTypeSize(pixelDataType);
|
SizeT GetBaseTexturePixelDataTypeSize(TexturePixelDataType type) {
|
||||||
if (dataTypeSize == 0) return 0;
|
switch (type) {
|
||||||
|
case TexturePixelDataType::UnsignedByte:
|
||||||
|
case TexturePixelDataType::Byte:
|
||||||
|
return 1;
|
||||||
|
case TexturePixelDataType::UnsignedShort:
|
||||||
|
case TexturePixelDataType::Short:
|
||||||
|
return 2;
|
||||||
|
case TexturePixelDataType::UnsignedInt:
|
||||||
|
case TexturePixelDataType::Int:
|
||||||
|
case TexturePixelDataType::Float:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return pixelSize * dataTypeSize * size.x() * size.y() * size.z();
|
SizeT GetInternalBytesPerPixel(TextureInternalFormat internalformat, TexturePixelDataType type) {
|
||||||
|
SizeT sizedTextureFormatSize = GetSizedInternalFormatSizeInBytes(internalformat);
|
||||||
|
if (sizedTextureFormatSize > 0)
|
||||||
|
return sizedTextureFormatSize;
|
||||||
|
SizeT sizedPixelFormatSize = GetSizedTexturePixelDataTypeSize(type);
|
||||||
|
if (sizedPixelFormatSize > 0)
|
||||||
|
return sizedPixelFormatSize;
|
||||||
|
SizeT chCount = GetBaseInternalFormatComponentCount(internalformat);
|
||||||
|
SizeT bytesPerChannel = GetBaseTexturePixelDataTypeSize(type);
|
||||||
|
return chCount * bytesPerChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeT GetInputBytesPerPixel(TextureInternalFormat internalformat, TexturePixelDataType type) {
|
||||||
|
SizeT sizedPixelFormatSize = GetSizedTexturePixelDataTypeSize(type);
|
||||||
|
if (sizedPixelFormatSize > 0)
|
||||||
|
return sizedPixelFormatSize;
|
||||||
|
SizeT bytesPerChannel = GetBaseTexturePixelDataTypeSize(type);
|
||||||
|
SizeT chCount = GetBaseInternalFormatComponentCount(internalformat);
|
||||||
|
return chCount * bytesPerChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeT CalculateInputTextureImageSize(TextureInternalFormat internalFormat, TexturePixelDataType pixelDataType,
|
||||||
|
IntVec3 size) {
|
||||||
|
return GetInputBytesPerPixel(internalFormat, pixelDataType) * size.x() * size.y() * size.z();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace MG_Util
|
} // namespace MG_Util
|
||||||
|
|||||||
@@ -4,9 +4,15 @@
|
|||||||
|
|
||||||
namespace MobileGL {
|
namespace MobileGL {
|
||||||
namespace MG_Util {
|
namespace MG_Util {
|
||||||
SizeT GetTexturePixelSize(TextureInternalFormat internal);
|
SizeT GetSizedInternalFormatSizeInBytes(TextureInternalFormat internal);
|
||||||
SizeT GetTexturePixelDataTypeSize(TexturePixelDataType type);
|
SizeT GetBaseInternalFormatComponentCount(TextureInternalFormat format);
|
||||||
SizeT CalculateTextureImageSize(TextureInternalFormat internalFormat, TexturePixelDataType pixelDataType,
|
SizeT GetSizedTexturePixelDataTypeSize(TexturePixelDataType type);
|
||||||
IntVec3 size);
|
SizeT GetBaseTexturePixelDataTypeSize(TexturePixelDataType type);
|
||||||
|
// This should respect internal format more
|
||||||
|
SizeT GetInternalBytesPerPixel(TextureInternalFormat internalformat, TexturePixelDataType type);
|
||||||
|
// This should respect type more, representing data passed in
|
||||||
|
SizeT GetInputBytesPerPixel(TextureInternalFormat internalformat, TexturePixelDataType type);
|
||||||
|
SizeT CalculateInputTextureImageSize(TextureInternalFormat internalFormat, TexturePixelDataType pixelDataType,
|
||||||
|
IntVec3 size);
|
||||||
} // namespace MG_Util
|
} // namespace MG_Util
|
||||||
} // namespace MobileGL
|
} // namespace MobileGL
|
||||||
|
|||||||
Reference in New Issue
Block a user