You are on page 1of 47

ACKNOWLEDGEMENT

I take this opportunity to whole-heartedly express my gratitude to each and every one who
has guided and helped me to complete my project successfully and in time.

I am grateful to The Director, Prof.T.J.Ramamurthy and principal, Dr.Krishnamurthy G.N,


BNM Institute of Technology, Bangalore for giving me this opportunity to carry out a project
in this institution.

I am grateful to my institution BNM Institute of Technology for providing me a congenial


atmosphere to carry out the project successfully.

I would also like to express my heartfelt gratitude to Dr. Sahana D. Gowda, HOD, Computer
Science and Engineering whose guidance and support was truly invaluable.

I am very grateful to my guide Aiswariya K Milan, Assistant Professor, Department of


Computer Science, for her able guidance and valuable advice at every stage of my project
which helped me in the successful completion of my project.

I would also indebted to my Parents and Friends for their continued moral and material
support throughout the course of project and helping me in finalize the presentation.

My heartfelt thanks to all those have contributed bits, bytes and words to accomplish this
project.

Thanking you all,


Shreyas V Kashyap
ABSTRACT

An Amusement Park simulator is developed in OpenGL using the library functions defined
in it. The graphics software system not only draws objects like Giant Wheel, Columbus and
Roller Coaster, but also adds rotation and motion effects to them. The Entire scene is placed
in a SkyBox for a realistic sky effect. The system also features first person movement, where
the viewer can move around anywhere in the scene.
CONTENTS

CHAPTERS PAGE NUMBER


1. INTRODUCTION 1
1.1 Overview
1.2 Problem statement
1.3 Objectives
1.4 Motivation
2. LITERATURE SURVEY 2-9
2.1 Computer graphics
2.1.1 Applications of Computer Graphics
2.2 OpenGL API
2.2.1 Introduction to OpenGL
2.2.2 Features of OpenGL
2.2.3 OpenGL Libraries
2.2.4 OpenGL as State Machine
2.2.5 Graphic Pipeline Architecture
3. SYSTEM REQUIREMENTS 10-11
3.1 Hardware Requirements
3.2 Software Requirements
4. SYSTEM DESIGN 12-15
4.1 Flowchart
4.2 Algorithms
5. IMPLEMENTATION 16-38
5.1 Modules
5.1.1 OpenGL functions
5.1.2 User defined functions
5.2 Code
6. SNAPSHOTS 39-41
7. CONCLUSION AND FUTURE ENHANCEMENT 42
BIBLIOGRAPHY 43
CHAPTER - 1

INTRODUCTION

1.1 Overview

An Amusement Park simulator is developed in OpenGL using the library functions defined
in it. The graphics software system not only draws objects like Giant Wheel, Columbus and
Roller Coaster, but also adds rotation and motion effects to them. The Entire scene is placed
in a Sky-Box for a realistic sky effect. The system also features first person movement,
where the viewer can move around anywhere in the scene.

1.2 Problem statement

The project is mainly devised to display the scene of an Amusement Park. The project
problem was taken and was implemented to show 3D realistic view of the Amusement Park,
thereby giving first person view.

1.3 Objectives
The objective of the program is to show how the 3D modeling and SKY-BOX feature works
in OpenGL, and also the perspective viewing of the scene as a first person where a user can
view the scene as if he/she is roaming inside the Amusement Park.

1.4 Motivation
I got motivation through the concepts of lab programs. The subject "Computer graphics with
OpenGL" that is studied as a part of the course and the laboratory helped to know the power
of computer graphics in real life and motivated to implement the idea which we see in the
real life application. I was first amazed by how the perspective view works in OpenGL, I
was even fascinated by knowing the features like movements of 3D objects. And I always
wanted to create a scene of Disney World using all those modules. Hence, this led to
implementation of "Amusement Park" using OpenGL libraries as my project.

Department of CSE, BNMIT 2015-2016 Page |1


CHAPTER - 2

LITERATURE SURVEY

Computer graphics is the creation and manipulation of picture with the aid of
computers. It is concerned with all aspects of producing pictures or images using a computer.
Computer graphics enables us to display the information in the form of graphical objects such
as pictures, charts, graphs and diagrams instead of simple text. The pictures or graphical
objects may vary from engineering drawings, business graphs and architectural structures to
animated movies. All the functionalities required for the development and presentation of
such an environment or interface to the user is provided by the graphics package.

2.1 Computer Graphics


Computer graphics plays a major role in the design of user interfaces. There are numerous
ways in which computer graphics has made user interaction fast, effective and easy. Graphics
has enabled the designers to introduce the concept of windows that act as virtual graphics
terminals, each of which is capable of running an independent application. The introduction
of the mouse has made the selection of objects on the interface easy by the Point and Click
facility and a lot more.

2.1.1 Applications of Computer Graphics

Computer Graphics finds its applications in a variety of fields. The applications of computer
graphics can be divided into four major areas:

1. Display of information

2. Design

3. Simulation and animation

4. User interface

Department of CSE, BNMIT 2015-2016 Page |2


Amusement Park Introduction

Display of information:
Computer graphics has enabled architects, researchers and designers to pictorially
interpret the vast quantity of data. Cartographers have developed maps to display the celestial
and geographical information. Medical imaging technologies like Computerized Tomography
(CT), Magnetic Resonance Imaging (MRI), Ultrasound, Positron Emission Tomography
(PET) and many others make use of computer graphics.

Design:
Professions such as engineering and architecture are concerned with design. They start
with a set of specification; seek cost-effective solutions that satisfy the specification. Designing is
an iterative process. Designer generates a possible design, tests it and then uses the results as the
basis for exploring other solutions. The use of interactive graphical tools in Computer Aided
Design (CAD) pervades the fields including architecture, mechanical engineering, the design of
very-large-scale integrated (VLSI) circuits and creation of characters for animation.

Simulation and animation:


Once the graphics system evolved to be capable of generating sophisticated images in
real time, engineers and researchers began to use them as simulators. Graphical flight
simulators have proved to increase the safety and to reduce the training expenses. The field of
virtual reality (VR) has opened many new horizons. A human viewer can be equipped with a
display headset that allow him/her to see the images with left eye and right eye which gives
the effect of stereoscopic vision. This has further led to motion pictures and interactive video
games.

User interfaces:
Computer graphics has led to the creation of graphical user interfaces (GUI) using
which even naive users are able to interact with a computer. Interaction with the computer has
been dominated by a visual paradigm that includes windows, icons, menus and a pointing
device such as mouse. Millions of people are internet users; they access the internet through
the graphical network browsers such as Microsoft internet explorer and Mozilla Firefox

Department of CSE, BNMIT 2015-2016 Page | 3


Amusement Park Introduction

2.2 OpenGL API

OpenGL is a standard specification defining a cross-language API for writing applications that
produce 2D and 3D computer graphics. The interface consists of over 250 different function calls
which can be used to draw complex three-dimensional scenes from simple primitives.

2.2.1 Introduction to OpenGL

OpenGL (Open Graphics Library) is a hardware-independent, operating system independent,


vendor neutral graphics API specification. Many vendors provide implementations of this
specification for a variety of hardware platforms. Bindings exist primarily for the C
programming language, but bindings are also available for other popular languages. OpenGL
has been designed using a client/server paradigm, allowing the client application and the
graphics server controlling the display hardware to exist on the same or separate machines.
The network is transparent to the application.

OpenGL was developed by Silicon Graphics Inc. (SGI) in 1992 and is widely used in
CAD, virtual reality, scientific visualization, information visualization, and flight simulation.
It is also used in video games, where it competes with Direct3D on Microsoft Windows
platforms. OpenGL is managed by the non-profit technology consortium, the Khronos Group.

OpenGL's basic operation is to accept primitives such as points, lines and polygons,
and convert them into pixels. This is done by a graphics pipeline known as the OpenGL state
machine. Most OpenGL commands either issue primitives to the graphics pipeline, or
configure how the pipeline processes these primitives.

