Sunday, April 28, 2013

To display a set of {fij} values as a rectangular mesh

10. Program to display a set of values {fij} as a rectangular mesh.

#include<GL/glut.h>
#include<stdio.h>
static  GLdouble  viewer[]={0,0,5};
int  m, n;
void rectmesh( int  m, int  n)
{
            int  i, j;
            for(i=0;i<m;i++)
            for(j=0;j<n;j++)
            {
            glBegin(GL_LINE_LOOP);
            glVertex2i( i, j);
            glVertex2i( i+1, j);
            glVertex2i( i+1, j+1);
            glVertex2i( i, j+1);
            glEnd();
            }
}
void display()
{
            glClear(GL_COLOR_BUFFER_BIT);
            glLoadIdentity();
            gluLookAt(viewer[0],viewer[1],viewer[2],0,0,0,0,1,0);
            glTranslated(0,0,-5);
            glColor3f(0,0,0);
            rectmesh( m, n);
            glFlush();
}
void myReshape(int w,int h)
{
            glViewport(0,0,w,h);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(-2,20,-2,20,-10,20);
            glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char **argv)
{
printf(“enter m & n:”);
scanf(“%d%d”,&m,&n);
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow(“Rectangular Mesh”);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glClearColor(1.0,1.0,1.0,1.0);
glutMainLoop();
return 0;
}

Saturday, April 27, 2013

Scanline-Area Filling Algorithm

9. program to fill any given polygon using scanline-area filling algorithm.

Exams approaching and it is tough to get someone to explain the code to you.... Here are some comments to understand the code.

Scan-line area filling uses the property of coherence to color the polygon. Scanline coherence means if a point lies inside a polygon then other points lying on the same scanline near to it are also likely to be inside the polygon.

There are various ways to check if a point is inside the polygon or not. If somehow all pixels lying inside are found out then it is just a matter of changing their pixel value to color the polygon.

In this program it uses two arrays le and re denoting left edge and right edge. They span the entire window height(500-array size) and store the position(x value) of the intersection point of the scan line with one of the edges of polygon(either left or right).

Initial values in le array is 500. That of re array is 0. We scan convert individual edges of the polygon and each point on the edge, its x value goes to the correct le or re array.

Finally once le and re arrays are populated we draw a line from the left edge to the right edge in a loop and iterate over the entire window region(all 500 scanlines).

#include<stdio.h>
#include<GL/glut.h>
GLfloat x1,y1,x2,y2,x3,y3,x4,y4;
void edgedetect(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2,int *le,int *re)
{
            float mx,x,temp;
            int i;
            if((y2-y1)<0)    // if second point is below first point interchange them
            {
              temp=x1;x1=x2;x2=temp;
              temp=y1;y1=y2;y2=temp;
            }
              if((y2-y1)!=0)      // if denominator is zero we can't find slope
                        mx=(x2-x1)/(y2-y1);
            else
                        mx=x2-x1;    // y2-y1=0 implies line is horizontal
            x=x1;
            for(i=y1;i<y2;i++)        // starting from x1,y1 add slope mx to x
            {                                  // and round it to find the next point on the
                                                // line. For that particular scan line i
                        if(x<le[i])         // insert the x value into either le or re.
                                    le[i]=x; // Initially both le and re will contain same
                                                // value...
                        if(x>re[i])         // in the next time for the other edge
                                    re[i]=x; // either le or re will change
                        x+=mx;            // NOTE: le and re are integer arrays and x
            }                                  // is float so automatic type conversion.
}
void drawpixel(int x,int y)
{
            glColor3f(0.0,1.0,1.0);
            glBegin(GL_POINTS);
            glVertex2i(x,y);
            glEnd();
}
void scanfill(float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4)
{
            int le[500],re[500];
            int i,y;
            for(i=0;i<500;i++)   // initialize le and re array values
            {
                        le[i]=500;
                        re[i]=0;
            }
            edgedetect(x1,y1,x2,y2,le,re);    // call edge detect four times
            edgedetect(x2,y2,x3,y3,le,re);    // once for each edge.
            edgedetect(x3,y3,x4,y4,le,re);
            edgedetect(x4,y4,x1,y1,le,re);
for(y=0;y<500;y++)        // for every scan line with value y
{
           if(le[y]<=re[y])            // refer to le and re arrays to see if a part
                        for(i=le[y]+1;i<re[y];i++) // of the scanline is inside polygon
                                    drawpixel(i,y);       // if so draw a horizontal line from
}                                                              // left edge to right edge
}
void display()
{
            glClear(GL_COLOR_BUFFER_BIT);
            x1=200,y1=200,x2=100,y2=300,x3=200,y3=400,x4=300,y4=300;
            glBegin(GL_LINE_LOOP);       // draw the boundary of the polygon
            glVertex2f(x1,y1);                   // to be filled.
             glVertex2f(x2,y2);
            glVertex2f(x3,y3);
            glVertex2f(x4,y4);
    glEnd();
   scanfill(x1,y1,x2,y2,x3,y3,x4,y4);       // call scanfill to fill the polygon
   glFlush();   // Usually students fail the lab because they forget glFlush.
}
void myinit()
{
            glClearColor(1.0,1.0,1.0,1.0);
            glColor3f(0.0,0.0,1.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);// 500 height is hardcoded
            glutInitWindowPosition(0,0);
            glutCreateWindow("scanfill");
            glutDisplayFunc(display);
            myinit();
            glutMainLoop();
            return 0;
   }

