You are on page 1of 25

#include<GL/glut.

h>
#include<iostream.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<GLU.h>

const GLfloat PI=3.141f;


const GLfloat TWO_PI=2*PI;
const GLfloat RAD_TO_DEG=180.0/PI;
const GLfloat INNER_RADIUS=90.0;
const GLfloat TRACK_WIDTH=20.0;
const GLfloat TRACK_MIDDLE=INNER_RADIUS+0.5*TRACK_WIDTH;

GLfloat grass[]={0.0f,0.8f,0.1f};
GLfloat road[]={0.2f,0.2f,0.2f};
GLfloat car_body[]={0.2f,0.0f,0.9f};
GLfloat car_axle[]={0.4f,0.4f,0.4f};
GLfloat car_wheel[]={1.0,0.0,0.0};
GLfloat house_wall[]={0.7f,0.4f,0.2f};
GLfloat house_roof[]={0.8f,0.0,0.2f};
GLfloat fog[4]={0.7f,0.7f,0.7f,1.0f};

enum

{
DISTANT,INSIDE,OUTSIDE,DRIVER,HOUSE,OTHER,BESIDE,BALLOON,HELICOPTER,AUTO
}
view=DISTANT;

GLUquadricObj *p;

GLfloat car_direction=0.0;
GLfloat car_x_pos=100.0;
GLfloat car_y_pos=0.0;
GLfloat car_z_pos=0.0;
GLfloat height=5.0;
GLfloat zoom=50.0;
GLfloat mouse_x=0.0;
GLfloat mouse_y=0.0;

GLint win_width=400;
GLint win_height=300;

bool movie_mode=false;
long clock=0;
long next_switch_time=0;
bool fog_enabled=false;
GLfloat fog_density=0.01f;
GLfloat bumpiness=0.0;

void draw_car()
{

glPushMatrix();
glTranslatef(0.0,0.0,3.0);
glRotatef(95.0,0.0,1.0,0.0);
glColor3fv(car_body);
gluCylinder(p,2.0,1.0,12.0,10,12);
gluDisk(p,0.0,2.0,25,5);
glTranslatef(0.0,0.0,12.0);
gluDisk(p,0.0,1.0,20,5);
glPopMatrix();

glPushMatrix();

glColor3fv(car_axle);
glTranslatef(3.0,-3.0,2.0);
glRotatef(90.0,-1.0,0.0,0.0);
gluCylinder(p,0.5,0.5,6.0,10,1);
glColor3fv(car_wheel);
gluDisk(p,0.0,2.0,25,5);
glTranslatef(0.0,6.0,0.0);
gluDisk(p,0.0,1.0,25,5);

glPopMatrix();

glPushMatrix();
glTranslatef(9.0,-2.0,1.0);
glRotatef(90.0,-1.0,0.0,0.0);
glColor3fv(car_axle);
gluCylinder(p,0.3f,0.3f,4.0,10,1);
glColor3fv(car_wheel);
gluDisk(p,0.0,1.0,20,5);
glTranslatef(0.0,0.0,4.0);
gluDisk(p,0.0,1.0,20,5);
glPopMatrix();

void draw_house(GLfloat x,GLfloat y,GLfloat size)

{
glPushMatrix();
glTranslatef(x,y,0.0);
glScalef(size,size,size);
glBegin(GL_POLYGON);
glColor3fv(house_wall);
glVertex3f(1.0,-1.0,0.0);
glVertex3f(1.0,-1.0,1.0);
glVertex3f(-1.0,-1.0,1.0);
glVertex3f(-1.0,-1.0,0.0);
glVertex3f(1.0,-1.0,0.0);
glVertex3f(1.0,1.0,0.0);
glVertex3f(1.0,1.0,1.0);
glVertex3f(1.0,-1.0,1.0);
glVertex3f(-1.0,1.0,0.0);
glVertex3f(-1.0,1.0,1.0);
glVertex3f(1.0,1.0,1.0);
glVertex3f(1.0,1.0,0.0);

glVertex3f(-1.0,-1.0,1.0);
glVertex3f(-1.0,1.0,1.0);
glVertex3f(-1.0,1.0,0.0);
glVertex3f(-1.0,-1.0,0.0);

glColor3fv(house_roof);

glVertex3f(1.0,-1.0,1.0);
glVertex3f(0.0,-1.0,1.5);
glVertex3f(0.0,1.0,1.5);
glVertex3f(1.0,1.0,1.0);
glVertex3f(-1.0,-1.0,1.0);
glVertex3f(0.0,-1.0,1.5);
glVertex3f(0.0,1.0,1.5);
glVertex3f(-1.0,1.0,1.0);

glEnd();
glBegin(GL_TRIANGLES);

glVertex3f(-1.0,-1.0,1.0);
glVertex3f(0.0,-1.0,1.5);
glVertex3f(1.0,-1.0,1.0);
glVertex3f(-1.0,1.0,1.0);

glVertex3f(0.0,1.0,1.5);
glVertex3f(1.0,1.0,1.0);
glEnd();

glPopMatrix();

void draw_scenery()

glColor3fv(grass);
gluDisk(p,0.0,INNER_RADIUS,50,5);
glColor3fv(road);
gluDisk(p,INNER_RADIUS,INNER_RADIUS+TRACK_WIDTH,50,5);
draw_house(-20.0,50.0,5.0);
draw_house(0.0,70.0,10.0);
draw_house(20.0,-10.0,8.0);
draw_house(40.0,120.0,10.0);

draw_house(-30.0,-50.0,7.0);
draw_house(10.0,-60.0,10.0);
draw_house(-20.0,75.0,8.0);
draw_house(-40.0,140.0,10.0);

void set_viewpoint()
{

switch(view)
{

case DISTANT:
gluLookAt(250.0,0.0,20.0*height,0.0,0.0,0.0,0.0,0.0,1.0);

draw_scenery();
glTranslatef(car_x_pos,car_y_pos,car_z_pos);
glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,-1.0);
draw_car();

break;

case INSIDE:

gluLookAt(85.0,0.0,height,car_x_pos,car_y_pos,0.0,0.0,0.0,1.0);

draw_scenery();

glTranslatef(car_x_pos,car_y_pos,car_z_pos);
glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,-1.0);
draw_car();

break;

case OUTSIDE:

gluLookAt(115.0,0.0,height,car_x_pos,car_y_pos,0.0,0.0,0.0,1.0);

draw_scenery();

glTranslatef(car_x_pos,car_y_pos,car_z_pos);
glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,-1.0);
draw_car();

break;

case DRIVER:

gluLookAt(2.0,0.0,height,12.0,0.0,2.0,0.0,0.0,1.0);

draw_car();

glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,-1.0);
glTranslatef(-car_x_pos,-car_y_pos,car_z_pos);

