Monday, March 4, 2013

Shaded Teapot over a Table

7) Using OpenGL functions write a program to draw a shaded scene consisting of a tea pot on a table. Define suitably the position and properties of the light source along with the properties of the surfaces of the solid object used in the scene.

#include<GL/glut.h>
void wall(double thickness)
{
    glPushMatrix();
    glTranslated(0.5,0.5*thickness,0.5);
    glScaled(1.0,thickness,1.0);
    glutSolidCube(1.0);
    glPopMatrix();
}
void tableLeg(double thick,double len)  // draw one table leg
{
    glPushMatrix();
    glTranslated(0,len/2,0);
    glScaled(thick,len,thick);
    glutSolidCube(1.0);
    glPopMatrix();
}
void table(double topWid, double topThick,double legThick,double legLen)
{
    glPushMatrix();
    glTranslated(0,legLen,0);
    glScaled(topWid, topThick,topWid);
    glutSolidCube(1.0);
    glPopMatrix();
    double dist =0.95* topWid/2.0 - legThick/2.0;
    glPushMatrix();
    glTranslated(dist,0,dist);
    tableLeg(legThick,legLen);
    glTranslated(0.0,0.0,-2*dist);
    tableLeg(legThick,legLen);
    glTranslated(-2*dist,0,2*dist);
    tableLeg(legThick,legLen);
    glTranslated(0,0,-2*dist);
    tableLeg(legThick,legLen);
    glPopMatrix();
}
void displaySolid(void)
{
    GLfloat mat_ambient[] = { 0.7f,0.7f,0.7f,1.0f};// gray
    GLfloat mat_diffuse[] = { 0.7f,0.7f,0.7f,1.0f};
    GLfloat mat_specular[] = { 1.0f,1.0f,1.0f,1.0f};
    GLfloat mat_shininess[]={50.0f};

    glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);
    glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
    glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);

    // set the light sources propertis
    GLfloat lightIntensity[] ={ 1.0f,1.0f,1.0f,1.0f};
    GLfloat light_position[] ={ 2.0f,6.0f,3.0f,0.0f};
    glLightfv(GL_LIGHT0 ,GL_POSITION,light_position);
    glLightfv(GL_LIGHT0 ,GL_DIFFUSE,lightIntensity);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.33,1.33, -1,1,0.1,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(2.3,1.3,2.0,0.0,0.25,0.0,0.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslated(0.4,0,0.4);
table(0.6,0.02,0.02,0.3);
glPopMatrix();
glPushMatrix();
glTranslated(0.6,0.38,0.5);
glRotated(30,0,1,0);
glutSolidTeapot(0.08);
glPopMatrix();
wall(0.02);
glPushMatrix();
glRotated(90.0,0.0,0.0,1.0);
wall(0.02);
glPopMatrix();
glPushMatrix();
glRotated(-90.0,1.0,0.0,0.0);
wall(0.02);
glPopMatrix();
glFlush();
}
int main(int argc, char** argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(100,100);
    glutCreateWindow("simple shaded scene consisting of a tea pot on a table ");
    glutDisplayFunc(displaySolid);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_NORMALIZE);
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.1,0.1,0.1,0.0);
    glViewport(0,0,640,480);
    glutMainLoop();
return 0;
}

Suppose the external asks for changing the color of each wall or table or teapot it can be done easily. Here is a modification to the teapot program=> Click Here

Cylinder and Parallelopiped

6) Write an OpenGL Program to create a cylinder and a parallelepiped by extruding  a circle and quadrilateral respectively. Allow the user to specify the circle and the quadrilateral.

#include<stdlib.h>
#include<GL/glut.h>
#include<math.h>
#define ONERAD 0.0174

