Quick Introduction to Open GL (with C++) - Part II




    

                                             OpenGL Tutorial – Part II

The following are the primary things to keep in mind before executing the code.

Window Management

Five routines perform tasks necessary to initialize a window.
  • glutInit(int *argc, char **argv) initializes GLUT and processes any command line arguments (for X, this would be options like -display and -geometry). glutInit() should be called before any other GLUT routine.
  • glutInitDisplayMode(unsigned int mode) specifies whether to use an RGBA or color-index color model. You can also specify whether you want a single- or double-buffered window. (If you're working in color-index mode, you'll want to load certain colors into the color map; use glutSetColor() to do this.) Finally, you can use this routine to indicate that you want the window to have an associated depth, stencil, and/or accumulation buffer. For example, if you want a window with double buffering, the RGBA color model, and a depth buffer, you might call glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH).

  • specifies the screen location for the upper-left corner of your window.

  • glutInitWindowSize(int width, int size) specifies the size, in pixels, of your window.
  • int glutCreateWindow(char *string) creates a window with an OpenGL context. It returns a unique identifier for the new window. Be warned: Until glutMainLoop() is called (see next section), the window is not yet displayed.


The Display Callback


glutDisplayFunc(void (*func)(void)) is the first and most important event callback function you will see. Whenever GLUT determines the contents of the window need to be redisplayed, the callback function registered by glutDisplayFunc() is executed. Therefore, you should put all the routines you need to redraw the scene in the display callback function.
If your program changes the contents of the window, sometimes you will have to call glutPostRedisplay(void), which gives glutMainLoop() a nudge to call the registered display callback at its next opportunity.

Handling Input Events

You can use these routines to register callback commands that are invoked when specified events occur.
  • glutReshapeFunc(void (*func)(int w, int h)) indicates what action should be taken when the window is resized.
  • glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)) and glutMouseFunc(void (*func)(int button, int state, int x, int y)) allow you to link a keyboard key or a mouse button with a routine that's invoked when the key or mouse button is pressed or released.
  • glutMotionFunc(void (*func)(int x, int y)) registers a routine to call back when the mouse is moved while a mouse button is also pressed.

Running the Program

The very last thing you must do is call glutMainLoop(void). All windows that have been created are now shown, and rendering to those windows is now effective. Event processing begins, and the registered display callback is triggered. Once this loop is entered, it is never exited!

More into the code:

Let us look at some codes to get a clear idea on how openGL executes them using the GLUT kit functions.

JOINING TWO CURVES:

Here I have given a code to draw two different curves (hermite curves) and join them using C1 or G1 continuity based on user input. The code involves all the functions explained in previous tutorial with some new functions explained in this tutorial. The display functions fully involve plotting the coordinates and generate a curve. Understand it as joining of two curves after plotting them individually. The coordinate points are obtained by hermite curve formula. We just focus on how those points are plotted, not on how those are obtained.

glBegin(GL_paramater):

This command plots the points in desired fashion depending on what the ‘parameter’ is. ‘parameter’ can be POINTS, LINES, LINE_STRIP, TRIANGLES. GL_POINTS plot the coordinates. GL_LINES – pairs of vertices are connected.  GL_LINE_STRIP -  series of connected line segments while GL_TRIANGLES draw triangles with three vertices taken in order.

glVertex3f(x, y, z) 

- plots a coordinate where x, y, z are float values.

glColor3f(red, green, blue) 

- sets the drawing color as per the RGB values.

glFlush( ) 

- forces previously issued OpenGL commands to begin execution, thus guaranteeing that they complete in finite time.

PLOTTING--Once we have set of coordinates and depending on how we want to connect them, we use specific parameter in glBegin() function.  For a curve, we have to plot coordinates and connect them using line segments continuously. Closer the points are, smoother the curve will be.
Go through the code and the output. Change the gscalef() values if you want a broad view.


