目前我的应用程序仅使用Direct3D9进行图形处理,但是将来我计划将其扩展到D3D10和可能的OpenGL.问题是如何以一种整洁的方式做到这一点?
目前我的代码中有各种Render方法
void Render(boost::function&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)渲染模式......
定义足以满足应用程序图形输出要求的界面.然后为要支持的每个渲染器实现此接口.
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)引擎不是一个想法吗?根据我的经验,设计这种接口真的会分散你真正想要的东西:)