float z=0;
void myinit()
{
    glClearColor(1.0,1.0,1.0,0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-10,40.0,-10,30.0,-20,20);
}
void drawObjects(float radius,float u,float v)
{float i;
float x1=5,y1=5,x2=15,y2=5,x3=15,y3=15,x4=5,y4=15;

    glPushMatrix();
    glRotatef(30,1,0,0);
    glRotatef(40,0,1,0);
  while(z<10)
   {
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glColor3f(1.0,0.0,0.0);
   for (i=0; i<360; i+=6)
   {
    glBegin(GL_POLYGON);
    float angle = i*ONERAD;
    glVertex3f(u+cos(angle)*radius,v+(sin(angle))*radius,0);
    angle=(i+6)*ONERAD;
    glVertex3f(u+cos(angle)*radius,v+(sin(angle))*radius,0);
    glVertex3f(u+cos(angle)*radius,v+(sin(angle))*radius,z);
    angle=i*ONERAD;
    glVertex3f(u+cos(angle)*radius,v+(sin(angle))*radius,z);
    glEnd();
   }
   glColor3f(0.0,0.0,1.0);
   glBegin(GL_POLYGON);
   glVertex3f(x1,y1,0);
   glVertex3f(x2,y2,0);
   glVertex3f(x2,y2,z);
   glVertex3f(x1,y1,z);
   glEnd();
   glBegin(GL_POLYGON);
   glVertex3f(x2,y2,0);
   glVertex3f(x3,y3,0);
   glVertex3f(x3,y3,z);
   glVertex3f(x2,y2,z);
   glEnd();
   glBegin(GL_POLYGON);
   glVertex3f(x3,y3,0);
   glVertex3f(x4,y4,0);
   glVertex3f(x4,y4,z);
   glVertex3f(x3,y3,z);
   glEnd();
   glBegin(GL_POLYGON);
   glVertex3f(x4,y4,0);
   glVertex3f(x1,y1,0);
   glVertex3f(x1,y1,z);
    glVertex3f(x4,y4,z);
    glEnd();
   z++;
   glFlush();
   glutSwapBuffers();
    }
  glPopMatrix();
}
void display()
{int j;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    drawObjects(5.0,0.0,0.0);
   glFlush();
}
int main(int argc,char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH );
    glutInitWindowSize(600,600);
    glutCreateWindow("6");
    glutDisplayFunc(display);
    myinit();
    glEnable(GL_DEPTH_TEST);
    glutMainLoop();
return 0;
}

Cohen-Sutherland Line Clipping

5) Write an OpenGL Program to implement the Cohen-Sutherland line-clipping  algorithm. Make provision to specify the input line, window for clipping and view port for displaying the clipped image.
/* So you have come to this page looking for the working of this program in between fb and whatsapp. I may not be an authority on graphics but will try my best to explain in as few sentences as possible.
The plane in which the window lies is divided into nine regions each with a different outcode. Outcodes of a point are integers(we use only last four bits) with appropriate bits set/reset to indicate the region in which that point lies.
The advantage of using region codes is that it makes it extremely simple to accept/reject a line which is completely inside/outside a window.
Outcode of two points inside the window is 0000 and 0000 and bitwise OR of these codes yields a zero hence this line can be accepted.
Outcode of two points lying completely on one side of the window either to left or right or top or bottom implies that one bit of both the outcodes is set(1). So a bitwise AND of the outcodes yields a non zero value which indicates that the line is completely on one side and hence rejected.
We need to find the multiple intersection points of a line with the four edges, if it intersects an edge and some part is inside the window.
*/










#include<stdio.h>
#include<GL/glut.h>
#define outcode int

double xmin=50,ymin=50,xmax=100,ymax=100;// Windows boundaries
double xvmin=200,yvmin =200, xvmax=300,yvmax=300; // Viewport boundaries

const int RIGHT= 8; // bit codes for the right
const int LEFT =2;  //bit codes for the left
const int TOP=4;    // bit codes for the top
const int BOTTOM=1; //bit codes for the bottom

outcode ComputeOutCode(double x,double y); // used to compute bit codes of a point

// Cohen -Sutherland clipping algorithm clips a line from
// p0=(x0,y0)  to p1 =(x1,y1) against a rectangle with.
// diagonal from (xmin,ymin)to (xmax,ymax)

