Saturday, May 17, 2014

Western Michigan - CS5270 - Lab Assignment #2

Here is the second assignment @ Link.
The output looks like this:


I lazily kept postponing working on this assignment and somewhat slogged in the last few days. The professor kept postponing the last date for submitting the assignment so that helped. My purpose of posting the solutions is not to help future students but with an intension of forcing changes in assignments and updation of questions.
I don't know if the gimbal lock problem is there in this solution or not. I thought using quaternions solves the problem. If you think there is a problem still plz contact me.

I didn't solve this assignment completely. Anyone with basic programming skills can modify the code and make it work according to the expectations of the professor.

Here it is:
/*
 * ellipsoid.c
 *
 *  Created on: Oct 27, 2013
 *      Author: kamath
 */
#include<GL/glut.h>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include "quater.h"
#define Pi 3.141
static  GLdouble  viewer[]={80,80,50};
float phi=0,timestamp,alpha1,beta1,gamma1;
FILE *fp;
void DrawEllipsoid(unsigned int uiStacks, unsigned int uiSlices, float fA, float fB, float fC)
{
    float s,t,tStep = (Pi) / (float)uiSlices;
    float sStep = (Pi) / (float)uiStacks;

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    for(t = -Pi/2; t <= (Pi/2)+.0001; t += tStep)
    {
        glBegin(GL_TRIANGLE_STRIP);
        for(s = -Pi; s <= Pi+.0001; s += sStep)
        {
            glVertex3f(fA * cos(t) * cos(s), fB * cos(t) * sin(s), fC * sin(t));
            glVertex3f(fA * cos(t+tStep) * cos(s), fB * cos(t+tStep) * sin(s), fC * sin(t+tStep));
        }
        glEnd();
    }
}
void display()
{float m2[4][4],m3[4][4],m4[4][4],m21[16],m31[16],m41[16];
float a1[3]={0,0,1.0},a2[3]={0,1.0,0},q[4],k[4],j[4];

int i;

alpha1=alpha1*3.141/180;    //convert degrees into radians
beta1=beta1*3.141/180;
gamma1=gamma1*3.141/180;
axis_to_quat(a1,alpha1,q);    //convert euler angles into quaternions
axis_to_quat(a2,beta1,k);
axis_to_quat(a1,gamma1,j);
//add_quats(q,k,dest)
build_rotmatrix(m2,q);        //convert quaternions into matrices
build_rotmatrix(m3,k);
build_rotmatrix(m4,j);
for(i=0;i<16;i++) //convert matrix into column major order
{
    m21[i]=m2[i%4][(int)floor(i/4)];
}
for(i=0;i<16;i++)
{
    m31[i]=m3[i%4][(int)floor(i/4)];
}
for(i=0;i<16;i++)
{
    m41[i]=m4[i%4][(int)floor(i/4)];
}

usleep(1000);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glColor3f(1,0,0);
    glLoadIdentity();
    gluLookAt(viewer[0],viewer[1],viewer[2],0,0,0,0,1,0);
    glLoadIdentity();
    glPushMatrix();
    glRotatef(45,1,1,1);
    glBegin(GL_LINES);
    glVertex3f(0,0,-10);
    glVertex3f(0,0,10);
    glVertex3f(10,0,0);
    glVertex3f(-10,0,0);
    glVertex3f(0,10,0);
        glVertex3f(0,-10,0);
        glEnd();
        glColor3f(0.8,0.8,0.4);
        glTranslatef(30,30,0);
    glMultMatrixf(m41);//rotate wrt Z
    glMultMatrixf(m31);//rotate wrt x
    glMultMatrixf(m21);//rotate wrt z
    DrawEllipsoid(10, 10, 12,6,24);
    glFlush();
    glPopMatrix();
    glutSwapBuffers();

}
void init()
{
    glClearColor(1.0,1.0,1.0,0.0);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-80,80,-80,80,-80,80);
        glMatrixMode(GL_MODELVIEW);
}
void idle()
{// read file and get angles
    if(fscanf (fp,"%f %f %f %f\n",&timestamp,&alpha1,&beta1,&gamma1)==EOF)
    {
        fclose(fp);
        printf("end of input");
        exit(0);
    }

    glutPostRedisplay();
}
int main(int argc,char *argv[])
{
    fp = fopen ("el1_sh.txt", "r");
     if (fp == NULL)
            {
                printf ("Error opening file");
                exit(1);
            }
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(200,0);
    glutCreateWindow("ellipsoid");
    glutDisplayFunc(display);
    init();
    glEnable(GL_DEPTH_TEST);
    glutIdleFunc(idle);
    glutMainLoop();

    return 0;
}



