Currently my app uses just Direct3D9 for graphics, however in the future I’ m planning to extend this to D3D10 and possibly OpenGL. The question is how can I do this in a tidy way?
At present there are various Render methods in my code
void Render(boost::function<void()> &Call) { D3dDevice->BeginScene(); Call(); D3dDevice->EndScene(); D3dDevice->Present(0,0,0,0); }
The function passed then depends on the exact state, eg MainMenu->Render, Loading->Render, etc. These will then oftern call the methods of other objects.
void RenderGame() { for(entity::iterator it = entity::instances.begin();it != entity::instance.end(); ++it) (*it)->Render(); UI->Render(); }
And a sample class derived from 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(); };
Each method then takes care of how best to render given the more detailed settings (eg are pixel shaders supported or not).
The problem is I’m really not sure how to extend this to be able to use one of, what may be somewhat different (D3D v OpenGL) render modes…
Define an interface that is sufficient for your application’s graphic output demands. Then implement this interface for every renderer you want to support.
Properly designing and maintaining these interfaces can be very challenging though.
In case you also operate with render driver dependent objects like textures, you can use a factory pattern to have the separate renderers each create their own implementation of e.g. ITexture using a factory method in IRenderer:
Isn’t it an idea to look at existing (3d) engines though? In my experience designing this kind of interfaces really distracts from what you actually want to make 🙂