CODE:
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<GL/glut.h>
#include<gl/GL.h>
#include <malloc.h>
void reshape(int w, int h)
{
 glViewport(0, 0, w, h);    /* Establish viewing area to cover entire window. */
 glMatrixMode(GL_PROJECTION);  /* Start modifying the projection matrix. */
 glLoadIdentity();          /* Initialize the current matrix to accept the effects */
 glClearColor(0.0, 0.0, 0.0, 0.0); // sets the window background to black
 glClear(GL_COLOR_BUFFER_BIT); // clears color buffer bits
 glOrtho(0, w, 0, h, -1, 1);   /* Map abstract coords directly to window coords. */
 glScalef(100, 100, 100);           /* Invert Y axis so increasing Y goes down. */
 glTranslatef(w/1000, h/1000, 0);       /* Shift origin up to upper-left corner. */
}
void display(void) // function where the curves are drawn plotting the points and connecting them
{
        int i,j,k,l,m,n,p,h;
float x,y,z,u,a,b,c,d;
        float A1[4][3];
        float A2[4][3];
        float A3[4][3];
float B1[4][3];
        float B2[4][3];
        float B3[4][3];
float M[4][4]={{2.0,-2.0,1.0,1.0},{-3.0,3.0,-2.0,-1.0},{0.0,0.0,1.0,0.0},{1.0,0.0,0.0,0.0}};
//float N[4][4]={{0,0,0,1},{1,1,1,1},{0,0,1,0},{3,2,1,0}};
        //a=b=c=d=0;
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_STRIP);// begin the drawing as series of connecting line segments
printf("\nenter the elements of B1 \n");
        for(i=0;i<4;++i)
        {
                    for(j=0;j<3;++j)
                    {
           scanf("%f",&B1[i][j]);
                    }
        }
                    printf("\n");
for(m=0;m<4;m++)
        {
                    for(n=0;n<3;n++)
                    {
                                A1[m][n]=0;
                                for(k=0;k<4;k++)
                            {
                                A1[m][n]+=M[m][k]*B1[k][n];
                                }
                    }
        }
        printf("\n THE MATRIX A1 IS  \n");
        printf("\n");
        for(i=0;i<4;i++)
        {
                    for(j=0;j<3;j++)
                                printf("%f  ",A1[i][j]);
                    printf("\n");
        }
for(u=0.0;u<=1.0;u=u+0.005)
{
                    x=((A1[0][0]*u*u*u)+(A1[1][0]*u*u)+(A1[2][0]*u)+(A1[3][0]));
           y=((A1[0][1]*u*u*u)+(A1[1][1]*u*u)+(A1[2][1]*u)+(A1[3][1]));
           z=((A1[0][2]*u*u*u)+(A1[1][2]*u*u)+(A1[2][2]*u)+(A1[3][2]));
                    glColor3f(1.0, 0.0, 0.0);// set drawing color to red
    glVertex2f(x,y);
}
        glEnd();// end drawing the object
glFlush(); // execute all the drawing commands
glBegin(GL_LINE_STRIP);// begin drawing the object by connecting the line segments
        printf("\nenter the elements of B2 \n");
        for(i=0;i<4;++i)
        {
                    for(j=0;j<3;++j)
                    {
           scanf("%f",&B2[i][j]);
                    }
        }
        printf("\n");
for(m=0;m<4;m++)
        {
                    for(n=0;n<3;n++)
                    {
                                A2[m][n]=0;
                                for(k=0;k<4;k++)
                                {
                                A2[m][n]+=M[m][k]*B2[k][n];
                                }
                    }
        }
        printf("\n THE MATRIX A2 IS  \n");
        printf("\n");
        for(i=0;i<4;i++)
        {
                    for(j=0;j<3;j++)
                                printf("%f  ",A2[i][j]);
                    printf("\n");
        }
