Top Banner
Creating Realistic Three-Dimensional "Map" using OpenGL By Dan Hooper Senior Computer Science Thesis 05/04/2002 SP COSC HOO 02/73
112

rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Feb 26, 2021

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Creating Realistic Three-Dimensional "Map" using OpenGL

By Dan HooperSenior Computer Science Thesis

05/04/2002

SPCOSCHOO02/73

Page 2: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

iJ

Table of Contents

1.0 Thesis Introduction 3

2.0 Introduction to OpenGL 42.1 State Variables 52.2 Coordinate System 52.3 GLUT ... 6

3.0 OpenGL Primitives 73.1 Vertices 73.2 Points 83.3 Lines 83.4 Polygons 83.5 Creating a Primitive 103.6 Colour 113.7 Curved Surfaces 133.8 Removing Hidden Surfaces 133.9 T-Bird Lounge Program 15

3.9.1 Primitives 153.9.2 Colour 163.9.3 Curved Surfaces 173.9.4 Removal Of Hidden Surfaces 18

4.0 Viewing in OpenGL 194.1 The Camera Analogy 194.2 Viewing Transformation 204.3 Model Transformation 224.4 Projection Transformation 234.5 Viewport Transformation 264.6 Matrix Stacks 264.7 T-Bird Lounge Program 28

4.7.1 Transformations 284.7.2 Viewing ... 29

5.0 Lighting in OpenGL 325.1 Real World Lighting 325.2 Types of Light 335.3 Creating Light Sources 345.4 Light Model 355.5 Materials Properties 375.6 Normal Vectors 395.7 T-Bird Lounge Program 41

5.7.1 Light Properties 415.7.2 Material Properties 425.7.3 Normal Vectors 42

Page 3: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

6.0 Textures in OpenGL 436.1 Creating Texture Maps 436.2 T-Bird Lounge Program 45

7.0 Shadows in OpenGL 467.1 Static Shadows 467.2 Projective Shadows 477.3 Stenciled Shadow Volumes 487.4 T-Bird Lounge Program 49

8.0 T-Bird Lounge Program (Everything Else) 508.1 Data Gathering 508.2 Manual 51

8.3 Program Layout 528.4 Program Functions 53

9.0 Conclusions 62

10.0 Bibliography 64

Appendix A 66

2

Page 4: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

1.0 Thesis Introduction

The purpose of this thesis is to determine how to create realistic looking "maps"

using OpenGL. A "map" in the context of computer graphics is a three dimensional

environment. Thus a realistic looking map is a realistic looking three-dimensional

environment.

Once familiar with the concepts of OpenGL, I will attempt to create a realistic

looking map of the student lounge at Algoma University College, called the T-Bird

Lounge. I will also make the map interactive to the viewer. The viewer will be able to

move through the lounge and examine anything they wish. Through the generation of

this map I will gain a deeper understanding of what is involved in creating such

graphically intensive software.

I will be using Microsoft Visual C++ 6.0 to write the program. I am also using

the latest version of OpenGL available at the time, version 1.2.

3

Page 5: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

2.0 Introduction to OpenGL

OpenGL provides programmers with the ability to access graphics hardware

through software. It is composed of over 200 commands that are used to access the

graphics hardware in order to create three-dimensional scenes. OpenGL has a hardware-

independent interface that can be used across multiple platfolins. Because of this

platform independence, OpenGL does not include any commands for windowing tasks.

You must use whatever means are necessary to setup the window in which the OpenGL

program will run.

OpenGL also does not contain commands for complex shapes. It can construct

objects through the use of its three geometric primitives — points, lines, and polygons.

The OpenGL Utility Library (GLU) provides many such functions to create more

complex objects with a single command This GLU library is an addition to Open GL.

OpenGL allows you to arrange these primitives in a three-dimensional environment, and

it allows you to choose a viewpoint within that environment.

OpenGL also can do colour and lighting operations otherwise would be extremely

difficult to program. OpenGL also allows the application of textures in many ways to a

scene. When the entire above are specified, the mathematical representations of them are

converted into pixels that appear on your screen.

4

Page 6: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

2.1 State Variables

OpenGL functions as a state machine. The program can be put into different modes. It

will remain in those modes until they are explicitly changed by the programmer. Some of

the state variables include the current colour, the current normal vector, the current

primitive type, etc... There are many state variables in OpenGL that can be enabled or

disabled using the two commands glEnable(state Variable); or glDisable(stateVariable);.

These state variables can then be queried during to the program to test their current status.

The commands to do so are as follows: glGetBooleanv();, glGetDoublev();,

glGetFloatv();, glGetIntegerv();, glGetPointerv();, or glIsEnabled(stateVariable).

There over 250 state variables in OpenGL. The following list is just a small

example of the types of state variables:

GL_CURRENT_COLORGL_CURRENT NORMALGL_EDGE_FLAGGL_COLOR ARRAYGL_DEPTH_RANGEGL_FOG_COLORGLSHADE_MODEL

GL_LIGHTINGGL_POSITIONGL_DEPTH_BITSGL_RGBA_MODEGL_MAX_LIGHTSGL_READ_BUFFERGL_DRAW_BUFFER

2.2 Coordinate System

OpenGL uses a standard three-dimensional coordinate system with x, y, and z

axis. The axes are unit-less. The axes take on whatever units you like, and you need not

specify what type of units you are using. Your units can be meters, inches, kilometers,

picometers, furlongs, or whatever you want. In order to produce scale scenes, all that is

necessary is that you use the same units for every object in the scene. Each axis extends

5

Page 7: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

32 768 units in the positive and negative directions. All measurements are relative to

whatever scale you choose.

2.3 GLUT

GLUT stands for OpenGL Utility Toolkit. It was created by Mike Kilgard. The

purpose of GLUT is to manage functions which OpenGL does not control on its own.

For example, GLUT contains procedures to initialize a window and get input from

various devices such as the keyboard. The commands are universal to all windowed

environments, and thus, the programmer does not need to learn a new API to create an

OpenGL program. All GLUT commands have the prefix "glut".

6

Page 8: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

3.0 OpenGL Primitives

In OpenGL, a virtually endless amount of possible scenes can be created.

Although all of these scenes look quite different from one another, they are all

constructed using the same building blocks. OpenGL has a set of primitive objects which

are used to draw anything and everything in a scene. Each one of these primitives is

defined by its vertices. There are three primitives in OpenGL. They are points, lines and

polygons.

3.1 Vertices

Vertices are composed of a set of coordinates in three-dimensional space.

Vertices are very versatile. They can be specified in a variety of data types. The

coordinates of a vertex can be a short integer, a regular integer, a 16-bit floating point

number, a 32-bit floating point number, or an array of any of the previously mentioned

data types. The vertices can also take two, three or four coordinates (x, y, z, and w) in

specifying a vertex. Unless specified, w is given a default value of one, and z is given a

default value of zero. Vertices are specified using the a variation of the command:

glVertex { 234 } { sifd } [v] (TYPE cords);

{234} specifies how many coordinates are going to be given. {sifc} specifies what data

type the coordinates will be given in, short, int, float, or double. [v] indicates that the

coordinates will be given in an array. Here are some examples that will clarify the above:

glVertex2s(2, 3);glVertex3d(0.0, 0.0, 3.14159265358989);glVertex4f(2.3, 1.0, -2.2, 2.0);GLdouble coords[3] = (5.0, 9.0, 1992.0);glvertex3dv(coords);

7

Page 9: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

3.2 Points

Quite simply, a point is single location in three-dimensional space defined by its

vertex. Points can also be specified in two-dimensional coordinates, only specifying x

and y coordinates. When this is done, a z value of zero is given to the vertex.

3.3 Lines

A line in OpenGL is a line segment. It is defined by two vertices as endpoints. A

line is drawn between the two vertices in three-dimensional space.

3.4 Polygons

This is the most complex type and most often used type of primitive. A polygon

is a plane enclosed by a group of line segments. There are several ways to draw

polygons. The most common way to draw them is to fill in the area between the vertices,

creating the appearance of a surface. You can also draw the outline of the polygon. This

would create a wire frame effect.

Polygons must follow a set of rules in order to be drawn correctly. Every polygon

must be a convex polygon. If the vertices of a polygon represent a concave polygon, then

it will not be drawn correctly. One way to tell if a polygon is convex is to draw (or

imagine) a line between each pair of vertices in the polygon. If all the lines remain inside

the implied edges of the polygon, then it is convex, and thus valid, otherwise, it is

concave and invalid. Another rule is that polygons can not have a hole in the middle of

them (see figure 3-1). This case is not possible to describe using OpenGL anyway.

8

Page 10: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

InvalidValid

Finally, all point of a polygon must be on the same plane. If they are not all on the same

plane, the polygon may not be drawn correctly from all angles. One way to get around

this rule is to create all of your polygons using a set of triangles. Since a triangle is

always in one plane, this case would never arise.

Figure 3-1: Examples of valid and invalid polygons

Polygons also have a front face and a back face. By default, the front face of a

polygon is that face in which the vertices are counter-clockwise. Conversely, the back

face is that face in which the vertices are clockwise. This default can be over-ridden, thus

making the front face clockwise, and the back face counter-clockwise. This feature

becomes useful when frame rates become an issue. OpenGL allows for only front facing

polygons to be drawn. They also allow for only back facing polygons to be drawn. And

by default, both faces of the polygon are drawn. This feature is known as culling. The

following command allows the various types of culling:

glCullFace(GLenum mode);

Where "GLenum mode" can be GL_FRONT to cull (remove) the front facing polygons,

GL_BACK to cull the backwards facing polygons, or GL_FRONT_AND_BACK to cull

all polygons. Just using this command will not cull any polygons. The culling state

variable must be enabled (glEnable(GL_CULL_FACE);).

I

Page 11: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

The reason for all of these rules is to speed up the rendering process. These

features could be added so that the polygons would be drawn correctly, but it would take

extra hardware features to detect and draw them, which would increase the time it takes

to draw the scene. The scene will likely still be drawn without any runtime errors, but the

scene may not be drawn correctly. OpenGL and the hardware to support it, does not

detect these cases.

3.5 Creating a Primitive

In order to create one of these primitives, the vertices must be specified between

the statements glBegin(GLenum mode); and glEnd();. Here, "GLenum mode" specifies

what type of primitive will be drawn using the vertices specified between these two

statements. There are ten possible modes in which the primitives can be drawn:

GL_POINTS (creates individual points), GL LINES (creates separate lines for every pair

of vertices, ie. vertex 1 and vertex 2 are used to make a line, then vertex 3 and 4 are used

to make a separate line), GL_LINE_STRIP (creates one line from a series of line

segments), GL_LINE_LOOP (creates one line from a series of line segments and also

creates a line segment between the first and last vertex specified in the vertex list),

GL_TRIANGLES (creates separate triangles grouping the vertices in threes),

GL_TRIANGLE_STRIP (creates a number of triangles which share a common edge),

GL_TRIANGLE_FAN (creates a number of triangles which share a common edge and

also share the first vertex), GL_QUADS (creates separate quadrilaterals grouping the

vertices in fours), GL_QUAD_STRIP (creates a series of quadrilaterals which share a

10

Page 12: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Vo V2® V4.

V1. V3 ® Vg

GL_POINTS

V2

V1

GL TRIA1■JGLE AN

Figure 3-2: Types of Primitives, Including Vertex Order

common edge), and GL_POLYGON (creates an n-sided polygon defined by the n

vertices). Each of these modes specifies a different way to use the vertices in order to

draw the primitive (see Figure 3-2).

3.6 Colour

Computer monitors create the spectrum of colours by mixing red light, green light

and blue light together (RGB). Often a fourth number is associated with these three

11

Page 13: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

values, called alpha. This alpha value is used create blending effects. This is the format

in which OpenGL facilitates the use of colour as well. OpenGL can also operate in

colour index mode. In this mode, all of the colours are entered into an array. The colours

can then be accessed by using the index of the colour in the array. By default, OpenGL is

in RGBA mode.

In order to create a primitive with colour, the vertices that define that primitive

need to be assigned a colour. This can be done by using the following command:

glColor3{b s i f d ub us ui } (TYPE r, TYPE g, TYPE b);

where {b s i f d ub us ui } represent the data type of the input parameters (b = signed char,

s = short integer, i = integer, f = floating point number, d = double precision floating

point number, ub = unsigned char, us = unsigned short integer, and ui = unsigned

integer), and r, g, and b represent the percentage of red light, green light and blue light

respectively. This command sets the current colour. Every vertex specified after this

command will have the specified colour associated with it.

Primitives can be made up of one colour, or from several colours. In order to

specify which mode you prefer, you must choose a shading model using the command

glShadeModel(GLenum mode); where mode can be GL_SMOOTH or GL_FLAT. In

GL_SMOOTH mode, the vertices of a primitive can be different colours. OpenGL will

make each vertex its designated colour, and then mix with the other colours as the move

• 1 away from the vertices to fill in the primitive. In GL_FLAT mode, the colour of one of

Page 14: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

the vertices is copied to the rest of the vertices, thus producing a primitive which is all

one colour.

3.7 Curved Surfaces

All of the above types of primitives are in a straight line or on a flat plane. So

what do you do when you wish to create a curved surface? Since OpenGL does not let

you create a curved surface using a single primitive, several must be used to approximate

the curve. Divide the curve into small simple primitives, either lines or polygons. If you

increase the number of subdivisions, it will be harder to see the individual flat sections

(see figure 3-3).

