0

I have made an class for openGl manipulation. Now the glut call back functions need the pointer of the function as an argument. and I am providing the member function by instantiating an object of the class.And it shows an error like

main.cpp: In function ‘int main(int, char**)’:
main.cpp:23:64: error: cannot convert ‘std::_Bind_helper<false, void (glActivity::*)(), glActivity*>::type {aka std::_Bind<std::_Mem_fn<void (glActivity::*)()>(glActivity*)>}’ to ‘void (*)()’ for argument ‘1’ to ‘void glutDisplayFunc(void (*)())’
     glutDisplayFunc(std::bind(&glActivity::display,&GLactivity));
main.cpp:24:51: error: cannot convert ‘GlActivity::reshape’ from type ‘void (GlActivity::)(int, int)’ to type ‘void (*)(int, int)’
     glutReshapeFunc(GLactivity.GlActivity::reshape);

my code for header file is here:

#include<GL/freeglut.h>
#include<GL/gl.h>
class GlActivity{
protected:
    bool keys[256];
public:
    /*Initialize material property,light source,lighting model
     *and depth buffer through the constructor call.
     */
    GlActivity(){
    glShadeModel(GL_FLAT);
    //glEnable(GL_LIGHTING);
    //glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }
    void Keydown(unsigned char ch,int x,int y){
        if(ch == 27) glutExit();
        keys[ch]=true;
    }
    void keyup(unsigned char ch,int x,int y){
        keys[ch]=false;
    }
    void display(void){
    }
    void reshape( int w,int h){
        glViewport(0,0,(GLsizei) w,(GLsizei) h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        if(w <= h)
            glOrtho(-1.5,1.5,-1.5*(GLfloat)h/(GLfloat)w,
            1.5*(GLfloat)h/(GLfloat)w,-10.0,10.0);
        else
            glOrtho(-1.5,1.5,-1.5*(GLfloat)w/(GLfloat)h,
            1.5*(GLfloat)w/(GLfloat)h,-10.0,10.0);
            glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }
    void idle(){}
};

and that for main.cpp is:

#include"matrix.h"
#include"GlActivity.h"
#include <functional>
class glActivity : public GlActivity{
public:
    glActivity():GlActivity(){}
    void display(){
        glBegin(GL_TRIANGLES);
            glVertex2f(0.0f,1.0f);
            glVertex2f(0.87f,-0.5f);
            glVertex2f(-0.87f,-0.5f);
        glEnd();
        glFlush();
    }
};
int main(int argc,char** argv){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow(argv[0]);
    glActivity GLactivity;
    glutDisplayFunc(std::bind(&glActivity::display,&GLactivity));
    glutReshapeFunc(GLactivity.GlActivity::reshape);
    glutKeyboardFunc(GLactivity.GlActivity::keydown);
    glutKeyboardFunc(GLactivity.GlActivity::keyup);
    glutIdleFunc(GLactivity.GlActivity::idle);
    glutMainLoop();
    return 0;
}
Shehary
  • 9,926
  • 10
  • 42
  • 71
chitraketu Pandey
  • 153
  • 1
  • 1
  • 8
  • You already know how to pass a member function pointer, but the library you're using won't accept one. – Ben Voigt Jan 09 '15 at 17:11
  • possible duplicate of [Callback to non-static method](http://stackoverflow.com/questions/2067498/callback-to-non-static-method) – Ben Voigt Jan 09 '15 at 17:13
  • oh... Mjolnir didn't work, because you used [tag:c++11] without also [tag:c++] – Ben Voigt Jan 09 '15 at 17:14
  • Anyway, your question has been asked before, many times: http://stackoverflow.com/search?q=opengl+c%2B%2B+callback+member – Ben Voigt Jan 09 '15 at 17:15

2 Answers2

1

GLUT is not going to make this easy for you, but it is possible if you understand the conditions that exist when GLUT invokes a callback.

Most C-based APIs let you pass a void* for user-data and that allows you to dispatch C-based callbacks to an instance of a C++ class simply by casting to the appropriate interface. GLUT does not do this, absolutely no instance specific information is passed to your callback.

However, when GLUT invokes a callback, it does so with an established "current window". You can manually query the current window by calling glutGetWindow (...) and use that instead.

So you might consider something like this:

glActivity* windows [2];

void glut_display_callback (void)
{
  windows [glutGetWindow ()]->display ();
}

You would want to use something more sophisticated than an array in the real-world, since window IDs do not even start at 0 in GLUT, but this gives you the general idea.

Community
  • 1
  • 1
Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
0

The problem is this line I guess:

glutDisplayFunc(std::bind(&glActivity::display,&GLactivity));

The problem is that glutDisplayFunc is a C function, and std::bind returns a C++ object, something which can't be handled by any C function.

You must provide something which a C function can handle, like a pure function pointer, or a non-capturing lambda.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621