void CohenSutherlandLineClipAnddraw(double x0,double y0,double x1,double y1)
{
   // OutCodes for P0 ,P1 and Whatever point(among P0 & P1) lies outside the
   // clip rectangle

    outcode outcode0,outcode1,outcodeOut;

int accept =0,done =0;// These are two bits to indicate trivial accept and/or
                                     // done with clipping
    //compute outcodes
outcode0= ComputeOutCode(x0,y0);
outcode1= ComputeOutCode(x1,y1);

do
{
    if(!(outcode0|outcode1)) // logical or is 0 trivially accept and exit
    { accept=1;
      done=1;
    }

    else
        if(outcode0 & outcode1)  // logical and is 0 trivially reject and exit
             done=1;
        else
        {
            //failed both tests , so calculate the line segment clip;
            // from an outside point to an intersection with clip edge
            double x,y;
            // at least one endpoint is outside the clip rectangle ; pick it.
            outcodeOut= outcode0?outcode0:outcode1;
       
            //now find the intersection point ; slope m= (y1-y0)/(x1-x0)
            // use formula
/// y=y0+slope*(x-x0), //either x is xmin or xmax
/// x=x0+(1/slope)*(y-y0) // y is ymin or ymax


Method to find intersection point

             if(outcodeOut & TOP) //point is above the clip rectangle
   {
x= x0+(x1-x0)*(ymax-y0)/(y1-y0);
                 y=ymax;
             }
           else
if(outcodeOut & BOTTOM) //point is below the clip rectangle
             {
x= x0+(x1-x0)*(ymin-y0)/(y1-y0);
                 y=ymin;
             }
             else
if(outcodeOut & RIGHT) //point is to the right of clip rectangle
             {
y= y0+(y1-y0)*(xmax-x0)/(x1-x0);
                 x=xmax;
         }
             else                   //point is to the left of the clip rectangle
             {
                 y= y0+(y1-y0)*(xmin-x0)/(x1-x0);
                 x=xmin;
             }
// now we move outside point to intersection point to clip
             // and get ready for next pass.
      if(outcodeOut == outcode0) // If the outside point was p0 update x0,y0 to x,y
             { x0=x;                           // so x,y become the new x0,y0
               y0=y;
               outcode0 = ComputeOutCode(x0,y0);
                //compute outcode of new endpoint
             }
        else                            // If the outside point was p1 update x1,y1 to x,y
             {                           // so x,y becomes the new x1,y1
               x1=x;
               y1=y;
               outcode1 = ComputeOutCode(x1,y1);
              // compute outcode of new endpoint
             }
        }
}while(!done);
if(accept) //If line was trivial reject no need to draw viewport
{
         // window to viewport mapping
    double sx=(xvmax-xvmin)/(xmax-xmin);// scale parameter in x direction
    double sy=(yvmax-yvmin)/(ymax-ymin);// scale parameter in y direction
    double vx0 = xvmin+(x0-xmin)*sx;
    double vy0 = yvmin+(y0-ymin)*sy;
    double vx1 = xvmin+(x1-xmin)*sx;
    double vy1 = yvmin+(y1-ymin)*sy;
    //draw a red color viewport
    glColor3f(1.0,0.0,0.0);
    glBegin(GL_LINE_LOOP);
    glVertex2f(xvmin,yvmin);
    glVertex2f(xvmax,yvmin);
    glVertex2f(xvmax,yvmax);
    glVertex2f(xvmin,yvmax);
  glEnd();
glColor3f(0.0,0.0,1.0);
glBegin(GL_LINES);
glVertex2d(vx0,vy0);
glVertex2d(vx1,vy1);
glEnd();
}
}
// compute the bit code for a point (x,y) using the clip rectangle
// bounded diagonally by (xmin,ymin) and (xmax,ymax)
outcode ComputeOutCode(double x,double y)
{
    outcode code =0;
     if(y>ymax)   //above the clip window
         code |=TOP;
    if(y<ymin)   //below the clip window
         code |=BOTTOM;
    if(x>xmax)        //to the right of the clip window
         code |=RIGHT;
    if(x<xmin)  //to the left of the clip window
         code |=LEFT;
         return code;
}
void display()
{
    double x0=120,y0=10,x1=40,y1=130;
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0,0.0,0.0); // draw red color lines
     glBegin(GL_LINES);
          glVertex2d(x0,y0);
          glVertex2d(x1,y1);
          glVertex2d(60,20);
          glVertex2d(80,120);
          glEnd();
   glColor3f(0.0,0.0,1.0); // draw a blue colored window
      glBegin(GL_LINE_LOOP);
         glVertex2f(xmin,ymin);
         glVertex2f(xmax,ymin);
         glVertex2f(xmax,ymax);
         glVertex2f(xmin,ymax);
         glEnd();
       CohenSutherlandLineClipAnddraw(x0,y0,x1,y1);
       CohenSutherlandLineClipAnddraw(60,20,80,120);
       glFlush();
}
void myinit()
{
    glClearColor(1.0,1.0,1.0,1.0);
    glColor3f(1.0,0.0,0.0);
    glPointSize(1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,499.0,0.0,499.0);
}
int main(int argc, char** argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0,0);
    glutCreateWindow("cohen Sutherland line clipping algorithm");
    glutDisplayFunc(display);
    myinit();
    glutMainLoop();
    return 0;
}