(",,,,,====221=-)

Figure 3-3: Various Degrees of Approximating Curves

This will increase the number of lines or polygons in your scene. Implementing many

curved surface approximations will increase your polygon count significantly, and

depending on your hardware, you may experience noticeably slower drawing times.

3.8 Removing Hidden Surfaces

By default, OpenGL draws primitives in the order in which it encounters them.

Imagine drawing the six surfaces of a cube, each one a unique colour. You would have

13

Page 15: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

to start off with the surface furthest away from the view point, and continue drawing the

surface furthest away from you until all of the surfaces were drawn in order for the front

face to be in-front of the other surfaces. Now suppose you move the viewpoint to the

opposite side of the cube. Instead of looking at the back face of the cube, you would still

be looking at the front face because it was the last side to be drawn (the back side was

overwritten even though it is now in-front of the original front face). Obviously, this is

not the desired affect needed to create a realistic looking scene.

To overcome this we shall use the depth buffer. It works by associating with each

vertex a depth value from the current viewpoint. By enabling a depth test, OpenGL will

examine the depth of the object being drawn, and place it accordingly in the scene.

Vertices with a depth value less than the current vertices being drawn will appear in-front

of the object being drawn. Similarly, any vertices with a depth value greater than the

vertices being drawn will appear to be behind the object being drawn. Using this strategy

in the cube example, when the viewpoint is moved to the back of the cube, the viewer

will now see the back of the cube, and not the front.

To achieve this effect, the following must be done:

glutInitDisplayMode(GLUT_DEPTHglEnable(GL_DEPTH_TEST);

glClear(GL_DEPTH_BUFFER_BIT);draw_the_scene();

The Utility Toolkit function is the first line of code, creates a window with a depth buffer

in which the scene is drawn. Next, the depth test state variable is enabled. Before each

pass through the portion of the program which draws the geometry of the scene, the depth

14

Page 16: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

buffer must be cleared. Then the scene can be drawn. Since there may be some surfaces

that are not drawn at all, the performance of the scene will increase.

3.9 T-Bird Lounge Program

3.9.1 Primitives

The T-Bird Lounge program uses several types of primitives to draw the various

elements of the scene. Since the walls are rectangular shaped, it made sense to make the

walls out of various rectangles. Thus, all of the walls are constructed using quadrilaterals

(GL_QUADS). The doorways, pillars, wood trim, window sills, the stage and the bar are

also constructed using quadrilaterals. The foosball table and the projection television

with its stand are simple objects that were also created using quadrilaterals. The

rectangular tables, although much more complex then all of the above, were also created

using quadrilaterals (see figure 3-4).

Figure 3-4: Wire frame view of the rectangular table.

15

Page 17: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

The Coke machine has an odd front face to it. It is in the shape of an "S". In

order to accommodate this shape, the Coke machine was also made up several

quadrilaterals on the front and side faces of the machine. The top, bottom and back of the

machine are single quadrilaterals.

The round tables are made up of a fan of triangles (GL_TRIANGLE_FAN) for

the table top and the circular base. The rest of the table, including the support, is

constructed with quadrilaterals. The chairs contain two, six-sided polynomials

(GL_POLYNOMIAL) as the sitting surface. Again, the rest of the chair is composed of

quadrilaterals (see figure 3-5).

Figure 3-5: Round table and a chair in wire frame mode

In order to increase performance, back facing polygons were not drawn.

3.9.2 Colour

Colours were assigned to vertices using the actual colours of the objects. These

colours retrieved through digital photographs taken of the lounge. The program does not

16

Page 18: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

use the command in section 3.6 (pg 11), but rather assigns colour to vertices using

material properties discussed in section 5.5 (pg 37).

3.9.3 Curved Surfaces

The T-Bird Lounge program has several examples of curved surface

approximations. Refer to section 3.9.1 (pg 15) for wire frame views of the objects

discussed here. The objects that contain these approximations are the Coke Machine, the

rectangular tables, the round tables, and the chairs. The Coke Machine has a curved front

face in the shape of an "S" as discussed in section 3.9.1 (pg 15). The rectangular tables

contain two types of curved surfaces. The first curved surface approximation is the round

edge of the table top. The second type is on the cylindrical legs of the table. The

rectangular table tops are similar to the Coke Machine in that all of the vertices were

assigned with absolute values — that is they were not calculated by the program.

The round tables, the chairs and the legs of the rectangular tables all have

approximated curved surfaces that were computed by the program. The round tables are

the more complex example as you can see from the wire frame example above. The legs

of the tables and the supports for the chairs are all the same type of curved surface

approximation - they are all cylindrical shaped, and the vertices were generated by the

program. For more detail on how these vertices were calculated, please refer to section

8.4 (pg 53).

17

Page 19: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

3.9.4 Removing Hidden Surfaces

Since the T-Bird Lounge program is interactive (i.e. you can move around within

the lounge), hidden surface removal was a must (section 3.8, pg 13). Without the depth

test in this program, from various vantage points, objects which ought to be behind other

objects will appear in front of them. The depth test mentioned above determines the

orientation in three-dimensional space of all the objects in the scene relative to the view

point, and ensures that the scene be drawn correctly.

18

Page 20: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

4.0 Viewing in OpenGL

The teiiii viewing refers to the way in which the scene is drawn. Given all of the

input primitives, a final scene must be drawn to the screen. OpenGL provides the means

to describe a three-dimensional scene, but the final scene is not drawn in three-

dimensions, it is drawn on the two-dimensional plane of your screen. This is

accomplished through a series of transformations. A transformation is represented by a

matrix multiplication. This matrix is multiplied by certain (or in many cases, all) vertices

transform their shape, or location in two-dimensional or three-dimensional space. A

single object or the entire scene may undergo such a transformation to yield the desired

effect. The first step in understanding how viewing transformations are applied is to

examine an analogy as to how viewing is accomplished in OpenGL.

4.1 Camera Analogy

The following analogy compares drawing a scene using OpenGL with taking a

photograph. These steps give a better understanding of how a scene is drawn in OpenGL:

1. Take your camera and set it up to point at where your scene will be

located. This is the viewing transformation.

2. Now, arrange the objects in your scene to your liking. This is the model

transformation.

3. On the camera, adjust the zoom setting and/or the lens you are using. This

is the projection transformation.

19

Page 21: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

4. Finally, determine the size of the final photograph. This is the viewport

transformation.

In this analogy, viewing transformations must precede the model transformations.

However, the projection and viewport transformations can be specified at any time before

U

the drawing of the scene occurs.

So, what actually happens? The viewing and modeling transformations are combined to

the modelview matrix. This matrix when multiplied by the vertices transforms the scene

into eye coordinates. If there are any clipping planes, they are applied now to remove

any objects which lie beyond these planes. The projection matrix then yields clip

coordinates. These coordinates all lie inside a viewing volume defined by the clipping

planes. If an object (or part of an object) lies outside of this viewing volume, it does not

proceed to the next transformation. Now, perspective division is performed to transform

the scene into normalized device coordinates. This applies the desired perspective to the

scene. Finally, the scene is transformed into a two-dimensional set of window

coordinates by the viewport matrix, and the scene is drawn to the screen. All of the

matrix multiplications are done for you by OpenGL.

p 4.2 Viewing Transformation

This transformation was analogous to the positioning of the camera in the camera

analogy. Since this matrix multiplies the current matrix (other transformations may have

occurred prior to this incursion) by the matrix about to be applied, the current matrix may

20

Page 22: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

need to be set to the identity matrix if this extra transformation is not desired. This can

p

be done using the command glLoadIdentity(). Quite simply, this command sets the

current matrix to the identity matrix.

By default, the camera is positioned at the origin looking down the negative z-

axis. Keeping in mind that viewing transformations must be done before model

transformations, the commands glTranslate*() and glRotate*() can be used to adjust the

orientation of the camera. The "*" must be either "d" (representing double precision

floating point input parameters) or "f" (representing single precision floating point

parameters).

The translate command above takes three input parameters representing x, y and z

coordinates. This command will not move the camera from its current position in three-

dimensional space, but rather move the origin to a new location specified in the input

parameters. For example: the command glTranslatef (1.0 , 2 . 0 , 3 . 0) ; will move

the origin of three-dimensional space to the coordinates (1.0, 2.0, 3.0). All subsequent

transformations take place relative to this new origin, which is (0.0, 0.0, 0.0). The

camera remains where it used to be, which relative to the new origin would be the

coordinates (-1.0, -2.0, -3.0).

The rotate command above takes 4 input parameters. The first is an angle,

represented in degrees. The next three parameters represent x, y and z coordinates in that

order. The three coordinates represent a vector in three-dimensional space. The origin is

21

Page 23: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

then rotated about the specified vector the given angle. Again, the camera remains in its

original orientation, but the origin has been rotated. The origin still lies at the same

position, but the axes of the coordinate system have been rotated.

The orientation of the camera can also be specified using the gluLookAt()

command. This command is not directly supported by OpenGL, but rather is part of the

GLU utility kit mentioned earlier (section 2.0, pg 4). This command takes three vectors

as input, for a total of nine input parameters, to describe the orientation of the camera.

The first three parameters refer to the camera's position in three-dimensional space. The

next three parameters represent a point in three-dimensional space at which the camera is

pointing. The final three parameters indicate to the camera which direction is considered

to be "up".

4.3 Model Transformations

Model transformations perform various operations on you coordinate system.

The three operations are glTranslate*(), glRotate*(), and glScale*(), where "*" must be

either "d" (representing double precision floating point input parameters) or "f'

(representing single precision floating point parameters). The translate and rotate

functions are the same as in the viewing transformations (Section 4.2, pg 20).

glTranslate*() moves the origin to a new origin, and glRotate*() rotates the coordinate

axes about the given vector.

I

22

Page 24: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

The third command, glScale*() has three input parameters, x, y, and z. Instead of

adding these values to the current origin, these values are multiplied by the current

matrix. The result of this multiplication can expand certain axes (with values greater than

1.0), shrink axes (with values less than 1.0, but greater than 0.0), or even invert axes

(with negative values).

4.4 Projection Transformations

As in the previous section, projection transformations alter the vertices and

coordinate system of a scene. Before any transformations are done, you must indicate

that future transformations are to be done to the projection matrix and not the modelview

matrix. This can be done by using the command glMatrixMode (GL_PROJECTION) ; . If

there are any model or viewing transformations to be done later on in the program, the

matrix mode must be reset to perform the transformations on the modelview matrix. This

can be done using the command glMatrixMode (GL_MODELVIEW) ; . Once the matrix

mode has been set to alter the projection matrix, the Identity matrix will most likely need

to be loaded into the current matrix. Compound projection transformations are not

common, since each projection transformation completely describes the desired

transformation.

The purpose of the projection transformations is to define a region that defines

what will be drawn. Vertices inside this region will be drawn. It also accommodates for

various types of projection modes. There are 2 types of modes: Perspective and

Orthographic.

23

Page 25: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

The perspective mode represents the way in which we see every day life. Objects

that are farther away from us appear to be smaller than if they were very close. This

effect is called foreshortening. The viewing volume for perspective mode is a frustum,

which is a pyramid with its top cut off. Every vertex and edge that lies within that shape

is projected back towards the camera (i.e. the apex of the pyramid). Objects that lie

closer to the apex in the frustum occupy a larger percentage of the available space then

the same size object placed further from the apex, thus, generating the effect of

perspective.

OpenGL's method of applying perspective works, but is not intuitive. The GLU

utility library provides a much more intuitive process. The command to setup the

perspective frustum is:

void gluPerspective(GLdoublefovy, GLdouble aspect, GLdouble near, GLdouble far);

Where fovy represents the viewing angle in the y direction, aspect is the ratio of the

height/width of the frustum, near is the distance to the front of the frustum, and far is the

distance to the back of the frustum (see figure 4-1). Only objects that lie within this area

are drawn to the final scene.

24

Page 26: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Figure 4-1: Perspective Viewing Volume as defined by gluPerspective()

The Orthographic mode has a cube shaped viewing volume- more specifically, a

rectangular parallelepiped. Objects of the same size appear the same size regardless of

where they are positioned. This projection method is not life-like. It is used more

commonly in schematics, where the shape of the object is more important than how it

looks in reality. The command for setting up the viewing volume is:

glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);

Where each parameter is the distance to its respective edge of the viewing volume (see

figure 4-2).

to

Toward theviewpoint

Figure 4-2: Orthographic Viewing Volume

25

Page 27: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

4.5 Viewport Transformations

The viewport transformation determines the final size of the scene. The size is

measured in pixels. You can make a scene take up the entire screen, or just a small

window if you wish. At this stage of the process, the viewpoint has been setup, the

objects in the seen have been transformed, the projection matrix has been setup, and all

the vertices outside of the viewing volume have been clipped.

As discussed earlier (section 2.0, pg 4), OpenGL is not responsible for opening up

a window in which to draw a scene in. By default, the size of the window determines the

size of the viewport in pixels. The command for specifying the viewport is as follows:

glViewport(GLint x, GLint y, GLint width, GLint height);

Where x, and y represent the window coordinates of the bottom left hand corner of the

viewport, and width and height represent the size of the viewport rectangle. By default,

the height and width are automatically read from the size of the window.

When drawing a scene using perspective, the ratio of height/width should be the

same as the aspect ratio of the viewing volume (section 4.4 pg 23). Otherwise, the final

scene drawn will be distorted.

4.6 Matrix Stacks

As you might have already guessed, it becomes very easy to lose track of where

you are and which way you are pointing after a few consecutive transfollnations. Say,

26

Page 28: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

after drawing an object after these transfot nations, you want to return to your original

origin (this is an extremely common thing to want to do). You would have to perform the

inverse translation and inverse rotation in the reverse order in which they were first

applied to return to your original position. You would also have to reset the scale.

Executing the reverse translations and inverse rotations in the wrong order will most

likely not place the origin in its original position. A way to get around this was built into

every OpenGL program. The solution is a matrix stack. The stack is an ideal data

structure for this type of reverse order execution.

Modelview Projectionmatrix stack

< matrix stack

(32 4 x 4 matrices) (2 4 x 4 matrices)

Figure 4-3: The Modelview and Projection Matrix Stacks

There are two matrix stacks that are included in every OpenGL program- a

Modelview Matrix Stack, and a Projection Matrix Stack. The Modelview stack can hold

at least 32 matrices, while the projection matrix can usually hold a maximum of 2

matrices (see figure 4-3). Modelview matrices are generated by multiplying

transformation matrices by the current matrix. Projection transformations are usually not

intended to be multiplied by the current matrix. Thus, glLoadIdentity() is usually called

to load the identity matrix before the transformation (section 4.3, pg 22). The current

matrix for both stacks is the top matrix on the stack. Before any type of transformation,

call the function glPushMatrix();. This function makes a copy of itself, and places the

27

Page 29: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

copy on the top of the stack, essentially remembering where the origin is and it's

orientation at the moment. Now, the top and second from the top elements in the stack

are the same. The transformations following the push alter the top element of the stack.

Once the transformation is no longer needed, the function glPopMatrix(); should be

called. This function pops the top matrix off the stack, and it is destroyed. Now, the top

of the stack has our original transformation matrix, and thus we are back where we

started before we performed the transformations.

Any number of transformations can occur between the glPushMatrix() and

glPopMatrix() functions. The result will always bring you back to where you started.

Also, you can perform further push operations before calling the pop operation so long as

you do not exceed the size of the stack. Every glPushMatrix() should have a

glPopMatrix() in order to prevent popping from and empty stack, or pushing onto a full

stack (both of which will generate errors).

4.7 T-Bird Lounge Program

4.7.1 Transformations

The T-Bird Lounge program makes frequent use of modelview transformations.

Most noticeably so are the 45 chairs that are in the lounge, as well as the 7 round tables,

and the 3 rectangular tables. The foosball table and the projection television also make

use of modelview transformations. Each of the above objects was created once in a

function. The object was created about the origin. Once it came time to place the objects

in their correct position in the scene, the current matrix was pushed onto the stack, then

28

Page 30: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

the necessary translation and rotation took place, and the object was drawn about the new

origin using the objects function. Then the current (translated and rotated) matrix was

popped off the modelview matrix stack, restoring the original origin. The next object

could then be drawn using the same procedure.

Non of the walls, including the window sills or the pillars were constructed using

transformations. The T-Bird program does require the use of projection transformations.

4.7.2 Viewing

The viewing in the T-Bird Lounge program is interactive. The user can move

about the room, traveling through objects to examine anything they wish. The program

utilizes the "GLU" function "gluLookAt()" to setup the viewpoint.

The program has three global arrays in which the location of the camera, the

location of where the camera is pointing, and the direction which is up are stored (section

4.2, pg 20). After motion beings, the distance from the camera to the location in which it

is pointing is one unit away. After each movement, the vector from the camera location

to the point at which the camera is pointing is always normalized.

Whenever the user wishes to move forward, the coordinates in the direction array

is copied, then the vector from the camera position to the direction array is doubled, and

the direction array becomes this new value. Now, the new camera position can be set to

the old direction array. So, what happened was the camera move to where it was

29

Page 31: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

pointing, but before it moved, the location to which it was pointing was projected out

another unit length, thus preserving the orientation of the camera.

When moving backwards, the vector from the camera to the direction array is

extended from the end on which the camera is situated one unit length. The camera takes

on this new position behind itself, but still in line with its previous position and the

direction array. Now the direction array is pointing at a space that is located two unit

lengths away from the camera. This is fixed by normalizing the vector from the camera

to the direction array.

In order to accommodate looking up and looking down, the z value of the

direction array was simply incremented for looking up and decremented for looking

down. This too would also make the vector from the camera slightly longer than a unit

length. Again, this is fixed by the normalization process. This implementation also

makes it extremely unlikely that the viewer will be looking straight up or straight down.

If the viewer were able to do such a thing, it would be difficult to determine which way is

up and which way is down.

Turning is a little bit more complex. In order to turn right, the camera stays where

it is, but the direction vector rotates to the right. The calculation is best described with

the following excerpt from the T-Bird Program:

temp[0] = direction[0] + ((direction[1] - camera[1]) * turnMult);temp[1] = direction[1] - ((direction[0] - camera[0]) * turnMult);direction[0] = temp[0];direction[1] = temp[1];

normDirection();

30

Page 32: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Where turnMult is a constant set to 0.1, and temp[0] and temp[1] are temporary place

holders for the new direction array x and y values. A left turn is very similar. In order to

turn left, simply replace the first addition symbol in the first equation with a subtraction

symbol, and do the opposite with the second equation.

The viewing mode used in the T-Bird Program is the perspective mode (section

4.4, pg 23). It has a field of view angle of 90 degrees, the aspect ratio is 4/3 to conform

to the size of the viewport (to prevent distortion) which is 800/600 = 4/3, the near edge of

the viewing volume is 0.1cm from the viewer, and the far edge of the viewing volume is

10,000cm from the viewer. All objects within the frustum defined by the above values

will be visible to the viewer.

The viewport is set to draw the bottom left-hand side of the scene directly on the

bottom left-hand side of the window (section 4.5, pg 26). Whenever the window is

reshaped, the viewport ratio of width/height will always be 4/3, to match the aspect ratio

of the viewing volume.

31

Page 33: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

5.0 OpenGL Lighting

Lighting is a very important part of creating realistic-looking objects. Everything

that we see is result of light bouncing off objects and then continuing on into our eyes.

OpenGL has its own lighting algorithms built in, ready for use. The lighting algorithms

can be adjusted to approximate real world lighting.

5.1 Real World Lighting

In the real world, light emits in the form of Photons is all directions. Some of that

light is reflected off surfaces and into our eyes. Some of the light is also absorbed by the

surface. It depends on the surface how much light gets reflected. Most surfaces reflect

and absorb some light. The OpenGL lighting model breaks up the light into three

components — red, green, and blue. This model is an approximation of real life lighting,

also, the calculations can be performed relatively quickly. The default lighting can be

overridden with a different lighting model.

Light comes from various light sources. These light sources can be created using

OpenGL. Each source can be turned on or off. There is also light that comes from a

particular direction. And finally, there is light that has bounced off several sources, and

is hard to tell exactly which direction it is coming from. In the OpenGL model, the

lighting only has an effect when it comes in contact with a surface that reflects or absorbs

the light. The material properties can also be specified.

132

Page 34: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

5.2 Types of Light

There are basically four different types of light in the real world. They are

ambient, diffuse, specular and emissive light. Ambient light is light that has reflected off

so many surfaces, its direction or source is unknown. Ambient light scatters in all

directions when it hits a surface. Typically, indoor scenes have more ambient light

whereas outdoor scenes have less. The light can be contained indoors. Outdoors it can

reflect off a surface and not hit another surface for quite some distance, or perhaps reflect

off into space.

Diffuse light comes from a particular direction. Thus, when diffuse light hits a

surface squarely, it reflects more light than it would if it hits the surface at a thin angle.

Once the light hits the surface, it reflects equally in all directions, regardless of where the

view point is situated.

Specular light also comes from a particular direction as diffuse light does. The

light then however reflects in a certain direction. A typical example of this is a mirror.

The reflected light ray leaves a surface at the same angle in which the incident light ray

hits the surface. There are few surfaces that reflect this much light. Certain grades of

metal or plastic also posses specular qualities.

And finally, we have emissive light. Emissive light is light that is emitted from

a surface. For example, a blue surface may emit a percentage of blue light. In the

33

Page 35: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

OpenGL light model, emissive light from a surface does not add light to the entire scene,

nor is an emissive surface affected by other light sources in the scene.

5.3 Creating Light Sources

Associated with each light in a scene is the colour of light, the position of the

light, and the direction in which the light points. These components of each light can be

created and altered using the following command:

glLight{if} (GLenum light, GLenum pname, TYPE param);

where {if} indicate whether the input parameters are integers or floating point numbers,

light specifies which light is being created or altered. OpenGL can support at least 8

lights (GL_LIGHTO --> GL_LIGHT7). Depending on hardware, more may be supported.

pname indicates the parameter name to be altered. Accepted values are one of the

following: GL_AMBIENT, GL_SPECULAR, GL_POSITION,

GL_SPOT_DIRECTION, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION,

GL_LINEAR_ATTENUATION, OR GL_QUADRATIC_ATTENUATION. param

refers to the values that pname will take on.

In specifying the position of the light, you can also decide what type of light it is.

The input for the parameter GL_POSITION is four numbers. The first three are the

coordinates in three-dimensional space. The fourth determines how the previous three

values are interpreted. If the fourth value is zero, then the light source is considered to be

directional. That is, that the light is infinitely far away coming from a vector defined by

the first three values. If the fourth value is non-zero, then the light is considered to be

34

Page 36: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

11

positional. The first three parameters indicate the coordinates in three-dimensional space

where the light is situated. Positional lights are affected by modelview matrix

transformations (section 4.3, pg 22), but are not affected buy projection matrix

transformations (section 4.4, pg. 23).

5.4 Light Model

The OpenGL lighting model has four components to it - The amount of ambient

light, a local or viewpoint that is considered to be an infinite distance away, lighting for

front and back faces of objects (section 3.4, pg 8), and whether or not the specular colour

should be applied after the textures have been applied. In order to use these operations,

or any of the lights in the previous sections, OpenGL lighting must be enabled using the

command glEnable(GL_LIGHTING);. Also, every light source that is created must also

be enabled before it becomes active (glEnable(GL_LIGHT0);

glEnable(GL_LIGHT7);) (section 5.3, pg 34). Once the lights are enabled, the lighting

model can be specified. All of the lighting model commands are accessed through the

command:

glLightModel{ i f}(GLen urn pname, TYPE param);.

Where {if} indicates the data type of the input parameters (integers or floating point

numbers). pname specifies the parameter name which can be one of the following:

GL_LIGHT_MODEL_AMB I F,NT, GL_LIGHT_MODEL_LOCAL_VIEMER,

GL_LIGHT_MODEL_TWO_SIDE, or GL_LIGHT_MODEL_COLOR_CONTROL.

These four parameters refer to the lighting effects discussed at the beginning of this

section respectively. And finally, param specifies the input values for the above.

Page 37: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

The parameter GL_LIGHT_MODEL_AMB I hNT specifies the amount of

ambient light in the scene that doesn't come from a particular source. Other light sources

can also contribute to the amount of ambient light in the scene. This parameter takes an

array of size four, specifying the amount of red, green and blue light, as well as the

intensity of the light. The default values are (0.2, 0.2, 0.2, 1.0).

The parameter GL_LIGHT_MODEL_LOCAL_V1EWER is a Boolean parameter.

This parameter specifies whether the viewer is intended to be local, or an infinite distance

away. A local viewer will involve more complex lighting calculations, than the infinitely

distant viewer. Thus, treating the viewer as though it were an infinite distance away will

increase the performance of the scene, but it will lot look as realistic as if it were a

considered a local viewer. The default value is false, indicating that the viewer should be

considered to be an infinite distance away from the scene.

The next parameter, GL_LIGHT_MODEL_TWO_SIDE is also a Boolean

parameter. In OpenGL, front facing polygons are typically seen, and not the back facing

polygons (section 3.4, pg 8). As a result, in order to increase performance for the front

facing polygons, the lighting for the back facing polygons is not accurate. This parameter

allows you to make the correct lighting calculations for the back facing polygons as well,

at a cost of performance. Many times, the back faces of polygons are never scene. Thus,

the lighting for the back faces of the polygons need not be accurate in the interests of

increasing the performance of your scene. For example, imagine a scene of a simple

36

Page 38: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

cube on the floor. From all viewpoints (except inside the cube) you see the front faces of

the cube. So if you are not planning to move the viewpoint inside the cube, it does not

make sense to have the back faces of the cube properly lit. The default value for this

parameter is false. This means that the back faces are not properly lit.

The final parameter, GL_LIGHT_MODEL_COLOR_CONTROL, is used in

lighting calculations for textures. Lighting is applied to polygons before the textures are

applied. Often times this creates an undesirable-looking scene. This parameter allows

the specular color to be carried over to the texturing process. When this occurs, instead

of the usual one colour per vertex, there are two colours associated with each vertex.

After the textures are applied, this second colour is added to the polygon, creating more

realistic looking specular lighting effects. This second colour is obtained from the

specular objects specular light component (discussed in the next section). The default

value for this parameter is GL_SINGLE_COLOR, which associates only a single colour

per vertex. The value GL_SEPERATE_SPECULAR_COLOR will associate two colours

per vertex, creating a more realistic looking scene.

5.5 Material Properties

Lighting in OpenGL involves many different properties of the light. Another very

important factor on what is seen by the viewer is not only the type of light emitted by the

light source, but also, the properties of the material it is reflecting off of. Just as the

properties of the light can be specified, so can the properties of the materials. There are

37

Page 39: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

five types of material properties that can be set for a surface in OpenGL. To access these

material properties, use the command:

glMaterial{ if } (GLenum face, GLenum pname, TYPE param);

where {if} indicate the data type of the input parameters, face indicates which face of the

current polygon is to acquire these properties (GL_FRONT, GL_BACK, or

GL_PRONT_AND_BACK are the accepted values). pname indicates what material

property is being modified (GL_AMBIENT, GL_DIFFUSE,

GL_AMBIFNT_AND_DIFFUSE, GL_SPECULAR, GL_SHININESS, GL_EMISSION,

and GL_COLOR_INDEXES are the accepted values). param indicates the input values

for the material property to take on.

The ambient parameter above will alter how a surface will reflect the ambient

light in the scene. This parameter determines what the overall colour of the surface will

be. It does not change depending on where the viewer is. The total amount of ambient

light that the surface will reflect is dependent upon the total amount of ambient light in

the scene (i.e. global ambient light, and the ambient light from actual light sources).

The diffuse parameter has many of the same qualities of the ambient reflection

above. The diffuse component of the surface is the most important aspect in determining

what colour of light a surface reflects. This colour is generated by examining the

orientation of the surface and its nounal vectors (section 5.6, pg 39) relative to the light

source(s). Typically, in reality, the ambient and diffuse components of a surface reflect

38

Page 40: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

the same colour of light. It is for that reason that they both can be specified with the one

parameter GL_AMB I HNT_AND DIFFUSE.

Specular reflection is dependent upon the location of the viewer. The specular

light will be brightest when the viewer is at an angle to the surface equal to the incident

angle of light source to the surface. A specified colour will be reflected at different

intensities depending on the location of the viewer. The amount of reflection can be

specified with the parameter GL_SHININESS. This value is a single value from 0.0 to

128.0. The higher shininess value a surface has, the more intense the reflection will be.

Emission refers to a surface radiating its own light. When using this feature for a

surface, the surface will appear to radiate light of a specified colour into the scene. This

will not be the case however. Surfaces that emit light do not contribute in any way to the

amount of light in the scene. To create realistic results, a light should be created with the

same colour as the emission light and placed in the center of the surface. Light sources

on their own are not visible.

5.6 Normal Vectors

Normal vectors are vectors that are perpendicular to a surface. This is not always

true in OpenGL. It is intuitive to think that for any surface created, the normal vectors

should be able to be automatically generated from any three of the points on that surface.

This is assuming that a surface is flat. As stated earlier, truly curved surface cannot be

generated in OpenGL. They must be estimated by combining smaller flat surfaces

39

Page 41: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

(section 3.6, pg 11). OpenGL does not automatically generate normal vectors for a

surface. A normal vector is specified for each vertex of a surface, which do not have to

be the same even though they are on the same plane. The following command specifies

the current noinial vector:

glNormal3 { bsidf}(TYPE nx, TYPE ny, TYPE nz);

where {bsidf} specifies the data type of the input parameters (b = Boolean values, s =

short integer values, I = integer values, d = double precision floating point number

values, and f = single precision floating point number values). The three parameters nx,

ny, and nz represent the normal vector in the form (x, y, z) respectively. The normal

vector specified should be a unit vector — the magnitude of the vector should be equal to

one. All vertices specified after this command will have associated with it this normal

vector.

Normal vectors are used in the OpenGL lighting calculations for a surface. The

OpenGL lighting system examines the normal vector of each vertex on a surface. It then

determines how much light the vertex should have (depending on the orientation of the

normal vector to the light sources in the scene). Once the lighting has been calculated for

each vertex, OpenGL fills the surface, blending from one vertex to the next. The result of

a flat surface which has different normal vectors for each vertex is a surface that appears

to be slightly curved. The following illustration shows the benefits of having different

I

noiinal vectors on a single surface:

40

Page 42: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

I

Same Normal Vectors Different Normal Vectors

Figure 5-1: Two Cylinders with indicated normal vectors for each quadrilateral

The shape on the left has the same noimal vector for each flat surface. The shape on the

right has normal vectors that are different at each vertex. The normal vectors are

specified in such a way that they would be the true normal vectors if the surface were

curved.

5.7 T-Bird Program

5.7.1 Light Properties

There are 8 lights in the T-Bird Lounge program (section 5.3, pg 34). Each light

has the same properties. Each light contributes the RGBA values of (0.12, 0.12, 0.12,

1.0) to the amount of global ambient light. Each light also has a RGBA diffuse

component of (0.05, 0.05, 0.05, 1.0), and a RGBA specular component of (0.2, 0.2, 0.2,

1.0). Each light is enabled using glEnable(GL_LIGHTn); where 0 <= n <= 7. Lighting

is then enabled by using glEnable(GL_LIGHTING);.

Page 43: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

5.7.2 Material Properties

There are different types of materials in the T-Bird Lounge Program. However

most of the surfaces in the lounge possess the same qualities. Therefore most materials

specified have the same relative proportions. The colour of the material was obtained

though actual digital photographs of the scene. The following is an example of the

material settings used for the walls:

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

Where wallMaroon and diffuse are RGBA colours Maroon and a light brown

respectively.

5.7.3 Normal Vectors

Normal vectors are specified for each vertex in the T-Bird Lounge program. For

most of the surfaces, it was a simple mater to decide what the normal vector should be.

Such surfaces would be the surfaces that are parallel to one of the planes of the

coordinate axis (xy-plane, xz-plane, yz-plane).

The normal vectors became more complex when dealing with the approximated

curved surfaces, such as the front face of the Coke Machine, both types of tables and the

chairs. The normal vectors for the Coke Machine were calculated by hand, along with

the normal vectors for the table top of the rectangular tables. The nolinal vectors for the

round table top and the legs of the tables and chairs were all calculated along with

vertices at run time (see appendix A for the calculations).

42

Page 44: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

6.0 Textures in OpenGL

Up until now, if we wanted to create a tiled wall, we would have to create

separate polygons for each tile, and the mortar between the tiles. This would increase the

polygon count extremely quickly, and it would not be long before performance became

an issue for the scene. A wall with tiles can get by with just being a single polygon, with

a picture of tiles placed upon it.

Textures fulfill this role. A texture is a bitmap image that is placed on the face of

a polygon. The bitmap image is broken down into an array of colours. Each element in

that array is called a texel.

6.1 Creating Texture Maps

There are basically four steps in creating a texture map in OpenGL. First, you

must create a texture object, and assign a texture to that object. Secondly, you must

indicate how the texture will be applied. Next, you have to enable texture mapping. And

finally, you have to draw the scene using texture and geometric coordinates.

Textures are traditionally though of as two-dimensional objects. Textures can

also be one-dimensional and three-dimensional. It all depends on the amount of data

represented in each texel. The texture could be in the form of a single value, or it could

have a full set of red, green, blue, and alpha intensity levels associated with each texel.

To enable texture mapping, you must know the highest dimension of texture that will be

I43

Page 45: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

used in your scene. Then, you can call glEnable(texture _mode); where texture_mode can

be GL_TEXTURE_1D, GL_TEXTURE_2D, or GL_TEXTURE_3D.

The texture coordinates range from 0.0 4 1.0 in both directions. The coordinates

of geometric objects can be anything. In order to create the wall of tiles as discussed at

the beginning of this section, you would need to map the texture coordinates (0, 0), (1,0),

(1, 1), and (0, 1) to the four corners of the geometric rectangle where the tiles are to

appear. If the texture is a picture of one tile only, you must indicate that the texture must

be repeated to get the desired effect. If this is going to happen, then the left side of the

texture should appear to be seamless when placed to the right of a copy of itself.

Similarly, the top and bottom should also appear to be seamless.

Before any of the above can be done, a texture must be specified. A two-

dimensional texture can be loaded into memory by using the following command:

glTexImage2D(GLenum target, GLint level, GLint internalFormat,

GLsize width, GLsize height, GLint border,

GLenum format, GLenum type, const GLvoid *texels);

Where target can be either GL_TEXTURE_2D or GL_PROXY_TEXTURE_2D,

depending on whether multiple resolutions of a texture are available (Multiple resolutions

require GL_PROXY_TEXTURE_2D), level indicates the number of different resolutions

there are available minus one. So if there is only one resolution available for a texture,

then the level would be zero. internalFormat is an integer from 1 to 4, or it can be one of

38 symbolic constants. These 38 symbolic constants are then mapped to one of the four

44

Page 46: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

digits. The width and height give the dimensions of the texture image in pixels. Border

indicates the width of the border around the texture. It can be zero (for no border) or 1.

There is a limitation on the size of the texture. Both the height and the width of the

texture must be of the form 2' + 2b where n is an integer greater than or equal to 6 and b

is the value of border. Thus, the minimum size of a texture is 64x64 pixels. format

indicates what colour format the data is in. Accepted values are GL_COLOUR_INDEX,

GL_RGB, GL_RGBA, GL_BGR, GL_BGRA, GL_RED, GL_GREEN, GL_BLUE,

GL ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_STENCIL_INDEX,

and GL_DEPTH_COMPONENT. type indicate what data type the values are in. And

texel contains the data which describes the texture image itself along with its borders.

6.2 T-Bird Lounge Program

Unfortunately, I ran into several problems while trying to load the textures into

memory. Thus, the T-Bird Lounge program does not use this feature.

45

Page 47: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

7.0 Shadows in OpenGL

Shadows are everywhere in the world around us. Thus, in order to create a

realistic scene, one should include shadows. OpenGL does not directly support the

generation of shadows. There are a few techniques that have been developed to create

shadows using OpenGL. Creating a shadow of a simple object over a flat surface would

be relatively easy. Simply figure out which part of the flat surface is hidden from the

light source by the object, and draw that region in a dark shade. The task becomes a little

more complex when the shadow is being projected onto a surface which is not flat, or

there are a number of irregular objects in the scene casting shadows. Ideally, every

surface would be considered to be a surface that casts a shadow, and a surface on which a

shadow can be cast. But what if there are multiple light sources? The task of creating

shadows can become computationally complex quite quickly.

7.1 Static Shadows

Static shadows provide the mean to avoid the complexities of shadow

computation at runtime. Instead, the shadows are generated in advance. Since the

shadows are generated in advance, the most realistic model possible can be used. It may

take longer to compute, but it only needs to be calculated once. The shadows that are

generated can be applied to the textures, thus eliminating the need to do real-time shadow

calculations. The shadows generated using this technique often does not look real. They

do not change as light sources move, or as the viewer moves, thus the name static.

46

Page 48: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

7.2 Projective Shadows

Projective shadows allow the projection of a shadow into a plane. The basic

concept is to project the object which is casting the shadow onto a plane from the

perspective of that light source. The object is then drawn in a dark (perhaps black)

colour. A shadow effect is created. This method of creating shadows produces fairly

accurate results.

In order to facilitate this projection, a transformation matrix must be used. The

matrix must take into account the location of the light and plane on to which the shadow

is being cast. This is the transformation matrix required:

clot — lightPos[0] * plane.a

- lightPos[0] * plane.b

- lightPos[0] * plane.c

- lightPos[0] * plane.d

- lightPos[1] * plane.a

dot — lightPos[1] * plane.b

- lightPos[1] * plane.c

- lightPos[1] * plane.d

- lightPos[2] * plane.a

- lightPos[2] * plane.b

dot — lightPos[2] * plane.c

- lightPos[2] * plane.d

- lightPos[3] * plane.a

- lightPos[3] * plane.b

- lightPos[3] * plane.c

dot — lightPos[3] * plane.d

Where "dot" is the dot product of the light position and the plane, lightPos is the position

of the light (x, y, z, and w) (section 5.3, pg 34), plane is a data structure in which a, b, c,

and d are from the equation ax + by + cz + d = 0.

Now, the object in which is casting the shadow must be transformed using this

matrix. Once the projection has occurred, the object casting the shadow will now appear

flat and on the plane. It then needs to be drawn in black or a darker shade to simulate the

effect of a shadow. Since the projected shadow will be on the same plane as the plane

itself, holes may appear in the shadow due to the depth buffer used in removing hidden

47

Page 49: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

surfaces. To overcome this, simply disable the depth test, and make sure that it is re-

enabled after the shadow has been drawn. This technique can then be repeated for any

other surfaces that cast shadows, or any other light sources. Using this technique requires

an entire pass though of the geometry in your scene for each object casting a shadow. It

must be done again if there is another light source. The computational costs of this

technique are doubled for each new object casting a shadow and light source, and thus

can become quite demanding quite quickly.

This technique does not generate perfect results either. The surface onto which

the shadow is being cast still possesses specular reflection over the shadow, which

shouldn't occur. Also, unless every polygon is treated as a shadow casting object, certain

shadows will be left out on the object itself.

7.3 Stenciled Shadow Volumes

Stenciled shadow volumes produce the best shadows, but until recently, they were

too computationally intense for real-time rendering. This method correctly shadows

every object in the scene. The basic idea of this type of shadow generation is that you

project lines from the light source through the edges of the objects in the scene, which

creates an infinitely large volume on the other side of the object. Now that you have this

new shadow volume behind the object, look for any objects and or points that lie within

that shadow volume and darken that area.

48

Page 50: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

The portion of this algorithm that is the most demanding computationally is the

defining of the shadow volumes. A shadow volume is generated from silhouette edges of

an object. A silhouette edge is joint between two polygons where one is front-facing and

the other is back-facing (section 3.4, pg 8). This requires that every edge in the scene be

tested for this silhouette quality. Once they have all been found, the vertices that define

the edge have lines drawn through them from the light source, thus creating an infinite

shadow volume behind the object.

Now every object in the scene must be tested to see if it lies inside a shadow

volume. This is done by drawing new lines from the light source to the object in

question. Every time the line enters a shadow volume, you increment a counter. Every

time the line leaves a shadow volume, you decrement the counter. If at the end, the

counter is greater than zero, then that point on the object lies within a shadow volume,

and thus is in a shadow. This shadow algorithm requires several passes through the entire

geometry of the scene after all the shadow volumes have been created, and thus is very

demanding.

7.4 T-Bird Program

Unfortunately, there was insufficient time to apply any of the above techniques

for shadows. There are no shadows in the T-Bird Lounge program.

49

Page 51: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

8.0 T-Bird Lounge Program (Everything Else)

To demonstrate most of the features mentioned above, I began creating a scale

model of the T-Bird Lounge, which is the student lounge at Algoma University College

in Sault Ste. Marie, Ontario, Canada. For a full copy of the source code, please consult

Appendix A. Many features of the program were discussed already, but others were not.

8.1 Data Gathering

One of the most tedious tasks in creating this model was the process of gathering

my input data. I spent many Saturdays and Sundays in the T-Bird Lounge measuring out

the walls, the windows, the doors, the trim along the walls, the coke machine, the tables

and chairs, etc... I have on the order of 30 sheets of free-hand schematic drawings of

individual parts of the lounge. All the measurements were taken in centimeters with a

measuring tape. I often required assistance in measuring out certain large walls or large

objects.

After all the measurements were taken, the wall, window and pillar measurements

needed to be mapped onto a stationary coordinate system. This process was extremely

tedious. As one can see by looking at the data in the T-Bird Lounge program source

code, there is an enormous amount of vertex data there. This process took

overwhelmingly long.

50

Page 52: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Another form of data gathering was the digital photographs I took of the lounge.

Although textures were barely used in the program, these photographs provided me with

a consistent view of what the colours of certain objects were. The photographs were

picked apart, and a small portion of an object was examined. The remaining colour in

that region was blended together until it was one solid colour (and average colour). The

RGB values of that colour were recorded and used in the program.

Unfortunately, there was no real way to measure the physical material properties

of the objects in the scene other than looking at them. In most cases it was hard to see

any difference at all.

8.2 Manual

The following is a set of operator's instructions on how to use the T-Bird Lounge

program:

To run the program, you must have the GLUT DLL files. They are available for

free on the internet. It is currently compiled to run on a Microsoft Windows system.

In order to move around the lounge, simply use the arrow keys beside the keypad.

To look up, press the "Page Up" key. To look down, press the "Page Down" key. To

reset your viewing angle so that you are viewing parallel to the horizon, hit the "End"

key.

51

Page 53: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

There are also a few toggle buttons in the program. They activate and deactivate

certain OpenGL state variables. Hitting the "w" key will transform the lounge into wire

frame mode. Only the edges of polygons are visible. Hitting it again will return it to the

normal filled mode. Hitting the "c" key will enable/disable culling (section 3.4, pg).

This feature is noticeable when standing outside of the lounge, inside an object or in wire

frame mode.

8.3 Program Layout

The main body of an OpenGL program is quite simple. The following is the main

function of my simulation of the T-Bird lounge:

int main(int argc, char** argv)

glutlnit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE I GLUT_RGB I GLUT_DEPTH);glutInitWindowSize(800, 600);glutInitWindowPosition(0, 0);glutCreateWindow(argv[0]);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutSpecialFunc(processSpecialKeys);glutKeyboardFunc(keyboard);glutMainLoop();return 0;

}

