Pregunta

Actualmente mi aplicación usa sólo Direct3D9 para los gráficos, sin embargo, en el futuro, estoy planeando extender esto a D3D10 y posiblemente OpenGL.La pregunta es ¿cómo puedo hacer esto en una forma óptima?

En la actualidad existen diversos métodos de Procesamiento en mi código

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

La función se pasa, a continuación, depende del estado exacto, por ejemplo, la MainMenu->Render, Carga->Render, etc.Estos serán entonces oftern llamar a los métodos de otros objetos.

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

Y una muestra de la clase derivada de la entidad::Base

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

Cada método se encarga entonces de la mejor manera de representar dado que la configuración más detallada (por ejemplo, son los sombreadores de píxeles compatible o no).

El problema es que realmente no estoy seguro de cómo extender esta para ser capaz de usar uno de, lo que puede ser algo diferente (D3D v OpenGL) modos de procesamiento...

¿Fue útil?

Solución

Definir una interfaz que es suficiente para la aplicación del gráfico de salida de las demandas.Implementar esta interfaz para cada representador que quiere apoyar.

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

Correctamente el diseño y mantenimiento de estas interfaces pueden ser muy difícil, sin embargo.

En caso de que también operan con procesar el controlador de objetos dependientes como las texturas, se puede utilizar un patrón de fábrica que han separado a los renderizadores de que cada uno cree su propia aplicación, por ejemplo, deITexture el uso de un método de fábrica en 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);
    }
  //...
};

¿No es una idea mirar existente (3d) de los motores, aunque?En mi experiencia en el diseño de este tipo de interfaces realmente distrae de lo que realmente quieren hacer :)

Otros consejos

Yo diría que si usted desea un muy completa la respuesta, voy a ver el código fuente de Ogre3D.Ambos han D3D y OpenGL la parte final.Mira : http://www.ogre3d.org Básicamente su API tipo de fuerzas en el trabajo en un D3D-ish manera, la creación de objetos de búfer y relleno con los datos, la emisión de dibujar pide a los búferes.Esa es la forma en que el hardware gusta de todos modos, así que no es una mala manera de ir.

Y, a continuación, una vez que vea cómo hacer las cosas, bien podría simplemente seguir adelante y utilizar y ahorrarse la molestia de tener que volver a implementar todos los que ya proporciona.:-)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top