OpenGL VRML W3D            
  Home Tutorials Books Applications Tools Docs Models Textures  

 

              Bugs

GLUT Tutorial   

  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


Google

OpenGLTutorials @ Lighthouse3d.com

Led Shader
View Frustum Culling
GLSL Tutorial
Maths Tutorial
Billboarding Tutorial
Picking Tutorial
Terrain Tutorial
Display Lists Tutorial
GLUT Tutorial

   
[Previous: Advanced Keyboard] [Next: Mouse]

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.

[Previous: Advanced Keyboard] [Next: Mouse]

       


Site designed and maintained by António Ramires Fernandes
Your comments, suggestions and references to further material are welcome!

Lighthouse 3D privacy statement