Introduction
This project is based on my previous project CS02OpenGL3DNavigationTaoCSharp
, however I did add more features in it. I think that one of the most important areas of knowledge for beginners in OpenGL is to learn how to create 3D space and navigate in this space. It can be very confusing if you don't know where you are actually looking. This program shows how to navigate in 3D space. This is a beginner level program to show how to navigate in 3D space. It uses glRotatef()
, glTranslatef()
and glLookAt()
functions for navigation. It has an example of key events, mouse events. It has an example of 3D cube and color. In order to make it easy, I divided the 3D space with lines. The intersection of the x,y,z axis is the location (0,0,0). The doted part of the line is the negative side for each axis. Notice that the z-axis is not viewable, because we look at the space from (0,0,15) coordinates.
Using the Code
- Green for x axis
- Red for y axis
- Blue for z axis
- x rotates on x axis // uses
glRotatef()
function
- X rotates to opposite direction "
- y rotates on y axis "
- Y rotates to opposite direction "
- z rotates on z axis "
- Z rotates to opposite direction "
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 translates on x axis, // uses
glLookAt()
J translates to opposite direction on x axis "
- k translates on y axis "
- K translates to opposite direction on y axis "
- l translates on z axis "
- L translates to opposite direction 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 starting position
*********************************************************
New Keys and Functionality
- F1 removes/shows the lines
- F2 rotates/stops the cube in x,y,z direction
- Left Mouse Down translates cube in x and y direction (up/down,left/right)
- Mouse wheel translates cube in +/- z direction (zoom in / zoom out)
using System;
using System.Collections.Generic;
using System.Text;
using Tao.OpenGl;
using Tao.FreeGlut;
namespace OpenGLNavigation2TaoCSharp
{
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 bool lines = true;
static bool rotation = false;
static int old_x, old_y;
static int mousePressed;
static void drawings()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_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);
if (rotation)
{
rotX += 0.2f;
rotY += 0.2f;
rotZ += 0.2f;
}
Gl.glTranslatef(X, Y, Z);
if (lines)
{
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.glBegin(Gl.GL_POLYGON);
Gl.glColor3f(0.0f, 0.0f, 1.0f);
Gl.glVertex3f(3.0f, 3.0f, 3.0f);
Gl.glColor3f(1.0f, 0.0f, 0.0f);
Gl.glVertex3f(3.0f, -3.0f, 3.0f);
Gl.glColor3f(0.0f, 1.0f, 0.0f);
Gl.glVertex3f(-3.0f, -3.0f, 3.0f);
Gl.glColor3f(1.0f, 0.0f, 1.0f);
Gl.glVertex3f(-3.0f, 3.0f, 3.0f);
Gl.glEnd();
Gl.glBegin(Gl.GL_POLYGON);
Gl.glColor3f(0.50f, 0.50f, 1.0f);
Gl.glVertex3f(3.0f, 3.0f, -3.0f);
Gl.glVertex3f(3.0f, -3.0f, -3.0f);
Gl.glVertex3f(-3.0f, -3.0f, -3.0f);
Gl.glVertex3f(-3.0f, 3.0f, -3.0f);
Gl.glEnd();
Gl.glBegin(Gl.GL_POLYGON);
Gl.glColor3f(0.0f, 1.0f, 0.0f);
Gl.glVertex3f(3.0f, 3.0f, 3.0f);
Gl.glVertex3f(3.0f, 3.0f, -3.0f);
Gl.glVertex3f(3.0f, -3.0f, -3.0f);
Gl.glVertex3f(3.0f, -3.0f, 3.0f);
Gl.glEnd();
Gl.glBegin(Gl.GL_POLYGON);
Gl.glColor3f(0.50f, 1.0f, 0.50f);
Gl.glVertex3f(-3.0f, 3.0f, 3.0f);
Gl.glVertex3f(-3.0f, -3.0f, 3.0f);
Gl.glVertex3f(-3.0f, -3.0f, -3.0f);
Gl.glVertex3f(-3.0f, 3.0f, -3.0f);
Gl.glEnd();
Gl.glBegin(Gl.GL_POLYGON);
Gl.glColor3f(1.0f, 0.0f, 0.0f);
Gl.glVertex3f(3.0f, 3.0f, 3.0f);
Gl.glVertex3f(3.0f, 3.0f, -3.0f);
Gl.glVertex3f(-3.0f, 3.0f, -3.0f);
Gl.glVertex3f(-3.0f, 3.0f, 3.0f);
Gl.glEnd();
Gl.glBegin(Gl.GL_POLYGON);
Gl.glColor3f(1.0f, 0.50f, 0.50f);
Gl.glVertex3f(3.0f, -3.0f, 3.0f);
Gl.glVertex3f(3.0f, -3.0f, -3.0f);
Gl.glVertex3f(-3.0f, -3.0f, -3.0f);
Gl.glVertex3f(-3.0f, -3.0f, 3.0f);
Gl.glEnd();
Gl.glDisable(Gl.GL_LINE_STIPPLE);
Glut.glutPostRedisplay();
Gl.glPopMatrix();
Glut.glutSwapBuffers();
}
static void init()
{
Gl.glShadeModel(Gl.GL_SMOOTH);
Gl.glClearColor(0, 0, 0, 0.0f);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glClearDepth(1.0f);
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glDepthFunc(Gl.GL_LEQUAL);
Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);
}
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, 500.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 -= 2.0f;
break;
case 88:
rotX += 2.0f;
break;
case 121:
rotY -= 2.0f;
break;
case 89:
rotY += 2.0f;
break;
case 122:
rotZ -= 2.0f;
break;
case 90:
rotZ += 2.0f;
break;
case 106:
rotLx -= 2.0f;
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 += 2.0f;
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 -= 2.0f;
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 += 2.0f;
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 -= 2.0f;
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 += 2.0f;
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:
rotation = false;
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 -= 2.0f;
break;
case Glut.GLUT_KEY_RIGHT:
X += 2.0f;
break;
case Glut.GLUT_KEY_UP:
Y += 2.0f;
break;
case Glut.GLUT_KEY_DOWN:
Y -= 2.0f;
break;
case Glut.GLUT_KEY_PAGE_UP:
Z -= 2.0f;
break;
case Glut.GLUT_KEY_PAGE_DOWN:
Z += 2.0f;
break;
case Glut.GLUT_KEY_F1:
lines = !lines;
break;
case Glut.GLUT_KEY_F2:
rotation = !rotation;
break;
default:
break;
}
Glut.glutPostRedisplay();
}
static void processMouseActiveMotion(int button, int state, int x, int y)
{
mousePressed = button;
old_x = x;
old_y = y;
}
static void processMouse(int x, int y)
{
if ((mousePressed == 0))
{
X = (x - old_x) / 15;
Y = -(y - old_y) / 15;
}
Glut.glutPostRedisplay();
}
static void processMouseWheel(int wheel, int direction, int x, int y)
{
Z += direction;
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(drawings);
Glut.glutKeyboardFunc(new Glut.KeyboardCallback(keyboard));
Glut.glutSpecialFunc(new Glut.SpecialCallback(specialKey));
Glut.glutMouseFunc(new Glut.MouseCallback(processMouseActiveMotion));
Glut.glutMotionFunc(new Glut.MotionCallback(processMouse));
Glut.glutMouseWheelFunc(new Glut.MouseWheelCallback(processMouseWheel));
Glut.glutMainLoop();
}
}
}
History
- 20th February, 2008: Initial post