OpenGL serves two main purposes:

To hide the complexities of interfacing with different 3D accelerators, by presenting the


programmer with a single, uniform API.
To hide the differing capabilities of hardware platforms, by requiring that all
implementations support the full OpenGL feature set (using software emulation if
necessary).

Department of CSE, BNMIT 2015-2016 Page | 4


Amusement Park Introduction

2.2.2 Features of OpenGL


Some features of OpenGL include the following:

Geometric and raster primitives


RGBA or color index mode
Display list or immediate mode
Viewing and modeling transformations
Lighting and Shading
Hidden surface removal (Depth Buffer)
Texture Mapping

OpenGL is a low-level, procedural API, requiring the programmer to dictate the exact
steps required to render a scene. These contrasts with descriptive APIs, where a programmer
only needs to describe a scene and can let the library manage the details of rendering it.
OpenGL's low-level design requires programmers to have a good knowledge of the graphics
pipeline, but also gives a certain amount of freedom to implement novel rendering
algorithms. OpenGL has historically been influential on the development of 3D accelerators,
promoting a base level of functionality that is now common in consumer-level hardware.

2.2.3 OpenGL Libraries

OpenGL can be accessed directly through functions in three libraries:

1. GL library (OpenGL in windows) Main functions for windows.


2. GLU (OpenGL utility library) - Creating and viewing objects.
3. GLUT (OpenGL utility toolkit)- Functions that help in creating interface of windows

GL library contains the main functions for windows implementation. GLU library uses
only GL functions, but contains code for creating common objects and simplifying viewing.
GLUT is the OpenGL Utility Toolkit, a window system independent toolkit for writing
OpenGL programs. It implements a simple windowing application programming interface
(API) for OpenGL. GLUT makes it considerably easier to learn about and explore OpenGL
Programming.

Department of CSE, BNMIT 2015-2016 Page | 5


Amusement Park Introduction

Figure 1.1: Library Organization

The OpenGL Extension to the X Window System (GLX) provides a means of creating
an OpenGL context and associating it with an X Window System window.
To be hardware independent, OpenGL provides its own data types. They all begin
with "GL". For example GLfloat, GLint and so on. All symbolic constants begin with "GL_",
like GL_POINTS, GL_POLYGON. The commands have the prefix "gl" like glBegin().

2.2.4 OpenGL as a state machine

OpenGL is a state machine. It can be put into various states (or modes) that then remain in
effect until it is changed. As it is already seen, the current color is a state variable. The user
can set the current color to white, red, or any other color, and thereafter every object is drawn
with that color until the current set color to something else. The current color is only one of
many state variables that OpenGL maintains. Others control such things as the current
viewing and projection transformations; line and polygon stipple patterns, polygon drawing
modes, pixel-packing conventions, positions and characteristics of lights, and material
properties of the objects being drawn. Many state variables refer to modes that are enabled or
disabled with the command glEnable () or glDisable (). Each state variable or mode has a
default value, and at any point the user can query the system for each variable's current value.

For temporary state changes, the user should use these commands rather than any of
the query commands, since they're likely to be more efficient.

Department of CSE, BNMIT 2015-2016 Page | 6


Amusement Park Introduction

2.2.5 The Graphics Pipeline Architecture

OpenGL uses graphics pipeline architecture to convert high level specifications into low level
implementations. In graphics pipeline architecture, commands enter from the left and proceed
through what can be thought of as a graphics processing pipeline. Some commands specify
geometric objects to be drawn, and others control how the objects are handled during the
various processing stages. The graphics pipeline is built in stages. Every stage is specialized
in precisely one element of the rendering process. Once we are familiar with these tasks, we
will be able to recognize them in the designs of the GPU. Figure 1.2 gives an abstract, high-
level block diagram of how OpenGL processes data.

Display Lists:

All data, whether it describes geometry or pixels, can be saved in a display list for
current or later use. (The alternative to retaining data in a display list is processing the data
immediately - also known as immediate mode.) When a display list is executed, the retained
data is sent from the display list just as if it were sent by the application in immediate mode.

Figure 1.2: The Graphics Pipeline architecture

Evaluators:
The evaluator stage of processing provides an efficient means for approximating curve
and surface geometry by evaluating polynomial commands of input values. During the next

Department of CSE, BNMIT 2015-2016 Page | 7


Amusement Park Introduction

stage, per-vertex operations and primitive assembly, OpenGL processes geometric primitives
like points, line segments, and polygons, all of which are described by vertices. Vertices are
transformed and lit, and primitives are clipped to the viewport in preparation for the next
stage OpenGL performs to render an image on the screen.

Per-Vertex Operations:

For vertex data, next is the "per-vertex operations" stage, which converts the vertices
into primitives. Some vertex data are transformed by 4 x 4 floating-point matrices. Spatial
coordinates are projected from a position in the 3D world to a position on the screen. If
advanced features are enabled, this stage is even busier. If texturing is used, texture
coordinates may be generated and transformed here. If lighting is enabled, the lighting
calculations are performed using the transformed vertex, surface normal, light source
position, material properties, and other lighting information to produce a colour value.

Primitive Assembly:

Clipping, a major part of primitive assembly, is the elimination of portions of


geometry which fall outside a half-space, defined by a plane. Point clipping simply passes or
rejects vertices; line or polygon clipping can add additional vertices depending upon how the
line or polygon is clipped. Depending upon the polygon mode, a polygon may be drawn as
points or lines. The results of this stage are complete geometric primitives, which are the
transformed and clipped vertices with related colour, depth, and sometimes texture-
coordinate values and guidelines for the rasterization step.

Pixel Operations:
While geometric data takes one path through the OpenGL rendering pipeline, pixel data
takes a different route. Pixels from an array in system memory are first unpacked from one of a
variety of formats into the proper number of components. Next the data is scaled, biased, and
processed by a pixel map. The results are clamped and then either written into texture memory or
sent to the rasterization step. If pixel data is read from the frame buffer, pixel-transfer operations
are performed. Then these results are packed into an appropriate format and returned to an array
in system memory. There are special pixel copy operations to copy data in the frame buffer to
other parts of the frame buffer or to the texture memory. A single pass is made through

Department of CSE, BNMIT 2015-2016 Page | 8


Amusement Park Introduction

the pixel transfer operations before the data is written to the texture memory or back to the
frame buffer.

Texture Assembly:

An OpenGL application may wish to apply texture images onto geometric


objects to make them look more realistic. If several texture images are used, it's wise to put
them into texture objects so that it can be easily switched among them. Some OpenGL
implementations may have special resources to accelerate texture performance. There may be
specialized, high-performance texture memory. If this memory is available, the texture
objects may be prioritized to control the use of this limited and valuable resource.

Rasterization:

Rasterization is the conversion of both geometric and pixel data into fragments. Each
fragment square corresponds to a pixel in the frame buffer. Line and polygon stipples, line
width, point size, shading model, and coverage calculations to support ant aliasing are taken
into consideration as vertices are connected into lines or the interior pixels are calculated for
a filled polygon. Colour and depth values are assigned for each fragment square.

Fragment Operations:

Before values are actually stored into the frame buffer, a series of operations are
performed that may alter or even throw out fragments. All these operations can be enabled or
disabled. The first operation which may be encountered is texturing, where a Texel is generated
from texture memory for each fragment and applied to the fragment. Then fog calculations may
be applied, followed by the scissor test, the alpha test, the stencil test, and the depth-buffer test.
Failing an enabled test may end the continued processing of a fragment's square. Then, blending,
dithering, logical operation, and masking by a bitmask may be performed. Finally, the thoroughly
processed fragment is drawn into the appropriate buffer.

Department of CSE, BNMIT 2015-2016 Page | 9


CHAPTER - 3

SYSTEM REQUIREMENTS

To be used efficiently, all computer software needs certain hardware components or other
software components to be present on a computer. These prerequisites are known as software
requirements. Though our graphics software does not demand strict specifications, certain
basic hardware and software requirements must be met.

