I am trying to write some boilerplate code for a game in C++. I want to draw using both SDL and OpenGL. For example, I would like to have 2 versions of the functions “DrawPixel” written in both OpenGL and SDL. I can’t use both SDL and OpenGL for rendering at the same time, but I would like a common interface for the drawing so I don’t have to write twice as much when implementing the game.
I can write a base class with all the drawing functions I want in virtual, and then overload 2 versions of it for SDL and OpenGL. The problem is the performance, since I may end up calling DrawPixel million and millions of times every second, resolving the virtual calls will be expensive.
What other options do I have other than this OO approach? (or you could tell me that virtual isn’t slow)
Before I get into answering your question, have you considered making this a compile-time flag, e.g. #define — That would let you decide on either GL or SDL, without wasting space or requiring a virtual call. Definitely go for this solution if you can.
Virtual functions are just an extra pointer lookup, calling a pointer-referenced function instead of a constant value. — and they have a big drawback that they cannot be inlined as the compiler doesn’t know where the function is. This is going to be the problem for any program which decides the functions at runtime.
I’ll start with a warning: these may be micro-optimizations that aren’t worth worrying about. I would perhaps consider doing performance benchmark to see how important this is. For example, GL and SDL calls are already in a separate library, so each of them probably already require pointer lookups, among other things. An extra pointer is probably the least of your concerns.
If you really can’t decide at compile-time, the only simple method IMHO that avoids virtual calls is to use C++ templates to do the job. In your case, I would make two separate classes with a function for each GL or SDL function you need, named the same, but do not make them virtual. Then, every function/class in your whole program which uses these functions would need to be declared as a template, either using SDL or GL. Finally, in your top-level main() function, have an if statement which runs one or the other version of your program depending on which version you want.
This will lead to a perfectly efficient solution, even inlining all functions which can be inlined; however, at the cost of having two copies of your program and taking up more space. Also — because it results in a larger program, this may actually reduce performance.
If you don’t want templates, one weird way that might also work would be to get the loader to use one of two different dynamically linked libraries. Both libraries would export the same functions, and then you would choose to load either one (e.g. by setting the LD_LIBRARY_PATH to one directory)