Introduction
I think one of the most important steps for beginners is to learn how to create a 3D space and navigate in this space. It is especially important to know how to navigate in 3D space. It can be very confusing for beginners. This program shows how to navigate in 3D space.
Using the Code
The base code is from the redbook "OpenGL Programming Guide (Third Edition)". This is a beginner level program to show how to navigate in 3D space. It uses glRotatef()
, glTranslatef()
and gluLookAt()
functions. I divided the 3D space with lines. The intersection of the x,y,z arises is the location (0,0,0). The doted parts of the lines are the negative sides of the axises.The z axis is not viewable, because we look at the space from (0,0,15) coordinates. I rotated the above picture so that the z axis can be seen.
- Green for x axis
- Red for y axis
- Blue for z axis
- x,X - rotates on x axis // uses
glRotatef()
function - y,Y - rotates on y axis "
- z,Z - rotates on z axis "
- left_key - translates to left (x axis) // uses
glTranslatef()
- right_key - translates to right (x axis) "
- up_key - translates up (y axis) "
- down_key - translates down (y axis) "
- page_up - translates on z axis (zoom in) "
- page_down - translates on z axis (zoom out) "
- j,J translates on x axis // uses
glLookAt()
- k,K translates on y axis "
- l,L translates on z axis "
- b,B rotates (+/-)90 degrees on x axis
- n,N rotates (+/-)90 degrees on y axis
- m,M rotates (+/-)90 degrees on z axis
- o,O brings everything to default (starting coordinates)
Notice that glTranslatef
and gluLookAt()
behave the same. However, it is not exactly the same. You can figure out by using this program.
#include "stdafx.h"
#include <GL/glut.h> // Once you include glut.h (you don't need gl.h or glu.h)
GLfloat X = 0.0f; GLfloat Y = 0.0f; GLfloat Z = 0.0f; GLfloat rotX = 0.0f; GLfloat rotY = 0.0f; GLfloat rotZ = 0.0f; GLfloat rotLx = 0.0f; GLfloat rotLy = 0.0f; GLfloat rotLz = 0.0f;
void glDisplayLines(void);
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); glEnable (GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); }
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(rotX,1.0,0.0,0.0); glRotatef(rotY,0.0,1.0,0.0); glRotatef(rotZ,0.0,0.0,1.0); glTranslatef(X, Y, Z); glBegin(GL_LINES);
glColor3f (0.0, 1.0, 0.0); glVertex3f(0,0,0);
glVertex3f(10,0,0);
glColor3f(1.0,0.0,0.0); glVertex3f(0,0,0);
glVertex3f(0,10,0);
glColor3f(0.0,0.0,1.0); glVertex3f(0,0,0);
glVertex3f(0,0,10);
glEnd();
glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x0101); glBegin(GL_LINES);
glColor3f (0.0, 1.0, 0.0); glVertex3f(-10,0,0);
glVertex3f(0,0,0);
glColor3f(1.0,0.0,0.0); glVertex3f(0,0,0);
glVertex3f(0,-10,0);
glColor3f(0.0,0.0,1.0); glVertex3f(0,0,0);
glVertex3f(0,0,-10);
glEnd();
glDisable(GL_LINE_STIPPLE); glPopMatrix(); glutSwapBuffers();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity ();
gluPerspective(75, (GLfloat) w /(GLfloat) h , 0.10, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void keyboard (unsigned char key, int x, int y)
{
switch (key) { case 'x': rotX -= 0.5f;
break;
case 'X': rotX += 0.5f;
break;
case 'y': rotY -= 0.5f;
break;
case 'Y': rotY += 0.5f;
break;
case 'z': rotZ -= 0.5f;
break;
case 'Z': rotZ += 0.5f;
break;
case 'j':
rotLx -= 0.2f;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
break;
case 'J':
rotLx += 0.2f;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
break;
case 'k':
rotLy -= 0.2f;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
break;
case 'K':
rotLy += 0.2f;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
break;
case 'l': if(rotLz + 14 >= 0)
rotLz -= 0.2f;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.
break;
case 'L':
rotLz += 0.2f;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
break;
case 'b': rotX -= 90.0f;
break;
case 'B': rotX += 90.0f;
break;
case 'n': rotY -= 90.0f;
break;
case 'N': rotY += 90.0f;
break;
case 'm': rotZ -= 90.0f;
break;
case 'M': rotZ += 90.0f;
break;
case 'o': case 'O':
X = Y = 0.0f;
Z = 0.0f;
rotX = 0.0f;
rotY = 0.0f;
rotZ = 0.0f;
rotLx = 0.0f;
rotLy = 0.0f;
rotLz = 0.0f;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(rotLx, rotLy, 15.0f + rotLz, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
break;
}
glutPostRedisplay(); }
void specialKey(int key, int x, int y) {
switch(key) {
case GLUT_KEY_LEFT : X -= 0.1f;
break;
case GLUT_KEY_RIGHT : X += 0.1f;
break;
case GLUT_KEY_UP : Y += 0.1f;
break;
case GLUT_KEY_DOWN : Y -= 0.1f;
break;
case GLUT_KEY_PAGE_UP: Z -= 0.1f;
break;
case GLUT_KEY_PAGE_DOWN: Z += 0.1f;
break;
}
glutPostRedisplay(); }
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (600,600); glutCreateWindow("OpenGL 3D Navigation Program");
init ();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard); glutSpecialFunc(specialKey); glutMainLoop();
return 0;
}