As you can see, the main function is quite concise, and is dominated by GLUT

commands. "glutlnit (&argc, argv) ;" initializes the GLUT system. It checks to see

if the windows system is compatible with OpenGL. It also processes command line

arguments. "glutlnitDisplayMode(GLUT_DOUBLE 1 GLUT_RGB I GLUT_DEPTH);"

sets up the program with a double display buffer, in RGB colour mode, and also with a

depth buffer. "glutInitWindowSize (800, 600) ; " sets the window size to 800 pixels in

52

Page 54: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

width by 600 pixels in height. "glutInitWindowPosition ( 0 , 0 ) ; " indicates the height

and width offset from the top left hand corner of the screen which the new window will

be placed. "glutCreateWindow (argv [ ) ;" actually creates the window with the title

of the name of the program being run. The "init ( ) ;" function sets up the state variables

that are going to be used in the program.

"glutDisplayFunc (display) ;" indicates which function contains the geometric

data to draw the scene (the function is "display()"). "glutReshapeFunc (reshape) ;"

indicates which function to call when the window is resized (the function is "reshape()").

"glutSpecialFunc (processSpecialKeys) ;" indicates which function to call when

there is a special key pushed (the function is "proccessSpecialKeys()"). Special keys

include the arrow keys, the keypad, and the function keys.

"glutKeyboardFunc (keyboard) ; " indicates which function to call when a normal key is

pressed on the keyboard (the function is "keyboard()"). Normal keys include the alpha-

numeric characters. "glutMainLoop ( ) ;" starts the GLUT event processing loop. This

loop will continue to monitor the functions after the "initQ" function for events. It will

continue to redraw the scene as often as it can, processing any events that occur on the

way.

8.4 Program Functions

The following is a list of all the functions in the T-Bird Lounge program. They

are listed in the order in which they appear.

53

Page 55: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

void nor Jirection(void)

This function involves the viewing of the scene. It normalizes the distance

between the location of the camera and the direction in which the camera is

pointing. The result of calling this function is that the camera and the location of

the point it is pointing to (the direction array) are 1 unit apart. (For more detail,

please consult the source code, this function is on page 66)

void forward(void)

This function moves the viewer forward. It is explained in more detail in section

4.7.2 (pg 29).

void backward(void)

This function moves the viewer forward. It is explained in more detail in section

4.7.2 (pg 29).

void xRectangle(GLfloat x, GLfloat yl, GLfloat zl,GLfloat y2, GLfloat z2, GLint normDir)

This function draws a rectangle with a constant x value. That is, it is parallel to

the y-z plane. It draws the rectangle using a quadrilateral (GL_QUADS). The

value of normDir indicates whether the normal for this rectangle is in the positive

or negative x direction. Depending on this value, the vertices are specified in the

correct order to make the front face of the quadrilateral face the inside of the

room. (for more detail, please consult the source code, this function is on page

67)

Page 56: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

void yRectangle(GLfloat xl, GLfloat y, GLfloat zl,GLfloat x2, GLfloat z2, GLint normDir)

This function draws a rectangle with a constant y value. That is, it is parallel to

the x-z plane. It draws the rectangle using a quadrilateral (GL_QUADS). The

value of normDir indicates whether the normal for this rectangle is in the positive

or negative y direction. Depending on this value, the vertices are specified in the

correct order to make the front face of the quadrilateral face the inside of the

room. (For more detail, please consult the source code, this function is on page

68)

void zRectangle(GLfloat xl, GLfloat yl, GLfloat z,GLfloat x2, GLfloat y2, GLint normDir)

This function draws a rectangle with a constant z value. That is, it is parallel to

the x-y plane. It draws the rectangle using a quadrilateral (GL_QUADS). The

value of normDir indicates whether the normal for this rectangle is in the positive

or negative z direction. Depending on this value, the vertices are specified in the

I correct order to make the front face of the quadrilateral face the inside of the

I room. (For more detail, please consult the source code, this function is on page

68)

I

void cylender(GLfloat radius, GLfloat theta, GLfloat height)

This function creates a cylinder with a radius specified. The cylinder starts at the

origin and travels a distance height up the z-axis. The value of theta specifies the

angle of each flat portion of the cylinder. Theta must divide 360 evenly to

produce the desired effect. This function calculates all of the vertices using the

55

Page 57: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

a1U

1aI

U

given infaunation. It also calculates the appropriate noimal vectors to produce a

correctly lit approximated curved surface (see figure 8-1). (For more detail,

please consult the source code, this function is on page 68)

Figure 8-1: Cylinder Function

void pillar (GLfloat x, GLfloat y)

This function creates a pillar using the rectangle functions above. The

coordinates specified indicate the south-west corner of the pillar (see figure 8-2).

(For more detail, please consult the source code, this function is on page 69)

Figure 8-2: Pillar Function

Page 58: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

void windowl(GLfloat x)

This function creates a window sill for the south wall. It includes the window

frame as well. The given x value specifies the western most point on the window

sill. By definition of a window sill on the south wall, it has a y value of 100 at the

wall. (For more detail, please consult the source code, this function is on page 70)

void window2(GLfloat x)

This function creates a window sill for the north wall. It includes the window

frame as well. The given x value specifies the western most point on the window

sill. By definition of a window sill on the north wall, it has a y value of 1124 at

the wall. (For more detail, please consult the source code, this function is on page

70)

void foosBall()

This function creates a foosball table about the origin. It is made up of

quadrilaterals. (For more detail, please consult the source code, this function is on

page 71)

void rectTableLeg()

This function creates a leg for the rectangular table about the origin. This

function uses the cylinder function for the leg itself, and quadrilaterals for the

footing. (For more detail, please consult the source code, this function is on page

71)

57

Page 59: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

void recTable ( )

This function constructs a rectangular table about the origin. It uses the function

rectTableLeg twice in order to construct the legs of the table. This table top was

the most mentally challenging to map out and specify normal vectors for. The

values for this table top are not calculated by the program. The round edge on

this table is an example of curved surface approximation (see figure 8-3). (For

more detail, please consult the source code, this function is on page 72)

Figure 8-3: recTable Function

void roundTable ( )

This function creates a round table about the origin. This table is the only object

in the lounge in which the vertices are calculated by the program. The table top is

constructed of a triangle fan (GL_TRIANGLEFAN). The edges of the table top

are quadrilaterals. The Normal vectors for this object were also entirely generated

by the program. The leg supporting the table top was made using the cylinder

function. The base is also a triangle fan (see figure 8-4). (For more detail, please

consult the source code, this function is on page 77)

58

Page 60: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Figure 8-4: roundtable Function

void chair ( )

This function creates a chair about the origin. This function has two polygons as

the seat of the chair. The top of the back rest is made of quadrilaterals. The rest

of the chair is built using cylinders. This function required extensive use of the

modelview matrix stack, and modelview transfoimations (see figure 8-5). (For

more detail, please consult the source code, this function is on page 81)

Figure 8-5: Chair Function

59

Page 61: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

void bigTV ( )

This function creates a large projection television and a stand about the origin.

This function uses the rectangle functions, as well as quadrilaterals for the back of

the television (see figure 8-6). (For more detail, please consult the source code,

this function is on page 85)

Figure 8-6: bigTV Function

void init (void)

This function sets up all of the OpenGL state variables that are required for the

rendering of the scene. It includes the definitions of the lights as well. (For more

detail, please consult the source code, this function is on page 85)

void display (void)

This is the function that draws either draws the geometry itself or calls a function

that draws the geometry. The geometry that this function draws on its own are all

the walls, the ceiling and the floor. It also constructs the doorways, the stage, and

60

Page 62: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

the Coke Machine. This function makes hundreds of calls to the rectangle

functions, the pillar function 8 times, the window functions 8 times, the

rectangular table function 3 times, the round table function 7 times, the chair

function 45 times and the foosball table and television functions once. This

function also makes tremendous use of the modelview matrix stack along with

modelview transformations. (For more detail, please consult the source code, this

function is on page 87)

void reshape(int w, int h)

This function is responsible for resizing the viewport whenever the window is

resized. If the viewport does not maintain the same aspect ratio as the perspective

setting, there will be some visual distortion. Thus this function maintains the

same aspect ration throughout. (For more detail, please consult the source code,

this function is on page 109)

void processSpecialKeys(int key, int x, int y)

This function processes the special key events. This function calls the forward

and backward functions. It also contains the algorithms for turning to the left and

to the right, and to rotate up and down as well. It also contains event function to

level off the viewing angle. This function makes several calls to normDirection().

(For more detail, please consult the source code, this function is on page 109)

void keyboard( unsigned char key, int x, int y )

This function processes regular keyboard stroke events. This function is

responsible for toggling culling and wire frame modes. (For more detail, please

consult the source code, this function is on page 110)

61

Page 63: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

9.0 Conclusions

Creating a realistic three-dimensional map is an extremely complex task. One

cannot learn the intricacies of OpenGL and expect to create realistic scenery without

investing extremely large amounts of time. I would estimate, that given another year, I

could generate a realistic model of the T-Bird Lounge.

There were a few key features that were not included in the T-Bird lounge

program that would have improved the appearance of the map — Textures and shadows.

Unfortunately, both of these features needed more time to reveal their secrets to me.

One of the hardest parts of the program was the data gathering and the data entry.

This process took the most time by far. As you can see by the amount of geometric data

that is involved in creating such a scene is enormous. Since there is such a vast amount

of data to be entered, I suggest using a rapid prototype approach to creating the map.

Create a program that runs, and then start adding geometric data. After a small amount of

data entry, recompile the program and double check your work. It is extremely easy to

mix up the order of the vertices or place a negative sign on a normal that should not have

one. That being said, I do not suggest creating a simple program that runs and then try to

add features such as texturing or shadows afterwards. The program should be ready to

handle all the features you plan to throw at it before you start the rapid prototyping

process. Also, a GUI would also increase the speed of data entry. Unfortunately, from

62

Page 64: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

what I've experienced in writing this thesis, creating such an interface would be vastly

more complex then this program.

I am pleased with the progress I have made. I now understand why it takes large

development teams a long time to create graphic intensive software.

63

Page 65: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

p

p

10.0 Bibliography

Books:

OpenGL Programming Guide, third editionAuthors: Mason Woo, Jackie Neider, Tom Davis, Dave ShreinerPublished by: Addison-Wesley in the year 1999

OpenGL Reference Manual, third editionEditor: Dave ShreinerPublished by: Addison-Wesley in the year 2000

OpenGL Game ProgrammingAuthors: Kevin Hawkins, Dave Astle, Andre LaMontePublished by: Prima Publishing in the year 2001

C++, How To Program, second editionAuthors: Deitel and DeitelPublished by: Prentice Hall in the year 1998

Elementary Linear Algebra, fifth editionAuthors: Stanley L. GrossmanPublished by: Saunders College Publishing in the year 1994

Fundamentals Of Physics Extended, fifth editionAuthors: Halladay, Resnick, WalkerPublished by: Wiley in the year 1997

Websites:

GLUT API Commandshttp://www.tangentorg/—brian/dict/spec3/node113.html

Core Lighting Effects Library Moduleshtt ://www—hoff/lighting effects/docs/lighting effects.html

math.hhttp://www.opengroup.org/onlinepubs/7908799/xsh/math.h.html

NeHe Productions Online Forumhttp://www.gamedev.net/community/forums/forum.asp?forum id=27&forum title=NeHe+Productions

64

Page 66: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

NeHe Productions (OpenGL Tutorials)http://nehe.gamedev.net/

Official OpenGL Website:http://www.opengl.org/

OpenGL Tutorial — State Variableshttp://www.eecs.tulane.edu/www/Terry/OpenGL/Changing State.html

OpenGL.org Discussion and Help Forumshttp://www.opengl.org/discussion boards/cgi directory/Ultimate.cgi?action=intro&B ypassCookie=true

SGI — Programming with OpenGLhttp://www.sgi.com/software/opengl/advanced96/programs.html

Yindo Window Management Libraryhttp://www.yindo.com/docs/runtime/Glut.html

65

Page 67: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Appendix A

The following is the source code for the T-Bird Lounge program (to obtain thesource code for this file and/or to view screenshots of the program please visit:"http://members .shaw .ca/onemanclan/tbird.html "):

// T-Bird Lounge Program By Dan Hooper - Modified April 1st, 2002

#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <GL/gl.h>#include <GL/glu.h>#include <GL/glut.h>#include <math.h>

const double pi = 3.14159265358979323846;

//PiGLboolean wireframe = GL_FALSE;

//Boolean Value to signal wire frame mode.

static GLfloat camera[3] = {0.0, 0.0, 180.0)static GLfloat direction[3] = {1000.0, 500.0pointing.static GLfloat up[3] = {0.0, 0.0, 1.0);static GLfloat temp[3];

//Used for moving about map.

, 180.0);//Position of the camera.//The Direction the camera

//Which direction is up.

i s

const GLfloat zCheck = 0.01;point straight up or down.const GLfloat strafeMult = 1.5;const GLfloat turnMult = 0.1;

float LightAmb[] = {0.12, 0.12, 0.12, 1.0);float LightDiff] = {0.05, 0.05, 0.05, 1.0);float LightSpc[] = {0.2, 0.2, 0.2, 1.0);

float MatAmb[] = {0.4, 0.4, 0.4, 1.0);float MatDif[] = {0.6, 0.6, 0.6, 1.0);float MatSpc[] = {0.0, 0.0, 0.0, 1.0);float MatShn[] = (0.0);

float wallMaroon[] = {0.5234, 0.1797, 0.2266, 1.0);float floorBrown[] = {0.6328, 0.5664, 0.4961);float ceilingGrey[] = {0.7063, 0.7297, 0.7219);float doorFrameMaroon[] = {0.5039, 0.3398, 0.2930);float doorMaroon[] = {0.3359, 0.1484, 0.1484);float tvStandGreen[] = {0.1602, 0.4570, 0.3398);float diffuse[] = {0.5, 0.4, 0.3, 1.0);

//Used to make sure you dont

//Strafe Multiplier.//Turn Multiplier.

Ambient Light Values

0.8Diffuse Light Values 0.6Specular Light Values

// Material - Ambient Values// Material - Diffuse Values// Material - Specular Values// Material - Shininess

/ / Maroon colour of the walls// Brown Colour of the floor tiles// Grey colour of the Ceiling Tiles/ / Maroon colour door frames// Maroon colour of the main doors// Green colour of the TV stand

float red[] =float blue[] =float green[] =float cyan[] =float brown[] =float grey[] =float ltgrey[] =

{0.7109, 0.1719, 0.0703, 1.0);{0.0, 1.0, 0.0, 1.0);

{0.0, 0.0, 1.0, 1.0);{0.0, 1.0, 1.0, 1.0);

{0.6406, 0.5781, 0.4883, 1.0 );{0.0, 0.0, 0.0, 1.0);{0.5, 0.5, 0.5, 1.0);

void normDirection(void)

// Make sure direction vector is normalized.

GLfloat magnitude;

temp[0] = direction [0] - camera[0];temp[1] = direction [1] - camera[1];temp[2] = direction [2] - camera[2];

magnitude = sqrt((temp[0] * temp[0]) + (temp[1] * temp[1]) + (temp[2] * temp[2]));

66

Page 68: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

direction[0] = camera[0] + (temp[0]/magnitude);direction[1] = camera[1] + (temp[1]/magnitude);direction[2] = camera[2] + (temp[2]/magnitude);

void forward(void)

temp[0] = direction[0];temp[1] = direction[1];temp[2] = direction[2];

direction[0] = direction[0] + (direction[0] - camera[0]);direction[1] = direction[1] + (direction[1] - camera[1]);direction[2] = direction[2] + (direction[2] - camera[2]);

camera[0] = temp[0];camera[1] = temp[1];camera[2] = temp[2];

// direction[2] = camera[2];

normDirection();glLoadIdentity();glutPostRedisplay();

void backward(void)

temp[0] = camera[0];temp[1] = camera[1];temp[2] = camera[2];

camera[0] = camera[0] - (direction[0] camera[0]);camera[1] = camera[1] - (direction[1] camera[1]);camera[2] = camera[2] - (direction[2] - camera[2]);

direction[0] = temp[0];direction[1] = temp[1];direction[2] = temp[2];

normDirection();glLoadIdentity();glutPostRedisplay();

void xRectangle(GLfloat x, GLfloat y1, GLfloat zl,{// Creates a rectangle parallel to the y-z plane.

GLfloat temp;if(yl > y2)

temp = yl;yl = y2;y2 = temp;

if(zl > z2)

temp = zl;zl = z2;z2 = temp;

if(normDir < 0){

temp = yl;yl = y2;y2 = temp;

}glBegin(GL_QUADS);

GLfloat y2, GLfloat z2, GLint normDir)

67

Page 69: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glNormal3f(1.0 * normDir, 0.0, 0.0);glVertex3f(x, yl, zl);glVertex3f(x, y2, zl);glVertex3f(x, y2, z2);glVertex3f(x, yl, z2);

glEnd();

void yRectangle(GLfloat x1, GLfloat y, GLfloat zl, GLfloat x2, GLfloat z2, GLint normDir)

// Creates a rectangle parallel to the x-z plane.GLfloat temp;if(xl > x2)

temp = xl;xl = x2;x2 = temp;

if(zl > z2)

temp = zl;zl = z2;z2 = temp;

if(normDir < 0)

temp = x1;xl = x2;x2 = temp;

glBegin(GL_QUADS);glNormal3f(0.0, 1 0 * normDir, 0.0);glVertex3f(xl, y, zl);glVertex3f(xl, y, z2);glVertex3f(x2, y, z2);glVertex3f(x2, y, zl);

glEnd();

void zRectangle(GLfloat x1, GLfloat y1, GLfloat z, GLfloat x2, GLfloat y2, GLint normDir)

// Creates a rectangle parallel to the x-y plane.GLfloat temp;if(xl > x2)

temp = xl;xl = x2;x2 = temp;

if(yl > y2)

temp = yl;yl = y2;y2 = temp;

if(normDir < 0)

temp = xl;xl = x2;x2 = temp;

glBegin(GL_QUADS);glNormal3f(0.0, 0.0, 1.0 * normDir);glVertex3f(xl, yl, z);glVertex3f(x2, yl, z);glVertex3f(x2, y2, z);glVertex3f(xl, y2, z);

glEnd();

void cylender(GLfloat radius, GLfloat theta, GLfloat height)

68

Page 70: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

// Creates a Cylender with radius, and height. Theta is the angle between polygonedges.// Creates the cylender at the origin, pointing in the positive Z direction.

theta = theta * pi / 180.0;

GLfloat currentAngle = 0.0;GLfloat magnitude;GLfloat Normal[3];GLfloat xTemp;GLfloat yTemp;

while (currentAngle <= 2 * pi)

glBegin(GL_QUADS);xTemp = cos(currentAngle)*(radius);yTemp = sin(currentAngle)*(radius);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = 0.0;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;

//

Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, height);glVertex3f(xTemp, yTemp, 0.0);

xTemp = cos(currentAngle + theta)*(radius);yTemp = sin(currentAngle + theta)*(radius);Normal[0] = xTemp;Normal[l] = yTemp;Normal[2] = 0.0;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;

//

Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 0.0);glVertex3f(xTemp, yTemp, height);

glEnd();currentAngle = currentAngle + theta;

}

void pillar(GLfloat x, GLfloat y)

// Creates a pillar given x and y coordinates

xRectangle(x - 2.0, y - 2.0, 0.0, y + 31.0, 5.0, -1 );yRectangle(x - 2.0, y + 31.0, 0.0, x + 31.0, 5.0, 1);xRectangle(x + 31.0, y + 31.0, 0.0, y - 2.0, 5.0, 1);yRectangle(x + 31.0, y - 2.0, 0.0, x - 2.0, 5.0, -1);zRectangle(x - 2.0, y - 2.0, 5.0, x + 31.0, y + 31.0, 1);

xRectangle(x - 2.0, y - 2.0, 216.0, y + 31.0, 221.0, -1);yRectangle(x - 2.0, y + 31.0, 216.0, x + 31.0, 221.0, 1);xRectangle(x + 31.0, y + 31.0, 216.0, y - 2.0, 221.0, 1);yRectangle(x + 31.0, y - 2.0, 216.0, x - 2.0, 221.0, - 1);zRectangle(x - 2.0, y - 2.0, 221.0, x + 31.0, y + 31.0, 1);zRectangle(x - 2.0, y - 2.0, 216.0, x + 31.0, y + 31.0, -1);

xRectangle(x, y, 5.0, y + 2.0, 216.0, -1);yRectangle(x, y + 2.0, 5.0, x + 1.0, 216.0, 1);xRectangle(x + 1.0, y + 1.0, 5.0, y + 27.0, 216.0, -1);yRectangle(x, y + 27.0, 5.0, x + 1.0, 216.0, -1);xRectangle(x, y + 27.0, 5.0, y + 29.0, 216.0, - 1);

yRectangle(x, y + 29.0, 5.0, x + 2.0, 216.0, 1);xRectangle(x + 2.0, y + 29.0, 5.0, y + 28.0, 216.0, 1);yRectangle(x + 2.0, y + 28.0, 5.0, x + 27.0, 216.0, 1);

69

Page 71: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

xRectangle(x + 27.0, y + 28.0, 5.0, y + 29.0, 216.0, -1);yRectangle(x + 27.0, y + 29.0, 5.0, x + 29.0, 216.0, 1);

xRectangle(x +yRectangle(x +xRectangle(x +yRectangle(x +xRectangle(x +

29.0, y + 29.0, 5.0, y + 27.0, 216.0, 1);29.0, y + 27.0, 5.0, x + 28.0, 216.0, -1);28.0, y + 27.0, 5.0, y + 2.0, 216.0, 1);28.0, y + 2.0, 5.0, x + 29.0, 216.0, 1);29.0, y + 2.0, 5.0, y, 216.0, 1);

yRectangle(x + 29.0, y, 5.0, x + 27.0, 216.0, -1);xRectangle(x + 27.0, y, 5.0, y + 1.0, 216.0, -1);yRectangle(x + 27.0, y + 1.0, 5.0, x + 2.0, 216.0, -1);xRectangle(x + 2.0, y + 1.0, 5.0, y, 216.0, 1);yRectangle(x + 2.0, y, 5.0, x, 216.0, -1);

void windowl(GLfloat x)

//

