いくつかのグラフィックス API (DirectX9 および DirectX11) の上に抽象化レイヤーを作成しています。ご意見をお聞かせください。
従来、抽象化したい概念ごとに基本クラスを作成していました。
したがって、典型的な OO のやり方では、たとえばクラス Shader と 2 つのサブクラス DX9Shader および DX11Shader を使用します。
テクスチャなどのプロセスを繰り返します...それらをインスタンス化する必要がある場合、現在のグラフィックス API に応じて適切なサブクラスを返す抽象ファクトリがあります。
RAII に従って、返されるポインターは std::shared_ptr にカプセル化されます。
これまでのところうまくいっていますが、私の場合、このアプローチにはいくつかの問題があります。
- 両方の API (および将来的には他の API) の機能をカプセル化するパブリック インターフェイスを考え出す必要があります。
- 派生クラスは別々の DLL (DX9 用に 1 つ、DX11 用に 1 つなど) に格納されており、クライアントでそれらに shared_ptr を設定するのは呪いです: 終了時にグラフィック DLL がアンロードされ、クライアントにまだ shared_ptr がある場合アンロードされた DLL からのコードの呼び出しが原因で、グラフィックス オブジェクトの 1 つがブーム、クラッシュします。
これにより、私は自分のやり方を再設計するようになりました.リソースへの生のポインターを返すだけで、グラフィックス API をきれいにすることができると思っていましたが、クライアント側にぶら下がっているポインターの問題とインターフェイスの問題がまだあります. COM のような手動参照カウントも考えましたが、それは後退だと思いました (shared_ptr の世界から来て、手動参照カウントは原始的なようです)。
次に、すべてのグラフィックス クラスが整数 ID で表される Humus の作業を見ました (OpenGL と同じように)。新しいオブジェクトを作成すると、その整数 ID のみが返され、ポインターが内部に保存されます。それはすべて完全に不透明です!
抽象化を表すクラス (DX9Shader など) はすべて、唯一のインターフェイスであるデバイス API の背後に隠されています。
テクスチャを設定したい場合は、device->SetTexture(ID) を呼び出すだけで、残りは舞台裏で行われます。
残念なことに、API の隠れた部分が肥大化していること、それを機能させるために必要なボイラー プレート コードがたくさんあること、そして私はすべてを行うクラスのファンではないことです。
アイデア/考えはありますか?