Help end child hunger

Animation

 
Prev: Reshape Next: Keyboard
 

OK, so far so good. We have an OpenGL window with a white triangle. Nothing very exciting, but hey, its a start. Now to complete this part of the GLUT tutorial lets have that triangle spinning.

The first thing we must do is to tell GLUT that when the application is idle, the render function should be called. This causes GLUT to keep calling our rendering function therefore enabling animation. GLUT provides a function, glutIdleFunc, that lets you register a callback function to be called when the application is idle.


void glutIdleFunc(void (*func)(void));

Parameters:

    • func – The name of the function that will be called whenever the application is idle.

In our case, when the application is idle we want to call the previously defined function that does the actual rendering: renderScene. OK, so the main function now looks like this:

 

int main(int argc, char **argv) {

	// init GLUT and create window
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(320,320);
	glutCreateWindow("Lighthouse3D- GLUT Tutorial");

	// register callbacks
	glutDisplayFunc(renderScene);
	glutReshapeFunc(changeSize);

	// here is the idle func registration
	glutIdleFunc(renderScene);

	// enter GLUT event processing cycle
	glutMainLoop();

	return 1;
}

 

Afterwards, we go and change the rendering itself. First lets declare a floating point variable angle, and initialize it to 0.0 . Then we add the necessary stuff to the renderScene function.

 

float angle = 0.0f;

void renderScene(void) {

	// Clear Color and Depth Buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Reset transformations
	glLoadIdentity();
	// Set the camera
	gluLookAt(	0.0f, 0.0f, 10.0f,
			0.0f, 0.0f,  0.0f,
			0.0f, 1.0f,  0.0f);

	glRotatef(angle, 0.0f, 1.0f, 0.0f);

	glBegin(GL_TRIANGLES);
		glVertex3f(-2.0f,-2.0f, 0.0f);
		glVertex3f( 2.0f, 0.0f, 0.0);
		glVertex3f( 0.0f, 2.0f, 0.0);
	glEnd();

	angle+=0.1f;

	glutSwapBuffers();
}

 

A note on double buffering

As you recall, when we set the display mode in our main function we requested double buffering. This feature provides two buffers for display. The buffer being shown is the front buffer, and the other buffer is the back buffer. It is in the latter buffer that drawing takes place. When we’re done sending drawing commands we ask to swap the buffers, i.e. once the driver is done rendering the back buffer will become the front buffer, and the previous front buffer will become the back buffer, where the rendering of the next frame will take place.

The glutSwapBuffers function cause the front and back buffers to switch thereby showing what was previously drawn in the back buffer. The syntax is as follows:

void glutSwapBuffers();

 

The code so far

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

void changeSize(int w, int h) {

	// Prevent a divide by zero, when window is too short
	// (you cant make a window of zero width).
	if (h == 0)
		h = 1;

	float ratio =  w * 1.0 / h;

	// Use the Projection Matrix
	glMatrixMode(GL_PROJECTION);

	// Reset Matrix
	glLoadIdentity();

	// Set the viewport to be the entire window
	glViewport(0, 0, w, h);

	// Set the correct perspective.
	gluPerspective(45.0f, ratio, 0.1f, 100.0f);

	// Get Back to the Modelview
	glMatrixMode(GL_MODELVIEW);
}

float angle = 0.0f;

void renderScene(void) {

	// Clear Color and Depth Buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Reset transformations
	glLoadIdentity();
	// Set the camera
	gluLookAt(	0.0f, 0.0f, 10.0f,
				0.0f, 0.0f,  0.0f,
				0.0f, 1.0f,  0.0f);

	glRotatef(angle, 0.0f, 1.0f, 0.0f);

	glBegin(GL_TRIANGLES);
		glVertex3f(-2.0f,-2.0f, 0.0f);
		glVertex3f( 2.0f, 0.0f, 0.0);
		glVertex3f( 0.0f, 2.0f, 0.0);
	glEnd();

	angle+=0.1f;

	glutSwapBuffers();
}

int main(int argc, char **argv) {

	// init GLUT and create window
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(320,320);
	glutCreateWindow("Lighthouse3D- GLUT Tutorial");

	// register callbacks
	glutDisplayFunc(renderScene);
	glutReshapeFunc(changeSize);
	glutIdleFunc(renderScene);

	// enter GLUT event processing cycle
	glutMainLoop();

	return 1;
}

 

Just copy the code above to your project and try it, or alternatively check out the source code at GitHub. Isn’t it great? OK, ok…but I warned you, no fancy stuff in here, keeping the code to the minimum and focusing on GLUT!

 