You may want to visit landing page of my blog: Wind Energy


A Video Explanation:


Now you may want to have a look at the ===> Liang-Barsky Line Clipping Algorithm <===too.

House Rotation

4) Write an OpenGL Program to create a house like figure and rotate it about  a given fixed point using OpenGL functions.

#include<stdio.h>
#include<math.h>
#include<GL/glut.h>
GLfloat house[2][9]={{100.0,100.0,175.0,250.0,250.0,150.0,150.0,200.0,200.0},        {100.0,300.0,400.0,300.0,100.0,100.0,150.0,150.0,100.0}};
GLfloat theta;
GLfloat h=100.0;
GLfloat k=100.0;
void drawhouse()
{
    glColor3f(1.0,0.0,0.0);
    glBegin(GL_LINE_LOOP);
    glVertex2f(house[0][0],house[1][0]);
    glVertex2f(house[0][1],house[1][1]);
    glVertex2f(house[0][3],house[1][3]);
    glVertex2f(house[0][4],house[1][4]);
    glEnd();
    glColor3f(1.0,0.0,1.0);
    glBegin(GL_LINE_LOOP);
    glVertex2f(house[0][5],house[1][5]);
    glVertex2f(house[0][6],house[1][6]);
    glVertex2f(house[0][7],house[1][7]);
    glVertex2f(house[0][8],house[1][8]);
    glEnd();
    glColor3f(1.0,0.0,0.0);
    glBegin(GL_LINE_LOOP);
    glVertex2f(house[0][1],house[1][1]);
    glVertex2f(house[0][2],house[1][2]);
    glVertex2f(house[0][3],house[1][3]);
    glEnd();
}
void display()
{
    int i;
    GLfloat m[16],p,q;
    p=-h*(cos(theta)-1)+k*(sin(theta));
    q=-k*(cos(theta)-1)-h*(sin(theta));
    for(i=0;i<15;i++)
        m[i]=0.0;
    m[0]=cos(theta);
    m[1]=sin(theta);
    m[4]=-sin(theta);
    m[5]=cos(theta);
    m[12]=p;
    m[13]=q;
    m[10]=1;
    m[15]=1;
    glMatrixMode(GL_MODELVIEW);
    glClear(GL_COLOR_BUFFER_BIT);
    drawhouse();
    glPushMatrix();
    glMultMatrixf(m);
    drawhouse();
    glPopMatrix();
    glFlush();
}
void myinit()
{
    glClearColor(1.0,1.0,1.0,1.0);
    glColor3f(1.0,1.0,0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,499.0,0.0,499.0);
    glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char **argv)
{

    printf("enter the rotation angle\n");
    scanf("%f",&theta);
    theta=theta*3.141/180;
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0,0);
    glutCreateWindow("rotated house");
    glutDisplayFunc(display);
    myinit();
    glutMainLoop();
    return 0;
}
Input:
enter  the rotation angle
-30

Rotating a Color Cube

3) Write an OpenGL Program to draw a color cube and spin it using OpenGL transformation matrices.

#include<stdlib.h>
#include<GL/glut.h>

