GLUT中使用的全局类不好?如果是这样,怎么可以避免?

时间:2011-03-15 05:16:58

标签: c++ opengl glut

我使用Open GL利用GLUT函数绘制了这个简单的程序。为了操纵立方体,我使用了glutKeyboardFunc(),它使用变量来操纵相机或角度,此时调用glutIdleFunc()来重绘场景。我能够在我的rend函数和我的keycheck函数之间获得的唯一方法是创建一个包含我的变量和两个函数的全局类。

以下是与我的问题直接相关的代码。

enter code here

#include "stdafx.h"
#include "OGL.h"


void boingdraw();
void boingkeys();

OGL  Tramp; //Global class
void boingdraw() // called by glutDisplayFunc and kicks to my draw function
{
    Tramp.rend();
}
void boingkeys(unsigned char key, int x, int y) //called by glutKeyboardFunc
                                                     //kicks to my key switch
{
    Tramp.Keycheck( key,x, y);
}




int main (int argc, char**argv)
{





    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(400,400);
    glutCreateWindow("Testing");
    render3d();
    glutDisplayFunc(boingdraw);
    glutKeyboardFunc(boingkeys);
    glutIdleFunc(boingdraw);
    glutReshapeFunc(resize);
    glutMainLoop();
}

OGL.h文件只包含我的包含并初始化OGL类的2个函数。继承人OGL.cpp文件

enter code here 
#include "stdafx.h"
#include "OGL.h"


OGL::OGL()
{
    lx= 0.0;
    updown= 0.0;
    z= -5.0;
    v1=0.0;
    v2=1.0;
    v3=0.0;
}
void OGL::rend() 
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
                        // camera perspective variables used to move camera
                        //with keyfunc       
        gluLookAt(0.0,updown,z,
              lx,0.0,0.0,
              v1,v2,v3);





    glPushMatrix();
    glTranslatef(-0.0,-0.0,0.0);
              //angle if changed in keycheck func called by glutKeyboardFunc()
    glRotatef(angle,0.0,1.0,0.0); 


    glBegin(GL_QUADS);

               //draws stuff not important really



    glEnd();
    glPopMatrix();
    glutSwapBuffers();

}
void OGL::Keycheck(unsigned char key, int x, int y)
      //Key switchboard with various checks for wsadqe and esc keys

    {
switch (key) 
    {
    case 27: 
        {
            exit(0);break;
        }
    case 97:
        {
                lx=lx+0.25;

                        break;
        }
    case 100: 
        {
            {
                lx=lx-0.25;

                        break;
        }
        }
    case 101: 
        {

            angle += 2.0f;
            if(angle > 360) angle -= 360;

            break;

        }
    case 113: 
        {

            angle -= 2.0f;
            if(angle < 0) angle += 362;

            break;
        }
    case 115:
        {
            z=z-0.25;

                        break;
        }
    case 119:
        {
            z=z+0.25;


        }


    }
}

我已经尝试了很多trampolines和函数指针的实现来尝试进入我的类并且只是在main中初始化它但我永远无法在没有错误的情况下进行编译。使用过剩时,全球课程被认为是不好的吗?如果有的话,请有人举一些可以与我的代码一起使用的技术示例来解决这个问题吗?

请不要将此作为“为我做我的作业”主题或任何我只使用我的代码要求的示例,因为它将帮助我更好地理解这些技术的实现。

提前谢谢你,请原谅可怜的代码(如果是的话),我只是在学习,并且不想有坏习惯。

2 个答案:

答案 0 :(得分:1)

我认为你正在试图调整“全局变量总是邪恶”并且必须在GLUT中使用非OO回调。

简短回答 - 你必须使用某种全球性是正确的。

因此,对于良好的程序设计,请回过头来考虑全局问题。您的代码“按原样”是好的,因为全局在一个文件中。将其明确标记为文件范围会更好:

static OGL  Tramp; // Or use a local namespace.

这意味着它有点封装,但可以从回调中访问。 您可以使用Singleton遵循相同的模式。 如果您确定只需要一个OGL实例,那么这很好。如果您可能需要其他实例,可以将其包装在函数调用中(可能是静态类方法):

OGL&  getOGLInstance(unsigned id = 0)
{
    static OGL  Tramp; // Or use a local namespace.
    // Later, add in handling to find the instance given 'id'.
    return Tramp; 
}

答案 1 :(得分:1)

基本的GLUT API没有任何方法可以将用户数据与过剩的Windows相关联。

因此,通常所做的是保持静态范围映射,将每个窗口类实例的过量窗口ID映射到应用程序。

static std::map<int,MyGlutWindowClass*> windows;

在每个静态回调函数中,您在创建过剩窗口时查找添加到地图的类实例: -

struct MyGlutWindowClass {
  static void CallBack(){
    MyGlutWindowClass* self = windows[glutGetWindow()];
    self->OnCallback();
  }
  void OnCallback(){
    AccessMemberVariables();
  }

};