在类中使用OpenGL glutDisplayFunc [英] Using OpenGL glutDisplayFunc within class

查看:1057
本文介绍了在类中使用OpenGL glutDisplayFunc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  
void myPixmap :: display()
{
//打开OpenGL窗口(如果尚未打开)
if(!openedWindow)
{
// 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拒绝编译此代码声明:




类型为'void(myPixmap ::)()'的参数不匹配'void是否有一种方法可以在类的成员函数内部使用GLUT工具包,或者必须使用GLUT工具包。我调用程序的 main 函数中的所有GLUT函数?

解决方案

问题是指向实例绑定成员函数的指针必须包括 this 指针。 OpenGL是一个C API,并且不了解这个指针。您必须使用静态成员函数(不需要实例,因此不需要 this ),并设置一些静态数据成员(以访问实例)以便使用 glutDisplayFunc

  class myPixmap 
{
private:
static myPixmap * currentInstance;

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

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

您可能还有C链接与C ++链接的问题,在这种情况下,你必须玩周围有 externC。如果是这样,您可能必须使用全局函数,而不是使用静态成员函数作为回调,并 调用 myPixmap :: draw 。类似的东西:

  class myPixmap 
{
public:
void draw

private:
void setupDrawCallback();
};

myPixmap * g_CurrentInstance;

externC
void drawCallback()
{
g_CurrentInstance-> draw
}

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

所有这一切,尝试尽可能少的更改,



如果你想要多个实例(我不认为大多数人使用GLUT做多个实例,你可能需要找出一个使用std :: map来检索实例的解决方案:

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

你会得到 int 解决其中实例,我不确定:)



FYI,您应该定义不需要参数的函数:

  void some_function(){} 


$ b b

不是

  void some_function(void){} 


I've created a C++ class (myPixmap) to encapsulate the work performed by the OpenGL GLUT toolkit. The display() member function of the class contains most of the code required to set up 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;
    }  
}

The display function passed to glutDisplayFunc() is another member function of the class:


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

However, gcc 4.2.1 on Mac OS X 10.6.4 refuses to compile this code, claiming that:

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

Is there a way to use the GLUT toolkit inside a member function of a class, or must I call all GLUT functions within the main function of the program?

解决方案

The problem is that a pointer to an instance bound member function has to include the this pointer. OpenGL is a C API, and knows nothing about this pointers. You'll have to use a static member function (which doesn't require an instance, and thus no this), and set some static data members (to access the instance) in order to use glutDisplayFunc.

class myPixmap
{
private:
  static myPixmap* currentInstance;

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

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

You may also have problems with C linkage vs C++ linkage, in which case you'll have to play around with extern "C". If so, you might have to use a global function, rather than a static member function as your callback, and have that call myPixmap::draw. Something like:

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);
}

With all of this, try to make as few changes as possible, since this is really kind of a kludge to deal w/ OpenGL being a C API.

If you want multiple instances (I don't think most people using GLUT make multiple instances, but maybe you are), you'll have to figure out a solution using a std::map to retrieve the instance:

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

Where you'd get the int to resolve which instance, I am not sure :)

FYI, you should define functions that take no parameters this way:

void some_function() { }

not

void some_function(void) { }

这篇关于在类中使用OpenGL glutDisplayFunc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