GLfloat vertices[][3] = {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,-1.0,1.0},{1.0,-1.0,1.0},{1.0,1.0,1.0},{-1.0,1.0,1.0}};
GLfloat colors[][3] = {{0.0,0.0,0.0},{1.0,0.0,0.0},{1.0,0.0,0.0},{1.0,1.0,0.0},
{0.0,0.0,1.0},{1.0,0.0,1.0},{1.0,1.0,1.0},{0.0,1.0,1.0}};
static GLfloat theta[]={0.0,0.0,0.0};
GLint axis =1;
void polygon(int a, int b,int c,int d)
{
//draw a polygon via list of vertices
glBegin(GL_POLYGON);
  glColor3fv(colors[a]);
  glVertex3fv(vertices[a]);
  glColor3fv(colors[b]);
  glVertex3fv(vertices[b]);
  glColor3fv(colors[c]);
  glVertex3fv(vertices[c]);
  glColor3fv(colors[d]);
  glVertex3fv(vertices[d]);
  glEnd();
}
void colorcube(void)
{ //map vertices to faces
polygon(0,3,2,1);
polygon(2,3,7,6);
polygon(0,4,7,3);
polygon(1,2,6,5);
polygon(4,5,6,7);
polygon(0,1,5,4);
}

void display(void)
{
// display callback , clear frame buffer an Z buffer ,rotate cube and draw , swap buffer.
   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
   glLoadIdentity();
   glRotatef(theta[0],1.0,0.0,0.0);
   glRotatef(theta[1],0.0,1.0,0.0);
   glRotatef(theta[2],0.0,0.0,1.0);
  colorcube();
  glFlush();
glutSwapBuffers();
}
void spinCube()
{
  // idle callback,spin cube 2 degreees about selected axis
   theta[axis] +=1.0;
if(theta[axis]>360.0)
theta[axis]-= 360.0;
glutPostRedisplay();
}
void mouse(int btn,int state,int x,int y)
{
//mouse calback ,select an axis about which to rotate
if(btn== GLUT_LEFT_BUTTON && state ==GLUT_DOWN) axis =0;
if(btn== GLUT_MIDDLE_BUTTON && state ==GLUT_DOWN) axis =1;
if(btn== GLUT_RIGHT_BUTTON && state ==GLUT_DOWN) axis =2;
}
void myReshape(int w,int h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-2.0,2.0,-2.0 , 2.0, -10.0,10.0);
    glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
//need both double buffering and Zbuffer
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(500,500);
glutCreateWindow("Rotating a color cube ");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutIdleFunc(spinCube);
glutMouseFunc(mouse);
glEnable(GL_DEPTH_TEST);  //Enable hidden surface removal
glutMainLoop();
return 0;
}

Liang-Barsky Parametric Line Clipping

2) Write an OpenGL Program to implement Liang-Barsky line clipping algorithm.
/* Hi There this program is difficult to understand and its my goal to make you understand. This is a parametric line clipping algorithm. The parameter t is a fraction between 0 and 1. So your lessons in ratios in school are useful in this program. The thing is if we know the parameter t on a line from (x1,y1) to (x2,y2) we can find any point(x,y) on the line by:
x=x1+t*dx;
y=y1+t*dy;
where dx and dy are x2-x1 and y2-y1 respectively. So starting from (x1,y1) t gives an idea of how much far have we gone towards (x2,y2).
For clipping we find t value of intersection points. There are four intersection points of a line with four edges of the window. If at an intersection point if line is going into the window it means it is a potentially entering point. If intersection point is such that line is leaving the window then it is potentially leaving. We consider lines going from left to right and bottom to top. Argument holds if line is in any other direction.

In this figure Line number 1 looks proper and its part is inside the window. It starts with line entering bottom edge then entering left edge then leaving top edge and then leaving right edge.
Something wrong with Line Number 2. It enters bottom edge then leaves top edge and then enters left edge and then leaves right edge(not shown). So since entering intersection point has crossed over after the leaving intersection point. Hence the line is rejected.
Lines no. 3 are horizontal and dy=0 so they go to third condition in cliptest function and are rejected.
Ditto with lines no 4. where dx=0;
*/
#include<stdio.h>
#include<GL/glut.h>

