10

私はC++でSDLを使用して2Dプラットフォーマーゲームを書いています。しかし、解像度へのスケーリングに関する大きな問題に遭遇しました。ゲームをフルHDで見栄えよくしたいので、ゲームのすべての画像は、ゲームの自然な解像度が1920x1080になるように作成されています。ただし、誰かが小さい解像度を使用している場合はゲームを正しい解像度にスケールダウンし、誰かが大きい解像度を使用している場合は大きくスケールダウンしたいと思います。

問題は、これを行うための効率的な方法を見つけることができなかったことです.SDL_gfxライブラリを使用してすべての画像を事前にスケーリングすることから始めましたが、多くのオフバイワンエラーが発生するため、これは機能しません、 1つのピクセルが失われていました。また、アニメーションが再生されるときにアニメーションが1つの画像に含まれているため、アニメーションは各フレームでわずかに上下に移動します。

次に、いくつか調べた後、openglを使用してスケーリングを処理しようとしました。現在、私のプログラムはすべての画像を1920x1080のSDL_Surfaceに描画します。次に、このサーフェスをopenglテクスチャに変換し、このテクスチャを画面解像度にスケーリングしてから、テクスチャを描画します。これは視覚的には問題なく機能しますが、問題はまったく効率的ではないということです。現在、最大fpsが18になっています:(

だから私の質問は、SDLディスプレイを画面解像度にスケーリングする効率的な方法を知っている人はいますか?

4

1 に答える 1

10

OpenGL はそのように動作するように設計されていないため、非効率的です。現在の設計における主なパフォーマンスの問題:

  • 最初の問題: SDL でソフトウェア ラスタライズを行っています。申し訳ありませんが、この構成で何をしてもボトルネックになります。1920x1080 の解像度では、2,073,600 ピクセルに色を付けることができます。各 4 チャネル ピクセルをシェーディングするのに 10 クロック サイクルかかると仮定すると、2 GHz プロセッサで最大96.4 fps が実行されます。それは悪いことではありませんが、おそらくピクセルをそれほど速くシェーディングすることはできず、AI、ユーザー入力、ゲームの仕組み、サウンド、物理学、その他すべてをまだ行っておらず、おそらくいくつかのピクセルを描画しています.とにかく少なくとも一度。SDL_gfx は高速かもしれませんが、解像度が大きい場合、CPU は基本的にオーバータスクになります。
  • 2 番目の問題: 各フレームで、グラフィックス バスを介して GPU にデータをコピーしています。これは、グラフィックに関して実行できる最も遅い処理です。画像データはおそらくその中で最悪です通常、画像データは非常に多いためです。基本的に、各フレームで GPU に 200 万個のピクセルを RAM から VRAM にコピーするように指示します。Wikipediaによると、各 4 バイトで 2,073,600 ピクセルの場合、258.9 fps を超えないことを期待できます。

私の推奨事項: アプリケーションを完全に OpenGL に切り替えてください。これにより、テクスチャにレンダリングして画面にコピーする必要がなくなります。画面に直接レンダリングするだけです。また、スケーリングはビュー マトリックス (2D の場合は glOrtho/gluOrtho2D) によって自動的に処理されるため、スケーリングの問題をまったく気にする必要はありません。ビューポートにはすべてが同じ縮尺で表示されます。 これはあなたの問題に対する理想的な解決策です。

現在、OpenGL 描画コマンドを使用してすべてを再コーディングする必要があるという 1 つの大きな欠点があります (これは作業ですが、特に長期的にはそれほど難しくありません)。それ以外では、速度を向上させるために次のアイデアを試すことができます。

  • PBO。ピクセル バッファ オブジェクトを使用して、テクスチャの読み込み/コピーを非同期にすることで、問題 2 に対処できます。
  • レンダリングをマルチスレッド化します。ほとんどの CPU には少なくとも 2 つのコアがあり、新しいチップでは 1 つのコアに対して 2 つのレジスタ状態を保存できます (ハイパースレッディング)。GPUがレンダリングの問題を解決する方法を本質的に複製しています(多くのスレッドが進行しています)。SDL_gfx がどの程度スレッド セーフかはわかりませんが、特に画像の異なる部分を同時に処理している場合は、うまくいくと思います。
  • 描画面が SDL のどの場所にあるかに注意してください。おそらくSDL_SWSURFACEであるはずです(CPUで描画しているため)。
  • VSync を削除します。これにより、60Hz で実行していなくてもパフォーマンスが向上します。
  • 元のテクスチャを描いていることを確認してください。新しいテクスチャに拡大または縮小しないでください。別のサイズで描画し、ラスタライザーに任せましょう!
  • 散発的に更新する: 一度に画像の半分だけを更新します。これはおそらく「フレームレート」の 2 倍近くになり、(通常は) 目立ちません。
  • 同様に、画像の変更部分のみを更新します。

お役に立てれば。

于 2012-06-17T07:42:08.273 に答える