PDA

View Full Version : polymorphism / global variables in glutDisplayFunc



newsb
12-30-2011, 03:15 PM
Dear all:

Regarding polymorphism / global variables in glutDisplayFunc, I've now made a program that should draw different objects/shapes. Currently, I use the "naive" approach by having a lot of global variables so my different source code files can see everything. In main() I have something like:



....
int main(..)
{
....
glutDisplayFunc(display);
....
}



void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
//==================
glPushMatrix();
glTranslatef(xPos, yPos, 0.0);
...
object1.draw(); // a LOT of global stuff is required for this
newoject.draw(); // a LOT of global stuff is required for this
anotherObj.draw(); // a LOT of global stuff is required for
this
object2.draw(); // a LOT of global stuff is required for this
...
}



Currently, I think I should change my program, use polymorphism, to only have one draw()-call (I have a book with an example, I think I can adobt) but what do you guys do with all the *ugly* global variable passing???

Isn't there any way of avoiding all this *ugly* global variable passing or am I doing something wrong?

Would be nice with examples, if you have good solutions / ideas - I feel my use of global variables is not very nice, on the other hand I don't know if there exists better solutions...

Alfonse Reinheart
12-30-2011, 03:27 PM
It's ultimately up to you, but you're going to need at least one global variable in order to know what to draw, since you cannot pass parameters to GLUT's display function.

If you're writing demonstration apps (the kind of thing that GLUT is for), then it really shouldn't matter that much. If you're writing something more series, then you probably want to have specific objects that manage things. A shader manager, a mesh handler, a scene graph, etc. Each of these objects would need to be either global or accessible globally.

newsb
12-30-2011, 04:35 PM
Hmmm. Ok. No way to avoid it, I see...

Questions:
- What do you mean by: demonstration apps = the kind of thing that GLUT is for?
- A shader manager: hmm. I don't know much about shaders yet, but is it like a global "parent class" from which all shaders are derived from?
- a mesh handler: I suppose, for constructing surfaces?
- a scene graph: What is that?

I think I want to try to make a a global "parent class" and then derive my objects from that. I think I need a static int counter to know how many objects to draw and then a virtual member-function draw()...

Anyone with good experience: Please share ideas, thanks :-)

carsten neumann
12-30-2011, 04:51 PM
GLUT makes it easy to quickly have something up and running, good for demos and tutorial style programs. It hides quite a bit of complexity regarding OpenGL context creation and event handling. Whether that is the right tradeoff for you mostly depends on how much flexibility you need and how much complexity you are willing to put up with.

Shader manager, mesh handler: Once your program starts reaching a certain size/complexity you'll notice that there are some resources (e.g. OpenGL textures or shader or buffer objects) that you want to always handle the same way and make sure are clean up when you don't need them any more. One way to solve that is by introducing a central place that manages that resource for you and have the rest of your code just make requests to that manager if it needs such a resource.

The friendly neighbourhood search engine suggests: Wikipedia: Scene graph (http://en.wikipedia.org/wiki/Scene_graph) ;)

newsb
12-30-2011, 05:57 PM
Not understood: When is GLUT bad to use (good for demos etc, but is it very ressource-demanding and is it better to program the slowest GLUT-routines oneself)? Is GLUT slow for big/complicated programs?

And isn't it a good idea for me to make a a global "parent class" and then derive my graphical objects from that?

Here's my start-code:




class drawableObj
{
private:

protected: // derived classes can see this
static int numberOfObjs;

public:
// constructor
drawableObj();

// destructor
~drawableObj();

// member functions
virtual void draw();
};

.... somewhere else ...


class graphicsClass : public drawableObj
{
private:

public:
int maxVectorSize;
int N_kontur;
double *cpp_X, *cpp_Y;
etc...
}



Everytime I initialize a derived drawableObj, then that is something that should be shown as a graphics object on the screen. I should then end up having, e.g:



int numberOfObjs = 0; // global!
// THIS IS THE KEY TO ALL MY GRAPHICS OBJECTS
drawableObj allMyObjs(); // one single global object!

....
int main(..)
{
// object1: note this had previously to be global
// such that glutDisplayFunc(display) could see it...

// now I should just do (I hope it'll work):
someThingDerivedFrom_drawableObj object1(someinput);
someThingDerivedFrom_drawableObj object2(someinput);
anotherThingDerivedFrom_drawableObj object3(someinput);

// note that because all drawable objects are derived
// from global drawableObj allMyObjs(), then it knows/should
// know how many objects to draw (all derived classes have a
// draw() member-function. I think I just neen to store
// the pointer location/address of each derived object,
// in the global drawableObj allMyObjs-object... Right?

....
glutDisplayFunc(display);
....
}



void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
//==================
glPushMatrix();
glTranslatef(xPos, yPos, 0.0);
...
allMyObjs.draw(); // <====== ONLY 1 SINGLE CALL!!! VERY NICE!

// not used anymore:
//object1.draw(); // a LOT of global stuff is required for this
//newoject.draw(); // a LOT of global stuff is required for this
//anotherObj.draw(); // a LOT of global stuff is required for
this
//object2.draw(); // a LOT of global stuff is required for this
...
}


??? comments/ideas ???

Am I on the right track? I would call this "a graphics object handler", i.e. my drawableObj-class...

McLeary
12-30-2011, 06:48 PM
GLUT is not bad to use. All that Alfonse Reinheart was telling is that GLUT is better for build demos, since it is easy to setup and provides an OpenGL context with a ready-to-draw window. The windows system you're using doesn't matter.

I think that there ins't a "right" track to follow when implementing this kind of stuf. As you already notice, when the application starts to grow, it's get complicated not having a background framework doing basic thing for you.

If you are really interested in build complex graphics applications, with many objects and many complex attributes for each object, take a look at OpenSG http://www.opensg.org/. (http://www.opensg.org/)

If you want to write your own resources manager, I suggest you to build a class that has a vector of objects or something like that, instead of have a static object counter. This class should be able to draw the objects with a single call as you want.

newsb
12-30-2011, 07:54 PM
McLeary: I don't want a vector of objects if I can avoid it. I have one global object and inside of that, I want to put references (of type "pointer to base-class") to the other derived (non-global) objects, which I define and create in main().

I'm only worried if it'll work, since the (maybe vector of) pointer (to derived graphical objects) are pointing to something that is not global...

?

newsb
12-31-2011, 01:46 AM
Uhh... Now it works - sort of, with polymorphism! I'll show the code later (so you can tell if I made some serious mistakes), however I have an important question:

Currently I have:



glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutSpecialFunc(special);
glutKeyboardFunc(keyboard);
glutTimerFunc(100, timer, 0);
glutMainLoop();

for (int z=0; z<(int) drawableObj::pObjs.size(); z++)
delete drawableObj::pObjs[z]; // NOT SURE IF IT WORKS!
}


void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27: // escape
{
exit(0); // CANNOT HAVE THIS!!!
break;
}


How do I exit nicely (case 27=escape key) and still clean up allocated memory in the end (using "delete"-something) - I need to call destructors for all graphical objects???