double xmin=50, ymin=50, xmax=100,ymax=100; //window boundaries
double xvmin=200,yvmin=200,xvmax=300, yvmax=300; //viewport boundaries
int x1,y1,x2,y2;
int cliptest(double p,double q,double *t1,double *t2)
{      // p is denominator in division and q is numerator                 
// t1 is t entering and t2 is t leaving
    double t=q/p;
    if(p<0.0)        //potentially entry point ,update te
    {    if(t>*t1) *t1=t;
        if(t>*t2) return(0); //line portion is outside as in line no 2 where t(entering)
                                       // has become more than t(leaving)
    }
    else if(p>0.0) //potentially leaving point ,update tl
        {
        if(t<*t2) *t2=t;
            if(t<*t1) return(0); //line portion is outside
        }
        else if(p==0.0)
            { if(q<0.0)
                 return(0);//line parallel to edge but outside
            }
            return(1);
}
void liangbaraskylineclipanddraw(double x0,double y0,double x1,double y1)
{
    double dx= x1-x0,dy=y1-y0, te=0.0,tl=1.0;

    if(cliptest(-dx,x0-xmin,&te,&tl))// inside test wrt left edge
// t for the left edge is t=(xmin-x0) /dx .... order of numerator is reversed and you get -dx
    if(cliptest(dx,xmax-x0,&te,&tl))// inside test wrt right edge
// t for the right edge is t=(xmax-x0)/dx.... first parameter becomes q and second p then t=q/p
    if(cliptest(-dy,y0-ymin,&te,&tl))// inside test wrt bottom edge
// same story numerator by demoninator to find t
    if(cliptest(dy,ymax-y0,&te,&tl))// inside test wrt top edge
// in one way cohen sutherland and liang barasky are similar
    {
        if(tl<1.0)
        {
            x1=x0+tl*dx;
            y1=y0+tl*dy;
        }
        if(te>0.0)
        {
            x0=x0+te*dx;
            y0=y0+te*dy;
        }
    }
    //window to viewport mappings
    double sx= (xvmax-xvmin)/(xmax-xmin);// scale parameters
            double sy= (yvmax-yvmin)/(ymax-ymin);
            double vx0= xvmin+(x0-xmin)*sx;
            double vy0= yvmin+(y0-ymin)*sy;
            double vx1= xvmin+(x1-xmin)*sx;
            double vy1= yvmin+(y1-ymin)*sy;
// draw a red colored viewport
        glColor3f(1.0,0.0,0.0);
        glBegin(GL_LINE_LOOP);
        glVertex2f(xvmin,yvmin);
        glVertex2f(xvmax,yvmin);
        glVertex2f(xvmax,yvmax);
        glVertex2f(xvmin,yvmax);
        glEnd();
        glColor3f(0.0,0.0,1.0); //draw blue colored clip line
        glBegin(GL_LINES);
        glVertex2d(vx0,vy0);
        glVertex2f(vx1,vy1);
        glEnd();

}
void display()
{
    double x0=60,y0=20,x1=80,y1=120;
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0,0.0,0.0);          //draw a line with red color
    glBegin(GL_LINES);
    glVertex2d(x0,y0);
    glVertex2d(x1,y1);
    glEnd();
    glColor3f(0.0,0.0,1.0);     //draw a blue color window
    glBegin(GL_LINE_LOOP);
    glVertex2f(xmin,ymin);
    glVertex2f(xmax,ymin);
    glVertex2f(xmax,ymax);
    glVertex2f(xmin,ymax);
    glEnd();
    liangbaraskylineclipanddraw(x0,y0,x1,y1);
    glFlush();
}
void myinit()
{    glClearColor(1.0,1.0,1.0,1.0);
    glColor3f(1.0,0.0,0.0);
    glPointSize(1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,499.0,0.0,499.0);
}
int main(int argc, char** argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0,0);
    glutCreateWindow("liang barsky line clipping algorithm");
    glutDisplayFunc(display);
    myinit();
    glutMainLoop();
    return 0;
}

Sierpinski Gasket in a Tetrahedron

1) Write an OpenGL Program to recursively subdivide a tetrahedron to from 3D Sierpinski gasket. The number of recursive steps is to be specified by the user.
#include<stdlib.h>
#include<stdio.h>
#include<GL/glut.h>
GLfloat v[4][3]={{0.0,0.0,1.0},{0.0,1.0,0.0},
                     {-1.0,-0.5,0.0}, {1.0,-0.5,0.0}};
