How to pass a non-stationary member function to glutDisplayFunc

I have a class that has functionality to initialize opengl and runs it in a separate thread.

My problem: openGL calls like glutDisplayFunc, glutMotionFunc etc. void (* f) void, and I cannot pass a member function to a class.

. 1) I can declare a member function as static, but in this case I need to declare all used member variables as static and ultimately declare the whole class as static.

2) I can use some autonomous function and declare my object global, but this is too bad.

I wonder if there are any ways, so I don’t need to set the opengl static class? (using C ++)

+6
c ++ static opengl
source share
4 answers

You will need to create a "thunk" or "trampoline" function : C API functions in the code of a C ++ member function

+4
source share

Since callbacks take no parameters, you cannot do much. One option is to create a namespace with functions and a static data member, which is your current class. These functions simply redirect function calls to an existing class. This is just a slightly cleaner version of your # 2.

namespace GLForwader { static MyGLClass* = new myGlClass(); void glutDisplayFunc() {myGlClass->glutDisplayFunc();} void glutMotionFunc() {myGlClass->glutMotionFunc();} } 
+2
source share

A simple workaround is:

Declare a global pointer to your class and initialize it in main (), let callback call the regular method on this instance

 MyOGLClass *g_pOGL; void oglDraw() { if(g_pOGL) g_pOGL->oglDraw(); } void main() { // Init your class MyOGLClass o; g_pOGL = &o; //... glutMainLoop(); } 

Limitation: you can have only one instance of your class, but for an OpenGL application this is not as bad as you really need anyway ...

0
source share

I just searched for this, since I had the same problem when cleaning and OOP'ing our code. It turns out that nice things like std :: bind don't work here, but if you are compiling in C ++ 11, you can actually define an anonymous function to wrap your member function.

 class Renderer { void Start(); void Render(); } // ... void Renderer::Start() { // ... glutDisplayFunc([](){ Render(); }); } 
0
source share

All Articles