This is a .h file you need to include: (Contains code to work with quaternions)
#include <math.h>
//#include "trackball.h"

/*
 * This size should really be based on the distance from the center of
 * rotation to the point on the object underneath the mouse.  That
 * point would then track the mouse as closely as possible.  This is a
 * simple example, though, so that is left as an Exercise for the
 * Programmer.
 */
#define TRACKBALLSIZE  (0.8)

/*
 * Local function prototypes (not defined in trackball.h)
 */
static float tb_project_to_sphere(float, float, float);
static void normalize_quat(float [4]);

void
vzero(float *v)
{
    v[0] = 0.0;
    v[1] = 0.0;
    v[2] = 0.0;
}

void
vset(float *v, float x, float y, float z)
{
    v[0] = x;
    v[1] = y;
    v[2] = z;
}

void
vsub(const float *src1, const float *src2, float *dst)
{
    dst[0] = src1[0] - src2[0];
    dst[1] = src1[1] - src2[1];
    dst[2] = src1[2] - src2[2];
}

void
vcopy(const float *v1, float *v2)
{
    register int i;
    for (i = 0 ; i < 3 ; i++)
        v2[i] = v1[i];
}

void
vcross(const float *v1, const float *v2, float *cross)
{
    float temp[3];

    temp[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
    temp[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
    temp[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
    vcopy(temp, cross);
}

float
vlength(const float *v)
{
    return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}

void
vscale(float *v, float div)
{
    v[0] *= div;
    v[1] *= div;
    v[2] *= div;
}

void
vnormal(float *v)
{
    vscale(v,1.0/vlength(v));
}

float
vdot(const float *v1, const float *v2)
{
    return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
}

void
vadd(const float *src1, const float *src2, float *dst)
{
    dst[0] = src1[0] + src2[0];
    dst[1] = src1[1] + src2[1];
    dst[2] = src1[2] + src2[2];
}
/*
 *  Given an axis and angle, compute quaternion.
 */
void
axis_to_quat(float a[3], float phi, float q[4])
{
    vnormal(a);
    vcopy(a,q);
    vscale(q,sin(phi/2.0));
    q[3] = cos(phi/2.0);
}
/*
 * Ok, simulate a track-ball.  Project the points onto the virtual
 * trackball, then figure out the axis of rotation, which is the cross
 * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
 * Note:  This is a deformed trackball-- is a trackball in the center,
 * but is deformed into a hyperbolic sheet of rotation away from the
 * center.  This particular function was chosen after trying out
 * several variations.
 *
 * It is assumed that the arguments to this routine are in the range
 * (-1.0 ... 1.0)
 */
void
trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
{
    float a[3]; /* Axis of rotation */
    float phi;  /* how much to rotate about axis */
    float p1[3], p2[3], d[3];
    float t;

    if (p1x == p2x && p1y == p2y) {
        /* Zero rotation */
        vzero(q);
        q[3] = 1.0;
        return;
    }

    /*
     * First, figure out z-coordinates for projection of P1 and P2 to
     * deformed sphere
     */
    vset(p1,p1x,p1y,tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y));
    vset(p2,p2x,p2y,tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y));

    /*
     *  Now, we want the cross product of P1 and P2
     */
    vcross(p2,p1,a);

    /*
     *  Figure out how much to rotate around that axis.
     */
    vsub(p1,p2,d);
    t = vlength(d) / (2.0*TRACKBALLSIZE);

    /*
     * Avoid problems with out-of-control values...
     */
    if (t > 1.0) t = 1.0;
    if (t < -1.0) t = -1.0;
    phi = 2.0 * asin(t);

    axis_to_quat(a,phi,q);
}



/*
 * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
 * if we are away from the center of the sphere.
 */
static float
tb_project_to_sphere(float r, float x, float y)
{
    float d, t, z;

    d = sqrt(x*x + y*y);
    if (d < r * 0.70710678118654752440) {    /* Inside sphere */
        z = sqrt(r*r - d*d);
    } else {           /* On hyperbola */
        t = r / 1.41421356237309504880;
        z = t*t / d;
    }
    return z;
}

/*
 * Given two rotations, e1 and e2, expressed as quaternion rotations,
 * figure out the equivalent single rotation and stuff it into dest.
 *
 * This routine also normalizes the result every RENORMCOUNT times it is
 * called, to keep error from creeping in.
 *
 * NOTE: This routine is written so that q1 or q2 may be the same
 * as dest (or each other).
 */

#define RENORMCOUNT 97

void
add_quats(float q1[4], float q2[4], float dest[4])
{
    static int count=0;
    float t1[4], t2[4], t3[4];
    float tf[4];

    vcopy(q1,t1);
    vscale(t1,q2[3]);

    vcopy(q2,t2);
    vscale(t2,q1[3]);

    vcross(q2,q1,t3);
    vadd(t1,t2,tf);
    vadd(t3,tf,tf);
    tf[3] = q1[3] * q2[3] - vdot(q1,q2);

    dest[0] = tf[0];
    dest[1] = tf[1];
    dest[2] = tf[2];
    dest[3] = tf[3];

    if (++count > RENORMCOUNT) {
        count = 0;
        normalize_quat(dest);
    }
}

/*
 * Quaternions always obey:  a^2 + b^2 + c^2 + d^2 = 1.0
 * If they don't add up to 1.0, dividing by their magnitued will
 * renormalize them.
 *
 * Note: See the following for more information on quaternions:
 *
 * - Shoemake, K., Animating rotation with quaternion curves, Computer
 *   Graphics 19, No 3 (Proc. SIGGRAPH'85), 245-254, 1985.
 * - Pletinckx, D., Quaternion calculus as a basic tool in computer
 *   graphics, The Visual Computer 5, 2-13, 1989.
 */
static void
normalize_quat(float q[4])
{
    int i;
    float mag;

    mag = (q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
    for (i = 0; i < 4; i++) q[i] /= mag;
}

/*
 * Build a rotation matrix, given a quaternion rotation.
 *
 */
void
build_rotmatrix(float m[4][4], float q[4])
{
    m[0][0] = 1.0 - 2.0 * (q[1] * q[1] + q[2] * q[2]);
    m[0][1] = 2.0 * (q[0] * q[1] - q[2] * q[3]);
    m[0][2] = 2.0 * (q[2] * q[0] + q[1] * q[3]);
    m[0][3] = 0.0;

    m[1][0] = 2.0 * (q[0] * q[1] + q[2] * q[3]);
    m[1][1]= 1.0 - 2.0 * (q[2] * q[2] + q[0] * q[0]);
    m[1][2] = 2.0 * (q[1] * q[2] - q[0] * q[3]);
    m[1][3] = 0.0;

    m[2][0] = 2.0 * (q[2] * q[0] - q[1] * q[3]);
    m[2][1] = 2.0 * (q[1] * q[2] + q[0] * q[3]);
    m[2][2] = 1.0 - 2.0 * (q[1] * q[1] + q[0] * q[0]);
    m[2][3] = 0.0;

    m[3][0] = 0.0;
    m[3][1] = 0.0;
    m[3][2] = 0.0;
    m[3][3] = 1.0;
}


This is a text file el1_sh.txt that is the input to the rotation functions, so u need to put it inside the project folder. I will soon update the post to include a few more comments to explain the program.

Western Michigan - CS5270 - Lab Assignment #1

One of my students happened to take admission in a US varsity and sought my help in a lab assignment. I wanted to learn something new so happily volunteered for help.

This was the first assignment @ Link.

I solved it within a couple of days and here is the solution for the first task. The code runs in ubuntu. Please search some good site which will help you install glew.

This program uses glew and runs as well as the glaux function using program.

/**************************************************
   solar.c

   Program to demonstrate how to use a local
   coordinate method to position parts of a
   model in relation to other model parts.

   Pressing the "a" key toggles the animation
   Pressing the up and down arrow keys will
   increase/decrease the animation rate

**************************************************/

//#include "glos.h" // MS specifc stuff
#include<GL/glew.h>
#include <GL/gl.h> // system OpenGL includes
#include <GL/glu.h>
//#include <GL/glaux.h>
#include<GL/glut.h>

static GLenum spinMode = GL_TRUE;

void OpenGLInit(void);

static void Animate(void );
/*static void Key_a(void );
static void Key_up(void );
static void Key_down(void );*/
static void ResizeWindow(GLsizei w, GLsizei h);
static int HourOfDay = 0, DayOfYear = 0;
static int AnimateIncrement = 24; // in hours

/*static void Key_a(void)
{
    spinMode = !spinMode;
}

static void Key_up(void)
{
    AnimateIncrement *= 2;
    if ( 0 == AnimateIncrement )
        AnimateIncrement = 1;
}

static void Key_down(void)
{
    AnimateIncrement /= 2;

}*/
static void special1(int key,int x,int y)
{
    switch(key)
    {
    case GLUT_KEY_UP:
        AnimateIncrement *= 2;
            if ( 0 == AnimateIncrement )
                AnimateIncrement = 1;break;
    case GLUT_KEY_DOWN:AnimateIncrement /= 2;break;
    }

}
void mykeys(unsigned char key,int x,int y)
{
    if(key=='a' || key=='A')
        spinMode = !spinMode;
}

static void Animate(void)
{
    // clear the redering window
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (spinMode)
        {
        // calc animation parameters
        HourOfDay += AnimateIncrement;
        DayOfYear += HourOfDay/24;

        HourOfDay = HourOfDay%24;
        DayOfYear = DayOfYear%365;
        }

    // clear current matrix (Modelview)
    glLoadIdentity();
    // back off six units
    glTranslatef ( 0.0f, 0.0f, -5.0f );
    // rotate the plane of the elliptic
    // (rotate the model's plane about the
    // x axis by five degrees)
    glRotatef( 5.0f, 1.0f, 0.0f, 0.0f );

    // draw the sun
    glColor3f( 1.0, 1.0, 1.0 );
    glutWireSphere( 1.0,100,100 );

    // draw the Earth
    glRotatef( (GLfloat)(360.0*DayOfYear/365.0),
        0.0, 1.0, 0.0 );
    glTranslatef( 4.0, 0.0, 0.0 );
    glPushMatrix(); // save matrix state
    glRotatef( (GLfloat)(360.0*HourOfDay/24.0), 0.0, 1.0, 0.0 );
    glColor3f( 0.2, 0.2, 1.0 );
    glutWireSphere( 0.2,100,100 );
    glPopMatrix(); // restore matrix state

       glRotatef( (GLfloat)(360.0*12.5*DayOfYear/365.0),
        0.0, 1.0, 0.0 );
    glTranslatef( 0.5, 0.0, 0.0 );
    glColor3f( 0.3, 0.3, 0.3 );
    glutWireSphere( 0.05 ,100,100);

    // flush the pipeline, swap the buffers
    glFlush();
    glutSwapBuffers();

}

// initialize OpenGL
void OpenGLInit(void)
{
    glShadeModel( GL_FLAT );
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    glClearDepth( 1.0f );
    glDepthFunc( GL_LEQUAL );
    glEnable( GL_DEPTH_TEST );
}

// called when the window is resized
static void ResizeWindow(GLsizei w, GLsizei h)
{
    h = (h == 0) ? 1 : h;
    w = (w == 0) ? 1 : w;
    glViewport( 0, 0, w, h );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 45.0, (GLfloat)w/(GLfloat)h, 1.0f, 20.0f );
    // select the Modelview matrix
    glMatrixMode( GL_MODELVIEW );
}

// main routine
// set up OpenGL, hook up callbacks
// and start the main loop
int main( int argc, char** argv )
{
    // we're going to animate it, so double buffer
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH );
    glutInitWindowPosition( 0, 0);
    glutInitWindowSize(620, 160 );
    glutCreateWindow( "Solar System Example" );

    // Initialize OpenGL as we like it..
    OpenGLInit();

    // set up callback functions
/*    auxKeyFunc( AUX_UP, Key_up ); // faster
    auxKeyFunc( AUX_DOWN, Key_down ); // slower
    auxKeyFunc( AUX_a, Key_a ); //animate*/
    glutReshapeFunc( ResizeWindow );
    glutSpecialFunc(special1);
    glutKeyboardFunc(mykeys);
    glEnable(GL_DEPTH_TEST);
    // call this when idle
    glutIdleFunc( Animate );
    // call this in main loop
//    auxMainLoop( Animate );
    glutMainLoop();

    return(0);
}








