我为openGl操作创建了一个类。现在,过度回调函数需要函数的指针作为参数。我通过实例化类的对象来提供成员函数。它显示了像
这样的错误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);
头文件的代码在这里:
#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(){}
};
和main.cpp的那个是:
#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;
}
答案 0 :(得分:0)
问题就在这一行我猜:
glutDisplayFunc(std::bind(&glActivity::display,&GLactivity));
问题是glutDisplayFunc
是一个C函数,std::bind
返回一个C ++对象,这是任何C函数都无法处理的。
您必须提供C函数可以处理的内容,例如纯函数指针或非捕获lambda。
答案 1 :(得分:0)
GLUT不会让你这么容易,但如果你理解GLUT调用回调时存在的条件,就有可能。
大多数基于C的API允许您为用户数据传递void*
,并允许您通过强制转换到适当的接口,将基于C的回调分派给C ++类的实例。 GLUT不这样做,绝对没有特定于实例的信息传递给你的回调。
但是,当GLUT调用回调时,它会使用已建立的&#34;当前窗口&#34; 进行回调。您可以通过调用glutGetWindow (...)
手动查询当前窗口,然后使用它。
glActivity* windows [2];
void glut_display_callback (void)
{
windows [glutGetWindow ()]->display ();
}
你会想要在现实世界中使用比数组更复杂的东西,因为窗口ID甚至不是从GLUT中的 0 开始,但这给你一般的想法。