C++ C++;上课

C++ C++;上课,c++,glut,C++,Glut,下面是绘制矩形的代码,但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); gluOr

下面是绘制矩形的代码,但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;
}
#包括
#包括
使用名称空间std;
类GUI
{
公众:
int W,H;
GUI()
{
W=800;
H=600;
glClearColor(0,0,0,0);
gluOrtho2D(-W,W,-H,H);
glMatrixMode(GL_投影);
}
无效显示()
{
glBegin(GL_多边形);
glVertex2d(-500300);
glVertex2d(500300);
glVertex2d(500,-300);
glVertex2d(-500,-300);
格伦德();
glFlush();
}
};
int main(int argv,字符**argc)
{
桂ob;
glutInit(&argv,argc);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowSize(ob.W,ob.H);
位置(100100);
“女王问题”;
glutDisplayFunc(ob.display);//错误
glutMainLoop();
返回0;
}
我正在使用。我在中创建了一些程序,但没有任何类别。这是我第一次在OpenGL中使用类

错误是:

错误1错误C3867:“GUI::display”:函数调用缺少参数列表;使用“&GUI::display”创建指向成员的指针

我试图使用
&GUI::display
,但也导致了错误。

C++没有一个称为“闭包”的概念。闭包是一个元组,由一个函数和一个作用域组成,函数在其中执行。类成员函数需要使用类实例。你不能接受一个实例成员函数的函数指针,因为C++中缺少这个概念。

此外,GLUT是一个C API,这意味着即使C++支持闭包,GLUT也不知道如何处理这个。 所以,您必须使用非成员函数来调用实例上的类成员函数。大多数C API允许您提供回调参数(通常以

void*
的形式)。然而,GLUT并不能做到这一点,所以实际上只能调用该类的全局实例

更新 您的代码还有其他问题。在出现OpenGL上下文之前,先实例化
GUI
。OpenGL上下文由
glutCreateWindow
创建。但是“GUI”构造函数进行OpenGL调用,如果没有可用的构造函数,调用无效


更糟糕的是:构造函数中的所有调用实际上都属于绘图代码。

C++和C不共享相同的链接和ABI。此外,对于类,有一个称为“隐式”的参数,称为“this”指针,参数是隐藏的,并为您解析。在内部,这将改变您期望的函数签名,并且编译器会处理细节以确保其正常工作。C函数调用需要对具有预期签名的函数的引用。它也无法直接进行互操作,您必须以某种方式将其连接起来。

  • 您收到错误消息的原因是您将函数display()定义为GUI类的成员函数,或者您没有将display()函数定义为GUI类的成员,并且您试图从GUI类调用它
  • 要解决此问题,您需要将display()函数定义为GUI的非成员函数,不带输入参数。如果它是非成员函数,则不能执行此ob.display。glutDisplayFunc不接受成员函数
  • 要引用GUI类上的非成员函数display(),需要以这种方式调用它
  • glutDisplayFunc(&display)
解决方案
  • 使
    显示
    静态
  • 或者去掉GUI类。如果你只有一个窗口,你并不真的需要它
  • 创建GUI类的单个全局实例,并从glut display回调调用其
    display()
    方法
  • 或用于初始化OpenGL
  • 或者找到一种通过glut传递“this”指针的方法
  • 解释 < C++类方法中有隐藏的<代码> < < /C> >参数,除非它是静态的。 如果没有
    这个
    指针,就不能调用非静态类成员

    GLUT需要一个没有
    这个
    参数的函数

    如果你不知道< <代码> < <代码>指针是什么,你需要得到一本C++书并多学习。< /P> 要么将“display”设为静态(在这种情况下,您将无法从方法中访问类成员),要么找到某种方法传递要在中使用的“this”指针

    通过glut传递
    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,您可能已经在其中使用了函数

    在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);
        ...
        ...
    }
    
    typedef int WindowId;
    typedef std::map GuiMap;
    命名空间内部{
    GuiMap-GuiMap;
    }
    类Gui{
    公众:
    ...
    void display();
    }
    void setWindowGui(WindowId,Gui*p){
    Inertnal::guiMap[id]=p;//guiMap.insert(std::make_pair(id,p))
    }
    Gui*getWindowGui(WindowId){
    GuiMap::iterator found=Internal.GuiMap.find(id);
    if(found==Internal.guiMap.end())
    返回0;
    第二,返回;
    }
    void displayForwarder(){
    WindowId=getWindow();//glut函数
    Gui*Gui=getWindowGui(id);
    如果(!gui)
    抛出std::string(“未找到gui”);
    gui->display();
    }
    int main(int argc,字符**argv){
    ...
    桂桂;
    WindowId window=glutCreateWindow(…);。。。
    setWindowGUI(窗口和gui);
    glutDisplayFunc(显示器转发器);
    ...
    ...
    }
    
    如果你不理解答案,那就找一本C++书吧。