带有类的C++中的GLUT代码
GLUT code in C++ with classes
下面是绘制矩形的代码,但我在glutdisplayFunc()中遇到了一个错误。我该怎么修?
#include <iostream>
#include <glut.h>
using namespace std;
class GUI
{
public:
int W,H;
GUI()
{
W = 800;
H = 600;
glClearColor(0, 0, 0, 0);
gluOrtho2D(-W, W, -H, H);
glMatrixMode(GL_PROJECTION);
}
void display()
{
glBegin(GL_POLYGON);
glVertex2d(-500, 300);
glVertex2d(500, 300);
glVertex2d(500, -300);
glVertex2d(-500, -300);
glEnd();
glFlush();
}
};
int main(int argv, char **argc)
{
GUI ob;
glutInit(&argv, argc);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowSize(ob.W, ob.H);
glutInitWindowPosition(100, 100);
glutCreateWindow("Queen Problem");
glutDisplayFunc(ob.display); //Error
glutMainLoop();
return 0;
}
我正在使用Visual;工作室;2010年。我在OpenGL中创建了一些程序,但没有任何冲突。这是我第一次在OpenGL中使用类。
错误为:
错误1错误C3867:"GUI::display":函数调用缺少参数列表;使用'&GUI::display'以创建指向成员的指针。
我尝试使用&GUI::display
,但它也导致了错误。
C++和C不共享相同的链接和ABI。此外,对于类,还有一个称为"this"指针的"隐式"参数,该参数是隐藏的并为您解析。在内部,这将改变您所期望的函数签名,编译器会处理细节以确保这一点有效。C函数调用需要对具有所需签名的函数的引用。它也没有办法直接互操作,您必须以某种方式桥接它。
- 您收到错误消息的原因是,您将函数display()定义为GUI类的成员函数,或者您没有将display()函数定义为GUI类别的成员,并且您正试图从GUI类别调用它
- 要解决这个问题,您需要将display()函数定义为GUI的非成员函数,不带任何输入参数。如果它是非成员函数,则不能执行此操作。ob.display.glutDisplayFunc不接受成员函数
- 要引用GUI类上的非成员函数display(),需要这样调用它
- glutDisplayFunc(&display)
C++没有称为";"闭包" 此外,GLUT是一个C API,这意味着即使C++支持闭包,GLUT也不知道如何使用它。 所以你必须使用一个非成员函数,使用它来调用实例上的类成员函数。大多数C API允许您提供回调参数(通常以 您的代码还有其他问题。在出现OpenGL上下文之前,先安装 更糟糕的是:构造函数中的所有调用实际上都属于绘图代码。void*
的形式)。但是GLUT并不能做到这一点,所以实际上您只能调用类的全局实例。更新
GUI
。OpenGL上下文由glutCreateWindow
创建。但是"GUI"构造函数进行OpenGL调用,如果没有可用的构造函数,这些调用将无效。
解决方案
- 使
display
为静态 - 或者去掉GUI类。如果你只有一个窗口,你其实并不需要它
- 制作GUI类的单个全局实例,并从供过于求显示回调中调用其
display()
方法 - 或者使用不同的库来初始化OpenGL
- 或者想办法通过";这个";指针穿过供过于求
解释
在C++类中,方法有隐藏的this
参数,除非它是静态的。如果没有this
指针,就不能调用非静态类成员。
GLUT需要一个没有this
参数的函数。
如果您不知道CCD_;指针是,你需要得到一本C++书和学习更多。
要么制造";显示";static(在这种情况下,您将无法从方法中访问类成员),或者找到某种方法来传递";这个";要在中使用的指针。
通过供过于求传递this
指针并将调用转发给一个类,如下所示:
class Gui{
public:
void display();
};
void* getWindowData(int id);
void setWindowData(int id, void* p);
void displayForwarded(){
Gui *gui = (Gui*)getWindowData();
if (gui)
gui->display();
}
int main(int argc, char** argv){
....
int windowId = glutCreateWindow();
Gui gui;
setWindowData(windowId, &gui);
glutDisplayFunc(displayForwarder);
}
问题在于getWindowData()
和setWindowData()
的内容。如果您使用的是OpenGLUT,您可以在其中使用glutSetWindowData
函数。
在FreeGLUT中,你可以滥用窗口标题来传递指针(坏主意,不要这样做),但这是一种糟糕的体验。
所以剩下的就是创建一个全局映射,通过它将窗口id转换为用户数据指针和用户数据。
typedef int WindowId;
typedef std::map<WindowId, Gui*> GuiMap;
namespace Internal{
GuiMap guiMap;
}
class Gui{
public:
...
void display();
}
void setWindowGui(WindowId id, Gui* p){
Inertnal::guiMap[id] = p; // guiMap.insert(std::make_pair(id, p))
}
Gui* getWindowGui(WindowId id){
GuiMap::iterator found = Internal.guiMap.find(id);
if (found == Internal.guiMap.end())
return 0;
return found.second;
}
void displayForwarder(){
WindowId = getGetWindow();//glut function
Gui *gui = getWindowGui(id);
if (!gui)
throw std::string("gui not found");
gui->display();
}
int main(int argc, char** argv){
...
Gui gui;
WindowId window = glutCreateWindow(.....);...
setWindowGuiwindow, &gui);
glutDisplayFunc(displayForwarder);
...
...
}
如果你不明白答案,那就拿一本C++书读一读。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- .cpp和.h文件中的模板专用化声明
- 反向给定链表中的K节点
- 正在查找文档以获得PS4平台的C++中的设备信息
- enum是C++中的宏变量还是整数变量
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 使用键盘功能修改C GLUT中的2D数组指针
- 在opengl中使用Glut的Vsync麻烦
- GLUT 显示桌面的一部分,而不是我的代码中的内容
- 从Glut中的滚轮获取输入
- 鼠标拖动OpenGL/GLUT中的对象
- glTexImage2D 在 OpenGL 3 及更高版本的 GLUT/FreeType 示例中失败
- 摆脱在Qt QGlWidget中绘制实体对象的glut函数
- GLUT中的流畅键盘输入
- C++中的扫描线填充 OpenGL/GLUT 算法
- 带有类的C++中的GLUT代码
- opengl/glut 中的 renderDisplayFunc 不止一次调用 myfunc
- GLUT中的平滑移动
- 使用非成员方法作为GLUT中的回调
- Windows 8 中的 glut 空闲 - 重新渲染