在类中使用OpenGL glutDisplayFunc [英] Using OpenGL glutDisplayFunc within class
问题描述
我创建了一个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屋!