3.1 Hardware Requirements

Table 3.1 specifies the minimum hardware requirements that must be met in order to run the
graphics software.

Processor Intel Pentium IV

System Memory 1 GB

Graphics Memory 64 MB

Secondary Memory 20 GB

Processor Speed 1.7 GHz

Keyboard Standard alphanumeric keyboard

Mouse Standard mouse

Display Resolution 1366 x 768

Table 3.1: Hardware requirements

Department of CSE, BNMIT 2015-2016 P a g e | 10


Amusement Park System Requirements

3.2 Software requirements

Since GLUT is a cross platform library, the graphics software can be run on any platform that
GLUT supports. In our implementation, we have used a windows distribution of GLUT and
hence we expect the target machine to have windows distribution of GLUT library installed.
Table 3.2 outlines the minimum software requirements.

Operating System Windows XP

IDE Visual Studio 6.0

OpenGL Library GLUT for Windows

Graphic driver Compatible with Graphics hardware

Table 3.2: Software requirements

Department of CSE, BNMIT 2015-2016 P a g e | 11


CHAPTER - 4

SYSTEM DESIGN

4.1 Flowchart

A flowchart is a common type of chart that represents an algorithm or process showing the steps as
boxes of various kinds, and their order by connecting these with arrows. Flowcharts are used in
analyzing, designing, documenting or managing a process or program in various fields. Figure 3.1
shows the interactions between various components of the graphics software system as a flowchart.

Idle Start Mouse/Keyboard Input

Change colour
Main
Start/Stop movement
Flag set?
Navigation
Display
Yes
Change camera
Update Angle position
or Rotation and Draw Skybox
Roller Coaster
progress
Update state variables and
Draw Giant
movement flags
Wheel,
Columbus and
Roller Coaster

Quit

Stop

Figure 4.1: Flowchart showing organization of components

Department of CSE, BNMIT 2015-2016 P a g e | 12


Amusement Park Design

4.2 Algorithm

The design process of each component can be explained using algorithms. An algorithm is a
step-by-step finite list of well-defined instructions. Algorithms provide only high level
descriptions, but sometimes they can also provide implementation level details. The following
sections describe algorithms for each component created in this graphics software system.

4.2.1 Algorithm to draw a spinning Giant Wheel


1. Initialize rotation_angle = 0.
2. Create two circular rings using solid torus.
3. Draw a trolley on the edge (rim) of torus. Trolley is drawn using wired cube. To draw
multiple trolleys, rotate the original trolley with respect to the center of the torus multiple
times and draw it at every point. Also spin the trolleys in opposite direction about their
center so that they always remain upright.
4. The stand for the Giant Wheel is drawn using cylinders.
5. To rotate the giant wheel, rotate the torus about its center with an angle equal to
rotation_angle and also spin each trolley about its center with an angle equal to the
rotation_angle to make them appear always upright.
6. Increment the rotation_angle and go to step 2.

Rotate trolley about


center of the torus

Spin trolley
about its center

Figure 3.3: Second trolley made upright by


Figure 3.2: Second trolley formed by spinning about its center.
rotating original trolley.

Department of CSE, BNMIT 2015-2016 P a g e | 13


Amusement Park Design

4.2.2 Algorithm to draw a swinging Columbus Ship

1. Initialize theta=0.
2. Scale the z axis about thrice its original scale and draw a sphere. Use a clipping plane to
cut it horizontally exactly about its center to form the Columbus ship body.
3. Stand of Columbus is visualized using cylinders.
4. Rotate the Columbus ship body about the center of the stand with an offset_angle where
the offset_angle is the product of a fixed offset and sine of the angle theta, where theta
varies from 0 to 360 degrees continuously.
5. Since sine of theta varies from +1 to -1, rotation angle of Columbus ship varies from
+offset_angle to -offset_angle. This gives a swinging effect to the Columbus ship body.
6. Increase the value of theta and go to step 2.

4.2.3 Algorithm to draw moving Roller Coaster


1. Initialize Roller coaster progress variable to 0.
2. Scale the z axis twice its original scale and draw a cube to make it look like a cuboid. Cut
the cuboid horizontally at the center to make the roller coaster body.
3. Place the roller coaster on the initial curve point.
4. Calculate the next roller coaster track point using Bezier curve function.
5. Place the roller coaster on the newly calculated point.
6. Calculate the angle made by the curve with the tangent, normal and bi-normal at new
curve point and rotate the roller coaster with respect to x, y and z axes about the
calculated angles to properly orient the roller coaster along the track.
7. Increment roller coaster progress variable. If the track is not complete, go to step 2. If
track is complete, stop.
Normal
Binormal
Tangent

Figure 3.4: Tangent, Normal and Binormal of a


curve at a point p.

Department of CSE, BNMIT 2015-2016 P a g e | 14


Amusement Park Design

4.2.4 Algorithm to draw a SkyBox environment

1. Create a cube. Use the six skybox images to texture map them on the six faces from the
inner side of the cube.
2. If the viewer moves horizontally or vertically in the scene, translate the center of the
skybox along with him so that he does not goes beyond the face of the skybox after
moving continuously.
3. If viewer rotates, rotate the skybox in opposite direction to give appropriate effect.
4. The ground is created using textured squares repeated like tiles of a floor.

Figure 3.5: Viewer along with the scene placed


inside the Skybox

Department of CSE, BNMIT 2015-2016 P a g e | 15


CHAPTER - 5
IMPLEMENTATION

Implementation is a stage where the planned activities are put into action. It is the realization
of a technical specification or an algorithm as a program or software component.

5.1 Modules
The module implementation of the graphics software system can be described in two stages:

1. OpenGL library functions description


2. User defined functions description

5.1.1 OpenGL functions

Initializes GLUT. The arguments from main are passed in


glutInit()
and can be used by the application.

Requests a display with the properties in mode. The value of


mode is determined by the logical OR of options including
glutInitDisplayMode()
the colour model (GLUT_RGB, GLUT_INDEX) and
buffering (GLUT_SINGLE, GLUT_DOUBLE).

glutInitWindowSize() Specifies the initial height and width of the window in pixels.

Creates a window on the display. The string can be used to


label the window. The return value provides a reference to
glutCreateWindow()
the window that can be used when there are multiple
windows.

Registers the display function that is executed when the


glutDisplayFunc()
window needs to be redrawn.

Registers the display callback function that is executed


glutIdleFunc()
whenever there are no other events to be handled.

Department of CSE, BNMIT 2015-2016 P a g e | 16


Amusement Park Implementation
Registers the mouse callback function. The callback function
returns The button (GLUT_LEFT_BUTTON,
GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON),
glutMouseFunc()
the state of the button after the event (GLUT_UP,
GLUT_DOWN), and the position of the mouse relative to the
top-left corner of the window.

Cause the program to enter an event-processing loop. It


glutMainLoop()
should be the last statement in main.

Sets the present RGBA clear colour used when clearing the
glClearColor()
colour buffer.

Sets the reshape callback for the current window. The reshape
callback is triggered when a window is reshaped. A reshape
glutReshapeFunc() callback is also triggered immediately before a window's first
display callback after a window is created or whenever an
overlay for the window is established.

Sets the keyboard callback for the current window. When a


user types into the window, each key press generating an

glutKeyboardFunc() ASCII character will generate a keyboard callback. The x and


y callback parameters indicate the mouse location in window
relative coordinates when the key was pressed.

Creates a new pop-up menu and returns a unique small


glutCreateMenu()
integer identifier.

glLoadIdentity() Sets the current transformation matrix to an identity matrix

Registers the display callback function that is executed


glutIdleFunc()
whenever there are no other events to be handled.

gluPerspective() Sets up a perspective projection matrix


Department of CSE, BNMIT 2015-2016 P a g e | 17
Amusement Park Implementation

It attaches a mouse button for the current window to the


