I want to program a game which works in OpenGL and DirectX. I know that I have to program my functions once with OpenGL API and once with DirectX API. But how can I choose the graphics API before my game starts.
In my programm I have a superclass which have pure virtual functions which have to be implemented by subclasses. The subclasses are classes which use the specific renderAPI to execute the function .
Here you have a little example to make it clear:
#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;
}
How can I change my static variable api before my game starts? I have an idea but I am not sure it is the correct way. For example use int main(int argc, char *argv[])
and give the graphic API in the command line. But how make it big companys in the reality.
CodePudding user response:
You can use an abstract interface and inheritance.
Make an abstract class (struct) that contains the API you want to use:
struct My_API
{
virtual void draw_line(const Point& start, const Point& end) = 0;
}
Using the Factory Design Pattern, create child classes that implement the API using the framework of your choice:
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;
};
Now you can do something like this:
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);
The big companies in reality use only one framework and tailor it to their needs. The brave companies write their own frameworkds.
CodePudding user response:
The big companies would have a configuration file, in the start of the main function, you would read the file and capture the value of the API you should be using. Then in your game you would have a window/panel/screen in which you can select values, after changing those values the new value would be saved to that configuration file. Next time your software comes up, it will read the file and there will be a new value there, specifying a new API.
Regarding code, you would have actually something like this:
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
Then in your main function you would have something like this:
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().....