OpenGL/Glut Help

Soldato
Joined
7 Apr 2004
Posts
4,212
Hi,

Im fairly new to opengl, and im trying to move a small rectangle (will eventually be a polygon) from
the bottom of my window to the top, not all in one go, just so it
moves from the bottom to top in an animated fashion (its a rocket in a
game if that makes more sense...).

So i approached this as follows, basically every time the main draw
function is called the rectangles y coordinate values are incremented, now
obviously this results in a super fast animation that is barely
visible due to high fps.

So can someone tell me if firstly im approaching this correctly? And secondly how i can get control over the speed the rectangle moves from bottom to top. I think i might need to calculate the delta time, but if i did this i wouldn't know how to use the delta time on the updating of the coordinates?

Here is the relevant code:

Code:
void CShip::DrawMissiles()
{
        glColor3f(1.0f, 0.0f, 0.0f);

// Draw missile
        if(Missiles.size() != 0)
        {
                for(int i = 0; i < Missiles.size(); i++)
                {
                        glRectd(Missiles[i].x1, Missiles[i].y1, Missiles[i].x2,
Missiles[i].y2);
                }
        }

// Move missiles upwards

        if(Missiles.size() != 0)
        {
                for(int i = 0; i < Missiles.size(); i++)
                {
                        Missiles[i].y1++;
                        Missiles[i].y2++;
                }
        }

Thanks for any help,

Jack
 
A quick and dirty hack for the speed issues would be to force VSync in your video drivers (that's what I'm doing for my coursework, anyway...if there's an easy way that's better it'd be welcomed :p)

The way I'm making my objects move is:

Code:
	glPushMatrix();
	glColor3f(1.0,1.0,1.0);
	glTranslatef(Xtri, Ytri, 0.0);
		glBegin(GL_POLYGON);
			glVertex2f(8,8);
			glVertex2f(-8,8);
			glVertex2f(-8,-8);
			glVertex2f(8,-8);
		glEnd();
	glPopMatrix();

And then incrementing/decrementing Xtri and Ytri as appropriate to move the object, so you'd just have to do Ytri++ in your idle function to have it move up 1 on each loop. If you do it in a for loop it'll just do it all in one go and only update the display at the end of the loop, if you did it in this way. There's probably a few different ways to do it.
 
Last edited:
rather than adding 1 add a smaller number like 0.1.

The problem I had was that I only tested it on my machine and the animation ran smoothly for a couple of minutes and was enjoyable to watch, when it came to marking it my lecturer ran it on his (far inferior) machine and apparently it took aaaaaages to run. Some sort of control to increase or decrease the amounts that the x & y values are changing would be a good idea

Code:
glPushMatrix();
	glColor3f(1.0,1.0,1.0);
	glTranslatef(Xtri * speed, Ytri * speed, 0.0);
		glBegin(GL_POLYGON);
			glVertex2f(8,8);
			glVertex2f(-8,8);
			glVertex2f(-8,-8);
			glVertex2f(8,-8);
		glEnd();
	glPopMatrix();

then just have speed initialized to 1, pressing the '-' key can decrease speed and pressing the '+' key will increase it. There are probably far more elegant methods though!!
 
To get the same performance across different machines could you consider implementing some sort of "heartbeat" method within your code - a method that gets triggered at known intervals, perhaps on a timer. Within that method you then move each element according to the equation distance = velocity * time, having previously defined the velocity of the rockets.
 
To get the same performance across different machines could you consider implementing some sort of "heartbeat" method within your code - a method that gets triggered at known intervals, perhaps on a timer. Within that method you then move each element according to the equation distance = velocity * time, having previously defined the velocity of the rockets.

that sounds much more elegant :p
 
Ok, sure... Bare with me 'cause I'm not a programmer! This is the simplest way, I believe.

First you need your timer class; the main functionality is as so:

Code:
float& Timer::getDelta(void)	
{
        //get the current system clock value
	float m_current=clock();
        //subtract the old time value from the new (the last part converts it to seconds)
	float m_delta=(m_current-m_last)/CLOCKS_PER_SEC;
        //your newly calculated tick is now the 'old' value - used for the next iteration
	m_last=m_current;
	return m_delta;
}

Basically, all this does is calculate a value that represents a time-step. The the value will always represent the same length of time, irrespective of system performance. Remember to initialise m_last with the current time in the constructor otherwise you'll get some strange behaviour when you run the code. These functions are available in "time.h" from the STL.

You only need to instantiate this class once. The getDelta method needs to be called continuously so call it via GLUT's idle function. You can then pass a reference to it around your objects.

To calculate the new positions of your bits:

Code:
m_newPosition=m_oldPosition+(_deltaPointer->getDelta()*m_velocity);

If you're working in 2D, you need to perform this function on each abscissa/ordinate. The velocity can be unitised, but you will need to add a seperate value in order to control the speed of the object. Note that this algorithm will only ever deliver a constant, straight path for your object. However, by changing the velocity values on a dynamic basis, you'll be able to do some interesting things.

So, in summary, per frame:
* Calculate Delta Time and pass to objects
* Calculate all new positions for all your objects
* Draw all of your objects
* Rinse, repeat

I hope this helps.
 
Last edited:
I did it essentially that way to work out the deltaTime but added/changed a few bits. Basically I used that way of getting the deltaTime, then had an accumulator where if the deltaTime went above a certain amount (say, 16ms for 60Hz) it'd run the physics function.

I've seen a few different ways to get it working, some more complex than others but this works nicely. Game is running at 1100fps but the physics are at 50-60Hz so I'm happy with that :)

Cheers
 
Back
Top Bottom