identifier of the current menu. By attaching a menu identifier
to a button, the named menu will be popped up when the user
glutAttachMenu() presses the specified button. Button should be one of
GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, and
GLUT_RIGHT_BUTTON. Note that the menu is attached to
the button by identifier, not by reference.

Specifies which matrix will be affected by subsequent


glMatrixMode() transformations. Mode can be GL_MODELVIEW,
GL_PROJECTION or GL_TEXTURE.

Sets the parameter for face (GL_FRONT, GL_BACK or


glMaterialfv()
GL_FRONT_AND_BACK).

glLightfv() Sets scalar and vector parameters for light source.

Enables an OpenGL feature. Features that can be enabled


include GL_DEPTH_TEST, GL_,
glEnable()
GL_POLYGON_STIPPLE, GL_FOG and
GL_NORMALIZE.

Post multiplies the current matrix by a matrix determined by


gluLookAt() a viewer at the eye point looking at the point with the
specified up direction.

Sets the present RGB colours. The maximum and minimum


glColor()
values of the floating point types are 1.0 and 0.0 respectively

glRasterPosition() Specifies a raster position.

Renders the character with ASCII code char at the current


raster position using the raster font given by font. Fonts
glutBitmapCharacter()
include GLUT_BITMAP_TIMES_ROMAN_10. The raster
position is incremented by the width of the character
Department of CSE, BNMIT 2015-2016 P a g e | 18
Amusement Park Implementation

glutSwapBuffers() Swaps the front and back buffers.

glFlush() Forces any buffered OpenGL commands to execute

Requests that the display callback be executed after the


glutPostRedisplay() current callback returns.

Alters the current matrix by a displacement specified along x


glTranslatef() y and z directions.

gluCylinder() Draw a cylinder with height in z direction.

Define a sphere using slices lines of longitude and stacks


glutSolidSphere()
lines of latitude.

glutSolidTorus() Draw a solid torus (circular ring).

5.1.2 User defined functions

1. void set_material(int): Sets the material for a particular object.


2. int LoadBMP(char*): Loads a bitmap texture and returns the index of loaded texture.
3. void initSky(): Initializes SkyBox variables and textures.
4. void initLights(): Initializes the light intensity and position configuration.
5. void Draw_Skybox(float x, float y, float z, float width, float height, float
length): Draws a skybox at a specified point of required dimensions
6. void draw_ground(): Draws ground by repeating textured tiles.
7. void draw_gwheel(): Draws the giant wheel.
8. void draw_columbus(): Draws the Columbus ship.
9. void draw_wagon(): Draws the wagon for giant wheel.
10. void idle(): Updates state variables like rotation angle and Roller Coaster progress.
11. void draw_seat(): Draws seat at a required position.

Department of CSE, BNMIT 2015-2016 P a g e | 19


Amusement Park Implementation

12. void draw_wheels(): Draws wheels for Roller Coaster.


13. void draw_loco(): Draws the Roller Coaster locomotive.
14. void getCurveAt(double *x, double *y, double *z, int index, double
progress): Gets the next curve point calculated from the current progress.
15. void drawText(char* str, float x, float y, float z): Displays text on
the screen.
16. void display(): Display function draws all objects.
17. void displayReshape(int h, int w): Reshape callback function to maintain aspect
ratio.
18. double bezier(double a, double b, double c, double d, double t):
Applies Bezier function and returns the curve point.
19. void moveToBezier(double progress):Moves the camera to a specified point on
curve
20. void draw_cyl(float x1, float y1, float z1, float x2, float y2, float z2, int
radius, int subdiv): Draws a cylinder between two given points with proper
orientation.
21. void draw_bezier(): Draws the roller coaster track
22. void windowSpecial(int key, int x, int y): Handles navigational keys movement
23. void kb(unsigned char key, int x, int y): Keyboard callback function to respond
to user inputs
24. void handleMouse(int x, int y): Handles mouse drag to rotate the view
25. void passiveMouse(int x, int y): Keeps track of mouse position
26. void place_camera(int action): Places camera at a specified position
27. void addMenu(): Adds submenu, defines callback handlers and attaches it to right-
click of mouse.
28. void main(int argc, char* argv[]): Creates a window of given size at a given
position, registers the call back functions and runs an event driven loop.

Department of CSE, BNMIT 2015-2016 P a g e | 20


Amusement Park Implementation

5.2 Code

#include<stdlib.h>
#include<GL/glut.h>
#include<GL/gl.h>
#include<stdio.h>
#include<math.h>
#include<windows.h>
const int SKY_FRONT=0, SKY_RIGHT=1, SKY_LEFT=2, SKY_BACK=3, SKY_UP=4,
SKY_DOWN=5, COLUMBUS=1, COLUMBUS_STAND=2, GWHEEL_RING=3,
GWHEEL_TROLLEY=4, GWHEEL_TOP=5, ROLLER_BODY=6, ROLLER_FRAME=7;

int ni=0,prevx=0, rcam=1,bezno,camw=0, roll=0, background=0,


cswing=0, gw=0,columbus_color=0, columbus_stand_color=0,
gwheel_ring_color=0, gwheel_trolley_color=0, roller_body_color=0;

GLint skybox[6], grass,help=0,x_r=0, y_r=0, z_r=0;

GLfloat viewer[3] = {1.0f, 0.0f, 0.0f},camera[3] = {0.0f, 0.0, 0.0};

GLdouble curr=0, prev=0,gw_spin = 0.0,angle=0.0,c_angle=90.0,gw_width = 8.0,


gw_radius=45.0,gw_x=-180.0, gw_y=50.0, gw_z=220.0,co_x=180.0, co_y=0.0,
co_z=80.0,lx=50.0,ly=50.0,lz=50.0,bez_prog=0.0,roller_speed=0.0150,gy=0,movcord[3]
={-150,-10,200};

double bez[][3]={{30,10,-200},{30,10,-110}, {30,10,10}, {30,10,50},


{30,70,100}, {60,90,140}, {80,80,100}, {70,80,70}, {0,50,80}};

void set_material(int m)

{if(m==0)
{

float materialGrey[]={0.8,0.8,0.8},materialWhite[]={0.2,0.2,0.2};
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,materialGrey);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,materialWhite);

if(m==COLUMBUS)

{ float materialColours[][3]={{1,0.6,0.3}, {0.2,0.2,0.2}, {0.6,0.6,0.6},


{0.75,0.164,0.164},{0.601,0.19,1.0}, {1,1,0}},
materialLightBr[]={0.2,0.2,0.0};

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFU
SE, materialColours[columbus_color]);

glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,materialLightBr);

Department of CSE, BNMIT 2015-2016 P a g e | 21


Amusement Park Implementation

GLuint LoadBMP(const char *fileName)

{
FILE *file;
unsigned char header[54],*data;
unsigned int dataPos,size,width, height; file
= fopen(fileName, "rb"); fread(header, 1,
54, file);
dataPos = *(int*)&(header[0x0A]);
size = *(int*)&(header[0x22]); width
= *(int*)&(header[0x12]); height =
*(int*)&(header[0x16]); if (size ==
NULL)
size = width * height * 3; if
(dataPos == NULL)
dataPos = 54;
data = new unsigned char[size];
fread(data, 1, size, file);
fclose(file);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR_EXT, GL_UNSIGNED_BYTE, data);
return texture;
}
void initSky()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
skybox[SKY_DOWN] = LoadBMP("BMP11/down.bmp");
skybox[SKY_FRONT] = LoadBMP("BMP11/front.bmp");
skybox[SKY_BACK] = LoadBMP("BMP11/back.bmp");
skybox[SKY_RIGHT] = LoadBMP("BMP11/right.bmp");
skybox[SKY_LEFT] = LoadBMP("BMP11/left.bmp");
skybox[SKY_UP] = LoadBMP("BMP11/up.bmp");
grass=LoadBMP("BMP11/grass_1.bmp");
}

