#include <windows.h> // Normal Windows stuff
#include <math.h>
#include <gl/gl.h> // Core OpenGL functions
#include <gl/glu.h> // OpenGL Utility functions
#include <gl/glaux.h>
#include "externs.h" // Data shared between files
#include "glutils.h" // Utilities for this application
// Prevent anoying compiler warnings - only used locally
#define fsin(x) (float)sin(x)
#define fcos(x) (float)cos(x)
// Useful structure for storing coordinates of objects. We declare
// an array of these to hold the positions of the various types of
objects
struct COORD
{
float x;
float z;
};
// Maximum number of each type of object
#define MAX_EACH 15
// Arrays of objects
struct COORD Pyramids[MAX_EACH];
struct COORD Trees[MAX_EACH];
struct COORD Slabs[MAX_EACH];
struct COORD Pillers[MAX_EACH];
struct COORD Fly[MAX_EACH];
void RandomizePositions(void);
float RandomPos(void);
void PlaceTress(void);
void PlacePyramids(void);
void PlaceSlabs(void);
void PlacePillers(void);
//void PlaceBoxes(void);
void DrawGround(void);
//void DrawBox(void);
///////////////////////////////////////////////////////////////////////////////
// Pick a random value between -1000.0 and 1000.0
float RandomPos(void)
{
double dRet = 0.0f;
dRet = (double)rand(); // between 0 and RAND_MAX
dRet = dRet/(double)RAND_MAX; // between 0 and 1.0
dRet *= 2000.0f; // between 0 and 2000
dRet -= 1000.0f; // between -1000 and 1000
return (float)dRet;
}
///////////////////////////////////////////////////////////////////////////////
// Position the objects in the scene
void RandomizePositions()
{
int i;
// Pick two random values for x and z coordinates
for(i = 0; i < MAX_EACH; i++)
{
Pyramids[i].x = RandomPos();
Pyramids[i].z = RandomPos();
Slabs[i].x = RandomPos();
Slabs[i].z = RandomPos();
Pillers[i].x = RandomPos();
Pillers[i].z = RandomPos();
Fly[i].x = RandomPos();
Fly[i].z = RandomPos();
Trees[i].x = RandomPos();
Trees[i].z = RandomPos();
}
}
////////////////////////////////////////////////////////////////////////////////
// Put the Pyramids in place Draws each one individually
void PlacePyramids(void)
{
int i;
for(i = 0; i < MAX_EACH; i++)
{
glPushMatrix();
glTranslatef(Pyramids[i].x, 0.0f, Pyramids[i].z);
DrawPyramid();
glPopMatrix();
}
}
////////////////////////////////////////////////////////////////////////////////
// Put the tress in place Draws each one individually
void PlaceTrees(void)
{
int i;
for(i = 0; i < 45; i++)
{
glPushMatrix();
glTranslatef(Trees[i].x, 0.0f, Trees[i].z);
DrawTree();
glPopMatrix();
}
}
///////////////////////////////////////////////////////////////////////////////
// Put the slabs in place
void PlaceSlabs(void)
{
int i;
// Loop through, and place each one
for(i = 0; i < MAX_EACH; i++)
{
glPushMatrix();
glTranslatef(Slabs[i].x, 21.0f, Slabs[i].z);
DrawSlab();
glPopMatrix();
}
}
////////////////////////////////////////////////////////////////////////////////
// Put the Pillers in place
void PlacePillers(void)
{
int i;
// Place each Piller
for(i = 0; i < MAX_EACH; i++)
{
glPushMatrix();
glTranslatef(Pillers[i].x, 23.5f, Pillers[i].z);
DrawPiller();
glPopMatrix();
}
}
////////////////////////////////////////////////////////////////////////////////
// Put the Boxess in place
/*void PlaceBoxes(void)
{
int i;
// Place each Box
for(i = 0; i < MAX_EACH; i++)
{
glPushMatrix();
glTranslatef(Fly[i].x, 0.00f, Fly[i].z);
DrawBox();
glPopMatrix();
}
}
*/
////////////////////////////////////////////////////////////////////////////////
// Render the entire scene
void RenderWorld(void)
{
glCallList(nWorldList);
// Pillers not place in display list because of auxSolidBox problems
PlacePillers();
// PlaceBoxes();
PlaceTrees();
DrawGround();
}
/////////////////////////////////////////////////////////////////////////////
/// Objects contained in the scene
/////////////////////////////////////////////////////////////////////////////////
// Draw the ground just as a grid of lines. No transformation to take
place
void DrawGround(void)
{
int r,c;
int nStep = 1;
// Draw Ground in Green
glRGB(0,255,0);
// The ground has a normal too
// Just draw a bunch of horizontal and vertical lines
glColor3f(0,255,0);
glBegin(GL_LINES);
for(r = -1000; r <= 1000; r += nStep)
{
glVertex3f((float)r, 0.0f, -1000.0f);
glVertex3f((float)r, 0.0f, 1000.0f);
}
for(c = -1000; c <= 1000; c += nStep)
{
glVertex3f(1000.0f, 0.0f, (float)c);
glVertex3f(-1000.0f, 0.0f, (float)c);
}
glEnd();
}
////////////////////////////////////////////////////////////////////////////
// A Tree
void DrawTree()
{
GLfloat vNormal[3];
GLfloat x,z,angle; // Storage for coordinates and angles
GLfloat fStep = (float)PI/4.0f;
GLfloat fHeight = 20.0f;
GLfloat fRadius = 4.0f;
glTranslatef(0, 6.0f, 0);
//brown
glRGB(139,101,8);
// Normals are easy for cylinders
glBegin(GL_QUAD_STRIP);
vNormal[0] = fRadius;
vNormal[1] = fHeight;
vNormal[2] = 0.0f;
ReduceToUnit(vNormal);
glNormal3fv(vNormal);
glVertex3f(fRadius, fHeight/3, 0.0f);
glVertex3f(fRadius, -fHeight/3, 0.0f);
for(angle = fStep; angle < 3.0f*PI; angle += fStep)
{
x = fRadius*fsin(angle);
z = fRadius*fcos(angle);
vNormal[0] = x;
vNormal[1] = fHeight;
vNormal[2] = z;
ReduceToUnit(vNormal);
glNormal3fv(vNormal);
glVertex3f(x, fHeight/3, z );
glVertex3f(x, -fHeight/3, z);
}
glEnd();
// Draw the cone s
glPushMatrix();
glTranslatef(0.0f, 2.0, 0.0f);
glRotatef(-90.0f,1.0f,0.0f,0.0f);
glRGB(0,230,0);
auxSolidCone(12.0f,16.0f);
glTranslatef(0.0f, 0.0, 12.0f);
auxSolidCone(6.0f,8.0f);
glPopMatrix();
}
/////////////////////////////////////////////////////////////////////////////////////
// A Piller or column
void DrawPiller()
{
GLfloat vNormal[3];
GLfloat x,z,angle; // Storage for coordinates and angles
GLfloat fStep = (float)PI/4.0f;
GLfloat fHeight = 20.0f;
GLfloat fRadius = 7.0f;
// Grey
glRGB(128,128,128);
// Normals are easy for cylinders
glBegin(GL_QUAD_STRIP);
vNormal[0] = fRadius;
vNormal[1] = fHeight;
vNormal[2] = 0.0f;
ReduceToUnit(vNormal);
glNormal3fv(vNormal);
glVertex3f(fRadius, fHeight, 0.0f);
glVertex3f(fRadius, -fHeight, 0.0f);
for(angle = fStep; angle < 3.0f*PI; angle += fStep)
{
x = fRadius*fsin(angle);
z = fRadius*fcos(angle);
vNormal[0] = x;
vNormal[1] = fHeight;
vNormal[2] = z;
ReduceToUnit(vNormal);
glNormal3fv(vNormal);
glVertex3f(x, fHeight, z );
glVertex3f(x, -fHeight, z);
}
glEnd();
// Draw the box at both ends
glPushMatrix();
glTranslatef(0.0f, -fHeight-(fRadius/4), 0.0f);
auxSolidBox(fRadius*2.5, fRadius/2, fRadius*2.5);
glTranslatef(0.0f, (fHeight+(fRadius/4))*2, 0.0f);
auxSolidBox(fRadius*2.5, fRadius/2, fRadius*2.5);
glPopMatrix();
}
///////////////////////////////////////////////////////////////////////////////
// Draw a pyramid
void DrawPyramid(void)
{
GLfloat vNormal[3];
GLfloat vvVertices[3][3];
GLfloat fWidth = 15.0f;
GLfloat fHeight = 30.0f;
// Red Pyramids
glRGB(255,0,0);
// Simple, build with four triangles.
glBegin(GL_TRIANGLES);
vvVertices[0][0] = fWidth;
vvVertices[0][1] = 0.0f;
vvVertices[0][2] = fWidth;
vvVertices[1][0] = fWidth;
vvVertices[1][1] = 0.0f;
vvVertices[1][2] = -fWidth;
vvVertices[0][0] = 0.0f;
vvVertices[0][1] = fHeight;
vvVertices[0][2] = 0.0f;
calcNormal(vvVertices, vNormal);
glNormal3fv(vNormal);
glVertex3f(fWidth, 0.0f, fWidth);
glVertex3f(fWidth, 0.0f, -fWidth);
glVertex3f(0.0f, fHeight, 0.0f);
vvVertices[0][0] = fWidth;
vvVertices[0][1] = 0.0f;
vvVertices[0][2] = fWidth;
vvVertices[1][0] = 0.0f;
vvVertices[1][1] = fHeight;
vvVertices[1][2] = 0.0f;
vvVertices[0][0] = -fWidth;
vvVertices[0][1] = 0.0f;
vvVertices[0][2] = fWidth;
calcNormal(vvVertices, vNormal);
glNormal3fv(vNormal);
glVertex3f(fWidth, 0.0f, fWidth);
glVertex3f(0.0f, fHeight, 0.0f);
glVertex3f(-fWidth, 0.0f, fWidth);
vvVertices[0][0] = -fWidth;
vvVertices[0][1] = 0.0f;
vvVertices[0][2] = fWidth;
vvVertices[1][0] = 0.0f;
vvVertices[1][1] = fHeight;
vvVertices[1][2] = 0.0f;
vvVertices[0][0] = -fWidth;
vvVertices[0][1] = 0.0f;
vvVertices[0][2] = -fWidth;
calcNormal(vvVertices, vNormal);
glNormal3fv(vNormal);
glVertex3f(-fWidth, 0.0f, fWidth);
glVertex3f(0.0f, fHeight, 0.0f);
glVertex3f(-fWidth, 0.0f, -fWidth);
vvVertices[0][0] = -fWidth;
vvVertices[0][1] = 0.0f;
vvVertices[0][2] = -fWidth;
vvVertices[1][0] = 0.0f;
vvVertices[1][1] = fHeight;
vvVertices[1][2] = 0.0f;
vvVertices[0][0] = fWidth;
vvVertices[0][1] = 0.0f;
vvVertices[0][2] = -fWidth;
calcNormal(vvVertices, vNormal);
glNormal3fv(vNormal);
glVertex3f(-fWidth, 0.0f, -fWidth);
glVertex3f(0.0f, fHeight, 0.0f);
glVertex3f(fWidth, 0.0f, -fWidth);
glEnd();
}
///////////////////////////////////////////////////////////////////////////////
// Draw the Slabs
void DrawSlab()
{
GLfloat fWidth = 12.0f;
GLfloat fHeight = 20.0f;
GLfloat fDepth = 7.0f;
GLfloat fEdge = 1.0f;
GLfloat vNormal[3];
GLfloat vvVertices[3][3];
// Blue Slabs
glRGB(0,0, 255);
// Simple, build with four triangles.
glBegin(GL_QUADS);
// Front
glNormal3f(0.0f, 0.0f, -1.0f);
glVertex3f(fWidth, fHeight, -fDepth);
glVertex3f(fWidth, -fHeight, -fDepth);
glVertex3f(-fWidth, -fHeight, -fDepth);
glVertex3f(-fWidth, fHeight, -fDepth);
// Back
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(-fWidth, fHeight, fDepth);
glVertex3f(-fWidth, -fHeight, fDepth);
glVertex3f(fWidth, -fHeight, fDepth);
glVertex3f(fWidth, fHeight, fDepth);
// Top
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(fWidth-fEdge, fHeight+fEdge, fDepth-fEdge);
glVertex3f(fWidth-fEdge, fHeight+fEdge, -(fDepth-fEdge));
glVertex3f(-(fWidth-fEdge), fHeight+fEdge, -(fDepth-fEdge));
glVertex3f(-(fWidth-fEdge), fHeight+fEdge, fDepth-fEdge);
// Bottom
glNormal3f(0.0f, -1.0f, 0.0f);
glVertex3f(-(fWidth-fEdge), -(fHeight+fEdge), fDepth-fEdge);
glVertex3f(-(fWidth-fEdge), -(fHeight+fEdge), -(fDepth-fEdge));
glVertex3f(fWidth-fEdge, -(fHeight+fEdge), -(fDepth-fEdge));
glVertex3f(fWidth-fEdge, -(fHeight+fEdge), fDepth-fEdge);
// Left
glNormal3f(1.0f, 0.0f, 0.0f);
glVertex3f(fWidth, fHeight, fDepth);
glVertex3f(fWidth, -fHeight, fDepth);
glVertex3f(fWidth, -fHeight, -fDepth);
glVertex3f(fWidth, fHeight, -fDepth);
// Right
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-fWidth, fHeight, fDepth);
glVertex3f(-fWidth, fHeight, -fDepth);
glVertex3f(-fWidth, -fHeight, -fDepth);
glVertex3f(-fWidth, -fHeight, fDepth);
// Top Bevels
vvVertices[0][0] = fWidth-fEdge;
vvVertices[0][1] = fHeight+fEdge;
vvVertices[0][2] = fDepth-fEdge;
vvVertices[1][0] = -(fWidth-fEdge);
vvVertices[1][1] = fHeight+fEdge;
vvVertices[1][2] = fDepth-fEdge;
vvVertices[2][0] = -fWidth;
vvVertices[2][1] = fHeight;
vvVertices[2][2] = fDepth;
calcNormal(vvVertices,vNormal);
glNormal3fv(vNormal);
glVertex3f(fWidth-fEdge, fHeight+fEdge, fDepth-fEdge);
glVertex3f(-(fWidth-fEdge), fHeight+fEdge, fDepth-fEdge);
glVertex3f(-fWidth, fHeight, fDepth);
glVertex3f(fWidth, fHeight, fDepth);
vvVertices[0][0] = fWidth;
vvVertices[0][1] = fHeight;
vvVertices[0][2] = -fDepth;
vvVertices[1][0] = fWidth-fEdge;
vvVertices[1][1] = fHeight+fEdge;
vvVertices[1][2] = -(fDepth-fEdge);
vvVertices[2][0] = fWidth-fEdge;
vvVertices[2][1] = fHeight+fEdge;
vvVertices[2][2] = fDepth-fEdge;
calcNormal(vvVertices,vNormal);
glNormal3fv(vNormal);
glVertex3f(fWidth, fHeight, -fDepth);
glVertex3f(fWidth-fEdge, fHeight+fEdge, -(fDepth-fEdge));
glVertex3f(fWidth-fEdge, fHeight+fEdge, fDepth-fEdge);
glVertex3f(fWidth, fHeight, fDepth);
vvVertices[0][0] = fWidth;
vvVertices[0][1] = fHeight;
vvVertices[0][2] = -fDepth;
vvVertices[1][0] = -fWidth;
vvVertices[1][1] = fHeight;
vvVertices[1][2] = -fDepth;
vvVertices[2][0] = -(fWidth-fEdge);
vvVertices[2][1] = fHeight+fEdge;
vvVertices[2][2] = -(fDepth-fEdge);
calcNormal(vvVertices,vNormal);
glNormal3fv(vNormal);
glVertex3f(fWidth, fHeight, -fDepth);
glVertex3f(-fWidth, fHeight, -fDepth);
glVertex3f(-(fWidth-fEdge), fHeight+fEdge, -(fDepth-fEdge));
glVertex3f(fWidth-fEdge, fHeight+fEdge, -(fDepth-fEdge));
vvVertices[0][0] = -fWidth;
vvVertices[0][1] = fHeight;
vvVertices[0][2] = fDepth;
vvVertices[1][0] = -(fWidth-fEdge);
vvVertices[1][1] = fHeight+fEdge;
vvVertices[1][2] = fDepth-fEdge;
vvVertices[2][0] = -(fWidth-fEdge);
vvVertices[2][1] = fHeight+fEdge;
vvVertices[2][2] = -(fDepth-fEdge);
calcNormal(vvVertices,vNormal);
glNormal3fv(vNormal);
glVertex3f(-fWidth, fHeight, fDepth);
glVertex3f(-(fWidth-fEdge), fHeight+fEdge, fDepth-fEdge);
glVertex3f(-(fWidth-fEdge), fHeight+fEdge, -(fDepth-fEdge));
glVertex3f(-fWidth, fHeight, -fDepth);
// Bottom Bevels
vvVertices[0][0] = fWidth;
vvVertices[0][1] = -fHeight;
vvVertices[0][2] = fDepth;
vvVertices[1][0] = -fWidth;
vvVertices[1][1] = -fHeight;
vvVertices[1][2] = fDepth;
vvVertices[2][0] = -(fWidth-fEdge);
vvVertices[2][1] = -(fHeight+fEdge);
vvVertices[2][2] = fDepth-fEdge;
calcNormal(vvVertices,vNormal);
glNormal3fv(vNormal);
glVertex3f(fWidth, -fHeight, fDepth);
glVertex3f(-fWidth, -fHeight, fDepth);
glVertex3f(-(fWidth-fEdge), -(fHeight+fEdge), fDepth-fEdge);
glVertex3f(fWidth-fEdge, -(fHeight+fEdge), fDepth-fEdge);
vvVertices[0][0] = fWidth;
vvVertices[0][1] = -fHeight;
vvVertices[0][2] = fDepth;
vvVertices[1][0] = fWidth-fEdge;
vvVertices[1][1] = -(fHeight+fEdge);
vvVertices[1][2] = fDepth-fEdge;
vvVertices[2][0] = fWidth-fEdge;
vvVertices[2][1] = -(fHeight+fEdge);
vvVertices[2][2] = -(fDepth-fEdge);
calcNormal(vvVertices,vNormal);
glNormal3fv(vNormal);
glVertex3f(fWidth, -fHeight, fDepth);
glVertex3f(fWidth-fEdge, -(fHeight+fEdge), fDepth-fEdge);
glVertex3f(fWidth-fEdge, -(fHeight+fEdge), -(fDepth-fEdge));
glVertex3f(fWidth, -fHeight, -fDepth);
vvVertices[0][0] = fWidth-fEdge;
vvVertices[0][1] = -(fHeight+fEdge);
vvVertices[0][2] = -(fDepth-fEdge);
vvVertices[1][0] = -(fWidth-fEdge);
vvVertices[1][1] = -(fHeight+fEdge);
vvVertices[1][2] = -(fDepth-fEdge);
vvVertices[2][0] = -fWidth;
vvVertices[2][1] = -fHeight;
vvVertices[2][2] = -fDepth;
calcNormal(vvVertices,vNormal);
glNormal3fv(vNormal);
glVertex3f(fWidth-fEdge, -(fHeight+fEdge), -(fDepth-fEdge));
glVertex3f(-(fWidth-fEdge), -(fHeight+fEdge), -(fDepth-fEdge));
glVertex3f(-fWidth, -fHeight, -fDepth);
glVertex3f(fWidth, -fHeight, -fDepth);
vvVertices[0][0] = -fWidth;
vvVertices[0][1] = -fHeight;
vvVertices[0][2] = -fDepth;
vvVertices[1][0] = -(fWidth-fEdge);
vvVertices[1][1] = -(fHeight+fEdge);
vvVertices[1][2] = -(fDepth-fEdge);
vvVertices[2][0] = -(fWidth-fEdge);
vvVertices[2][1] = -(fHeight+fEdge);
vvVertices[2][2] = fDepth-fEdge;
calcNormal(vvVertices,vNormal);
glNormal3fv(vNormal);
glVertex3f(-fWidth, -fHeight, -fDepth);
glVertex3f(-(fWidth-fEdge), -(fHeight+fEdge), -(fDepth-fEdge));
glVertex3f(-(fWidth-fEdge), -(fHeight+fEdge), fDepth-fEdge);
glVertex3f(-fWidth, -fHeight, fDepth);
glEnd();
}
///////////////////////////////////////////////////////////////////////////////
// This consists of just a box
/*void DrawBox(void)
{
// Position the box
glPushMatrix();
// Place and orient box
glTranslatef(flyPos.xPos, 5.0f, flyPos.zPos);
glRotatef(dRadToDeg(flyPos.radsFromEast+((float)PI/2.0f)), 0.0f,
1.0f, 0.0f);
// Draw box
glRGB(255,125,150);
glPushMatrix();
auxSolidBox(25.0f, 11.0f, 40.0f);
glPopMatrix();
glPopMatrix();
}
*/