challenge 1: Add tree objects into OpenGL space
#include <GL/freeglut.h>
#define DEGREES_PER_PIXEL 0.6f
#define UNITS_PER_PIXEL 0.1f
#define ZOOM_FACTOR 0.04f
#define earth_RADIUS 2.0f
#define SPOTLIGHT_RADIUS 0.5f
void EnableLighting();
void LoadTextureMap();
typedef struct
{
bool leftButton;
bool rightButton;
int x;
int y;
} MouseState;
MouseState mouseState = {false, false, 0, 0};
GLuint tex_ID;
/* scene rotation angles to alter interactively */
float xRotate = 0, yRotate = 0;
/* quadrics pointers for GLU spheres and cylinders */
GLUquadricObj *earthObj;
/* camera position and orientation -- used by gluLookAt */
GLfloat eye[] = {0, 0, 10};
GLfloat at[] = {0, 0, 0};
/* light1 position -- along the z-axis (to be used later) */
GLfloat light1_position[]={0.0, 0.0, 1.0, 1.0};
/* The earth is a sphere centered at the origin
* of the coordinate system.
*/
void earth(float x, float y, float z)
{
glPushMatrix();
glScalef(earth_RADIUS, earth_RADIUS, earth_RADIUS);
glTranslatef(x, y, z);
glRotatef(90,1.0f,0.0f,0.0f);
gluSphere(earthObj, 1.0, 20, 20);
glPopMatrix();
}
void DrawScene()
{
/* Rotate the scene in the x and y directions */
glRotatef(xRotate, 0,1,0);
glRotatef(yRotate, 1,0,0);
earth(0, 0, 0);
}
/*
* This function is called whenever the display needs
* to be redrawn. First called when program starts.
*/
void Display(void)
{
/* Draw to the back buffer */
glDrawBuffer( GL_BACK );
/* Clear the display */
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* (Re)position the camera */
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], 0,1,0);
DrawScene();
/* Before returning, flush the graphics buffer,
* so all graphics appear in the window */
glFlush();
glutSwapBuffers();
}
/*
* A special keyboard event occurs when the user presses a
* special key (arrows, F? keys). Arrows cause the scene to
* move in the direction indicated; this is accomplished by
* moving camera position (and maintaining the orientation).
* HOME and END keys should cause the scene to zoom in and
* out; this is accomplished by moving the camera along the
* vector between the eye and the lookat point.
*/
void SpecialKey(int key, int x, int y)
{
switch(key) {
case GLUT_KEY_LEFT:
/* as camera moves to the right, the image moves to the left */
eye[0] = eye[0] + UNITS_PER_PIXEL;
at[0] = at[0] + UNITS_PER_PIXEL;
break;
case GLUT_KEY_RIGHT:
eye[0] = eye[0] - UNITS_PER_PIXEL;
at[0] = at[0] - UNITS_PER_PIXEL;
break;
case GLUT_KEY_UP:
eye[1] = eye[1] - UNITS_PER_PIXEL;
at[1] = at[1] - UNITS_PER_PIXEL;
break;
case GLUT_KEY_DOWN:
eye[1] = eye[1] + UNITS_PER_PIXEL;
at[1] = at[1] + UNITS_PER_PIXEL;
break;
case GLUT_KEY_END: /* zoom out */
eye[0] = (1 + ZOOM_FACTOR) * eye[0] - at[0] * ZOOM_FACTOR;
eye[1] = (1 + ZOOM_FACTOR) * eye[1] - at[1] * ZOOM_FACTOR;
eye[2] = (1 + ZOOM_FACTOR) * eye[2] - at[2] * ZOOM_FACTOR;
break;
case GLUT_KEY_HOME: /* zoom in */
eye[0] = (1 - ZOOM_FACTOR) * eye[0] + at[0] * ZOOM_FACTOR;
eye[1] = (1 - ZOOM_FACTOR) * eye[1] + at[1] * ZOOM_FACTOR;
eye[2] = (1 - ZOOM_FACTOR) * eye[2] + at[2] * ZOOM_FACTOR;
break;
}
glutPostRedisplay();
}
/*
* A keyboard event occurs when the user presses a key:
* '+' should cause the scene to zoom in
* '-' should cause the scene to zoom out
*/
void Keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case '+': SpecialKey(GLUT_KEY_HOME, 0, 0);
break;
case '-': SpecialKey(GLUT_KEY_END, 0, 0);
break;
case 'q': exit(0);
}
}
void Mouse(int button, int state, int x, int y)
{
// update the button state
if(button == GLUT_LEFT_BUTTON)
{
if(state == GLUT_DOWN)
mouseState.leftButton = true;
else
mouseState.leftButton = false;
}
if(button == GLUT_RIGHT_BUTTON)
{
if(state == GLUT_DOWN)
mouseState.rightButton = true;
else
mouseState.rightButton = false;
}
// update the mouse position, so we can track the mouse move
mouseState.x = x;
mouseState.y = y;
}
void MouseMove(int x, int y)
{
/* Calculate the displacement in movement */
int xDelta = mouseState.x - x;
int yDelta = mouseState.y - y;
/* Commit the mouse position */
mouseState.x = x;
mouseState.y = y;
/* If left button is down, rotate when mouse is moved */
if(mouseState.leftButton) {
xRotate -= xDelta * DEGREES_PER_PIXEL;
yRotate -= yDelta * DEGREES_PER_PIXEL;
}
/* If right button is down, translate when mouse is moved.
* Simulate translation by moving the eye--lookat vector:
* if vector moves to the left, scene moves to the right.
*/
else if(mouseState.rightButton) {
eye[0] += xDelta * UNITS_PER_PIXEL;
eye[1] -= yDelta * UNITS_PER_PIXEL;
at[0] += xDelta * UNITS_PER_PIXEL;
at[1] -= yDelta * UNITS_PER_PIXEL;
}
glutPostRedisplay();
}
void myInit()
{
/* set color used when clearing the window to black */
glClearColor( 0.0, 0.0, 0.0, 1.0 );
/* Set drawing color to red (no effect if lighting is used) */
glColor3f(1.0, 0.0, 0.0);
/* allocate quadrics with filled drawing style */
earthObj = gluNewQuadric();
gluQuadricDrawStyle(earthObj, GLU_FILL);
/* Set up perspective projection */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0f, 1.0f, 0.1f, 40.0f);
/* Initialize the camera position */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], 0,1,0);
/* Enable hidden--surface--removal */
glEnable(GL_DEPTH_TEST);
/* set up the lights */
EnableLighting();
}
/*
* Invokes OpenGL commands that set the lighting and
* material properties and then enables light 0.
*/
void EnableLighting( void )
{
glEnable(GL_LIGHTING);
GLfloat light1_diffuse[] = {1.0, 1.0, 1.0, 1.0}; /* bright white */
GLfloat light1_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light1_ambient[] = {0.8, 0.8, 0.8, 1.0}; /* soft white */
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
glEnable(GL_LIGHT1);
glShadeModel(GL_SMOOTH);
glEnable(GL_NORMALIZE);
}
void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("Lighting Demo");
/* register callback functions */
glutDisplayFunc(Display);
glutKeyboardFunc(Keyboard);
glutSpecialFunc(SpecialKey);
glutMouseFunc(Mouse);
glutMotionFunc(MouseMove);
/* set window attributes */
myInit();
/* start event processing */
glutMainLoop();
}
challenge 2: Create an OpenGL application with one spot light (green colored)
facing to the center of the ball object.
#include <GL/freeglut.h>
#include <math.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define DEGREES_PER_PIXEL 0.6f
#define UNITS_PER_PIXEL 0.1f
#define ZOOM_FACTOR 0.04f
#define BULB_RADIUS 0.3f
#define SPOTLIGHT_RADIUS 0.5f
#define ROOM_SIZE 4.0f
#define WALL_THICKNESS 0.05f
void EnableLighting();
typedef struct
{
bool leftButton;
bool rightButton;
int x;
int y;
} MouseState;
MouseState mouseState = {false, false, 0, 0};
/* scene rotation angles to alter interactively */
float xRotate = 0, yRotate = 0;
/* quadrics pointers for GLU spheres and cylinders */
GLUquadricObj *bulbObj;
/* camera position and orientation -- used by gluLookAt */
GLfloat eye[] = {0, 0, 10};
GLfloat at[] = {0, 0, 0};
/* light1 position -- along the z-axis (to be used later) */
GLfloat light1_position[]={0.0, 0.0, 1.0, 1.0};
/* The room (composed of three orthogonal walls) is
* centered at the origin of the coordinate system.
*/
void room()
{
/* ceiling */
glPushMatrix();
glTranslatef(0,ROOM_SIZE/2,0);
glScalef(ROOM_SIZE, WALL_THICKNESS, ROOM_SIZE);
glutSolidCube( 1.0 );
glPopMatrix();
/* floor */
glPushMatrix();
glTranslatef(0,-ROOM_SIZE/2,0);
glScalef(ROOM_SIZE, WALL_THICKNESS, ROOM_SIZE);
glutSolidCube( 1.0 );
glPopMatrix();
/* right wall */
glPushMatrix();
glTranslatef(ROOM_SIZE/2,0,0);
glScalef(WALL_THICKNESS, ROOM_SIZE, ROOM_SIZE);
glutSolidCube( 1.0 );
glPopMatrix();
/* left wall */
glPushMatrix();
glTranslatef(-ROOM_SIZE/2,0,0);
glScalef(WALL_THICKNESS, ROOM_SIZE, ROOM_SIZE);
glutSolidCube( 1.0 );
glPopMatrix();
/* back wall */
glPushMatrix();
glTranslatef(0, 0, -ROOM_SIZE/2);
glScalef(ROOM_SIZE, ROOM_SIZE, WALL_THICKNESS);
glutSolidCube( 1.0 );
glPopMatrix();
}
/* The bulb is a sphere centered at the origin
* of the coordinate system.
*/
void bulb()
{
glPushMatrix();
glScalef(BULB_RADIUS, BULB_RADIUS, BULB_RADIUS);
gluSphere(bulbObj, 1.0, 20, 20);
glPopMatrix();
}
void DrawScene()
{
/* Rotate the scene in the x and y directions */
glRotatef(xRotate, 0,1,0);
glRotatef(yRotate, 1,0,0);
room();
bulb();
/* If you want to preserve the relative position of
* the light in the scene, uncomment the line below */
// glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
}
/*
* This function is called whenever the display needs
* to be redrawn. First called when program starts.
*/
void Display(void)
{
/* Draw to the back buffer */
glDrawBuffer( GL_BACK );
/* Clear the display */
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* (Re)position the camera */
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], 0,1,0);
DrawScene();
/* Before returning, flush the graphics buffer,
* so all graphics appear in the window */
glFlush();
glutSwapBuffers();
}
/*
* A special keyboard event occurs when the user presses a
* special key (arrows, F? keys). Arrows cause the scene to
* move in the direction indicated; this is accomplished by
* moving camera position (and maintaining the orientation).
* HOME and END keys should cause the scene to zoom in and
* out; this is accomplished by moving the camera along the
* vector between the eye and the lookat point.
*/
void SpecialKey(int key, int x, int y)
{
switch(key) {
case GLUT_KEY_LEFT:
/* as camera moves to the right, the image moves to the left */
eye[0] = eye[0] + UNITS_PER_PIXEL;
at[0] = at[0] + UNITS_PER_PIXEL;
break;
case GLUT_KEY_RIGHT:
eye[0] = eye[0] - UNITS_PER_PIXEL;
at[0] = at[0] - UNITS_PER_PIXEL;
break;
case GLUT_KEY_UP:
eye[1] = eye[1] - UNITS_PER_PIXEL;
at[1] = at[1] - UNITS_PER_PIXEL;
break;
case GLUT_KEY_DOWN:
eye[1] = eye[1] + UNITS_PER_PIXEL;
at[1] = at[1] + UNITS_PER_PIXEL;
break;
case GLUT_KEY_END: /* zoom out */
eye[0] = (1 + ZOOM_FACTOR) * eye[0] - at[0] * ZOOM_FACTOR;
eye[1] = (1 + ZOOM_FACTOR) * eye[1] - at[1] * ZOOM_FACTOR;
eye[2] = (1 + ZOOM_FACTOR) * eye[2] - at[2] * ZOOM_FACTOR;
break;
case GLUT_KEY_HOME: /* zoom in */
eye[0] = (1 - ZOOM_FACTOR) * eye[0] + at[0] * ZOOM_FACTOR;
eye[1] = (1 - ZOOM_FACTOR) * eye[1] + at[1] * ZOOM_FACTOR;
eye[2] = (1 - ZOOM_FACTOR) * eye[2] + at[2] * ZOOM_FACTOR;
break;
}
glutPostRedisplay();
}
/*
* A keyboard event occurs when the user presses a key:
* '+' should cause the scene to zoom in
* '-' should cause the scene to zoom out
*/
void Keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case '+': SpecialKey(GLUT_KEY_HOME, 0, 0);
break;
case '-': SpecialKey(GLUT_KEY_END, 0, 0);
break;
case 'q': exit(0);
}
}
void Mouse(int button, int state, int x, int y)
{
// update the button state
if(button == GLUT_LEFT_BUTTON)
{
if(state == GLUT_DOWN)
mouseState.leftButton = true;
else
mouseState.leftButton = false;
}
if(button == GLUT_RIGHT_BUTTON)
{
if(state == GLUT_DOWN)
mouseState.rightButton = true;
else
mouseState.rightButton = false;
}
// update the mouse position, so we can track the mouse move
mouseState.x = x;
mouseState.y = y;
}
void MouseMove(int x, int y)
{
/* Calculate the displacement in movement */
int xDelta = mouseState.x - x;
int yDelta = mouseState.y - y;
/* Commit the mouse position */
mouseState.x = x;
mouseState.y = y;
/* If left button is down, rotate when mouse is moved */
if(mouseState.leftButton) {
xRotate -= xDelta * DEGREES_PER_PIXEL;
yRotate -= yDelta * DEGREES_PER_PIXEL;
}
/* If right button is down, translate when mouse is moved.
* Simulate translation by moving the eye--lookat vector:
* if vector moves to the left, scene moves to the right.
*/
else if(mouseState.rightButton) {
eye[0] += xDelta * UNITS_PER_PIXEL;
eye[1] -= yDelta * UNITS_PER_PIXEL;
at[0] += xDelta * UNITS_PER_PIXEL;
at[1] -= yDelta * UNITS_PER_PIXEL;
}
glutPostRedisplay();
}
void myInit()
{
/* set color used when clearing the window to black */
glClearColor( 0.0, 0.0, 0.0, 1.0 );
/* Set drawing color to red (no effect if lighting is used) */
glColor3f(1.0, 0.0, 0.0);
/* allocate quadrics with filled drawing style */
bulbObj = gluNewQuadric();
gluQuadricDrawStyle(bulbObj, GLU_FILL);
/* Set up perspective projection */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0f, 1.0f, 0.1f, 40.0f);
/* Initialize the camera position */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye[0], eye[1], eye[2], at[0], at[1], at[2], 0,1,0);
/* Enable hidden--surface--removal */
glEnable(GL_DEPTH_TEST);
/* set up the lights */
EnableLighting();
}
/*
* Invokes OpenGL commands that set the lighting and
* material properties and then enables light 0.
*/
void EnableLighting( void )
{
}
void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("Lighting Demo");
/* register callback functions */
glutDisplayFunc(Display);
glutKeyboardFunc(Keyboard);
glutSpecialFunc(SpecialKey);
glutMouseFunc(Mouse);
glutMotionFunc(MouseMove);
/* set window attributes */
myInit();
/* start event processing */
glutMainLoop();
}
challenge 3: Create a program that supports an animation.
- Using transformation and MemoryStack to build a robot object (animated).
- Use glutTimerFunc()


0 comments