Department of CSE, BNMIT 2015-2016 P a g e | 22


Amusement Park Implementation

void initLights()
{
GLfloat whiteSpecularMaterial[] =
{1.0,1.0,1.0},light_post0[]={0.0,0.0,10.0,1.0},whiteSpecularLight[] = {1.0, 1.0,
1.0},blackAmbientLight[] = {0.3, 0.3, 0.3},whiteDiffuseLight[] = {1.0, 1.0,
1.0},mShininess[] = {50},twoModel[]={GL_TRUE};
glEnable
(GL_DEPTH_TEST);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_SPECULAR, whiteSpecularLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, blackAmbientLight); glLightfv(GL_LIGHT0,
GL_DIFFUSE, whiteDiffuseLight); glLightfv(GL_LIGHT0, GL_POSITION,
light_post0); glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, twoModel);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, whiteSpecularMaterial);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mShininess);
}

void Draw_Skybox(float x, float y, float z, float width, float height, float length){
glMatrixMode(GL_PROJECTION
); glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
x = x - width / 2; y =
y - height / 2; z = z -
length / 2;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,skybox[SKY_UP])
; glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x+width, y+height, z);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x+width, y+height, z+length);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y+height, z+length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y+height, z);
glEnd();
glBindTexture(GL_TEXTURE_2D,skybox[SKY_FRONT]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x+width, y, z);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x+width, y, z+length);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x+width, y+height, z+length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x+width, y+height, z);
glEnd();
glBindTexture(GL_TEXTURE_2D,skybox[SKY_BACK]);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y+height, z);

Department of CSE, BNMIT 2015-2016 P a g e | 23


Amusement Park Implementation
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y+height, z+length);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z+length);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z);
glEnd();
glBindTexture(GL_TEXTURE_2D,skybox[SKY_RIGHT])
;
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x+width, y, z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x+width, y+height, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y+height, z);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z);
glEnd();
glBindTexture(GL_TEXTURE_2D,skybox[SKY_LEFT]);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z+length);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y+height, z+length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x+width, y+height, z+length);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x+width, y, z+length);
glEnd();
glBindTexture(GL_TEXTURE_2D,skybox[SKY_DOWN]
);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x+width, y, z+length);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x+width, y, z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y, z+length);
glEnd();
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIE
W);
}

void draw_ground()
{ glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,grass);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(5000,-10,5000);
glTexCoord2f(800.0f, 0.0f); glVertex3f(5000,-10,-5000);
glTexCoord2f(800.0f, 800.0f); glVertex3f(-5000,-10,-5000);
glTexCoord2f(0.0f, 800.0f); glVertex3f(-5000,-10,5000); glEnd();
glDisable(GL_TEXTURE_2D);
glLineWidth(5.0);
glTranslatef(0.0, -2, 0.0);
draw_bezier();
glTranslatef(0.0, 2, 0.0);
}

Department of CSE, BNMIT 2015-2016 P a g e | 24


Amusement Park Implementation
void draw_gwheel()
{
int num=12;
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricNormals(quadric, GLU_SMOOTH);
glPushMatrix();
initLightsforGW();
GLfloat twoModel[]={GL_FALSE};
glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, twoModel);
set_material(GWHEEL_RING);
glTranslatef(0.0,0.0, gw_width);
glRotatef(-gw_spin,0,0,1);
draw_cyl(0,0,0,0,-55,20,1.5,8);
glTranslatef(0.0,0.0, -gw_width*2);
draw_cyl(0,0,0,0,-55,-20,1.5,8);
glTranslatef(0.0,0.0, gw_width*2);
glRotatef(gw_spin,0,0,1);
glutSolidTorus(1.0, 35.0, 16, 64);
gluDisk(quadric,0.0, 10.0, 10.0, 1);
glTranslatef(0.0,0.0, -gw_width*2);
glutSolidTorus(1.0, 35.0, 16, 64);
gluDisk(quadric,0.0, 10.0, 10.0, 1);
glTranslatef(0.0,0.0, gw_width);
for(int i=0; i<num; i++)
{ glEnable(GL_LIGHTING); glPushMatrix();
glRotatef(360*i/num, 0.0, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glTranslatef(0.0,0.0, gw_width);

draw_cyl(0.0, 45.0, 0.0, 0.0, 45.0, -5.0, 1.0, 12);


draw_cyl(0.0, 45.0, 0.0, 0.0, 2.0, 0.0, 1.0, 12);
glTranslatef(0.0,0.0, -gw_width*2);
draw_cyl(0.0, 45.0, 0.0, 0.0, 2.0, 0.0, 1.0, 12);
draw_cyl(0.0, 45.0, 0.0, 0.0, 45.0, 5.0, 1.0, 12);
glTranslatef(0.0,0.0, gw_width);
glDisable(GL_LIGHTING);
glTranslatef(0.0, -45.0, 0.0); glRotatef(-gw_spin-(360*i/num)-
sin(gw_spin/10)*10, 0, 0, 1.0); set_material(GWHEEL_TROLLEY);
draw_wagon();
set_material(GWHEEL_RING
);
glTranslatef(0.0, 45.0, 0.0);
glPopMatrix();
}
set_material(0);
twoModel[0]=GL_TRU
E;
glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE,
twoModel); glPopMatrix();
glDisable(GL_LIGHT1);
}

Department of CSE, BNMIT 2015-2016 P a g e | 25


Amusement Park Implementation

void draw_columbus()
{
double eqn[]={0.0, -1.0, 0.0, 0.5};
glPushMatrix();
glEnable(GL_LIGHTING);
GLfloat twoModel[]={GL_FALSE};
glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE,
twoModel); set_material(COLUMBUS_STAND);
draw_cyl(0.0, 105.0,30.0,0.0,105.0,-30.0 ,1.0,10);
draw_cyl(0.0, 105.0,30.0,30.0,-10.0,30.0 ,1.0,10);
draw_cyl(0.0, 105.0,30.0,-30.0,-10.0,30.0 ,1.0,10);
draw_cyl(0.0, 105.0,-30.0,30.0,-10.0,-30.0 ,1.0,10);
draw_cyl(0.0, 105.0,-30.0,-30.0,-10.0,-30.0 ,1.0,10);
glTranslatef(0.0, 105.0, 0.0);
glRotatef(cos(c_angle*3.14/180.0)*50.0, 0.0, 0.0, 1.0);
draw_cyl(0.0, -70.0,-15.0,0.0,-2.0,-1.0 ,0.3,10);
draw_cyl(0.0, -70.0,15.0,0.0,-2.0,1.0 ,0.3,10);
glutSolidTorus(1.0, 3.0, 5, 8);
twoModel[0]=GL_TRUE;
glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE,
twoModel); glTranslatef(0.0, -70.0, 0.0);
glEnable(GL_DEPTH_TEST);
glClipPlane(GL_CLIP_PLANE0, eqn);
glEnable(GL_CLIP_PLANE0);
glScalef(3.0,1.0, 1.0);
set_material(COLUMBUS);
glutSolidSphere(15.0, 64.0, 64.0);
set_material(0);
glScalef( 1/3.0,1.0, 1.0);
glDisable(GL_CLIP_PLANE0);
glRotatef(-90.0, 1.0, 0.0, 0.0);
glScalef(3.0, 5.0, 3.0);
glTranslatef(11.5,0.0,0.0); for(int
c=0;c<6;c++)
{
glTranslatef(-3.2, 0.0, 0.0);
draw_seat();
}
glPopMatrix();

Department of CSE, BNMIT 2015-2016 P a g e | 26


Amusement Park Implementation

void draw_wagon()
{
GLdouble wagon_size=5.0;
double eqn[]={0.0, -1.0, 0.0, -3.5};
glPushMatrix();
glTranslatef(0.0, -5.0, 0.0);
glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE0, eqn);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glDisable(GL_CLIP_PLANE0); for(int
c=0;c<4;c++)
{
glRotatef((90/4.0), 0.0, 1.0, 0.0);
glNormal3f(1.0,0.0,0.0);
glutWireCube(wagon_size*2.0);
}
glPopMatrix();
}

