/* my_sphere.cc */ /* E. Angel, Interactive Computer Graphics */ /* A Top-Down Approach with OpenGL, Third Edition */ /* Addison-Wesley Longman, 2003 */ // Modified by Dana Vrajitoru /* Recursive subdivision of cube (Chapter 6). Three display modes: wire frame, constant, and interpolative shading */ /*Program also illustrates defining materials and light sources in myiit() */ /* mode 0 = wire frame, mode 1 = constant shading, mode 3 = interpolative shading */ #include #include #include void myinit(); typedef float point[4]; /* initial tetrahedron */ point v[]={{0.0, 0.0, 1.0}, {0.0, 0.942809, -0.33333}, {-0.816497, -0.471405, -0.333333}, {0.816497, -0.471405, -0.333333}}; static GLfloat theta[] = {0.0,0.0,0.0}; static float shadow_theta = 0; int n; int mode; void shadow() { GLfloat light[3]={0.0, 10.0, 0.0}; GLfloat m[16]; //double sin(), cos(); int i; for(i=0;i<16;i++) m[i]=0.0; light[0]=5.0*sin((6.28/180.0)*shadow_theta); light[2]=5.0*cos((6.28/180.0)*shadow_theta); m[0]=m[5]=m[10]=1.0; m[7]=-1.0/light[1]; glPushMatrix(); glTranslatef(light[0], light[1], light[2]); glMultMatrixf(m); glTranslatef(-light[0], -light[1],-light[2]); GLfloat mat_specular[]={0.0, 0.0, 0.0, 1.0}; GLfloat mat_diffuse[]={0.0, 0.0, 0.0, 1.0}; GLfloat mat_ambient[]={0.2, 0.2, 0.2, 1.0}; GLfloat mat_shininess={1.0}; glTranslatef(0, -3, 0); /* define material proerties for front face of all polygons */ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); } void material1() { GLfloat mat_specular[]={1.0, 0.5, 0.5, 1.0}; GLfloat mat_diffuse[]={0.0, 0.0, 1.0, 1.0}; GLfloat mat_ambient[]={0.5, 0.5, 1.0, 1.0}; GLfloat mat_shininess={50.0}; /* define material proerties for front face of all polygons */ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); } void material2() { GLfloat mat_specular[]={1.0, 1.0, 0.0, 1.0}; GLfloat mat_diffuse[]={1.0, 0.0, 1.0, 1.0}; GLfloat mat_ambient[]={0.3, 0.3, 0.3, 1.0}; GLfloat mat_shininess={300.0}; /* define material proerties for front face of all polygons */ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); } void triangle( point a, point b, point c) /* display one triangle using a line loop for wire frame, a single normal for constant shading, or three normals for interpolative shading */ { if (mode==0) glBegin(GL_LINE_LOOP); else glBegin(GL_POLYGON); if(mode==1) glNormal3fv(a); if(mode==2) glNormal3fv(a); glVertex3fv(a); if(mode==2) glNormal3fv(b); glVertex3fv(b); if(mode==2) glNormal3fv(c); glVertex3fv(c); glEnd(); } void normal(point p) { /* normalize a vector */ //double sqrt(); float d =0.0; int i; for(i=0; i<3; i++) d+=p[i]*p[i]; d=sqrt(d); if(d>0.0) for(i=0; i<3; i++) p[i]/=d; } void divide_triangle(point a, point b, point c, int m) { /* triangle subdivision using vertex numbers righthand rule applied to create outward pointing faces */ point v1, v2, v3; int j; if(m>0) { for(j=0; j<3; j++) v1[j]=a[j]+b[j]; normal(v1); for(j=0; j<3; j++) v2[j]=a[j]+c[j]; normal(v2); for(j=0; j<3; j++) v3[j]=b[j]+c[j]; normal(v3); divide_triangle(a, v1, v2, m-1); divide_triangle(c, v2, v3, m-1); divide_triangle(b, v3, v1, m-1); divide_triangle(v1, v3, v2, m-1); } else(triangle(a,b,c)); /* draw triangle at end of recursion */ } void tetrahedron( int m) { /* Apply triangle subdivision to faces of tetrahedron */ divide_triangle(v[0], v[1], v[2], m); divide_triangle(v[3], v[2], v[1], m); divide_triangle(v[0], v[3], v[1], m); divide_triangle(v[0], v[2], v[3], m); } void display(void) { /* Displays all three modes, side by side */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glLoadIdentity(); gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0); glColor3f (1, 0.0, 0.0); mode=2; myinit(); tetrahedron(n); mode=2; glPushMatrix(); glTranslatef(-2.0, 0.0,0.0); material1(); tetrahedron(n); mode=2; material2(); glTranslatef( 4.0, 0.0,0.0); tetrahedron(n); glPopMatrix(); glTranslatef(0, -2, 0); shadow(); tetrahedron(n); glTranslatef(-2.0, 0.0,0.0); tetrahedron(n); glTranslatef( 4.0, 0.0,0.0); tetrahedron(n); glPopMatrix(); glFlush(); glutSwapBuffers(); } void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float factor=4.0; if (w <= h) glOrtho(-factor, factor, -factor * (GLfloat) h / (GLfloat) w, factor * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glOrtho(-factor * (GLfloat) w / (GLfloat) h, factor * (GLfloat) w / (GLfloat) h, -factor, factor, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); display(); } void myinit() { GLfloat mat_specular[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_diffuse[]={0.0, 0.0, 1.0, 1.0}; GLfloat mat_ambient[]={0.0, 0.5, 1.0, 1.0}; GLfloat mat_shininess={100.0}; GLfloat light_ambient[]={1.0, 1.0, 1.0, 1.0}; GLfloat light_diffuse[]={1.0, 1.0, 0.0, 1.0}; GLfloat light_specular[]={1.0, 1.0, 1.0, 1.0}; /* set up ambient, diffuse, and specular components for light 0 */ glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); /* define material proerties for front face of all polygons */ glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess); glShadeModel(GL_SMOOTH); /*enable smooth shading */ glEnable(GL_LIGHTING); /* enable lighting */ glEnable(GL_LIGHT0); /* enable light 0 */ glEnable(GL_DEPTH_TEST); /* enable z buffer */ glClearColor (1.0, 1.0, 1.0, 1.0); glColor3f (1, 0.0, 0.0); } void myidle() { shadow_theta += 0.5; if(shadow_theta>360.0) shadow_theta-=360; glutPostRedisplay(); } void main(int argc, char **argv) { n=5; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow("sphere"); myinit(); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutIdleFunc(myidle); glutMainLoop(); }