// Pike OpenGL demo program // Accompanies http://community.roxen.com/articles/005_opengl/ // // This code is released under the GPL. // // Copyright (c) 2000, Roxen Internet Software // Make the GL, GLUT and GLU namespaces available locally import GL; import GLUT; import GLU; int frame; int start_time; float fov=45.0; #define ROXEN_DISPLAYLIST 1 // Normalized coordinates for the different intersections // in the Roxen 'orange R' logo. constant rox_x=({ -0.500000, -0.235849, -0.084906, 0.009434, 0.254717, 0.405660, 0.500000 }); constant rox_y=({ 0.415000, 0.226321, 0.075377, -0.113302, -0.320849, -0.415189}); // Create a "side" of a box. Use the 'dir' argument to create // a correct normal. void make_side(float x0, float y0, float x1, float y1, float z, string dir) { glBegin(GL_QUADS); switch(dir) { case "up": glNormal(0.0,1.0,0.0); break; case "right": glNormal(1.0,0.0,0.0); break; case "down": glNormal(0.0,-1.0,0.0); break; case "left": glNormal(-1.0,0.0,0.0); break; } glVertex(x0, y0, z); glVertex(x1, y1, z); glVertex(x1, y1, -z); glVertex(x0, y0, -z); glEnd(); } // Creates a box, complete with normals. void make_box(float x0, float y0, float x1, float y1) { float z=0.09434/2; glBegin(GL_QUADS); glNormal(0.0, 0.0, 1.0); glVertex(x0, y0, z); glVertex(x1, y0, z); glVertex(x1, y1, z); glVertex(x0, y1, z); glEnd(); glBegin(GL_QUADS); glNormal(0.0, 0.0, -1.0); glVertex(x0, y0, -z); glVertex(x0, y1, -z); glVertex(x1, y1, -z); glVertex(x1, y0, -z); glEnd(); make_side(x1, y0, x0, y0, z, "up"); make_side(x1, y1, x1, y0, z, "right"); make_side(x0, y1, x1, y1, z, "down"); make_side(x0, y0, x0, y1, z, "left"); } // Create a Roxen 'R' logo by combining several 'boxes' void make_the_roxen_r() { glNewList(ROXEN_DISPLAYLIST, GL_COMPILE); glColor(1.0,0.5, 0.0); glMaterial(GL_FRONT, GL_DIFFUSE, ({1.0, 1.0, 1.0, 1.0}) ); make_box(rox_x[0],rox_y[0], rox_x[1],rox_y[5]); make_box(rox_x[1],rox_y[0], rox_x[6],rox_y[1]); make_box(rox_x[4],rox_y[1], rox_x[6],rox_y[2]); make_box(rox_x[2],rox_y[2], rox_x[6],rox_y[3]); make_box(rox_x[3],rox_y[3], rox_x[4],rox_y[5]); make_box(rox_x[5],rox_y[4], rox_x[6],rox_y[5]); glEndList(); } float v=0.0; void rotate_object() { // Rotate the object glRotate(v+=0.5, 0.0, 0.0, 0.25); glRotate(v, 0.0, 0.5, 0.0); glRotate(v, 0.25, 0.0, 0.0); } void print_stats() { frame++; if(!start_time) start_time = time(); werror("%2.2f fps \r", (start_time-time()?(frame / (float)(time()-start_time)): 0.0)); } void animate() { print_stats(); // Clear the RGB buffer and the depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set the modelview matrix to be the identity matrix glLoadIdentity(); glTranslate(0.0, 0.0, -5.0); rotate_object(); // Draw Roxen logo glCallList(ROXEN_DISPLAYLIST); // Make GL flush the buffer glFlush(); glutSwapBuffers(); glutPostRedisplay(); } void setup_light() { array specular = ({ 0.003, 0.003, 0.003, 1.0 }); array diffuse = ({ 0.002, 0.002, 0.002, 1.0 }); array ambient = ({ 0.0, 0.0, 0.0, 1.0 }); float shininess = 0.0; array position = ({ 0.0, 0.0, 120.0, 0.0 }); // Define material properties of specular color and degree of // shininess. Since this is only done once in this particular // example, it applies to all objects. Material properties can // be set for individual objects, individual faces of the objects, // individual vertices of the faces, etc... glMaterial(GL_FRONT_AND_BACK, GL_SPECULAR, specular); glMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT, diffuse); glMaterial(GL_FRONT_AND_BACK, GL_SHININESS, shininess); // Set the GL_AMBIENT_AND_DIFFUSE color state variable to be the // one referred to by all following calls to glColor glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); // Create a Directional Light Source glLight(GL_LIGHT0, GL_POSITION, position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } void setup_GL() { glutInit(); glutInitWindowSize(640, 480); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Rolling R"); glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); } void setup_projection() { // Make the projection matrix the current matrix glMatrixMode(GL_PROJECTION); gluPerspective( /* field of view in degrees */ 16.0, /* aspect ratio */ 1.44, /* Z near */ 1.0, /* Z far */ 20.0); // Make the modelview matrix the current matrix glMatrixMode(GL_MODELVIEW); gluLookAt(0.0, 0.0, 30.0, // eye is at (0,0,20) 0.0, 0.0, 0.0, // center is at (0,0,0) 0.0, 1.0, 0.0); // up is in positivie Y direction } int main(int argc, array(string) argv) { setup_GL(); setup_projection(); setup_light(); // Create the display list make_the_roxen_r(); glutDisplayFunc(animate); glutMainLoop(); return 0; }