Lab (3) - Graphics

Objectives:
To learn to create different views of a cube
To learn about glLookAt function
To create a rotating cube

Following is a program that creates a cube.

#include <GL/glut.h>
#include <math.h>
typedef GLfloat point3[3];
double PI;
point3 p[8]={
        {0,0,0},  //black
        {0,0,1},  //blue
        {1,0,1},  //magenta
        {1,0,0},  //red
        {0,1,0},  //green
        {0,1,1},  //green+blue
        {1,1,1},  //white
        {1,1,0}   //yellow
};

void drawPoint(int i){
        glVertex3fv(p[i]);
}
void drawFace(int i1,int i2,int i3,int i4){
        glBegin(GL_POLYGON);
        glColor3fv(p[i1]);
        drawPoint(i1);
        drawPoint(i2);
        drawPoint(i3);
        drawPoint(i4);
        glEnd();
}
        

void myinit(void)
{
 
/* attributes */
        glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */
        glColor3f(0.0, 0.0, 0.0); /* draw in black */
/* set up viewing */
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-1, 1, -1, 1,-10,10);
        glMatrixMode(GL_MODELVIEW);
        glEnable(GL_DEPTH_TEST);
        PI=4*atan(1); // arctan of 1 is pi/4, a way to define PI
}
void drawCube(){
        drawFace(0,3,2,1); //bottom = black,
        drawFace(1,2,6,5); //front = blue
        drawFace(2,3,7,6); //right side = magenta
        drawFace(3,0,4,7); //back side = red
        drawFace(4,5,6,7); //top = green
        drawFace(5,4,0,1); //left side = green + blue
}

void display( void )
{
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);  /*clear the window */
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(-.5,-.5,-.5);
        drawCube();
        glFlush(); /* clear buffers */
}

void main(int argc, char** argv)
{
/* Standard GLUT initialization */
        glutInit(&argc,argv);
        glutInitDisplayMode (GLUT_SINGLE| GLUT_RGB|GLUT_DEPTH);

        glutInitWindowSize(500,500); /* 500 x 500 pixel window */
        glutInitWindowPosition(0,0); /* place window top left on display */
        glutCreateWindow("Cube"); /* window title */
        glutDisplayFunc(display); /* display callback invoked when window opened */
        myinit(); /* set attributes */
        glutMainLoop(); /* enter event loop */
}
Activity (1)
Cut and paste the program into your VC++ screen and compile, then run it.  What kind of shape do you think will be created?

If you said a square you are right.  If you said a cube that is seen from its front side (only front face) that is better.

Activity (2)
Make changes in the program such that the following shape is created.

Note that this image can be created by rotating the cube about the x axis by 45 and then about the y axis by 45.
As we mentioned in class, this does not produce an "isogonal view" of the cube.  We learned that to create the
correct view the rotation about y axis must be 45 but rotation about x axis must be computed.  The angle of
rotation around x axis must be:
        Tetha = sin-1 (sqrt(3)/3)  OR Tetha = cos-1 (sqrt(2)/sqrt(3) )

Note that this angles must be in Radian.

Activity (3)
Make changes to create the correct "isogonal view" of the cube as shown below.

Using gluLookAt Function
The gluLookAt function provides an alternative to glTranslatef and glRotatef sequences
for positioning the camera. It does not, however, change the "lens" (or projection
matrix) used. Here's the documentation:

gluLookAt

NAME

gluLookAt -- define a viewing transformation 

C SPECIFICATION

void gluLookAt(GLdouble eyex,
               GLdouble eyey,
               GLdouble eyez,
               GLdouble centerx,
               GLdouble centery,
               GLdouble centerz,
               GLdouble upx,
               GLdouble upy,
               GLdouble upz)

PARAMETERS

eyex, eyey, eyez 
     Specifies the position of the eye point. 
centerx, centery, centerz 
     Specifies the position of the reference point. 
upx, upy, upz 
     Specifies the direction of the up vector. 

DESCRIPTION

gluLookAt creates a viewing matrix derived from an eye point, a reference point indicating
the center of the scene, and an up vector. The matrix maps the reference point to the
negative z axis and the eye point to the origin, so that, when a typical projection matrix
is used, the center of the scene maps to the center of the viewport. Similarly, the
direction described by the up vector projected onto the viewing plane is mapped to the
positive y axis so that it points upward in the viewport. The up vector must not be
parallel to the line of sight from the eye to the reference point. The matrix generated
by gluLookAt postmultiplies the current matrix.
Activity (4)
Make a change in your program such that you create the same "isogonal" view of the box as shown above using the
glLookAt function.

Activity (5)
Make changes so that your program creates and spins a color cube in a cumulative direction. In order to do this, you can
use the Idle call back function.  Your program should do different things based on the following list:
    1) if 'x' or 'X' is pressed, it rotates about x axis
    2) if 'y' or 'Y' is pressed, it rotates about y axis
    3) if 'z' or 'Z' is pressed, it rotates about z axis
    4) if '+' is pressed, it increases the speed of rotation
    5) if '-' is pressed, it decreases the speed of rotation
    6) if '  ' spacebar is pressed, everything is reset
    7) if 'q' or 'Q' is pressed, it terminates A hint for rotation: Hint

Follow up - More Challenging
Can you write your program such that chnage in rotation direction is done by mouse click? Can you use the mouse such that the
first 6 actions can be done with the three mouse buttons?