異なる解像度のフレームバッファをバインドするたびに glViewport を呼び出す必要がありますか? 質問する

異なる解像度のフレームバッファをバインドするたびに glViewport を呼び出す必要がありますか? 質問する

さまざまなサイズのフレームバッファを 3 つほど持つプログラムがあります。最初にそれらを初期化し、適切なレンダリング ターゲットを指定して、それぞれのビューポート サイズを変更します。

当初は、フレームバッファーを初期化するときにのみ呼び出す必要があると考えていましたがglViewport、これによりプログラムで問題が発生したため、これは間違っていると思います。解像度がすべて異なるため、現在は各フレームでレンダリングするときに、最初のフレームバッファーをバインドし、そのフレームバッファーに合うようにビューポートのサイズを変更し、2 番目のフレームバッファーをバインドし、2 番目のフレームバッファーの解像度に合うようにビューポートのサイズを変更し、3 番目のフレームバッファーをバインドし、それに合うようにビューポートのサイズを変更し、次にウィンドウ フレーム バッファーをバインドし、ビューポートのサイズをウィンドウの解像度に変更します。

これは必要なのでしょうか、それともプログラム内の他の部分に問題があるのでしょうか? これはフレームごとに実行されるため、実行する必要がない場合は、若干の不要なオーバーヘッドが発生するのではないかと心配しています。

ベストアンサー1

glViewport()異なるサイズのフレームバッファに描画を開始する前に、常に を呼び出す必要があります。これは、ビューポートがフレームバッファ状態の一部ではないために必要です。

たとえば、OpenGL 3.3 仕様のセクション 6.2 の「状態テーブル」の 278 ページ目から始まる部分を見ると、状態全体のテーブルが含まれており、各状態の範囲が示されています。

  • 299 ページの表 6.23 には、「フレームバッファ オブジェクトごとの状態」がリストされています。リストされている状態は、描画バッファと読み取りバッファのみです。ビューポートがフレームバッファ状態の一部である場合は、ここにリストされます。
  • ビューポートは、表 6.8「変換状態」にリストされています。これはグローバル状態であり、どのオブジェクトにも関連付けられていません。

OpenGL 4.1 では複数のビューポートが導入されています。ただし、それらは依然としてグローバル変換状態の一部です。

なぜそうなっているのか疑問に思うかもしれませんが、唯一の本当の答えは、このように定義されたということです。グラフィックス パイプラインを見ると、それは理にかなっています。呼び出しglViewport()は、レンダリングするフレーム バッファー内の四角形を指定しているように見えますが、実際には、頂点シェーダー (または、ある場合はジオメトリ シェーダー) とフラグメント シェーダー間の固定関数ブロックの一部として適用される変換を定義します。ビューポート設定は、NDC (正規化デバイス座標) がウィンドウ座標にマップされる方法を決定します。

一方、フレームバッファの状態は、フラグメント シェーダの出力がフレームバッファに書き込まれる方法を決定します。したがって、パイプラインのまったく異なる部分を制御します。

アプリケーションによるビューポートの通常の使用方法からすると、ビューポートをフレームバッファ状態の一部にする方が合理的だと思います。しかし、OpenGL は実際にはグラフィックス ハードウェアの抽象化を目的とした API であり、その観点からすると、ビューポートはフレームバッファ状態から独立しています。

おすすめ記事