To draw a color cube and allow the user to move the camera


8.  Program to draw a color cube and allow the user to move the camera suitably to experiment with  perspective viewing using OpenGL functions.
 
#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 normals[][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,1.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}};
void polygon(int a, int b, int c, int d)
{
            glBegin(GL_POLYGON);
            glColor3fv(colors[a]);
            glNormal3fv(normals[a]);
            glVertex3fv(vertices[a]);
            glColor3fv(colors[b]);
            glNormal3fv(normals[b]);
            glVertex3fv(vertices[b]);
            glColor3fv(colors[c]);
            glNormal3fv(normals[c]);
            glVertex3fv(vertices[c]);
            glColor3fv(colors[d]);
            glNormal3fv(normals[d]);
            glVertex3fv(vertices[d]);
            glEnd();
}
void colorcube()
{           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);
}
static GLfloat theta[] = {0.0,0.0,0.0};
static GLint axis =2;
static GLdouble viewer[] = {0.0,0.0,5.0};
void display(void)
{
            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
            //update viewer position in modelview matrix
  glLoadIdentity();
  gluLookAt(viewer[0],viewer[1],viewer[2],0.0,0.0,0.0,0.0,1.0,0.0);
  //rotate cube
  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 mouse(int btn, int state, int x,int y)
{
   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;
   theta[axis] += 2.0;
   if(theta[axis]>360.0)theta[axis]-=360.0;
   display();
}
void Keys(unsigned char key, int x,int y)
{
            // use x, X,y,Y,z and Z keys to move viewer
            if(key =='x') viewer[0]-=1.0;
            if(key =='X') viewer[0]+=1.0;
            if(key =='y') viewer[1]-=1.0;
            if(key =='Y') viewer[1]+=1.0;
            if(key =='z') viewer[2]-=1.0;
            if(key =='Z') viewer[2]+=1.0;
      glutPostRedisplay();
}
void myReshape(int w,int h)
{
            glViewport(0,0,w,h);
            //use the prespective view
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
           if(w<=h)
glFrustum(-2.0,2.0,-2.0*(GLfloat) h/(GLfloat) w, 2.0*(GLfloat) h/(GLfloat) w ,2.0,20.0);
    else
glFrustum(-2.0,2.0,-2.0*(GLfloat) w/(GLfloat) h, 2.0*(GLfloat) w/(GLfloat) h ,2.0,20.0);
  glMatrixMode(GL_MODELVIEW);
}
Int main(int argc,char** argv)
{
            glutInit(&argc,argv);
            glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
             glutInitWindowSize(500,500);
            glutCreateWindow("colorcube viewer");
            glutReshapeFunc(myReshape);
            glutDisplayFunc(display);
            glutMouseFunc(mouse);
            glutKeyboardFunc(Keys);
            glEnable(GL_DEPTH_TEST);
            glutMainLoop();
            return 0;
}