 |
|
GLUT Tutorial
Index
Setup
Basics Initialization Resizing the Window Animation
Input Keyboard Moving the Camera Advanced Keyboard Moving the Camera II Mouse
Pop-up Menus Basics Sub Menus Modifying a Menu Swapping Menus
Fonts Bitmap Fonts Bitmaps and the Ortho View Stroke Fonts
Extras Frames per Second GLUT Game Mode
Subwindows Creating and Destroying Subwindows Resizing SubWindows Rendering to SubWindows
OpenGLTutorials @ Lighthouse3d.com
Led Shader
View Frustum Culling
GLSL Tutorial
Maths Tutorial
Billboarding Tutorial
Picking Tutorial
Terrain Tutorial
Display Lists Tutorial
GLUT Tutorial
|
|
 |
|
GLUT Tutorial
Keyboard Example: Moving around the world II
In this section the last example is revisited. This time we'll use the advanced keyboard features. The code that follows will have comments only in the new bits.
In the initialization section we have two new variables: deltaAngle and deltaMove. These variables control the rotation and movement of the camera respectively. When non-zero some camera action will occur, when zero the camera is still. These two variables take an initial zero value, meaning that initially the camera is still.
#include <math.h>
#include <GL/glut.h>
float angle=0.0,deltaAngle = 0.0,ratio;
float x=0.0f,y=1.75f,z=5.0f;
float lx=0.0f,ly=0.0f,lz=-1.0f;
GLint snowman_display_list;
int deltaMove = 0;
void changeSize(int w, int h)
{
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;
ratio = 1.0f * w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the clipping volume
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}
void drawSnowMan() {
glColor3f(1.0f, 1.0f, 1.0f);
// Draw Body
glTranslatef(0.0f ,0.75f, 0.0f);
glutSolidSphere(0.75f,20,20);
// Draw Head
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.25f,20,20);
// Draw Eyes
glPushMatrix();
glColor3f(0.0f,0.0f,0.0f);
glTranslatef(0.05f, 0.10f, 0.18f);
glutSolidSphere(0.05f,10,10);
glTranslatef(-0.1f, 0.0f, 0.0f);
glutSolidSphere(0.05f,10,10);
glPopMatrix();
// Draw Nose
glColor3f(1.0f, 0.5f , 0.5f);
glRotatef(0.0f,1.0f, 0.0f, 0.0f);
glutSolidCone(0.08f,0.5f,10,2);
}
GLuint createDL() {
GLuint snowManDL;
// Create the id for the list
snowManDL = glGenLists(1);
// start list
glNewList(snowManDL,GL_COMPILE);
// call the function that contains
// the rendering commands
drawSnowMan();
// endList
glEndList();
return(snowManDL);
}
void initScene() {
glEnable(GL_DEPTH_TEST);
snowman_display_list = createDL();
}
void orientMe(float ang) {
lx = sin(ang);
lz = -cos(ang);
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}
void moveMeFlat(int i) {
x = x + i*(lx)*0.1;
z = z + i*(lz)*0.1;
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}
Here are some of the new bits. The function bellow starts by checking if any of the variables which define camera action are different from zero, and if so it will call the appropriate function to perform the required movement.
void renderScene(void) {
if (deltaMove)
moveMeFlat(deltaMove);
if (deltaAngle) {
angle += deltaAngle;
orientMe(angle);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw ground
glColor3f(0.9f, 0.9f, 0.9f);
glBegin(GL_QUADS);
glVertex3f(-100.0f, 0.0f, -100.0f);
glVertex3f(-100.0f, 0.0f, 100.0f);
glVertex3f( 100.0f, 0.0f, 100.0f);
glVertex3f( 100.0f, 0.0f, -100.0f);
glEnd();
// Draw 36 SnowMen
for(int i = -3; i < 3; i++)
for(int j=-3; j < 3; j++) {
glPushMatrix();
glTranslatef(i*10.0,0,j * 10.0);
glCallList(snowman_display_list);;
glPopMatrix();
}
glutSwapBuffers();
}
The functions that follow are the ones which we've registered as callbacks for the special keys, and normal keys release, respectively.
void pressKey(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT :
deltaAngle = -0.01f;break;
case GLUT_KEY_RIGHT :
deltaAngle = 0.01f;break;
case GLUT_KEY_UP :
deltaMove = 1;break;
case GLUT_KEY_DOWN :
deltaMove = -1;break;
}
}
void releaseKey(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT :
case GLUT_KEY_RIGHT :
deltaAngle = 0.0f;break;
case GLUT_KEY_UP :
case GLUT_KEY_DOWN :
deltaMove = 0;break;
}
}
In the main function there are three new lines:
glutIgnoreKeyRepeat is called with a non-zero parameter to ask GLUT to stop reporting key repeats. Afterwards, both glutSpecialUpFunc and glutKeyboardUpFunc are called to register the callbacks.
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(640,360);
glutCreateWindow("SnowMen from 3D-Tech");
initScene();
glutIgnoreKeyRepeat(1);
glutSpecialFunc(pressKey);
glutSpecialUpFunc(releaseKey);
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);
glutMainLoop();
return(0);
}
You can download the VC 6.0 project here. Try fooling around with the camera settings functions.
|