c++ tiene múltiples opciones de gráficos
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...
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.:-)