在类中使用OpenGL glutDisplayFunc

时间:2010-08-28 04:06:30

标签: c++ opengl class compiler-errors

我创建了一个C ++类(myPixmap)来封装OpenGL GLUT工具包执行的工作。该类的display()成员函数包含设置GLUT所需的大部分代码。


void myPixmap::display()
{
    // open an OpenGL window if it hasn't already been opened
    if (!openedWindow)
    {
        // command-line arguments to appease glut
        char *argv[] = {"myPixmap"};
        int argc = 1;
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
        glutInitWindowSize(640, 480);
        glutInitWindowPosition(30, 30);
        glutCreateWindow("Experiment");
        glutDisplayFunc(draw);
        glClearColor(0.9f, 0.9f, 0.9f, 0.0);
        glClear(GL_COLOR_BUFFER_BIT);
        glutMainLoop();

        openedWindow = true;
    }  
}

传递给glutDisplayFunc()的显示函数是该类的另一个成员函数:


void myPixmap::draw(void)
{
    glDrawPixels( m,n,GL_RGB,GL_UNSIGNED_BYTE, pixel );
}

但是,Mac OS X 10.6.4上的gcc 4.2.1拒绝编译此代码,声称:

argument of type 'void (myPixmap::)()' does not match 'void (*)()'

有没有办法在类的成员函数中使用GLUT工具包,还是必须在程序的main函数中调用所有GLUT函数?

4 个答案:

答案 0 :(得分:32)

问题是指向实例绑定成员函数的指针必须包含this指针。 OpenGL是一个C API,对this指针一无所知。您将不得不使用静态成员函数(不需要实例,因此不需要this),并设置一些静态数据成员(以访问实例)以使用glutDisplayFunc

class myPixmap
{
private:
  static myPixmap* currentInstance;

  static void drawCallback()
  {
    currentInstance->draw();
  }

  void setupDrawCallback()
  {
    currentInstance = this;
    ::glutDisplayFunc(myPixmap::drawCallback);
  }
};

您可能还遇到C链接与C ++链接的问题,在这种情况下,您将不得不使用extern "C"。如果是这样,您可能必须使用全局函数而不是静态成员函数作为回调,并且 调用myPixmap::draw。类似的东西:

class myPixmap
{
public:
  void draw();

private:
  void setupDrawCallback();
};

myPixmap* g_CurrentInstance;

extern "C"
void drawCallback()
{
  g_CurrentInstance->draw();
}

void myPixmap::setupDrawCallback();
{
  ::g_CurrentInstance = this;
  ::glutDisplayFunc(::drawCallback);
}

考虑到所有这些,尽量做出尽可能少的更改,因为这真的是将OpenGL作为C API进行交易的一种方法。

如果你想要多个实例(我不认为大多数人使用GLUT创建多个实例,但也许你是),你将不得不找出一个使用std :: map来检索实例的解决方案:

static std::map<int, myPixmap> instanceMap;

您需要int来解析哪个实例,我不确定:)

仅供参考,您应该以这种方式定义不带参数的函数:

void some_function() { }

void some_function(void) { }

答案 1 :(得分:4)

请查看本教程,我认为这是您正在寻找的内容: http://paulsolt.com/2010/08/glut-object-oriented-framework-on-github/

答案 2 :(得分:2)

Merlyn解决方案对我不起作用,所以我做了一些修改,将当前的Instance带到了课堂之外并且它有效:

Class myPixmap;
static myPixmap* currentInstance;
Class myPixmap {
...
}

答案 3 :(得分:1)

我无法理解Merlyn的正确答案,所以这里是简化版本:

myPixmap.h 中,将显示功能更改为静态成员函数。应该工作。

class myPixmap
{
  //...
  static void display();
  //...
};