Create Window sill for Windows on south wall. Y co-ord = 100 by definition.zRectangle(x, 100.0, 101.0, x + 98.0, 32.0, 1);xRectangle(x, 100.0, 101.0, 65.0, 245.0, 1);yRectangle(x, 65.0, 101.0, x + 3.0, 245.0, 1);xRectangle(x + 3.0, 65.0, 101.0, 32.0, 245.0, 1);glMaterialfv(GL_FRONT, GL_AMBIENT, doorMaroon);

yRectangle(x + 3.0, 33.0, 101.0, x + 95, 107.0, 1);yRectangle(x + 3.0, 33.0, 107.0, x + 9.0, 147.0, 1);yRectangle(x + 3.0, 33.0, 147.0, x + 95, 155.0, 1);yRectangle(x + 89.0, 33.0, 107.0, x + 95.0, 147.0, 1);yRectangle(x + 3.0, 32.0, 155.0, x + 6.0, 242.0, 1);yRectangle(x + 3.0, 32.0, 242.0, x + 95.0, 245.0, 1);yRectangle(x + 92.0, 32.0, 155.0, x + 95.0, 242.0, 1);

zRectangle(x + 9.0, 33.0, 107.0, x + 89.0, 32.0, 1);xRectangle(x + 9.0, 33.0, 107.0, 32.0, 147.0, 1);zRectangle(x + 9.0, 33.0, 147.0, x + 89.0, 32.0, -1);xRectangle(x + 89.0, 33.0, 107.0, 32.0, 147.0, -1);

zRectangle(x + 3.0, 33.0, 155.0, x + 95.0, 31.0, 1);xRectangle(x + 6.0, 32.0, 155.0, 31.0, 242.0, 1);zRectangle(x + 6.0, 32.0, 242.0, x + 92.0, 31.0, -1);xRectangle(x + 92.0, 32.0, 155.0, 31.0, 242.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);xRectangle(x + 98.0, 100.0, 101.0, 65.0, 245.0, -1);yRectangle(x + 98.0, 65.0, 101.0, x + 95.0, 245.0, 1);xRectangle(x + 95.0, 65.0, 101.0, 32.0, 245.0, -1);

void window2(GLfloat x)

//

Create Window sill for windows on North wall. Y co-ord = 1124 by definition.xRectangle(x, 1124 0, 94.0, 1187.0, 245.0, 1);xRectangle(x + 90.0, 1124.0, 94.0, 1187.0, 245.0, -1);zRectangle(x, 1124.0, 94.0, x + 90.0, 1187.0, 1);

glMaterialfv(GL_FRONT, GL_AMBIENT, doorMaroon);

yRectangle(x, 1186.0, 94.0, x + 90.0, 100.0, -1);yRectangle(x, 1186.0, 100.0, x + 6.0, 140.0, -1);yRectangle(x, 1186.0, 140.0, x + 90.0, 148.0, -1);yRectangle(x + 84.0, 1186.0, 100.0, x + 90.0, 140.0, -1);yRectangle(x, 1187.0, 148.0, x + 3.0, 242.0, -1);yRectangle(x, 1187.0, 242.0, x + 90.0, 245.0, -1);yRectangle(x + 87, 1187.0, 148.0, x + 90.0, 242.0, -1);

zRectangle(x + 6.0, 1186.0, 100.0, x + 84.0, 1187.0, 1);

70

Page 72: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

xRectangle(x + 6.0, 1186.0, 100.0, 1187.0, 140.0, 1);zRectangle(x + 6.0, 1186.0, 140.0, x + 84.0, 1187.0, -1);xRectangle(x + 84.0, 1186.0, 100.0, 1187.0, 140.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);

zRectangle(x, 1186.0, 148.0, x + 90.0, 1188.0, 1);xRectangle(x + 3.0, 1187.0, 148.0, 1188.0, 242.0, 1);zRectangle(x + 3.0, 1187.0, 242.0, x + 87.0, 1188.0, - 1);xRectangle(x + 87.0, 1187.0, 148.0, 1188.0, 242.0, -1);

void foosBall()

//

Draw a Foosball table at the origin.//LegsxRectangle(0.0, 0.0, 0.0, 10.0, 51.0, -1);yRectangle(0.0, 0.0, 0.0, 10.0, 51.0, -1);xRectangle(10.0, 0.0, 0.0, 10.0, 51.0, 1);yRectangle(0.0, 10.0, 0.0, 10.0, 51.0, 1);

xRectangle(0.0, 131.0, 0.0, 141.0, 51.0, -1);yRectangle(0.0, 131.0, 0.0, 10.0, 51.0, -1);xRectangle(10.0, 131.0, 0.0, 141.0, 51.0, 1);yRectangle(0.0, 141.0, 0.0, 10.0, 51.0, 1);

xRectangle(66.0, 0.0, 0.0, 10.0, 51.0, -1);yRectangle(66.0, 0.0, 0.0, 76.0, 51.0, -1);xRectangle(76.0, 0.0, 0.0, 10.0, 51.0, 1);yRectangle(66.0, 10.0, 0.0, 76.0, 51.0, 1);

xRectangle(66.0, 131.0, 0.0, 141.0, 51.0, -1);yRectangle(66.0, 131.0, 0.0, 76.0, 51.0, -1);xRectangle(76.0, 131.0, 0.0, 141.0, 51.0, 1);yRectangle(66.0, 141.0, 0.0, 76.0, 51.0, 1);

//Main BodyzRectangle(0.0, 0.0, 51.0, 76.0, 141.0, -1);xRectangle(0.0, 0.0, 51.0, 141.0, 92.0, -1);yRectangle(0.0, 0.0, 51.0, 76.0, 83.0, -1);xRectangle(76.0, 0.0, 51.0, 141.0, 92.0, 1);yRectangle(0.0, 141.0, 51.0, 76.0, 92.0, 1);zRectangle(0.0, 0.0, 92.0, 4.0, 141.0, 1);zRectangle(4.0, 0.0, 92.0, 72.0, 11.0, 1);zRectangle(72.0, 0.0, 92.0, 76.0, 141.0, 1);zRectangle(4.0, 130.0, 92.0, 72.0, 141.0, 1);

xRectangle(4.0, 11.0, 82.0, 130.0, 92.0, 1);yRectangle(4.0, 11.0, 82.0, 72.0, 92.0, 1);xRectangle(72.0, 11.0, 82.0, 130.0, 92.0, -1);yRectangle(4.0, 130.0, 82.0, 72.0, 92.0, -1);zRectangle(4.0, 11.0, 82.0, 72.0, 130.0, 1);

xRectangle(0.0, -12.0, 83.0, 0.0, 92.0, -1);yRectangle(0.0, -12.0, 83.0, 76.0, 92.0, -1);xRectangle(76.0, -12.0, 83.0, 0.0, 92.0, 1);zRectangle(0.0, -12.0, 83.0, 76.0, 0.0, -1);zRectangle(0.0, -12.0, 92.0, 76.0, 0.0, 1);

void rectTableLeg()

//

Draws a leg for the rectangular table about the origin.glMaterialfv(GL_FRONT, GL_AMBIENT, grey);xRectangle(-2.5, -33.0, 0.0, 33.0, 2.0, -1);yRectangle(-2.5, -33.0, 0.0, 2.5, 2.0, -1);xRectangle(2.5, -33.0, 0.0, 33.0, 2.0, 1);yRectangle(-2.5, 33.0, 0.0, 2.5, 2.0, 1);zRectangle(-2.5, -33.0, 2.0, 2.5, 33.0, 1);

glPushMatrix();

Page 73: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glTranslatef(0.0, 0.0, 2.0);cylender(2.5, 36.0, 69.0);glPopMatrix();

void recTable()

// Draws a rectangular table at the origin.glMaterialfv(GL_FRONT, GL_AMBIENT, brown);

73.5, -1);73.5, 1);

glBegin(GL_QUADS);//Edge from (1.5, 1.5) --> (1.5, 73.5)glNormal3f(0.0, 0.0, 1.0);glVertex3f(1.5, 1.5, 74.0);glVertex3f(1.5, 73.5, 74.0);glNormal3f(-0.7071, 0.0, 0.7071);glVertex3f(0.3594, 73.5, 73.6406);glVertex3f(0.3594, 1.5, 73.6406);

glVertex3f(0.3594, 1.5, 73.6406);glVertex3f(0.3594, 73.5, 73.6406);glNormal3f(-1.0, 0.0, 0.0);glVertex3f(0.0, 73.5, 72.5);glVertex3f(0.0, 1.5, 72.5);

glVertex3f(0.0, 1.5, 72.5);glVertex3f(0.0, 73.5, 72.5);glNormal3f(-0.7071, 0.0, -0.7071);glVertex3f(0.3594, 73.5, 71.3594);glVertex3f(0.3594, 1.5, 71.3594);

