Rotation

In the last tutorial I taught you how to add color to triangles and quads. In this tutorial I will teach you how to rotate these colored objects around an axis.

Using the code from the last tutorial, we will be adding to a few places in the code. I will rewrite the entire section of code below so it's easy for you to figure out what's been added, and what needs to be replaced.

We'll start off by adding the two variables to keep track of the rotation for each object. We do this at the top of our program, underneath the other variables. You will notice two new lines after 'bool fullscreen=TRUE;'. These lines set up two floating point variables that we can use to spin the objects with very fine accuracy. Floating point allows decimal numbers. Meaning we're not stuck using 1, 2, 3 for the angle, we can use 1.1, 1.7, 2.3, or even 1.015 for fine accuracy. You will find that floating point numbers are essential to OpenGL programming. The new variables are called rtri which will rotate the triangle and rquad which will rotate the quad.

#include	<windows.h>					// Header File For Windows
#include	<gl\gl.h>					// Header File For The OpenGL32 Library
#include	<gl\glu.h>					// Header File For The GLu32 Library
#include	<gl\glaux.h>					// Header File For The GLaux Library

HDC		hDC=NULL;					// Private GDI Device Context
HGLRC		hRC=NULL;					// Permanent Rendering Context
HWND		hWnd=NULL;					// Holds Our Window Handle
HINSTANCE	hInstance;					// Holds The Instance Of The Application

bool		keys[256];					// Array Used For The Keyboard Routine
bool		active=TRUE;					// Window Active Flag
bool		fullscreen=TRUE;				// Fullscreen Flag Set To TRUE By Default

GLfloat		rtri;						// Angle For The Triangle ( NEW )
GLfloat		rquad;						// Angle For The Quad     ( NEW )

Now we need to modify the DrawGLScene() code. I will rewrite the entire procedure. This should make it easier for you to see what changes I have made to the original code. I'll explain why lines have been modified, and what exactly it is that the new lines do. The next section of code is exactly the same as in the last tutorial.

int DrawGLScene(GLvoid)						// Here's Where We Do All The Drawing
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
	glLoadIdentity();					// Reset The View
	glTranslatef(-1.5f,0.0f,-6.0f);				// Move Into The Screen And Left

The next line of code is new. glRotatef(Angle,Xvector,Yvector,Zvector) is responsible for rotating the object around an axis. You will get alot of use out of this command. Angle is some number (usually stored in a variable) that represents how much you would like to spin the object. Xvector, Yvector and Zvector parameters together represent the vector about which the rotation will occur. If you use values (1,0,0), you are describing a vector which travels in a direction of 1 unit along the x axis towards the right. Values (-1,0,0) describes a vector that travels in a direction of 1 unit along the x axis, but this time towards the left.

D. Michael Traub: has supplied the above explanation of the Xvector, Yvector and Zvector parameters.

To better understand X, Y and Z rotation I'll explain using examples...

X Axis - You're working on a table saw. The bar going through the center of the blade runs left to right (just like the x axis in OpenGL). The sharp teeth spin around the x axis (bar running through the center of the blade), and appear to be cutting towards or away from you depending on which way the blade is being spun. When we spin something on the x axis in OpenGL it will spin the same way.

Y Axis - Imagine that you are standing in the middle of a field. There is a huge tornado coming straight at you. The center of a tornado runs from the sky to the ground (up and down, just like the y axis in OpenGL). The dirt and debris in the tornado spins around the y axis (center of the tornado) from left to right or right to left. When you spin something on the y axis in OpenGL it will spin the same way.

Z Axis - You are looking at the front of a fan. The center of the fan points towards you and away from you (just like the z axis in OpenGL). The blades of the fan spin around the z axis (center of the fan) in a clockwise or counterclockwise direction. When You spin something on the z axis in OpenGL it will spin the same way.

So in the following line of code, if rtri was equal to 7, we would spin 7 on the Y axis (left to right). You can try experimenting with the code. Change the 0.0f's to 1.0f's, and the 1.0f to a 0.0f to spin the triangle on the X and Y axes at the same time.

It's important to note that rotations are done in degrees. If rtri had a value of 10, we would be rotating 10 degrees on the y-axis.

	glRotatef(rtri,0.0f,1.0f,0.0f);				// Rotate The Triangle On The Y axis ( NEW )

