web-dev-qa-db-ja.com

SDL2テクスチャのポイントは何ですか?

SDL2テクスチャの背後にあるロジックにこだわっています。私には、あなたが引き寄せることができないので、彼らは無意味です。

私のプログラムでは、いくつかのサーフェス(またはSDL2に切り替える前のwereサーフェス)を使用して、それらをまとめてレイヤーを形成しました。今、同じ効果を作成するためにいくつかのレンダラーとテクスチャを作成する必要があるようですSDL_RenderCopyはテクスチャポインタを受け取ります。

それだけでなく、allレンダラーはウィンドウから取得する必要がありますが、それは私が理解しているものですが、それでも私を少し汚してしまいます。

これはすべて非常に大きくて遅いようです。何か不足していますか?テクスチャに直接描画する方法はありますか?テクスチャのポイントは何ですか?サーフェスであったものの代わりに複数(数百ではないにしても)のレンダラーを使用しても安全ですか?

SDL_Textureオブジェクトはビデオカードのメモリのできるだけ近くに格納されるため、GPUで簡単に高速化できます。サイズ変更、アルファブレンディング、アンチエイリアシング、およびほとんどの計算負荷の高い操作は、このパフォーマンス向上の影響を大きく受ける可能性があります。プログラムでテクスチャ上でピクセルごとのロジックを実行する必要がある場合は、一時的にテクスチャをサーフェスに変換することをお勧めします。ストリーミングテクスチャで回避策を実現することも可能です。

編集:この回答はかなりの注目を集めているので、私の提案を詳しく説明したいと思います。

Texture -> Surface -> Textureワークフローを使用してピクセル単位の操作を適用する場合は、レンダリングサイクルごとに再計算する必要がない限り、必ず最終テクスチャをキャッシュしてください。このソリューションのテクスチャは、SDL_TEXTUREACCESS_STATICフラグで作成されます。

ストリーミングテクスチャ(作成フラグはSDL_TEXTUREACCESS_STREAMING)は、ピクセルデータのソースがネットワーク、デバイス、フレームサーバー、またはSDLアプリケーションの完全な範囲を超えているその他のソースである場合や、キャッシュが明らかである場合に推奨されます。ソースからのフレームは非効率的または機能しません。

テクスチャがSDL_TEXTUREACCESS_TARGETフラグで作成されている場合、テクスチャの上にレンダリングすることが可能です。これにより、描画操作のソースが他のテクスチャに限定されますが、そもそもそれがすでに必要な場合もあります。 「レンダーターゲットとしてのテクスチャ」は、SDL2の最新で最も広くサポートされていない機能の1つです。

好奇心の強い読者のためのオタク情報:

SDL実装の性質上、最初の2つの方法は、アプリケーションレベルの読み取りおよびコピー操作に依存しますが、推奨されるシナリオ用に最適化されており、リアルタイムアプリケーション用に十分高速です。

アプリケーションレベルからのデータのコピーは、ほとんどの場合、GPUでの後処理と比較すると遅くなります。 SDLが提供できるものよりも要件が厳しく、ロジックが一部の外部ピクセルデータソースに依存しない場合は、SDLサーフェスからペイントされた生のOpenGLテクスチャを割り当てて適用するのが賢明ですshaders(GPUロジック)。

シェーダーは、GLPUアセンブリにコンパイルされる言語であるGLSLで記述されています。 ハードウェア/ GPUアクセラレーションは、実際にはGPUコアで並列化されたコードを指し、レンダリングのためにシェーダーを使用することをお勧めします。

注意!SDLレンダリング関数および構造と組み合わせて未加工のOpenGLテクスチャおよびシェーダーを使用すると、予期しない競合が発生したり、ライブラリによって提供される柔軟性が失われる可能性があります。

TLDR;テクスチャを変更するのは面倒な場合がありますが、サーフェスよりもテクスチャをレンダリングして操作する方が高速です。

35
diegoperini

SDL2テクスチャをSTREAMINGタイプとして作成することにより、テクスチャ全体またはピクセルの領域のみをロックおよびロック解除して、直接ピクセル操作を実行できます。前にSDL2サーフェスを作成し、次のようにロック/ロック解除とリンクする必要があります。

SDL_Surface surface = SDL_CreateSurface(..);
SDL_LockTexture(texture, &rect, &surface->pixels, &surface->pitch);
// Paint into surface pixels
SDL_UnlockTexture(texture);

重要なのは、より大きなサイズのテクスチャに描画し、その描画がインクリメンタルである場合(リアルタイムのデータグラフなど)、更新する実際の領域のみをロックおよびロック解除することです。そうしないと、メモリのコピーが大量に発生し、操作が遅くなります。

私は妥当なパフォーマンスを経験しており、使用モデルは理解するのにそれほど難しくありません。

8
Dan The man

SDL2では、画面外にレンダリングしたり、テクスチャに直接レンダリングしたりできます。使用する関数は次のとおりです。

int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture);

これは、レンダラーがSDL_RENDERER_TARGETTEXTUREを有効にしている場合にのみ機能します。

6