The second programming task uses shaders which i was not familiar with. I somehow solved the problem but still wondering how it works.

Here it is:
Solar2.cpp

/**************************************************
   solar.c

   Program to demonstrate how to use a local
   coordinate method to position parts of a
   model in relation to other model parts.

   Pressing the "a" key toggles the animation
   Pressing the up and down arrow keys will
   increase/decrease the animation rate

**************************************************/

//#include "glos.h" // MS specifc stuff
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>

#include<GL/glew.h>

#include <GL/gl.h> // system OpenGL includes
#include <GL/glu.h>
//#include <GL/glaux.h>
#include<GL/glut.h>



static GLenum spinMode = GL_TRUE;

void OpenGLInit(void);

static void Animate(void );
/*static void Key_a(void );
static void Key_up(void );
static void Key_down(void );*/
static void ResizeWindow(GLsizei w, GLsizei h);

static int HourOfDay = 0, DayOfYear = 0;
static int AnimateIncrement = 24; // in hours
using namespace std;

/*
   Global handles for the currently active program object, with its two shader objects
*/
GLuint programObject = 0;
GLuint vertexShaderObject = 0;
GLuint fragmentShaderObject = 0;
static GLint win = 0;

int readShaderSource(char *fileName, GLchar **shader )
{
    // Allocate memory to hold the source of our shaders.
    FILE *fp;
    int count, pos, shaderSize;

    fp = fopen( fileName, "r");
    if ( !fp )
        return 0;

    pos = (int) ftell ( fp );
    fseek ( fp, 0, SEEK_END );            //move to end
    shaderSize = ( int ) ftell ( fp ) - pos;    //calculates file size
    fseek ( fp, 0, SEEK_SET );             //rewind to beginning

    if ( shaderSize <= 0 ){
        printf("Shader %s empty\n", fileName);
        return 0;
    }

    *shader = (GLchar *) malloc( shaderSize + 1);

    // Read the source code

    count = (int) fread(*shader, 1, shaderSize, fp);
    (*shader)[count] = '\0';

    if (ferror(fp))
        count = 0;


    fclose(fp);

    return 1;
}

