解压缩PVRTC

时间:2012-10-08 18:42:32

标签: c# c++

任务

对于我自己的OpenGL-Framework,当平台不支持时,我试图解压缩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(所以8x大小压缩图像)。

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#的源代码我将使用它,但我找不到)

1 个答案:

答案 0 :(得分:1)

分而治之

在翻译代码的情况下,我建议逐步测试代码。如果您可以为相同的代码片段提供相同的数据(从最简单的方法开始),您可以确定问题所在。

输入尺寸

请注意,C#中的long可能与C ++中的long不同。请注意,我没有查看您的代码,看看这是否是您的问题(太多工作)。

致电约定

在.NET中调用不安全的代码时,可能必须指定调用方法(如何将参数推入堆栈并从堆栈中删除)。这些是我们在纯.NET解决方案中不必担心的事情,因为它们完全相同。