任务
对于我自己的 OpenGL 框架,当平台不支持它时,我正在尝试解压缩 PVRTC 纹理。为此,我下载了PVRTC-SDK并将 C++ 代码 1:1 转换为带有非托管代码的 C# 代码。
问题
简而言之:它不起作用,我不知道它的原因。我已经检查了两次代码,它似乎没问题,应该可以工作。有时我得到一个AccessViolationException
,有时一个LoaderLock
。AccessViolationException
不再发生,我的代码的另一部分出现错误。PVRTC 的颜色仍然是错误的。它看起来很奇怪,基本的笔画是可见的,但颜色是错误的。
代码
由于代码很大,我上传了它:
[C#] http://codeviewer.org/view/code:2a65
[C++] http://codeviewer.org/view/code:2a66
也是 C# 方法的调用代码,大小实际上与预期值匹配(所以源数组的图像值是完全正确width * height * 4bit
的,输出大小是width * height * 4byte
(所以压缩图像的 8 倍大小)。
private static unsafe Image ConvertPVRTC_RGBA8888(Image source)
{
Int32 mipmapCount = source.HasMipmaps ? Image.GetMipmapCount(source.Width, source.Height) : 1;
// Create a array with bytes for the target format
Byte[] bytes = new Byte[RGBA8.GetMipMappedSize(0, mipmapCount, source.Width, source.Height)];
fixed (Byte* pTarget = bytes)
{
fixed (Byte* pSource = source.GetData())
{
Int32 sourceOffset = 0;
Int32 targetOffset = 0;
for (Int32 i = 0; i < mipmapCount; i++)
{
// Calculate offsets
Int32 sourceSize = source.Format.GetMipMappedSize(i, 1, source.Width, source.Height);
Int32 targetSize = RGBA8.GetMipMappedSize(i, 1, source.Width, source.Height);
// Decompress mipmapLevel
PVRTC.DecompressPVRTC(pSource + sourceOffset, pTarget + targetOffset, GetMipmapSize(source.Width, i), GetMipmapSize(source.Height, i), source.Format.BitsPerPixel == 2);
// Calculate pointer offset
sourceOffset += sourceSize;
targetOffset += targetSize;
}
}
}
return new Image(bytes, ImageFormat.RGBA8, source.Width, source.Height, source.HasMipmaps, source.IsCubemap);
}
想法
原始源代码不正确,或者我在翻译代码时遗漏了一些东西。无论如何,我需要一个解决方案并检查了两次源代码。
(如果有任何 C# 的源代码,我会使用它,但我找不到任何源代码)