//  public
int installShaders(const GLchar *vertex, const GLchar *fragment)
{
    GLint  vertCompiled, fragCompiled;  // status values
    GLint  linked;

    // Create a vertex shader object and a fragment shader object

    vertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
    fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);

    // Load source code strings into shaders, compile and link

    glShaderSource(vertexShaderObject, 1, &vertex, NULL);
    glShaderSource(fragmentShaderObject, 1, &fragment, NULL);

    glCompileShader(vertexShaderObject);
    glGetShaderiv(vertexShaderObject, GL_COMPILE_STATUS, &vertCompiled);

    glCompileShader( fragmentShaderObject );
    glGetShaderiv( fragmentShaderObject, GL_COMPILE_STATUS, &fragCompiled);

    if (!vertCompiled || !fragCompiled)
        return 0;

    // Create a program object and attach the two compiled shaders

    programObject = glCreateProgram();
    glAttachShader( programObject, vertexShaderObject);
    glAttachShader( programObject, fragmentShaderObject);

    // Link the program object

    glLinkProgram(programObject);
    glGetProgramiv(programObject, GL_LINK_STATUS, &linked);

    if (!linked)
        return 0;

    // Install program object as part of current state

    glUseProgram(programObject);

    return 1;
}

/*static void Key_a(void)
{
    spinMode = !spinMode;
}

static void Key_up(void)
{
    AnimateIncrement *= 2;
    if ( 0 == AnimateIncrement )
        AnimateIncrement = 1;
}

static void Key_down(void)
{
    AnimateIncrement /= 2;

}*/
static void special1(int key,int x,int y)
{
    switch(key)
    {
    case GLUT_KEY_UP:
        AnimateIncrement *= 2;
            if ( 0 == AnimateIncrement )
                AnimateIncrement = 1;break;
    case GLUT_KEY_DOWN:AnimateIncrement /= 2;break;
    }

}
void mykeys(unsigned char key,int x,int y)
{
    if(key=='a' || key=='A')
        spinMode = !spinMode;
}
void CleanUp(void)
{
   glDeleteShader(vertexShaderObject);
   glDeleteShader(fragmentShaderObject);
   glDeleteProgram(programObject);
   glutDestroyWindow(win);
}
void Animate(void)
{
     GLchar *VertexShaderSource, *FragmentShaderSource;
       int loadstatus = 0;
    // clear the redering window
       readShaderSource("tests.vert", &VertexShaderSource );
           readShaderSource("tests.frag", &FragmentShaderSource );
           loadstatus = installShaders(VertexShaderSource, FragmentShaderSource);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (spinMode)
        {
        // calc animation parameters
        HourOfDay += AnimateIncrement;
        DayOfYear += HourOfDay/24;

        HourOfDay = HourOfDay%24;
        DayOfYear = DayOfYear%365;
        }

    // clear current matrix (Modelview)
    glLoadIdentity();
    // back off six units
    glTranslatef ( 0.0f, 0.0f, -5.0f );
    // rotate the plane of the elliptic
    // (rotate the model's plane about the
    // x axis by five degrees)
    glRotatef( 5.0f, 1.0f, 0.0f, 0.0f );

    // draw the sun
    glColor3f( 1.0, 1.0, 1.0 );
    glutWireSphere( 1.0,100,100 );

    readShaderSource("tests.vert", &VertexShaderSource );
               readShaderSource("tests1.frag", &FragmentShaderSource );
               loadstatus = installShaders(VertexShaderSource, FragmentShaderSource);
    // draw the Earth
    glRotatef( (GLfloat)(360.0*DayOfYear/365.0),
        0.0, 1.0, 0.0 );
    glTranslatef( 4.0, 0.0, 0.0 );
    glPushMatrix(); // save matrix state
    glRotatef( (GLfloat)(360.0*HourOfDay/24.0), 0.0, 1.0, 0.0 );
    glColor3f( 0.2, 0.2, 1.0 );
    glutWireSphere( 0.2,100,100 );
    glPopMatrix(); // restore matrix state

       glRotatef( (GLfloat)(360.0*12.5*DayOfYear/365.0),
        0.0, 1.0, 0.0 );
    glTranslatef( 0.5, 0.0, 0.0 );
    glColor3f( 0.3, 0.3, 0.3 );
    readShaderSource("tests.vert", &VertexShaderSource );
    readShaderSource("tests2.frag", &FragmentShaderSource );
    loadstatus = installShaders(VertexShaderSource, FragmentShaderSource);
    glutWireSphere( 0.05 ,100,100);

    // flush the pipeline, swap the buffers
    glFlush();
    glutSwapBuffers();

}
int init(void)
{

   const char *version;
   GLchar *VertexShaderSource, *FragmentShaderSource;
   int loadstatus = 0;

   version = (const char *) glGetString(GL_VERSION);
   if (version[0] != '2' || version[1] != '.') {
      printf("This program requires OpenGL 2.x, found %s\n", version);
      exit(1);
   }
   readShaderSource("tests.vert", &VertexShaderSource );
   readShaderSource("tests.frag", &FragmentShaderSource );
   loadstatus = installShaders(VertexShaderSource, FragmentShaderSource);

   return loadstatus;
}
// initialize OpenGL
void OpenGLInit(void)
{
    glShadeModel( GL_FLAT );
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    glClearDepth( 1.0f );
    glDepthFunc( GL_LEQUAL );
    glEnable( GL_DEPTH_TEST );
}