glVertex3f(0.3594, 1.5, 71.3594);glVertex3f(0.3594, 73.5, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(1.5, 73.5, 71.0);glVertex3f(1.5, 1.5, 71.0);

//Corner to next edgeglNormal3f(0.0, 0.0, 1.0);glVertex3f(1.5, 1.5, 74.0);glVertex3f(1.5, 1.5, 74.0);glNormal3f(-0.7071, 0.0, 0.7071);glVertex3f(0.3594, 1.5, 73.6406);glNormal3f(-0.5774, -0.5774, 0.5774);glVertex3f(0.6327, 0.6327, 73.6406);

glVertex3f(0.6327, 0.6327, 73.6406);glNormal3f(0.0, -0.7071, 0.7071);glVertex3f(1.5, 0.3594, 73.6406);glNormal3f(0.0, 0.0, 1.0);glVertex3f(1.5, 1.5, 74.0);glVertex3f(1.5, 1.5, 74.0);

glNormal3f(-0.7071, 0.0, 0.7071);glVertex3f(0.3594, 1.5, 73.6406);glNormal3f(-1.0, 0.0, 0.0);glVertex3f(0.0, 1.5, 72.5);glNormal3f(-0.7071, -0.7071, 0.0);glVertex3f(0.3594, 0.3594, 72.5);glNormal3f(-0.5774, -0.5774, 0.5774);glVertex3f(0.6327, 0.6327, 73.6406);

glVertex3f(0.6327, 0.6327, 73.6406);glNormal3f(-0.7071, -0.7071, 0.0);glVertex3f(0.3594, 0.3594, 72.5);glNormal3f(0.0, -1.0, 0.0);glVertex3f(1.5, 0.0, 72.5);glNormal3f(0.0, -0.7071, 0.7071);glVertex3f(1.5, 0.3594, 73.6406);

zRectangle(1.5, 1.5, 71.0, 170.5,zRectangle(1.5, 1.5, 74.0, 170.5,

72

Page 74: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glNormal3f(-1.0, 0.0, 0.0);glVertex3f(0.0, 1.5, 72.5);glNormal3f(-0.7071, 0.0, -0.7071);glVertex3f(0.3594, 1.5, 71.3594);glNormal3f(-0.5774, -0.5774, -0.5774);glVertex3f(0.6327, 0.6327, 71.3594);glNormal3f(-0.7071, -0.7071, 0.0);glVertex3f(0.3594, 0.3594, 72.5);

glVertex3f(0.3594, 0.3594, 72.5);glNormal3f(-0.5774, -0.5774, -0.5774);glVertex3f(0.6327, 0.6327, 71.3594);glNormal3f(0.0, -0.7071, -0.7071);glVertex3f(1.5, 0.3594, 71.3594);glNormal3f(0.0, -1.0, 0.0);glVertex3f(1.5, 0.0, 72.5);

glNormal3f(-0.7071, 0.0, -0.7071);glVertex3f(0.3594, 1.5, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(1.5, 1.5, 71.0);glVertex3f(1.5, 1.5, 71.0);glNormal3f(-0.5774, -0.5774, -0.5774);glVertex3f(0.6327, 0.6327, 71.3594);

glVertex3f(0.6327, 0.6327, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(1.5, 1.5, 71.0);glVertex3f(1.5, 1.5, 71.0);glNormal3f(0.0, -0.7071, -0.7071);glVertex3f(1.5, 0.3594, 71.3594);

//Edge from (1.5, 1.5) --> (170.5, 1.5)glNormal3f(0.0, 0.0, 1.0);glVertex3f(170.5, 1.5, 74.0);glVertex3f(1.5, 1.5, 74.0);glNormal3f(0.0, -0.7071, 0.7071);glVertex3f(1.5, 0.3594, 73.6406);glVertex3f(170.5, 0.3594, 73.6406);

glVertex3f(170.5, 0.3594, 73.6406);glVertex3f(1.5, 0.3594, 73.6406);glNormal3f(0.0, -1.0, 0.0);glVertex3f(1.5, 0.0, 72.5);glVertex3f(170.5, 0.0, 72.5);

glVertex3f(170.5, 0.0, 72.5);glVertex3f(1.5, 0.0, 72.5);glNormal3f(0.0, -0.7071, -0.7071);glVertex3f(1.5, 0.3594, 71.3594);glVertex3f(170.5, 0.3594, 71.3594);

glVertex3f(170.5, 0.3594, 71.3594);glVertex3f(1.5, 0.3594, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(1.5, 1.5, 71.0);glVertex3f(170.5, 1.5, 71.0);

//Corner to next edgeglNormal3f(0.0, 0.0, 1.0);glVertex3f(170.5, 1.5, 74.0);glVertex3f(170.5, 1.5, 74.0);glNormal3f(0.0, -0.7071, 0.7071);glVertex3f(170.5, 0.3594, 73.6406);glNormal3f(0.5774, -0.5774, 0.5774);glVertex3f(171.3673, 0.6327, 73.6406);

glVertex3f(171.3673, 0.6327, 73.6406);glNormal3f(0.7071, 0.0, 0.7071);glVertex3f(171.6406, 1.5, 73.6406);glNormal3f(0.0, 0.0, 1.0);

73

Page 75: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glVertex3f(170.5, 1.5, 74.0);glVertex3f(170.5, 1.5, 74.0);

glNormal3f(0.0, -0.7071, 0.7071);glVertex3f(170.5, 0.3594, 73.6406);glNormal3f(0.0, -1.0, 0.0);glVertex3f(170.5, 0.0, 72.5);glNormal3f(0.7071, -0.7071, 0.0);glVertex3f(171.6406, 0.3594, 72.5);glNormal3f(0.5774, -0.5774, 0.5774);glVertex3f(171.3673, 0.6327, 73.6406);

glVertex3f(171.3673, 0.6327, 73.6406);glNormal3f(0.7071, -0.7071, 0.0);glVertex3f(171.6406, 0.3594, 72.5);glNormal3f(1.0, 0.0, 0.0);glVertex3f(172.0, 1.5, 72.5);glNormal3f(0.7071, 0.0, 0.7071);glVertex3f(171.6406, 1.5, 73.6406);

glNormal3f(0.0, -1.0, 0.0);glVertex3f(170.5, 0.0, 72.5);glNormal3f(0.0, -0.7071, -0.7071);glVertex3f(170.5, 0.3594, 71.3594);glNormal3f(0.5774, -0.5774, -0.5774);glVertex3f(171.3673, 0.6327, 71.3594);glNormal3f(0.7071, -0.7071, 0.0);glVertex3f(171.6406, 0.3594, 72.5);

glVertex3f(171.6406, 0.3594, 72.5);glNormal3f(0.5774, -0.5774, -0.5774);glVertex3f(171.3673, 0.6327, 71.3594);glNormal3f(0.7071, 0.0, -0.7071);glVertex3f(171.6406, 1.5, 71.3594);glNormal3f(1.0, 0.0, 0.0);glVertex3f(172.0, 1.5, 72.5);

glNormal3f(0.0, -0.7071, -0.7071);glVertex3f(170.5, 0.3594, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(170.5, 1.5, 71.0);glVertex3f(170.5, 1.5, 71.0);glNormal3f(0.5774, -0.5774, -0.5774);glVertex3f(171.3673, 0.6327, 71.3594);

glVertex3f(171.3673, 0.6327, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(170.5, 1.5, 71.0);glVertex3f(170.5, 1.5, 71.0);glNormal3f(0.7071, 0.0, -0.7071);glVertex3f(171.6406, 1.5, 71.3594);

//Edge from (170.5, 1.5) --> (170.5, 73.5)glNormal3f(0.0, 0.0, 1.0);glVertex3f(170.5, 73.5, 74.0);glVertex3f(170.5, 1.5, 74.0);glNormal3f(0.7071, 0.0, 0.7071);glVertex3f(171.6406, 1.5, 73.6406);glVertex3f(171.6404, 73.5, 73.6406);

glVertex3f(171.6404, 73.5, 73.6406);glVertex3f(171.6406, 1.5, 73.6406);glNormal3f(1.0, 0.0, 0.0);glVertex3f(172.0, 1.5, 72.5);glVertex3f(172.0, 73.5, 72.5);

glVertex3f(172.0, 73.5, 72.5);glVertex3f(172.0, 1.5, 72.5);glNormal3f(0.7071, 0.0, -0.7071);glVertex3f(171.6404, 1.5, 71.3594);glVertex3f(171.6404, 73.5, 71.3594);

74

Page 76: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glVertex3f(171.6404, 73.5, 71.3594);glVertex3f(171.6404, 1.5, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(170.5, 1.5, 71.0);glVertex3f(170.5, 73.5, 71.0);

//Corner to next edgeglNormal3f(0.0, 0.0, 1.0);glVertex3f(170.5, 73.5, 74.0);glVertex3f(170.5, 73.5, 74.0);glNormal3f(0.7071, 0.0, 0.7071);glVertex3f(171.6406, 73.5, 73.6406);glNormal3f(0.5774, 0.5774, 0.5774);glVertex3f(171.3673, 74.3673, 73.6406);

glVertex3f(171.3673, 74.3673, 73.6406);glNormal3f(0.0, 0.7071, 0.7071);glVertex3f(170.5, 74.6406, 73.6406);glNormal3f(0.0, 0.0, 1.0);glVertex3f(170.5, 73.5, 74.0);glVertex3f(170.5, 73.5, 74.0);

glNormal3f(0.7071, 0.0, 0.7071);glVertex3f(171.6406, 73.5, 73.6406);glNormal3f(1.0, 0.0, 0.0);glVertex3f(172.0, 73.5, 72.5);glNormal3f(0.7071, 0.7071, 0.0);glVertex3f(171.6406, 74.6406, 72.5);glNormal3f(0.5774, 0.5774, 0.5774);glVertex3f(171.3673, 74.3673, 73.6406);

glVertex3f(171.3673, 74.3673, 73.6406);glNormal3f(0.7071, 0.7071, 0.0);glVertex3f(171.6406, 74.6406, 72.5);glNormal3f(0.0, 1.0, 0.0);glVertex3f(170.5, 75.0, 72.5);glNormal3f(0.0, 0.7071, 0.7071);glVertex3f(170.5, 74.6406, 73.6406);

giNormal3f(1.0, 0.0, 0.0);glVertex3f(172.0, 73.5, 72.5);glNormal3f(0.7071, 0.0, -0.7071);glVertex3f(171.6406, 73.5, 71.3594);glNormal3f(0.5774, 0.5774, -0.5774);glVertex3f(171.3673, 74.3673, 71.3594);glNormal3f(0.7071, 0.7071, 0.0);glVertex3f(171.6406, 74.6406, 72.5);

glVertex3f(171.6406, 74.6406, 72.5);glNormal3f(0.5774, 0.5774, -0.5774);glVertex3f(171.3673, 74.3673, 71.3594);glNormal3f(0.0, 0.7071, -0.7071);glVertex3f(170.5, 74.6406, 71.3594);glNormal3f(0.0, 1.0, 0.0);glVertex3f(170.5, 75.0, 72.5);

glNormal3f(0.7071, 0.0, -0.7071);glVertex3f(171.6406, 73.5, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(170.5, 73.5, 71.0);glVertex3f(170.5, 73.5, 71.0);glNormal3f(0.5774, 0.5774, -0.5774);glVertex3f(171.3673, 74.3673, 71.3594);

glVertex3f(171.3673, 74.3673, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(170.5, 73.5, 71.0);glVertex3f(170.5, 73.5, 71.0);glNormal3f(0.0, 0.7071, -0.7071);glVertex3f(170.5, 74.6406, 71.3594);

75

Page 77: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

//Edge from (1.5, 73.5) --> (170.5, 73.5)glNormal3f(0.0, 0.0, 1.0);glVertex3f(1.5, 73.5, 74.0);glVertex3f(170.5, 73.5, 74.0);glNormal3f(0.0, 0.7071, 0.7071);glVertex3f(170.5, 74.6406, 73.6406);glVertex3f(1.5, 74.6406, 73.6406);

glVertex3f(1.5, 74.6406, 73.6406);glVertex3f(170.5, 74.6406, 73.6406);glNormal3f(0.0, 1.0, 0.0);glVertex3f(170.5, 75.0, 72.5);glVertex3f(1.5, 75.0, 72.5);

glVertex3f(1.5, 75.0, 72.5);glVertex3f(170.5, 75.0, 72.5);glNormal3f(0.0, 0.7071, -0.7071);glVertex3f(170.5, 74.6406, 71.3594);glVertex3f(1.5, 74.6406, 71.3594);

glVertex3f(1.5, 74.6406, 71.3594);glVertex3f(170.5, 74.6406, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(170.5, 73.5, 71.0);glVertex3f(1.5, 73.5, 71.0);

//Corner to First EdgeglNormal3f(-0.7071, 0.0, 0.7071);glVertex3f(0.3594, 73.5, 73.6406);glNormal3f(0.0, 0.0, 1.0);glVertex3f(1.5, 73.5, 74.0);glVertex3f(1.5, 73.5, 74.0);glNormal3f(-0.5774, 0.5774, 0.5774);glVertex3f(0.6327, 74.3673, 73.6406);

glVertex3f(0.6327, 74.3673, 73.6406);glNormal3f(0.0, 0.0, 1.0);glVertex3f(1.5, 73.5, 74.0);glVertex3f(1.5, 73.5, 74.0);glNormal3f(0.0, 0.7071, 0.7071);glVertex3f(1.5, 74.6406, 73.6406);

glNormal3f(-1.0, 0.0, 0.0);glVertex3f(0.0, 73.5, 72.5);glNormal3f(-0.7071, 0.0, 0.7071);glVertex3f(0.3594, 73.5, 73.6406);glNormal3f(-0.5774, 0.5774, 0.5774);glVertex3f(0.6327, 74.3673, 73.6406);glNormal3f(-0.7071, 0.7071, 0.0);glVertex3f(0.3594, 74.6406, 72.5);

glVertex3f(0.3594, 74.6406, 72.5);glNormal3f(-0.5774, 0.5774, 0.5774);glVertex3f(0.6327, 74.3673, 73.6406);glNormal3f(0.0, 0.7071, 0.7071);glVertex3f(1.5, 74.6406, 73.6406);glNormal3f(0.0, 1.0, 0.0);glVertex3f(1.5, 75.0, 72.5);

glNormal3f(-0.7071, 0.0, -0.7071);glVertex3f(0.3594, 73.5, 71.3594);glNormal3f(-1.0, 0.0, 0.0);glVertex3f(0.0, 73.5, 72.5);glNormal3f(-0.7071, 0.7071, 0.0);glVertex3f(0.3594, 74.6406, 72.5);glNormal3f(-0.5774, 0.5774, -0.5774);glVertex3f(0.6327, 74.3673, 71.3594);

glVertex3f(0.6327, 74.3673, 71.3594);glNormal3f(-0.7071, 0.7071, 0.0);

76

Page 78: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glVertex3f(0.3594, 74.6406, 72.5);glNormal3f(0.0, 1.0, 0.0);glVertex3f(1.5, 75.0, 72.5);glNormal3f(0.0, 0.7071, -0.7071);glVertex3f(1.5, 74.6406, 71.3594);

glNormal3f(-0.5774, 0.5774, -0.5774);glVertex3f(0.6327, 74.3673, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(1.5, 73.5, 71.0);glVertex3f(1.5, 73.5, 71.0);glNormal3f(-0.7071, 0.0, -0.7071);glVertex3f(0.3594, 73.5, 71.3594);

glNormal3f(0.0, 0.7071, -0.7071);glVertex3f(1.5, 74.6406, 71.3594);glNormal3f(0.0, 0.0, -1.0);glVertex3f(1.5, 73.5, 71.0);glVertex3f(1.5, 73.5, 71.0);glNormal3f(-0.5774, 0.5774, -0.5774);glVertex3f(0.6327, 74.3673, 71.3594);

glEnd();

glPushMatrix();glTranslatef(24.5, 37.5, 0.0);rectTableLeg();glPopMatrix();

glPushMatrix();glTranslatef(147.5, 37.5, 0.0);rectTableLeg();glPopMatrix();

void roundTable()

// Draws a round table about the origin.GLfloat xTemp;GLfloat yTemp;

GLfloat Normal[3];GLfloat magnitude;

GLfloat count = 50.0;GLfloat currentAngle = 0.0;GLfloat theta = 5.0 * pi / 180.0;GLfloat radius = 44.0;

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);

glBegin(GL_TRIANGLE_FAN);glNormal3f(0.0, 0.0, 1.0);glVertex3f(0.0, 0.0, 73.0);

while (currentAngle <= 2 * pi)

xTemp = cos(currentAngle)*radius;yTemp = sin(currentAngle)*radius;glVertex3f(xTemp, yTemp, 73.0);currentAngle = currentAngle + theta;

glEnd();

currentAngle = 0.0;

glBegin(GL_TRIANGLE_FAN);glNormal3f(0.0, 0.0, -1.0);glVertex3f(0.0, 0.0, 70.0);

while (currentAngle >= -2 * pi)

77

Page 79: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

xTemp = cos(currentAngle)*radius;yTemp = sin(currentAngle)*radius;glVertex3f(xTemp, yTemp, 70.0);currentAngle = currentAngle - theta;

glEnd();

currentAngle = 0.0;

while (currentAngle <= 2 * pi)

glBegin(GL_QUADS);//Top EdgeglNormal3f(0.0, 0.0, 1.0);xTemp = cos(currentAngle)*radius;yTemp = sin(currentAngle)*radius;glVertex3f(xTemp, yTemp, 73.0);

xTemp = cos(currentAngle)*(radius + 1.1406);yTemp = sin(currentAngle)*(radius + 1.1406);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = radius + 1.1406;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2) +

pow(Normal[2], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;

glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 72.6406);

xTemp = cos(currentAngle + theta)*(radius + 1.1406);yTemp = sin(currentAngle + theta)*(radius + 1.1406);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = radius + 1.1406;magnitude = sqrt(pow(Normal[0], 2) pow(Normal[1], 2) +

pow(Normal[2], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 72.6406);

glNormal3f(0.0, 0.0, 1.0);xTemp = cos(currentAngle + theta)*(radius);yTemp = sin(currentAngle + theta)*(radius);glVertex3f(xTemp, yTemp, 73.0);

//Middle-Top EdgexTemp = cos(currentAngle)*(radius + 1.1406);yTemp = sin(currentAngle)*(radius + 1.1406);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = radius + 1.1406;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2)

pow(Normal[2], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 72.6406);

xTemp = cos(currentAngle)*(radius + 1.5);yTemp = sin(currentAngle)*(radius + 1.5);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = 0.0;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2));

78

Page 80: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;

//

Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 71.5);

xTemp = cos(currentAngle + theta)*(radius + 1.5);yTemp = sin(currentAngle + theta)*(radius + 1.5);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = 0.0;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;

//

Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 71.5);

xTemp = cos(currentAngle + theta)*(radius + 1.1406);yTemp = sin(currentAngle + theta)*(radius + 1.1406);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = radius + 1.1406;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2) +

pow(Normal[2], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 72.6406);

//Middle-Bottom edgexTemp = cos(currentAngle + theta)*(radius + 1.5);yTemp = sin(currentAngle + theta)*(radius + 1.5);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = 0.0;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;

/ /

Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 71.5);

xTemp = cos(currentAngle)*(radius + 1.5);yTemp = sin(currentAngle)*(radius + 1.5);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = 0.0;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;

/ /

Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 71.5);

xTemp = cos(currentAngle)*(radius + 1.1406);yTemp = sin(currentAngle)*(radius + 1.1406);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = (radius + 1.1406) * (-1.0);magnitude = sqrt(pow(Normal[0], 2) pow(Normal[1], 2) +

pow(Normal[2], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 70.3594);

xTemp = cos(currentAngle + theta)*(radius + 1.1406);yTemp = sin(currentAngle + theta)*(radius + 1.1406);

79

Page 81: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

pow(Normal[2], 2));

Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = (radius + 1.1406) * (-1.0);magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1],

Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 70.3594);

2) +

//Bottom EdgexTemp = cos(currentAngle + theta)*(radius + 1.1406);yTemp = sin(currentAngle + theta)*(radius + 1.1406);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = (radius + 1.1406) * ( - 1.0);magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2)

pow(Normal[2], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 70.3594);

xTemp = cos(currentAngle)*(radius + 1.1406);yTemp = sin(currentAngle)*(radius + 1.1406);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = (radius + 1.1406) * ( -1.0);magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2)

pow(Normal[2], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 70.3594);

glNormal3f(0.0, 0.0, -1.0);xTemp = cos(currentAngle)*(radius);yTemp = sin(currentAngle)*(radius);glVertex3f(xTemp, yTemp, 70.0);

glNormal3f(0.0, 0.0, -1.0);xTemp = cos(currentAngle + theta)*(radius);yTemp = sin(currentAngle + theta)*(radius);glVertex3f(xTemp, yTemp, 70.0);

glEnd();

currentAngle = currentAngle + theta;

glMaterialfv(GL_FRONT, GL_AMBIENT, grey);glPushMatrix();glTranslatef(0.0, 0.0, 3.0);cylender(2.5, 36.0, 67.0);glPopMatrix();

//Circular BasecurrentAngle = 0.0;radius = 27.5;theta = 10.0 * pi / 180.0;

glBegin(GL_TRIANGLE_FAN);glNormal3f(0.0, 0.0, 1.0);glVertex3f(0.0, 0.0, 5.0);

while (currentAngle <= 2 * pi)

xTemp = cos(currentAngle)*radius;

80

Page 82: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

yTemp = sin(currentAngle)*radius;Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = radius * 4.1667;magnitude = sqrt(pow(Normal[0], 2) pow(Normal[1], 2) +

pow(Normal[2], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;Normal[2] = Normal[2] / magnitude;glVertex3f(xTemp, yTemp, 2.0);currentAngle = currentAngle + theta;

glEnd();

currentAngle = 0.0;

while (currentAngle <= 2 * pi)

glBegin(GL_QUADS);//EdgexTemp = cos(currentAngle)*(radius);yTemp = sin(currentAngle)*(radius);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = 0.0;magnitude = sqrt(pow(Normal[0], 2) + pow(Normal[1], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;

//

Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 2.0);glVertex3f(xTemp, yTemp, 0.0);

xTemp = cos(currentAngle + theta)*(radius);yTemp = sin(currentAngle + theta)*(radius);Normal[0] = xTemp;Normal[1] = yTemp;Normal[2] = 0.0;magnitude = sgrt(pow(Normal[0], 2) + pow(Normal[1], 2));Normal[0] = Normal[0] / magnitude;Normal[1] = Normal[1] / magnitude;

//

Normal[2] = Normal[2] / magnitude;glNormal3fv(Normal);glVertex3f(xTemp, yTemp, 0.0);glVertex3f(xTemp, yTemp, 2.0);

glEnd();currentAngle = currentAngle + theta;

void chair()

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);glBegin(GL_POLYGON);

glNormal3f(0.0, 0.0, 1.0);glVertex3f(-21.0, -15.0, 44.0);glVertex3f(0.0, -22.0, 44.0);glVertex3f(21.0, -15.0, 44.0);glVertex3f(21.0, 15.0, 44.0);glVertex3f(0.0, 22.0, 44.0);glVertex3f(-21.0, 15.0, 44.0);

glEnd();

glBegin(GL_POLYGON);glNormal3f(0.0, 0.0, -1.0);glVertex3f(-21.0, -15.0, 41.0);glVertex3f(-21.0, 15.0, 41.0);glVertex3f(0.0, 22.0, 41.0);glVertex3f(21.0, 15.0, 41.0);glVertex3f(21.0, -15.0, 41.0);glVertex3f(0.0, -22.0, 41.0);

81

Page 83: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glEnd();

glBegin(GL_QUADS);glNormal3f(-0.7071, -0.7071, 0.0);glVertex3f(-21.0, -15.0, 44.0);glVertex3f(-21.0, -15.0, 41.0);glNormal3f(0.0, -1.0, 0.0);glVertex3f(0.0, -22.0, 41.0);glVertex3f(0.0, -22.0, 44.0);

glVertex3f(0.0, -22.0, 44.0);glVertex3f(0.0, -22.0, 41.0);glNormal3f(0.7071, -0.7071, 0.0);glVertex3f(21.0, -15.0, 41.0);glVertex3f(21.0, -15.0, 44.0);

glVertex3f(21.0, -15.0, 44.0);glVertex3f(21.0, -15.0, 41.0);glNormal3f(0.7071, 0.7071, 0.0);glVertex3f(21.0, 15.0, 41.0);glVertex3f(21.0, 15.0, 44.0);

glVertex3f(21.0, 15.0, 44.0);glVertex3f(21.0, 15.0, 41.0);glNormal3f(0.0, 1.0, 0.0);glVertex3f(0.0, 22.0, 41.0);glVertex3f(0.0, 22.0, 44.0);

glVertex3f(0.0, 22.0, 44.0);glVertex3f(0.0, 22.0, 41.0);glNormal3f(-0.7071, 0.7071, 0.0);glVertex3f(-21.0, 15.0, 41.0);glVertex3f(-21.0, 15.0, 44.0);

glVertex3f(-21.0, 15.0, 44.0);glVertex3f(-21.0, 15.0, 41.0);glNormal3f(-0.7071, -0.7071, 0.0);glVertex3f(-21.0, -15.0, 41.0);glVertex3f(-21.0, -15.0, 44.0);

glEnd();

//LegsglPushMatrix();glTranslatef(-20.0, -14.5, 0.0);glRotatef(180.0, 3.0, 3.0, 41.0);cylender(1.75, 36.0, 42.5);glPopMatrix();

glPushMatrix();glTranslatef(20.0, -14.5, 0.0);glRotatef(180.0, -3.0, 3.0, 41.0);cylender(1.75, 36.0, 42.5);glPopMatrix();

glPushMatrix();glRotatef(180.0, 0.0, 0.0, 1.0);

glPushMatrix();glTranslatef(-20.0, -14.5, 0.0);glRotatef(180.0, 3.0, 3.0, 41.0);cylender(1.75, 36.0, 42.5);glPopMatrix();

glPushMatrix();glTranslatef(20.0, -14.5, 0.0);glRotatef(180.0, -3.0, 3.0, 41.0);cylender(1.75, 36.0, 42.5);glPopMatrix();

glPopMatrix();

82

Page 84: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

//Leg SupportsglPushMatrix();glTranslatef(-18.4, -13.0, 10.0);glRotatef(180.0, 0.0, 1.0, 1.0);cylender(1.5, 36.0, 26.0);glPopMatrix();

glPushMatrix();glTranslatef(18.4, -13.0, 10.0);glRotatef(180.0, 0.0, 1.0, 1.0);cylender(1.5, 36.0, 26.0);glPopMatrix();

glPushMatrix();glTranslatef(-18.4, 0.0, 10.0);glRotatef(180.0, 1.0, 0.0, 1.0);cylender(1.5, 36.0, 36.8);glPopMatrix();

glBegin(GL_QUADS);glNormal3f(0.0, -1.0, 0.0);glVertex3f(-28.5, -5.0, 89.0);glVertex3f(-28.5, -5.0, 82.0);glVertex3f(-26.5, -5.0, 82.0);glVertex3f(-26.5, -5.0, 89.0);

glNormal3f(0.9833, -0.1821, 0.0);glVertex3f(-26.5, -5.0, 89.0);glVertex3f(-26.5, -5.0, 82.0);glNormal3f(0.7071, -0.7071, 0.0);glVertex3f(-21.87037037, 20.0, 82.0);glVertex3f(-21.87037037, 20.0, 89.0);

glVertex3f(-21.87037037, 20.0, 89.0);glVertex3f(-21.87037037, 20.0, 82.0);glNormal3f(-0.7071, -0.7071, 0.0);glVertex3f(21.87037037, 20.0, 82.0);glVertex3f(21.87037037, 20.0, 89.0);

glVertex3f(21.87037037, 20.0, 89.0);glVertex3f(21.87037037, 20.0, 82.0);glNormal3f(-0.9833, -0.1821, 0.0);glVertex3f(26.5, -5.0, 82.0);glVertex3f(26.5, -5.0, 89.0);

glNormal3f(0.0, -1.0, 0.0);glVertex3f(28.5, -5.0, 82.0);glVertex3f(28.5, -5.0, 89.0);glVertex3f(26.5, -5.0, 89.0);glVertex3f(26.5, -5.0, 82.0);

glNormal3f(-0.9833, 0.1821, 0.0);glVertex3f(-28.5, -5.0, 82.0);glVertex3f(-28.5, -5.0, 89.0);glNormal3f(-0.7071, 0.7071, 0.0);glVertex3f(-23.5, 22.0, 89.0);glVertex3f(-23.5, 22.0, 82.0);

glVertex3f(-23.5, 22.0, 82.0);glVertex3f(-23.5, 22.0, 89.0);glNormal3f(0.7071, 0.7071, 0.0);glVertex3f(23.5, 22.0, 89.0);glVertex3f(23.5, 22.0, 82.0);

glNormal3f(0.9833, 0.1821, 0.0);glVertex3f(28.5, -5.0, 89.0);glVertex3f(28.0, -5.0, 82.0);glNormal3f(0.7071, 0.7071, 0.0);glVertex3f(23.5, 22.0, 82.0);glVertex3f(23.5, 22.0, 89.0);

83

Page 85: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glNormal3f(0.0, 0.0, 1.0);glVertex3f(-23.5, 22.0, 89.0);glVertex3f(-28.5, -5.0, 89.0);glVertex3f(-26.5, -5.0, 89.0);glVertex3f(-21.87037037, 20.0, 89.0);

glVertex3f(-23.5, 22.0, 89.0);glVertex3f(-21.87037037, 20.0, 89.0);glVertex3f(21.87037037, 20.0, 89.0);glVertex3f(23.5, 22.0, 89.0);

glVertex3f(28.5, -5.0, 89.0);glVertex3f(23.5, 22.0, 89.0);glVertex3f(21.87037037, 20.0, 89.0);glVertex3f(26.5, -5.0, 89.0);

glNormal3f(0.0, 0.0, -1.0);glVertex3f(-28.5, -5.0, 82.0);glVertex3f(-23.5, 22.0, 82.0);glVertex3f(-21.87037037, 20.0, 82.0);glVertex3f(-26.5, -5.0, 82.0);

glVertex3f(-21.87037037, 20.0, 82.0);glVertex3f(-23.5, 22.0, 82.0);glVertex3f(23.5, 22.0, 82.0);glVertex3f(21.87037037, 20.0, 82.0);

glVertex3f(23.5, 22.0, 82.0);glVertex3f(28.5, -5.0, 82.0);glVertex3f(26.5, -5.0, 82.0);glVertex3f(21.87037037, 20.0, 82.0);

glEnd();

//Back Support RodsglPushMatrix();glTranslatef(-18.9, 8.0, 44.0);glRotatef(180.0, -3.0, 0.0, 38.0);cylender(0.8, 45.0, 39.0);glPopMatrix();

glPushMatrix();glTranslatef(18.9, 8.0, 44.0);glRotatef(180.0, 3.0, 0.0, 38.0);cylender(0.8, 45.0, 39.0);glPopMatrix();

glPushMatrix();glTranslatef(-13, 13.0, 44.0);glRotatef(180.0, -3.0, 3.85, 38.0);cylender(0.8, 45.0, 41.0);glPopMatrix();

glPushMatrix();glTranslatef(13, 13.0, 44.0);glRotatef(180.0, 3.0, 3.85, 38.0);cylender(0.8, 45.0, 41.0);glPopMatrix();

glPushMatrix();glTranslatef(-5, 15.0, 44.0);glRotatef(180.0, -1.0, 3.0, 38.0);cylender(0.8, 45.0, 39.0);glPopMatrix();

glPushMatrix();glTranslatef(5, 15.0, 44.0);glRotatef(180.0, 1.0, 3.0, 38.0);cylender(0.8, 4.0, 39.0);glPopMatrix();

84

Page 86: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

void bigTV()

// Draws the big Projection TV about the origin//TV StandglMaterialfv(GL_FRONT, GL_AMBIENT, tvStandGreen);yRectangle(-53.5, 38.0, 9.0, 53.5, 72.0, 1);xRectangle(-53.5, 38.0, 9.0, -38.0, 72.0, -1);yRectangle(53.5, -38.0, 9.0, -53.5, 72.0, -1);xRectangle(53.5, 38.0, 9.0, -38.0, 72.0, 1);zRectangle(-53.5, -38.0, 9.0, 53.5, 38.0, -1);zRectangle(-53.5, -38.0, 72.0, -51.5, 38.0, 1);zRectangle(-51.5, -38.0, 72.0, 51.5, -36.0, 1);zRectangle(53.5, 38.0, 72.0, 51.5, -38.0, 1);zRectangle(51.5, 38.0, 72.0, -51.5, 36.0, 1);xRectangle(-51.5, -36.0, 72.0, 36.0, 70.0, 1);yRectangle(-51.5, -36.0, 72.0, 51.5, 70.0, 1);xRectangle(51.5, 36.0, 72.0, -36.0, 70.0, -1);yRectangle(51.5, 36.0, 72.0, -51.5, 70.0, -1);zRectangle(-51.5, -36.0, 70.0, 51.5, 36.0, 1);

//TVglMaterialfv(GL_FRONT, GL_AMBIENT, grey);yRectangle(-50.5, -20.0, 68.0, 50.5, 112.0, -1);yRectangle(-50.5, -20.0, 112.0, -46.5, 181.0, -1);yRectangle(50.5, -20.0, 112.0, 46.5, 181.0, -1);yRectangle(-50.5, -20.0, 181.0, 50.5, 185.0, -1);xRectangle(-50.5, -20.0, 68.0, 6.0, 185.0, -1);zRectangle(-50.5, -20.0, 185.0, 50.5, 6.0, 1);xRectangle(50.5, -20.0, 68.0, 6.0, 185.0, 1);

yRectangle(-38.5, 31.0, 68.0, 38.5, 117.0, 1);

glBegin(GL_QUADS);glNormal3f(-0.9015, 0.4327, 0.0);glVertex3f(-38.5, 31.0, 117.0);glVertex3f(-38.5, 31.0, 68.0);glVertex3f(-50.5, 6.0, 68.0);glVertex3f(-50.5, 6.0, 185.0);

glNormal3f(0.9015, 0.4327, 0.0);glVertex3f(38.5, 31.0, 68.0);glVertex3f(38.5, 31.0, 117.0);glVertex3f(50.5, 6.0, 185.0);glVertex3f(50.5, 6.0, 68.0);

glNormal3f(0.0, 0.9386, 0.3451);glVertex3f(50.5, 6.0, 185.0);glVertex3f(38.5, 31.0, 117.0);glVertex3f(-38.5, 31.0, 117.0);glVertex3f(-50.5, 6.0, 185.0);

glEnd();

glMaterialfv(GL_FRONT, GL_AMBIENT, ltgrey);glMaterialfv(GL_FRONT, GL_DIFFUSE, ltgrey);yRectangle(-46.5, -20.0, 112.0, 46.5, 181.0, -1);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

void init(void)

GLfloat light0_positionE = (1000.0, 610.0, 220.0, 1000.0);GLfloat light1position[] = {2000.0, 350.0, 244.0, 1000.0};GLfloat light2position[] {1500.0, 610.0, 220.0, 1000.0};

GLfloat light3_position[] = {400.0, 870.0, 244.0, 1000.0};GLfloat light4position[] = (800.0, 870.0, 244.0, 1000.0);

GLfloat light5_position[] = {1800.0, 870.0, 244.0, 1000.0};

GLfloat light6position[] = {800.0, 350.0, 244.0, 1000.0};GLfloat light7_position[] = {1400.0, 350.0, 244.0, 1000.0};

Page 87: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glShadeModel(GL_SMOOTH);glClearColor(0.0f, O.Of, O.Of, 1.0f);glClearDepth(1.0f);// Depth Buffer SetupglClearStencil(0);// Stencil Buffer SetupglEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);// The Type Of Depth Testing To DoglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glLightfv(GL_LIGHTO, GL_POSITION, light0position);glLightfv(GL_LIGHTO, GL_AMBIENT, LightAmb);glLightfv(GL_LIGHTO, GL_DIFFUSE, LightDif);glLightfv(GL_LIGHTO, GL_SPECULAR, LightSpc);glEnable(GL_LIGHT0);

glLightfv(GL_LIGHT1, GL_POSITION, lightl_position);glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmb);glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDif);glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpc);glEnable(GL_LIGHT1);

glLightfv(GL_LIGHT2, GL_POSITION, lightl_position);glLightfv(GL_LIGHT2, GL_AMBIENT, LightAmb);glLightfv(GL_LIGHT2, GL_DIFFUSE, LightDif);glLightfv(GL_LIGHT2, GL_SPECULAR, LightSpc);glEnable(GL_LIGHT2);

glLightfv(GL_LIGHT3, GL_POSITION, light3_position);glLightfv(GL_LIGHT3, GL_AMBIENT, LightAmb);glLightfv(GL_LIGHT3, GL_DIFFUSE, LightDif);glLightfv(GL_LIGHT3, GL_SPECULAR, LightSpc);glEnable(GL_LIGHT3);

glLightfv(GL_LIGHT4, GL_POSITION, light4_position);glLightfv(GL_LIGHT4, GL_AMBIENT, LightAmb);glLightfv(GL_LIGHT4, GL_DIFFUSE, LightDif);glLightfv(GL_LIGHT4, GL_SPECULAR, LightSpc);glEnable(GL_LIGHT4);

glLightfv(GL_LIGHT5, GL_POSITION, light5_position);glLightfv(GL_LIGHT5, GL_AMBIENT, LightAmb);glLightfv(GL_LIGHT5, GL_DIFFUSE, LightDif);glLightfv(GL_LIGHT5, GL_SPECULAR, LightSpc);glEnable(GL_LIGHT5);

glLightfv(GL_LIGHT6, GL_POSITION, light6_position);glLightfv(GL_LIGHT6, GL_AMBIENT, LightAmb);glLightfv(GL_LIGHT6, GL_DIFFUSE, LightDif);glLightfv(GL_LIGHT6, GL_SPECULAR, LightSpc);glEnable(GL_LIGHT6);

glLightfv(GL_LIGHT7, GL_POSITION, light7_position);glLightfv(GL_LIGHT7, GL_AMBIENT, LightAmb);glLightfv(GL_LIGHT7, GL_DIFFUSE, LightDif);glLightfv(GL_LIGHT7, GL_SPECULAR, LightSpc);glEnable(GL_LIGHT7);

// Enable Smooth Shading// Black Background

// Enables Depth Testing

//NicePerspectiveCalculations

// Set LightO Position// Set Lightl Ambience// Set Lightl Diffuse// Set Lightl Specular// Enable Light()

// Set Light() Position// Set Lightl Ambience// Set Lightl Diffuse// Set Lightl Specular// Enable Lightl

// Set Light() Position// Set Lightl Ambience// Set Lightl Diffuse// Set Lightl Specular// Enable Light2

// Set Light() Position// Set Lightl Ambience// Set Lightl Diffuse// Set Lightl Specular// Enable Light3

// Set LightO Position// Set Lightl Ambience// Set Lightl Diffuse// Set Lightl Specular// Enable Light4

// Set LightO Position// Set Lightl Ambience// Set Lightl Diffuse// Set Lightl Specular// Enable Light5

// Set LightO Position// Set Lightl Ambience// Set Lightl Diffuse// Set Lightl Specular// Enable Light6

// Set Light() Position// Set Lightl Ambience// Set Lightl Diffuse// Set Lightl Specular// Enable Lightl

glEnable(GL_LIGHTING); // Enable Lighting

glMaterialfv(GL_FRONT, GL_AMBIENT, MatAmb);

// Set Material AmbienceglMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

// Set Material Diffuse

glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpc);

// Set Material SpecularglMaterialfv(GL_FRONT, GL_SHININESS, MatShn);

// Set Material Shininess

glCullFace(GL_BACK); 7/ Set Culling Face To Back FaceglEnable(GL_CULL_FACE);// Enable Culling

I

86

Page 88: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);

normDirection();

// loadTextures();

void display(void)

glClear(GL_COLOR_BUFFER_BIT 1 GL_DEPTH_BUFFER_BIT);glPushMatrix();gluLookAt(camera[0], camera[1], camera[2],

direction[0], direction[1], direction[2],up[0], up[1], up[2]);

//Floor:glMaterialfv(GL_FRONT, GL_AMBIENT, floorBrown);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);zRectangle(0.0, 0.0, 0.0, 300.0, 300.0, 1);zRectangle(0.0, 300.0, 0.0, 300.0, 600.0, 1);zRectangle(0.0, 600.0, 0.0, 300.0, 900.0, 1);zRectangle(0.0, 900.0, 0.0, 300.0, 1162.0, 1);

zRectangle(300.0, 0.0, 0.0, 600.0, 300.0, 1);zRectangle(300.0, 300.0, 0.0, 600.0, 600.0, 1);zRectangle(300.0, 600.0, 0.0, 600.0, 900.0, 1);zRectangle(300.0, 900.0, 0.0, 600.0, 1162.0, 1);

zRectangle(600.0, 0.0, 0.0, 900.0, 300.0, 1);zRectangle(600.0, 300.0, 0.0, 900.0, 600.0, 1);zRectangle(600.0, 600.0, 0.0, 900.0, 900.0, 1);zRectangle(600.0, 900.0, 0.0, 900.0, 1162.0, 1);

zRectangle(900.0, 0.0, 0.0, 1200.0, 300.0, 1);zRectangle(900.0, 300.0, 0.0, 1200.0, 600.0, 1);zRectangle(900.0, 600.0, 0.0, 1200.0, 900.0, 1);zRectangle(900.0, 900.0, 0.0, 1200.0, 1162.0, 1);

zRectangle(1200.0, 0.0, 0.0, 1500.0, 300.0, 1);zRectangle(1200.0, 300.0, 0.0, 1500.0, 600.0, 1);zRectangle(1200.0, 600.0, 0.0, 1500.0, 900.0, 1);zRectangle(1200.0, 900.0, 0.0, 1500.0, 1162.0, 1);

zRectangle(1500.0, 0.0, 0.0, 1800.0, 300.0, 1);zRectangle(1500.0, 300.0, 0.0, 1800.0, 600.0, 1);zRectangle(1500.0, 600.0, 0.0, 1800.0, 900.0, 1);zRectangle(1500.0, 900.0, 0.0, 1800.0, 1162.0, 1);

zRectangle(1800.0, 0.0, 0.0, 2100.0, 300.0, 1);zRectangle(1800.0, 300.0, 0.0, 2100.0, 600.0, 1);zRectangle(1800.0, 600.0, 0.0, 2100.0, 900.0, 1);zRectangle(1800.0, 900.0, 0.0, 2100.0, 1162.0, 1);

zRectangle(2100.0, 0.0, 0.0, 2288.0, 300.0, 1);zRectangle(2100.0, 300.0, 0.0, 2288.0, 600.0, 1);zRectangle(2100.0, 600.0, 0.0, 2288.0, 900.0, 1);zRectangle(2100.0, 900.0, 0.0, 2288.0, 1162.0, 1);

// zRectangle(0.0, 0.0, 0.0, 2288.0, 1162.0, 1);

//Ceiling:glMaterialfv(GL_FRONT, GL_AMBIENT, ceilingGrey);

zRectangle(0.0, 32.0, 221.0, 349.0, 300.0, -1);zRectangle(0.0, 300.0, 221.0, 349.0, 495.0, -1);

zRectangle(0.0, 495.0, 221.0, 349.0, 733.0, - 1);zRectangle(349.0, 495.0, 221.0, 600.0, 733.0, -1);zRectangle(600.0, 495.0, 221.0, 900.0, 733.0, -1);zRectangle(900.0, 495.0, 221.0, 1155.0, 733.0, -1);zRectangle(1155.0, 495.0, 221.0, 1455.0, 733.0, -1);

Page 89: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

zRectangle(1455.0, 495.0, 221.0, 1610.0, 733.0,zRectangle(1610.0, 495.0, 221.0, 1800.0, 733.0,zRectangle(1800.0, 495.0, 221.0, 2045.0, 733.0,

I

11*.l

-1);- 1);-1);

// zRectangle(0.0, 495.0, 221.0, 2045.0, 733.0, -1);

