クロスプラットフォームの低レベルグラフィックAPI


11

システムの抽象化を作成する場合、プラットフォームのさまざまなAPIを、意味のある最低レベルの共通インターフェースによって非表示にすることをお勧めします。

さまざまな最新(固定関数パイプラインなし)のネイティブグラフィックAPIを考慮に入れる:OpenGLES 2.0 +、OpengGL 3.0 +、DirectX 10.0 +、Xbox DirectX 9、LibGCM

ステートレスな低レベルグラフィックAPI を作成してそれらすべての上に配置する場合、それを可能な限り薄く、高速にするために最適な方法は何でしょうか。


APIがステートレスであるという要件は興味深いものです。たとえばOpenGLはステートフルであり、それをラップするステートレスAPIは、それがはるかに高いレベルである場合にのみ意味があると思います。そのため、たとえば、それぞれに同じマトリックスをプッシュおよびポップする必要はありません。レンダリングする表面。
SpoonMeiser、2010

デバイスに送信する前に状態に基づいてレンダーコールを並べ替えるなど、不要な状態の変更を回避することは、より高いレベルで実装できます。そして、現在の状態と異なる場合のみ状態を設定する。
NocturnDragon 2010

しかし、それは無国籍ではありません。多分私は間違っているかもしれませんが、私がステートレスと考えるとき私が思うのは、各呼び出しが以前の呼び出しにまったく依存しないAPIです。つまり、通常はどこかにある状態で保存される情報は、その情報を必要とするすべての呼び出しで渡される必要があります。たとえば、OpenGLの場合、これらはスタック、ライティング、Zバッファリング、および正規化オプションのマトリックスになります。
SpoonMeiser、2010

はい、必要な描画呼び出しごとに、メッシュデータ、ブレンド状態、バインドするテクスチャ、サンプリング状態など。APIを変更することなく、後で最適化を行うことができます。それとも、私はあなたのコメントを間違って読んでいる...
NocturnDragon

回答:


6

私の観点から理解できる最低レベルは、レンダリングに関連するリソース(vb / ib、レンダリングサーフェス、テクスチャ、シェーダー、ステートブロックなど)について話すものです。

ここでの問題は、APIに応じて、これらのいくつかを異なる形式にする必要があることです。そのため、少しトリッキーになります。それを回避する最も簡単な方法は、それぞれのAPIの静的リソースを前処理することです。動的なものの場合はシェーダーのみを使用して生成します。これにより、ネイティブ形式のままにするのがかなり簡単になります。

その後、より高いレベルで行うことは、リソースが接続されたパイプラインをセットアップし、それらをGPUに渡すことです。特にハードウェア固有のトリックを利用する場合は、すべてがそのようにうまく抽象化できるわけではありません。しかし、それは良いスタートです。

(補足:プラットフォーム固有のトリックを特別な種類のリソースとして扱う場合、この概念全体をかなり遠くまでプッシュできます。)

したがって、ある方法で、ハードウェアリソースマネージャーと、これらのリソースのDAGを設定するツールキットの2つを作成します。


プラットフォーム固有のものをリソースとして扱うことは考えていませんでした。それはとても良い考えのように思えます!ありがとう。
NocturnDragon 2010

10

カバーするAPIの範囲が広い場合、一般的なラッピングアプローチは非効率的であり、特定の機能をさまざまなレベルでサポートするかどうかにかかわらず、他のいくつかのAPI間でAPIの概念をマッピングするのが難しい傾向があります。

結果として、最も賢明なアプローチは、機能中心の API を作成することです。このアプローチでは、APIユーザーが利用可能なすべての機能を利用できなくなりますが、各バックエンドの実装が大幅に簡略化され、他の方法では不可能だったバックエンド固有の最適化が可能になります。

