• openGL中的函数调用类成员函数


    做图形学作业终于到的问题。打算将每一个场景抽象为一个Scene类,然后调用类的run接口来显示场景。

    其中遇到了关于glutDisplayFunc函数调用的问题,函数原型为:

    extern void APIENTRY glutDisplayFunc(void (*func)(void));

    即要求func参数为一个void (*func)(void)类型,对于如下定义的类:

    class Scene
    {
        public:
            Scene(std::string title, int width=1024, int height=768);
            virtual ~Scene();
            /*初始化场景*/
            virtual void init(int argc, char *argv[]) = 0;
            /*运行场景*/
            virtual int run() = 0;
        protected:
            /*绘制场景*/
            virtual void display() = 0;
            /*键盘回调函数*/
            virtual void key(unsigned char key, int x, int y) = 0;
            virtual void reshape(int width, int height) = 0;
            virtual void idle() = 0;
    };

    那么我需要传入的是Scene::display函数,此时将会出现函数类型不匹配的问题。因为Scene::display为Scene类的成员函数,类成员函数的实现方式是传入了一个默认的Scene *this参数,所以如果要使用成员函数,必须同时传入this指针,这与func类型冲突。

    参考stackoverflow上的解决方法1:http://stackoverflow.com/questions/3589422/using-opengl-glutdisplayfunc-within-class

    将Scene设计为一个单例类,定义static void displayCallback()函数,内部通过单例指针调用display函数,通过这种添加中间层的方式将带有默认this指针的函数转变为全局可访问的 void (*func)(void)函数。但其付出的代价就是不能创建多个场景实例,不过目前所做的是一个单场景,并不需要考虑此问题。

    修改后代码如下:

    /*
    file:Scene.h
    brief:创建一个opengl场景
    */
    #ifndef SCENE_H
    #define SCENE_H
    
    #include <string>
    
    #include "opengl.h"
    
    class Scene
    {
        public:
            Scene(std::string title, int width=1024, int height=768);
            virtual ~Scene();
            /*初始化场景*/
            virtual void init(int argc, char *argv[]) = 0;
            /*运行场景*/
            virtual int run() = 0;
    
            void setupDisplayCallback()
            {
                currentInstance = this;
                ::glutDisplayFunc(Scene::displayCallback);
            }
    
            void setupKeyCallback()
            {
                currentInstance = this;
                ::glutKeyboardFunc(Scene::keyCallback);
            }
            void setupReshapeCallback()
            {
                currentInstance = this;
                ::glutReshapeFunc(Scene::reshapeCallback);
            }
            void setupIdleCallBack()
            {
                currentInstance = this;
                ::glutIdleFunc(Scene::idleCallback);
            }
    
            static void displayCallback()
            {
                currentInstance->display();
            }
            static void keyCallback(unsigned char key, int x, int y)
            {
                currentInstance->key(key, x, y);
            }
            static void reshapeCallback(int width, int height)
            {
                currentInstance->reshape(width, height);
            }
            static void idleCallback()
            {
                currentInstance->idle();
            }
        protected:
            std::string _title;
            int _height;
            int _width;
    
            /*绘制场景*/
            virtual void display() = 0;
            /*键盘回调函数*/
            virtual void key(unsigned char key, int x, int y) = 0;
            virtual void reshape(int width, int height) = 0;
            virtual void idle() = 0;
        private:
            static Scene * currentInstance;
    };
    #endif // SCENE_H
  • 相关阅读:
    向量空间模型 词袋模型
    python 小点
    python list的append()和extend()方法
    numpy 数组运算
    内置函数和numpy中的min(),max()函数
    python index()函数
    Python支持的正则表达式元字符和语法
    Python多线程
    查看linux机器配置&内核版本
    Shell获取文件的文件名和扩展名的例子
  • 原文地址:https://www.cnblogs.com/CooCoo/p/5304150.html
Copyright © 2020-2023  润新知