Click to See Complete Forum and Search --> : OpenGL and GLUT : going from java to C++


TripleM
December 23rd, 2005, 04:42 AM
[warning - newbie alert]

I've been programming in java for a little while now, but decided I wanted to transfer the little game I've been making from java to C++, and decided I'd use opengl/glut for the graphics.

Basically the main thing that happens in this game is, you click on various things on the screen to set things up, and click 'go', which causes everything on the screen to move around for a few seconds, and then we go back to the first step. In java this is quite easy - just have a timer which simulates the next step and calls repaint().

Now I'm trying to get my head around how this would work in glut. Once you enter the main loop, it will never return (though I've been looking at freeglut, which has the glutMainLoopEvent or whatever its called which just does one thing then returns, or allows you to leave the main loop itself at any stage).

How do I structure my code to get the above idea working? The only way I can see to do animation is to set the idle function to render the scene, so its continuously drawing things. But do I put, say, at the end of the render method, something like (ifweshouldbesimulating) simulateNextStep(), or something like that? I'm not quite sure when this render function is being called, but it feels like its going to be called more than when I want it.

I probably haven't explained that very well, but if anyone understands what I'm talking about, what do I do?

(The other thing I can think of is to have all the drawing in another thread, which is really what java is doing, but I can't seem to find anybody else with google who does that, so theres probably something wrong with it.)

edit - I guess what I'm really asking is, how do I get my program to actually process all the rest of the code rather than just the graphics. Though in this case its about sometimes having something simulated, sometimes having other input. Hmm.

Marc G
December 23rd, 2005, 07:47 AM
Maybe something like the following.
When you click the go-button, set a boolean variable something like bRender. Install an idle function callback and let this callback call your render function only when bRender is true.
Then use glutTimerFunc to install a timer callback that will be called at a specific time. When the timer fires, set bRender to false.

Hnefi
December 25th, 2005, 06:04 AM
It sounds like you're trying to use Java-like event programming in C++. That's unnessecarily difficult. Why not just do something like

bool done = false;
Timer timer; /*some sort of timer. Exactly how to implement your timer is up to you - there are many ways to do that in C++.*/

int main(){
while(!done){
Dealwithinput(); /*handles input and sets done to true if, say, escape is pressed.*/
if(timer.timesincelastcall >= 1/60){
Simulatenextstep();
DrawScene();
}
timer.update();
}
}

TripleM
December 25th, 2005, 04:37 PM
Well yeah, its something like that which I want.. but how would you do a drawScene method or the event handling one, for that matter? All I know of glut is that you register a display method and methods for handling events and then call glutMainLoop(), which is why I have a problem. Theres nowhere to put that code that you wrote. Well, there is, but obviously I don't know enough about glut to do it.. so where do I put that code?

Hnefi
December 26th, 2005, 08:00 AM
Well yeah, its something like that which I want.. but how would you do a drawScene method or the event handling one, for that matter? All I know of glut is that you register a display method and methods for handling events and then call glutMainLoop(), which is why I have a problem. Theres nowhere to put that code that you wrote. Well, there is, but obviously I don't know enough about glut to do it.. so where do I put that code?
If I were you I'd forget about GLUT and use either WinAPI (if you are programming in Windows), SDL or Allegro. I haven't seen anyone use GLUT in ages. However, if you're determined to use GLUT, you can call glutDisplayFunc(DrawScene) before glutMainLoop and you'll be able to use DrawScene() as your drawing function, in the form shown below.

The code skeleton I showed you should be put in the main() function (if you don't use GLUT - if you do use GLUT, I'm not sure exactly how to deal with the main loop. Too long since I last used it), which in C++ is the function that is called when a program is executed. You construct the main program loop yourself with the while(!done) statement.

The DrawScene() function simply consists of a call to glLoadIdentity() followed by explicit calls to the rendering function in whatever objects you want to draw. For example, it might look like this:
class Object{
public:
(...)
void Render();
(...)
};
class Container{
static std::vector<Object> obj;
};

DrawScene(){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
for(int d1 = 0; d1 < Container::obj.size(); d1++){
Container::obj[d1]->Render();
}
SwapBuffers(hDC); //hDC is a pointer to the current device context in WinAPI. GLUT has its own buffer swapping function.
}
The Object::Render() function should begin with a call to glLoadIdentity() followed by whatever OpenGL commands you desire.

As for event handlers, I would simply create my own system. Let DealWithInput() be called once every loop, and let it send messages to the relevant objects. Give each class a Tick() function to calculate its behaviour in one particular moment, and call Tick() for each object in SimulateNextStep() just like you call Render() for each object in DrawScene().

For example, DealWithInput might check if a mouse button has been pressed. If so, it would retrieve the current mouse position and compare it with each object in the Container::obj vector. If it finds an object that is placed on the coordinates where the mouse was clicked, it might set a boolean variable in that object to true, or call a Click() function in that object or whatever.

migol
December 26th, 2005, 05:39 PM
errr... guys...

it's easy to make timers in OpenGL + GLUT.

you use:

void glutTimerFunc(unsigned int msecs, (*func)(int value), int value);

where:
msecs is the time that timer have to wait in msec
*func is the function that will be executed
value is the value that will be passed to that function

remember that you shold execute this function at the end of the *func in order to set a new timer.

Marc G
December 27th, 2005, 02:56 PM
errr... guys...

it's easy to make timers in OpenGL + GLUT.

you use:

void glutTimerFunc(unsigned int msecs, (*func)(int value), int value);

where:
msecs is the time that timer have to wait in msec
*func is the function that will be executed
value is the value that will be passed to that function

remember that you shold execute this function at the end of the *func in order to set a new timer.
Yes, that's what I said in my reply above ;)

TripleM
December 27th, 2005, 03:53 PM
Yeah, I knew that much. My main problem wasn't about how to do a timer (can easily do that with threads anyway), just how to structure all the code with glut after being used to all graphics being in a seperate thread in java. I'll just have a play around.