zRectangle(1155.0,zRectangle(1155.0,zRectangle(1455.0,zRectangle(1455.0,

// zRectangle(1155.0,

733.0, 221.0, 1455.0, 1033.0, -1);1033.0, 221.0, 1455.0, 1162.0, -1);733.0, 221.0, 1610.0, 1033.0, -1);1033.0, 221.0, 1610.0, 1162.0, -1);733.0, 221.0, 1610.0, 1162.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);xRectangle(349.0, 100.0, 221.0, 400.0, 245.0, 1);xRectangle(349.0, 400.0, 221.0, 495.0, 245.0, 1);yRectangle(349.0, 495.0, 221.0, 649.0, 245.0, -1);yRectangle(649.0, 495.0, 221.0, 949.0, 245.0, -1);yRectangle(949.0, 495.0, 221.0, 1249.0, 245.0, -1);yRectangle(1249.0, 495.0, 221.0, 1549.0, 245.0, -1);yRectangle(1549.0, 495.0, 221.0, 1849.0, 245.0, -1);yRectangle(1849.0, 495.0, 221.0, 2045.0, 245.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, ceilingGrey);

zRectangle(349.0, 32.0, 245.0, 649.0, 300.0, -1);zRectangle(349.0, 300.0, 245.0, 649.0, 511.0, -1);zRectangle(649.0, 32.0, 245.0, 949.0, 300.0, -1);zRectangle(649.0, 300.0, 245.0, 949.0, 511.0, -1);zRectangle(949.0, 32.0, 245.0, 1249.0, 300.0, -1);zRectangle(949.0, 300.0, 245.0, 1249.0, 511.0, -1);zRectangle(1249.0, 32.0, 245.0, 1549.0, 300.0, -1);zRectangle(1249.0, 300.0, 245.0, 1549.0, 511.0, - 1);zRectangle(1549.0, 32.0, 245.0, 1849.0, 300.0, -1);zRectangle(1549.0, 300.0, 245.0, 1849.0, 511.0, -1);zRectangle(1849.0, 32.0, 245.0, 2149.0, 300.0, - 1);zRectangle(1849.0, 300.0, 245.0, 2149.0, 511.0, - 1);zRectangle(2149.0, 32.0, 245.0, 2286.0, 300.0, -1);zRectangle(2149.0, 300.0, 245.0, 2286.0, 511.0, - 1);

/7 zRectangle(349.0, 0.0, 245.0, 2286.0, 511.0, - 1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);

yRectangle(120.0, 733.0, 221.0, 420.0, 245.0, 1);yRectangle(420.0, 733.0, 221.0, 720.0, 245.0, 1);yRectangle(720.0, 733.0, 221.0, 1020.0, 245.0, 1);yRectangle(1020.0, 733.0, 221.0, 1155.0, 245.0, 1);xRectangle(1155.0, 733.0, 221.0, 1033.0, 245.0, - 1);xRectangle(1155.0, 1033.0, 221.0, 1124.0, 245.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, ceilingGrey);

zRectangle(120.0, 733.0, 245.0, 420.0, 1033.0, -1);zRectangle(120.0, 1033.0, 245.0, 420.0, 1187.0, -1);zRectangle(420.0, 733.0, 245.0, 720.0, 1033.0, - 1);zRectangle(420.0, 1033.0, 245.0, 720.0, 1187.0, -1);zRectangle(720.0, 733.0, 245.0, 1020.0, 1033.0, -1);zRectangle(720.0, 1033.0, 245.0, 1020.0, 1187.0, - 1);zRectangle(1020.0, 733.0, 245.0, 1155.0, 1033.0, -1);zRectangle(1020.0, 1033.0, 245.0, 1155.0, 1187.0, -1);

// zRectangle(120.0, 733.0, 245.0, 1155.0, 1187.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);

xRectangle(1610.0, 733.0, 221.0, 1033.0, 245.0, 1);xRectangle(1610.0, 1033.0, 221.0, 1123.0, 245.0, 1);yRectangle(1610.0, 733.0, 221.0, 1910.0, 245.0, 1);yRectangle(1910.0, 733.0, 221.0, 2045.0, 245.0, 1);

glMaterialfv(GL_FRONT, GL_AMBIENT, ceilingGrey);

zRectangle(1610.0, 733.0, 245.0, 1910.0, 1033.0, - 1);zRectangle(1610.0, 1033.0, 245.0, 1910.0, 1143.0, -1);

88

Page 90: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

zRectangle(1910.0, 733.0, 245.0, 2045.0, 1033.0, -1);zRectangle(1910.0, 1033.0, 245.0, 2045.0, 1143.0, -1);

// zRectangle(1610.0, 733.0, 245.0, 2045.0, 1143.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);

xRectangle(176.0, 1069.0, 216.0, 1124.0, 245.0, 1);yRectangle(120.0, 1069.0, 216.0, 176.0, 245.0, -1);zRectangle(120.0, 1069.0, 216.0, 176.0, 1124.0, -1);

//West Wall

xRectangle(151.0, 100.0, 0.0, 127.0, 221.0, 1);yRectangle(100.0, 127.0, 0.0, 151.0, 221.0, 1);

xRectangle(100.0, 127.0, 0.0, 204.0, 88.0, 1);xRectangle(100.0, 127.0, 88.0, 204.0, 202.0, 1);xRectangle(100.0, 127.0, 202.0, 204.0, 221.0, 1);xRectangle(100.0, 204.0, 0.0, 341.0, 88.0, 1);xRectangle(100.0, 204.0, 202.0, 341.0, 221.0, 1);xRectangle(100.0, 341.0, 0.0, 388.0, 88.0, 1);xRectangle(100.0, 341.0, 88.0, 388.0, 202.0, 1);xRectangle(100.0, 341.0, 202.0, 388.0, 221.0, 1);xRectangle(100.0, 388.0, 202.0, 483.0, 221.0, 1);xRectangle(100.0, 483.0, 0.0, 497.0, 202.0, 1);xRectangle(100.0, 483.0, 202.0, 497.0, 221.0, 1);glMaterialfv(GL_FRONT, GL_AMBIENT, doorFrameMaroon); // Set Material Ambience// Bar WindowyRectangle(100.0, 204.0, 114.0, 101.0, 202.0, -1);yRectangle(100.0, 204.0, 110.0, 123.0, 114.0, -1);yRectangle(100.0, 204.0, 88.0, 102.0, 110.0, -1);yRectangle(100.0, 341.0, 114.0, 101.0, 202.0, 1);yRectangle(100.0, 341.0, 110.0, 123.0, 114.0, 1);yRectangle(100.0, 341.0, 88.0, 102.0, 110.0, 1);

zRectangle(100.0, 204.0, 88.0, 102.0, 341.0, -1);zRectangle(102.0, 204.0, 110.0, 123.0, 341.0, -1);zRectangle(82.0, 204.0, 114.0, 123.0, 341.0, 1);zRectangle(100.0, 204.0, 202.0, 101.0, 341.0, 1);

xRectangle(102.0, 204.0, 88.0, 341.0, 110.0, 1);xRectangle(123.0, 204.0, 110.0, 341.0, 114.0, 1);xRectangle(101.0, 204.0, 114.0, 210.0, 196.0, 1);xRectangle(101.0, 204.0, 196.0, 210.0, 202.0, 1);xRectangle(101.0, 210.0, 196.0, 335.0, 202.0, 1);xRectangle(101.0, 335.0, 196.0, 341.0, 202.0, 1);xRectangle(101.0, 335.0, 114.0, 341.0, 196.0, 1);

yRectangle(101.0, 210.0, 114.0, 82.0, 196.0, 1);yRectangle(101.0, 335.0, 114.0, 82.0, 196.0, -1);glMaterialfv(GL_FRONT, GL_AMBIENT, ltgrey);xRectangle(82.0, 210.0, 114.0, 335.0, 196.0, 1);glMaterialfv(GL_FRONT, GL_AMBIENT, doorFrameMaroon);zRectangle(82.0, 210.0, 196.0, 101.0, 335.0, -1);

//Bar DooryRectangle(100.0, 388.0, 0.0, 101.0, 202.0, -1);zRectangle(100.0, 388.0, 202.0, 101.0, 483.0, 1);yRectangle(100.0, 483.0, 0.0, 101.0, 202.0, 1);xRectangle(101.0, 388.0, 0.0, 393.0, 197.0, 1);xRectangle(101.0, 388.0, 197.0, 393.0, 202.0, 1);xRectangle(101.0, 393.0, 197.0, 478.0, 202.0, 1);xRectangle(101.0, 478.0, 197.0, 483.0, 202.0, 1);xRectangle(101.0, 478.0, 0.0, 483.0, 197.0, 1);yRectangle(101.0, 393.0, 0.0, 97.0, 197.0, 1);zRectangle(101.0, 393.0, 197.0, 97.0, 478.0, -1);yRectangle(101.0, 478.0, 0.0, 97.0, 197.0, -1);xRectangle(97.0, 393.0, 0.0, 394.0, 197.0, 1);xRectangle(97.0, 394.0, 196.0, 478.0, 197.0, 1);xRectangle(97.0, 477.0, 0.0, 478.0, 196.0, 1);yRectangle(97.0, 394.0, 0.0, 92.0, 196.0, 1);

89

Page 91: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glVertex3f(90.0, 535.0,glVertex3f(92.0, 532.0,glVertex3f(92.0, 602.0,glVertex3f(90.0, 599.0,

glEnd();

glBegin(GL_QUADS);glNormal3f(0.8321, 0.0, 0.5547);

110.0);107.0);107.0);110.0);

111

11

zRectangle(97.0, 394.0, 196.0, 92.0, 477.0, -1);yRectangle(97.0, 477.0, 0.0, 92.0, 196.0, -1);glMaterialfv(GL_FRONT, GL_AMBIENT, brown);xRectangle(92.0, 394.0, 0.0, 477.0, 196.0, 1);

//West main door to LoungeglMaterialfv(GL_FRONT, GL_AMBIENT, doorFrameMaroon);xRectangle(102.0, 512.0, 0.0, 517.0, 221.0, 1);xRectangle(102.0, 517.0, 216.0, 703.0, 221.0, 1);xRectangle(102.0, 617.0, 0.0, 622.0, 216.0, 1);xRectangle(102.0, 698.0, 0.0, 703.0, 216.0, 1);xRectangle(102.0, 622.0, 0.0, 698.0, 10.0, 1);xRectangle(102.0, 622.0, 100.0, 698.0, 125.0, 1);

//Door TrimyRectangle(102.0, 517.0, 0.0, 98.0, 216.0, 1);zRectangle(102.0, 517.0, 216.0, 98.0, 617.0, -1);yRectangle(102.0, 617.0, 0.0, 98.0, 216.0, -1);

xRectangle(98.0, 517.0, 0.0, 519.0, 216.0, 1);xRectangle(98.0, 519.0, 214.0, 615.0, 216.0, 1);xRectangle(98.0, 615.0, 0.0, 617.0, 216.0, 1);

yRectangle(98.0, 519.0, 0.0, 92.0, 214.0, 1);zRectangle(98.0, 519.0, 214.0, 92.0, 615.0, - 1);yRectangle(98.0, 615.0, 0.0, 92.0, 214.0, -1);

//Door itselfglMaterialfv(GL_FRONT, GL_AMBIENT, doorMaroon);xRectangle(92.0, 519.0, 0.0, 532.0, 107.0, 1);xRectangle(92.0, 519.0, 107.0, 532.0, 201.0, 1);xRectangle(92.0, 519.0, 201.0, 532.0, 214.0, 1);xRectangle(92.0, 532.0, 0.0, 602.0, 107.0, 1);xRectangle(92.0, 532.0, 201.0, 602.0, 214.0, 1);xRectangle(92.0, 602.0, 0.0, 615.0, 107.0, 1);xRectangle(92.0, 602.0, 107.0, 615.0, 201.0, 1);xRectangle(92.0, 602.0, 201.0, 615.0, 214.0, 1);

//Door window trimglBegin(GL_QUADS);

glNormal3f(0.8321, 0.5547, 0.0);glVertex3f(92.0, 532.0, 107.0);glVertex3f(90.0, 535.0, 110.0);glVertex3f(90.0, 535.0, 198.0);glVertex3f(92.0, 532.0, 201.0);

glEnd();

glBegin(GL_QUADS);glNormal3f(0.8321, 0.0, -0.5547);glVertex3f(92.0, 532.0, 201.0);glVertex3f(90.0, 535.0, 198.0);glVertex3f(90.0, 599.0, 198.0);glVertex3f(92.0, 602.0, 201.0);

glEnd();

glBegin(GL_QUADS);glNormal3f(0.8321, -0.5547, 0.0);glVertex3f(92.0, 602.0, 201.0);glVertex3f(90.0, 599.0, 198.0);glVertex3f(90.0, 599.0, 110.0);glVertex3f(92.0, 602.0, 107.0);

glEnd();

90

Page 92: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

//door latchglMaterialfv(GL_FRONT, GL_AMBIENT, ltgrey);zRectangle(92.0,zRectangle(92.0,yRectangle(92.0,yRectangle(92.0,xRectangle(97.0,xRectangle(97.0,zRectangle(97.0,zRectangle(97.0,yRectangle(97.0,yRectangle(97.0,xRectangle(101.0,

529.0,529.0,529.0,613.0,529.0,612.0,559.0,559.0,559.0,612.0,559.0,

97.0,91.0,91.0,91.0,91.0,91.0,97.0,91.0,97.0,97.0,97.0,

97.0, 613.0, 1);97.0, 613.0, -1);97.0, 97.0, -1);97.0, 97.0, 1);559.0, 97.0, 1);613.0, 97.0, 1);101.0, 612.0, 1);101.0, 612.0, - 1);101.0, 91.0, - 1);101.0, 91.0, 1);612.0, 91.0, 1);

//door springyRectangle(92.0 ,yRectangle(92.0 ,xRectangle(95.0 ,zRectangle(92.0 ,yRectangle(92.0 ,yRectangle(92.0 ,xRectangle(98.0 ,zRectangle(92.0 ,

526.0,582.0,526.0,526.0,529.0,560.0,529.0,529.0,

214.0,214.0,212.0,212.0,212.0,212.0,203.0,203.0,

95.0, 212.0, - 1);

95.0, 212.0, 1);

582.0, 214.0, 1);

95.0, 582.0, -1);

98.0, 203.0, - 1);

98.0, 203.0, 1);

560.0, 212.0, 1);

98.0, 560.0, - 1);

//Window Trim beside doorglMaterialfv(GL_FRONT, GL_AMBIENT, doorFrameMaroon);zRectangle(102.0, 622.0, 10.0, 101.0, 698.0, 1);xRectangle(101.0, 622.0, 10.0, 698.0, 12.0, 1);zRectangle(101.0, 624.0, 12.0, 99.0, 696.0, 1);

yRectangle(102.0 , 622.0, 10.0, 101.0, 100.0, 1);xRectangle(101.0 , 622.0, 12.0, 624.0, 98.0, 1);yRectangle(101.0 , 624.0, 12.0, 99.0, 98.0, 1);

zRectangle(102.0 , 622.0, 100.0, 101.0, 698.0, - 1);xRectangle(101.0 , 622.0, 100.0, 698.0, 98.0, 1);zRectangle(101.0 , 624.0, 98.0, 99.0, 696.0, - 1);

yRectangle(102.0, 698.0, 10.0, 101.0, 100.0, - 1);xRectangle(101.0, 698.0, 12.0, 696.0, 98.0, 1);yRectangle(101.0, 696.0, 12.0, 99.0, 98.0, -1);

zRectangle(102.0, 622.0, 125.0, 101.0, 698.0, 1);xRectangle(101.0, 622.0, 125.0, 698.0, 127.0, 1);zRectangle(101.0, 624.0, 127.0, 99.0, 696.0, 1);

yRectangle(102.0, 622.0, 125.0, 101.0, 216.0, 1);xRectangle(101.0, 622.0, 127.0, 624.0, 214.0, 1);yRectangle(101.0, 624.0, 127.0, 99.0, 214.0, 1);

zRectangle(102.0, 622.0, 216.0, 101.0, 698.0, -1);xRectangle(101.0, 622.0, 216.0, 698.0, 214.0, 1);zRectangle(101.0, 624.0, 214.0, 99.0, 696.0, -1);

yRectangle(102.0, 698.0, 125.0, 101.0, 216.0, -1);xRectangle(101.0, 698.0, 127.0, 696.0, 214.0, 1);yRectangle(101.0, 696.0, 127.0, 99.0, 214.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);// xRectangle(100.0, 127.0, 0.0, 497.0, 221.0, 1);

yRectangle(100.0, 497.0, 0.0, 122.0, 221.0, - 1);xRectangle(122.0, 497.0, 0.0, 512.0, 221.0, 1);yRectangle(102.0, 512.0, 0.0, 122.0, 221.0, 1);

// xRectangle(102.0, 512.0, 0.0, 703.0, 221.0, 1);yRectangle(102.0, 703.0, 0.0, 122.0, 221.0, - 1);xRectangle(122.0, 703.0, 0.0, 733.0, 221.0, 1);yRectangle(120.0, 733.0, 0.0, 122.0, 221.0, 1);

Page 93: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

II

I

xRectangle(120.0, 733.0, 88.0, 1124.0, 245.0, 1);

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);

xRectangle(122.0 , 733.0, 0.0, 1122.0, 79.0, 1);zRectangle(120.0 , 733.0, 88.0, 124.0, 1120.0, 1);xRectangle(124.0 , 733.0, 85.0, 1120.0, 88.0, 1);zRectangle(124.0 , 733.0, 85.0, 122.0, 1122.0, -1);xRectangle(122.0 , 733.0, 84.0, 1122.0, 85.0, 1);zRectangle(124.0 , 733.0, 84.0, 122.0, 1122.0, 1);xRectangle(124.0 , 733.0, 81.0, 1120.0, 84.0, 1);zRectangle(124.0 , 733.0, 81.0, 123.0, 1121.0, -1);xRectangle(123.0 , 733.0, 79.0, 1121.0, 81.0, 1);zRectangle(123.0 , 733.0, 79.0, 122.0, 1121.0, -1);

yRectangle(122.0 , 733.0, 88.0, 124.0, 85.0, -1);yRectangle(122.0 , 733.0, 81.0, 124.0, 84.0, -1);yRectangle(122.0 , 733.0, 81.0, 123.0, 79.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);

//North Wall://4 Windows

// yRectangle(120.0 , 1124.0, 0.0, 1288.0, 94.0, -1);yRectangle(120.0 , 1124.0, 88.0, 226.0, 94.0, -1);yRectangle(226.0 , 1124.0, 88.0, 316.0, 94.0, -1);yRectangle(316.0 , 1124.0, 88.0, 402.0, 94.0, -1);yRectangle(402.0 , 1124.0, 88.0, 492.0, 94.0, -1);yRectangle(492.0 , 1124.0, 88.0, 579.0, 94.0, -1);yRectangle(579.0 , 1124.0, 88.0, 669.0, 94.0, -1);yRectangle(669.0 , 1124.0, 88.0, 760.0, 94.0, -1);yRectangle(760.0 , 1124.0, 88.0, 850.0, 94.0, - 1);yRectangle(850.0 , 1124.0, 88.0, 1288.0, 94.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);

yRectangle(124.0, 1120.0, 88.0, 422.0, 85.0, -1);yRectangle(422.0, 1120.0, 88.0, 722.0, 85.0, -1);yRectangle(722.0, 1120.0, 88.0, 1022.0, 85.0, -1);yRectangle(1022.0, 1120.0, 88.0, 1292.0, 85.0, -1);

zRectangle(120.0, 1124.0, 88.0, 422.0, 1120.0, 1);zRectangle(422.0, 1124.0, 88.0, 722.0, 1120.0, 1);zRectangle(722.0, 1124.0, 88.0, 1022.0, 1120.0, 1);zRectangle(1022.0, 1124.0, 88.0, 1292.0, 1120.0, 1);

yRectangle(122.0, 1122.0, 85.0, 422.0, 84.0, -1);yRectangle(422.0, 1122.0, 85.0, 722.0, 84.0, -1);yRectangle(722.0, 1122.0, 85.0, 1022.0, 84.0, -1);yRectangle(1022.0, 1122.0, 85.0, 1290.0, 84.0, -1);

zRectangle(120.0, 1122.0, 85.0, 422.0, 1120.0, -1);zRectangle(422.0, 1122.0, 85.0, 722.0, 1120.0, -1);zRectangle(722.0, 1122.0, 85.0, 1022.0, 1120.0, -1);zRectangle(1022.0, 1122.0, 85.0, 1290.0, 1120.0, -1);

yRectangle(124.0, 1120.0, 84.0, 422.0, 81.0, -1);yRectangle(422.0, 1120.0, 84.0, 722.0, 81.0, -1);yRectangle(722.0, 1120.0, 84.0, 1022.0, 81.0, -1);yRectangle(1022.0, 1120.0, 84.0, 1292.0, 81.0, -1);

zRectangle(120.0, 1122.0, 84.0, 422.0, 1120.0, 1);zRectangle(422.0, 1122.0, 84.0, 722.0, 1120.0, 1);zRectangle(722.0, 1122.0, 84.0, 1022.0, 1120.0, 1);zRectangle(1022.0, 1122.0, 84.0, 1290.0, 1120.0, 1);

yRectangle(123.0, 1121.0, 81.0, 422.0, 79.0, -1);yRectangle(422.0, 1121.0, 81.0, 722.0, 79.0, -1);yRectangle(722.0, 1121.0, 81.0, 1022.0, 79.0, -1);yRectangle(1022.0, 1121.0, 81.0, 1291.0, 79.0, -1);

92

Page 94: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

zRectangle(122.0, 1120.0, 81.0, 422.0, 1121.0, -1);zRectangle(422.0, 1120.0, 81.0, 722.0, 1121.0, -1);zRectangle(722.0, 1120.0, 81.0, 1022.0, 1121.0, -1);zRectangle(1022.0, 1120.0, 81.0, 1291.0, 1121.0, -1);

yRectangle(122.0, 1122.0, 0.0, 422.0, 79.0, -1);yRectangle(422.0, 1122.0, 0.0, 722.0, 79.0, -1);yRectangle(722.0, 1122.0, 0.0, 1022.0, 79.0, -1);yRectangle(1022.0, 1122.0, 0.0, 1290.0, 79.0, -1);

zRectangle(121.0, 1121.0, 79.0, 422.0, 1122.0, -1);zRectangle(422.0, 1121.0, 79.0, 722.0, 1122.0, -1);zRectangle(722.0, 1121.0, 79.0, 1022.0, 1122.0, -1);zRectangle(1022.0, 1121.0, 79.0, 1290.0, 1122.0, - 1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);

yRectangle(120.0,window2(226.0);

yRectangle(316.0,window2(402.0);

yRectangle(492.0,window2(579.0);

yRectangle(669.0,window2(760.0);

1124.0,

1124.0,

1124.0,

1124.0,

94.0, 226.0, 245.0, -1);

94.0, 402.0, 245.0, -1);

94.0, 579.0, 245.0, -1);

94.0, 760.0, 245.0, -1);

//DoorwayyRectangle(850.0,xRectangle(1288.0,

1124.0,1124.0,

94.0, 1288.0, 245.0, -1);

88.0, 1159.0, 221.0, 1);

//StageglMaterialfv(GL_FRONT, GL_AMBIENT, brown);zRectangle(1300.0,xRectangle(1300.0,yRectangle(1300.0,xRectangle(1147.0,

zRectangle(1146.9,xRectangle(1146.9,yRectangle(1146.9,xRectangle(902.9,

zRectangle(1146.9,xRectangle(1146.9,yRectangle(1146.9,xRectangle(902.9,

zRectangle(1146.9,xRectangle(1146.9,yRectangle(1146.9,

1122.0,1122.0,877.0,1122.0,

1122.0,1122.0,1001.0,

1122.0,

1000.9,1000.9,879.9,

1000.9,

879.8,879.8,758.8,

15.0, 1147.0, 877.0, 1);0.0, 877.0, 15.0, 1);

0.0, 1147.0, 15.0, - 1);0.0, 877.0, 15.0, - 1);

15.0, 902.9, 1001.0, 1);0.0, 1001.0, 15.0, 1);0.0, 902.9, 15.0, - 1);

0.0, 1001.0, 15.0, -1);

15.0, 902.9, 879.9, 1);0.0, 879.9, 15.0, 1);

0.0, 902.9, 15.0, -1);0.0, 879.9, 15.0, -1);

15.0, 902.9, 758.8, 1);0.0, 758.8, 15.0, 1);0.0, 902.9, 15.0, -1);

xRectangle(902.9,

zRectangle(902.8,xRectangle(902.8,

879.8, 0.0,

1122.0,1122.0,

758.8, 15.0, -1);

15.0, 749.8, 877.0, 1);

0.0, 877.0, 15.0, 1);yRectangle(902.8,xRectangle(749.8,

877.0, 0.0,1122.0,

749.8, 15.0, -1);0.0, 877.0, 15.0, -1);

//Coke MachineglMaterialfv(GL_FRONT, GL_AMBIENT, red);zRectangle(1307.0, 1148.0, 1.0, 1398.0, 1063.0, -1);yRectangle(1307.0, 1148.0, 1.0, 1398.0, 203.0, 1);zRectangle(1307.0, 1148.0, 203.0, 1398.0, 1060.0, 1);

glBegin(GL_QUADS);glNormal3f(-1.0, 0.0, 0.0);glVertex3f(1307.0, 1148.0, 1.0);glVertex3f(1307.0, 1063.0, 1.0);

93

Page 95: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glVertex3f(1307.0, 1062.0, 23.0);glVertex3f(1307.0, 1148.0, 23.0);

glVertex3f(1307.0, 1148.0, 23.0);glVertex3f(1307.0, 1062.0, 23.0);glVertex3f(1307.0, 1061.0, 43.0);glVertex3f(1307.0, 1148.0, 43.0);

glVertex3f(1307.0, 1148.0, 43.0);glVertex3f(1307.0, 1061.0, 43.0);glVertex3f(1307.0, 1061.0, 63.0);glVertex3f(1307.0, 1148.0, 63.0);

glVertex3f(1307.0, 1148.0, 63.0);glVertex3f(1307.0, 1061.0, 63.0);glVertex3f(1307.0, 1061.0, 83.0);glVertex3f(1307.0, 1148.0, 83.0);

glVertex3f(1307.0, 1148.0, 83.0);glVertex3f(1307.0, 1061.0, 83.0);glVertex3f(1307.0, 1062.0, 103.0);glVertex3f(1307.0, 1148.0, 103.0);

