Sto scrivendo un motore di gioco open source chiamato YoghurtGum per piattaforme mobili (Windows Mobile, Android). Questo è stato uno dei miei grandi problemi. Per prima cosa l'ho risolto in questo modo:
class RenderMethod
{
public:
virtual bool Init();
virtual bool Tick();
virtual bool Render();
virtual void* GetSomeData();
}
Hai notato il void*
? Questo perché RenderMethodDirectDraw
restituisce una superficie DirectDraw mentre RenderMethodDirect3D
restituisce un pool di vertici. Anche tutto il resto è stato diviso. Avevo una Sprite
classe che aveva un SpriteDirectDraw
puntatore o un SpriteDirect3D
puntatore. In un certo senso ha fatto schifo.
Quindi ultimamente, ho riscritto molte cose. Quello che ho ora è a RenderMethodDirectDraw.dll
e a RenderMethodDirect3D.dll
. In effetti, puoi provare a utilizzare Direct3D, fallire e utilizzare invece DirectDraw. Questo perché l'API rimane la stessa.
Se vuoi creare uno sprite, non lo fai direttamente ma attraverso una fabbrica. Il factory chiama quindi la funzione corretta nella DLL e la converte in un genitore.
Quindi, questo è RenderMethod
nell'API:
virtual Sprite* CreateSprite(const char* a_Name) = 0;
E questa è la definizione di cui RenderMethodDirectDraw
:
Sprite* RenderMethodDirectDraw::CreateSprite(const char* a_Name)
{
bool found = false;
uint32 i;
for (i = 0; i < m_SpriteDataFilled; i++)
{
if (!strcmp(m_SpriteData[i].name, a_Name))
{
found = true;
break;
}
}
if (!found)
{
ERROR_EXPLAIN("Could not find sprite named '%s'", a_Name);
return NULL;
}
if (m_SpriteList[m_SpriteTotal]) { delete m_SpriteList[m_SpriteTotal]; }
m_SpriteList[m_SpriteTotal] = new SpriteDirectDraw();
((SpriteDirectDraw*)m_SpriteList[m_SpriteTotal])->SetData(&m_SpriteData[i]);
return (m_SpriteList[m_SpriteTotal++]);
}
Spero che abbia senso. :)
PS Mi sarebbe piaciuto usare STL per questo, ma non c'è supporto su Android. :(
Fondamentalmente:
- Mantieni ogni rendering nel suo contesto. O una DLL, una libreria statica o solo un gruppo di intestazioni. Finché hai un RenderMethodX, SpriteX e StuffX sei d'oro.
- Ruba il più possibile dalla fonte degli Ogre.
EDIT: Sì, ha senso avere interfacce virtuali come questa. Se il tuo primo tentativo fallisce, puoi provare un altro metodo di rendering. In questo modo è possibile mantenere agnostico tutto il metodo di rendering del codice.