for(u=0.0;u<=1.0;u=u+0.005)
{
                    x=((A2[0][0]*u*u*u)+(A2[1][0]*u*u)+(A2[2][0]*u)+(A2[3][0]));
           y=((A2[0][1]*u*u*u)+(A2[1][1]*u*u)+(A2[2][1]*u)+(A2[3][1]));
           z=((A2[0][2]*u*u*u)+(A2[1][2]*u*u)+(A2[2][2]*u)+(A2[3][2]));
                    glColor3f(0.0, 1.0, 0.0);// set drawing color to green
                    glVertex2f(x,y);// plot the coordinate
}
        glEnd();
glFlush();
        printf("\nType 1 to enter C1 continuous curve or 0 for G1 continuous curve \n");
        scanf("%d",&h);
        if(h==1)
        {
                    glBegin(GL_LINE_STRIP);
                    for(i=0;i<3;++i)
                    {
                                B3[0][i]=B1[1][i];
                                B3[1][i]=B2[0][i];
        B3[2][i]=B1[3][i];
                                B3[3][i]=B2[2][i];
                    }
                    printf("\n");
for(m=0;m<4;m++)
        {
                    for(n=0;n<3;n++)
                    {
                                A3[m][n]=0;
                                for(k=0;k<4;k++)
                                {
                                A3[m][n]+=M[m][k]*B3[k][n];
                                }
                    }
        }
        printf("\n THE MATRIX A3 IS  \n");
        printf("\n");
        for(i=0;i<4;i++)
        {
                    for(j=0;j<3;j++)
                                printf("%f  ",A3[i][j]);
                    printf("\n");
        }
for(u=0.0;u<=1.0;u=u+0.005)
{
                    x=((A3[0][0]*u*u*u)+(A3[1][0]*u*u)+(A3[2][0]*u)+(A3[3][0]));
           y=((A3[0][1]*u*u*u)+(A3[1][1]*u*u)+(A3[2][1]*u)+(A3[3][1]));
           z=((A3[0][2]*u*u*u)+(A3[1][2]*u*u)+(A3[2][2]*u)+(A3[3][2]));
                    glColor3f(0.0, 0.0, 1.0);// set drawing color to blue
                    glVertex2f(x,y);// plot the coordinate
}
        glEnd();
glFlush();
        }
        if(h==0)
        {
                    glBegin(GL_LINE_STRIP);
                    printf("Enter left parameter ");
                    scanf("%d",&m);
    printf("Enter right parameter ");
                    scanf("%d",&n);
    for(i=0;i<3;++i)
                    {
                                B3[0][i]=B1[1][i];
                                B3[1][i]=B2[0][i];
        B3[2][i]=m*(B1[3][i]);
                                B3[3][i]=n*(B2[2][i]);
                    }
    printf("\n");
for(m=0;m<4;m++)
        {
                    for(n=0;n<3;n++)
                    {
                                A3[m][n]=0;
                                for(k=0;k<4;k++)
                                {
                                A3[m][n]+=M[m][k]*B3[k][n];
                                }
                    }
        }
        printf("\n THE MATRIX A3 IS  \n");
        printf("\n");
        for(i=0;i<4;i++)
        {
                    for(j=0;j<3;j++)
                                printf("%f  ",A3[i][j]);
                    printf("\n");
        }
for(u=0.0;u<=1.0;u=u+0.005)
{
                    x=((A3[0][0]*u*u*u)+(A3[1][0]*u*u)+(A3[2][0]*u)+(A3[3][0]));
           y=((A3[0][1]*u*u*u)+(A3[1][1]*u*u)+(A3[2][1]*u)+(A3[3][1]));
           z=((A3[0][2]*u*u*u)+(A3[1][2]*u*u)+(A3[2][2]*u)+(A3[3][2]));
                    glColor3f(0.0, 0.0, 1.0);// set drawing color to blue
                    glVertex2f(x,y);// plot the coordinate
}
        glEnd();
glFlush();
        }
}
int main(int argc, char **argv)
{
glutInit(&argc, argv); // initialize the GLUT library
glutInitWindowSize(1280,720); // Initial values to the new window to be created
glutCreateWindow("Hermite Curve");// create a new window with title 'Hermite curve'
glutDisplayFunc(display);// call display function
glutReshapeFunc(reshape);// call the reshape funcion
glutMainLoop();// enter the loop
        getch();
return 0;
}