void idle()
{
double bez_offset=0.000;
if(cswing)
{ c_angle++;
if(camw==
2)
{ movcord[0]=-co_x-cos(c_angle*3.14/180.0)*50.0;
movcord[1]=-co_y-35-fabs(cos(c_angle*3.14/180.0))*35;
movcord[2]=co_z;
}
}

if(roll)
{ if(ni==bezno-2)
{ roll=0;
bez_prog=0.0;
ni=0.0;
viewer[0]=1.0;
viewer[1]=viewer[2]=camera[0]=camera[1]=camera[2]=x_r=
0.0; return;
}
if(bez_prog>=1.0)
{ni++;

Department of CSE, BNMIT 2015-2016 P a g e | 27


Amusement Park Implementation

bez_prog=0.0;
}
bez_prog+=roller_speed;
moveToBezier(bez_prog+bez_offset);
}

if(gw)
{ gw_spin+=0.25;
if(camw==1)
{
movcord[0]=-gw_x+(gw_radius*sin(gw_spin*3.14/180))+ sin(gw_spin/10);
movcord[2]=gw_z; movcord[1]=-gw_y-
(gw_radius*cos(gw_spin*3.14/180.0))+6;
}
}
glutPostRedisplay();
}

void draw_seat()
{ glPushMatrix();
glEnable(GL_LIGHTING);
glTranslatef(1.0, 0.0, -1.0);
glRotatef(90.0, 0.0, 0.0, 1.0);
glTranslatef(0.0, 0.5, 0.0);
draw_cyl(-2.5,0.0,0.0,2.5,0.0,0.0,0.05,6);
glTranslatef(0.0,-0.5,0.0);
glNormal3f(0.0,1.0,0.0);
glScalef(4.0, 0.1, 1.0);
glutSolidCube(1.0);
glScalef(1/4.0, 1/0.1, 1.0);
glTranslatef(0.0, 0.5, -1.0);
glRotatef(80.0, 1.0, 0.0, 0.0);
glScalef(4.0, 0.1, 1.0);
glNormal3f(0.0,1.0,0.0);
glutSolidCube(1.0);
glScalef(1/4.0, 1/0.1, 1.0);
glPopMatrix();
}