glVertex3f(1307.0, 1148.0, 103.0);glVertex3f(1307.0, 1062.0, 103.0);glVertex3f(1307.0, 1064.0, 123.0);glVertex3f(1307.0, 1148.0, 123.0);

glVertex3f(1307.0, 1148.0, 123.0);glVertex3f(1307.0, 1064.0, 123.0);glVertex3f(1307.0, 1065.0, 143.0);glVertex3f(1307.0, 1148.0, 143.0);

glVertex3f(1307.0, 1148.0, 143.0);glVertex3f(1307.0, 1065.0, 143.0);glVertex3f(1307.0, 1064.0, 163.0);glVertex3f(1307.0, 1148.0, 163.0);

glVertex3f(1307.0, 1148.0, 163.0);glVertex3f(1307.0, 1064.0, 163.0);glVertex3f(1307.0, 1063.0, 183.0);glVertex3f(1307.0, 1148.0, 183.0);

glVertex3f(1307.0, 1148.0, 183.0);glVertex3f(1307.0, 1063.0, 183.0);glVertex3f(1307.0, 1060.0, 203.0);glVertex3f(1307.0, 1148.0, 203.0);

glNormal3f(1.0, 0.0, 0.0);glVertex3f(1398.0, 1148.0, 23.0);glVertex3f(1398.0, 1062.0, 23.0);glVertex3f(1398.0, 1063.0, 1.0);glVertex3f(1398.0, 1148.0, 1.0);

glVertex3f(1398.0, 1148.0, 43.0);glVertex3f(1398.0, 1061.0, 43.0);glVertex3f(1398.0, 1062.0, 23.0);glVertex3f(1398.0, 1148.0, 23.0);

glVertex3f(1398.0, 1148.0, 63.0);glVertex3f(1398.0, 1061.0, 63.0);glVertex3f(1398.0, 1061.0, 43.0);glVertex3f(1398.0, 1148.0, 43.0);

glVertex3f(1398.0, 1148.0, 83.0);glVertex3f(1398.0, 1061.0, 83.0);glVertex3f(1398.0, 1061.0, 63.0);glVertex3f(1398.0, 1148.0, 63.0);

glVertex3f(1398.0, 1148.0, 103.0);

94

Page 96: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glVertex3f(1398.0, 1062.0, 103.0);glVertex3f(1398.0, 1061.0, 83.0);glVertex3f(1398.0, 1148.0, 83.0);

glVertex3f(1398.0, 1148.0, 123.0);glVertex3f(1398.0, 1064.0, 123.0);glVertex3f(1398.0, 1062.0, 103.0);glVertex3f(1398.0, 1148.0, 103.0);

glVertex3f(1398.0, 1148.0, 143.0);glVertex3f(1398.0, 1065.0, 143.0);glVertex3f(1398.0, 1064.0, 123.0);glVertex3f(1398.0, 1148.0, 123.0);

glVertex3f(1398.0, 1148.0, 163.0);glVertex3f(1398.0, 1064.0, 163.0);glVertex3f(1398.0, 1065.0, 143.0);glVertex3f(1398.0, 1148.0, 143.0);

glVertex3f(1398.0, 1148.0, 183.0);glVertex3f(1398.0, 1063.0, 183.0);glVertex3f(1398.0, 1064.0, 163.0);glVertex3f(1398.0, 1148.0, 163.0);

glVertex3f(1398.0, 1148.0, 203.0);glVertex3f(1398.0, 1060.0, 203.0);glVertex3f(1398.0, 1063.0, 183.0);glVertex3f(1398.0, 1148.0, 183.0);

//Front face of machine.glNormal3f(0.0, -0.9990, -0.0454);glVertex3f(1307.0, 1063.0, 1.0);glVertex3f(1398.0, 1063.0, 1.0);glNormal3f(0.0, -0.9989, -0.0476);glVertex3f(1398.0, 1062.0, 23.0);glVertex3f(1307.0, 1062.0, 23.0);

glVertex3f(1307.0, 1062.0, 23.0);glVertex3f(1398.0, 1062.0, 23.0);glNormal3f(0.0, -0.9997, -0.0250);glVertex3f(1398.0, 1061.0, 43.0);glVertex3f(1307.0, 1061.0, 43.0);

glVertex3f(1307.0, 1061.0, 43.0);glVertex3f(1398.0, 1061.0, 43.0);glNormal3f(0.0, -1.0, 0.0);glVertex3f(1398.0, 1061.0, 63.0);glVertex3f(1307.0, 1061.0, 63.0);

glVertex3f(1307.0, 1061.0, 63.0);glVertex3f(1398.0, 1061.0, 63.0);glNormal3f(0.0, -0.9997, 0.0250);glVertex3f(1398.0, 1061.0, 83.0);glVertex3f(1307.0, 1061.0, 83.0);

glVertex3f(1307.0, 1061.0, 83.0);glVertex3f(1398.0, 1061.0, 83.0);glNormal3f(0.0, -0.9972, 0.0748);glVertex3f(1398.0, 1062.0, 103.0);glVertex3f(1307.0, 1062.0, 103.0);

glVertex3f(1307.0, 1062.0, 103.0);glVertex3f(1398.0, 1062.0, 103.0);glNormal3f(0.0, -0.9972, 0.0748);glVertex3f(1398.0, 1064.0, 123.0);glVertex3f(1307.0, 1064.0, 123.0);

glVertex3f(1307.0, 1064.0, 123.0);glVertex3f(1398.0, 1064.0, 123.0);glNormal3f(0.0, -1.0, 0.0);glVertex3f(1398.0, 1065.0, 143.0);

95

Page 97: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

I

I

I

glVertex3f(1307.0, 1065.0, 143.0);

glVertex3f(1307.0, 1065.0, 143.0);glVertex3f(1398.0, 1065.0, 143.0);glNormal3f(0.0, -0 9988, -0.0499);glVertex3f(1398.0, 1064.0, 163.0);glVertex3f(1307.0, 1064.0, 163.0);

glVertex3f(1307.0, 1064.0, 163.0);glVertex3f(1398.0, 1064.0, 163.0);glNormal3f(0.0, -0 9950, -0.0995);glVertex3f(1398.0, 1063.0, 183.0);glVertex3f(1307.0, 1063.0, 183.0);

glVertex3f(1307.0, 1063.0, 183.0);glVertex3f(1398.0, 1063.0, 183.0);glNormal3f(0.0, -0 9889, -0.1483);glVertex3f(1398.0, 1060.0, 203.0);glVertex3f(1307.0, 1060.0, 203.0);

glEnd();

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

// glMaterialfv(GL_FRONT, GL_SPECULAR, LightSpc);

xRectangle(1292.0, 1120.0, 88.0, 1159.0, 85.0, 1);zRectangle(1288.0, 1124.0, 88.0, 1292.0, 1159.0, 1);xRectangle(1290.0, 1122.0, 85.0, 1159.0, 84.0, 1);zRectangle(1292.0, 1120.0, 85.0, 1290.0, 1159.0, -1);xRectangle(1292.0, 1120.0, 84.0, 1159.0, 81.0, 1);zRectangle(1292.0, 1120.0, 84.0, 1290.0, 1159.0, 1);xRectangle(1291.0, 1121.0, 81.0, 1159.0, 79.0, 1);zRectangle(1291.0, 1120.0, 81.0, 1292.0, 1159.0, -1);xRectangle(1290.0, 1122.0, 0.0, 1159.0, 79.0, 1);zRectangle(1291.0, 1121.0, 79.0, 1290.0, 1159.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wa11Maroon);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

