Archived

This topic is now archived and is closed to further replies.

JeroMiya

OpenGL minus Global variables?

Recommended Posts

I''m trying to write a driver for a game I''m working on. However, I DO NOT want to use global variables in this driver. I hate global variables. However, I see absolutely no way around using them in an OpenGL program. I want to share data between the OpenGL functions (DisplayFunc, IdleFunc, etc...), but I don''t want the data to be global. For example, in this game I''m using an object list (each object has all the information about where it is on the screen, how to draw it, and how to move it). I could just make this list static data in the draw function, but I would rather share the list with the idle function. That way, I can do frame rate timing in the idle function. How are you supposed to do this? I tried assigning the member functions of a class, so that I can have the list as private data of the class, but I get an error saying "converting void (foo:: *)() to void (*)()". This is a short snipit of what I''m trying to do.
  
...
GLvoid InitGL(GLvoid);
GLvoid Idle(GLvoid);
class MyGLControlClass
{
    public:
        ...
        GLvoid draw(GLvoid);
        GLvoid init(GLvoid);
        ...
    private:
        int a;
};
int main(int argc, char** argv)
{
        MyGLControlClass con;

	glutInit(&argc, argv);										
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
        glutGameModeString("1024x768:32@75");
        glutEnterGameMode();
        
        con.init();
	InitGL();
        glutDisplayFunc(con.draw()); // NOTE: THIS IS CAUSING THE ERROR <-------------------------------
	glutIdleFunc(Idle);//Idle Function is dont every loop
	glutMainLoop();
	

	return 0;
}

GLvoid InitGL(GLvoid)
{

	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);		// This Will Clear The Background Color To Black
                                                        // Colours follow standar Red, Green, Blue, then alpha channel
	glClearDepth(1.0);				// Enables Clearing Of The Depth Buffer
	glDepthFunc(GL_LESS);				// The Type Of Depth Test To Do
	glEnable(GL_DEPTH_TEST);			// Enables Depth Testing
	glShadeModel(GL_SMOOTH);			// Enables Smooth Color Shading

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();				// Reset The Projection Matrix

	gluPerspective(45.0f,(GLfloat)1024/(GLfloat)768,0.1f,100.0f);	// Calculate The Aspect Ratio Of The Window

	glMatrixMode(GL_MODELVIEW);

}

// Idle ---------------------------------------------------------------------

GLvoid Idle(GLvoid)
{	
	glutPostRedisplay();//Makes glut re-render the scene
}


GLvoid MyGLControlClass::init(GLvoid)
{
    a = 10;
}

GLvoid MyGLControlClass::draw(GLvoid)
{
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear The Screen And The Depth Buffer
	glLoadIdentity();										// Reset The View
	//Lesson 2
	a++;
        if (a > 14)
            a = 0;
	glTranslatef(-1.5f,0.0f,-6.0f);                 // Move Left 1.5 Units And Into The Screen 6.0
	
	//Setup the rotation for the triangle
	glRotatef(a,0.0f,1.0f,0.0f);                 // Rotate The Triangle On The Y axis
        glRotatef(a,1.0f,0.0f,0.0f);
	//Make a Triangle
	glBegin(GL_TRIANGLES);                          // Drawing Using Triangles
			//Front Face
			glColor3f(1.0f,0.0f,0.0f);                      // Red
            glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Front)
            glColor3f(0.0f,1.0f,0.0f);                      // Green
            glVertex3f(-1.0f,-1.0f, 1.0f);                  // Left Of Triangle (Front)
            glColor3f(0.0f,0.0f,1.0f);                      // Blue
          	glVertex3f( 1.0f,-1.0f, 1.0f);                  // Right Of Triangle (Front)
			//Right Face
			glColor3f(1.0f,0.0f,0.0f);                      // Red
            glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Right)
            glColor3f(0.0f,0.0f,1.0f);                      // Blue
            glVertex3f( 1.0f,-1.0f, 1.0f);                  // Left Of Triangle (Right)
            glColor3f(0.0f,1.0f,0.0f);                      // Green
            glVertex3f( 1.0f,-1.0f, -1.0f);                 // Right Of Triangle (Right)
            //Left Face
            glColor3f(1.0f,0.0f,0.0f);                      // Red
            glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Back)
            glColor3f(0.0f,1.0f,0.0f);                      // Green
            glVertex3f( 1.0f,-1.0f, -1.0f);                 // Left Of Triangle (Back)
            glColor3f(0.0f,0.0f,1.0f);                      // Blue
            glVertex3f(-1.0f,-1.0f, -1.0f);                 // Right Of Triangle (Back)
            //Back Face
            glColor3f(1.0f,0.0f,0.0f);                      // Red
            glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Left)
            glColor3f(0.0f,0.0f,1.0f);                      // Blue
            glVertex3f(-1.0f,-1.0f,-1.0f);                  // Left Of Triangle (Left)
            glColor3f(0.0f,1.0f,0.0f);                      // Green
            glVertex3f(-1.0f,-1.0f, 1.0f);                  // Right Of Triangle (Left)
    glEnd();                                        // Finished Drawing The Triangles
    glBegin(GL_QUADS);
            glVertex3f(-1.0f,-0.5f, 1.0f);
            glVertex3f(1.0f,-0.5f, 1.0f);
            glVertex3f(1.0f,-0.5f, -1.0f);
            glVertex3f(-1.0f,-0.5f, -1.0f);
    glEnd();

    glutSwapBuffers();


}
[/CODE]    

Share this post


Link to post
Share on other sites
Well I''ve never used glut, but you seem to be specifiying the function wrong. You are passing the return value of con.draw() which is a type GLvoid, so you may as well be doing this:

Glvoid tmp;
glutDisplayFunc(tmp);

which is not what you want to happen. Look up some glut examples to see how to correctly specify the display function. Also you will have to make your draw function a static class member because all class functions have a hidden this* pointer passed to them as a parameter, so glut may fail calling the function:

static GLvoid draw(GLvoid);

This will mean that every instance of your class calls the same draw function, but that''s a whole seperate issue.

Hope that helps you,

FatalXC

Share this post


Link to post
Share on other sites
Well lets look at your error message first off.

"converting void (foo:: *)() to void (*)()"
Your handing a class pointer of a function according to this message. You need to pass a address of the function. You do this by

typedef void (*pfunc)();

pfunc mypfunc = myfunction;

Now the address of the function is in the varible and dereference it before using it in a function!!!!

Share this post


Link to post
Share on other sites
If I may be so bold, I believe you are all overlooking the essential problem... The original question was "I DO NOT want to use global variables". Note in the code he is using glut. If you want to do *anything* with glut, you will need to use global/static variables. As far as I know, that''s the bottom line.

My advice is to only use glut for your initial startup. Once you get a solid framework going, write your own windowing code. Of course, even better would be to use your own code from the get go. And of course, even better then that would be to just use the excellent code NeHe has already provided

Share this post


Link to post
Share on other sites