14,970,944 members
Articles / Desktop Programming / Win32
Article
Posted 19 Feb 2008

64.7K views
40 bookmarked

# OpenGL 3D Navigation with Tao and C#

Rate me:
19 Feb 2008CPOL2 min read
OpenGL 3D navigation with Tao and C#, using glRotatef, glTranslatef, and gluLookAt.

## 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.

C#
```using System;
using System.Collections.Generic;
using System.Text;
using Tao.OpenGl;
using Tao.FreeGlut;

{

sealed class Program
{
static float X = 0.0f;       // Translate screen to x direction (left or right)
static float Y = 0.0f;       // Translate screen to y direction (up or down)
static float Z = 0.0f;       // Translate screen to z direction (zoom in or out)
static float rotX = 0.0f;    // Rotate screen on x axis
static float rotY = 0.0f;    // Rotate screen on y axis
static float rotZ = 0.0f;    // Rotate screen on z axis

static float rotLx = 0.0f;   // Translate screen by using  the glulookAt
// function (left or right)
static float rotLy = 0.0f;   // Translate screen by using  the glulookAt
// function (up or down)
static float rotLz = 0.0f;   // Translate screen by using  the glulookAt
// function (zoom in or out)

// Initiliaze the OpenGL window
static void init()
{
Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);          // Clear the color
Gl.glShadeModel (Gl.GL_FLAT);                     // Set the shading model
// to GL_FLAT
Gl.glEnable (Gl.GL_LINE_SMOOTH);
Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST);  // Set Line Antialiasing
}

// Draw the lines (x,y,z)
static void display()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);             // Clear the Color Buffer
Gl.glPushMatrix();                              // It is important to push
// the Matrix before calling
// glRotatef and glTranslatef
Gl.glRotatef(rotX, 1.0f, 0.0f, 0.0f);           // Rotate on x
Gl.glRotatef(rotY, 0.0f, 1.0f, 0.0f);           // Rotate on y
Gl.glRotatef(rotZ, 0.0f, 0.0f, 1.0f);           // Rotate on z
Gl.glTranslatef(X, Y, Z);                       // Translates the screen
// left or right, up or down
// or zoom in zoom out

// Draw the positive side of the lines x,y,z
Gl.glBegin(Gl.GL_LINES);
Gl.glColor3f(0.0f, 1.0f, 0.0f);                // Green for x axis
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(10f, 0f, 0f);
Gl.glColor3f(1.0f, 0.0f, 0.0f);                // Red for y axis
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(0f, 10f, 0f);
Gl.glColor3f(0.0f, 0.0f, 1.0f);                // Blue for z axis
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(0f, 0f, 10f);
Gl.glEnd();

// Dotted lines for the negative sides of x,y,z
Gl.glEnable(Gl.GL_LINE_STIPPLE);            // Enable line stipple to
// use a dotted pattern for
// the lines
Gl.glLineStipple(1, 0x0101);                // Dotted stipple pattern for
// the lines
Gl.glBegin(Gl.GL_LINES);
Gl.glColor3f(0.0f, 1.0f, 0.0f);         // Green for x axis
Gl.glVertex3f(-10f, 0f, 0f);
Gl.glVertex3f(0f, 0f, 0f);
Gl.glColor3f(1.0f, 0.0f, 0.0f);         // Red for y axis
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(0f, -10f, 0f);
Gl.glColor3f(0.0f, 0.0f, 1.0f);         // Blue for z axis
Gl.glVertex3f(0f, 0f, 0f);
Gl.glVertex3f(0f, 0f, -10f);
Gl.glEnd();

Gl.glDisable(Gl.GL_LINE_STIPPLE);           // Disable the line stipple
Gl.glPopMatrix();                           // Don't forget to pop the Matrix
Glut.glutSwapBuffers();
}

// This function is called whenever the window size is changed
static void reshape (int w, int h)
{

Gl.glViewport (0, 0, w,  h);                // Set the viewport
Gl.glMatrixMode (Gl.GL_PROJECTION);         // Set the Matrix mode
Glu.gluPerspective(75f, (float) w /(float)h , 0.10f, 100.0f);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Glu.gluLookAt (rotLx, rotLy, 15.0f + rotLz, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f);
}

// This function is used for the navigation keys
public static void keyboard(byte key, int x, int y)
{
switch (key) {

// x,X,y,Y,z,Z uses the glRotatef() function
case 120:    // x           // Rotates screen on x axis
rotX -= 0.5f;
break;
case 88:    // X            // Opposite way
rotX += 0.5f;
break;
case 121:    // y           // Rotates screen on y axis
rotY -= 0.5f;
break;
case 89:    // Y            // Opposite way
rotY += 0.5f;
break;
case 122:    // z           // Rotates screen on z axis
rotZ -= 0.5f;
break;
case 90:    // Z            // Opposite way
rotZ += 0.5f;
break;

// j,J,k,K,l,L uses the gluLookAt function for navigation
case 106:   // j
rotLx -= 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 74:    // J
rotLx += 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 107:   // k
rotLy -= 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 75:    // K
rotLy += 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 108: // (l) It has a special case when the rotLZ becames less
// than -15 the screen is viewed from the opposite side
// therefore this if statement below does not allow rotLz
// be less than -15
if(rotLz + 14 >= 0)
rotLz -= 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0);
break;
case 76:    // L
rotLz += 0.2f;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Glu.gluLookAt (rotLx, rotLy, 15.0 + rotLz, 0.0, 0.0, 0.0, 0.0,
1.0, 0.0);
break;
case 98:    // b        // Rotates on x axis by -90 degree
rotX -= 90.0f;
break;
case 66:    // B        // Rotates on y axis by 90 degree
rotX += 90.0f;
break;
case 110:    // n       // Rotates on y axis by -90 degree
rotY -= 90.0f;
break;
case 78:    // N        // Rotates on y axis by 90 degree
rotY += 90.0f;
break;
case 109:    // m       // Rotates on z axis by -90 degree
rotZ -= 90.0f;
break;
case 77:    // M        // Rotates on z axis by 90 degree
rotZ += 90.0f;
break;
case 111:    // o       // Default, resets the translations vies from
// starting view
case 80:    // 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;
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Glu.gluLookAt(rotLx, rotLy, 15.0f + rotLz, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f);

break;
}
Glut.glutPostRedisplay();    // Redraw the scene
}

// called on special key pressed
private static void specialKey(int key, int x, int y) {

// The keys below are using the gluLookAt() function for navigation
// Check which key is pressed
switch(key) {
case Glut.GLUT_KEY_LEFT :  // Rotate on x axis
X -= 0.1f;
break;
case Glut.GLUT_KEY_RIGHT:    // Rotate on x axis (opposite)
X +=  0.1f;
break;
case Glut.GLUT_KEY_UP:       // Rotate on y axis
Y += 0.1f;
break;
case Glut.GLUT_KEY_DOWN:     // Rotate on y axis (opposite)
Y -= 0.1f;
break;
case Glut.GLUT_KEY_PAGE_UP:  // Roatae on z axis
Z -= 0.1f;
break;
case Glut.GLUT_KEY_PAGE_DOWN:// Roatae on z axis (opposite)
Z += 0.1f;
break;
}
Glut.glutPostRedisplay();      // Redraw the scene
}
static void Main(string[] args)
{

Glut.glutInit();
// Setup display mode to double buffer and RGB color
Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_RGB);
// Set the screen size
Glut.glutInitWindowSize(600, 600);
Glut.glutCreateWindow("OpenGL 3D Navigation Program With Tao");
init();
Glut.glutReshapeFunc(reshape);
Glut.glutDisplayFunc(display);
// set window's key callback
Glut.glutKeyboardFunc(new Glut.KeyboardCallback(keyboard));
// set window's to specialKey callback
Glut.glutSpecialFunc(new Glut.SpecialCallback(
specialKey));
Glut.glutMainLoop();
}
}
}```

## About the Author

 Software Developer United States
None

## Comments and Discussions

 First Prev Next
 Thanks a lot wangzhe19458-Jul-10 3:40 wangzhe1945 8-Jul-10 3:40
 Thanks! ppaula7-Sep-09 17:54 ppaula 7-Sep-09 17:54
 reshaping works =) uaterelelli27-Dec-08 2:14 uaterelelli 27-Dec-08 2:14
 Nice Work Ben Daniel19-Feb-08 11:51 Ben Daniel 19-Feb-08 11:51
 Last Visit: 31-Dec-99 18:00     Last Update: 24-Jul-21 13:30 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.