draw_scenery();
break;

case HOUSE:

glRotatef(RAD_TO_DEG*car_direction,0.0,-1.0,0.0);

gluLookAt(2.0,0.0,height,40.0-car_x_pos,120.0-car_y_pos,car_z_pos,0.0,0.0,1.0);

draw_car();

glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,-1.0);
glTranslatef(-car_x_pos,-car_y_pos,car_z_pos);

draw_scenery();

break;

case OTHER:

gluLookAt(25.0,5.0,height,0.0,0.0,3.0+car_z_pos,0.0,0.0,1.0);
draw_car();
glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,1.0);
glTranslatef(-car_x_pos,-car_y_pos,0.0);
draw_scenery();
break;

case BESIDE:

gluLookAt(5.0,15.0,height,5.0,0.0,3.0+car_z_pos,0.0,0.0,1.0);
draw_car();
glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,1.0);
glTranslatef(-car_x_pos,-car_y_pos,0.0);
draw_scenery();
break;

case BALLOON:

gluLookAt(150.0,75.0,250.0,200.0*mouse_x,200.0*mouse_y,0.0,0.0,0.0,1.0);
draw_scenery();

glTranslatef(car_x_pos,car_y_pos,car_z_pos);

glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,-1.0);
draw_car();
break;

case HELICOPTER:

gluLookAt(200.0*mouse_x,200.0*mouse_y,200.0,0.0,0.0,0.0,0.0,0.0,1.0);
draw_scenery();
glTranslatef(car_x_pos,car_y_pos,car_z_pos);
glRotatef(RAD_TO_DEG*car_direction,0.0,0.0,-1.0);
draw_car();
break;

void display(void)
{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
set_viewpoint();
glutSwapBuffers();
}

void set_projection()
{

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(zoom,GLfloat(win_width)/GLfloat(win_height),1.0,500.0);
}

void reshape(GLint new_width,GLint new_height)


{
win_height=new_width;
win_height=new_height;
glViewport(0,0,win_width,win_height);
set_projection();
}

void drive()
{
car_direction +=0.05f;
if(car_direction>TWO_PI)
car_direction-=TWO_PI;

car_x_pos=TRACK_MIDDLE*sin(car_direction);
car_y_pos=TRACK_MIDDLE*cos(car_direction);
car_z_pos=(bumpiness*rand())/RAND_MAX;

if(movie_mode)
{
clock++;
if(clock>next_switch_time)
{
next_switch_time+=20+rand()%200;

cout<<
"Time:"<<clock<<".Next change:"<<next_switch_time<<'.'<<endl;

switch(rand()%7)
{
case 0:
view=DISTANT;
break;

case 1:
view=DISTANT;
break;

case 2:
view=OUTSIDE;
break;

case 3:
view=DRIVER;
break;

case 4:
view=HOUSE;
break;

case 5:
view=OTHER;
break;

case 6:
view=BESIDE;
break;
}
}
}
glutPostRedisplay();
}

