0

仕事

私自身の OpenGL フレームワークでは、プラットフォームがサポートしていないときに PVRTC テクスチャを解凍しようとしています。このために、PVRTC-SDKをダウンロードし、C++ コードを 1:1 でアンマネージ コードを含む C# コードに変換しました。

問題

簡単に言うと、機能していません。理由がわかりません。コードを 2 回確認しましたが、問題ないようで、動作するはずです。ときどき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);
}

考え

元のソースコードが正しくないか、コードを翻訳したときに何かが抜けていました。とにかく解決策が必要で、ソースコードを2回チェックしました。

(C#のソースコードがあればそれを使用しますが、見つかりません)

4

1 に答える 1

1

分割統治

コードを翻訳する場合は、段階的にコードをテストすることをお勧めします。同じデータを同じコード片に提供できれば (最も単純な方法から始めて)、どこに問題があるかを判断できます。

タイプサイズ

C# の long は、C++ の long と同じではない可能性があることに注意してください。これがあなたの場合の問題であるかどうかを確認するためにあなたのコードを見ていないことに注意してください(作業が多すぎます)。

呼び出し規約

.NET で安全でないコードを呼び出す場合、呼び出し方法 (パラメーターをスタックにプッシュしたり、スタックから削除したりする方法) を指定する必要がある場合があります。これらはすべて同じであるため、純粋な .NET ソリューションでは心配する必要はありません。

于 2012-10-09T01:37:33.430 に答える