2013-08-04 26 views
2

我編碼一個遊戲引擎類,我一直建議增加此#定義處理多個API以這種方式:在運行時或編譯時更改API?

#ifdef OGL 
    typedef COpenGl CBaseApi; 
#elif defined(OGLES) 
    typedef COpenGlEs CBaseApi; 
#elif defined(DX9) 
    typedef CDirectX9 CBaseApi; 
#elif defined(DX10) 
    typedef CDirectX10 CBaseApi; 
#elif defined(DX11) 
    typedef CDirectX11 CBaseApi; 
#endif 

而且我有兩個問題:我怎樣才能獲得以上工作?

我想:

class CBaseAPI 
{ 
    //abstract class, virtual functions 
} 
class COpenGL : public CBaseAPI 
{ 
    //implementations 
} 

但正如我預料它沒有工作。

第二個問題是,這種#define方法比使用某種工廠更好嗎?我最初是這樣做的:

//inside the Main program 
myGameEngine.Initialize(GraphicAPI::DirectX11); 

//inside the Initialize function 
void GameEngine::Initialize(GraphicAPI graphicAPI) 
{ 
    switch(graphicAPI) 
    { 
     case GraphicAPI::DirectX11: 
     { 
      //Defined as private members:     
      //BaseAPI graphicAPI; 

      //class CDirectX11 : public BaseAPI 

      graphicAPI = new CDirectX11(); 
     } 
     //other cases here 
    } 
} 

這些方法有什麼優點和缺點,什麼是首選嗎?

回答

-1

第二個是可怕的。兩階段初始化非常容易出錯,在一般情況下,遊戲完全不需要在運行時更改渲染API。使用接口和繼承完全浪費時間和性能,更不用說失去了很好的強類型。

對於#define,沒有必要通過繼承鏈接這些類。你可能會更好地使用模板,但條件編譯是預處理器的功能。簡單的使用場景:

class OGL { 
public: 
    void dostuff(); 
}; 
class DX { 
public: 
    void dostuff(); 
}; 
class GameEngine { 
#ifdef USE_OPENGL 
    OGL BaseAPI; 
#else 
    DX BaseAPI; 
#endif 
public: 
    void dostuff() { BaseAPI.dostuff(); } 
}; 

此外,CClass? Owch。你需要找到新的學習材料,好友。

+0

所以你將不得不重新編譯來改變渲染API? – Hna

+0

@Hna能夠在運行時更改渲染API不值得額外的性能成本。 – Borgleader

+0

@Borgleader不要在運行時改變它。更像是讀取命令行參數或用戶設置文件,然後選擇渲染API。你不能用預處理器指令來做到這一點。 – Hna

0

您似乎有一個與基類(CBaseApi)具有相同名稱的typedef。這不會很好。

您是不是要找這樣的:

class CBaseAPI 
{ 
    //abstract class, virtual functions 
}; 
class COpenGlEs : public CBaseAPI 
{ 
    // implementations 
}; 

#ifdef OGL 
    typedef COpenGl BaseApiImpl; 
#elif defined(OGLES) 
    typedef COpenGlEs BaseApiImpl; 
#elif defined(DX9) 
    typedef CDirectX9 BaseApiImpl; 
#elif defined(DX10) 
    typedef CDirectX10 BaseApiImpl; 
#elif defined(DX11) 
    typedef CDirectX11 BaseApiImpl; 
#endif