当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - Global Class used in GLUT bad? if so how can this be avoided?

问题描述:

I drew up this simple program using Open GL utilizing the GLUT functions. In order to manipulate the cube i'm using glutKeyboardFunc() which manipulates the camera or the angle using variables at which point glutIdleFunc() is called to redraw the scene. The only way I have been able to get between my rend function and my keycheck function is creating a global class which houses my variables and both functions.

Here is the code that pertains directly to my question.

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 file just has my includes and initializes the 2 functions of OGL class. Heres the OGL.cpp file

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;

}

}

}

I have tried many implementations of trampolines and function pointers to try to get into my class and just initializing it in main but I can never get it to compile without errors. Is a global class considered bad when using glut? And if so could somebody please give some examples of techniques that can be used with my code to work around this issue?

Please dont take this as a "Do my homework for me" thread or whatever I only ask for examples using my code because it will help me better understand the implementation of the techniques.

thank you in advance and please excuse the poor code(if it is) im just learning and would like to not get off with bad habits.

网友答案:

I think you are trying to get your head around reconciling "globals are always Evil" and having to use non-OO callbacks in GLUT.

Short answer - You are correct in having to use some kind of global.

So for good program design, come back to considering the issues with globals. Your code "as is" is good in that the global is in a single file. Marking it explicitly as file scope would be better:

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

This means that it is somewhat encapsulated, but accessible from your callbacks. You can follow much the same pattern using a Singleton. If you are certain that you will only ever want a single instance of OGL, then this is fine. If you might want other instances, you can wrap it in a function call (maybe a static class method):

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; 
}
网友答案:

The basic GLUT API does not have any way of associating user data with glut Windows.

So, what is typically done is a static scoped map is maintained mapping glut window Ids to your applications per window class instance.

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

Inside each of your static callback functions you lookup the class instance you add to the map when you create the glut window :-

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

};
分享给朋友:
您可能感兴趣的文章:
随机阅读: