#include // use as needed for your system #include #include #include #include #define PI 3.14159265 GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0}; /* White diffuse light. */ GLfloat light_position[] = {10.0, 10.0, 10.0, 1.0}; /* Light location. */ GLfloat material[] = {0.f, .5f, 1.f, 1.f}; /* Material for the surface. */ void ruledSurface(int steps) { /* Set material properties for the surface. */ glMaterialfv(GL_FRONT, GL_DIFFUSE, material); /* Construct a sheet with corners at (-1.0,0.0,1.0), (-1.0,0.0,-1.0), (1.0,0.0,1.0), and (1.0,1.0,-1.0). We construct this surface as a ruled surface where the left side is the line connecting the first two points: p1(s) = (-1.0,0.0,1.0-2*s), the right side is the line connecting the second two points: p2(s) = (1.0,s,1.0-2*s). The surface then is given by p(s,t) = (p1(s)*(1-t)+p2(s)*t) = (2*t-1,s*t,1-2*s). Normals are given by (dp/dt cross dp/ds) = (-2*s,2,2*t).*/ float h,u,v,s,t; float v_x,v_y,v_z; float n_x,n_y,n_z; h = 1.0/steps; /* Step size */ glBegin(GL_QUADS); for(u = 0.0;u < 1.0;u += h) for(v = 0.0;v < 1.0;v += h) { /* Compute the vertices and normals from the parameterization. */ s = u; t = v; v_x = 2*t-1.0; n_x = -2*s; v_y = s*t; n_y = 2.0; v_z = 1.0-2*s; n_z = 2*t; glNormal3f( n_x, n_y, n_z); glVertex3f( v_x, v_y, v_z ); t = v+h; v_x = 2*t-1.0; n_x = -2*s; v_y = s*t; n_y = 2.0; v_z = 1.0-2*s; n_z = 2*t; glNormal3f( n_x, n_y, n_z); glVertex3f( v_x, v_y, v_z ); s = u+h; v_x = 2*t-1.0; n_x = -2*s; v_y = s*t; n_y = 2.0; v_z = 1.0-2*s; n_z = 2*t; glNormal3f( n_x, n_y, n_z); glVertex3f( v_x, v_y, v_z ); t = v; v_x = 2*t-1.0; n_x = -2*s; v_y = s*t; n_y = 2.0; v_z = 1.0-2*s; n_z = 2*t; glNormal3f( n_x, n_y, n_z); glVertex3f( v_x, v_y, v_z ); } glEnd(); } void resize(int w,int h) { glViewport(0,0,(GLsizei) w,(GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( /* field of view in degree */ 40.0, /* aspect ratio */ (float) w/(float) h, /* Z near */ 5.0, /* Z far */ 50.0); glutPostRedisplay(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ruledSurface(20); glutSwapBuffers(); } void init(void) { /* Enable a single OpenGL light. */ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); /* Turn on automatic normalization. */ glEnable(GL_NORMALIZE); /* Use depth buffering for hidden surface elimination. */ glEnable(GL_DEPTH_TEST); /* Make sure smooth shading is turned on. */ glShadeModel(GL_SMOOTH); /* Set the clear color to white. */ glClearColor(1.0, 1.0, 1.0, 1.0); /* Setup the view of the cube. */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( /* field of view in degree */ 40.0, /* aspect ratio */ 1.0, /* Z near */ 5.0, /* Z far */ 50.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 2.0, 10.0, /* eye is at (0,2,10) */ 0.0, 0.0, 0.0, /* center is at (0,0,0) */ 0.0, 1.0, 0.); /* up is in positive Y direction */ } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(512, 512); glutInitWindowPosition(100,100); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Ruled Surface"); glutDisplayFunc(display); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }