12

OpenGL の経験中に、いくつかの状態を設定するのを忘れることがよくありました。したがって、現在のステート マシンは適切な設計ではない可能性があると思います。しかし、今は互換性がなければなりません。また、初期の DirectX もステート マシンであったことも知っています。OpenGL と DirectX がもともとステート マシンとして設計された理由を知りたいのですが。

4

2 に答える 2

26

人々が「ステート マシン」に言及するときに何を意味するのかは明確ではありません。そこで、OpenGL の「ステート マシン」と現在の D3D の「ステート マシンではない」という観点から、一般的かつ具体的に説明します。

OpenGL と Direct3D はどちらもグローバル状態を使用します。すべてのレンダリング コマンドでは、一連の状態を設定する必要があります。

両方の API でレンダリングするには、一連のグローバル状態を設定する必要があります。使用するシェーダーを設定する必要があります。これらのユニフォームを使用する現在のパラメーターを設定する必要があります。テクスチャを使用している場合は、それらを設定する必要があります。現在のビューポート パラメータを設定する必要があります。などなど。

この種の「ステート マシン」の理由は単純です。それが、ハードウェアが一般的にどのように機能するかです。

状態の各ビットは、GPU 内のいくつかのレジスタを表します。これらのレジスタは状態です。レンダリングするには、シェーダーをロードする必要があります。ビューポート レジスタを設定する必要があります。使用しているテクスチャ アドレッシング レジスタを設定する必要があります。などなど。したがって、 GPUはステート マシンであるため、API はステートマシンです。

これは、レンダリング コマンドによって実行されると想像できます。ただし、渡す必要があるオブジェクトの数を見てください。たくさんのシェーダー、たくさんのテクスチャ、頂点データ、フレームバッファー、ビューポート設定、ブレンド設定などを渡す必要があります。

代わりに、API を使用すると、GPU が行うことを行うことができます。これらすべてを事前に設定します。

さらに、これにより API が高速になります。なんで?API は、使用している状態を認識できるようになったためです。たとえば、1 つのメッシュの異なる部分を異なるテクスチャでレンダリングしたい場合、フレームバッファ、ビューポート、頂点データなどをすべて同じに保つことができます。それらの間で変更するのは、使用するテクスチャだけです。

数十個のパラメーターを使用してある種の巨大な Draw 呼び出しを使用した場合、API は各パラメーターを調べて、最後の描画呼び出しと同じかどうかを確認する必要があります。そうでない場合は、GPU レジスタを更新する必要があります。

さて、OpenGLとD3Dの違いについて。この場合、問題の違いはオブジェクトの扱い方です。

D3D は、オブジェクトを変更する関数がオブジェクトをパラメーターとして受け取るという点で、オブジェクト ベースです。また、ほとんどの D3D オブジェクトは不変です。それらを作成すると、ほとんどの設定を変更できなくなります。特定のサイズ、フォーマットなどのテクスチャを作成したら、完了です。オブジェクトを削除して新しいオブジェクトを作成せずに、別のサイズ/フォーマット/などで再割り当てすることはできません。

OpenGL は状態ベースです。これが意味することは、オブジェクトを変更する OpenGL 関数 (ほとんどの場合) は、操作対象のオブジェクトをパラメーターとして取りません。

これは単なる「設計」ではなく、下位互換性に対する OpenGL の厳密な準拠です。OpenGL のオブジェクトは、グローバル状態の断片にすぎません。それが彼らが定義されている方法です。なんで?

元々、OpenGL 1.0 では、(表示リスト以外に)オブジェクトがなかったからです。はい、テクスチャ オブジェクトでさえありません。これはばかげており、オブジェクトが必要であると判断したとき、後方互換性のある方法でそれらを実装することにしました。誰もがすでにグローバル状態を操作する関数を使用していました。つまり、オブジェクトをバインドすることによって、グローバルな状態をオーバーライドすると彼らは言ったのです。グローバルな状態を変更するために使用された関数は、オブジェクトの状態を変更するようになりました。

このようにして、オブジェクトのみで動作する一連の新しい関数を導入することなく、API にオブジェクトを導入することができました。したがって、以前は機能していたコードは、コードの重要な書き直しを強制するのではなく、非常にわずかな微調整だけでオブジェクトを操作できました。また、テクスチャを突く新しい機能を導入する必要がある場合、オブジェクトの有無にかかわらず機能することも意味します。したがって、後方互換性と前方互換性がありました。

ほとんどの OpenGL オブジェクトはこのように機能します。変更したい場合は、それらをバインドしてから「グローバル」状態を変更する必要があります。

于 2013-03-04T06:19:22.087 に答える
11

http://www.cs.tufts.edu/research/graphics/resources/OpenGL/OpenGL.htmから:

OpenGL がステート マシンのように動作する理由は、各関数呼び出しで多くの引数を渡す必要がないようにするためです。

最小限の引数パッセージ

アプリケーション プログラムと OpenGL 間の通信は、最終的にワークステーション データ バスを介してグラフィックス ハードウェアに到達する必要があります。通常、データ バスはワークステーションの CPU やグラフィック ハードウェアよりもはるかに低速であるため、高速グラフィックのボトルネックになることがよくあります。可能な限り最高の速度を維持するために、OpenGL のドキュメントを確認するとわかるように、OpenGL はその関数呼び出しでできるだけ少ない引数を渡します。すべての呼び出しは、多くの内部変数が以前に必要な値に設定されていることを前提としています。

于 2013-03-04T04:57:49.587 に答える