void draw_wheels()
{
int i=0;
glPushMatrix();
glRotatef(90.0,1.0,0.0,0.0);

Department of CSE, BNMIT 2015-2016 P a g e | 28


Amusement Park Implementation

for(i=0;i<4;i++)
{ glutSolidTorus(0.2,0.3,4,16);
glTranslatef(0.0,2.0,0.0);
}
glPopMatrix();

void draw_loco()
{
int i;
double eqn[]={1.0, 0.0, 0.0, -0.5};
double eqnt[]={-1.0, 0.0, 0.0, 1.6};
glPushMatrix();
set_material(ROLLER_BODY);
glEnable (GL_LIGHTING);
glEnable(GL_CLIP_PLANE0);
glClipPlane(GL_CLIP_PLANE0, eqn);
glScalef(1.3, 2.0, 1.5);
glutSolidCube(3.0); glScalef(1/1.3,
1/2.0, 1/1.5);
glDisable(GL_CLIP_PLANE0);
glRotatef(90.0, 1.0, 0.0, 0.0);
glEnable(GL_CLIP_PLANE1);
glClipPlane(GL_CLIP_PLANE1, eqnt);
glTranslatef(0.0, 0.0, 3.0);
glutSolidTorus(0.2, 3.0, 10, 10);
draw_seat();
glTranslatef(0.0, 0.0, -1.5);
glutSolidTorus(0.2, 3.0, 10, 10);
glTranslatef(0.0, 0.0, -1.5);
glutSolidTorus(0.2, 3.0, 10, 10);
draw_seat();
glTranslatef(0.0, 0.0, -1.5);
glutSolidTorus(0.2, 3.0, 10, 10);
glTranslatef(0.0, 0.0, -1.5);
glutSolidTorus(0.2, 3.0, 10, 10);
glDisable(GL_CLIP_PLANE1);
set_material(0);
glTranslatef(2.5,1.0,0);
draw_wheels(); glTranslatef(-2.5,-
1.0,0); glTranslatef(2.5,-1.0,0);
draw_wheels();

Department of CSE, BNMIT 2015-2016 P a g e | 29


Amusement Park Implementation

for(i=0;i<4;i++)
{
draw_cyl(0,2.1,0,0,-0.1,0,0.1,12);
glTranslatef(0.0,0.0,2.0);
}
glPopMatrix();
}

void getCurveAt(GLdouble *ax,GLdouble *ay,GLdouble *az,int index,GLdouble atpoint)


{
if(ax) *ax=-bezier(bez[0+index][0],bez[1+index][0],bez[2+index]
[0],bez[3+index][0],atpoint);
if(ay) *ay=-bezier(bez[0+index][1],bez[1+index][1],bez[2+index]
[1],bez[3+index][1],atpoint);
if(az) *az=-bezier(bez[0+index][2],bez[1+index][2],bez[2+index]
[2],bez[3+index][2],atpoint);
}

void display()
{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1.0,1.0,1.0,1.0);
glLoadIdentity();
gluLookAt(viewer[0], viewer[1], viewer[2],camera[0], camera[1],
camera[2],0, 1, 0);

getCurveAt(&tx,&ty,&tz,ni,bez_prog+0.058);
getCurveAt(&nx,&ny,&nz,ni,bez_prog+0.070);
gy=ny;
float bz1=bezier(bez[0+ni][2],bez[1+ni][2],bez[2+ni][2],bez[3+ni]
[2],bez_prog+0.02)-1*fabs(cos(angle*3.14/180.0));
float bx1=bezier(bez[0+ni][0],bez[1+ni][0],bez[2+ni][0],bez[3+ni]
[0],bez_prog+0.02)-1*fabs(sin(angle*3.14/180.0));
float bz2=bezier(bez[0+ni][2],bez[1+ni][2],bez[2+ni][2],bez[3+ni]
[2],bez_prog+0.02)+1*fa bs(cos(angle*3.14/180.0));
float bx2=bezier(bez[0+ni][0],bez[1+ni][0],bez[2+ni][0],bez[3+ni]
[0],bez_prog+0.02)+1*fa bs(sin(angle*3.14/180.0));
double degreer = atan2(1,bx2-bx1)*fabs(sin(angle*3.14/180.0))* 180 /
3.14+fabs(cos(angle*3.14/180.0))*atan2(1,bz2-bz1)* 180 / 3.14;
double angler = degreer ;
double degree= atan2(nz-tz, nx-tx);
angle = degree * 180 / 3.14;
double degreey= atan2(ny-ty,1);
double angley = degreey * 180 / 3.14;

Department of CSE, BNMIT 2015-2016 P a g e | 30


Amusement Park Implementation

glPushMatrix(); glTranslatef(-nx,-ny,-
nz); glRotatef(-angle, 0.0, 1.0, 0.0);
glRotatef(angley-90, 0, 0, 1.0);
glRotatef(angler-45, 0.0, 1.0, 0.0);
if(camw==0) angle=90.0;
glTranslatef(-2.5, 3.0, 0.0); draw_loco();

glPopMatrix();
glPushMatrix(); glTranslatef(co_x,
co_y, -co_z); draw_columbus();
glPopMatrix();
glPushMatrix(); glTranslatef(gw_x,
gw_y, -gw_z); glRotatef(gw_spin, 0.0,
0.0, 1.0); draw_gwheel();
glPopMatrix();
glutSwapBuffers();
}
void displayReshape(int width,int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION
); glLoadIdentity();
gluPerspective(65,(GLfloat)width/(GLfloat)height,0.01f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

double bezier(double x0, double x1, double x2, double x3, double t)
{
return 0.5f*((2.0f*x1)+(-x0+x2)*t+(2.0f*x0-5.0f*x1+4*x2-x3)*t*t+(-
x0+3.0f*x1-3.0f*x2+x3)*t*t*t);
}
void moveToBezier( double t)
{ int n=0.0; viewer[0]=1.0;
viewer[1]= viewer[2]=0.0;
if(camw==3)

{ getCurveAt(&movcord[0],&movcord[1], &movcord[2], ni, t);


movcord[0]+=1.0;
movcord[1]-=3.5;

Department of CSE, BNMIT 2015-2016 P a g e | 31


Amusement Park Implementation

camera[0]=bezier(bez[0+ni][0],bez[1+ni][0],bez[2+ni][0],bez[3+ni][0],t+0.1)
-bezier(bez[0+ni][0],bez[1+ni][0],bez[2+ni][0],bez[3+ni][0],t);

camera[1]=bezier(bez[0+ni][1],bez[1+ni][1],bez[2+ni][1],bez[3+ni][1],t+0.1)-
bezier(bez[0+ni][1],bez[1+ni][1],bez[2+ni][1],bez[3+ni][1],t);

camera[2]=bezier(bez[0+ni][2],bez[1+ni][2],bez[2+ni][2],bez[3+ni][2],t+0.1)-
bezier(bez[0+ni][2],bez[1+ni][2],bez[2+ni][2],bez[3+ni][2],t);

if(gy<movcord[1]+2.5)
movcord[1]=gy-2.5;
glutPostRedisplay();
}
}

void renderCylinder(float x1, float y1, float z1, float x2,float y2, float z2, float
radius,int subdivisions,GLUquadricObj *quadric)
{ float vx = x2-x1,vy = y2-y1,vz = z2-z1; if(vz
== 0) vz = .0001;
float v = sqrt( vx*vx + vy*vy + vz*vz ); float
ax = 57.2957795*acos( vz/v );
if ( vz < 0.0 ) ax
= -ax;
float rx = -vy*vz; float ry =
vx*vz; glPushMatrix();
glTranslatef( x1,y1,z1 );
glRotatef(ax, rx, ry, 0.0);
gluQuadricOrientation(quadric,GLU_OUTSIDE);
gluCylinder(quadric, radius, radius, v, subdivisions, 1);
gluQuadricOrientation(quadric,GLU_INSIDE);
gluDisk( quadric, 0.0, radius, subdivisions, 1);
glTranslatef( 0,0,v );
gluQuadricOrientation(quadric,GLU_OUTSIDE);
gluDisk( quadric, 0.0, radius, subdivisions, 1);
glPopMatrix();
}
void draw_cyl(float x1, float y1, float z1, float x2,float y2, float z2, float radius,int
subdivisions)
{
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricNormals(quadric, GLU_SMOOTH);
renderCylinder(x1,y1,z1,x2,y2,z2,radius,subdivisions,quadric);
gluDeleteQuadric(quadric);
}

Department of CSE, BNMIT 2015-2016 P a g e | 32


Amusement Park Implementation

void draw_bezier()
{ GLfloat bx,by,bz,bx1,by1,bz1,bx2,by2,bz2,i=0.0; int
n=0;
glColor3f(1.0,1.0,0.0);
glDisable(GL_LIGHTING);
glPushMatrix(); for(n=0;
n<bezno-2; n++)
{

for(i=0.0;i<=1.0;i+=0.015)
{
glBegin(GL_LINES);
bx1=bezier(bez[0+n][0],bez[1+n][0],bez[2+n][0],bez[3+n][0],i)-
1.3*fabs(sin(angle*3.14/180.0));
by1=bezier(bez[0+n][1],bez[1+n][1],bez[2+n][1],bez[3+n][1],i);
bz1=bezier(bez[0+n][2],bez[1+n][2],bez[2+n][2],bez[3+n][2],i)-
1.3*fabs(cos(angle*3.14/180.0));
glVertex3f(bx1,by1,bz1);
bx2=bezier(bez[0+n][0],bez[1+n][0],bez[2+n][0],bez[3+n][0],i)+1.3*fabs(sin(
angle*3.14/180.0));
by2=bezier(bez[0+n][1],bez[1+n][1],bez[2+n][1],bez[3+n][1],i);
bz2=bezier(bez[0+n][2],bez[1+n][2],bez[2+n][2],bez[3+n][2],i)+1.3*fabs(cos(
angle*3.14/180.0));
glVertex3f(bx2,by2,bz2);
glEnd();
}
glBegin(GL_LINE_STRIP);
for(i=0.0;i<=1.00;i+=0.02)
{
bz1=bezier(bez[0+n][2],bez[1+n][2],bez[2+n][2],bez[3+n][2],i+0.02)-
1.0*fabs(cos(angle*3.14/180.0));
bx1=bezier(bez[0+n][0],bez[1+n][0],bez[2+n][0],bez[3+n][0],i+0.02)-
1.0*fabs(sin(angle*3.14/180.0));
by1=bezier(bez[0+n][1],bez[1+n][1],bez[2+n][1],bez[3+n][1],i+0.02);
glVertex3f(bx1,by1,bz1);
}
glEnd();
glBegin(GL_LINE_STRIP);
for(i=0.0;i<=1.0;i+=0.02)
{

bz1=bezier(bez[0+n][2],bez[1+n][2],bez[2+n][2],bez[3+n][2],i+0.02)+1.0*fabs
(cos(angle*3.14/180.0));
bx1=bezier(bez[0+n][0],bez[1+n][0],bez[2+n][0],bez[3+n][0],i+0.02)+1.0*fabs
(sin(angle*3.14/180.0));
by1=bezier(bez[0+n][1],bez[1+n][1],bez[2+n][1],bez[3+n][1],i+0.02);

Department of CSE, BNMIT 2015-2016 P a g e | 33


Amusement Park Implementation

glVertex3f(bx1,by1,bz1);
}
glEnd();
glLineWidth(2.0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
for(i=0.0;i<=1.0;i+=1.00)
{
bx=bezier(bez[0+n][0],bez[1+n][0],bez[2+n][0],bez[3+n][0],i);
by=bezier(bez[0+n][1],bez[1+n][1],bez[2+n][1],bez[3+n][1],i);
bz=bezier(bez[0+n][2],bez[1+n][2],bez[2+n][2],bez[3+n][2],i);
draw_cyl(bx,by-0.5,bz,bx,-10.0,bz,0.5,12);
}
glDisable(GL_LIGHTING);
glLineWidth(2.0);
}
glFlush();
glPopMatrix();
}
void windowSpecial(int key,int x,int y)
{
if(key==GLUT_KEY_UP)
{ movcord[0]+=5*cos(-2.0*x_r*3.14/180.0);
movcord[2]+=5*sin(2.0*x_r*3.14/180.0);
}
if(key== GLUT_KEY_DOWN)
{movcord[0]-=5*cos(-2.0*x_r*3.14/180.0);
movcord[2]-=5*sin(2.0*x_r*3.14/180.0);
}
if(key==GLUT_KEY_RIGHT)
x_r+=3;
if(key==GLUT_KEY_LEFT) x_r-=3;
display();

}
void kb(unsigned char key, int x, int y)
{ if(key=='+') movcord[1]--;
if(key=='-') movcord[1]++;
glutPostRedisplay();
}
void handleMouse(int x,int y)
{ if((x-prevx)>=0) x_r+=1; else
x_r-=1;
prevx=x;
}

Department of CSE, BNMIT 2015-2016 P a g e | 34


Amusement Park Implementation

void passiveMouse(int x, int y)


{
prevx=x;
}
void place_camera(int action)
{
if(camw==3)
x_r=0;
camw=action;
if(camw==2)
{ movcord[0]=-co_x+cos(c_angle*3.14/180.0)*50.0;
movcord[1]=-co_y-38;
movcord[2]=co_z;
}
if(camw==3)
{moveToBezier(bez_prog);
viewer[0]=1.0;
viewer[1]=viewer[2]=camera[0]=camera[1]=camera[2]=0.0;
x_r=-45;
}
if(camw==1)
{ movcord[0]=-gw_x +(gw_radius*sin(gw_spin*3.14/180.0)) +
sin(gw_spin/10.0);
movcord[2]=gw_z; movcord[1]=-gw_y-
(gw_radius*cos(gw_spin*3.14/180.0))+6;
}
if(camw==0)
viewer[1]=viewer[2]=camera[0]=camera[1]=camera[2]=0.0;
}

void handle_gwheel(int action)


{
if(action==0) gw==0?(gw=1):(gw=0);
}

void handle_columbus(int action)


{
if(action==0) cswing==0?(cswing=1):(cswing=0);
}
void handle_roller(int action)
{
if(action==0) { roll==0?(roll=1):
(roll=0); viewer[0]=1.0;

Department of CSE, BNMIT 2015-2016 P a g e | 35


Amusement Park Implementation

viewer[1]=viewer[2]=camera[0]=camera[1]=camera[2]=x_r=0.0;
}
}

void menu(int action)


{
if(action==0)
{ background=(background+
1)%3; initSky();
}
if(action==1) exit(0);
}

void handle_columbus_body(int action)


{ columbus_color=action;
}

void handle_columbus_stand(int action)


{ columbus_stand_color=action;
}

void handle_gwheel_ring(int action)


{ gwheel_ring_color=action;
}

void handle_gwheel_trolley(int action)


{gwheel_trolley_color=action;
}
void handle_roller_color(int action)
{ roller_body_color=action;
}
void addMenu()
{
int submenu1,submenu2,submenu21, submenu22,submenu3, submenu31,
submenu32, submenu4, submenu41;
submenu1 = glutCreateMenu(place_camera);
glutAddMenuEntry("Free Movement",0);
glutAddMenuEntry("Inside Giant Wheel",1);
glutAddMenuEntry("On Columbus ship",2);
glutAddMenuEntry("On Roller Coaster",3);
submenu21 = glutCreateMenu(handle_gwheel_ring);
glutAddMenuEntry("Yellow",0);
glutAddMenuEntry("Silver",1);

Department of CSE, BNMIT 2015-2016 P a g e | 36


Amusement Park Implementation

glutAddMenuEntry("Pale red",2);
glutAddMenuEntry("Brown",3);
glutAddMenuEntry("Grey",4);
submenu22 = glutCreateMenu(handle_gwheel_trolley);
glutAddMenuEntry("Blue",0);
glutAddMenuEntry("Yellow",1);
glutAddMenuEntry("Grey",2);
glutAddMenuEntry("Pale red",3);
glutAddMenuEntry("Brown",4);
submenu2 = glutCreateMenu(handle_gwheel);
glutAddMenuEntry("Stop/Start Giant Wheel",0);
glutAddSubMenu("Giant Wheel frame colour",submenu21);
glutAddSubMenu("Giant Wheel trolley colour",submenu22);
submenu31 = glutCreateMenu(handle_columbus_body);
glutAddMenuEntry("Light Brown",0);
glutAddMenuEntry("Black",1); glutAddMenuEntry("Grey",2);
glutAddMenuEntry("Dark Brown",3);
glutAddMenuEntry("Purple",4);
submenu32 = glutCreateMenu(handle_columbus_stand);
glutAddMenuEntry("Light Grey",0);
glutAddMenuEntry("White",1); glutAddMenuEntry("Dark
Grey",2); glutAddMenuEntry("Brown",3);
glutAddMenuEntry("Dark Blue",4);

submenu3 = glutCreateMenu(handle_columbus);
glutAddMenuEntry("Stop/Start Columbus ship",0);
glutAddSubMenu("Columbus body colour",submenu31);
glutAddSubMenu("Columbus stand colour",submenu32);
submenu41 = glutCreateMenu(handle_roller_color);
glutAddMenuEntry("Silver",0);
glutAddMenuEntry("Gold",1);
glutAddMenuEntry("Dark Grey",2);
glutAddMenuEntry("Brown",3);
glutAddMenuEntry("Purple",4);
submenu4 = glutCreateMenu(handle_roller);
glutAddMenuEntry("Stop/Start Roller Coaster",0);
glutAddSubMenu("Roller Coaster colour",submenu41);
glutCreateMenu(menu);
glutAddSubMenu("Camera
Position",submenu1); glutAddSubMenu("Giant
Wheel",submenu2);
glutAddSubMenu("Columbus ship",submenu3);
glutAddSubMenu("Roller Coaster",submenu4);
glutAddMenuEntry("Change Background",0);

Department of CSE, BNMIT 2015-2016 P a g e | 37


Amusement Park Implementation

glutAddMenuEntry("Quit",1);
glutAttachMenu(GLUT_RIGHT_BUTTO
N);

}
int main(int argc, char** argv)
{
bezno=(sizeof(bez)/24)-2;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|
GLUT_DEPTH); glutInitWindowSize(800,600);
glutCreateWindow("Amusement Park");
initLights();
initSky();
glutDisplayFunc(display);
glutReshapeFunc(displayReshape);
glutKeyboardFunc(kb);
glutMotionFunc(handleMouse);
glutPassiveMotionFunc(passiveMouse);
glutIdleFunc(idle);
glutSpecialFunc(windowSpecial);
addMenu();
glutMainLoop();
return 0;
}

Department of CSE, BNMIT 2015-2016 P a g e | 38


CHAPTER - 6
SNAPSHOTS

Figure 6.1: Giant Wheel viewed from free movement camera.

Figure 6.2: Camera placed inside Giant Wheel trolley.

Department of CSE, BNMIT 2015-2016


P a g e | 39
Amusement Park Snapshots

Figure 6.3: Camera placed on the Columbus ship.

Figure 6.4: Columbus ship viewed from free movement camera.

Department of CSE, BNMIT 2015-2016 P a g e | 40


Amusement Park Snapshots

Figure 6.5: Camera placed on the moving Roller Coaster.

Figure 6.6: Roller Coaster viewed from free movement camera.

Department of CSE, BNMIT 2015-2016 P a g e | 41


CHAPTER - 7

CONCLUSION AND FURTHER ENHANCEMENTS

An Amusement Park simulator is developed in OpenGL using the library functions defined in
it. The graphics software system not only draws objects like Giant Wheel, Columbus and
Roller Coaster, but also adds rotation and motion effects to them. The Entire scene is placed
in a SkyBox for a realistic sky effect. The system also features first person movement, where
the viewer can move around anywhere in the scene.

The curves of Roller Coaster track is drawn using Bezier functions. Lighting effect is
also employed for a better 3D appearance. The graphics software system is found to be
successful in displaying an Amusement Park.

This graphics system can be used in:

The graphics software system can be used as a Roller Coaster simulator.


This system can be used as a virtual Amusement Park.
This system can be used to study the motion of a trajectory along a curved path.

This can be further enhanced as below :

This system can also be modified as a game.


The SkyBox can be modified to an Aircraft Simulator to train pilots.
Other amusement park games can be added.

Department of CSE, BNMIT 2015-2016 P a g e | 42


BIBLIOGRAPHY

References:
[1] Edward Angel, Interactive Computer Graphics A Top-Down Approach with
OpenGL, 5th Edition, Pearson Education, 2004.
nd
[2] F.S. Hill Junior, Computer Graphics using OpenGL, 2 Edition, Pearson
Education, 2001.
[3] http://www.opengl.org/resources/code/samples/redbook/
[4] http://stackoverflow.com/questions/4288367/how-to-rotate-and-then-move-on-that-
direction/
[5] http://stackoverflow.com/questions/6243693/move-object-along-a-bezier-path-in-3d-
rotation-problem
[6] http://nehe.gamedev.net/

Department of CSE, BNMIT 2015-2016 P a g e | 43

You might also like