Question

I've started using OpenGL a while ago, using GLUT. You can't pass member functions to GLUT functions. (or pointers to members for that matter, though I did not explore that option really far).

I was wondering if there is a "decent" way, or what is the "most decent" way to solve this? I know you can use static member functions, but isn't there a better way?

I know there are other libraries, like SFML that are written in C++ and provide a C++ class-based interface, but I was wondering what the possibilities are concerning GLUT (freeglut to be exact).

Was it helpful?

Solution

First, GLUT is not for serious application work. It's for simple graphics demos. And for that purpose, it is fine. If you find yourself trying to do serious work in GLUT, you will find yourself spending lots of time working around its limitations. This limitation is only one of many that you will eventually encounter. GLFW, while still having this limitation (though the next version will not), is generally superior for serious application work.

Second, the "most decent" way to solve this depends on what you're doing. If you only have one window, then the correct solution is just a simple static function, which can global pointers (or functions that return global pointers) to whatever class you're interested in.

If you have multiple windows, then what you need is a global std::map that maps from GLUT's window identifiers to pointers to some object. Then you can get which window a particular function was called from and use the map to forward that call to the particular object that represents that window.

OTHER TIPS

Passing member functions to glut, or any other library, is easy enough. GLUT is looking for a function pointer.

Let Controller be a class with a member function OnKeyPress that we want to send into glutKeyboardFunc. You might first be tempted to try something like

glutKeyboardFunc(&Controller::OnKeyPress);

Here, we are passing a function pointer, however this is incorrect, since you want to send the member function of that class object. In C++11 you can use the new std::bind, or if you are on an older compiler, I would recommend boost::bind. Either way the syntax is around the same.

using namespace std::placeholders; // for the _1, _2 placeholders
glutKeyboardFunc(std::bind(&Controller::OnKeyPress, &GLInput, _1, _2, _3));

From the documentation it looks like glutKeyboardFunc requires 3 parameters. First we fix the first argument memory address of your object, since its a member function, and then supply 3 placeholders.

For those new to std::bind, it feels odd, but for anyone who has done object oriented code in C, its obvious. The function is really just a C function, and needs the "this" pointer to the class. The bind would not be necessary if the callback was a simple function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top