GLfloat colors[4][3]={{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{0.0,0.0,0.0}};
int n;
void triangle(GLfloat *va,GLfloat *vb,GLfloat *vc)
{
        glVertex3fv(va);
        glVertex3fv(vb);
        glVertex3fv(vc);
}
void tetra(GLfloat *a,GLfloat *b,GLfloat *c,GLfloat *d)
{
    glColor3fv(colors[0]);
    triangle( a, b, c);
    glColor3fv(colors[1]);
    triangle( a, c, d);
    glColor3fv(colors[2]);
    triangle( a, d, b);
    glColor3fv(colors[3]);
    triangle( b, d, c);
}

void divide_tetra(GLfloat *a,GLfloat *b,GLfloat *c,GLfloat *d,int m)
{
    GLfloat mid[6][3];
    int j;
    if(m>0)
    {    /*compute six midpoints*/
        for(j=0;j<3;j++) mid[0][j]=(a[j]+b[j])/2;
        for(j=0;j<3;j++) mid[1][j]=(a[j]+c[j])/2;
        for(j=0;j<3;j++) mid[2][j]=(a[j]+d[j])/2;
        for(j=0;j<3;j++) mid[3][j]=(b[j]+c[j])/2;
        for(j=0;j<3;j++) mid[4][j]=(c[j]+d[j])/2;
        for(j=0;j<3;j++) mid[5][j]=(b[j]+d[j])/2;
        divide_tetra(a,mid[0],mid[1],mid[2],m-1);
        divide_tetra(mid[0],b,mid[3],mid[5],m-1);
        divide_tetra(mid[1],mid[3],c,mid[4],m-1);
        divide_tetra(mid[2],mid[5],mid[4],d,m-1);
    }
    else
        tetra( a, b, c, d);      //draw triangle at end of recursion//
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glBegin(GL_TRIANGLES);      // This glBegin is to draw triangles taking three
    divide_tetra(v[0],v[1],v[2],v[3],n); // vertices at a time. divide_tetra calls itself
    glEnd();                                 //  and finally tetra which calls triangle four times
                                                         // which in-turn calls vertex function.
    glFlush();                                 // Call flush at the end to send output to screen
                                                                // making the gasket visible
}

void myReshape(int w,int h)
{
    glViewport(0,0,w,h);                 // Set the viewport to span the entire window
glMatrixMode(GL_PROJECTION);//Change the matrix mode to GL_PROJECTION
    glLoadIdentity();                       // Load the identity matrix to GL_PROJECTION
    glOrtho(-2.0,2.0,-2.0,2.0 ,-10.0,10.0);//Multiply orthographic projection matrix
                             // to this GL_PROJECTION matrix to change projection type to
                                                                  // Orthographic
glMatrixMode(GL_MODELVIEW);//Change the matrix mode to GL_MODELVIEW
    glutPostRedisplay();     //Arrange or fix or appoint or schedule a call to display
                                                          // function  as soon as possible.
}

int main(int argc,char **argv)//Comments for main included only in this program
{
printf("enter the no of division ");
scanf("%d",&n);
glutInit(&argc,argv);                                  // Initialize the graphics system
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
                                                   // Initialize the display mode
                             // to use a single buffer in the frame buffer and not DOUBLE                                       // and to use RGB color system(and not CMYK)
                                             // and to make use of DEPTH buffer since this
                                                      // is a 3D program
glutInitWindowSize(500,500);       // Initialize window size
glutCreateWindow("3d gasket");   // Create a window
glutReshapeFunc(myReshape);//Register the reshape function for call back when
                                                       // current window size changes.
glutDisplayFunc(display);       // Register the display function for call back.
                                       // Display function is called when ever the contents of
                            // the window changes as in an animation or any overlapping
                       //window gets closed and our window needs to be redrawn or our
                    // window changes shape or our window gets maximized and hence
                                     // visible from invisible
glEnable(GL_DEPTH_TEST);
                        // Enable hidden surface removal or visible surface determination
                            // this test is usually enabled in conjunction with use of
                            // GLUT_DEPTH in glutInitDisplayMode and hence only in 3D
                                         // programs
glClearColor(1.0,1.0,1.0,1.0);        // Set the background color to white
glutMainLoop();     // most important line of every program. This calls the event
                               // loop which is an infinite loop. It terminates when program
                          // is terminated. It is responsible for calling the display function, 
                           // the mouse function, the reshape function the idle function, the
                     // keyboard function, the special keyboard  function at appropriate
                         // times during the running of the program.
return 0;
}
 
If you are interested to know about a simple modification to the tetra program .... see how you can draw a sphere using this very same program here.