Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#define PIXEL_CENTER(x) ((long)(x) + 0.5)
void GLAleft();
void GLAright();
void GLAup();
void GLAdown();
void GLAzoomin();
void GLAzoomout();
void drawmountain();
void drawmoon();
void drawstar();
void drawstarpt();
void drawbox();
void drawcart_box();
void drawcart_wheel();
void drawcart_guy();
void drawcart_arm();
void drawcart_gum();
GLenum rgb, doubleBuffer, windType;
GLint windW, windH;
const float pi = 3.14159265;
GLint boxW, boxH;
float color[3];
int frame;
int numframes = 20;
float GLAparams[9]= {0,0,5, 0,0,0, 0,1,0};
float bezierpts[12] = {-50, 0, 0, -50, 4, 0, 50, 0, 0, 50, -2, 0};
// Initialize OpenGL window - prepare the frame-buffer for z-buffering.
static void glInit ()
{
// Clear color
glPushAttrib(GL_COLOR_BUFFER_BIT);
glColorMask(1, 1, 1, 1);
glIndexMask(~0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glPopAttrib();
// Enable Depth testing
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
}
// Function that gets called when the window is resized.
static void Reshape(int width, int height)
{
// Define window size.
windW = (GLint)width;
windH = (GLint)height;
// Viewport mapping
glViewport(0, 0, windW, windH);
// Define a perspective projection with a 45 degree field of view
// and looking from the the positive z axis at (0,0,10) towards the origin.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glFrustum(-10.0, 10.0, -10.0, 10.0, 1.0, 20.0); // Alternate method of specifying viewing paramters.
gluPerspective (45.0, 1.0, 1.0, 20.0);
gluLookAt ( GLAparams[0],
GLAparams[1],
GLAparams[2],
GLAparams[3],
GLAparams[4],
GLAparams[5],
GLAparams[6],
GLAparams[7],
GLAparams[8]);//,0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// Switch matrix stack to modelview stack.
glMatrixMode(GL_MODELVIEW);
}
void drawmountain(void)//Draws a snow-capped gray mountain.
{
glBegin(GL_POLYGON);//Mountain itself
glColor3f(0.4, 0.4, 0.4);
glVertex3f(-2, 0, 0);
glVertex3f(0, 5, 0);
glVertex3f(2, 0, 0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(0.4, 0.4, 0.4);
glVertex3f(2, 0, 0);
glVertex3f(0, 0, -2);
glVertex3f(0, 5, 0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(0.4, 0.4, 0.4);
glVertex3f(-2, 0, 0);
glVertex3f(0, 0, -2);
glVertex3f(0, 5, 0);
glEnd();
glBegin(GL_POLYGON);//Snow-capped peak
glColor3f(0.8, 0.8, 0.8);
glVertex3f(0, 5, 0.01);
glVertex3f(-.5, 3.75, 0.01);
glVertex3f(.5, 3.75,0.01);
glEnd();
}
void drawmoon()//draws a slightly yellow moon;
{
glBegin(GL_POLYGON);//yellow portion of moon
glColor3f(1, 1, 0.4);
GLUquadricObj * x;
x = gluNewQuadric();
gluSphere(x, 1, 100, 100);
glEnd();
}
void drawstar()//draws a four pointed white star
{
drawstarpt();
glRotatef(90, 0, 0, 1);
drawstarpt();
glRotatef(90, 0, 0, 1);
drawstarpt();
glRotatef(90, 0, 0, 1);
drawstarpt();
}
void drawstarpt()//helper function for drawstar, draws one of four points for a star
{
glBegin(GL_POLYGON);
glColor3f(1,1,1);
glVertex3f(0, 0, 0);
glVertex3f(1, 1, 0);
glVertex3f(0, 6, 0);
glVertex3f(-1, 1, 0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(1,1,1);
glVertex3f(0, 0, 0);
glVertex3f(1, 1, 1);
glVertex3f(1, 1, 0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(1,1,1);
glVertex3f(1, 1, 0);
glVertex3f(1, 1, 1);
glVertex3f(0, 6, 0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(1,1,1);
glVertex3f(0, 0, 0);
glVertex3f(-1, 1, 1);
glVertex3f(-1, 1, 0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(1,1,1);
glVertex3f(-1, 1, 0);
glVertex3f(-1, 1, 1);
glVertex3f(0, 6, 0);
glEnd();
}
void drawbox (void)//mod of provided drawbox, box is all red.
{
glBegin (GL_POLYGON);
glColor3f (1.0, 0.0, 0.0);
glVertex3f (-0.5, -0.5, 0.5);
glVertex3f (0.5, -0.5, 0.5);
glVertex3f (0.5, 0.5, 0.5);
glVertex3f (-0.5, 0.5, 0.5);
glEnd ();
glBegin (GL_POLYGON);
glColor3f (1.0, 0.0, 0.0);
glVertex3f (-0.5, -0.5, 0.5);
glVertex3f (-0.5, 0.5, 0.5);
glVertex3f (-0.5, 0.5, -0.5);
glVertex3f (-0.5, -0.5, -0.5);
glEnd ();
glBegin (GL_POLYGON);
glColor3f (1.0, 0.0, 0.0);
glVertex3f (0.5, -0.5, 0.5);
glVertex3f (0.5, 0.5, 0.5);
glVertex3f (0.5, 0.5, -0.5);
glVertex3f (0.5, -0.5, -0.5);
glEnd ();
glBegin (GL_POLYGON);
glColor3f (1.0, 0.0, 0.0);
glVertex3f (-0.5, 0.5, 0.5);
glVertex3f (0.5, 0.5, 0.5);
glVertex3f (0.5, 0.5, -0.5);
glVertex3f (-0.5, 0.5, -0.5);
glEnd ();
glBegin (GL_POLYGON);
glColor3f (1.0, 0.0, 0.0);
glVertex3f (-0.5, -0.5, 0.5);
glVertex3f (0.5, -0.5, 0.5);
glVertex3f (0.5, -0.5, -0.5);
glVertex3f (-0.5, -0.5, -0.5);
glEnd ();
glBegin (GL_POLYGON);
glColor3f (1.0, 0.0, 0.0);
glVertex3f (-0.5, -0.5, -0.5);
glVertex3f (-0.5, 0.5, -0.5);
glVertex3f (0.5, 0.5, -0.5);
glVertex3f (0.5, -0.5, -0.5);
glEnd ();
}
void drawcart_box()
{
glPushMatrix();
glScalef(1.5, 0.7, 1);
drawbox();
glPopMatrix();
}
void drawcart_wheel()//draws one of the cart's wheels
{
glBegin(GL_POLYGON);
glColor3f(.5, .5, .5);
GLUquadricObj * x;
x = gluNewQuadric();
gluCylinder(x, 1, 1, .5, 100, 100);
glPushMatrix();
glRotatef(90,0,0,1);
glScalef(.1, 1.8, .1);
drawbox();
glPopMatrix();
glPushMatrix();
glScalef(.1, 1.8, .1);
drawbox();
glPopMatrix();
glEnd();
}
void drawcart_guy()
{
glBegin(GL_POLYGON);//draw the guy's shoulders/head
glColor3f(1, 0.8, 0.7);
GLUquadricObj * x;
x = gluNewQuadric();
gluSphere(x, 1, 100, 100);
glPushMatrix();
glColor3f(.2, 1, .1);
glTranslatef(0, -1, 0);
glScalef(2.1, .8, .3);
gluSphere(x, 1, 100, 100);
//glPopMatrix(); //forgot this, bugB
glEnd();
}
void drawcart_arm()
{
glBegin(GL_POLYGON);
glColor3f(.1, 1.8, .1);
GLUquadricObj * x;
x = gluNewQuadric();
gluCylinder(x,.1, .1, 1, 10,10);
glPushMatrix();
glColor3f(1, .8, .7);
glTranslatef(0, 0, 1);
gluSphere(x, .2, 10, 10);
glPopMatrix();
glEnd();
}
void drawcart_gum()
{
glBegin(GL_POLYGON);
GLUquadricObj * x;
x = gluNewQuadric();
glColor3f(1, 0, .5);
gluSphere(x, 1, 10, 10);
glEnd();
}
// Draws the scene at any point in time.
static void Draw(void)
{
// Clear color and depth buffers
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
gluLookAt ( GLAparams[0],
GLAparams[1],
GLAparams[2],
GLAparams[3],
GLAparams[4],
GLAparams[5],
GLAparams[6],
GLAparams[7],
GLAparams[8]);
glPushMatrix();//Background drawing
glTranslatef(5, 5, -10);
drawmoon();
glPopMatrix();
glPushMatrix();
glScalef(.03,.03,.03);
glTranslatef(-30, 40, -10);
drawstar();
glPopMatrix();
glPushMatrix();
glScalef(.03,.03,.03);
glTranslatef(-70, 30, -10);
drawstar();
glPopMatrix();
glPushMatrix();
glScalef(.03,.03,.03);
glTranslatef(120, 20, -10);
drawstar();
glPopMatrix();
glPushMatrix();
glScalef(.03,.03,.03);
glTranslatef(-130, 100, -10);
drawstar();
glPopMatrix();
glPushMatrix();
glScalef(.03,.03,.03);
glTranslatef(60, 75, -10);
drawstar();
glPopMatrix();
glPushMatrix();
glScalef(.03,.03,.03);
glTranslatef(-50, 120, -10);
drawstar();
glPopMatrix();
glPushMatrix();
glTranslatef(-5,-3 ,-5);
drawmountain();
glPopMatrix();//stars moon and mountain drawn
glPushMatrix ();//main cart drawing code, assembles pieces
//translation code here
drawcart_box();
glPushMatrix();
glScalef(.2, .2, .2);
glTranslatef(-2, -1.4, 2.8);
glRotatef(frame*360. / numframes, 0, 0, 1);
drawcart_wheel();
glPopMatrix();
glPushMatrix();
glScalef(.2, .2, .2);
glTranslatef(2, -1.4, 2.8);
glRotatef(frame*360. / numframes, 0, 0, 1);
drawcart_wheel();
glPopMatrix();
glPushMatrix();
glScalef(.2, .2, .2);
glTranslatef(-2, -1.4, -3.2);
glRotatef(frame*360. / numframes, 0, 0, 1);
drawcart_wheel();
glPopMatrix();
glPushMatrix();
glScalef(.2, .2, .2);
glTranslatef(2, -1.4, -3.2);
glRotatef(frame*360. / numframes, 0, 0, 1);
drawcart_wheel();
glPopMatrix();//box of cart and wheels drawn and moving
glPushMatrix();
glScalef(.17, .17, .17);
glTranslatef(0, 3, 0);
drawcart_guy();
glPopMatrix();//guys bust drawn
glPushMatrix();
glScalef( (float) frame / numframes,
(float) frame / numframes,
(float) frame / numframes );
glTranslatef(0, .5, 1.2+(.9* (float) frame / numframes) );
drawcart_gum();
glPopMatrix();//gum is drawn and scaling;
glPushMatrix();
glScalef(2, 2, 2);
glTranslatef(1.45, -1 + (.2*sin(8*pi*frame / numframes)), 0);
glRotatef(270, 1, 0, 0);
drawcart_arm();
glPopMatrix();
glPushMatrix();
glScalef(2, 2, 2);
glTranslatef(-1.45, -1 + (.2*sin(8*pi*frame / numframes)), 0);
glRotatef(270, 1, 0, 0);
drawcart_arm();
glPopMatrix();
glPopMatrix();//fixB
glPopMatrix ();//all drawn and animated
glFlush();
// Increment the rotation angle
frame += 1.0;
if (frame == numframes) frame = 0.0;
if (doubleBuffer) {
glutSwapBuffers();
}
}
// Called when a keyboard key is pressed
static void Key(unsigned char key, int x, int y)
{
switch (key) {
case 27:
printf ("exit!\n");
exit(1);
default:
return;
}
glutPostRedisplay();
}
// Called when special keys are pressed - arrows and page-up/down
static void SpecialKey(int key, int x, int y)
{
switch (key) {
case GLUT_KEY_PAGE_UP: /* PAGE UP key pressed */
{
GLAzoomin();
break;
}
case GLUT_KEY_PAGE_DOWN: /* PAGE DOWN key pressed */
{
GLAzoomout();
break;
}
case GLUT_KEY_UP: /* Up arrow pressed */
{
GLAup();
break;
}
case GLUT_KEY_DOWN: /* Down arrow pressed */
{
GLAdown();
break;
}
case GLUT_KEY_LEFT: /* Left arrow pressed */
{
GLAleft();
break;
}
case GLUT_KEY_RIGHT: /* Right arrow pressed */
{
GLAright();
break;
}
default:
return;
}
glutPostRedisplay();
}
// Read input.
static GLenum Args(int argc, char **argv)
{
GLint i, inputfile_count;
rgb = GL_TRUE;
doubleBuffer = GL_TRUE;
inputfile_count = 0;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-ci") == 0) {
rgb = GL_FALSE;
} else if (strcmp(argv[i], "-rgb") == 0) {
rgb = GL_TRUE;
} else if (strcmp(argv[i], "-sb") == 0) {
doubleBuffer = GL_FALSE;
} else if (strcmp(argv[i], "-db") == 0) {
doubleBuffer = GL_TRUE;
}
else {
//printf("%s (Bad option).\n", argv[i]);
//return GL_FALSE;
}
}
return GL_TRUE;
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
if (Args(argc, argv) == GL_FALSE) {
exit(1);
}
// Initialize window size.
windW = 512;
windH = 512;
glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH);
// Enable frame buffer for double buffering and z-buffering.
windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(windType | GLUT_DEPTH);
if (glutCreateWindow("Sample Animation") == GL_FALSE) {
exit(1);
}
frame = 0.0; // Initialize frame to 0.0
glInit ();
glutReshapeFunc(Reshape); // Set reshape function
glutIdleFunc(Draw); // Even if no events, redraw to animate
glutKeyboardFunc(Key); // Set keyboard function
glutSpecialFunc(SpecialKey); // Set special keyboard function (arrow keys)
glutDisplayFunc(Draw); // Set Display function
glutMainLoop();
return 0;
}
void GLAleft()//rotates camera left
{
float magnitude = GLAparams[0] * GLAparams[0] +
GLAparams[2] * GLAparams[2];
magnitude = sqrt(magnitude);
float angle = asin(GLAparams[0] / magnitude);
angle = angle - (pi / 32);
GLAparams[0] = sin(angle) * magnitude;
GLAparams[2] = cos(angle) * magnitude;
}
void GLAright()//roatates camera right
{
float magnitude = GLAparams[0] * GLAparams[0] +
GLAparams[2] * GLAparams[2];
magnitude = sqrt(magnitude);
float angle = asin(GLAparams[0] / magnitude);
angle = angle + (pi / 32);
GLAparams[0] = sin(angle) * magnitude;
GLAparams[2] = cos(angle) * magnitude;
}
void GLAup()//rotates camera up
{
float magnitude = GLAparams[1] * GLAparams[1] +
GLAparams[2] * GLAparams[2];
magnitude = sqrt(magnitude);
float angle = asin(GLAparams[1] / magnitude);
angle = angle + (pi / 32.);
if (angle <= (pi/2.) - .1)
{
GLAparams[1] = sin(angle) * magnitude;
GLAparams[2] = cos(angle) * magnitude;
}
}
void GLAdown()//rotates camera down
{
float magnitude = GLAparams[1] * GLAparams[1] +
GLAparams[2] * GLAparams[2];
magnitude = sqrt(magnitude);
float angle = asin(GLAparams[1] / magnitude);
angle = angle - (pi / 32.);
if (angle >= -1*((pi/2.) - .1))
{
GLAparams[1] = sin(angle) * magnitude;
GLAparams[2] = cos(angle) * magnitude;
}
}
void GLAzoomin()//zooms in
{
GLAparams[0]=GLAparams[0] / 2.0;
GLAparams[1]=GLAparams[1] / 2.0;
GLAparams[2]=GLAparams[2] / 2.0;
}
void GLAzoomout()//zooms out
{
GLAparams[0]=GLAparams[0] * 2.0;
GLAparams[1]=GLAparams[1] * 2.0;
GLAparams[2]=GLAparams[2] * 2.0;
}