/* * simple_demo.c * Seth Long, Spring 2013 * Simple demo of OpenGL * * This should compile on most linux systems, provided glut is installed. * On Debian (and probably Ubuntu): * sudo aptitude install freeglut3-dev * Compile like this: * gcc simple_demo.c -lglut -lGL * * For OSX, it will *probably* work if you change the #includes to: * #include * #include * Compiling may be tricky, but I'd try this: * gcc -framework OpenGL -framwork GLUT simple_demo.c * You may have to install something or other first. Take a look here: * http://dottheslash.wordpress.com/2010/01/30/opengl-on-osx-with-glut-and-g/ * * For Visual Studio, these instructions look good to me (But I have not tested them!): * http://ins.nafsadh.com/2009/09/07/opengl-and-glut-in-c-with-ms-visual-studio-2008-msvs9/ * * There is a fairly extensive tutorial on glut here: * http://www.lighthouse3d.com/tutorials/glut-tutorial/ */ #include #include #include // Global variable used to specify whether glClear is called or not int clear = 1; void draw_cube(float x, float y, float z){ // Back glColor3f(0, 0, 1); glVertex3f(1+x, 1+y, -1+z); // Ab glVertex3f(1+x, -1+y, -1+z); // Bb glVertex3f(-1+x, -1+y, -1+z);// Cb glVertex3f(-1+x, 1+y, -1+z); // Db // Front glColor3f(1, 0, 0); glVertex3f(1+x, 1+y, 1+z); // A glVertex3f(1+x, -1+y, 1+z); // B glVertex3f(-1+x, -1+y, 1+z); // C glVertex3f(-1+x, 1+y, 1+z); // D // Top glColor3f(0, 1, 0); glVertex3f(1+x, 1+y, 1+z); // A glVertex3f(-1+x, 1+y, 1+z); // D glVertex3f(-1+x, 1+y, -1+z); // Db glVertex3f(1+x, 1+y, -1+z); // Ab // Left side glColor3f(1, 0, .6); glVertex3f(-1+x, 1+y, 1+z); // D glVertex3f(-1+x, -1+y, 1+z); // C glVertex3f(-1+x, -1+y, -1+z);// Cb glVertex3f(-1+x, 1+y, -1+z); // Db // Right side glColor3f(0, 1, 1); glVertex3f(1+x, 1+y, 1+z); // A glVertex3f(1+x, -1+y, 1+z); // B glVertex3f(1+x, -1+y, -1+z); // Bb glVertex3f(1+x, 1+y, -1+z); // Ab // Bottom glColor3f(.5, 1, 0); glVertex3f(1+x, -1+y, 1+z); // B glVertex3f(-1+x, -1+y, 1+z); // C glVertex3f(-1+x, -1+y, -1+z);// Cb glVertex3f(1+x, -1+y, -1+z); // Bb } /* This is used as a callback function. * That means, glut will call this function for us. Even though the function is * called from within glut, the scope of variables is from this file. So we could * use a global variable declared in this file to store things if we wanted to. */ void drawScene() { // Clears the previous drawing if clear is 1. // Otherwise the new frame will be drawn on top of it. if(clear) glClear(GL_COLOR_BUFFER_BIT); // Slightly reduce the size of the figure. This reduction is cumulative, so it // will continue shrinking. To change this, call glLoadIdentity() at the beginning // of drawScene. glScalef(.995,.995,.995); glCallList(1); // Rotation is cumulative, because glLoadIdentity() is not called. Parameters are the number // of degrees of rotation (1.25 here), and a vector describing the rotational axis (as // x, y, and z magnitudes). For example, this would rotate around the x axis instead: // glRotatef(1.25, 1, 0, 0); glRotatef(2.25, 1, 0, 1); // We're using double-buffering, and so we need to swap buffers to display the buffer that // is drawn by this function. glutSwapBuffers(); } /* The arguments this function takes have to match the ones glut wants to give it. At some point * in glut, there's something like this: * *keypress(key, x, y); * And, if we take the wrong number of arguments or something, that'll cause a problem. There * are constants defined like KP_UP for keys that don't make any of the usual characters. */ void keypress(unsigned char key, int x, int y){ switch(key){ case 'r': // glLoadIdentity undoes the cumulitive rotation and scaling // That is, it returns the square to the original spot. glLoadIdentity(); break; case 'c': clear = !clear; // if clear is 0, make it 1, if 1, make it 0. break; } } // In a console application, main actually takes arguments, although you can leave them out. // glutInit wants these arguments, so we have to include them in main. void main(int argc, char ** argv) { // glutInit initalizes various things behind the scenes. glutInit(&argc, argv); // The default here is single-buffered operation. GLUT_DOUBLE specifies double-buffering, // which allows one buffer to be displayed on the screen while the other is generated. // This avoids flickering while the next frame is created. glutInitDisplayMode(GLUT_DOUBLE); // Window size. If you don't call glutInitWindowSize, you get a default size window, // which is pretty small. glutInitWindowSize(1024, 768); // Creates a window on the screen. The parameter is the title of the window. glutCreateWindow("Simple OpenGL Demo"); glClearColor(1, 1, 1, 1); // Display list! Inform the video card where our objects are glNewList(1, GL_COMPILE); glBegin(GL_QUADS); draw_cube(0, 0, 0); draw_cube(0, 3, 0); int cubes = 2; while(cubes < 100){ draw_cube(random()%10, random()%10, random()%10); cubes++; // Makes cubes one larger than it was } glEnd(); glEndList(); // Callbacks - see explanation above. drawScene is called whenever glut is not // processing input, and because we're not using input from either the keyboard or // mouse, this will be *very* often. glutIdleFunc(drawScene); glutDisplayFunc(drawScene); // Second callback function - this time to handle keypresses. glutKeyboardFunc(keypress); // Starts an infinite loop, repeatedly calling drawScene. glutMainLoop(); }