void mouse(int x,int y)


{
mouse_x=(2.0*x)/win_width-1.0;
mouse_y=(2.0*y)/win_width-1.0;
}

void set_fog_density(GLfloat density)


{
fog_density=density;
cout<<"Fog density:"<<fog_density<<endl;
glFogf(GL_FOG_DENSITY,fog_density);
}

void keyboard(unsigned char key, int x,int y)


{

switch(key)
{

case'b':

if(bumpiness=0.0)
{
cout<<"Bumpy road! Use ',' and '>' to change bumpiness."<<endl;
bumpiness=0.1f;
}
else
{
cout<<"smooth road again!"<<endl;
bumpiness=0.0;
}
break;

case'<': bumpiness/=2.0;
break;

case'>': bumpiness*=2.0;
break;

case'f':

if(fog_enabled)
{
glDisable(GL_FOG);
cout<<"it's a clear day!"<<endl;
fog_enabled=false;
}
else
{
glEnable(GL_FOG);
cout<<"It's foggy:use +/- to change fog density."<<endl;
set_fog_density(0.01f);
fog_enabled=true;
}
break;

case'+':
set_fog_density(2.0*fog_density);
break;

case'-':
set_fog_density(0.5f*fog_density);
break;

case 27:
exit(0);
}
}

void keys(int key,int x,int y)


{

switch(key)
{

case GLUT_KEY_LEFT:

zoom*=1.2f;
cout<<"zoom angle="<<zoom<<endl;
set_projection();
break;

case GLUT_KEY_RIGHT:

zoom/=1.2f;
cout<<"zoom angle="<<zoom<<endl;
set_projection();
break;

case GLUT_KEY_UP:

height+=1.0f;
cout<<"height="<<height<<endl;
break;

case GLUT_KEY_DOWN:

height-=1.0f;
cout<<"height="<<height<<endl;
break;

case GLUT_KEY_F1:
movie_mode=false;
view=DISTANT;
cout<<"Distant,fixed camera projection."<<endl;
break;

case GLUT_KEY_F2:
movie_mode=false;
cout<<"view from a panning camera inside the track."<<endl;
view=INSIDE;
break;

case GLUT_KEY_F3:
movie_mode=false;
cout<<"view from a panning camera outside the track."<<endl;
view=OUTSIDE;
break;

case GLUT_KEY_F4:
movie_mode=false;
view=DRIVER;
height=6.0;
zoom=75.0;
set_projection();
cout<<"view from the driver's seat."<<endl;
break;

case GLUT_KEY_F5:
movie_mode=false;
view=HOUSE;
cout<<"looking at a house while driving around."<<endl;
break;

case GLUT_KEY_F6:
movie_mode=false;
view=OTHER;
cout<<"looking back from the car in front."<<endl;
break;

case GLUT_KEY_F7:
movie_mode=false;
view=BESIDE;
cout<<"view from another car."<<endl;
break;

case GLUT_KEY_F8:
movie_mode=false;
view=BALLOON;
cout<<"view from a baloon: use mouse to change viewing direction"<<endl;
break;

case GLUT_KEY_F9:
movie_mode=false;
view=HELICOPTER;
cout<<"View from a helicopter: move mouse to fly around"<<endl;

break;

case GLUT_KEY_F10:
movie_mode=true;
clock=0;
next_switch_time=0;
cout<<"MOVIE MODE:views change at random intervals"<<endl;
break;

case GLUT_KEY_END:
exit(0);
}
}

void main(int argc,char*argv[])


{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGBA);
glutInitWindowSize(win_width,win_height);
glutInitWindowPosition(100,100);
glutCreateWindow("An OpenGL Window");
glutDisplayFunc(display);
glutReshapeFunc(reshape);

glutIdleFunc(drive);
glutPassiveMotionFunc(mouse);
glutKeyboardFunc(keyboard);
glutSpecialFunc(keys);

glEnable(GL_DEPTH_TEST);
p=gluNewQuadric();
gluQuadricDrawStyle(p,GLU_FILL);
glFogi(GL_FOG_MODE,GL_EXP);
glFogfv(GL_FOG_COLOR,fog);
glFogf(GL_FOG_DENSITY,fog_density);
glClearColor(fog[0],fog[1],fog[2],fog[3]);

set_projection();

cout<<"change camera projections:"<<endl<<"Press keys F1,F2,F3,...,F9. Movie


mode:F10"<<endl<<"Bumpiness:"<<endl<<"Press 'b' to toggle bumpy road conditions."<<endl<<"press
'<' ('>') to decrease(increase) bumpiness."<<endl<<"Fog:"<<endl<<"press 'f' to toggle fog
effect."<<endl<<"press '+' ('-') to increase(decrease) fog"<<endl<<"press ESC to stop
program."<<endl<<"Keep window small for fast action."<<endl;
glutMainLoop();

You might also like