4

現在、私のアプリはグラフィックスに Direct3D9 のみを使用していますが、将来的にはこれを D3D10 および場合によっては OpenGL に拡張する予定です。問題は、これをきちんとした方法で行うにはどうすればよいかということです。

現在、私のコードにはさまざまな Render メソッドがあります

void Render(boost::function<void()> &Call)
{
    D3dDevice->BeginScene();
    Call();
    D3dDevice->EndScene();
    D3dDevice->Present(0,0,0,0);
}

渡される関数は、MainMenu->Render、Loading->Render などの正確な状態に依存します。これらは、多くの場合、他のオブジェクトのメソッドを呼び出します。

void RenderGame()
{
    for(entity::iterator it = entity::instances.begin();it != entity::instance.end(); ++it)
        (*it)->Render();
    UI->Render();
}

そして、entity::Base から派生したサンプル クラス

class Sprite: public Base
{
    IDirect3DTexture9 *Tex;
    Point2 Pos;
    Size2 Size;
public:
    Sprite(IDirect3DTexture9  *Tex, const Point2 &Pos, const Size2 &Size);
    virtual void Render();
};

次に、各メソッドは、より詳細な設定 (ピクセル シェーダーがサポートされているかどうかなど) に応じて、最適なレンダリング方法を処理します。

問題は、これを拡張して、多少異なる(D3D v OpenGL)レンダリングモードのいずれかを使用できるようにする方法が本当にわからないことです...

4

2 に答える 2

6

アプリケーションのグラフィック出力要求に十分なインターフェイスを定義します。次に、サポートするすべてのレンダラーにこのインターフェイスを実装します。

class IRenderer {
  public:
    virtual ~IRenderer() {}
    virtual void RenderModel(CModel* model) = 0;
    virtual void DrawScreenQuad(int x1, int y1, int x2, int y2) = 0;
    // ...etc...
};

class COpenGLRenderer : public IRenderer {
  public:
    virtual void RenderModel(CModel* model) {
      // render model using OpenGL
    }
    virtual void DrawScreenQuad(int x1, int y1, int x2, int y2) {
      // draw screen aligned quad using OpenGL
    }
};

class CDirect3DRenderer : public IRenderer {
  // similar, but render using Direct3D
};

ただし、これらのインターフェイスを適切に設計して維持することは、非常に困難な場合があります。

テクスチャなどのレンダ ドライバ依存オブジェクトも操作する場合は、ファクトリ パターンを使用して、IRenderer のファクトリ メソッドを使用して ITexture などの独自の実装をそれぞれのレンダラーに作成させることができます。

class IRenderer {
  //...
    virtual ITexture* CreateTexture(const char* filename) = 0;
  //...
};

class COpenGLRenderer : public IRenderer {
  //...
    virtual ITexture* CreateTexture(const char* filename) {
      // COpenGLTexture is the OpenGL specific ITexture implementation
      return new COpenGLTexture(filename);
    }
  //...
};

しかし、既存の(3D)エンジンを見るのはアイデアではありませんか?私の経験では、この種のインターフェースを設計すると、実際に作りたいものから本当に気が散ってしまいます:)

于 2008-09-13T19:33:55.107 に答える
1

本当に完全な答えが必要な場合は、のソースコードを参照してOgre3Dください。それらには両方D3DOpenGLバックエンドがあります。http://www.ogre3d.org 基本的に、それらのAPIは、D3D風の方法で作業し、バッファーオブジェクトを作成してデータを詰め込み、それらのバッファーで描画呼び出しを発行するように強制しますそれはとにかくハードウェアがそれを好む方法です、それでそれは行くのに悪い方法ではありません。

そして、それらがどのように機能するかを確認したら、先に進んでそれを使用し、すでに提供されているすべてを再実装する手間を省くことができます。:-)

于 2008-09-16T03:09:46.493 に答える