The next section of code has not changed. It draws a colorful smooth blended triangle. The triangle will be drawn on the left side of the screen, and will be rotated on it's Y axis causing it to spin left to right.

	glBegin(GL_TRIANGLES);					// Start Drawing A Triangle
		glColor3f(1.0f,0.0f,0.0f);			// Set Top Point Of Triangle To Red
		glVertex3f( 0.0f, 1.0f, 0.0f);			// First Point Of The Triangle
		glColor3f(0.0f,1.0f,0.0f);			// Set Left Point Of Triangle To Green
		glVertex3f(-1.0f,-1.0f, 0.0f);			// Second Point Of The Triangle
		glColor3f(0.0f,0.0f,1.0f);			// Set Right Point Of Triangle To Blue
		glVertex3f( 1.0f,-1.0f, 0.0f);			// Third Point Of The Triangle
	glEnd();						// Done Drawing The Triangle

You'll notice in the code below, that we've added another glLoadIdentity(). We do this to reset the view. If we didn't reset the view. If we translated after the object had been rotated, you would get very unexpected results. Because the axis has been rotated, it may not be pointing in the direction you think. So if we translate left on the X axis, we may end up moving up or down instead, depending on how much we've rotated on each axis. Try taking the glLoadIdentity() line out to see what I mean.

Once the scene has been reset, so X is running left to right, Y up and down, and Z in and out, we translate. You'll notice we're only moving 1.5 to the right instead of 3.0 like we did in the last lesson. When we reset the screen, our focus moves to the center of the screen. meaning we're no longer 1.5 units to the left, we're back at 0.0. So to get to 1.5 on the right side of zero we dont have to move 1.5 from left to center then 1.5 to the right (total of 3.0) we only have to move from center to the right which is just 1.5 units.

After we have moved to our new location on the right side of the screen, we rotate the quad, on the X axis. This will cause the square to spin up and down.

	glLoadIdentity();					// Reset The Current Modelview Matrix
	glTranslatef(1.5f,0.0f,-6.0f);				// Move Right 1.5 Units And Into The Screen 6.0
	glRotatef(rquad,1.0f,0.0f,0.0f);			// Rotate The Quad On The X axis ( NEW )

This section of code remains the same. It draws a blue square made from one quad. It will draw the square on the right side of the screen in it's rotated position.

	glColor3f(0.5f,0.5f,1.0f);				// Set The Color To A Nice Blue Shade
	glBegin(GL_QUADS);					// Start Drawing A Quad
		glVertex3f(-1.0f, 1.0f, 0.0f);			// Top Left Of The Quad
		glVertex3f( 1.0f, 1.0f, 0.0f);			// Top Right Of The Quad
		glVertex3f( 1.0f,-1.0f, 0.0f);			// Bottom Right Of The Quad
		glVertex3f(-1.0f,-1.0f, 0.0f);			// Bottom Left Of The Quad
	glEnd();						// Done Drawing The Quad

The next two lines are new. Think of rtri, and rquad as containers. At the top of our program we made the containers (GLfloat rtri, and GLfloat rquad). When we built the containers they had nothing in them. The first line below ADDS 0.2 to that container. So each time we check the value in the rtri container after this section of code, it will have gone up by 0.2. The rquad container decreases by 0.15. So every time we check the rquad container, it will have gone down by 0.15. Going down will cause the object to spin the opposite direction it would spin if you were going up.

Try chaning the + to a - in the line below see how the object spins the other direction. Try changing the values from 0.2 to 1.0. The higher the number, the faster the object will spin. The lower the number, the slower it will spin.

	rtri+=0.2f;						// Increase The Rotation Variable For The Triangle ( NEW )
	rquad-=0.15f;						// Decrease The Rotation Variable For The Quad     ( NEW )
	return TRUE;						// Keep Going
}

Finally change the code to toggle window / fullscreen mode so that the title at the top of the window is proper.

			if (keys[VK_F1])			// Is F1 Being Pressed?
			{
				keys[VK_F1]=FALSE;		// If So Make Key FALSE
				KillGLWindow();			// Kill Our Current Window
				fullscreen=!fullscreen;		// Toggle Fullscreen / Windowed Mode
				// Recreate Our OpenGL Window ( Modified )
				if (!CreateGLWindow("NeHe's Rotation Tutorial",640,480,16,fullscreen))
				{
					return 0;		// Quit If Window Was Not Created
				}
			}

