SlideShare a Scribd company logo
Page 1 of 16
main.cpp 12/05/2011 23:06
/****
ELE 8050 - Computer Graphics
Sebastian Krezel (29043024)
Advanced Visualisation / Computer Graphics Course Work 2010/2011
The purpose of the course work is to reinforce your understanding of, and your ability to use,
the OpenGL 3D graphics programming library, and the platform independent utility toolkit (the GLUT).
The coursework task is:
Make an interactive version of ‘the Towers of Hanoi game’ (See next page),
Make the simulation using the OpenGL and GLUT libraries,
and provide an elementary user interface so that the game operated from the keyboard
and visualised interactively from different points of view.
Write a formal report in the software engineering style outlining the key steps in designing and building
the program and discuss enhancements you would like to see added to it.
The basic shapes can be build using standard primitives.
Try and augment the visual appearance by placing the model on a mirrored surface,
possibly add shadows and/or make the material take on a coloured metallic lustre using a reflection map,
and/or or use a surface image map or GPU shader to give the material the appearance of wood.
Provide some animation of the moves and facilitate basic interactivity via the keyboard or mouse.
(e.g. to change the viewpoint and select disks to be moved) You will need to think about your user interface design,
e.g. how is the user going to choose the piece to move.
You can generally find a pre-built version of the GLUT library already installed.
But it may be necessary to build the library from its source code.
You may also need to install a development environment,
Visual Studio can be obtained through the MSDNAA. GNU-C/C++ can be obtained for Window and Unix/Linux platforms,
and XCODE is free if you wish to develop on an Apple Mac
If you wanted to be really really adventurous it should possible to develop a version for an
iPhone or Android smart-phone platform. – using their simulators.
This coursework carries 40% of the total marks for the module:
■ 15% for the report and enhancement suggestions
■ 15% for the code design, layout and annotation
■ 10% for the usability and appearance of the finished program
|===3===| | |
|====2====| | |
|=====1=====| | |
--------------------------------------------------
TOWER OF HANOI
****/
#ifdef WIN32
#include "windows.h"
#else
#define WORD unsigned short
#define DWORD unsigned long
#define LONG long
// Structure - BMP file header
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
// Structure - BMP Info header
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
#endif
#if __APPLE__
/*
Tested on: Mac OSX 10.6.4
Page 2 of 16
main.cpp 12/05/2011 23:06
XcodeVersion 3.2.4 (64-bit)
Component versions
Xcode IDE: 1708.0
Xcode Core: 1705.0
ToolSupport: 1591.0
Built-In (GPU)
Intel GMA 950:
64MB of Shared System Memory
OenGL ver: 2.1
*/
//Include libraries
#include <stdio.h>
#include <GLUT/glut.h>
#include <iostream>
#include <math.h>
#include <string.h>
#include <ctime>
//PC to MAC bit conversion
unsigned long pc2mac(unsigned long a){
unsigned long b;
b= a & (0x000000ff) << 24;
b |= a & (0x0000ff00) << 8 ;
b |= a & (0x00ff0000) >> 8 ;
b |= a & (0xff000000) >> 24 ;
return b;
}
#else
//Note: Other system has not been tested
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif
//Read short int from the file
unsigned short readShortInt(FILE *f){
unsigned short a,b;
fread((char*)&a,2,1,f);
b=a&(0x00ff) << 8;
b |= a&(0xff00) >> 8;
return b;
}
//Read long int from the file
unsigned long readLongInt(FILE *f){
unsigned long a,b;
fread((char*)&a,4,1,f);
b= a & (0x000000ff) << 24;
b |= a & (0x0000ff00) << 8 ;
b |= a & (0x00ff0000) >> 8 ;
b |= a & (0xff000000) >> 24 ;
return b;
}
//Loading BMP file - Use in texturing
unsigned char *LoadBmp(char *fn, int *wi, int *hi){
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
WORD bits;
FILE *t24;
unsigned char *lpBitmapBits;
long imagesize,nc;
// read the bitmap
t24=fopen((char *)fn,"rb");
if(t24 == NULL){printf("Could not open input file [%s]n",fn); exit(0);}
readShortInt(t24);
bmfh.bfSize=readLongInt(t24);
readShortInt(t24);
readShortInt(t24);
bmfh.bfOffBits=readLongInt(t24);
fread((char *)&bmih,sizeof(BITMAPINFOHEADER),1,t24);
if(bmih.biClrUsed != 0)nc=bmih.biClrUsed;
else{
bits = bmih.biBitCount;
switch (bits){
case 1: nc=2; break;
case 4: nc=16; break;
case 8: nc=256; break;
default: nc=0; break;
}
}
if(nc > 0) {
Page 3 of 16
main.cpp 12/05/2011 23:06
printf("Cannot handle paletted imagen");
exit(0);
}
imagesize = bmfh.bfSize - bmfh.bfOffBits;
printf("You have to allocate %ld n", imagesize);
lpBitmapBits = (unsigned char *)malloc(imagesize);
if(lpBitmapBits == NULL) {
printf("Cannot allocate memoryn");
fclose(t24);
exit (0);
}
fread((char *)lpBitmapBits,imagesize,1,t24);
fclose(t24);
#if __APPLE__
*wi=pc2mac(bmih.biWidth); *hi=pc2mac(bmih.biHeight);
#else
*wi=bmih.biWidth; *hi=bmih.biHeight;
#endif
return lpBitmapBits;
}
//Use standard namespace
using namespace std;
///////////////////////////////////////////////////////////
// Global variables
//This size fit nice (not hiding the dock )
//on my current resolution 1280 x 800
GLint WindowWidth = 1240; //1280;
GLint WindowHeight = 680; //800;
//to indicate rotate angle (board, light source)
GLfloat rtri = 0.0, Rlight = 0.0, rtrBoard = 0.0;
//Variables used in options (menu)
GLboolean menu_light = false;
GLboolean menu_texture = false;
GLboolean menu_solve = false;
GLboolean menu_restart = false;
GLboolean menu_surface = false;
GLboolean menu_restart_view = false;
GLboolean menu_details = false;
//Indicator of intro animation
GLboolean Gintro = true;
//Used in displaying details
GLint min_steps;
GLint no_steps;
//Time counter
time_t tstart = time(0), tend, tcount;
struct tm *current;
//Buffer for string conversions
char buffer [40];
//Light details
GLfloat fAmbLight[] = { 0.9f, 0.9f, 0.9f, 0.0f };
GLfloat fDiffLight[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat fSpecLight[] = { 0.9f, 0.9f, 0.9f, 0.0f };
GLfloat lightPos[] = {1.67f, 1.0f,-2.0f, 1.0f };
GLfloat border = 1; // used in light_move()
//Texturing
GLuint nTexture[7];
//Handle information about disk on each peg
GLint *peg_A, *peg_B, *peg_C;
//Game level, number of disk
GLint no_of_disk;
//Camera set up point
GLfloat camera_x = 4.3,
camera_y = 6,
camera_z = 7.25;
//Camera set up point for intro
GLfloat intro_camera_x = -48.5,
intro_camera_y = 20,
intro_camera_z = 7.25;
GLdouble posX, posY, posZ, //Handle mouse position in 3d space
Page 4 of 16
main.cpp 12/05/2011 23:06
ghostX, ghostY; //position of animated disk (ghost disk)
//Approximation of round objects
const GLfloat ROUND = 30;
//Hight from reflective surface
GLfloat HEIGHT = 0.0f;
//Details of the disk movement
GLint from = 0, to = 0;
//Mouse movement
GLfloat moveX = 0.0;
//Quadric - cylinders, spheres
GLUquadricObj *IDquadric;
//Mouse button is holed
bool lbuttonDown = false;
///////////////////////////////////////////////
// Tesselate floor
void drawFloor(void) {
float x, y, d = 1.0;
// Draw ground.
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, nTexture[6]);
glTranslatef(0.0, 0.1, 0.0);
glNormal3f(0,1,0);
// Tesselate floor so lighting looks more reasonable.
for (x=-8; x<=7; x+=d) {
glBegin(GL_QUAD_STRIP);
for (y=-8; y<=8; y+=d) {
glTexCoord2f(x+1, y);
glVertex3f(x+1, 0, y);
glTexCoord2f(x, y);
glVertex3f(x, 0, y);
}
glEnd();
}
glDisable(GL_TEXTURE_2D);
}
///////////////////////////////////////////////////////////
// Check if you win
bool win() {
int count = 0;
//Calculate who many disk you have on peg_C
for(int i = 0; i < no_of_disk; i++) {
if (peg_C[i] == i+1) count += 1;
}
//If all disk are on "C" you win
if (count == no_of_disk) {
return true;
}else return false;
}
///////////////////////////////////////////////////////////
// Initialize game details
void init_hanoi() {
//First clean up
delete [] peg_A;
delete [] peg_B;
delete [] peg_C;
//Allocate tables plus one cell to store index of the top disk
peg_A = new int[no_of_disk + 1];
peg_B = new int[no_of_disk + 1];
peg_C = new int[no_of_disk + 1];
for (int i = 0; i < no_of_disk; i++) {
//Put all disk at the first peg and clear others
peg_A[i] = i+1;
peg_B[i] = 0;
peg_C[i] = 0;
}
//Put the proper flag at the end of the table
peg_A[no_of_disk] = no_of_disk;
peg_B[no_of_disk] = 0;
Page 5 of 16
main.cpp 12/05/2011 23:06
peg_C[no_of_disk] = 0;
//Init variables used in Details
no_steps = 0;
min_steps = pow(2, no_of_disk) - 1;
if (lbuttonDown) tstart = time(0);
}
///////////////////////////////////////////////////////////
// Conversion between window and openGL
// return the correct OpenGL coordinates from mouse coordinates
void GetOGLPos(int x, int y) {
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);
winX = (float)x;
winY = (float)viewport[3] - (float)y;
glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
}
///////////////////////////////////////////////////////////
// Move peg from S-source to D-destination peg
bool move_it(int *S, int *D) {
int S_index, D_index;
//Check if you have disk to be moved
if (S[no_of_disk] == 0) {
return false;
} else {
S_index = S[no_of_disk] - 1;
//Peg is empty so we can put disk on it
if ((D[no_of_disk] == 0)) {
D[0] = S[S_index];
S[S_index] = 0;
S[no_of_disk] -= 1;
D[no_of_disk] += 1;
no_steps +=1; //Count this move
return true;
} else D_index = D[no_of_disk];
//Check if possible to move
if (S[S_index] > D[D_index - 1]) {
D[D_index] = S[S_index];
S[S_index] = 0;
S[no_of_disk] -= 1;
D[no_of_disk] += 1;
no_steps +=1; //Count this move
return true;
} else {
//You cant put bigger on smaller
return false;
}
}
}
///////////////////////////////////////////////////////////
// This function shows game details in the console
// It was used for testing purposes while implementing "solve_it()" function
//
// Example:
//
//
// //Test legal move between A and B Track solving steps:
// if (!move_it(B, C)) { [ 3 ][ 0 ][ 1 ]
// move_it(C,B); [ 0 ][ 0 ][ 2 ]
// console_hanoi(A,B,C); [ 0 ][ 0 ][ 0 ]
// } else console_hanoi(A,B,C); ___________________
// [ 1 ][ 0 ][ 2 ]
//
// currently not used to keep final code clear
Page 6 of 16
main.cpp 12/05/2011 23:06
void console_hanoi (int *A, int *B, int *C) {
cout << "Track solving steps:" << endl;
//For simplicity show it up side down
for (int i = 0; i < no_of_disk + 1; i++) {
if (i == no_of_disk) cout << "___________________" << endl;
//Display flags, number of disk on the peg
cout << "[ " << A[i] << " ]" << "[ " << B[i] << " ]" << "[ " << C[i] << " ]" << endl;
}
cout << endl << endl;
}
///////////////////////////////////////////////////////////
// Function is solving the game
void solve_it(int *A, int *B, int *C) {
//Use iterative solution
//In each case (even,odd), a total of 2n-1 moves are made.
//For an even number of disks:
if (no_of_disk % 2 == 0) {
//make the legal move between pegs A and B
if (!move_it(A,B)) move_it(B,A);
//make the legal move between pegs A and C
if (!move_it(A, C)) move_it(C,A);
//make the legal move between pegs B and C
if (!move_it(B, C)) move_it(C,B);
//For odd number of disk
} else {
//make the legal move between pegs A and C
if (!move_it(A,C)) move_it(C,A);
else {
//If solved just go out from this function
if (win()) return;
}
//make the legal move between pegs A and B
if (!move_it(A,B)) move_it(B,A);
//make the legal move between pegs B and C
if (!move_it(B,C)) move_it(C,B);
}
}
///////////////////////////////////////////////////////////
// Draw "ghost" disk to help track user movement and improve interface
void ghost_disk (GLfloat x, GLfloat y) {
int index;
//GLfloat h = 0; //hight position
GLfloat radius = 0, r_max = 1.1; //declare radius var
GLfloat r_step = 0.9 / no_of_disk; //calculate difference in radius between disks
switch (from) {
case 1:
if (peg_A[no_of_disk] != 0) {
index = peg_A[no_of_disk] -1;
radius = r_max - ((peg_A[index] - 1) * r_step);
radius += 0.01; //Make it a bit bigger then original
}
break;
case 2:
if (peg_B[no_of_disk] != 0) {
index = peg_B[no_of_disk] -1;
radius = r_max - ((peg_B[index] - 1) * r_step);
radius += 0.01; //Make it a bit bigger then original
}
break;
case 3:
if (peg_C[no_of_disk] != 0) {
index = peg_C[no_of_disk] -1;
radius = r_max - ((peg_C[index] - 1) * r_step);
radius += 0.01; //Make it a bit bigger then original
}
break;
default:
break;
}
//Draw the ghost disk with proper radius and place on proper height
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, nTexture[4]);
glRotatef(90, 1.0f, 0.0, 0.0);
glTranslatef(x, 0.0, 0.0);
Page 7 of 16
main.cpp 12/05/2011 23:06
gluCylinder(IDquadric, radius, radius, 0.30f, ROUND, ROUND);
gluDisk(IDquadric, 0.125f, radius, ROUND, ROUND);
//Bottom circle of the disk - not really visible
//so we don't have to draw it
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
///////////////////////////////////////////////////////////
//Mouse button is clicked/hold...
//defining drag and drop disk movement
void mouse(int button, int state, int x, int y) {
//Use only left mouse button to drag and drop disk
if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN) {
lbuttonDown = true;
GetOGLPos(x,y);
//Check what peg you "drag"
if (posX > -4.0 and posX < -1.34 and posY > 0) from = 1; //peg_A
if (posX > -1.3 and posX < 1.32 and posY > 0) from = 2; //peg_B
if (posX > 1.32 and posX < 4 and posY > 0) from = 3; //peg_C
if (win()) {
//Go to next level, Put limit of 13 disk
//It fit nice on pegs
if (no_of_disk < 13) no_of_disk += 1;
//Initialise new level
init_hanoi();
//go back to normal view - stop spinning
rtri = 0;
}
}
else {
lbuttonDown = false;
GetOGLPos(x,y);
//If drop disk on peg A
if (posX > -4.0 and posX < -1.34 and posY > 0) {
to = 1; //peg_A
switch (from) {
case 1:
break;
case 2:
move_it(peg_B, peg_A);
break;
case 3:
move_it(peg_C, peg_A);
break;
}
}
//If drop disk on peg B
if (posX > -1.3 and posX < 1.32 and posY > 0) {
to = 2; //peg_B
switch (from) {
case 1:
move_it(peg_A, peg_B);
break;
case 2:
break;
case 3:
move_it(peg_C, peg_B);
break;
}
}
//If drop disk on peg C
if (posX > 1.32 and posX < 4 and posY > 0) {
to = 3; //peg_C
switch (from) {
case 1:
move_it(peg_A, peg_C);
break;
case 2:
move_it(peg_B, peg_C);
break;
case 3:
break;
}
}
}
}
}
Page 8 of 16
main.cpp 12/05/2011 23:06
///////////////////////////////////////////////////////////
//Mouse motion
void motion(int x, int y) {
//If you hold left button and move mouse
//Update position of the cursor to refresh
//Animation of "ghost disk"
if (lbuttonDown) {
GetOGLPos(x, y);
}
}
///////////////////////////////////////////////////////////
// Defining key action
void processSpecialKeys(int key, int x, int y) {
switch(key) {
case GLUT_KEY_F1:
menu_restart = !menu_restart;
tstart = time(0);
break;
case GLUT_KEY_F2:
//Place disks on start position Before solving
//Avoid infinitive loops in iterative algorithm
menu_restart = true;
menu_solve = !menu_solve;
break;
case GLUT_KEY_F3:
menu_texture = !menu_texture;
break;
case GLUT_KEY_F4:
menu_surface = !menu_surface;
break;
case GLUT_KEY_F5:
menu_light = !menu_light;
break;
case GLUT_KEY_F6:
menu_restart_view = !menu_restart_view;
break;
case GLUT_KEY_F7:
menu_details = !menu_details;
break;
}
}
///////////////////////////////////////////////////////////
// Defining key action
void processNormalKeys(unsigned char key, int x, int y) {
//Light settings
if(key == 'q') lightPos[2] -= 0.25;
if(key == 'a') lightPos[2] += 0.25;
if(key == 'f') lightPos[0] += 0.25;
if(key == 's') lightPos[0] -= 0.25;
if(key == 'e') lightPos[1] += 0.25;
if(key == 'd') lightPos[1] -= 0.25;
//Camera positions
if (key == 'p') camera_z -= 0.25f;
if (key == ';') camera_z += 0.25f;
if (key == 'o')
//Don't go to low
//don't show whats under the board
if (camera_y > 0.5) camera_y -= 0.5f;
if (key == 'l') camera_y += 0.25f;
if (key == 'i') camera_x -= 0.25f;
if (key == 'k') camera_x += 0.25f;
if(key == 27) exit(0);
// Refresh the Window
glutPostRedisplay();
}
///////////////////////////////////////////////////////////////////////////////
// Reset flags as appropriate in response to menu selections
void ProcessMenu(int value) {
switch(value) {
case 1:
menu_restart = !menu_restart;
tstart = time(0);
break;
case 2:
//Place disks on start position Before solving
//Avoid infinitive loops in iterative algorithm
Page 9 of 16
main.cpp 12/05/2011 23:06
menu_restart = true;
menu_solve = !menu_solve;
break;
case 3:
menu_texture = !menu_texture;
break;
case 4:
menu_surface = !menu_surface;
break;
case 5:
menu_light = !menu_light;
break;
case 6:
menu_restart_view = !menu_restart_view;
break;
case 7:
menu_details = !menu_details;
break;
default:
break;
}
glutPostRedisplay();
}
///////////////////////////////////////////////////////////////////////////////
//process submenu - chose number of disk on board
void num_disk(int value) {
no_of_disk = value;
//Initialise with new number
init_hanoi();
tstart = time(0);
glutPostRedisplay();
}
///////////////////////////////////////////////////////////
// Called to clean quadric
void cleanupQuadric(void) {
gluDeleteQuadric(IDquadric);
cout << "cleanupQuadric completed" << endl;
}
///////////////////////////////////////////////////////////
// Called to clean up arrays
void cleanupArrays(void) {
delete [] peg_A;
delete [] peg_B;
delete [] peg_C;
peg_A = NULL;
peg_B = NULL;
peg_C = NULL;
cout << "cleanupArray completed" << endl;
}
///////////////////////////////////////////////////////////
// Called to draw a mirrored surface
void Surface() {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, nTexture[1]);
glBegin(GL_POLYGON);
glNormal3f(0.0, 1.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 8.0f, 0.15f,-8.0f); // Top Right Of The Quad (Top)
glTexCoord2f(0.0f, 1.0f); glVertex3f(-8.0f, 0.15f,-8.0f); // Top Left Of The Quad (Top)
glTexCoord2f(0.0f, 0.0f); glVertex3f(-8.0f, 0.15f, 8.0f); // Bottom Left Of The Quad (Top)
glTexCoord2f(1.0f, 0.0f); glVertex3f( 8.0f, 0.15f, 8.0f); // Bottom Right Of The Quad (Top)
glEnd();
glDisable(GL_TEXTURE_2D);
}
///////////////////////////////////////////////////////////
// Called to draw disk
// Depends of parameter type it draws disk with different textures
void draw_disk (GLfloat radius, GLfloat x, GLfloat h, GLboolean type) {
//Rough wood looking disks
//Use two different textures
if (type) {
glPushMatrix();
Page 10 of 16
main.cpp 12/05/2011 23:06
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, nTexture[4]);
glRotatef(90, 1.0f, 0.0, 0.0);
glTranslatef(x, 0.0, -h -0.6);
//Main part of the disk
gluCylinder(IDquadric,radius,radius,0.30f,ROUND, ROUND);
glDisable(GL_TEXTURE_2D);
//Top cover of the disk
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, nTexture[3]);
gluDisk(IDquadric,0.125f,radius,ROUND,ROUND);
//Bottom circle of the disk - not really visible
//so we don't have to draw it
glDisable(GL_TEXTURE_2D);
glPopMatrix();
//Use one texture for drawing
} else {
glPushMatrix();
glRotatef(90, 1.0f, 0.0, 0.0);
glTranslatef(x, 0.0, -h -0.4);
//Main part of the disk
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, nTexture[0]);
gluCylinder(IDquadric,radius,radius,0.30f,ROUND, ROUND);
gluDisk(IDquadric, 0.125f, radius, ROUND, ROUND);
//Bottom not visible
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
}
///////////////////////////////////////////////////////////
// Called to draw peg
void draw_peg(GLfloat x) {
glEnable(GL_TEXTURE_2D);
if (menu_texture)
glBindTexture(GL_TEXTURE_2D, nTexture[5]);
else
glBindTexture(GL_TEXTURE_2D, nTexture[0]);
glPushMatrix();
glTranslatef(x,0,0);
glRotatef(270.0, 1.0f, 0.0f, 0.0f);
gluCylinder(IDquadric, 0.15f, //base radius
0.1f, //top radius
4.0f, //height
ROUND, //approximation
ROUND //...
);
glTranslatef(0,0,4);
gluSphere(IDquadric,0.1f,ROUND,ROUND);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
///////////////////////////////////////////////////////////
// Called to draw game board
void draw_board() {
glEnable(GL_TEXTURE_2D);
if (menu_texture) glBindTexture(GL_TEXTURE_2D, nTexture[5]);
else glBindTexture(GL_TEXTURE_2D, nTexture[0]);
glBegin(GL_QUADS); // Start Drawing Hanoi board
glNormal3f(0.0, 1.0, 0.0); //Use to point proper sides for lighting
glTexCoord2f(1.0f, 1.0f); glVertex3f( 4.0f, 0.15f,-2.0f); // Top Right Of The Quad (Top)
glTexCoord2f(0.0f, 1.0f); glVertex3f(-4.0f, 0.15f,-2.0f); // Top Left Of The Quad (Top)
glTexCoord2f(0.0f, 0.0f); glVertex3f(-4.0f, 0.15f, 2.0f); // Bottom Left Of The Quad (Top)
glTexCoord2f(1.0f, 0.0f); glVertex3f( 4.0f, 0.15f, 2.0f); // Bottom Right Of The Quad (Top)
glNormal3f(0.0, -1.0, 0.0);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 4.0f,-0.15f, 2.0f); // Top Right Of The Quad (Bottom)
glTexCoord2f(0.0f, 1.0f); glVertex3f(-4.0f,-0.15f, 2.0f); // Top Left Of The Quad (Bottom)
glTexCoord2f(0.0f, 0.0f); glVertex3f(-4.0f,-0.15f,-2.0f); // Bottom Left Of The Quad (Bottom)
glTexCoord2f(1.0f, 0.0f); glVertex3f( 4.0f,-0.15f,-2.0f); // Bottom Right Of The Quad (Bottom)
glNormal3f(0.0, 0.0, 1.0);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 4.0f, 0.15f, 2.0f); // Top Right Of The Quad (Front)
Page 11 of 16
main.cpp 12/05/2011 23:06
glTexCoord2f(1.0f, 0.0f); glVertex3f(-4.0f, 0.15f, 2.0f); // Top Left Of The Quad (Front)
glTexCoord2f(1.0f, 1.0f); glVertex3f(-4.0f,-0.15f, 2.0f); // Bottom Left Of The Quad (Front)
glTexCoord2f(0.0f, 1.0f); glVertex3f( 4.0f,-0.15f, 2.0f); // Bottom Right Of The Quad (Front)
glNormal3f(0.0, 0.0, -1.0);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 4.0f,-0.15f,-2.0f); // Bottom Left Of The Quad (Back)
glTexCoord2f(1.0f, 1.0f); glVertex3f(-4.0f,-0.15f,-2.0f); // Bottom Right Of The Quad (Back)
glTexCoord2f(0.0f, 1.0f); glVertex3f(-4.0f, 0.15f,-2.0f); // Top Right Of The Quad (Back)
glTexCoord2f(0.0f, 0.0f); glVertex3f( 4.0f, 0.15f,-2.0f); // Top Left Of The Quad (Back)
glNormal3f(-1.0, 0.0, 0.0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-4.0f, 0.15f, 2.0f); // Top Right Of The Quad (Left)
glTexCoord2f(1.0f, 0.0f); glVertex3f(-4.0f, 0.15f,-2.0f); // Top Left Of The Quad (Left)
glTexCoord2f(1.0f, 1.0f); glVertex3f(-4.0f,-0.15f,-2.0f); // Bottom Left Of The Quad (Left)
glTexCoord2f(0.0f, 1.0f); glVertex3f(-4.0f,-0.15f, 2.0f); // Bottom Right Of The Quad (Left)
glNormal3f(1.0, 0.0, 0.0);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 4.0f, 0.15f,-2.0f); // Top Right Of The Quad (Right)
glTexCoord2f(1.0f, 1.0f); glVertex3f( 4.0f, 0.15f, 2.0f); // Top Left Of The Quad (Right)
glTexCoord2f(0.0f, 1.0f); glVertex3f( 4.0f,-0.15f, 2.0f); // Bottom Left Of The Quad (Right)
glTexCoord2f(0.0f, 0.0f); glVertex3f( 4.0f,-0.15f,-2.0f); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing
glDisable(GL_TEXTURE_2D);
}
///////////////////////////////////////////////////////////
//Functions draws all disks in the game radius depends of numbers
//of disk in the game
void draw_all_disks () {
GLfloat h = 0; //hight position
GLfloat r, r_max = 1.1; //declare radius var
GLfloat r_step = 0.9 / no_of_disk; //calculate difference in radius between disks
for (int i = 0; i < no_of_disk; i++) {
//draw on peg A
if (peg_A[i] != 0) {
//Calculate radius of the disk
r = r_max - ((peg_A[i] - 1) * r_step);
draw_disk (r, -2.5, h, menu_texture);
}
//draw on peg B
if (peg_B[i] != 0) {
//Calculate radius of the disk
r = r_max - ((peg_B[i] - 1) * r_step);
draw_disk (r, 0.0, h, menu_texture);
}
//draw on peg C
if (peg_C[i] != 0) {
//Calculate radius of the disk
r = r_max - ((peg_C[i] - 1) * r_step);
draw_disk (r, 2.5, h, menu_texture);
}
h += 0.3; //Move it up
}
}
///////////////////////////////////////////////////////////
//Function draw light source
//on the scene
void Draw_Light_Source () {
glPushMatrix();
glTranslatef(lightPos[0], lightPos[1], lightPos[2]);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, nTexture[2]);
glPushMatrix();
glRotatef(Rlight, 1.0, 1.0, 1.0);
gluSphere(IDquadric,0.15f,ROUND,ROUND);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
//////////////////////////////////////////////////////////////////////////
// To move light stripe slowly
void light_move() {
//Move just on y and z axis
lightPos[1] = 8.5;
lightPos[2] = -15.75;
//Set up range of movement
if (border == 1) {
Page 12 of 16
main.cpp 12/05/2011 23:06
lightPos[0] += 0.1;
if (lightPos[0] > 20.0) border = 0;
} else {
lightPos[0] -= 0.1;
if (lightPos[0] < -20.0) border = 1;
}
}
///////////////////////////////////////////////////////////
//Function combine all objets that have to be draw
void Draw_Hanoi () {
glPushMatrix();
draw_board(); //main board
draw_peg(0); //first stick
draw_peg(-2.5); //second stick
draw_peg(2.5); //third stick
draw_all_disks(); //draw disks
glPopMatrix();
}
///////////////////////////////////////////////////////////////////
//Function calculate camera position for intro animation purpose
bool intro() {
if (intro_camera_x < 3.5) intro_camera_x += 0.8;
//camera_x = -48.5,
if (intro_camera_y > 6) {
intro_camera_y -= 0.15;
return true;
} else return false;
}
///////////////////////////////////////////////////////////////////
//Function Display the text (r,g,b colours) on "viewing plane"
void DrawText(GLint x, GLint y, char* s, GLfloat r, GLfloat g, GLfloat b)
{
int lines;
char* p;
glDisable(GL_LIGHTING); //To get proper colour
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
//Change to Ortho
glOrtho(0.0, glutGet(GLUT_WINDOW_WIDTH),
0.0, glutGet(GLUT_WINDOW_HEIGHT), -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3f(r,g,b);
glRasterPos2i(x, y);
for(p = s, lines = 0; *p; p++) {
if (*p == 'n') {
lines++;
glRasterPos2i(x, y-(lines*18));
}
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p);
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glEnable(GL_LIGHTING); //Turn it back
}
///////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity(); //Re-set the view
glEnable(GL_NORMALIZE);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
//If flag is set up show light source
if (menu_light) Draw_Light_Source();
if (!intro())
Page 13 of 16
main.cpp 12/05/2011 23:06
gluLookAt(camera_x, camera_y, camera_z, // look from camera XYZ
0, 0, 0, // look at the origin
0, 1, 0 // positive Y up vector
);
else gluLookAt(intro_camera_x, intro_camera_y, intro_camera_z, 0, 0, 0, 0, 1, 0);
glScaled(1.1, 1.1, 1.1); //Make it a bit bigger
glRotatef(rtri,0.0f,1.0f,0.0f); //Rotate if Win
Draw_Hanoi(); //Draw board with disks
if (menu_surface) HEIGHT = 0.2;
else HEIGHT = 0;
glTranslatef(0.0f, -HEIGHT-0.3, 0.0f); //Place on surface
glEnable(GL_STENCIL_TEST); //Enable using the stencil buffer
glColorMask(0, 0, 0, 0); //Disable drawing colours to the screen
glDisable(GL_DEPTH_TEST); //Disable depth testing
glStencilFunc(GL_ALWAYS, 1, 1); //Make the stencil test always pass
//Make pixels in the stencil buffer be set to 1 when the stencil test passes
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
//Set all of the pixels covered by the floor to be 1 in the stencil buffer
//Draw mirrored plane
if (menu_surface) drawFloor();
else Surface();
glColorMask(1, 1, 1, 1); //Enable drawing colours to the screen
glEnable(GL_DEPTH_TEST); //Enable depth testing
//Make the stencil test pass only when the pixel is 1 in the stencil buffer
glStencilFunc(GL_EQUAL, 1, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); //Make the stencil buffer not change
//Draw Game board, reflected vertically, at all pixels where the stencil buffer is 1
glPushMatrix();
glScalef(1, -1, 1);
glTranslatef(0, HEIGHT, 0);
Draw_Hanoi();
glPopMatrix();
glDisable(GL_STENCIL_TEST); //Disable stencil buffer
//Blend the floor onto the screen
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glColor4f(1, 1, 1, 0.9f);
//Draw mirrored plane
if (menu_surface) drawFloor();
else Surface();
glDisable(GL_BLEND);
//If left button is pressed render move tracking disk
if (lbuttonDown) {
glPushMatrix();
glEnable (GL_BLEND);
glDepthMask (GL_FALSE);
glBlendFunc (GL_SRC_ALPHA, GL_ONE);
//Move if you point the game board
if (posX > -4 && posX < 4) {
if (posZ > -2 && posZ < 2) {
glTranslatef(posX, 1.0, posZ);
glColor4f(1, 1, 1, 0.5f);
ghost_disk(0.0, 4.0);
}
}
glDepthMask (GL_TRUE);
glDisable (GL_BLEND);
glPopMatrix();
}
//If you win display a message
if (win()) {
char tmp[50] = "You Solve it, Click to Next Level";
DrawText((glutGet(GLUT_WINDOW_WIDTH) /2) - 140, glutGet(GLUT_WINDOW_HEIGHT) /2, tmp, 1.0, 1.0, 1.0);
}
//If required display dame details
if (menu_details) {
sprintf(buffer, "Number of disks = %d", no_of_disk);
DrawText(20, glutGet(GLUT_WINDOW_HEIGHT) -30, buffer, 0.56, 0.34, 0.05);
sprintf(buffer, "Minimum to solve = %d", min_steps);
DrawText(20, glutGet(GLUT_WINDOW_HEIGHT) -50, buffer, 0.56, 0.34, 0.05);
sprintf(buffer, "Your moves: %d", no_steps);
DrawText(20, glutGet(GLUT_WINDOW_HEIGHT) -70, buffer, 0.56, 0.34, 0.05);
Page 14 of 16
main.cpp 12/05/2011 23:06
//Display time
current = localtime(&tcount);
sprintf(buffer, "Time: %02d:%02d:%02dn", current->tm_hour, current->tm_min, current->tm_sec);
DrawText(20, glutGet(GLUT_WINDOW_HEIGHT) -90, buffer, 0.56, 0.34, 0.05);
}
glColor3f(1.0, 1.0, 10.0);
glutSwapBuffers();
}
//////////////////////////////////////////////////////////////////////////
// Change viewing volume and viewport. Called when window is resized
void ChangeSize(int w, int h) {
GLfloat fAspect;
// Prevent a divide by zero
if(h == 0) h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
fAspect = (GLfloat)w/(GLfloat)h;
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Produce the perspective projection
gluPerspective(60.0f, fAspect, 1.0, 400.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
///////////////////////////////////////////////////////////
// Called by GLUT library when idle
void TimerFunction(int value) {
//If you show light object it will spin
Rlight +=1.2f;
//If you win current level board will spin until mouse button pressed
if (win()) {
rtri+=1.2f;
menu_solve = false;
lightPos[0] = 0.42;
lightPos[1] = 9.75;
lightPos[2] = -22;
}
//If chose run light movement
if (menu_surface) light_move();
//If chose solve puzzles
if (menu_solve) solve_it(peg_A, peg_B, peg_C);
//If restart level
if (menu_restart) {
init_hanoi();
menu_restart = !menu_restart;
}
//Restart view
if (menu_restart_view) {
camera_x = 4.3;
camera_y = 6;
camera_z = 7.25;
menu_restart_view = !menu_restart_view;
}
if (!win()) tend = time(0);
tcount = difftime(tend, tstart);
//Redraw the scene with new coordinates
glutPostRedisplay();
glutTimerFunc(1,TimerFunction, 1);
}
///////////////////////////////////////////////////////////
// Setting up texture
void SetupTexture (char *name, int nT) {
unsigned char *pix;
GLint w,h;
glBindTexture(GL_TEXTURE_2D, nT);
Page 15 of 16
main.cpp 12/05/2011 23:06
pix = LoadBmp(name,&w,&h);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h,
0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pix);
free(pix);
pix = NULL;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
///////////////////////////////////////////////////////////
// Setup the rendering state
void SetupRC(void) {
char tmp[50];
glShadeModel(GL_SMOOTH); //Enables Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Background
IDquadric=gluNewQuadric(); //Create A Pointer To The Quadric Object
gluQuadricNormals(IDquadric, GLU_SMOOTH); //Create Smooth Normals
gluQuadricTexture(IDquadric, GL_TRUE); //Create Texture Coords
no_of_disk = 3; //Game start level
init_hanoi(); //Initialize data
glClearDepth(1.0f); //Depth Buffer Setup
glEnable(GL_DEPTH_TEST); //Enables Depth Testing
glDepthFunc(GL_LEQUAL); //The Type Of Depth Test To Do
// Set up lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR, fDiffLight);
glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 64);
//Set up blending function
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glLightfv(GL_LIGHT0, GL_AMBIENT, fAmbLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, fDiffLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, fSpecLight);
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
//Perspective Calculations
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//Texturing
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glGenTextures(6, nTexture);
//Prepare all textures for use
//To avoid conversion warning use strcpy
strcpy (tmp,"tex1.bmp"); SetupTexture(tmp, nTexture[0]);
strcpy (tmp,"tex2.bmp"); SetupTexture(tmp, nTexture[1]);
strcpy (tmp,"tex3.bmp"); SetupTexture(tmp, nTexture[2]);
strcpy (tmp,"tex4.bmp"); SetupTexture(tmp, nTexture[3]);
strcpy (tmp,"tex5.bmp"); SetupTexture(tmp, nTexture[4]);
strcpy (tmp,"tex6.bmp"); SetupTexture(tmp, nTexture[5]);
strcpy (tmp,"tex7.bmp"); SetupTexture(tmp, nTexture[6]);
//Clean up at exit
atexit(cleanupQuadric);
atexit(cleanupArrays);
}
///////////////////////////////////////////////////////////
// Main program entry point
int main(int argc, char* argv[]) {
GLint sub;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(WindowWidth, WindowHeight);
glutInitWindowPosition(0, 0); //Place window on left top corner
glutCreateWindow("Tower of Hanoi - Sebastian Krezel - Courswork");
//No of disk - sub menu
sub = glutCreateMenu(num_disk);
glutAddMenuEntry("3", 3);
glutAddMenuEntry("4", 4);
glutAddMenuEntry("5", 5);
glutAddMenuEntry("6", 6);
Page 16 of 16
main.cpp 12/05/2011 23:06
glutAddMenuEntry("7", 7);
glutAddMenuEntry("8", 8);
glutAddMenuEntry("9", 9);
glutAddMenuEntry("10", 10);
glutAddMenuEntry("11", 11);
glutAddMenuEntry("12", 12);
glutAddMenuEntry("13", 13);
//Create the Menu
glutCreateMenu(ProcessMenu);
glutAddMenuEntry("Restart this level" ,1);
glutAddSubMenu("Pick-up no of disk" ,sub);
glutAddMenuEntry("Solve it for me!" ,2);
glutAddMenuEntry("Change Textures" ,3);
glutAddMenuEntry("Change Surface and Light",4);
glutAddMenuEntry("Show Light Opject" ,5);
glutAddMenuEntry("Restart view" ,6);
glutAddMenuEntry("Show details" ,7);
glutAttachMenu(GLUT_RIGHT_BUTTON);
SetupRC();
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
//Keyboard controls
glutKeyboardFunc(processNormalKeys);
glutSpecialFunc(processSpecialKeys);
//Mouse controls
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutTimerFunc(33, TimerFunction, 1);
glutMainLoop();
return 0;
}

More Related Content

Similar to main.pdf java programming practice for programs

Verilog tutorial
Verilog tutorialVerilog tutorial
Verilog tutorial
Abhiraj Bohra
 
Roll your own toy unix clone os
Roll your own toy unix clone osRoll your own toy unix clone os
Roll your own toy unix clone os
eramax
 
Oop Presentation
Oop PresentationOop Presentation
Oop Presentation
Ganesh Samarthyam
 
Introduction to CUDA C: NVIDIA : Notes
Introduction to CUDA C: NVIDIA : NotesIntroduction to CUDA C: NVIDIA : Notes
Introduction to CUDA C: NVIDIA : Notes
Subhajit Sahu
 
Drawing Figures
Drawing FiguresDrawing Figures
Drawing Figures
Ghaffar Khan
 
C Under Linux
C Under LinuxC Under Linux
C Under Linux
mohan43u
 
C for Java programmers (part 1)
C for Java programmers (part 1)C for Java programmers (part 1)
C for Java programmers (part 1)
Dmitry Zinoviev
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
Visual Engineering
 
为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?
勇浩 赖
 
Deep Learning Edge
Deep Learning Edge Deep Learning Edge
Deep Learning Edge
Ganesan Narayanasamy
 
BeagleBone Black: Platform Bring-Up with Upstream Components
BeagleBone Black: Platform Bring-Up with Upstream ComponentsBeagleBone Black: Platform Bring-Up with Upstream Components
BeagleBone Black: Platform Bring-Up with Upstream Components
GlobalLogic Ukraine
 
About Go
About GoAbout Go
About Go
Jongmin Kim
 
introduction to CUDA_C.pptx it is widely used
introduction to CUDA_C.pptx it is widely usedintroduction to CUDA_C.pptx it is widely used
introduction to CUDA_C.pptx it is widely used
Himanshu577858
 
Gift-VT Tools Development Overview
Gift-VT Tools Development OverviewGift-VT Tools Development Overview
Gift-VT Tools Development Overview
stn_tkiller
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
Miller Lee
 
Please write it in C not python .pdf
Please write it in C not python .pdfPlease write it in C not python .pdf
Please write it in C not python .pdf
abhisheksharmasre
 
ma project
ma projectma project
ma project
Aisu
 
Game Programming I - Introduction
Game Programming I - IntroductionGame Programming I - Introduction
Game Programming I - Introduction
Francis Seriña
 
PL-3 LAB MANUAL
PL-3 LAB MANUALPL-3 LAB MANUAL
Here is The code in C language .pdf
Here is The code in C language  .pdfHere is The code in C language  .pdf
Here is The code in C language .pdf
geetakannupillai1
 

Similar to main.pdf java programming practice for programs (20)

Verilog tutorial
Verilog tutorialVerilog tutorial
Verilog tutorial
 
Roll your own toy unix clone os
Roll your own toy unix clone osRoll your own toy unix clone os
Roll your own toy unix clone os
 
Oop Presentation
Oop PresentationOop Presentation
Oop Presentation
 
Introduction to CUDA C: NVIDIA : Notes
Introduction to CUDA C: NVIDIA : NotesIntroduction to CUDA C: NVIDIA : Notes
Introduction to CUDA C: NVIDIA : Notes
 
Drawing Figures
Drawing FiguresDrawing Figures
Drawing Figures
 
C Under Linux
C Under LinuxC Under Linux
C Under Linux
 
C for Java programmers (part 1)
C for Java programmers (part 1)C for Java programmers (part 1)
C for Java programmers (part 1)
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?为什么 rust-lang 吸引我?
为什么 rust-lang 吸引我?
 
Deep Learning Edge
Deep Learning Edge Deep Learning Edge
Deep Learning Edge
 
BeagleBone Black: Platform Bring-Up with Upstream Components
BeagleBone Black: Platform Bring-Up with Upstream ComponentsBeagleBone Black: Platform Bring-Up with Upstream Components
BeagleBone Black: Platform Bring-Up with Upstream Components
 
About Go
About GoAbout Go
About Go
 
introduction to CUDA_C.pptx it is widely used
introduction to CUDA_C.pptx it is widely usedintroduction to CUDA_C.pptx it is widely used
introduction to CUDA_C.pptx it is widely used
 
Gift-VT Tools Development Overview
Gift-VT Tools Development OverviewGift-VT Tools Development Overview
Gift-VT Tools Development Overview
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
 
Please write it in C not python .pdf
Please write it in C not python .pdfPlease write it in C not python .pdf
Please write it in C not python .pdf
 
ma project
ma projectma project
ma project
 
Game Programming I - Introduction
Game Programming I - IntroductionGame Programming I - Introduction
Game Programming I - Introduction
 
PL-3 LAB MANUAL
PL-3 LAB MANUALPL-3 LAB MANUAL
PL-3 LAB MANUAL
 
Here is The code in C language .pdf
Here is The code in C language  .pdfHere is The code in C language  .pdf
Here is The code in C language .pdf
 

More from RavinderKSingla

InTech-Utilising_virtual_environments_to_research_ways_to_improve_manipulatio...
InTech-Utilising_virtual_environments_to_research_ways_to_improve_manipulatio...InTech-Utilising_virtual_environments_to_research_ways_to_improve_manipulatio...
InTech-Utilising_virtual_environments_to_research_ways_to_improve_manipulatio...
RavinderKSingla
 
sdlc-Lecture2.doc System analsysis and design
sdlc-Lecture2.doc System analsysis and designsdlc-Lecture2.doc System analsysis and design
sdlc-Lecture2.doc System analsysis and design
RavinderKSingla
 
Information Systems, Design and MIS(MS-07).doc
Information Systems, Design and MIS(MS-07).docInformation Systems, Design and MIS(MS-07).doc
Information Systems, Design and MIS(MS-07).doc
RavinderKSingla
 
codeblocks-instructions.pdf
codeblocks-instructions.pdfcodeblocks-instructions.pdf
codeblocks-instructions.pdf
RavinderKSingla
 
Software_Engineering__8th_Ed.pdf
Software_Engineering__8th_Ed.pdfSoftware_Engineering__8th_Ed.pdf
Software_Engineering__8th_Ed.pdf
RavinderKSingla
 
glu1_3.pdf
glu1_3.pdfglu1_3.pdf
glu1_3.pdf
RavinderKSingla
 
OpenGL_Programming_Guide.pdf
OpenGL_Programming_Guide.pdfOpenGL_Programming_Guide.pdf
OpenGL_Programming_Guide.pdf
RavinderKSingla
 
ICTwhitepaperfinal.pdf
ICTwhitepaperfinal.pdfICTwhitepaperfinal.pdf
ICTwhitepaperfinal.pdf
RavinderKSingla
 
ictreport.pdf
ictreport.pdfictreport.pdf
ictreport.pdf
RavinderKSingla
 
midterm_fa08.pdf
midterm_fa08.pdfmidterm_fa08.pdf
midterm_fa08.pdf
RavinderKSingla
 
midterm_fa07.pdf
midterm_fa07.pdfmidterm_fa07.pdf
midterm_fa07.pdf
RavinderKSingla
 
Java Programming.pdf
Java Programming.pdfJava Programming.pdf
Java Programming.pdf
RavinderKSingla
 
final_2014.pdf
final_2014.pdffinal_2014.pdf
final_2014.pdf
RavinderKSingla
 
Android-Programming.pdf
Android-Programming.pdfAndroid-Programming.pdf
Android-Programming.pdf
RavinderKSingla
 
midterm10_sol.pdf
midterm10_sol.pdfmidterm10_sol.pdf
midterm10_sol.pdf
RavinderKSingla
 
Gate-Concept_of_Semaphore_Part_1_in_Operating_System_no_anno.pdf
Gate-Concept_of_Semaphore_Part_1_in_Operating_System_no_anno.pdfGate-Concept_of_Semaphore_Part_1_in_Operating_System_no_anno.pdf
Gate-Concept_of_Semaphore_Part_1_in_Operating_System_no_anno.pdf
RavinderKSingla
 

More from RavinderKSingla (16)

InTech-Utilising_virtual_environments_to_research_ways_to_improve_manipulatio...
InTech-Utilising_virtual_environments_to_research_ways_to_improve_manipulatio...InTech-Utilising_virtual_environments_to_research_ways_to_improve_manipulatio...
InTech-Utilising_virtual_environments_to_research_ways_to_improve_manipulatio...
 
sdlc-Lecture2.doc System analsysis and design
sdlc-Lecture2.doc System analsysis and designsdlc-Lecture2.doc System analsysis and design
sdlc-Lecture2.doc System analsysis and design
 
Information Systems, Design and MIS(MS-07).doc
Information Systems, Design and MIS(MS-07).docInformation Systems, Design and MIS(MS-07).doc
Information Systems, Design and MIS(MS-07).doc
 
codeblocks-instructions.pdf
codeblocks-instructions.pdfcodeblocks-instructions.pdf
codeblocks-instructions.pdf
 
Software_Engineering__8th_Ed.pdf
Software_Engineering__8th_Ed.pdfSoftware_Engineering__8th_Ed.pdf
Software_Engineering__8th_Ed.pdf
 
glu1_3.pdf
glu1_3.pdfglu1_3.pdf
glu1_3.pdf
 
OpenGL_Programming_Guide.pdf
OpenGL_Programming_Guide.pdfOpenGL_Programming_Guide.pdf
OpenGL_Programming_Guide.pdf
 
ICTwhitepaperfinal.pdf
ICTwhitepaperfinal.pdfICTwhitepaperfinal.pdf
ICTwhitepaperfinal.pdf
 
ictreport.pdf
ictreport.pdfictreport.pdf
ictreport.pdf
 
midterm_fa08.pdf
midterm_fa08.pdfmidterm_fa08.pdf
midterm_fa08.pdf
 
midterm_fa07.pdf
midterm_fa07.pdfmidterm_fa07.pdf
midterm_fa07.pdf
 
Java Programming.pdf
Java Programming.pdfJava Programming.pdf
Java Programming.pdf
 
final_2014.pdf
final_2014.pdffinal_2014.pdf
final_2014.pdf
 
Android-Programming.pdf
Android-Programming.pdfAndroid-Programming.pdf
Android-Programming.pdf
 
midterm10_sol.pdf
midterm10_sol.pdfmidterm10_sol.pdf
midterm10_sol.pdf
 
Gate-Concept_of_Semaphore_Part_1_in_Operating_System_no_anno.pdf
Gate-Concept_of_Semaphore_Part_1_in_Operating_System_no_anno.pdfGate-Concept_of_Semaphore_Part_1_in_Operating_System_no_anno.pdf
Gate-Concept_of_Semaphore_Part_1_in_Operating_System_no_anno.pdf
 

Recently uploaded

Lbs last rank 2023 9988kr47h4744j445.pdf
Lbs last rank 2023 9988kr47h4744j445.pdfLbs last rank 2023 9988kr47h4744j445.pdf
Lbs last rank 2023 9988kr47h4744j445.pdf
ashiquepa3
 
Gabrielle M. A. Sinaga Portfolio, Film Student (2024)
Gabrielle M. A. Sinaga Portfolio, Film Student (2024)Gabrielle M. A. Sinaga Portfolio, Film Student (2024)
Gabrielle M. A. Sinaga Portfolio, Film Student (2024)
GabrielleSinaga
 
官方认证美国旧金山州立大学毕业证学位证书案例原版一模一样
官方认证美国旧金山州立大学毕业证学位证书案例原版一模一样官方认证美国旧金山州立大学毕业证学位证书案例原版一模一样
官方认证美国旧金山州立大学毕业证学位证书案例原版一模一样
2zjra9bn
 
Tape Measure Training & Practice Assessments.pdf
Tape Measure Training & Practice Assessments.pdfTape Measure Training & Practice Assessments.pdf
Tape Measure Training & Practice Assessments.pdf
KateRobinson68
 
Resumes, Cover Letters, and Applying Online
Resumes, Cover Letters, and Applying OnlineResumes, Cover Letters, and Applying Online
Resumes, Cover Letters, and Applying Online
Bruce Bennett
 
Job Finding Apps Everything You Need to Know in 2024
Job Finding Apps Everything You Need to Know in 2024Job Finding Apps Everything You Need to Know in 2024
Job Finding Apps Everything You Need to Know in 2024
SnapJob
 
0624.speakingengagementsandteaching-01.pdf
0624.speakingengagementsandteaching-01.pdf0624.speakingengagementsandteaching-01.pdf
0624.speakingengagementsandteaching-01.pdf
Thomas GIRARD BDes
 
Learnings from Successful Jobs Searchers
Learnings from Successful Jobs SearchersLearnings from Successful Jobs Searchers
Learnings from Successful Jobs Searchers
Bruce Bennett
 
Status of Women in Pakistan.pptxStatus of Women in Pakistan.pptx
Status of Women in Pakistan.pptxStatus of Women in Pakistan.pptxStatus of Women in Pakistan.pptxStatus of Women in Pakistan.pptx
Status of Women in Pakistan.pptxStatus of Women in Pakistan.pptx
MuhammadWaqasBaloch1
 
Leadership Ambassador club Adventist module
Leadership Ambassador club Adventist moduleLeadership Ambassador club Adventist module
Leadership Ambassador club Adventist module
kakomaeric00
 
BUKU PENJAGAAN BUKU PENJAGAAN BUKU PENJAGAAN
BUKU PENJAGAAN BUKU PENJAGAAN BUKU PENJAGAANBUKU PENJAGAAN BUKU PENJAGAAN BUKU PENJAGAAN
BUKU PENJAGAAN BUKU PENJAGAAN BUKU PENJAGAAN
cahgading001
 
Introducing Gopay Mobile App For Environment.pptx
Introducing Gopay Mobile App For Environment.pptxIntroducing Gopay Mobile App For Environment.pptx
Introducing Gopay Mobile App For Environment.pptx
FauzanHarits1
 
在线制作加拿大萨省大学毕业证文凭证书实拍图原版一模一样
在线制作加拿大萨省大学毕业证文凭证书实拍图原版一模一样在线制作加拿大萨省大学毕业证文凭证书实拍图原版一模一样
在线制作加拿大萨省大学毕业证文凭证书实拍图原版一模一样
2zjra9bn
 
Leave-rules.ppt CCS leave rules 1972 for central govt employees
Leave-rules.ppt CCS leave rules 1972 for central govt employeesLeave-rules.ppt CCS leave rules 1972 for central govt employees
Leave-rules.ppt CCS leave rules 1972 for central govt employees
Sreenivas702647
 
lab.123456789123456789123456789123456789
lab.123456789123456789123456789123456789lab.123456789123456789123456789123456789
lab.123456789123456789123456789123456789
Ghh
 
Jill Pizzola's Tenure as Senior Talent Acquisition Partner at THOMSON REUTERS...
Jill Pizzola's Tenure as Senior Talent Acquisition Partner at THOMSON REUTERS...Jill Pizzola's Tenure as Senior Talent Acquisition Partner at THOMSON REUTERS...
Jill Pizzola's Tenure as Senior Talent Acquisition Partner at THOMSON REUTERS...
dsnow9802
 
IT Career Hacks Navigate the Tech Jungle with a Roadmap
IT Career Hacks Navigate the Tech Jungle with a RoadmapIT Career Hacks Navigate the Tech Jungle with a Roadmap
IT Career Hacks Navigate the Tech Jungle with a Roadmap
Base Camp
 
一比一原版布拉德福德大学毕业证(bradford毕业证)如何办理
一比一原版布拉德福德大学毕业证(bradford毕业证)如何办理一比一原版布拉德福德大学毕业证(bradford毕业证)如何办理
一比一原版布拉德福德大学毕业证(bradford毕业证)如何办理
taqyea
 
How to Prepare for Fortinet FCP_FAC_AD-6.5 Certification?
How to Prepare for Fortinet FCP_FAC_AD-6.5 Certification?How to Prepare for Fortinet FCP_FAC_AD-6.5 Certification?
How to Prepare for Fortinet FCP_FAC_AD-6.5 Certification?
NWEXAM
 
5 Common Mistakes to Avoid During the Job Application Process.pdf
5 Common Mistakes to Avoid During the Job Application Process.pdf5 Common Mistakes to Avoid During the Job Application Process.pdf
5 Common Mistakes to Avoid During the Job Application Process.pdf
Alliance Jobs
 

Recently uploaded (20)

Lbs last rank 2023 9988kr47h4744j445.pdf
Lbs last rank 2023 9988kr47h4744j445.pdfLbs last rank 2023 9988kr47h4744j445.pdf
Lbs last rank 2023 9988kr47h4744j445.pdf
 
Gabrielle M. A. Sinaga Portfolio, Film Student (2024)
Gabrielle M. A. Sinaga Portfolio, Film Student (2024)Gabrielle M. A. Sinaga Portfolio, Film Student (2024)
Gabrielle M. A. Sinaga Portfolio, Film Student (2024)
 
官方认证美国旧金山州立大学毕业证学位证书案例原版一模一样
官方认证美国旧金山州立大学毕业证学位证书案例原版一模一样官方认证美国旧金山州立大学毕业证学位证书案例原版一模一样
官方认证美国旧金山州立大学毕业证学位证书案例原版一模一样
 
Tape Measure Training & Practice Assessments.pdf
Tape Measure Training & Practice Assessments.pdfTape Measure Training & Practice Assessments.pdf
Tape Measure Training & Practice Assessments.pdf
 
Resumes, Cover Letters, and Applying Online
Resumes, Cover Letters, and Applying OnlineResumes, Cover Letters, and Applying Online
Resumes, Cover Letters, and Applying Online
 
Job Finding Apps Everything You Need to Know in 2024
Job Finding Apps Everything You Need to Know in 2024Job Finding Apps Everything You Need to Know in 2024
Job Finding Apps Everything You Need to Know in 2024
 
0624.speakingengagementsandteaching-01.pdf
0624.speakingengagementsandteaching-01.pdf0624.speakingengagementsandteaching-01.pdf
0624.speakingengagementsandteaching-01.pdf
 
Learnings from Successful Jobs Searchers
Learnings from Successful Jobs SearchersLearnings from Successful Jobs Searchers
Learnings from Successful Jobs Searchers
 
Status of Women in Pakistan.pptxStatus of Women in Pakistan.pptx
Status of Women in Pakistan.pptxStatus of Women in Pakistan.pptxStatus of Women in Pakistan.pptxStatus of Women in Pakistan.pptx
Status of Women in Pakistan.pptxStatus of Women in Pakistan.pptx
 
Leadership Ambassador club Adventist module
Leadership Ambassador club Adventist moduleLeadership Ambassador club Adventist module
Leadership Ambassador club Adventist module
 
BUKU PENJAGAAN BUKU PENJAGAAN BUKU PENJAGAAN
BUKU PENJAGAAN BUKU PENJAGAAN BUKU PENJAGAANBUKU PENJAGAAN BUKU PENJAGAAN BUKU PENJAGAAN
BUKU PENJAGAAN BUKU PENJAGAAN BUKU PENJAGAAN
 
Introducing Gopay Mobile App For Environment.pptx
Introducing Gopay Mobile App For Environment.pptxIntroducing Gopay Mobile App For Environment.pptx
Introducing Gopay Mobile App For Environment.pptx
 
在线制作加拿大萨省大学毕业证文凭证书实拍图原版一模一样
在线制作加拿大萨省大学毕业证文凭证书实拍图原版一模一样在线制作加拿大萨省大学毕业证文凭证书实拍图原版一模一样
在线制作加拿大萨省大学毕业证文凭证书实拍图原版一模一样
 
Leave-rules.ppt CCS leave rules 1972 for central govt employees
Leave-rules.ppt CCS leave rules 1972 for central govt employeesLeave-rules.ppt CCS leave rules 1972 for central govt employees
Leave-rules.ppt CCS leave rules 1972 for central govt employees
 
lab.123456789123456789123456789123456789
lab.123456789123456789123456789123456789lab.123456789123456789123456789123456789
lab.123456789123456789123456789123456789
 
Jill Pizzola's Tenure as Senior Talent Acquisition Partner at THOMSON REUTERS...
Jill Pizzola's Tenure as Senior Talent Acquisition Partner at THOMSON REUTERS...Jill Pizzola's Tenure as Senior Talent Acquisition Partner at THOMSON REUTERS...
Jill Pizzola's Tenure as Senior Talent Acquisition Partner at THOMSON REUTERS...
 
IT Career Hacks Navigate the Tech Jungle with a Roadmap
IT Career Hacks Navigate the Tech Jungle with a RoadmapIT Career Hacks Navigate the Tech Jungle with a Roadmap
IT Career Hacks Navigate the Tech Jungle with a Roadmap
 
一比一原版布拉德福德大学毕业证(bradford毕业证)如何办理
一比一原版布拉德福德大学毕业证(bradford毕业证)如何办理一比一原版布拉德福德大学毕业证(bradford毕业证)如何办理
一比一原版布拉德福德大学毕业证(bradford毕业证)如何办理
 
How to Prepare for Fortinet FCP_FAC_AD-6.5 Certification?
How to Prepare for Fortinet FCP_FAC_AD-6.5 Certification?How to Prepare for Fortinet FCP_FAC_AD-6.5 Certification?
How to Prepare for Fortinet FCP_FAC_AD-6.5 Certification?
 
5 Common Mistakes to Avoid During the Job Application Process.pdf
5 Common Mistakes to Avoid During the Job Application Process.pdf5 Common Mistakes to Avoid During the Job Application Process.pdf
5 Common Mistakes to Avoid During the Job Application Process.pdf
 

main.pdf java programming practice for programs

  • 1. Page 1 of 16 main.cpp 12/05/2011 23:06 /**** ELE 8050 - Computer Graphics Sebastian Krezel (29043024) Advanced Visualisation / Computer Graphics Course Work 2010/2011 The purpose of the course work is to reinforce your understanding of, and your ability to use, the OpenGL 3D graphics programming library, and the platform independent utility toolkit (the GLUT). The coursework task is: Make an interactive version of ‘the Towers of Hanoi game’ (See next page), Make the simulation using the OpenGL and GLUT libraries, and provide an elementary user interface so that the game operated from the keyboard and visualised interactively from different points of view. Write a formal report in the software engineering style outlining the key steps in designing and building the program and discuss enhancements you would like to see added to it. The basic shapes can be build using standard primitives. Try and augment the visual appearance by placing the model on a mirrored surface, possibly add shadows and/or make the material take on a coloured metallic lustre using a reflection map, and/or or use a surface image map or GPU shader to give the material the appearance of wood. Provide some animation of the moves and facilitate basic interactivity via the keyboard or mouse. (e.g. to change the viewpoint and select disks to be moved) You will need to think about your user interface design, e.g. how is the user going to choose the piece to move. You can generally find a pre-built version of the GLUT library already installed. But it may be necessary to build the library from its source code. You may also need to install a development environment, Visual Studio can be obtained through the MSDNAA. GNU-C/C++ can be obtained for Window and Unix/Linux platforms, and XCODE is free if you wish to develop on an Apple Mac If you wanted to be really really adventurous it should possible to develop a version for an iPhone or Android smart-phone platform. – using their simulators. This coursework carries 40% of the total marks for the module: ■ 15% for the report and enhancement suggestions ■ 15% for the code design, layout and annotation ■ 10% for the usability and appearance of the finished program |===3===| | | |====2====| | | |=====1=====| | | -------------------------------------------------- TOWER OF HANOI ****/ #ifdef WIN32 #include "windows.h" #else #define WORD unsigned short #define DWORD unsigned long #define LONG long // Structure - BMP file header typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER; // Structure - BMP Info header typedef struct tagBITMAPINFOHEADER { DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; #endif #if __APPLE__ /* Tested on: Mac OSX 10.6.4
  • 2. Page 2 of 16 main.cpp 12/05/2011 23:06 XcodeVersion 3.2.4 (64-bit) Component versions Xcode IDE: 1708.0 Xcode Core: 1705.0 ToolSupport: 1591.0 Built-In (GPU) Intel GMA 950: 64MB of Shared System Memory OenGL ver: 2.1 */ //Include libraries #include <stdio.h> #include <GLUT/glut.h> #include <iostream> #include <math.h> #include <string.h> #include <ctime> //PC to MAC bit conversion unsigned long pc2mac(unsigned long a){ unsigned long b; b= a & (0x000000ff) << 24; b |= a & (0x0000ff00) << 8 ; b |= a & (0x00ff0000) >> 8 ; b |= a & (0xff000000) >> 24 ; return b; } #else //Note: Other system has not been tested #include <GL/glut.h> #include <GL/gl.h> #include <GL/glu.h> #endif //Read short int from the file unsigned short readShortInt(FILE *f){ unsigned short a,b; fread((char*)&a,2,1,f); b=a&(0x00ff) << 8; b |= a&(0xff00) >> 8; return b; } //Read long int from the file unsigned long readLongInt(FILE *f){ unsigned long a,b; fread((char*)&a,4,1,f); b= a & (0x000000ff) << 24; b |= a & (0x0000ff00) << 8 ; b |= a & (0x00ff0000) >> 8 ; b |= a & (0xff000000) >> 24 ; return b; } //Loading BMP file - Use in texturing unsigned char *LoadBmp(char *fn, int *wi, int *hi){ BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; WORD bits; FILE *t24; unsigned char *lpBitmapBits; long imagesize,nc; // read the bitmap t24=fopen((char *)fn,"rb"); if(t24 == NULL){printf("Could not open input file [%s]n",fn); exit(0);} readShortInt(t24); bmfh.bfSize=readLongInt(t24); readShortInt(t24); readShortInt(t24); bmfh.bfOffBits=readLongInt(t24); fread((char *)&bmih,sizeof(BITMAPINFOHEADER),1,t24); if(bmih.biClrUsed != 0)nc=bmih.biClrUsed; else{ bits = bmih.biBitCount; switch (bits){ case 1: nc=2; break; case 4: nc=16; break; case 8: nc=256; break; default: nc=0; break; } } if(nc > 0) {
  • 3. Page 3 of 16 main.cpp 12/05/2011 23:06 printf("Cannot handle paletted imagen"); exit(0); } imagesize = bmfh.bfSize - bmfh.bfOffBits; printf("You have to allocate %ld n", imagesize); lpBitmapBits = (unsigned char *)malloc(imagesize); if(lpBitmapBits == NULL) { printf("Cannot allocate memoryn"); fclose(t24); exit (0); } fread((char *)lpBitmapBits,imagesize,1,t24); fclose(t24); #if __APPLE__ *wi=pc2mac(bmih.biWidth); *hi=pc2mac(bmih.biHeight); #else *wi=bmih.biWidth; *hi=bmih.biHeight; #endif return lpBitmapBits; } //Use standard namespace using namespace std; /////////////////////////////////////////////////////////// // Global variables //This size fit nice (not hiding the dock ) //on my current resolution 1280 x 800 GLint WindowWidth = 1240; //1280; GLint WindowHeight = 680; //800; //to indicate rotate angle (board, light source) GLfloat rtri = 0.0, Rlight = 0.0, rtrBoard = 0.0; //Variables used in options (menu) GLboolean menu_light = false; GLboolean menu_texture = false; GLboolean menu_solve = false; GLboolean menu_restart = false; GLboolean menu_surface = false; GLboolean menu_restart_view = false; GLboolean menu_details = false; //Indicator of intro animation GLboolean Gintro = true; //Used in displaying details GLint min_steps; GLint no_steps; //Time counter time_t tstart = time(0), tend, tcount; struct tm *current; //Buffer for string conversions char buffer [40]; //Light details GLfloat fAmbLight[] = { 0.9f, 0.9f, 0.9f, 0.0f }; GLfloat fDiffLight[] = { 1.0f, 1.0f, 1.0f, 0.0f }; GLfloat fSpecLight[] = { 0.9f, 0.9f, 0.9f, 0.0f }; GLfloat lightPos[] = {1.67f, 1.0f,-2.0f, 1.0f }; GLfloat border = 1; // used in light_move() //Texturing GLuint nTexture[7]; //Handle information about disk on each peg GLint *peg_A, *peg_B, *peg_C; //Game level, number of disk GLint no_of_disk; //Camera set up point GLfloat camera_x = 4.3, camera_y = 6, camera_z = 7.25; //Camera set up point for intro GLfloat intro_camera_x = -48.5, intro_camera_y = 20, intro_camera_z = 7.25; GLdouble posX, posY, posZ, //Handle mouse position in 3d space
  • 4. Page 4 of 16 main.cpp 12/05/2011 23:06 ghostX, ghostY; //position of animated disk (ghost disk) //Approximation of round objects const GLfloat ROUND = 30; //Hight from reflective surface GLfloat HEIGHT = 0.0f; //Details of the disk movement GLint from = 0, to = 0; //Mouse movement GLfloat moveX = 0.0; //Quadric - cylinders, spheres GLUquadricObj *IDquadric; //Mouse button is holed bool lbuttonDown = false; /////////////////////////////////////////////// // Tesselate floor void drawFloor(void) { float x, y, d = 1.0; // Draw ground. glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, nTexture[6]); glTranslatef(0.0, 0.1, 0.0); glNormal3f(0,1,0); // Tesselate floor so lighting looks more reasonable. for (x=-8; x<=7; x+=d) { glBegin(GL_QUAD_STRIP); for (y=-8; y<=8; y+=d) { glTexCoord2f(x+1, y); glVertex3f(x+1, 0, y); glTexCoord2f(x, y); glVertex3f(x, 0, y); } glEnd(); } glDisable(GL_TEXTURE_2D); } /////////////////////////////////////////////////////////// // Check if you win bool win() { int count = 0; //Calculate who many disk you have on peg_C for(int i = 0; i < no_of_disk; i++) { if (peg_C[i] == i+1) count += 1; } //If all disk are on "C" you win if (count == no_of_disk) { return true; }else return false; } /////////////////////////////////////////////////////////// // Initialize game details void init_hanoi() { //First clean up delete [] peg_A; delete [] peg_B; delete [] peg_C; //Allocate tables plus one cell to store index of the top disk peg_A = new int[no_of_disk + 1]; peg_B = new int[no_of_disk + 1]; peg_C = new int[no_of_disk + 1]; for (int i = 0; i < no_of_disk; i++) { //Put all disk at the first peg and clear others peg_A[i] = i+1; peg_B[i] = 0; peg_C[i] = 0; } //Put the proper flag at the end of the table peg_A[no_of_disk] = no_of_disk; peg_B[no_of_disk] = 0;
  • 5. Page 5 of 16 main.cpp 12/05/2011 23:06 peg_C[no_of_disk] = 0; //Init variables used in Details no_steps = 0; min_steps = pow(2, no_of_disk) - 1; if (lbuttonDown) tstart = time(0); } /////////////////////////////////////////////////////////// // Conversion between window and openGL // return the correct OpenGL coordinates from mouse coordinates void GetOGLPos(int x, int y) { GLint viewport[4]; GLdouble modelview[16]; GLdouble projection[16]; GLfloat winX, winY, winZ; glGetDoublev(GL_MODELVIEW_MATRIX, modelview); glGetDoublev(GL_PROJECTION_MATRIX, projection); glGetIntegerv(GL_VIEWPORT, viewport); winX = (float)x; winY = (float)viewport[3] - (float)y; glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ); } /////////////////////////////////////////////////////////// // Move peg from S-source to D-destination peg bool move_it(int *S, int *D) { int S_index, D_index; //Check if you have disk to be moved if (S[no_of_disk] == 0) { return false; } else { S_index = S[no_of_disk] - 1; //Peg is empty so we can put disk on it if ((D[no_of_disk] == 0)) { D[0] = S[S_index]; S[S_index] = 0; S[no_of_disk] -= 1; D[no_of_disk] += 1; no_steps +=1; //Count this move return true; } else D_index = D[no_of_disk]; //Check if possible to move if (S[S_index] > D[D_index - 1]) { D[D_index] = S[S_index]; S[S_index] = 0; S[no_of_disk] -= 1; D[no_of_disk] += 1; no_steps +=1; //Count this move return true; } else { //You cant put bigger on smaller return false; } } } /////////////////////////////////////////////////////////// // This function shows game details in the console // It was used for testing purposes while implementing "solve_it()" function // // Example: // // // //Test legal move between A and B Track solving steps: // if (!move_it(B, C)) { [ 3 ][ 0 ][ 1 ] // move_it(C,B); [ 0 ][ 0 ][ 2 ] // console_hanoi(A,B,C); [ 0 ][ 0 ][ 0 ] // } else console_hanoi(A,B,C); ___________________ // [ 1 ][ 0 ][ 2 ] // // currently not used to keep final code clear
  • 6. Page 6 of 16 main.cpp 12/05/2011 23:06 void console_hanoi (int *A, int *B, int *C) { cout << "Track solving steps:" << endl; //For simplicity show it up side down for (int i = 0; i < no_of_disk + 1; i++) { if (i == no_of_disk) cout << "___________________" << endl; //Display flags, number of disk on the peg cout << "[ " << A[i] << " ]" << "[ " << B[i] << " ]" << "[ " << C[i] << " ]" << endl; } cout << endl << endl; } /////////////////////////////////////////////////////////// // Function is solving the game void solve_it(int *A, int *B, int *C) { //Use iterative solution //In each case (even,odd), a total of 2n-1 moves are made. //For an even number of disks: if (no_of_disk % 2 == 0) { //make the legal move between pegs A and B if (!move_it(A,B)) move_it(B,A); //make the legal move between pegs A and C if (!move_it(A, C)) move_it(C,A); //make the legal move between pegs B and C if (!move_it(B, C)) move_it(C,B); //For odd number of disk } else { //make the legal move between pegs A and C if (!move_it(A,C)) move_it(C,A); else { //If solved just go out from this function if (win()) return; } //make the legal move between pegs A and B if (!move_it(A,B)) move_it(B,A); //make the legal move between pegs B and C if (!move_it(B,C)) move_it(C,B); } } /////////////////////////////////////////////////////////// // Draw "ghost" disk to help track user movement and improve interface void ghost_disk (GLfloat x, GLfloat y) { int index; //GLfloat h = 0; //hight position GLfloat radius = 0, r_max = 1.1; //declare radius var GLfloat r_step = 0.9 / no_of_disk; //calculate difference in radius between disks switch (from) { case 1: if (peg_A[no_of_disk] != 0) { index = peg_A[no_of_disk] -1; radius = r_max - ((peg_A[index] - 1) * r_step); radius += 0.01; //Make it a bit bigger then original } break; case 2: if (peg_B[no_of_disk] != 0) { index = peg_B[no_of_disk] -1; radius = r_max - ((peg_B[index] - 1) * r_step); radius += 0.01; //Make it a bit bigger then original } break; case 3: if (peg_C[no_of_disk] != 0) { index = peg_C[no_of_disk] -1; radius = r_max - ((peg_C[index] - 1) * r_step); radius += 0.01; //Make it a bit bigger then original } break; default: break; } //Draw the ghost disk with proper radius and place on proper height glPushMatrix(); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, nTexture[4]); glRotatef(90, 1.0f, 0.0, 0.0); glTranslatef(x, 0.0, 0.0);
  • 7. Page 7 of 16 main.cpp 12/05/2011 23:06 gluCylinder(IDquadric, radius, radius, 0.30f, ROUND, ROUND); gluDisk(IDquadric, 0.125f, radius, ROUND, ROUND); //Bottom circle of the disk - not really visible //so we don't have to draw it glDisable(GL_TEXTURE_2D); glPopMatrix(); } /////////////////////////////////////////////////////////// //Mouse button is clicked/hold... //defining drag and drop disk movement void mouse(int button, int state, int x, int y) { //Use only left mouse button to drag and drop disk if (button == GLUT_LEFT_BUTTON) { if (state == GLUT_DOWN) { lbuttonDown = true; GetOGLPos(x,y); //Check what peg you "drag" if (posX > -4.0 and posX < -1.34 and posY > 0) from = 1; //peg_A if (posX > -1.3 and posX < 1.32 and posY > 0) from = 2; //peg_B if (posX > 1.32 and posX < 4 and posY > 0) from = 3; //peg_C if (win()) { //Go to next level, Put limit of 13 disk //It fit nice on pegs if (no_of_disk < 13) no_of_disk += 1; //Initialise new level init_hanoi(); //go back to normal view - stop spinning rtri = 0; } } else { lbuttonDown = false; GetOGLPos(x,y); //If drop disk on peg A if (posX > -4.0 and posX < -1.34 and posY > 0) { to = 1; //peg_A switch (from) { case 1: break; case 2: move_it(peg_B, peg_A); break; case 3: move_it(peg_C, peg_A); break; } } //If drop disk on peg B if (posX > -1.3 and posX < 1.32 and posY > 0) { to = 2; //peg_B switch (from) { case 1: move_it(peg_A, peg_B); break; case 2: break; case 3: move_it(peg_C, peg_B); break; } } //If drop disk on peg C if (posX > 1.32 and posX < 4 and posY > 0) { to = 3; //peg_C switch (from) { case 1: move_it(peg_A, peg_C); break; case 2: move_it(peg_B, peg_C); break; case 3: break; } } } } }
  • 8. Page 8 of 16 main.cpp 12/05/2011 23:06 /////////////////////////////////////////////////////////// //Mouse motion void motion(int x, int y) { //If you hold left button and move mouse //Update position of the cursor to refresh //Animation of "ghost disk" if (lbuttonDown) { GetOGLPos(x, y); } } /////////////////////////////////////////////////////////// // Defining key action void processSpecialKeys(int key, int x, int y) { switch(key) { case GLUT_KEY_F1: menu_restart = !menu_restart; tstart = time(0); break; case GLUT_KEY_F2: //Place disks on start position Before solving //Avoid infinitive loops in iterative algorithm menu_restart = true; menu_solve = !menu_solve; break; case GLUT_KEY_F3: menu_texture = !menu_texture; break; case GLUT_KEY_F4: menu_surface = !menu_surface; break; case GLUT_KEY_F5: menu_light = !menu_light; break; case GLUT_KEY_F6: menu_restart_view = !menu_restart_view; break; case GLUT_KEY_F7: menu_details = !menu_details; break; } } /////////////////////////////////////////////////////////// // Defining key action void processNormalKeys(unsigned char key, int x, int y) { //Light settings if(key == 'q') lightPos[2] -= 0.25; if(key == 'a') lightPos[2] += 0.25; if(key == 'f') lightPos[0] += 0.25; if(key == 's') lightPos[0] -= 0.25; if(key == 'e') lightPos[1] += 0.25; if(key == 'd') lightPos[1] -= 0.25; //Camera positions if (key == 'p') camera_z -= 0.25f; if (key == ';') camera_z += 0.25f; if (key == 'o') //Don't go to low //don't show whats under the board if (camera_y > 0.5) camera_y -= 0.5f; if (key == 'l') camera_y += 0.25f; if (key == 'i') camera_x -= 0.25f; if (key == 'k') camera_x += 0.25f; if(key == 27) exit(0); // Refresh the Window glutPostRedisplay(); } /////////////////////////////////////////////////////////////////////////////// // Reset flags as appropriate in response to menu selections void ProcessMenu(int value) { switch(value) { case 1: menu_restart = !menu_restart; tstart = time(0); break; case 2: //Place disks on start position Before solving //Avoid infinitive loops in iterative algorithm
  • 9. Page 9 of 16 main.cpp 12/05/2011 23:06 menu_restart = true; menu_solve = !menu_solve; break; case 3: menu_texture = !menu_texture; break; case 4: menu_surface = !menu_surface; break; case 5: menu_light = !menu_light; break; case 6: menu_restart_view = !menu_restart_view; break; case 7: menu_details = !menu_details; break; default: break; } glutPostRedisplay(); } /////////////////////////////////////////////////////////////////////////////// //process submenu - chose number of disk on board void num_disk(int value) { no_of_disk = value; //Initialise with new number init_hanoi(); tstart = time(0); glutPostRedisplay(); } /////////////////////////////////////////////////////////// // Called to clean quadric void cleanupQuadric(void) { gluDeleteQuadric(IDquadric); cout << "cleanupQuadric completed" << endl; } /////////////////////////////////////////////////////////// // Called to clean up arrays void cleanupArrays(void) { delete [] peg_A; delete [] peg_B; delete [] peg_C; peg_A = NULL; peg_B = NULL; peg_C = NULL; cout << "cleanupArray completed" << endl; } /////////////////////////////////////////////////////////// // Called to draw a mirrored surface void Surface() { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, nTexture[1]); glBegin(GL_POLYGON); glNormal3f(0.0, 1.0, 0.0); glTexCoord2f(1.0f, 1.0f); glVertex3f( 8.0f, 0.15f,-8.0f); // Top Right Of The Quad (Top) glTexCoord2f(0.0f, 1.0f); glVertex3f(-8.0f, 0.15f,-8.0f); // Top Left Of The Quad (Top) glTexCoord2f(0.0f, 0.0f); glVertex3f(-8.0f, 0.15f, 8.0f); // Bottom Left Of The Quad (Top) glTexCoord2f(1.0f, 0.0f); glVertex3f( 8.0f, 0.15f, 8.0f); // Bottom Right Of The Quad (Top) glEnd(); glDisable(GL_TEXTURE_2D); } /////////////////////////////////////////////////////////// // Called to draw disk // Depends of parameter type it draws disk with different textures void draw_disk (GLfloat radius, GLfloat x, GLfloat h, GLboolean type) { //Rough wood looking disks //Use two different textures if (type) { glPushMatrix();
  • 10. Page 10 of 16 main.cpp 12/05/2011 23:06 glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, nTexture[4]); glRotatef(90, 1.0f, 0.0, 0.0); glTranslatef(x, 0.0, -h -0.6); //Main part of the disk gluCylinder(IDquadric,radius,radius,0.30f,ROUND, ROUND); glDisable(GL_TEXTURE_2D); //Top cover of the disk glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, nTexture[3]); gluDisk(IDquadric,0.125f,radius,ROUND,ROUND); //Bottom circle of the disk - not really visible //so we don't have to draw it glDisable(GL_TEXTURE_2D); glPopMatrix(); //Use one texture for drawing } else { glPushMatrix(); glRotatef(90, 1.0f, 0.0, 0.0); glTranslatef(x, 0.0, -h -0.4); //Main part of the disk glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, nTexture[0]); gluCylinder(IDquadric,radius,radius,0.30f,ROUND, ROUND); gluDisk(IDquadric, 0.125f, radius, ROUND, ROUND); //Bottom not visible glDisable(GL_TEXTURE_2D); glPopMatrix(); } } /////////////////////////////////////////////////////////// // Called to draw peg void draw_peg(GLfloat x) { glEnable(GL_TEXTURE_2D); if (menu_texture) glBindTexture(GL_TEXTURE_2D, nTexture[5]); else glBindTexture(GL_TEXTURE_2D, nTexture[0]); glPushMatrix(); glTranslatef(x,0,0); glRotatef(270.0, 1.0f, 0.0f, 0.0f); gluCylinder(IDquadric, 0.15f, //base radius 0.1f, //top radius 4.0f, //height ROUND, //approximation ROUND //... ); glTranslatef(0,0,4); gluSphere(IDquadric,0.1f,ROUND,ROUND); glPopMatrix(); glDisable(GL_TEXTURE_2D); } /////////////////////////////////////////////////////////// // Called to draw game board void draw_board() { glEnable(GL_TEXTURE_2D); if (menu_texture) glBindTexture(GL_TEXTURE_2D, nTexture[5]); else glBindTexture(GL_TEXTURE_2D, nTexture[0]); glBegin(GL_QUADS); // Start Drawing Hanoi board glNormal3f(0.0, 1.0, 0.0); //Use to point proper sides for lighting glTexCoord2f(1.0f, 1.0f); glVertex3f( 4.0f, 0.15f,-2.0f); // Top Right Of The Quad (Top) glTexCoord2f(0.0f, 1.0f); glVertex3f(-4.0f, 0.15f,-2.0f); // Top Left Of The Quad (Top) glTexCoord2f(0.0f, 0.0f); glVertex3f(-4.0f, 0.15f, 2.0f); // Bottom Left Of The Quad (Top) glTexCoord2f(1.0f, 0.0f); glVertex3f( 4.0f, 0.15f, 2.0f); // Bottom Right Of The Quad (Top) glNormal3f(0.0, -1.0, 0.0); glTexCoord2f(1.0f, 1.0f); glVertex3f( 4.0f,-0.15f, 2.0f); // Top Right Of The Quad (Bottom) glTexCoord2f(0.0f, 1.0f); glVertex3f(-4.0f,-0.15f, 2.0f); // Top Left Of The Quad (Bottom) glTexCoord2f(0.0f, 0.0f); glVertex3f(-4.0f,-0.15f,-2.0f); // Bottom Left Of The Quad (Bottom) glTexCoord2f(1.0f, 0.0f); glVertex3f( 4.0f,-0.15f,-2.0f); // Bottom Right Of The Quad (Bottom) glNormal3f(0.0, 0.0, 1.0); glTexCoord2f(0.0f, 0.0f); glVertex3f( 4.0f, 0.15f, 2.0f); // Top Right Of The Quad (Front)
  • 11. Page 11 of 16 main.cpp 12/05/2011 23:06 glTexCoord2f(1.0f, 0.0f); glVertex3f(-4.0f, 0.15f, 2.0f); // Top Left Of The Quad (Front) glTexCoord2f(1.0f, 1.0f); glVertex3f(-4.0f,-0.15f, 2.0f); // Bottom Left Of The Quad (Front) glTexCoord2f(0.0f, 1.0f); glVertex3f( 4.0f,-0.15f, 2.0f); // Bottom Right Of The Quad (Front) glNormal3f(0.0, 0.0, -1.0); glTexCoord2f(1.0f, 0.0f); glVertex3f( 4.0f,-0.15f,-2.0f); // Bottom Left Of The Quad (Back) glTexCoord2f(1.0f, 1.0f); glVertex3f(-4.0f,-0.15f,-2.0f); // Bottom Right Of The Quad (Back) glTexCoord2f(0.0f, 1.0f); glVertex3f(-4.0f, 0.15f,-2.0f); // Top Right Of The Quad (Back) glTexCoord2f(0.0f, 0.0f); glVertex3f( 4.0f, 0.15f,-2.0f); // Top Left Of The Quad (Back) glNormal3f(-1.0, 0.0, 0.0); glTexCoord2f(0.0f, 0.0f); glVertex3f(-4.0f, 0.15f, 2.0f); // Top Right Of The Quad (Left) glTexCoord2f(1.0f, 0.0f); glVertex3f(-4.0f, 0.15f,-2.0f); // Top Left Of The Quad (Left) glTexCoord2f(1.0f, 1.0f); glVertex3f(-4.0f,-0.15f,-2.0f); // Bottom Left Of The Quad (Left) glTexCoord2f(0.0f, 1.0f); glVertex3f(-4.0f,-0.15f, 2.0f); // Bottom Right Of The Quad (Left) glNormal3f(1.0, 0.0, 0.0); glTexCoord2f(1.0f, 0.0f); glVertex3f( 4.0f, 0.15f,-2.0f); // Top Right Of The Quad (Right) glTexCoord2f(1.0f, 1.0f); glVertex3f( 4.0f, 0.15f, 2.0f); // Top Left Of The Quad (Right) glTexCoord2f(0.0f, 1.0f); glVertex3f( 4.0f,-0.15f, 2.0f); // Bottom Left Of The Quad (Right) glTexCoord2f(0.0f, 0.0f); glVertex3f( 4.0f,-0.15f,-2.0f); // Bottom Right Of The Quad (Right) glEnd(); // Done Drawing glDisable(GL_TEXTURE_2D); } /////////////////////////////////////////////////////////// //Functions draws all disks in the game radius depends of numbers //of disk in the game void draw_all_disks () { GLfloat h = 0; //hight position GLfloat r, r_max = 1.1; //declare radius var GLfloat r_step = 0.9 / no_of_disk; //calculate difference in radius between disks for (int i = 0; i < no_of_disk; i++) { //draw on peg A if (peg_A[i] != 0) { //Calculate radius of the disk r = r_max - ((peg_A[i] - 1) * r_step); draw_disk (r, -2.5, h, menu_texture); } //draw on peg B if (peg_B[i] != 0) { //Calculate radius of the disk r = r_max - ((peg_B[i] - 1) * r_step); draw_disk (r, 0.0, h, menu_texture); } //draw on peg C if (peg_C[i] != 0) { //Calculate radius of the disk r = r_max - ((peg_C[i] - 1) * r_step); draw_disk (r, 2.5, h, menu_texture); } h += 0.3; //Move it up } } /////////////////////////////////////////////////////////// //Function draw light source //on the scene void Draw_Light_Source () { glPushMatrix(); glTranslatef(lightPos[0], lightPos[1], lightPos[2]); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, nTexture[2]); glPushMatrix(); glRotatef(Rlight, 1.0, 1.0, 1.0); gluSphere(IDquadric,0.15f,ROUND,ROUND); glPopMatrix(); glDisable(GL_TEXTURE_2D); glPopMatrix(); } ////////////////////////////////////////////////////////////////////////// // To move light stripe slowly void light_move() { //Move just on y and z axis lightPos[1] = 8.5; lightPos[2] = -15.75; //Set up range of movement if (border == 1) {
  • 12. Page 12 of 16 main.cpp 12/05/2011 23:06 lightPos[0] += 0.1; if (lightPos[0] > 20.0) border = 0; } else { lightPos[0] -= 0.1; if (lightPos[0] < -20.0) border = 1; } } /////////////////////////////////////////////////////////// //Function combine all objets that have to be draw void Draw_Hanoi () { glPushMatrix(); draw_board(); //main board draw_peg(0); //first stick draw_peg(-2.5); //second stick draw_peg(2.5); //third stick draw_all_disks(); //draw disks glPopMatrix(); } /////////////////////////////////////////////////////////////////// //Function calculate camera position for intro animation purpose bool intro() { if (intro_camera_x < 3.5) intro_camera_x += 0.8; //camera_x = -48.5, if (intro_camera_y > 6) { intro_camera_y -= 0.15; return true; } else return false; } /////////////////////////////////////////////////////////////////// //Function Display the text (r,g,b colours) on "viewing plane" void DrawText(GLint x, GLint y, char* s, GLfloat r, GLfloat g, GLfloat b) { int lines; char* p; glDisable(GL_LIGHTING); //To get proper colour glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); //Change to Ortho glOrtho(0.0, glutGet(GLUT_WINDOW_WIDTH), 0.0, glutGet(GLUT_WINDOW_HEIGHT), -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(r,g,b); glRasterPos2i(x, y); for(p = s, lines = 0; *p; p++) { if (*p == 'n') { lines++; glRasterPos2i(x, y-(lines*18)); } glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p); } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glEnable(GL_LIGHTING); //Turn it back } /////////////////////////////////////////////////////////// // Called to draw scene void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glLoadIdentity(); //Re-set the view glEnable(GL_NORMALIZE); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); //If flag is set up show light source if (menu_light) Draw_Light_Source(); if (!intro())
  • 13. Page 13 of 16 main.cpp 12/05/2011 23:06 gluLookAt(camera_x, camera_y, camera_z, // look from camera XYZ 0, 0, 0, // look at the origin 0, 1, 0 // positive Y up vector ); else gluLookAt(intro_camera_x, intro_camera_y, intro_camera_z, 0, 0, 0, 0, 1, 0); glScaled(1.1, 1.1, 1.1); //Make it a bit bigger glRotatef(rtri,0.0f,1.0f,0.0f); //Rotate if Win Draw_Hanoi(); //Draw board with disks if (menu_surface) HEIGHT = 0.2; else HEIGHT = 0; glTranslatef(0.0f, -HEIGHT-0.3, 0.0f); //Place on surface glEnable(GL_STENCIL_TEST); //Enable using the stencil buffer glColorMask(0, 0, 0, 0); //Disable drawing colours to the screen glDisable(GL_DEPTH_TEST); //Disable depth testing glStencilFunc(GL_ALWAYS, 1, 1); //Make the stencil test always pass //Make pixels in the stencil buffer be set to 1 when the stencil test passes glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); //Set all of the pixels covered by the floor to be 1 in the stencil buffer //Draw mirrored plane if (menu_surface) drawFloor(); else Surface(); glColorMask(1, 1, 1, 1); //Enable drawing colours to the screen glEnable(GL_DEPTH_TEST); //Enable depth testing //Make the stencil test pass only when the pixel is 1 in the stencil buffer glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); //Make the stencil buffer not change //Draw Game board, reflected vertically, at all pixels where the stencil buffer is 1 glPushMatrix(); glScalef(1, -1, 1); glTranslatef(0, HEIGHT, 0); Draw_Hanoi(); glPopMatrix(); glDisable(GL_STENCIL_TEST); //Disable stencil buffer //Blend the floor onto the screen glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glColor4f(1, 1, 1, 0.9f); //Draw mirrored plane if (menu_surface) drawFloor(); else Surface(); glDisable(GL_BLEND); //If left button is pressed render move tracking disk if (lbuttonDown) { glPushMatrix(); glEnable (GL_BLEND); glDepthMask (GL_FALSE); glBlendFunc (GL_SRC_ALPHA, GL_ONE); //Move if you point the game board if (posX > -4 && posX < 4) { if (posZ > -2 && posZ < 2) { glTranslatef(posX, 1.0, posZ); glColor4f(1, 1, 1, 0.5f); ghost_disk(0.0, 4.0); } } glDepthMask (GL_TRUE); glDisable (GL_BLEND); glPopMatrix(); } //If you win display a message if (win()) { char tmp[50] = "You Solve it, Click to Next Level"; DrawText((glutGet(GLUT_WINDOW_WIDTH) /2) - 140, glutGet(GLUT_WINDOW_HEIGHT) /2, tmp, 1.0, 1.0, 1.0); } //If required display dame details if (menu_details) { sprintf(buffer, "Number of disks = %d", no_of_disk); DrawText(20, glutGet(GLUT_WINDOW_HEIGHT) -30, buffer, 0.56, 0.34, 0.05); sprintf(buffer, "Minimum to solve = %d", min_steps); DrawText(20, glutGet(GLUT_WINDOW_HEIGHT) -50, buffer, 0.56, 0.34, 0.05); sprintf(buffer, "Your moves: %d", no_steps); DrawText(20, glutGet(GLUT_WINDOW_HEIGHT) -70, buffer, 0.56, 0.34, 0.05);
  • 14. Page 14 of 16 main.cpp 12/05/2011 23:06 //Display time current = localtime(&tcount); sprintf(buffer, "Time: %02d:%02d:%02dn", current->tm_hour, current->tm_min, current->tm_sec); DrawText(20, glutGet(GLUT_WINDOW_HEIGHT) -90, buffer, 0.56, 0.34, 0.05); } glColor3f(1.0, 1.0, 10.0); glutSwapBuffers(); } ////////////////////////////////////////////////////////////////////////// // Change viewing volume and viewport. Called when window is resized void ChangeSize(int w, int h) { GLfloat fAspect; // Prevent a divide by zero if(h == 0) h = 1; // Set Viewport to window dimensions glViewport(0, 0, w, h); fAspect = (GLfloat)w/(GLfloat)h; // Reset coordinate system glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Produce the perspective projection gluPerspective(60.0f, fAspect, 1.0, 400.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /////////////////////////////////////////////////////////// // Called by GLUT library when idle void TimerFunction(int value) { //If you show light object it will spin Rlight +=1.2f; //If you win current level board will spin until mouse button pressed if (win()) { rtri+=1.2f; menu_solve = false; lightPos[0] = 0.42; lightPos[1] = 9.75; lightPos[2] = -22; } //If chose run light movement if (menu_surface) light_move(); //If chose solve puzzles if (menu_solve) solve_it(peg_A, peg_B, peg_C); //If restart level if (menu_restart) { init_hanoi(); menu_restart = !menu_restart; } //Restart view if (menu_restart_view) { camera_x = 4.3; camera_y = 6; camera_z = 7.25; menu_restart_view = !menu_restart_view; } if (!win()) tend = time(0); tcount = difftime(tend, tstart); //Redraw the scene with new coordinates glutPostRedisplay(); glutTimerFunc(1,TimerFunction, 1); } /////////////////////////////////////////////////////////// // Setting up texture void SetupTexture (char *name, int nT) { unsigned char *pix; GLint w,h; glBindTexture(GL_TEXTURE_2D, nT);
  • 15. Page 15 of 16 main.cpp 12/05/2011 23:06 pix = LoadBmp(name,&w,&h); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pix); free(pix); pix = NULL; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } /////////////////////////////////////////////////////////// // Setup the rendering state void SetupRC(void) { char tmp[50]; glShadeModel(GL_SMOOTH); //Enables Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Background IDquadric=gluNewQuadric(); //Create A Pointer To The Quadric Object gluQuadricNormals(IDquadric, GLU_SMOOTH); //Create Smooth Normals gluQuadricTexture(IDquadric, GL_TRUE); //Create Texture Coords no_of_disk = 3; //Game start level init_hanoi(); //Initialize data glClearDepth(1.0f); //Depth Buffer Setup glEnable(GL_DEPTH_TEST); //Enables Depth Testing glDepthFunc(GL_LEQUAL); //The Type Of Depth Test To Do // Set up lighting glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT, GL_SPECULAR, fDiffLight); glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 64); //Set up blending function glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLightfv(GL_LIGHT0, GL_AMBIENT, fAmbLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, fDiffLight); glLightfv(GL_LIGHT0, GL_SPECULAR, fSpecLight); glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); //Perspective Calculations glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Texturing glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glGenTextures(6, nTexture); //Prepare all textures for use //To avoid conversion warning use strcpy strcpy (tmp,"tex1.bmp"); SetupTexture(tmp, nTexture[0]); strcpy (tmp,"tex2.bmp"); SetupTexture(tmp, nTexture[1]); strcpy (tmp,"tex3.bmp"); SetupTexture(tmp, nTexture[2]); strcpy (tmp,"tex4.bmp"); SetupTexture(tmp, nTexture[3]); strcpy (tmp,"tex5.bmp"); SetupTexture(tmp, nTexture[4]); strcpy (tmp,"tex6.bmp"); SetupTexture(tmp, nTexture[5]); strcpy (tmp,"tex7.bmp"); SetupTexture(tmp, nTexture[6]); //Clean up at exit atexit(cleanupQuadric); atexit(cleanupArrays); } /////////////////////////////////////////////////////////// // Main program entry point int main(int argc, char* argv[]) { GLint sub; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(WindowWidth, WindowHeight); glutInitWindowPosition(0, 0); //Place window on left top corner glutCreateWindow("Tower of Hanoi - Sebastian Krezel - Courswork"); //No of disk - sub menu sub = glutCreateMenu(num_disk); glutAddMenuEntry("3", 3); glutAddMenuEntry("4", 4); glutAddMenuEntry("5", 5); glutAddMenuEntry("6", 6);
  • 16. Page 16 of 16 main.cpp 12/05/2011 23:06 glutAddMenuEntry("7", 7); glutAddMenuEntry("8", 8); glutAddMenuEntry("9", 9); glutAddMenuEntry("10", 10); glutAddMenuEntry("11", 11); glutAddMenuEntry("12", 12); glutAddMenuEntry("13", 13); //Create the Menu glutCreateMenu(ProcessMenu); glutAddMenuEntry("Restart this level" ,1); glutAddSubMenu("Pick-up no of disk" ,sub); glutAddMenuEntry("Solve it for me!" ,2); glutAddMenuEntry("Change Textures" ,3); glutAddMenuEntry("Change Surface and Light",4); glutAddMenuEntry("Show Light Opject" ,5); glutAddMenuEntry("Restart view" ,6); glutAddMenuEntry("Show details" ,7); glutAttachMenu(GLUT_RIGHT_BUTTON); SetupRC(); glutReshapeFunc(ChangeSize); glutDisplayFunc(RenderScene); //Keyboard controls glutKeyboardFunc(processNormalKeys); glutSpecialFunc(processSpecialKeys); //Mouse controls glutMouseFunc(mouse); glutMotionFunc(motion); glutTimerFunc(33, TimerFunction, 1); glutMainLoop(); return 0; }