2

ゲームは、ソフトウェア レンダリングを使用して、フルスクリーンのパレット (8 ビット) 画像をメモリに描画します。

OpenGL を使用して、その画像を画面に表示する最速の方法は何ですか?

私が試したこと:

  • glDrawPixelsglPixelMapパレットを指定し、OpenGL にパレット マッピングを行わせます。パフォーマンスはひどかった (~5 FPS)。
  • ソフトウェアでパレット マッピング (インデックス -> BGRX) を実行し、glDrawPixels. DirectDrawパフォーマンスは向上しましたが、CPU 使用率は、同じソフトウェア パレット マッピングで32 ビットを使用する場合よりもはるかに高くなります。

代わりに何らかのテクスチャを使用する必要がありますか?

4

1 に答える 1

6
  • glDrawPixels で glPixelMap を使用してパレットを指定し、OpenGL にパレット マッピングを実行させます。パフォーマンスはひどかった (~5 FPS)。

それは驚くべきことではありません。そもそもglDrawPixelsはそれほど高速ではなく、glPixelMapはCPU上でインデックス/パレット→RGB変換を確実に最適化されていないコードパスで行います。

  • ソフトウェアでパレット マッピング (インデックス -> BGRX) を実行し、glDrawPixels を使用してそれを描画します。

glDrawPixels は、OpenGL で最も遅い関数の 1 つです。これには 2 つの主な理由があります。1 つ目はコードパッチがあまり最適化されていないこと、2 つ目はターゲット フレームバッファに直接書き込むため、パイプラインが呼び出されるたびに強制的に同期されることです。また、ほとんどの GPU では、キャッシュに支えられていません。

私が提案するのは、インデックス付きの画像を GL_R8 (OpenGL-3 以降の場合) または GL_LUMINANCE8 などの単一チャネル テクスチャに配置し、パレットを 1D RGB テクスチャに配置して、テクスチャ座標として使用されるインデックスが色を検索するようにすることです。テクスチャを LUT として使用することは完全に正常です。この組み合わせでは、その場でのパレット インデックスから色への変換にフラグメント シェーダーを使用します。

フラグメントシェーダーは次のようになります

#version 330

uniform sampler2D image;
uniform sampler1D palette;

in vec2 texcoord;

void main()
{
    float index = tex2D(image, texcoord).r * 255.f; // 255 for a 8 bit palette
    gl_FragColor = texelFetch(palette, index, 0);
}
于 2012-09-21T08:42:18.103 に答える