OUTPUT:
Here we can see the two curves plotted individually.














After joining them, it looks like this:



JOINING TWO SURFACES:
Here is another code where we join two surfaces (hermite surfaces).

CODE:
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<GL/glut.h>
#include<gl/GL.h>
#include <malloc.h>
//#define FREE_ARG1 char*
int g_rot_abt_x = 0, g_rot_abt_y=0, g_rot_abt_z=0;
float M[4][4]={{2,-2,1,1},{-3,3,-2,-1},{0,0,1,0},{1,0,0,0}};
float Mt[4][4]={{2,-3,0,1},{-2,3,0,0},{1,-2,1,0},{1,-1,0,0}};
float Mi[4][4]={{0,0,0,1},{1,1,1,1},{0,0,1,0},{3,2,1,0}};
float L[4][4]={{1,0,0,0},{0,0,0,1},{-5.5,9,-4.5,1},{-1,4.5,-9,5.5}};
float Lt[4][4]={{1,0,-5.5,-1},{0,0,9,4.5},{0,0,-4.5,-9},{0,1,1,5.5}};
float B[4][4][3];
float A[4][4][3];
float A2[4][4][3];
float B2[4][4][3];
float P[4][4][3];
float Ax[4][4];
float Ay[4][4];
float Az[4][4];
float A2x[4][4];
float A2y[4][4];
float A2z[4][4];
float Bx[4][4];
float By[4][4];
float Bz[4][4];
float B2x[4][4];
float B2y[4][4];
float B2z[4][4];
float Px[4][4];
float Py[4][4];
float Pz[4][4];
float Cx[4][4];
float Cy[4][4];
float Cz[4][4];
float Dx[4][4];
float Dy[4][4];
float Dz[4][4];
float Ex[4][4];
float Ey[4][4];
float Ez[4][4];
float X[4][4];
float Y[4][4];
float Z[4][4];
float multi(float X[4][4], float Y[4][4], float Z[4][4]);
int i,j,k,a;
float x,y,z;
void myinit()
{
 glClearColor(0.0,0.0,0.0,0.0);
 glShadeModel(GL_FLAT);
 glDisable(GL_LIGHTING);
 glDisable(GL_LIGHT1);
 glDisable(GL_DEPTH_TEST);
 glDisable(GL_BLEND);
}
float multi(float X[4][4], float Y[4][4], float Z[4][4])
{
        for(i=0;i<4;++i)
        {
                    for(j=0;j<4;++j)
                    {
                                Z[i][j]=0;
                                for(k=0;k<4;++k)
                                {
                                            Z[i][j]+=X[i][k]*Y[k][j];
                                }
                    }
        }
        return Z[4][4];
}

void myReshape(int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);    /*  prepare for and then  */
glLoadIdentity ();  /*  define the projection  */
glOrtho(-50.0,50.0,-50.0,50.0,-50.0,50.0);
//glOrtho(g_x_coord_min-40, g_x_coord_max+40, g_y_coord_min-40, g_y_coord_max+40, g_z_coord_min-40, g_z_coord_max+40);
glMatrixMode (GL_MODELVIEW);     /*  back to modelview matrix */
}

