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. Especially, how to navigate in 3D space is important. It can be very confusing for beginners. This program shows how to navigate in 3D space.
Background
I have the same project with a C++ Windows console application. If you are interested, check my other articles.
Using the code
The base code is from the red book "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 axes is the location (0,0,0). The doted parts of the lines are the negative sides of the axes. The z axis is not viewable, because we look at the space from the (0,0,15) coordinates. The above picture was rotated so 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 the
glRotatef()
function - y,Y - rotates on y axis; uses the
glRotatef()
function - z,Z - rotates on z axis; uses the
glRotatef()
function - left_key - translates to left (x axis); uses the
glTranslatef()
function - right_key - translates to right (x axis); uses the
glTranslatef()
function - up_key - translates up (y axis); uses the
glTranslatef()
function - down_key - translates down (y axis); uses the
glTranslatef()
function - page_up - translates on z axis (zoom in); uses the
glTranslatef()
function - page_down - translates on z axis (zoom out); uses the
glTranslatef()
function - j,J translates on x axis; uses the
glLookAt()
function - k,K translates on y axis; uses the
glLookAt()
function - l,L translates on z axis; uses the
glLookAt()
function - 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()
behaves the same. However, they are not exactly the same. You can figure this out by using this program.
using System;
using System.Collections.Generic;
using System.Text;
using Tao.OpenGl;
using Tao.FreeGlut;
namespace OpenGLNavigationWithTaoCSharp
{
sealed class Program
{
static float X = 0.0f;
static float Y = 0.0f;
static float Z = 0.0f;
static float rotX = 0.0f;
static float rotY = 0.0f;
static float rotZ = 0.0f;
static float rotLx = 0.0f;
static float rotLy = 0.0f;
static float rotLz = 0.0f;
static void init()
{
Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Gl.glShadeModel (Gl.GL_FLAT);
Gl.glEnable (Gl.GL_LINE_SMOOTH);
Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST);
}
static void display()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
Gl.glPushMatrix();
Gl.glRotatef(rotX, 1.0f, 0.0f, 0.0f);
Gl.glRotatef(rotY, 0.0f, 1.0f, 0.0f);
Gl.glRotatef(rotZ, 0.0f, 0.0f, 1.0f);
Gl.glTranslatef(X, Y, Z);
Gl.glBegin(Gl.GL_LINES);
Gl.glColor3f(0.0f, 1.0f, 0.0f);
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(10f, 0f, 0f);
Gl.glColor3f(1.0f, 0.0f, 0.0f);
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(0f, 10f, 0f);
Gl.glColor3f(0.0f, 0.0f, 1.0f);
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(0f, 0f, 10f);
Gl.glEnd();
Gl.glEnable(Gl.GL_LINE_STIPPLE);
Gl.glLineStipple(1, 0x0101);
Gl.glBegin(Gl.GL_LINES);
Gl.glColor3f(0.0f, 1.0f, 0.0f);
Gl.glVertex3f(-10f, 0f, 0f);
Gl.glVertex3f(0f, 0f, 0f);
Gl.glColor3f(1.0f, 0.0f, 0.0f);
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(0f, -10f, 0f);
Gl.glColor3f(0.0f, 0.0f, 1.0f);
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(0f, 0f, -10f);
Gl.glEnd();
Gl.glDisable(Gl.GL_LINE_STIPPLE);
Gl.glPopMatrix();
Glut.glutSwapBuffers();
}
static void reshape (int w, int h)
{
Gl.glViewport (0, 0, w, h);
Gl.glMatrixMode (Gl.GL_PROJECTION);
Gl.glLoadIdentity ();
Glu.gluPerspective(75f, (float) w /(float)h , 0.10f, 100.0f);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt (rotLx, rotLy, 15.0f + rotLz, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f);
}
public static void keyboard(byte key, int x, int y)
{
switch (key) {
case 120:
rotX -= 0.5f;
break;
case 88:
rotX += 0.5f;
break;
case 121:
rotY -= 0.5f;
break;
case 89:
rotY += 0.5f;
break;
case 122:
rotZ -= 0.5f;
break;
case 90:
rotZ += 0.5f;
break;
case 106:
rotLx -= 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 74:
rotLx += 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 107:
rotLy -= 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 75:
rotLy += 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 108:
if(rotLz + 14 >= 0)
rotLz -= 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 76:
rotLz += 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0,
1.0, 0.0);
break;
case 98:
rotX -= 90.0f;
break;
case 66:
rotX += 90.0f;
break;
case 110:
rotY -= 90.0f;
break;
case 78:
rotY += 90.0f;
break;
case 109:
rotZ -= 90.0f;
break;
case 77:
rotZ += 90.0f;
break;
case 111:
case 80:
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;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt(rotLx, rotLy, 15.0f + rotLz, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f);
break;
}
Glut.glutPostRedisplay();
}
private static void specialKey(int key, int x, int y) {
switch(key) {
case Glut.GLUT_KEY_LEFT :
X -= 0.1f;
break;
case Glut.GLUT_KEY_RIGHT:
X += 0.1f;
break;
case Glut.GLUT_KEY_UP:
Y += 0.1f;
break;
case Glut.GLUT_KEY_DOWN:
Y -= 0.1f;
break;
case Glut.GLUT_KEY_PAGE_UP:
Z -= 0.1f;
break;
case Glut.GLUT_KEY_PAGE_DOWN:
Z += 0.1f;
break;
}
Glut.glutPostRedisplay();
}
static void Main(string[] args)
{
Glut.glutInit();
Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_RGB);
Glut.glutInitWindowSize(600, 600);
Glut.glutCreateWindow("OpenGL 3D Navigation Program With Tao");
init();
Glut.glutReshapeFunc(reshape);
Glut.glutDisplayFunc(display);
Glut.glutKeyboardFunc(new Glut.KeyboardCallback(keyboard));
Glut.glutSpecialFunc(new Glut.SpecialCallback(
specialKey));
Glut.glutMainLoop();
}
}
}