Saturday, May 17, 2014

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.

No comments:

Post a Comment