void display(void)
{
 glClear(GL_COLOR_BUFFER_BIT);
 glMatrixMode(GL_MODELVIEW);
 glPushMatrix();
 //glTranslatef(g_translate_x, g_translate_y, g_translate_z);
 //glScalef(g_scale_x, g_scale_y, g_scale_z);
 glRotatef((GLfloat)g_rot_abt_z, 0, 0 , 1);
 glRotatef((GLfloat)g_rot_abt_y, 0, 1 , 0);
 glRotatef((GLfloat)g_rot_abt_x, 1, 0 , 0);
 glLineWidth(3.0);
 glBegin(GL_POINTS);
 float u,w;
 i=0;
 j=1;
 k=2;
 for(w=0.0;w<1.0;w=w+0.005)
 {
 for(u=0.0;u<1.0;u=u+0.005)
 {
         x=((A[0][0][i]*u*u*u*w*w*w)+(A[0][1][i]*u*u*u*w*w)+(A[0][2][i]*u*u*u*w)+(A[0][3][i]*u*u*u)+(A[1][0][i]*u*u*w*w*w)+(A[1][1][i]*u*u*w*w)+(A[1][2][i]*u*u*w)+(A[1][3][i]*u*u));
         x=x+((A[2][0][i]*u*w*w*w)+(A[2][1][i]*u*w*w)+(A[2][2][i]*u*w)+(A[2][3][i]*u)+(A[3][0][i]*w*w*w)+(A[3][1][i]*w*w)+(A[3][2][i]*w)+(A[3][3][i]));
         y=((A[0][0][j]*u*u*u*w*w*w)+(A[0][1][j]*u*u*u*w*w)+(A[0][2][j]*u*u*u*w)+(A[0][3][j]*u*u*u)+(A[1][0][j]*u*u*w*w*w)+(A[1][1][j]*u*u*w*w)+(A[1][2][j]*u*u*w)+(A[1][3][j]*u*u));
         y=y+((A[2][0][j]*u*w*w*w)+(A[2][1][j]*u*w*w)+(A[2][2][j]*u*w)+(A[2][3][j]*u)+(A[3][0][j]*w*w*w)+(A[3][1][j]*w*w)+(A[3][2][j]*w)+(A[3][3][j]));
         z=((A[0][0][k]*u*u*u*w*w*w)+(A[0][1][k]*u*u*u*w*w)+(A[0][2][k]*u*u*u*w)+(A[0][3][k]*u*u*u)+(A[1][0][k]*u*u*w*w*w)+(A[1][1][k]*u*u*w*w)+(A[1][2][k]*u*u*w)+(A[1][3][k]*u*u));
         z=z+((A[2][0][k]*u*w*w*w)+(A[2][1][k]*u*w*w)+(A[2][2][k]*u*w)+(A[2][3][k]*u)+(A[3][0][k]*w*w*w)+(A[3][1][k]*w*w)+(A[3][2][k]*w)+(A[3][3][k]));
         glColor3f(1.0, 0.0, 0.0);  /* red */
  glVertex3f(x,y,z);
         //printf("\n%f  %f  %f",x,y,z);//
 }
 }
 glEnd();
 /*glPopMatrix();
 glFlush();
 glMatrixMode(GL_MODELVIEW);
 glPushMatrix();
 //glTranslatef(g_translate_x, g_translate_y, g_translate_z);
 //glScalef(g_scale_x, g_scale_y, g_scale_z);
 glRotatef((GLfloat)g_rot_abt_z, 0, 0 , 1);
 glRotatef((GLfloat)g_rot_abt_y, 0, 1 , 0);
 glRotatef((GLfloat)g_rot_abt_x, 1, 0 , 0);
 glLineWidth(3.0);*/
 glBegin(GL_POINTS);
 i=0;
 j=1;
 k=2;
 for(w=0.0;w<1.0;w=w+0.005)
 {
 for(u=0.0;u<1.0;u=u+0.005)
 {
         x=((A2[0][0][i]*u*u*u*w*w*w)+(A2[0][1][i]*u*u*u*w*w)+(A2[0][2][i]*u*u*u*w)+(A2[0][3][i]*u*u*u)+(A2[1][0][i]*u*u*w*w*w)+(A2[1][1][i]*u*u*w*w)+(A2[1][2][i]*u*u*w)+(A2[1][3][i]*u*u));
         x=x+((A2[2][0][i]*u*w*w*w)+(A2[2][1][i]*u*w*w)+(A2[2][2][i]*u*w)+(A2[2][3][i]*u)+(A2[3][0][i]*w*w*w)+(A2[3][1][i]*w*w)+(A2[3][2][i]*w)+(A2[3][3][i]));
         y=((A2[0][0][j]*u*u*u*w*w*w)+(A2[0][1][j]*u*u*u*w*w)+(A2[0][2][j]*u*u*u*w)+(A2[0][3][j]*u*u*u)+(A2[1][0][j]*u*u*w*w*w)+(A2[1][1][j]*u*u*w*w)+(A2[1][2][j]*u*u*w)+(A2[1][3][j]*u*u));
         y=y+((A2[2][0][j]*u*w*w*w)+(A2[2][1][j]*u*w*w)+(A2[2][2][j]*u*w)+(A2[2][3][j]*u)+(A2[3][0][j]*w*w*w)+(A2[3][1][j]*w*w)+(A2[3][2][j]*w)+(A2[3][3][j]));
         z=((A2[0][0][k]*u*u*u*w*w*w)+(A2[0][1][k]*u*u*u*w*w)+(A2[0][2][k]*u*u*u*w)+(A2[0][3][k]*u*u*u)+(A2[1][0][k]*u*u*w*w*w)+(A2[1][1][k]*u*u*w*w)+(A2[1][2][k]*u*u*w)+(A2[1][3][k]*u*u));
         z=z+((A2[2][0][k]*u*w*w*w)+(A2[2][1][k]*u*w*w)+(A2[2][2][k]*u*w)+(A2[2][3][k]*u)+(A2[3][0][k]*w*w*w)+(A2[3][1][k]*w*w)+(A2[3][2][k]*w)+(A2[3][3][k]));
         glColor3f(0.0, 1.0, 0.0);  /* red */
  glVertex3f(x,y,z);
         //printf("\n%f  %f  %f",x,y,z);//
 }
 }
 glEnd();
 glPopMatrix();
 glFlush();
}