また、APIユーザーがサポートしていない機能の管理を大幅に簡素化します。機能Xが存在するかどうかを確認し、影響を受ける機能を特定する必要はなくなりました。代わりに、機能自体をクエリするだけで、現在の構成でサポートされているかどうかを確認できます。機能の部分的なモードまたは制限されたモードをサポートしている場合でも、提供されるコンテキストにより、管理がはるかに容易になります。

ステートレス(サブミッションベースとも呼ばれる)レンダラーの作成に関しては、通常、64ビットキーを使用して、レンダリング用のコマンドをパックおよびサブミットします。その時点から、サポートする機能や機能に応じて、コマンドの実行方法や送信する情報に関して、かなりの柔軟性があります。


これは実際には良いアイデアです。それは私が作成しようとしているデザインの一部ですが、私が考えていたのは、一般的な低レベルAPIの上にこの機能を実装することでした。ただし、一部の機能については、さらに特定のケースでは、ネイティブAPIを深く掘り下げる必要がある場合もあります。
NocturnDragon 2010

アイデアの一部は、共通の低レベルAPIを作成することを避け、最も一般的な分母アプローチでラップを処理する必要があることです。抽象化レベルを1段上げると、機能セットが多少制限されますが、各プラットフォームを活用することもできます。より頻繁にアクセスする必要がある場合に対処するために、プラットフォームヘッダーといくつかの内部ヘルパーを公開するヘッダーを提供することを好みます。バージョンごとに異なる場合がありますが、必要に応じて存在します。
Jason Kozak

1

まず、各APIの動作は異なるため、上記のAPIをすべてラップするのは難しいことは言うまでもありません。そうは言っても、そうする必要がある場合もあります。ある時点で、ゲームは、どれほど難しいかに関わらず、複数のプラットフォームで実行する必要があるだけです。

これを行う最善の方法は、基盤となるすべてのAPIに実装できる機能を考え出し、それを抽象化することです。マルチプラットフォームのゲームを開発している場合、各APIがサポートするあいまいな機能をすべて実装するのではなく、必要なものだけを実装します。これは、APIを小さく高速に保つのにも役立ちます。

異なる各APIの実装が出力に詰め込まれるのを避けるために、プラットフォームに依存しないヘッダーファイルとプラットフォーム固有のコードファイルを使用してコンパイルする必要があります。次に、ターゲットプラットフォームに固有のコードファイルのみがコンパイルされ、APIを小さく維持します。



-4

SDLライブラリまたはAllegroをチェックアウトすることをお勧めします。どちらも低レベルで移植性の高いゲームライブラリであり、OpenGLコンテキストにプラグインしてグラフィックをそこでレンダリングできる方法があります。SDLは、亡くなったLoki Gamesが2000年代の人気のあるゲームをLinuxに移植するために使用されたことで有名であり、Allegroは多くの時間を実行しており、アマチュアゲーム開発者の素晴らしいコミュニティを持っています。


4
OpenGLとDirectXの両方をラップすることは非常に可能であることは言うまでもありません(Ogre3D、Irrlichtなどを参照)。
Jason Kozak 2010

あなたがプレイしたゲームを考えてみましょう。それらのうちいくつにDirectXまたはOpenGLを使用するオプションがありますか?これは、2つのライブラリがいずれか1つをサポートできるようにするためのラッパーを作成する数です。あなたの想像力は限られています。:-P
リケット

OpenGLとDirectXのどちらでグラフィックスをレンダリングするかを選択できるゲームがあることを認識していますが、問題はクロスプラットフォームAPIに関するものなので、答えは適切だと思います。最初の段落を編集します。でも。
chiguire 2010

1
問題は、クロスプラットフォームのステートレス低レベルAPIについてです。SDLとAllegroは関係ありません。
NocturnDragon 2010

@NocturnDragon-質問のタイトルは少し誤解を招きます。一見、私は質問が利用可能なAPIの選択に関するものであると予想し、この回答者もそうであったと思います。
a_m0d 2010
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.