Prev: Reshape Next: Keyboard
 

  25 Responses to “Animation”

  1. This tutorial is now old as this is not modern OpenGL. However, for old OpenGL it is awesome! thank you. I hope you do a tutorial of modern OpenGLl Your explanations are super clear!

  2. why we required that glMatrixMode()

    thanks in advance

    • OpenGL works on the “current” matrix, current being the matrix set by glMatrixMode. The last glMatrixMode in changeSize is due to the fact that in all the other parts of the program we work with the modelview matrix. Having the glMatrixMode setting the current matrix to the modelview matrix avoids assures us that the current matrix is the right matrix outside the change size function.

      In short, the goal is to have the current matrix always as the modelview matrix. When we need to change the projection matrix we set the current matrix to the projection matrix, change it, and then set back the current matrix to the modelview matrix.

      Hope this helps.

  3. Hey Tutorial is awesome, really i learnt many things from scratch. But few things are still missing,i.e., will you please explain me how to apply a texture in a simple way. Till now we are only dealing with the normal primitives…..
    Expecting Texturing concept soon… 🙂

  4. Thanks for the tutorial. But what is idle? I mean, when does the OpenGL/GLUT enters in an idle state? And, instead of registering an idle function, why don’t you add glutPostRedisplay() at the end of renderScene()?

    • Idle is when there is nothing else to do. Basically we’re just telling GLUT to call the render function as often as it can. Using glutPostRedisplay at the end of the render scene function provides the same effect, as you mention.

  5. thanx for the tutorial,, it was more importent for me
    rhanx again 🙂

  6. Why does the triangle spin faster if I make the window smaller?
    I imagine it has to do with the triangle corners having a smaller diameter to travel through, but I’m not sure.

    • Screen is smaller! it is rendering faster and program is running faster 😉

      • Right. Smaller means less pixels to paint!

      • not exactly. for a single triangle, that shouldn’t happen. it’s too simple to take more or less time depending on screen size. did you register the changeSize() function? is it correct?

  7. Thanks for the tutorials 🙂

    How do we make this less resource intensive (processor/GPU going full steam while spinning the triangle)?

  8. It appears GLU isn’t working on my pc. If i comment the glu* functions out then it works fine…
    Has anyone else a problem with GLU and Linux?

    • compile with -lGLU then it will work example : my code –> test.cpp compile : g++ test.cpp -o test -lglut -lGLU

  9. Thanks for your greet efforts

    I have a small question, Why you declared angel as global, not inside the function it-self?

    When I tried I have it static non-moving triangle !!

    • Hi,

      Not sure what the problem is. I’ve tested it again and it works with me 🙁

    • Hey,

      If you declare the angle within the ‘renderscene’ function, then it causes it to keep reseting the angle back to zero, (since it keeps calls renderscene each frame) which would make it so it doesn’t rotate.

      Hope that helps!

  10. So, you are rotating the camera around the triangle rather rotating the triangle itself right?

    Can you please explain all the parameters for the function gluLookAt()..?

    Is the angle in degrees or radians? What 1.0f means?

    • Hi Ozair

      Actually I’m rotating the triangle. The rotation “prepares” the coordinate system for what follows. It never affects what has already been drawn, or placed in the case of the camera. The angle for glRotation is in degrees. Beware that in C the angle is in radians though.

      The first three params of gluLookAt are the camera position, the second group of three values is a point where the camera is aimed, and the final three, the up vector, relate to the tilt of the camera. Having (0,1,0) as the up vector means the camera is not tilted. Try with other values, for instance (1,1,0), and you’ll see what I mean.

      Finally 1.0f. If you just write 1.0 you’re actually writing a double, not a float. The f tells the compiler that the value is a float.

      Hope this helps,

      Antonio

  11. Hi ARF,
    you done a good job. Thanks man 🙂

    I tried to get it work without the changeSize function. But when I remove this function the window is just black. What is the problem? Normally changeSize just recalculates the triangle if I change the window size. I am I right?
    Cheers,
    Ron

    • The changeSize function deals with the projection matrix, so its required. This function is called when the window is shown, and afterwards when the window changes.

      • My case is just oppostie, I have the triangle without the changeSize and new renderScene for animation. The window will go blank if I add them, any idea what could be wrong ?

        • the problem is that you have to reejust the camera , i think whit a small call:


          // changeSize function
          glLoadIdentity();
          gluLookAt( ... );

          at the end of the changeSize-function;

  12. Nice nice, I finally made it work… but you forgot to add the #include
    parameter on your final example in this page

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: