CG Project Report
CG Project Report
VI Semester
GRAPHICS PACKAGE
TOWER OF HANOI
Submitted By
CERTIFICATE
VI semester B.E. for the partial fulfillment of the requirements for the Bachelor's degree in
External Examiner: 1. 2.
ACKNOWLEDGEMENT
I would like to express my special thanks of gratitude to my teacher Girija.J (Associate Professor)
as well as our H.O.D Dr.S.Nandagopalan who gave me the golden opportunity to do this wonderful
project on the topic Tower of Hanoi, which also helped me in doing a lot of research. I also learnt
a lot of new things about OPENGL API through the course of this project.
Secondly I would also like to thank my parents and friends who helped me a lot in finalizing
this project within the limited time frame.
DWARAKANANDAN.B.M
USN : 1BI13CS052
CONTENTS
Chapter Pg. No
1. Introduction to open GL 1
2. Design 11
3. Implementation 14
4. Results 24
5. Conclusion 27
6. Bibliography 29
Chapter-1
Introduction
Introduction
What Is OpenGL?
OpenGL is a software interface to graphics hardware. This interface consists of about 150 distinct
commands that you use to specify the objects and operations needed to produce interactive three-
dimensional applications.
A sophisticated library that provides these features could certainly be built on top of OpenGL. The
OpenGL Utility Library (GLU) provides many of the modeling features, such as quadric surfaces
and NURBS (Non-Uniform Rational B-Splines) curves and surfaces. GLU is a standard part of
every OpenGL implementation. Also, there is a higher-level, object-oriented toolkit, Open
Inventor, which is built atop OpenGL, and is available separately for many implementations of
OpenGL.
OpenGL-Related Libraries
OpenGL provides a powerful but primitive set of rendering commands, and all higher-level
drawing must be done in terms of these commands. Also, OpenGL programs have to use the
underlying mechanisms of the windowing system. A number of libraries exist to allow you to
simplify your programming tasks, including the following:
The OpenGL Utility Library (GLU) contains several routines that use lower-level OpenGL
commands to perform such tasks as setting up matrices for specific viewing orientations
and projections, performing polygon tessellation, and rendering surfaces. This library is
provided as part of every OpenGL implementation. GLU routines use the prefix glu.
For every window system, there is a library that extends the functionality of that window
system to support OpenGL rendering. For machines that use the X Window System, the
OpenGL Extension to the X Window System (GLX) is provided as an adjunct to OpenGL.
GLX routines use the prefix glX. For Microsoft Windows, the WGL routines provide the
Windows to OpenGL interface. All WGL routines use the prefix wgl. For IBM OS/2, the
PGL is the Presentation Manager to OpenGL interface, and its routines use the prefix pgl.
Open Inventor is an object-oriented toolkit based on OpenGL which provides objects and
methods for creating interactive three-dimensional graphics applications. Open Inventor,
which is written in C++, provides prebuilt objects and a built-in event model for user
interaction, high-level application components for creating and editing three-dimensional
scenes, and the ability to print objects and exchange data in other graphics formats. Open
Inventor is separate from OpenGL.
Include Files
For all OpenGL applications, you want to include the gl.h header file in every file. Almost all
OpenGL applications use GLU, the aforementioned OpenGL Utility Library, which requires
inclusion of the glu.h header file. So almost every OpenGL source file begins with
#include <GL/gl.h>
#include <GL/glu.h>
If you are directly accessing a window interface library to support OpenGL, such as GLX, AGL,
PGL, or WGL, you must include additional header files. For example, if you are calling GLX, you
may need to add these lines to your code
#include <X11/Xlib.h>
#include <GL/glx.h>
If you are using GLUT for managing your window manager tasks, you should include
#include <GL/glut.h>
Note that glut.h includes gl.h, glu.h, and glx.h automatically, so including all three files is
redundant. GLUT for Microsoft Windows includes the appropriate header file to access WGL.
As you know, OpenGL contains rendering commands but is designed to be independent of any
window system or operating system. Consequently, it contains no commands for opening windows
or reading events from the keyboard or mouse. Unfortunately, it's impossible to write a complete
graphics program without at least opening a window, and most interesting programs require a bit
of user input or other services from the operating system or window system.
In addition, since OpenGL drawing commands are limited to those that generate simple geometric
primitives (points, lines, and polygons), GLUT includes several routines that create more
complicated three-dimensional objects such as a sphere, a torus, and a teapot. This way, snapshots
of program output can be interesting to look at. (Note that the OpenGL Utility Library, GLU, also
has quadrics routines that create some of the same three-dimensional objects as GLUT, such as a
sphere, cylinder, or cone.)
No slide bars.
OpenGL is not object oriented so that there are multiple functions for a given logical
function :
glVertex3f
o glVertex2i
o glVertex3dv
Underlying storage mode is the same easy to create overloaded functions in C++ but issue
is efficiency.
OpenGL Interface
o GL (OpenGL in Windows)
Window Management
Five routines perform tasks necessary to initialize a window.
glutInit(int *argc, char **argv) initializes GLUT and processes any command line
arguments (for X, this would be options like -display and -geometry). glutInit() should be
called before any other GLUT routine.
glutInitWindowPosition(int x, int y) specifies the screen location for the upper-left corner
of your window.
glutInitWindowSize(int width, int size) specifies the size, in pixels, of your window.
glutDisplayFunc(void (*func)(void)) is the first and most important event callback function you
will see. Whenever GLUT determines the contents of the window need to be redisplayed, the
callback function registered by glutDisplayFunc() is executed. Therefore, you should put all the
routines you need to redraw the scene in the display callback function.
If your program changes the contents of the window, sometimes you will have to call
glutPostRedisplay(void), which gives glutMainLoop() a nudge to call the registered display
callback at its next opportunity.
The very last thing you must do is call glutMainLoop(void). All windows that have been created
are now shown, and rendering to those windows is now effective. Event processing begins, and
the registered display callback is triggered. Once this loop is entered, it is never exited!
Graphics Functions
Primitive functions:
points, line segments, polygons, pixels, text, curves, surfaces
Attributes functions:
color, pattern, typeface
Viewing functions:
position, orientation, clipping
Transformation functions:
rotation, translation, scaling
Input functions:
keyboards, mice, data tablets
Control functions:
communicate with windows, initialization, error handling
Inquiry functions: number of colors, camera parameters/values
Matrix Mode
There are two matrices in OpenGL:
Model-view: defines COP and orientation
Projection: defines the projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 500.0, 0.0, 500.0);
glMatrixMode(GL_MODELVIEW);
Control Functions
OpenGL assumes origin is bottom left
glutInit(int *argcp, char **argv);
glutCreateWindow(char *title);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(480,640);
glutInitWindowPosition(0,0);
OpenGL default: RGB color, no hidden-surface removal, single buffering
glPushAttrib (group);
glPopAttrib ( );
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
glFrustum (left, right, bottom, top, near, far);
gluPerspective (fov, aspect, near, far);
glOrtho (left, right, bottom, top, near, far);
Modelview Transformations
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ( );
gluLookAt (eye_x, eye_y, eye_z, at_x, at_y, at_z, up_x, up_y, up_z);
glTranslatef (dx, dy, dz);
Registering Callbacks
glutDisplayFunc (callback);
glutReshapeFunc (callback);
glutDisplayFunc (callback);
glutMotionFunc (callback);
glutPassiveMotionFunc (callback);
glutMouseFunc (callback);
glutKeyboardFunc (callback);
id = glutCreateMenu (callback);
glutMainLoop ( );
Display Lists
Managing Menus
id = glutCreateMenu (callback);
glutDestroyMenu (id);
glutAddMenuEntry (label, number);
glutAttachMenu (button);
glutDetachMenu (button);
Design
Tower of Hanoi:
The Tower of Hanoi is a mathematical game or puzzle. It consists of three rods, and a number of
disks of different sizes which can slide onto any rod. The puzzle starts with the disks in a neat
stack in ascending order of size on one rod, the smallest at the top, thus making a conical shape.
The objective of the puzzle is to move the entire stack to another rod, obeying the following
simple rules:
With three disks, the puzzle can be solved in seven moves. The minimum number of moves
required to solve a Tower of Hanoi puzzle is 2n - 1, where n is the number of disks.
Recursive Solution:
A key to solving this puzzle is to recognize that it can be solved by breaking the problem down
into a collection of smaller problems and further breaking those problems down into even
smaller problems until a solution is reached. For example:
The above is a recursive algorithm, to carry out steps 1 and 3, apply the same algorithm again
for n−1. The entire procedure is a finite number of steps, since at some point the algorithm will
be required for n = 1. This step, moving a single disc from peg A to peg C, is trivial. This
approach can be given a rigorous mathematical formalism with the theory of dynamic
programming and is often used as an example of recursion when teaching programming.
void pop(int p)
{
top[p]--;
}
void drawPegs()
{
int i;
glColor3f(0.5,0.0,0.1);
for(i=0;i<3;i++)
{
glPushMatrix();
glTranslatef(peg[i],5,0);
glRotatef(-90,1,0,0);
glutSolidCone(2,70,20,20);
glutSolidTorus(2,45, 20, 20);
glPopMatrix();
}
void drawSolved()
{
glColor3f(1,1,0);
glRasterPos3f(-60,87,0);
printString("Solved !!");
glColor3f(0.6,0.3,0.5);
glBegin(GL_POLYGON);
glVertex3f(-75,93,-5);
glVertex3f(-75,83,-5);
glVertex3f(10,83,-5);
glVertex3f(10,93,-5);
glEnd();
glColor3f(1,0,0);
glRasterPos3f(peg[0],70,0);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,'A');
glRasterPos3f(peg[1],70,0);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,'B');
glRasterPos3f(peg[2],70,0);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,'C');
}
void display()
{
int i,j,k;
if(randomColorFlag)
glClearColor((rand()%100)/100.0,(rand()%100)/100.0,(rand()%100)/100.0,
0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
if(lightflag)glEnable(GL_LIGHTING);
glPushMatrix();
gluLookAt(0,ycoordinate,0,0,0,-1,0,1,0);
drawPegs();
for(i=0;i<3;i++)
{
k=0;
for(j=0;j<=top[i];j++)
{
glPushMatrix();
glTranslatef(peg[i],pos[k++],0);
glRotatef(90,1,0,0);
glColor3f(0.1*POLES[i][j],0.2*POLES[i][j],0);
glutSolidTorus(2.0, 4*POLES[i][j], 20, 20);
glPopMatrix();
}
}
glPopMatrix();
glDisable(GL_LIGHTING);
if(counter==max_moves)
drawSolved();
else
drawText();
if(lightflag)glEnable(GL_LIGHTING);
glutSwapBuffers();
}
void animate(int n,int src,int dest)
{
int i;
if(speed<=0)speed=1;
for(i=pos[top[src]+1];i<90;i+=speed)
{
glPushMatrix();
glTranslatef(peg[src],i,0);
glRotatef(85,1,0,0);
glColor3f(0.1*n,0.2*n,0);
glutSolidTorus(2.0, 4*n, 20, 20);
glPopMatrix();
glutSwapBuffers();
display();
}
if(peg[src]<peg[dest])
for(i=peg[src];i<=peg[dest];i+=speed)
{
glPushMatrix();
glTranslatef(i,90,0);
glRotatef(85,1,0,0);
glColor3f(0.1*n,0.2*n,0);
glutSolidTorus(2.0, 4*n, 20, 20);
glPopMatrix();
glutSwapBuffers();
display();
}
else
for(i=peg[src];i>=peg[dest];i-=speed)
{
glPushMatrix();
glTranslatef(i,90,0);
glRotatef(85,1,0,0);
glColor3f(0.1*n,0.2*n,0);
glutSolidTorus(2.0, 4*n, 20, 20);
glPopMatrix();
glutSwapBuffers();
display();
}
}
animate(moves[counter][0],moves[counter][1],moves[counter][2]);
push(moves[counter][2],moves[counter][0]);
counter++;
}
}
if(btn == 3 && mode == GLUT_DOWN)
{
if(counter>0)
{
counter--;
pop(moves[counter][2]);
if(animationFlag)
animate(moves[counter][0],moves[counter][2],moves[counter][1]);
push(moves[counter][1],moves[counter][0]);
}
}
glutPostRedisplay();
}
void restart()
{
int i;
memset(POLES,0,sizeof(POLES));
memset(moves,0,sizeof(POLES));
memset(top,-1,sizeof(top));
cnt=0,counter=0;
ycoordinate=0.1;
max_moves = pow(2,NUM_DISKS)-1;
for(i=NUM_DISKS;i>0;i--)
{
push(0,i);
}
tower(NUM_DISKS,0,1,2);
}
glutKeyboardFunc(keyboard2);
glutMouseFunc(mouse);
break;
}
glutPostRedisplay();
}
Conclusion
It was a wonderful learning experience for me working on this project. This project took me
through various phases of project development and gave me real insight into the world of software
engineering. The joy of working and the thrill involved while tackling the various problems and
challenges gave me a feel of developers industry.
It was due to project that I came to know how professional software’s are designed.
I enjoyed each and every bit of work I had to put into this project.
Bibliography