如何在游戏开始前更改游戏中的图形API



我想编程一个可以在OpenGL和DirectX中工作的游戏。我知道我必须用OpenGL API和DirectX API对我的函数编程一次。但我如何才能在我的游戏开始前选择图形API。

在我的程序中,我有一个超类,它有纯虚拟函数,必须由子类实现。子类是使用特定renderAPI来执行函数的类。

这里有一个小例子可以说明这一点:


#include <iostream>
class Renderer{
public:

enum API{
None=0,
OpenGL = 1,
DirectX = 2
};

virtual void bindBuffer() = 0;
};
class OpenGLBuffer: public Renderer{
public:
virtual void bindBuffer(){
//opengl Code
}
};
static Renderer::API api = Renderer::API::OpenGL;  
using namespace std;
int main()
{

switch(api){
case Renderer::API::None:
cout<<"Nothing" << std::endl;
break;
case Renderer::API::OpenGL:
cout<<"OpenGL code" << std::endl;
break;
case Renderer::API::DirectX:
cout<<"DirectX code" << std::endl;
break;
}
return 0;
}

如何在游戏开始前更改静态变量api?我有一个主意,但我不确定这是正确的方法。例如,使用int main(int argc, char *argv[])并在命令行中给出图形API。但如何在现实中使其成为大公司。

您可以使用抽象接口和继承。

制作一个包含要使用的API的抽象类(结构(:

struct My_API
{
virtual void draw_line(const Point& start, const Point& end) = 0;
}

使用工厂设计模式,创建使用您选择的框架实现API的子类:

struct OpenGL_API : public My_API
{
void draw_line(const Point& start, const Point& end) override;
};
struct DirectX : public My_API
{
void draw_line(const Point& start, const Point& end) override;
};

现在你可以做这样的事情:

My_API * p_api = nullptr;
switch (api)
{
case USING_DIRECTX:  p_api = new DirectX; break;
case USING_OPENGL:   p_api = new OpenGL; break;
}
// Draw the line
p_api->draw_line(start_point, end_point);

事实上,大公司只使用一个框架,并根据自己的需求进行调整。勇敢的公司编写自己的框架。

大公司将有一个配置文件,在主函数的开头,您将读取该文件并获取您应该使用的API的值。然后在你的游戏中,你会有一个窗口/面板/屏幕,你可以在其中选择值,在更改这些值后,新值将保存到该配置文件中。下一次软件启动时,它将读取该文件,并且会有一个新值,指定一个新的API。

关于代码,你实际上会有这样的东西:

static Renderer *api; //a pointer of a generic renderer
static OpenGlRenderer openGlApi;//an actual instance of a specific renderer
static DirectxRenderer directxApi;//an actual instance of a specific renderer

然后在你的主要功能中,你会有这样的东西:

auto configuration = readMyConfigFileFunction("config.configdata");
switch(configuration.api){
case Renderer::API::None:
cout<<"Nothing" << std::endl;
break;
case Renderer::API::OpenGL:
api = &openGlApi;
break;
case Renderer::API::DirectX:
api = &directxApi;
break;
}
//then 
api->doRendering().....

最新更新