void keyboard(unsigned char key, int x, int y)
{
 switch(key){
 case 'x' :
g_rot_abt_x = (g_rot_abt_x + 1)%360;
glutPostRedisplay();
break;
 case 'X' :
g_rot_abt_x = (g_rot_abt_x - 1)%360;
glutPostRedisplay();
break;
 case 'y' :
g_rot_abt_y = (g_rot_abt_y + 1)%360;
glutPostRedisplay();
break;
 case 'Y' :
g_rot_abt_y = (g_rot_abt_y - 1)%360;
glutPostRedisplay();
break;
 case 'z' :
g_rot_abt_z = (g_rot_abt_z + 1)%360;
glutPostRedisplay();
break;
 case 'Z' :
g_rot_abt_z = (g_rot_abt_z - 1)%360;
glutPostRedisplay();
break;
 }
}
int main(int argc, char **argv)
{
 FILE *fpin;
 fpin = fopen("input.txt","r");
 for(i=0;i<3;i++)
        {
                    for(j=0;j<4;j++)
                    {
                                for(k=0;k<4;++k)
                                {
                                fscanf(fpin,"%f",&P[j][k][i]);
                                }
                    }
        }
 for(i=0;i<4;++i)
 {
         for(j=0;j<4;++j)
         {
                     Px[i][j]=P[i][j][0];
      Py[i][j]=P[i][j][1];
                     Pz[i][j]=P[i][j][2];
         }
 }
 multi(Px,Lt,Cx);
 multi(L,Cx,Bx);
 multi(Py,Lt,Cy);
 multi(L,Cy,By);
 multi(Pz,Lt,Cz);
 multi(L,Cz,Bz);
 for(i=0;i<4;++i)
 {
         for(j=0;j<4;++j)
         {
                     B[i][j][0]=Bx[i][j];
                     B[i][j][1]=By[i][j];
                     B[i][j][2]=Bz[i][j];
         }
 }
 printf("\nThe Matrix B is  ");
 printf("\n");
        for(i=0;i<3;i++)
        {
                    for(j=0;j<4;j++)
                    {
                                for(k=0;k<4;++k)
                                {
                                printf("%f ",B[j][k][i]);
                                }
                                printf("\n");
                    }
                    printf("\n");
        }
 multi(Bx,Mt,Dx);
 multi(M,Dx,Ax);
 multi(By,Mt,Dy);
 multi(M,Dy,Ay);
 multi(Bz,Mt,Dz);
 multi(M,Dz,Az);
 for(i=0;i<4;++i)
 {
         for(j=0;j<4;++j)
         {
                     A[i][j][0]=Ax[i][j];
                     A[i][j][1]=Ay[i][j];
                     A[i][j][2]=Az[i][j];
         }
 }
 printf("\n Type the parameter value for G1 continuity of the surface ( any value between 1 and 10)  \n");
 scanf("%d",&a);
 for(i=0;i<3;++i)
 {
         for(j=0;j<4;++j)
         {
                     B2[0][j][i]=B[1][j][i];
         }
 }
 for(i=0;i<3;++i)
 {
         for(j=0;j<2;++j)
         {
                     B2[2][j][i]=a*B[3][j][i];
         }
 }
 for(i=0;i<3;++i)
 {
         for(j=0;j<4;++j)
         {
                     if(i!=2)
                                 B2[1][j][i]=B[1][j][i]+50;
                     else
                                 B2[1][j][i]=B[1][j][i];
                      if(i!=2)
                                 B2[3][j][i]=B[3][j][i]+50;
                     else
                                 B2[3][j][i]=B[3][j][i];
         }
 }
 for(i=0;i<3;++i)
 {
         for(j=2;j<4;++j)
         {
                     if(i!=2)
                                 B2[2][j][i]=B[2][j][i]+50;
                     else
                                 B2[2][j][i]=B[2][j][i];
         }
 }
 for(i=0;i<4;++i)
 {
         for(j=0;j<4;++j)
         {
                     B2x[i][j]=B2[i][j][0];
      B2y[i][j]=B2[i][j][1];
                     B2z[i][j]=B2[i][j][2];
         }
 }
 printf("\nThe Matrix B2 is  ");
 printf("\n");
 for(i=0;i<3;i++)
        {
                    for(j=0;j<4;j++)
                    {
                                for(k=0;k<4;++k)
                                {
                                printf("%f ",B2[j][k][i]);
                                }
                                printf("\n");
                    }
                    printf("\n");
        }
 multi(B2x,Mt,Ex);
 multi(M,Ex,A2x);
 multi(B2y,Mt,Ey);
 multi(M,Ey,A2y);
 multi(B2z,Mt,Ez);
 multi(M,Ez,A2z);
 for(i=0;i<4;++i)
 {
         for(j=0;j<4;++j)
         {
                     A2[i][j][0]=A2x[i][j];
                     A2[i][j][1]=A2y[i][j];
                     A2[i][j][2]=A2z[i][j];
         }
 }
 glutInit(&argc,argv);
 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
 glutInitWindowSize(500,500);
 glutInitWindowPosition(600,600);
 glutCreateWindow("VIEWER");
 myinit();
 glutDisplayFunc(display);
 glutReshapeFunc(myReshape);
 glutKeyboardFunc(keyboard);
 glutMainLoop();
 return 0;
}


Check the output. Vary the values, experiment using different values in different commands and observe the changes each time you run it. Experimenting using a code is the only way to excel in openGL.



OUTPUT: