rtn rlt thrdnnl p n pnlarchives.algomau.ca/main/sites/default/files/2013-064... · 2015. 9. 21. ·...
Post on 26-Feb-2021
0 Views
Preview:
TRANSCRIPT
Creating Realistic Three-Dimensional "Map" using OpenGL
By Dan HooperSenior Computer Science Thesis
05/04/2002
SPCOSCHOO02/73
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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
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
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
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
(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
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);.
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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
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
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
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
■
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
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
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
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
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
// 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
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
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();
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
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
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
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
//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
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
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
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
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
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
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
■
■
//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
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
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};
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
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);
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
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
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
//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);
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
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
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
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
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
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
//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
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
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);
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);
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
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
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
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
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
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
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
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
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
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
top related