Frage

Zur Zeit meine App nutzt nur Direct3D9 für Grafiken, aber in der Zukunft ich dies D3D10 zu verlängern bin Planung und möglicherweise OpenGL. Die Frage ist, wie kann ich dies in einer ordentlichen Art und Weise zu tun?

Zur Zeit gibt es verschiedene Render-Methoden in meinem Code

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

Die Funktion dann über den genauen Zustand übergeben, hängt zB MainMenu-> Render, Belade-> Render usw. Diese werden dann oftern die Methoden anderer Objekte aufrufen.

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

Und eine Beispielklasse abgeleitet von Einheit :: Base

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

Jede Methode kümmert sich dann um, wie am besten, die detailliertere Einstellungen gegeben zu machen (zB sind Pixel-Shader unterstützt oder nicht).

Das Problem ist, ich bin wirklich nicht sicher, wie diese in der Lage sein, verlängern eines zu verwenden, was etwas anders (D3D v OpenGL) sein kann Rendermodi ...

War es hilfreich?

Lösung

Definieren Sie eine Schnittstelle, die für Ihre Anwendung Grafikausgabeanforderungen genügt. Dann implementieren diese Schnittstelle für jeden Renderer Sie unterstützen möchten.

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
};

Richtig entwerfen und diese Schnittstellen beibehalten kann jedoch sehr schwierig sein.

Falls Sie auch mit machen betreiben Fahrer abhängigen Objekte wie Texturen, können Sie eine Fabrik Muster verwenden die einzelnen Renderer jeweils ihre eigene Implementierung schaffen haben z.B. ITexture unter Verwendung einer Factory-Methode in IRenderer:

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);
    }
  //...
};

Ist es nicht eine Idee, wenn bei bestehenden (3d) Motoren suchen? In meiner Erfahrung in der Entwicklung dieser Art von Schnittstellen ablenkt wirklich von dem, was Sie wirklich wollen, machen:)

Andere Tipps

Ich würde sagen, wenn Sie die Antwort ein wirklich abschließen möchten, gehen Sie auf den Quellcode für Ogre3D suchen. Sie haben sowohl D3D und Enden OpenGL zurück. Schauen Sie sich: http://www.ogre3d.org Grundsätzlich ihre API Art von Kräften in ihr in einer D3D-isch Weise arbeiten, wodurch Puffer Objekte und Füllung sie mit Daten aus, dann fordert diesen Puffern Ausgeben ziehen. Das ist die Art und Weise der Hardware es trotzdem mag, so ist es kein schlechter Weg zu gehen.

Und dann, wenn Sie sehen, wie sie Dinge tun, dann kann man auch einfach nur und es voran gehen verwenden und sich die Mühe ersparen alle neu zu implementieren, die es bereits gibt. : -)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top