2017-08-06 8 views
1

私はレンダリングエンジンのAPI抽象化レイヤーを作成する予定です。私が含める2つのAPIは、D3D11とD3D12です。 私はいくつかのインターフェイスと各APIのそれぞれの実装を記述することから始めました。API抽象化レイヤー - APIインターフェイスの混合を避ける

次のコードスニペットexamplifiesこの:

class IDevice 
{ 
    //... (pure) virtual methods 
}; 

class CD3D11Device : public IDevice 
{ 
    //... virtual method implementations 
}; 

class CD3D12Device : public IDevice 
{ 
    //... virtual method implementations 
}; 

これまでのところは良いです。今実際の問題へ: IDevice*をパラメータとして必要とするメソッドを持つ別のインターフェイスがある場合、「正しい」デバイスが確実に渡されるようにするにはどうすればよいですか?

class ISomeClass 
{ 
public: 
    virtual void foo(IDevice* pDev) = 0; 
}; 

class CD3D11SomeClass : public ISomeClass 
{ 
public: 
    virtual void foo(IDevice* pDev) override 
    { 
     // should only be passed CD3D11Device 
    } 
}; 

class CD3D12SomeClass : public ISomeClass 
{ 
public: 
    virtual void foo(IDevice* pDev) override 
    { 
     // should only be passed CD3D12Device 
    } 
}; 

私はIDevice*ポインタに毎回dynamic_castを呼び出し、nullptrをチェックすることができることを知っているが、それは、パフォーマンスに関してで面倒なだけでなく、高価です。

この問題の解決方法はありますか?プロ/商用ゲームエンジンがそれにどのように対処しているか知っていますか?

+5

どのIDevice型が渡されているかは気にしないでください。それが抽象的なインターフェースの全体のポイントです。 – juanchopanza

+1

私は多くの人がグラフィックスエンジンでこの種のことをしようとしているので、私は賞賛しました。私の経験はちょっと違います。私は、特定のリリースで1つのAPIバージョンに固執しようとしているので、これらの問題はすべて避けてください。サポートするすべてのAPIは、実行するテストの量を倍増させます。 – Robinson

答えて

1

インターフェイスを単なるラッピングよりも抽象度が遠くになければ、D3D11とを一緒に抽象化することはできません。彼らの設計はあまりにも対称的に反対している。あなたが必要とするものは、高度に抽象的な単一のレンダリングエンジンインターフェイスを設計することです。 Material,またはModelのようなものは、SceneまたはRenderListのような側面に沿った厳しい底辺にする必要があります。単一のアプリケーションで複数のグラフィックスAPIのサポートについては

、あなたはここで間違ってそれを得る、あなたはD3D12を持っている場合、選択肢はD3D12/VulkanD3D11/GLあるべきD3D11コードパスにはポイントがありません。これはAPIの類似性のためではなく、アプリケーションで必要な機能が設定されているためです。

D3D12D3D11を置き換えるものではないため、前者は大量のデータセットにAAAゲームや重いGPGPUなどのアプリケーションの1%が存在するためです。 D3D11の専門家でなく、正確にD3D12を使用する必要がある理由がわからない場合は、使用しないでください!

関連する問題