yRectangle(1288.0, 1159.0, 0.0, 1416.0, 221.0,xRectangle(1416.0, 1159.0, 0.0, 1162.0, 221.0,yRectangle(1416.0, 1162.0, 0.0, 1424.0, 221.0,yRectangle(1525.0, 1162.0, 0.0, 1534.0, 221.0,xRectangle(1534.0, 1162.0, 88.0, 1123.0, 221.0,

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

xRectangle(1530.0, 1162.0, 88.0, 1119.0, 85.0, -1);zRectangle(1530.0, 1162.0, 88.0, 1534.0, 1119.0, 1);xRectangle(1532.0, 1162.0, 85.0, 1121.0, 84.0, - 1);zRectangle(1530.0, 1162.0, 85.0, 1532.0, 1119.0, -1);xRectangle(1530.0, 1162.0, 84.0, 1119.0, 81.0, - 1);zRectangle(1530.0, 1162.0, 84.0, 1532.0, 1119.0, 1);xRectangle(1531.0, 1162.0, 81.0, 1120.0, 79.0, -1);zRectangle(1530.0, 1162.0, 81.0, 1531.0, 1120.0, -1);xRectangle(1532.0, 1162.0, 0.0, 1121.0, 79.0, -1);zRectangle(1531.0, 1162.0, 79.0, 1532.0, 1120.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

yRectangle(1534.0, 1123.0, 88.0, 1630.0, 245.0, - 1);

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

zRectangle(1534.0, 1119.0, 88.0, 1634.0, 1123.0, 1);yRectangle(1530.0, 1119.0, 88.0, 1634.0, 85.0, - 1);

96

Page 98: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

zRectangle(1532.0 , 1121.0, 85.0, 1632.0, 1119.0, -1);yRectangle(1532.0 , 1121.0, 85.0, 1632.0, 84.0, -1);zRectangle(1532.0 , 1121.0, 84.0, 1632.0, 1119.0, 1);yRectangle(1530.0 , 1119.0, 84.0, 1634.0, 81.0, -1);zRectangle(1530.0 , 1119.0, 81.0, 1634.0, 1120.0, -1);yRectangle(1531.0 , 1120.0, 81.0, 1633.0, 79.0, -1);zRectangle(1531.0 , 1120.0, 79.0, 1633.0, 1121.0, -1);yRectangle(1532.0 , 1121.0, 0.0, 1632.0, 79.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

xRectangle(1630.0, 1123.0, 88.0, 1143.0, 245.0, 1);

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

xRectangle(1634.0 , 1119.0, 88.0, 1139.0, 85.0, 1);zRectangle(1630.0 , 1123.0, 88.0, 1634.0, 1143.0, 1);xRectangle(1632.0 , 1121.0, 85.0, 1141.0, 84.0, 1);zRectangle(1632.0 , 1119.0, 85.0, 1634.0, 1141.0, -1);xRectangle(1634.0 , 1119.0, 84.0, 1139.0, 81.0, 1);zRectangle(1632.0 , 1119.0, 84.0, 1634.0, 1141.0, 1);xRectangle(1633.0 , 1120.0, 81.0, 1140.0, 79.0, 1);zRectangle(1634.0 , 1120.0, 81.0, 1633.0, 1140.0, -1);xRectangle(1632.0 , 1121.0, 0.0, 1141.0, 79.0, 1);zRectangle(1632.0 , 1121.0, 79.0, 1633.0, 1141.0, - 1);

//East

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

yRectangle(1630.0, 1143.0, 88.0, 2021.0, 245.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);

zRectangle(1634.0 , 1139.0, 88.0, 2021.0, 1143.0, 1);yRectangle(1634.0 , 1139.0, 88.0, 2017.0, 85.0, -1);zRectangle(1632.0 , 1141.0, 85.0, 2019.0, 1139.0, -1);yRectangle(1632.0 , 1141.0, 85.0, 2019.0, 84.0, -1);zRectangle(1632.0 , 1141.0, 84.0, 2019.0, 1139.0, 1);yRectangle(1634.0 , 1139.0, 84.0, 2017.0, 81.0, -1);zRectangle(1632.0 , 1141.0, 81.0, 2019.0, 1139.0, -1);yRectangle(1633.0 , 1140.0, 81.0, 2018.0, 79.0, -1);zRectangle(1632.0 , 1140.0, 79.0, 2019.0, 1141.0, -1);yRectangle(1632.0 , 1141.0, 0.0, 2019.0, 79.0, -1);

WallzRectangle(2017.0 , 1143.0, 88.0, 2021.0, 862.0, 1);xRectangle(2017.0 , 1139.0, 88.0, 862.0, 85.0, -1);zRectangle(2017.0 , 1141.0, 85.0, 2019.0, 862.0, -1);xRectangle(2019.0 , 1142.0, 85.0, 862.0, 84.0, -1);zRectangle(2017.0 , 1141.0, 84.0, 2019.0, 862.0, 1);xRectangle(2017.0 , 1142.0, 84.0, 862.0, 81.0, -1);zRectangle(2017.0 , 1142.0, 81.0, 2018.0, 862.0, -1);xRectangle(2018.0 , 1142.0, 81.0, 862.0, 79.0, -1);zRectangle(2018.0 , 1142.0, 79.0, 2019.0, 862.0, -1);xRectangle(2019.0 , 1142.0, 0.0, 862.0, 79.0, -1);

yRectangle(2019.0 , 862.0, 0.0, 2021.0, 79.0, -1);yRectangle(2018.0 , 862.0, 79.0, 2021.0, 81.0, -1);yRectangle(2017.0 , 862.0, 81.0, 2021.0, 84.0, -1);yRectangle(2019.0 , 862.0, 84.0, 2021.0, 85.0, -1);yRectangle(2017.0 , 862.0, 85.0, 2021.0, 88.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);xRectangle(2021.0, 1143.0, 88.0, 862.0, 245.0, -1);

xRectangle(2021.0, 862.0, 0.0, 733.0, 245.0, -1);xRectangle(2021.0, 733.0, 0.0, 706.0, 221.0, -1);yRectangle(2021.0, 706.0, 0.0, 2045.0, 221.0, -1);

97

Page 99: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

//East Door unitglMaterialfv(GL_FRONT, GL_AMBIENT, doorFrameMaroon);

//door TrimxRectangle(2045. 0, 524.0, 0.0, 529.0, 221.0, -1);xRectangle(2045. 0, 529.0, 216.0, 629.0, 221.0, - 1);xRectangle(2045. 0, 629.0, 0.0, 634.0, 221.0, -1);xRectangle(2045. 0, 634.0, 0.0, 701.0, 10.0, -1);xRectangle(2045. 0, 634.0, 100.0, 701.0, 125.0, -1);xRectangle(2045. 0, 634.0, 216.0, 701.0, 221.0, -1);xRectangle(2045.0 , 701.0, 0.0, 706.0, 221.0, - 1);

yRectangle(2045.0 , 529.0, 0.0, 2049.0, 216.0, 1);zRectangle(2045.0 , 529.0, 216.0, 2049.0, 629.0, -1);yRectangle(2045.0 , 629.0, 0.0, 2049.0, 216.0, - 1);xRectangle(2049.0 , 529.0, 0.0, 531.0, 216.0, -1);xRectangle(2049.0 , 531.0, 214.0, 627.0, 216.0, -1);xRectangle(2049.0 , 627.0, 0.0, 629.0, 216.0, -1);yRectangle(2049.0 , 531.0, 0.0, 2055.0, 214.0, 1);zRectangle(2049.0 , 531.0, 214.0, 2055.0, 627.0, -1);yRectangle(2049.0 , 627.0, 0.0, 2055.0, 214.0, -1);

zRectangle(2045.0 , 634.0, 10.0, 2046.0, 701.0, 1);yRectangle(2045.0 , 634.0, 10.0, 2046.0, 100.0, 1);zRectangle(2045.0 , 634.0, 100.0, 2046.0, 701.0, -1);yRectangle(2045.0 , 701.0, 10.0, 2046.0, 100.0, - 1);

zRectangle(2045.0, 634.0, 125.0, 2046.0, 701.0, 1);yRectangle(2045.0, 634.0, 125.0, 2046.0, 216.0, 1);zRectangle(2045.0, 634.0, 216.0, 2046.0, 701.0, -1);yRectangle(2045.0, 701.0, 125.0, 2046.0, 216.0, -1);

xRectangle(2046.0, 634.0, 10.0, 701.0, 12.0, -1);xRectangle(2046.0, 634.0, 12.0, 636.0, 98.0, - 1);xRectangle(2046.0, 634.0, 98.0, 701.0, 100.0, -1);xRectangle(2046.0, 699.0, 12.0, 701.0, 98.0, - 1);

xRectangle(2046.0, 634.0, 125.0, 701.0, 127.0, -1);xRectangle(2046.0, 634.0, 127.0, 636.0, 214.0, -1);xRectangle(2046.0, 634.0, 214.0, 701.0, 216.0, -1);xRectangle(2046.0, 699.0, 127.0, 701.0, 214.0, -1);

zRectangle(2046.0, 636.0, 12.0, 2048.0, 699.0, 1);yRectangle(2046.0, 636.0, 12.0, 2048.0, 98.0, 1);zRectangle(2046.0, 636.0, 98.0, 2048.0, 699.0, -1);yRectangle(2046.0, 699.0, 12.0, 2048.0, 98.0, -1);

zRectangle(2046.0, 636.0, 127.0, 2048.0, 699.0, 1);yRectangle(2046.0, 636.0, 127.0, 2048.0, 214.0, 1);zRectangle(2046.0, 636.0, 214.0, 2048.0, 699.0, -1);yRectangle(2046.0, 699.0, 127.0, 2048.0, 214.0, -1);

//Door itselfglMaterialfv(GL_FRONT, GL_AMBIENT, doorMaroon);xRectangle(2055.0, 531.0, 0.0, 544.0, 107.0, -1);xRectangle(2055.0, 531.0, 107.0, 544.0, 201.0, -1);xRectangle(2055.0, 531.0, 201.0, 544.0, 214.0, -1);xRectangle(2055.0, 544.0, 0.0, 614.0, 107.0, -1);xRectangle(2055.0, 544.0, 201.0, 614.0, 214.0, -1);xRectangle(2055.0, 614.0, 0.0, 627.0, 107.0, - 1);xRectangle(2055.0, 614.0, 107.0, 627.0, 201.0, -1);xRectangle(2055.0, 614.0, 201.0, 627.0, 214.0, -1);

//Door window trimglBegin(GL_QUADS);

glNormal3f(-0.8321, 0.0, 0.5547);glVertex3f(2055.0, 544.0, 107.0);glVertex3f(2057.0, 547.0, 110.0);glVertex3f(2057.0, 611.0, 110.0);glVertex3f(2055.0, 614.0, 107.0);

98

Page 100: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glEnd();

glBegin(GL_QUADS);glNormal3f(-0.8321, -0.5547, 0.0);glVertex3f(2055.0, 614.0, 107.0);glVertex3f(2057.0, 611.0, 110.0);glVertex3f(2057.0,glVertex3f(2055.0,

611.0,614.0,

198.0);201.0);

glEnd();

glBegin(GL_QUADS);glNormal3f(-0.8321, 0.0, -0.5547);glVertex3f(2055.0, 614.0, 201.0);glVertex3f(2057.0, 611.0, 198.0);glVertex3f(2057.0,glVertex3f(2055.0,

547.0,544.0,

198.0);201.0);

glEnd();

glBegin(GL_QUADS);glNormal3f(-0.8321, 0.5547, 0.0);glVertex3f(2055.0,glVertex3f(2057.0,

544.0,547.0,

201.0);198.0);

glVertex3f(2057, 547.0, 110.0);glVertex3f(2055.0, 544.0, 107.0);

glEnd();

//Door LatchglMaterialfv(GL_FRONT, GL_AMBIENT, ltgrey);zRectangle(2055.0, 625.0, 97.0, 2050.0, 541.0, 1);yRectangle(2055.0, 541.0, 91.0, 2050.0, 97.0, 1);zRectangle(2055.0, 541.0, 91.0, 2050.0, 625.0, -1);yRectangle(2055.0, 625.0, 91.0, 2050.0, 97.0, -1);xRectangle(2050.0, 541.0, 91.0, 579.0, 97.0, -1);xRectangle(2050.0, 624.0, 91.0, 625.0, 97.0, -1);zRectangle(2050.0, 579.0, 97.0, 2046.0, 624.0, 1);yRectangle(2050.0, 579.0, 91.0, 2046.0, 97.0, -1);zRectangle(2050.0, 579.0, 91.0, 2046.0, 624.0, -1);yRectangle(2050.0, 624.0, 91.0, 2046.0, 97.0, 1);xRectangle(2046.0, 579.0, 91.0, 624.0, 97.0, -1);

//Door SpringyRectangle(2055.0, 538.0, 214.0, 2052.0, 212.0, - 1);zRectangle(2055.0, 538.0, 212.0, 2052.0, 596.0, -1);yRectangle(2055.0, 596.0, 214.0, 2052.0, 212.0, 1);xRectangle(2052.0, 538.0, 212.0, 596.0, 214.0, -1);

zRectangle(2055.0 , 541.0, 212.0, 2049.0, 572.0, 1);yRectangle(2055.0 , 541.0, 212.0, 2049.0, 203.0, -1);zRectangle(2055.0 , 541.0, 203.0, 2049.0, 572.0, -1);yRectangle(2055.0 , 572.0, 212.0, 2049.0, 203.0, 1);xRectangle(2049.0 , 541.0, 203.0, 572.0, 212.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);//wall

yRectangle(2045.0, 524.0, 0.0, 2039.0, 221.0, 1);xRectangle(2039.0, 524.0, 0.0, 494.0, 245.0, -1);yRectangle(2039.0, 494.0, 0.0, 2068.0, 245.0, -1);xRectangle(2068.0, 494.0, 0.0, 511.0, 245.0, 1);yRectangle(2068.0, 511.0, 0.0, 2286.0, 245.0, -1);xRectangle(2286.0, 511.0, 96.0, 100.0, 245.0, -1);

//South Wall//WindowsyRectangle(2286.0, 100.0, 96.0, 2232.0, 101.0, 1);yRectangle(2232.0, 100.0, 96.0, 2134.0, 101.0, 1);yRectangle(2134.0, 100.0, 96.0, 1989.0, 101.0, 1);yRectangle(1989.0, 100.0, 96.0, 1891.0, 101.0, 1);yRectangle(1891.0, 100.0, 96.0, 1750.0, 101.0, 1);yRectangle(1750.0, 100.0, 96.0, 1652.0, 101.0, 1);yRectangle(1652.0, 100.0, 96.0, 1511.0, 101.0, 1);

I 99

Page 101: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

yRectangle(1511.0, 100.0, 96.0, 1413.0, 101.0, 1);// yRectangle(2286.0, 100.0, 0.0, 1413.0, 101.0, 1);

yRectangle(1413.0, 100.0, 96.0, 1125.0, 101.0, 1);yRectangle(1413.0, 100.0, 101.0, 1125.0, 245.0, 1);

yRectangle(2286.0, 100.0, 101.0, 2232.0, 245.0, 1);yRectangle(2134.0, 100.0, 101.0, 1989.0, 245.0, 1);windowl(2134.0);yRectangle(1891.0, 100.0, 101.0, 1750.0, 245.0, 1);window1(1891.0);yRectangle(1652.0, 100.0, 101.0, 1511.0, 245.0, 1);windowl(1652.0);window1(1413.0);

// yRectangle(1413.0, 100.0, 0.0, 1125.0, 245.0, 1);

//Door under OverheadxRectangle(1125.0, 100.0, 0.0, 69.0, 202.0, -1);yRectangle(1125.0, 69.0, 0.0, 1113.0, 202.0, 1);yRectangle(1113.0, 69.0, 190.0, 1028.0, 202.0, 1);glMaterialfv(GL_FRONT, GL_AMBIENT, floorBrown);yRectangle(1113.0, 69.0, 0.0, 1028.0, 190.0, 1);glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);yRectangle(1028.0, 69.0, 0.0, 1016.0, 202.0, 1);xRectangle(1016.0, 69.0, 0.0, 100.0, 202.0, 1);

//OverheadxRectangle(1253.0, 100.0, 222.0, 139.0, 245.0, 1);yRectangle(1253.0, 139.0, 222.0, 1191.0, 245.0, 1);zRectangle(1253.0, 139.0, 222.0, 1191.0, 100.0, -1);zRectangle(1191.0, 114.0, 202.0, 944.0, 69.0, -1);yRectangle(944.0, 139.0, 222.0, 806.0, 245.0, 1);xRectangle(806.0, 139.0, 222.0, 100.0, 245.0, -1);zRectangle(944.0, 139.0, 222.0, 806.0, 100.0, -1);glBegin(GL_QUADS);

glNormal3f(-1.0, 0.0, 0.0);glVertex3f(944.0, 100.0, 245.0);glVertex3f(944.0, 179.0, 245.0);glVertex3f(944.0, 114.0, 202.0);glVertex3f(944.0, 100.0, 202.0);

glEnd();glBegin(GL_QUADS);

glNormal3f(1.0, 0.0, 0.0);glVertex3f(1191.0, 100.0, 202.0);glVertex3f(1191.0, 114.0, 202.0);glVertex3f(1191.0, 179.0, 245.0);glVertex3f(1191.0, 100.0, 245.0);

glEnd();glBegin(GL_QUADS);

glNormal3f(0.0, 0.5517, -0.8340);glVertex3f(1191.0, 179.0, 245.0);glVertex3f(1191.0, 114.0, 202.0);glVertex3f(944.0, 114.0, 202.0);glVertex3f(944.0, 179.0, 245.0);

glEnd();

//Another windowyRectangle(1016.0, 100.0, 96.0, 730.0, 101.0, 1);yRectangle(1016.0, 100.0, 101.0, 730.0, 245.0, 1);yRectangle(730.0, 100.0, 96.0, 632.0, 101.0, 1);windowl(632.0);yRectangle(632.0, 100.0, 96.0, 489.0, 101.0, 1);yRectangle(632.0, 100.0, 101.0, 489.0, 245.0, 1);

//StairsxRectangle(489.0,yRectangle(489.0,xRectangle(485.0,

// yRectangle(485.0,

yRectangle(395.0,zRectangle(395.0,

100.0, 96.0, 64.0, 245.0, -1);64.0, 0.0, 485.0, 245.0, 1);64.0, 0.0, 44.0, 245.0, -1);44.0, 0.0, 397.0, 245.0, 1);

100.0, 0.0, 487.0, 19.0, 1);100.0, 19.0, 487.0, 65.0, 1);

Page 102: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

yRectangle(395.0, 65.0,zRectangle(395.0, 65.0,

glMaterialfv(GL_FRONT,

//door trim

19.0, 487.0, 34.0, 1);

34.0, 487.0, 36.0, 1);

GL_AMBIENT, doorFrameMaroon);

yRectangle(397.0, 45.0, 34.0, 400.0, 242.0, 1);yRectangle(397.0, 45.0, 242.0, 485.0, 245.0, 1);yRectangle(485.0, 45.0, 34.0, 482.0, 242.0, 1);

xRectangle(400.0, 45.0, 34.0, 41.0, 242.0, 1);zRectangle(400.0, 45.0, 242.0, 482.0, 41.0, -1);xRectangle(482.0, 45.0, 34.0, 41.0, 242.0, - 1);

yRectangle(400.0, 41.0, 34.0, 401.0, 241.0, 1);yRectangle(400.0, 41.0, 241.0, 482.0, 242.0, 1);yRectangle(482.0, 41.0, 34.0, 481.0, 241.0, 1);

xRectangle(401.0, 41.0, 34.0, 36.0, 241.0, 1);zRectangle(401.0, 41.0, 241.0, 481.0, 36.0, -1);xRectangle(481.0, 41.0, 34.0, 36.0, 241.0, - 1);

//Door itselfglMaterialfv(GL_FRONT, GL_AMBIENT, doorMaroon);yRectangle(401.0, 36.0, 34.0, 416.0, 53.0, 1);yRectangle(401.0, 36.0, 53.0, 416.0, 111.0, 1);yRectangle(401.0, 36.0, 111.0, 416.0, 149.0, 1);yRectangle(401.0, 36.0, 149.0, 416.0, 225.0, 1);yRectangle(401.0, 36.0, 225.0, 416.0, 241.0, 1);

yRectangle(416.0, 36.0, 34.0, 437.0, 53.0, 1);

zRectangle(416.0, 36.0, 53.0, 437.0, 35.0, 1);xRectangle(416.0, 36.0, 53.0, 35.0, 111.0, 1);zRectangle(416.0, 36.0, 111.0, 437.0, 35.0, -1);xRectangle(437.0, 36.0, 53.0, 35.0, 111.0, - 1);

yRectangle(416.0, 36.0, 111.0, 437.0, 149.0, 1);

zRectangle(416.0, 36.0, 149.0, 437.0, 35.0, 1);xRectangle(416.0, 36.0, 149.0, 35.0, 225.0, 1);zRectangle(416.0, 36.0, 225.0, 437.0, 35.0, - 1);xRectangle(437.0, 36.0, 149.0, 35.0, 225.0, -1);

yRectangle(416.0, 36.0, 225.0, 437.0, 241.0, 1);

yRectangle(437.0, 36.0, 34.0, 481.0, 53.0, 1);yRectangle(437.0, 36.0, 53.0, 481.0, 111.0, 1);yRectangle(437.0, 36.0, 111.0, 481.0, 149.0, 1);yRectangle(437.0, 36.0, 149.0, 481.0, 225.0, 1);yRectangle(437.0, 36.0, 225.0, 481.0, 241.0, 1);

//Door LatchglMaterialfv(GL_FRONT, GL_AMBIENT, ltgrey);zRectangle(404.0, 36.0, 145.0, 470.0, 40.0, 1);xRectangle(404.0, 36.0, 140.0, 40.0, 145.0, - 1);zRectangle(404.0, 36.0, 140.0, 470.0, 40.0, -1);xRectangle(470.0, 36.0, 140.0, 40.0, 145.0, 1);yRectangle(404.0, 40.0, 145.0, 405.0, 140.0, 1);yRectangle(470.0, 40.0, 145.0, 450.0, 140.0, 1);

zRectangle(405.0, 40.0, 145.0, 450.0, 44.0, 1);xRectangle(405.0, 40.0, 145.0, 44.0, 140.0, - 1);zRectangle(405.0, 40.0, 140.0, 450.0, 44.0, - 1);xRectangle(450.0, 40.0, 145.0, 44.0, 140.0, 1);yRectangle(405.0, 44.0, 140.0, 450.0, 145.0, 1);

glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);

xRectangle(397.0, 44.0, 0.0, 64.0, 245.0, 1);yRectangle(397.0, 64.0, 0.0, 393.0, 245.0, 1);

Page 103: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

xRectangle(393.0, 64.0, 96.0, 100.0, 245.0, 1);

//Unique WindowyRectangle(393.0, 100.0, 96.0, 249.0, 101.0, 1);yRectangle(393.0, 100.0, 101.0, 249.0, 245.0, 1);yRectangle(249.0, 100.0, 96.0, 153.0, 101.0, 1);yRectangle(153.0, 100.0, 96.0, 151.0, 101.0, 1);yRectangle(153.0, 100.0, 101.0, 151.0, 221.0, 1);

zRectangle(249.0, 100.0, 101.0, 153.0, 32.0, 1);xRectangle(153.0, 100.0, 101.0, 66.0, 221.0, 1);yRectangle(153.0, 66.0, 101.0, 156.0, 221.0, 1);xRectangle(156.0, 66.0, 101.0, 32.0, 221.0, 1);glMaterialfv(GL_FRONT, GL_AMBIENT, doorMaroon);

yRectangle(156.0, 33.0, 101.0, 246.0, 107.0, 1);yRectangle(156.0, 33.0, 107.0, 162.0, 147.0, 1);yRectangle(156.0, 33.0, 147.0, 246.0, 155.0, 1);yRectangle(240.0, 33.0, 107.0, 246.0, 147.0, 1);yRectangle(156.0, 32.0, 155.0, 159.0, 218.0, 1);yRectangle(156.0, 32.0, 218.0, 246.0, 221.0, 1);yRectangle(243.0, 32.0, 155.0, 246.0, 218.0, 1);

zRectangle(162.0, 33.0, 107.0, 240.0, 32.0, 1);xRectangle(162.0, 33.0, 107.0, 32.0, 147.0, 1);zRectangle(162.0, 33.0, 147.0, 240.0, 32.0, -1);xRectangle(240.0, 33.0, 107.0, 32.0, 147.0, -1);

zRectangle(156.0, 33.0, 155.0, 246.0, 31.0, 1);xRectangle(159.0, 32.0, 155.0, 31.0, 218.0, 1);zRectangle(159.0, 32.0, 218.0, 243.0, 31.0, -1);xRectangle(243.0, 32.0, 155.0, 31.0, 218.0, -1);glMaterialfv(GL_FRONT, GL_AMBIENT, wallMaroon);

xRectangle(249.0, 100.0, 101.0, 66.0, 221.0, -1);yRectangle(249.0, 66.0, 101.0, 246.0, 221.0, 1);xRectangle(246.0, 66.0, 101.0, 32.0, 221.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);

zRectangle(151.0, 100.0, 96.0, 397.0, 104.0, 1);yRectangle(151.0, 104.0, 96.0, 397.0, 93.0, 1);zRectangle(151.0, 104.0, 93.0, 397.0, 102.0, -1);yRectangle(151.0, 102.0, 93.0, 395.0, 92.0, 1);zRectangle(151.0, 104.0, 92.0, 397.0, 102.0, 1);yRectangle(151.0, 104.0, 92.0, 397.0, 89.0, 1);zRectangle(151.0, 104.0, 89.0, 397.0, 103.0, -1);yRectangle(151.0, 103.0, 89.0, 396.0, 87.0, 1);zRectangle(151.0, 103.0, 87.0, 396.0, 102.0, -1);yRectangle(151.0, 102.0, 0.0, 395.0, 87.0, 1);

zRectangle(393.0, 100.0, 96.0, 397.0, 64.0, 1);xRectangle(397.0, 64.0, 96.0, 104.0, 93.0, 1);zRectangle(397.0, 64.0, 93.0, 395.0, 104.0, -1);xRectangle(395.0, 64.0, 93.0, 102.0, 92.0, 1);zRectangle(397.0, 64.0, 92.0, 395.0, 104.0, 1);xRectangle(397.0, 64.0, 92.0, 104.0, 89.0, 1);zRectangle(397.0, 64.0, 89.0, 396.0, 103.0, -1);xRectangle(396.0, 64.0, 89.0, 103.0, 87.0, 1);zRectangle(396.0, 64.0, 87.0, 395.0, 102.0, -1);xRectangle(395.0, 64.0, 0.0, 102.0, 87.0, 1);

zRectangle(489.0, 64.0, 96.0, 485.0, 100.0, 1);xRectangle(485.0, 64.0, 96.0, 104.0, 93.0, -1);zRectangle(485.0, 64.0, 93.0, 487.0, 102.0, -1);xRectangle(487.0, 64.0, 93.0, 102.0, 92.0, -1);zRectangle(485.0, 64.0, 92.0, 487.0, 102.0, 1);xRectangle(485.0, 64.0, 92.0, 104.0, 89.0, -1);zRectangle(485.0, 64.0, 89.0, 486.0, 103.0, -1);xRectangle(486.0, 64.0, 89.0, 103.0, 87.0, -1);zRectangle(486.0, 64.0, 87.0, 487.0, 102.0, -1);

102

Page 104: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

xRectangle(487.0, 64.0, 0.0, 102.0, 87.0, -1);

zRectangle(485.0, 100.0, 96.0, 750.0, 104.0, 1);yRectangle(485.0, 104.0, 96.0, 750.0, 93.0, 1);zRectangle(485.0, 104.0, 93.0, 750.0, 102.0, -1);yRectangle(487.0, 102.0, 93.0, 750.0, 92.0, 1);zRectangle(485.0, 104.0, 92.0, 750.0, 102.0, 1);yRectangle(485.0, 104.0, 92.0, 750.0, 89.0, 1);zRectangle(485.0, 104.0, 89.0, 750.0, 103.0, -1);yRectangle(486.0, 103.0, 89.0, 750.0, 87.0, 1);zRectangle(486.0, 103.0, 87.0, 750.0, 102.0, -1);yRectangle(487.0, 102.0, 0.0, 750.0, 87.0, 1);

zRectangle(750.0, 100.0, 96.0, 1020.0, 104.0, 1);yRectangle(750.0, 104.0, 96.0, 1020.0, 93.0, 1);zRectangle(750.0, 104.0, 93.0, 1020.0, 102.0, -1);yRectangle(750.0, 102.0, 93.0, 1018.0, 92.0, 1);zRectangle(750.0, 104.0, 92.0, 1020.0, 102.0, 1);yRectangle(750.0, 104.0, 92.0, 1020.0, 89.0, 1);zRectangle(750.0, 104.0, 89.0, 1020.0, 103.0, -1);yRectangle(750.0, 103.0, 89.0, 1019.0, 87.0, 1);zRectangle(750.0, 103.0, 87.0, 1019.0, 102.0, -1);yRectangle(750.0, 102.0, 0.0, 1018.0, 87.0, 1);

zRectangle(1020.0, 100.0, 96.0, 1016.0, 64.0, 1);xRectangle(1020.0, 69.0, 96.0, 104.0, 93.0, 1);zRectangle(1020.0, 69.0, 93.0, 1018.0, 104.0, -1);xRectangle(1018.0, 69.0, 93.0, 102.0, 92.0, 1);zRectangle(1020.0, 69.0, 92.0, 1018.0, 104.0, 1);xRectangle(1020.0, 69.0, 92.0, 104.0, 89.0, 1);zRectangle(1020.0, 69.0, 89.0, 1019.0, 103.0, -1);xRectangle(1019.0, 69.0, 89.0, 103.0, 87.0, 1);zRectangle(1019.0, 69.0, 87.0, 1018.0, 102.0, -1);xRectangle(1018.0, 69.0, 0.0, 102.0, 87.0, 1);

zRectangle(1121.0, 69.0, 96.0, 1125.0, 100.0, 1);xRectangle(1121.0, 69.0, 96.0, 104.0, 93.0, -1);zRectangle(1121.0, 69.0, 93.0, 1123.0, 102.0, -1);xRectangle(1123.0, 69.0, 93.0, 102.0, 92.0, -1);zRectangle(1121.0, 69.0, 92.0, 1123.0, 102.0, 1);xRectangle(1121.0, 69.0, 92.0, 104.0, 89.0, -1);zRectangle(1121.0, 69.0, 89.0, 1122.0, 103.0, -1);xRectangle(1122.0, 69.0, 89.0, 103.0, 87.0, -1);zRectangle(1122.0, 69.0, 87.0, 1123.0, 102.0, -1);xRectangle(1123.0, 69.0, 0.0, 102.0, 87.0, -1);

zRectangle(1121.0, 100.0, 96.0, 1400.0, 104.0, 1);yRectangle(1121.0, 104.0, 96.0, 1400.0, 93.0, 1);zRectangle(1121.0, 104.0, 93.0, 1400.0, 102.0, -1);yRectangle(1123.0, 102.0, 93.0, 1400.0, 92.0, 1);zRectangle(1121.0, 104.0, 92.0, 1400.0, 102.0, 1);yRectangle(1121.0, 104.0, 92.0, 1400.0, 89.0, 1);zRectangle(1121.0, 104.0, 89.0, 1400.0, 103.0, -1);yRectangle(1122.0, 103.0, 89.0, 1400.0, 87.0, 1);zRectangle(1122.0, 103.0, 87.0, 1400.0, 102.0, -1);yRectangle(1123.0, 102.0, 0.0, 1400.0, 87.0, 1);

zRectangle(1400.0, 100.0, 96.0, 1700.0, 104.0, 1);yRectangle(1400.0, 104.0, 96.0, 1700.0, 93.0, 1);zRectangle(1400.0, 104.0, 93.0, 1700.0, 102.0, -1);yRectangle(1400.0, 102.0, 93.0, 1700.0, 92.0, 1);zRectangle(1400.0, 104.0, 92.0, 1700.0, 102.0, 1);yRectangle(1400.0, 104.0, 92.0, 1700.0, 89.0, 1);zRectangle(1400.0, 104.0, 89.0, 1700.0, 103.0, -1);yRectangle(1400.0, 103.0, 89.0, 1700.0, 87.0, 1);zRectangle(1400.0, 103.0, 87.0, 1700.0, 102.0, -1);yRectangle(1400.0, 102.0, 0.0, 1700.0, 87.0, 1);

zRectangle(1700.0, 100.0, 96.0, 2000.0, 104.0, 1);yRectangle(1700.0, 104.0, 96.0, 2000.0, 93.0, 1);zRectangle(1700.0, 104.0, 93.0, 2000.0, 102.0, -1);

103

Page 105: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

yRectangle(1700.0 , 102.0, 93.0, 2000.0, 92.0, 1);zRectangle(1700.0 , 104.0, 92.0, 2000.0, 102.0, 1);yRectangle(1700.0 , 104.0, 92.0, 2000.0, 89.0, 1);zRectangle(1700.0 , 104.0, 89.0, 2000.0, 103.0, -1);yRectangle(1700.0 , 103.0, 89.0, 2000.0, 87.0, 1);zRectangle(1700.0 , 103.0, 87.0, 2000.0, 102.0, -1);yRectangle(1700.0 , 102.0, 0.0, 2000.0, 87.0, 1);

zRectangle(2000.0 , 100.0, 96.0, 2286.0, 104.0, 1);yRectangle(2000.0 , 104.0, 96.0, 2286.0, 93.0, 1);zRectangle(2000.0 , 104.0, 93.0, 2286.0, 102.0, -1);yRectangle(2000.0 , 102.0, 93.0, 2286.0, 92.0, 1);zRectangle(2000.0 , 104.0, 92.0, 2286.0, 102.0, 1);yRectangle(2000.0 , 104.0, 92.0, 2286.0, 89.0, 1);zRectangle(2000.0 , 104.0, 89.0, 2286.0, 103.0, -1);yRectangle(2000.0 , 103.0, 89.0, 2286.0, 87.0, 1);zRectangle(2000.0 , 103.0, 87.0, 2286.0, 102.0, -1);yRectangle(2000.0 , 102.0, 0.0, 2286.0, 87.0, 1);

zRectangle(2286.0 , 104.0, 96.0, 2282.0, 300.0, 1);xRectangle(2282.0 , 104.0, 96.0, 300.0, 93.0, -1);zRectangle(2282.0 , 102.0, 93.0, 2284.0, 300.0, -1);xRectangle(2284.0 , 102.0, 93.0, 300.0, 92.0, -1);zRectangle(2282.0 , 102.0, 92.0, 2284.0, 300.0, 1);xRectangle(2282.0 , 104.0, 92.0, 300.0, 89.0, -1);zRectangle(2282.0 , 104.0, 89.0, 2283.0, 300.0, -1);xRectangle(2283.0 , 103.0, 89.0, 300.0, 87.0, -1);zRectangle(2283.0 , 103.0, 87.0, 2284.0, 300.0, -1);xRectangle(2284.0 , 102.0, 0.0, 300.0, 87.0, -1);

zRectangle(2286.0 , 300.0, 96.0, 2282.0, 511.0, 1);xRectangle(2282.0 , 300.0, 96.0, 511.0, 93.0, -1);zRectangle(2282.0 , 300.0, 93.0, 2284.0, 511.0, -1);xRectangle(2284.0 , 300.0, 93.0, 511.0, 92.0, -1);zRectangle(2282.0 , 300.0, 92.0, 2284.0, 511.0, 1);xRectangle(2282.0 , 300.0, 92.0, 511.0, 89.0, -1);zRectangle(2282.0 , 300.0, 89.0, 2283.0, 511.0, -1);xRectangle(2283.0 , 300.0, 89.0, 511.0, 87.0, -1);zRectangle(2283.0 , 300.0, 87.0, 2284.0, 511.0, -1);xRectangle(2284.0 , 300.0, 0.0, 511.0, 87.0, -1);

glMaterialfv(GL_FRONT, GL_AMBIENT, brown);

// Pillarspillar(470.0, 495.0);pillar(858.0, 495.0);pillar(1254.0, 495.0);pillar(1643.0, 495.0);pillar(470.0, 704.0);pillar(858.0, 704.0);pillar(1254.0, 704.0);pillar(1643.0, 704.0);

glPushMatrix();glTranslatef(1435.0, 300.0, 0.0);glRotatef(1.0, 0.0, 0.0, 1.0);foosBall();glPopMatrix();

//3 Rectangular TablesglPushMatrix();glTranslatef(1400.0, 750.0, 0.0);glRotatef(90.0, 0.0, 0.0, 1.0);recTable();glPopMatrix();

glPushMatrix();glTranslatef(900.0, 175.0, 0.0);recTable();glPopMatrix();

104

Page 106: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glPushMatrix();glTranslatef(198.0, 740.0, 0.0);glRotatef(90.0, 0.0, 0.0, 1.0);recTable();glPopMatrix();

//7 Round TablesglPushMatrix();glTranslatef(500.0, 400.0, 0.0);roundTable();glPopMatrix();

glPushMatrix();glTranslatef(700.0, 350.0, 0.0);roundTable();glPopMatrix();

glPushMatrix();glTranslatef(1000.0, 410.0, 0.0);roundTable();glPopMatrix();

glPushMatrix();glTranslatef(1300.0, 200.0, 0.0);roundTable();glPopMatrix();

glPushMatrix();glTranslatef(1250.0, 375.0, 0.0);roundTable();glPopMatrix();

glPushMatrix();glTranslatef(1700.0, 300.0, 0.0);roundTable();glPopMatrix();

glPushMatrix();glTranslatef(1900.0, 350.0, 0.0);roundTable();glPopMatrix();

//45 ChairsglPushMatrix();glTranslatef(220.0, 760.0, 0.0);glRotatef(250.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(220.0, 840.0, 0.0);glRotatef(280.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(160.0, 960.0, 0.0);glRotatef(15.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(440.0, 400.0, 0.0);glRotatef(95.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(520.0, 470.0, 0.0);glRotatef(15.0, 0.0, 0.0, 1.0);chair();

105

Page 107: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glPopMatrix();

glPushMatrix();glTranslatef(560.0, 400.0, 0.0);glRotatef(-80.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(500.0, 330.0, 0.0);glRotatef(190.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(630.0, 340.0, 0.0);glRotatef(130.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(710.0, 415.0, 0.0);glRotatef(-2.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(775.0, 350.0, 0.0);glRotatef(272.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(700.0, 280.0, 0.0);glRotatef(175.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(930.0, 400.0, 0.0);glRotatef(82.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1000.0, 480.0, 0.0);glRotatef(10.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1062.0, 425.0, 0.0);glRotatef(270.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(982.0, 340.0, 0.0);glRotatef(170.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1240.0, 200.0, 0.0);glRotatef(96.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();g1Translatef(1312.0, 270.0, 0.0);glRotatef(-10.0, 0.0, 0.0, 1.0);

106

Page 108: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

chair();glPopMatrix();

glPushMatrix();glTranslatef(1362.0,glRotatef(260.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1310.0,glRotatef(170.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1180.0,

190.0,0.0,

130.0,0.0,

380.0,

0.0);1.0);

0.0);1.0);

0.0);glRotatef(83.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

g1PushMatrix();glTranslatef(1240.0, 450.0, 0.0);glRotatef(20.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1320.0,glRotatef(260.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1240.0,glRotatef(195.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1635.0,

375.0,0.0,

310.0,0.0,

300.0,

0.0);1.0);

0.0);1.0);

0.0);glRotatef(82.0, 0.0,chair();glPopMatrix();

glPushMatrix();

0.0, 1.0);

glTranslatef(1705.0,glRotatef(-10.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1762.0,glRotatef(260.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1705.0,glRotatef(200.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1830.0,

380.0,0.0,

295.0,0.0,

220.0,0.0,

350.0,

0.0);1.0);

0.0);1.0);

0.0);1.0);

0.0);glRotatef(90.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1900.0, 420.0, 0.0);

107

Page 109: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glRotatef(15.0, 0.0,chair();glPopMatrix();

glPushMatrix();

0.0, 1.0);

glTranslatef(1982.0,glRotatef(260.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1902.0,glRotatef(190.0, 0.0,chair();glPopMatrix();

340.0,0.0,

270.0,0.0,

0.0);1.0);

0.0);1.0);

//Chairs for rectangular tablesglPushMatrix();glTranslatef(870.0, 210.0, 0.0);glRotatef(130.0, 0.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(945.0, 270.0,glRotatef(10.0, 0.0, 0.0,chair();glPopMatrix();

1.0);

0.0);1.0);

glPushMatrix();glTranslatef(1035.0,glRotatef(-20.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1100.0,glRotatef(240.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1030.0,glRotatef(170.0, 0.0,chair();glPopMatrix();

glPushMatrix();

275.0,0.0,

220.0,0.0,

140.0,0.0,

0.0);1.0);

0.0);1.0);

0.0);1.0);

glTranslatef(940.0, 135.0,glRotatef(195.0, 0.0,chair();glPopMatrix();

glPushMatrix();glTranslatef(1280.0,

0.0,

780.0,

0.0);1.0);

0.0);glRotatef(90.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1275.0, 845.0, 0.0);glRotatef(60.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1350.0, 729.0, 0.0);glRotatef(110.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

108

Page 110: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glPushMatrix();glTranslatef(1362.0,glRotatef(25.0, 0.0,chair();glPopMatrix();

960.0, 0.0);0.0, 1.0);

glPushMatrix();glTranslatef(1430.0, 800.0, 0.0);glRotatef(270.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1425.0, 870.0, 0.0);glRotatef(255.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

//Stray chairsglPushMatrix();glTranslatef(602.0, 130.0, 0.0);glRotatef(190.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(670.0, 128.0, 0.0);glRotatef(180.0, 0.0, 0.0, 1.0);chair();glPopMatrix();

glPushMatrix();glTranslatef(1950.0, 1070.0, 0.0);glRotatef(-60.0, 0.0, 0.0, 1.0);bigTV();glPopMatrix();

glMaterialfv(GL_FRONT, GL_AMBIENT, MatAmb);

glPopMatrix();glutSwapBuffers();

void reshape(int w, int h)

if ((3*w) < (4*h))glViewport(0, 0, (GLsizei) w, (GLsizei) w * 3.0 / 4.0);

else if ((4*h) < (3*w))glViewport(0, 0, (GLsizei) h * 4.0 / 3.0, (GLsizei) h);

elseglViewport(0, 0, (GLsizei) w, (GLsizei) h);

glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(90.0, 4.0 / 3.0, 0.1, 10000.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();

void processSpecialKeys(int key, int x, int y)

switch(key) {case GLUT_KEY_UP :// Move Forward - Towards the direction vector.

forward();forward();forward();forward();forward();

break;

109

Page 111: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

case GLUT_KEY_DOWN :// Move backward - Away from the direction vector.

backward();backward();backward();backward();backward();break;

case GLUT_KEY_RIGHT :// Rotate the direction vector to the right.

temp[0] = direction[0] + ((direction[1] - camera[1]) * turnMult);temp[1] = direction[1] - ((direction[0] - camera[0]) * turnMult);

direction[0] = temp[0];direction[1] = temp[1];

normDirection();

glLoadIdentity();glutPostRedisplay();break;

case GLUT_KEY_LEFT :// Rotate the direction vector to the left.

temp[0] = direction[0] - ((direction[1] - camera[1]) * turnMult);temp[1] = direction[1] + ((direction[0] camera[0]) * turnMult);

direction[0] = temp[0];direction[1] = temp[1];

normDirection();

glLoadIdentity();glutPostRedisplay();break;

case GLUT_KEY_END :// Center the view

direction[2] = camera[2];glLoadIdentity();glutPostRedisplay();break;

case GLUT_KEY_PAGE_UP :// rotate the direction vector up.

direction[2] = direction [2] + 0.1;normDirection();

glLoadIdentity();glutPostRedisplay();break;

case GLUT_KEY_PAGE_DOWN :// rotate the direction vector down.

direction[2] = direction[2] - 0.1;normDirection();

glLoadIdentity();glutPostRedisplay();break;

default:break;

void keyboard( unsigned char key, int x, int y ){

switch (key) {case 'c':

if (gllsEnabled(GL_CULL_FACE) == GL_TRUE)glDisable(GL_CULL_FACE);

elseglEnable(GL_CULL_FACE);

110

Page 112: rtn Rlt ThrDnnl p n pnLarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. · pnL prvd prrr th th blt t rph hrdr thrh ftr. t pd f vr 200 nd tht r d t th rph

glutPostRedisplay();break;

case 'w':if(wireframe == GL_TRUE)

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //Normalwireframe = GL_FALSE;

else

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // wireframewireframe = GL_TRUE;

glutPostRedisplay();break;

default:break;

int main(int argc, char** argv)

glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE GLUT_RGBAglutInitWindowSize(800, 600);glutInitWindowPosition(0, 0);glutCreateWindow(argv[0]);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutSpecialFunc(processSpecialKeys);glutKeyboardFunc(keyboard);glutMainLoop();return 0;

GLUT_DEPTH);

111