0

主に固定スプライト (ディスクからロードされたビットマップ) といくつかのビデオを使用する C# の小さなゲームがあります。

現在のアプローチは

読み込み中:

texture.ID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, texture.ID);

GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, w, h, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, data);

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);

GL.BindTexture(TextureTarget.Texture2D, 0);

描く

GL.BindTexture(TextureTarget.Texture2D, texture.ID);
GL.MatrixMode(MatrixMode.Texture);
GL.PushMatrix();
    GL.Begin(BeginMode.Quads);

    GL.TexCoord2(x1, y1);
    GL.Vertex3(rx1, ry1, rect.Z);

    GL.TexCoord2(x1, y2);
    GL.Vertex3(rx1, ry2, rect.Z);

    GL.TexCoord2(x2, y2);
    GL.Vertex3(rx2, ry2, rect.Z);

    GL.TexCoord2(x2, y1);
    GL.Vertex3(rx2, ry1, rect.Z);

    GL.End();
GL.PopMatrix();

GL.BindTexture(TextureTarget.Texture2D, 0);

そして更新:

GL.BindTexture(TextureTarget.Texture2D, texture.ID);

GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, data);

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);

GL.BindTexture(TextureTarget.Texture2D, 0);

すべてのテクスチャは使用されるまで保持されるため、ロードは起動時に 1 回だけ行われます (一般的に)。ここで、PBO を適切に使用してテクスチャを更新したいと思います (主にビデオ用) A) PBO を使用して (bmp から) テクスチャを追加するのは良い考えですか? pbo を作成し、bmp から pbo にデータをコピーしてから、TexSubImage2D を使用します。そのためのパフォーマンスポイントはありますか、それともオーバーヘッドが高いですか? B) 更新も同じ: 現在のコード:

GL.BindBuffer(BufferTarget.PixelUnpackBuffer, texture.PBO);

IntPtr buffer = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
Marshal.Copy(data, 0, buffer, data.Length);

GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer);

GL.BindTexture(TextureTarget.Texture2D, texture.ID);

GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, w, h, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);

GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);

これは実際に機能しますか、それともメリットはありませんか?

私はhttp://www.opengl.org/wiki/Pixel_Buffer_Objecthttp://www.songho.ca/opengl/gl_pbo.htmlを読み、ダウンロードと使用に関する最初の記事では、データをアップロードしてすぐにそのテクスチャを描画する (または TexSubImage2D を使用しますか?) と、PBO によって速度が向上しません。これは正しいですか?したがって、PBO を使用する場合、2 番目の PBO を使用して、1 フレーム遅れてフレームを描画する必要がありますか?

私のメインループは次のようなものです:

{
  DoSomeInputHandling();
  CopyDecodedVideoFrameToTexture();
  DrawTexture();
}

別のスレッドでビデオをデコードします。

かなり素朴なアプローチですが、機能しています。これを行う正しい/より良い方法は何ですか?

4

1 に答える 1

0

テクスチャの作成と更新のコード パスは問題ありません。ただし、更新の場合、フィルタやラップ モードなどのテクスチャ オブジェクト パラメータを再指定する必要はありません。これらの状態はそのまま維持されます。描画に即時モードを使用しても、最適なパフォーマンスが得られる可能性は低くなります。

PBO を使用すると、データの余分なコピーを回避できます。たとえば、別のスレッドでビデオをデコードすると、 mappend PBO メモリに直接書き込むことができます (もちろん、スレッドが書き込みたいときにオブジェクトがマップされることを保証するために、何らかの同期スキームが必要になります)。したがって、提案している余分なコピーを削除します。あなたのコードで。PBO ピンポン (またはリング バッファー) アプローチを実装すると、パフォーマンスが向上し、個別のコード部分がさらに分離される可能性がありますが、遅延が増加するという犠牲が伴います。これがあなたのシナリオにとって懸念事項であるかどうかはわかりません。

于 2013-05-10T21:46:18.287 に答える