// called when the window is resized
static void ResizeWindow(GLsizei w, GLsizei h)
{
    h = (h == 0) ? 1 : h;
    w = (w == 0) ? 1 : w;
    glViewport( 0, 0, w, h );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 45.0, (GLfloat)w/(GLfloat)h, 1.0f, 20.0f );
    // select the Modelview matrix
    glMatrixMode( GL_MODELVIEW );
}

// main routine
// set up OpenGL, hook up callbacks
// and start the main loop
int main( int argc, char** argv )
{
    // we're going to animate it, so double buffer
    int success=0;
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH );
    glutInitWindowPosition( 0, 0);
    glutInitWindowSize(620, 160 );
    glutCreateWindow( "Solar System Example" );

    // Initialize OpenGL as we like it..
    OpenGLInit();



    // set up callback functions
/*    auxKeyFunc( AUX_UP, Key_up ); // faster
    auxKeyFunc( AUX_DOWN, Key_down ); // slower
    auxKeyFunc( AUX_a, Key_a ); //animate*/
    glutReshapeFunc( ResizeWindow );
    glutSpecialFunc(special1);
    glutKeyboardFunc(mykeys);
    glEnable(GL_DEPTH_TEST);
    // call this when idle
    glutIdleFunc( Animate );
    glewInit();
    // call this in main loop
//    auxMainLoop( Animate );
    success = init();
       if ( success )
         glutMainLoop();
       return 0;
}

tests.frag(this is a file you need to create and place inside your project folder)
//tests.frag
//a minimal fragment shader

void main(void)
{
  gl_FragColor = vec4( 1, 1, 1, 1);    //yellow color
}

tests.vert(this is a file you need to create and place inside your project folder)
//tests.vert
//a minimal vertex shader
void main(void)
{
  gl_Position     = ftransform();
  /*
    Same as:
      gl_Position = gl_ProjectionMatrix *  gl_ModelViewMatrix * gl_Vertex;
    or
      gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
  */
}

Hope to share many more things. I solved these assignments using google only. I could not mention the site from where i took the code to solve this.