In this tutorial I have tried to explain in as much detail as possible, how to rotate objects around an axis. Play around with the code, try spinning the objects, on the Z axis, the X & Y, or all three :) If you have comments or questions please email me. If you feel I have incorrectly commented something or that the code could be done better in some sections, please let me know. I want to make the best OpenGL tutorials I can. I'm interested in hearing your feedback.

Jeff Molofee (NeHe)

* DOWNLOAD Visual C++ Code For This Lesson.

* DOWNLOAD ASM Code For This Lesson. ( Conversion by Foolman )
* DOWNLOAD Borland C++ Builder 6 Code For This Lesson. ( Conversion by Christian Kindahl )
* DOWNLOAD BeOS Code For This Lesson. ( Conversion by Rene Manqueros )
* DOWNLOAD C# Code For This Lesson. ( Conversion by Sabine Felsinger )
* DOWNLOAD VB.Net CsGL Code For This Lesson. ( Conversion by X )
* DOWNLOAD Code Warrior 5.3 Code For This Lesson. ( Conversion by Scott Lupton )
* DOWNLOAD Cygwin Code For This Lesson. ( Conversion by Stephan Ferraro )
* DOWNLOAD D Language Code For This Lesson. ( Conversion by Familia Pineda Garcia )
* DOWNLOAD Delphi Code For This Lesson. ( Conversion by Michal Tucek )
* DOWNLOAD Dev C++ Code For This Lesson. ( Conversion by Dan )
* DOWNLOAD Euphoria Code For This Lesson. ( Conversion by Evan Marshall )
* DOWNLOAD Game GLUT Code For This Lesson. ( Conversion by Milikas Anastasios )
* DOWNLOAD Genu Code For This Lesson. ( Conversion by Louis-Charles Dumais )
* DOWNLOAD GLUT Code For This Lesson. ( Conversion by Andy Restad )
* DOWNLOAD Irix Code For This Lesson. ( Conversion by Lakmal Gunasekara )
* DOWNLOAD Java Code For This Lesson. ( Conversion by Jeff Kirby )
* DOWNLOAD Java/SWT Code For This Lesson. ( Conversion by Victor Gonzalez )
* DOWNLOAD Jedi-SDL Code For This Lesson. ( Conversion by Dominique Louis )
* DOWNLOAD JoGL Code For This Lesson. ( Conversion by Kevin J. Duling )
* DOWNLOAD LCC Win32 Code For This Lesson. ( Conversion by Robert Wishlaw )
* DOWNLOAD Linux Code For This Lesson. ( Conversion by Richard Campbell )
* DOWNLOAD Linux/GLX Code For This Lesson. ( Conversion by Mihael Vrbanec )
* DOWNLOAD Linux/SDL Code For This Lesson. ( Conversion by Ti Leggett )
* DOWNLOAD LWJGL Code For This Lesson. ( Conversion by Mark Bernard )
* DOWNLOAD Mac OS Code For This Lesson. ( Conversion by Anthony Parker )
* DOWNLOAD Mac OS X/Cocoa Code For This Lesson. ( Conversion by Bryan Blackburn )
* DOWNLOAD MASM Code For This Lesson. ( Conversion by Nico (Scalp) )
* DOWNLOAD Power Basic Code For This Lesson. ( Conversion by Angus Law )
* DOWNLOAD Pelles C Code For This Lesson. ( Conversion by Pelle Orinius )
* DOWNLOAD Perl Code For This Lesson. ( Conversion by Cora Hussey )
* DOWNLOAD Python Code For This Lesson. ( Conversion by John Ferguson )
* DOWNLOAD REALbasic Code For This Lesson. ( Conversion by Thomas J. Cunningham )
* DOWNLOAD Ruby Code For This Lesson. ( Conversion by Manolo Padron Martinez )
* DOWNLOAD Scheme Code For This Lesson. ( Conversion by Jon DuBois )
* DOWNLOAD Solaris Code For This Lesson. ( Conversion by Lakmal Gunasekara )
* DOWNLOAD Visual Basic Code For This Lesson. ( Conversion by Ross Dawson )
* DOWNLOAD Visual Fortran Code For This Lesson. ( Conversion by Jean-Philippe Perois )
* DOWNLOAD Visual Studio .NET Code For This Lesson. ( Conversion by Grant James )

 

< Lesson 03Lesson 05 >