CG Lab Manual
CG Lab Manual
RAICHUR-584134
LABORATORY MANUAL
SEMESTER: VI
#include<GL/glut.h>
#include<stdio.h>
int x1, y1, x2, y2;
void draw_pixel(int x, int y)
{
glColor3f(1.0,0.0,0.0);
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
}
void bresenhams_line_draw(int x1, int y1, int x2, int y2)
{
float dx = x2 - x1;
float dy = y2 - y1;
float m = dy/dx;
if(m < 1)
{
int decision_parameter = 2*dy - dx;
int x = x1; // initial x
int y = y1; // initial y
if(dx < 0) // decide the first point and second point
{
x = x2;
y = y2;
x2 = x1;
}
draw_pixel(x, y); // plot a point
while(x < x2) // from 1st point to 2nd point
{
if(decision_parameter >= 0)
{
x = x+1;
y = y+1;
decision_parameter=decision_parameter + 2*dy - 2*dx * (y+1 - y);
}
else
{
x = x+1;
y = y;
decision_parameter = decision_parameter + 2*dy - 2*dx * (y- y);
}
draw_pixel(x, y);
}
}
else if(m > 1)
{
int decision_parameter = 2*dx - dy;
x = x+1;
y = y+1;
decision_parameter=decision_parameter + 2*dx - 2*dy * (x+1 - x);
}
else
{
y = y+1;
x = x;
decision_parameter = decision_parameter + 2*dx - 2*dy * (x- x);
}
draw_pixel(x, y);
}
}
else if (m == 1)
{
int x = x1;
int y = y1;
draw_pixel(x, y);
while(x < x2)
{
x = x+1;
y = y+1;
draw_pixel(x, y);
}
}
}
void init()
{
glClearColor(1,1,1,1);
gluOrtho2D(0.0, 500.0, 0.0, 500.0); // left ->0, right ->500, bottom ->0,
top ->500
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
bresenhams_line_draw(x1, y1, x2, y2);
glFlush();
}
OUTPUT:
2. Create and rotate a triangle about the origin and a fixed
point.
#include<GL/glut.h>
#include<stdio.h>
int x,y;
int where_to_rotate=0; // don't rotate initially
float rotate_angle=0; // initial angle
float translate_x=0,translate_y=0; // initial translation
void draw_pixel(float x1, float y1)
{
glPointSize(5);
glBegin(GL_POINTS);
glVertex2f(x1,y1); // plot a single point
glEnd();
}
void triangle(int x, int y)
{
glColor3f(1,0,0);
glBegin(GL_POLYGON); // drawing a Triangle
glVertex2f(x,y);
glVertex2f(x+400,y+300);
glVertex2f(x+300,y+0);
glEnd();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(1,1,1); // mark origin point as white dot
draw_pixel(0,0); // plot origin - white colour
if (where_to_rotate == 1) //Rotate Around origin
{
translate_x = 0; // no translation for rotation around origin
translate_y = 0;
rotate_angle += 1; // the amount of rotation angle
}
if (where_to_rotate == 2) //Rotate Around Fixed Point
{
translate_x = x; // SET the translation to wherever the customer says
translate_y = y;
rotate_angle += 1; // the amount of rotation angle
glColor3f(0,0,1); // mark the customer coordinate as blue dot
draw_pixel(x,y); // plot the customer coordinate - blue colour
}
glTranslatef(translate_x, translate_y, 0); // ACTUAL translation +ve
glRotatef(rotate_angle, 0, 0, 1); // rotate
glTranslatef(-translate_x, -translate_y, 0); // ACTUAL translation -ve
triangle(translate_x,translate_y); // what to rotate? - TRIANGLE
glutPostRedisplay(); // call display function again and again
glutSwapBuffers(); // show the output
}
void init()
{
glClearColor(0,0,0,1); //setting to black
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-800, 800, -800, 800);
glMatrixMode(GL_MODELVIEW);
}
void rotateMenu (int option)
{
if(option==1)
where_to_rotate=1; // rotate around origin
if(option==2)
where_to_rotate=2; // rotate around customer's coordinates
if(option==3)
OUTPUT:
3. Draw a colour cube and spin it using OpenGL transformation
matrices.
#include<stdlib.h>
#include<GL/glut.h>
GLfloat vertices[]= {-1, -1, -1,
1, -1, -1,
1, 1, -1,
-1, 1, -1,
-1, -1, 1,
1, -1, 1,
1, 1, 1,
-1, 1, 1
};
GLfloat colors[]= {0, 0, 0,
1, 0, 0,
1, 1, 0,
0, 1, 0,
0, 0, 1,
1, 0, 1,
1, 1, 1,
0, 1, 1
};
GLubyte cubeIndices[]= {0, 3, 2, 1,
2, 3, 7, 6,
0, 4, 7, 3,
1, 2, 6, 5,
4, 5, 6, 7,
0, 1, 5, 4
};
static GLfloat theta[]= {0,0,0};
static GLint axis=2;
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(theta[0], 1, 0, 0);
glRotatef(theta[1], 0, 1, 0);
glRotatef(theta[2], 0, 0, 1);
glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,cubeIndices);
glutSwapBuffers();
}
void spinCube()
{
theta[axis] += 2;
if(theta[axis] > 360)
theta[axis] -= 360;
glutPostRedisplay();
}
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;
}
void myReshape(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-2, 2, -2*(GLfloat)h/(GLfloat)w, 2*(GLfloat)h/(GLfloat)w, -10, 10);
else
glOrtho(-2*(GLfloat)w/(GLfloat)h, 2*(GLfloat)w/(GLfloat)h, -2, 2, -10, 10);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("Spin a color cube");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glutIdleFunc(spinCube);
glutMouseFunc(mouse);
glEnable(GL_DEPTH_TEST);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(3, GL_FLOAT, 0, colors);
glColor3f(1, 1, 1);
glutMainLoop();
}
OUTPUT:
4. Draw a color cube and allow the user to move the camera suitably
to experiment with perspective viewing.
#include <stdlib.h>
#include <GL/glut.h>
GLfloat vertices[][3] = { {-1,-1,-1},
{1,-1,-1},
{1,1,-1},
{-1,1,-1},
{-1,-1,1},
{1,-1,1},
{1,1,1},
{-1,1,1}
};
GLfloat colors[][3] = { {1,0,0},
{1,1,0},
{0,1,0},
{0,0,1},
{1,0,1},
{1,1,1},
{0,1,1},
{0.5,0.5,0.5}
};
GLfloat theta[] = {0.0,0.0,0.0};
GLint axis = 2;
GLdouble viewer[]= {0.0, 0.0, 5.0}; // initial viewer location //
void polygon(int a, int b, int c, int d)
{
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)
{
polygon(0,3,2,1);
polygon(0,4,7,3);
polygon(5,4,0,1);
polygon(2,3,7,6);
polygon(1,2,6,5);
polygon(4,5,6,7);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(viewer[0],viewer[1],viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
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)
{
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;
display();
}
void myReshape(int w, int h)
{
glViewport(0, 0, w, h);
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();
}
OUTPUT:
OUTPUT:
OUTPUT:
7. Design, develop and implement recursively subdivide a
tetrahedron to form 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>
typedef float point[3];
point v[]= {{0, 0, 1}, {0, 1, 0}, {-1, -0.5, 0}, {1, -0.5, 0}};
int n;
void triangle(point a,point b,point c)
{
glBegin(GL_POLYGON);
glVertex3fv(a);
glVertex3fv(b);
glVertex3fv(c);
glEnd();
}
void divide_triangle(point a,point b,point c,int n)
{
point v1,v2,v3;
int j;
if(n>0)
{
for(j=0; j<3; j++)
v1[j] = (a[j]+b[j])/2;
for(j=0; j<3; j++)
v2[j] = (a[j]+c[j])/2;
for(j=0; j<3; j++)
v3[j] = (c[j]+b[j])/2;
divide_triangle(a,v1,v2,n-1);
glFlush();
divide_triangle(c,v2,v3,n-1);
glFlush();
divide_triangle(b,v3,v1,n-1);
glFlush();
}
else(triangle(a,b,c));
}
void tetrahedron(int n)
{
glColor3f(1, 0, 0);
divide_triangle(v[0], v[1], v[2], n);
glColor3f(0, 1, 0);
divide_triangle(v[3], v[2], v[1], n);
glColor3f(0, 0, 1);
divide_triangle(v[0], v[3], v[1], n);
glColor3f(0, 0, 0);
divide_triangle(v[0], v[2], v[3], n);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
tetrahedron(n);
glFlush();
}
void myReshape(int w,int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-2, 2, -2*(GLfloat)h/(GLfloat)w, 2*(GLfloat)h/(GLfloat)w, -10, 10);
else
glOrtho(-2*(GLfloat)w/(GLfloat)h, 2*(GLfloat)w/(GLfloat)h, -2, 2, -10, 10);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
int main(int argc,char ** argv)
{
printf("No of Recursive steps/Division: ");
scanf("%d",&n);
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutCreateWindow(" 3D Sierpinski gasket");
glutReshapeFunc(myReshape);
glutDisplayFunc(display);
glEnable(GL_DEPTH_TEST);
glClearColor(1, 1, 1, 0);
glutMainLoop();
return 0;
}
OUTPUT:
#include<GL/glut.h>
#include<stdio.h>
#include<math.h>
#define PI 3.1416
float theta = 0;
struct point
{
GLfloat x, y, z;
};
int factorial(int n)
{
if (n<=1)
return(1);
else
n=n*factorial(n-1);
return n;
}
void computeNcR(int n, int *hold_ncr_values)
{
int r;
for(r=0; r<=n; r++) //start from nC0, then nC1, nC2, nC3 till nCn
{
hold_ncr_values[r] = factorial(n) / (factorial(n-r) * factorial(r));
}
}
void computeBezierPoints(float t, point *actual_bezier_point, int
number_of_control_points, point *control_points_array, int *hold_ncr_values)
{
int i, n = number_of_control_points-1;
float bernstein_polynomial;
actual_bezier_point -> x = 0;
actual_bezier_point -> y = 0;
actual_bezier_point -> z = 0;
for(i=0; i < number_of_control_points; i++)
{
bernstein_polynomial = hold_ncr_values[i] * pow(t, i) * pow( 1-t, n-i);
actual_bezier_point -> x += bernstein_polynomial * control_points_array[i].x;
actual_bezier_point -> y += bernstein_polynomial * control_points_array[i].y;
actual_bezier_point -> z += bernstein_polynomial * control_points_array[i].z;
}
}
void bezier(point *control_points_array, int number_of_control_points, int
number_of_bezier_points)
{
point actual_bezier_point;
float t;
int *hold_ncr_values, i;
hold_ncr_values = new int[number_of_control_points]; // to hold the nCr
values
computeNcR(number_of_control_points-1, hold_ncr_values); // call nCr
function to calculate nCr values
glBegin(GL_LINE_STRIP);
for(i=0; i<=number_of_bezier_points; i++)
{
t=float(i)/float(number_of_bezier_points);
computeBezierPoints(t, &actual_bezier_point, number_of_control_points,
control_points_array, hold_ncr_values);
glVertex2f(actual_bezier_point.x, actual_bezier_point.y);
}
glEnd();
delete[] hold_ncr_values;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
int number_of_control_points = 4, number_of_bezier_points = 20;
point control_points_array[4] = {{100, 400, 0}, {150, 450, 0}, {250, 350, 0},{300,
400, 0}};
control_points_array[1].x += 50*sin(theta * PI/180.0);
control_points_array[1].y += 25*sin(theta * PI/180.0);
control_points_array[2].x -= 50*sin((theta+30) * PI/180.0);
control_points_array[2].y -= 50*sin((theta+30) * PI/180.0);
control_points_array[3].x -= 25*sin((theta-30) * PI/180.0);
control_points_array[3].y += sin((theta-30) * PI/180.0);
theta += 2;
glPushMatrix();
glPointSize(5);
glColor3f(1, 0.4, 0.2); //Indian flag: Saffron color code
for(int i=0; i<50; i++)
{
glTranslatef(0, -0.8, 0 );
bezier(control_points_array, number_of_control_points,
number_of_bezier_points);
}
glColor3f(1, 1, 1); //Indian flag: white color code
for(int i=0; i<50; i++)
{
glTranslatef(0, -0.8, 0);
bezier(control_points_array, number_of_control_points,
number_of_bezier_points);
}
glColor3f(0, 1, 0); //Indian flag: green color code
for(int i=0; i<50; i++)
{
glTranslatef(0, -0.8, 0);
bezier(control_points_array, number_of_control_points,
number_of_bezier_points);
}
glPopMatrix();
glLineWidth(5);
glColor3f(0.7, 0.5,0.3); //pole colour
glBegin(GL_LINES);
glVertex2f(100,400);
glVertex2f(100,40);
glEnd();
glutPostRedisplay();
glutSwapBuffers();
}
void init()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,500,0,500);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(0, 0);
glutInitWindowSize(500,500);
glutCreateWindow("Bezier Curve - updated");
init();
glutDisplayFunc(display);
glutMainLoop();
}
OUTPUT:
9. Develop a menu driven program to fill the polygon using scan line
algorithm.
// Scan-Line algorithm for filling a polygon
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
float x1, x2, x3, x4, y1, y2, y3, y4; // our polygon has 4 lines - so 8 coordinates
void edgedetect(float x1, float y1, float x2, float y2, int *left_edge, int
*right_edge)
{
float x_slope, x, temp;
int i;
if ((y2-y1)<0) // decide where to start
{
temp = y1;
y1 = y2;
y2 = temp;
temp = x1;
x1 = x2;
x2 = temp;
}
if ((y2-y1)!=0)
x_slope = (x2 - x1) / (y2 - y1);
else
x_slope = x2 - x1;
x = x1;
for (i = y1; i <= y2; i++)
{
if (x < left_edge[i])
left_edge[i] = x;
if (x > right_edge[i])
right_edge[i] = x;
x = x + x_slope;
}
}
void draw_pixel (int x, int y)
{
glColor3f (1, 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 left_edge[500], right_edge[500];
int i, y;
for (i = 0; i <= 500; i++)
{
left_edge [i] = 500;
right_edge [i] = 0;
}
edgedetect (x1, y1, x2, y2, left_edge, right_edge);
edgedetect (x2, y2, x3, y3, left_edge, right_edge);
edgedetect (x3, y3, x4, y4, left_edge, right_edge);
edgedetect (x4, y4, x1, y1, left_edge, right_edge);
for (y = 0; y <= 500; y++)
{
if (left_edge[y] <= right_edge[y])
{
for (i = left_edge[y]; i <= right_edge[y]; i++)
{
draw_pixel (i, y);
glFlush ();
}
}
}
}
void display()
{
x1 = 200, y1 = 200;
x2 = 100, y2 = 300;
x3 = 200, y3 = 400;
x4 = 300, y4 = 300;
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (0, 0, 1);
glBegin (GL_LINE_LOOP);
glVertex2f (x1, y1);
glVertex2f (x2, y2);
glVertex2f (x3, y3);
glVertex2f (x4, y4);
glEnd ();
scanfill (x1, y1, x2, y2, x3, y3, x4, y4);
}
void init()
{
glClearColor (1, 1, 1, 1);
gluOrtho2D (0, 499, 0, 499);
}
int main (int argc, char** argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (0, 0);
glutCreateWindow ("Filling a Polygon using Scan-line Algorithm");
init ();
glutDisplayFunc (display);
glutMainLoop ();
}
OUTPUT: