/* * ACM/SIGGRAPH University of Michigan Student Chapter * OpenGL Workshop * * OpenGL Basics * * This program goes over some of the basic drawing functions in OpenGL and * also introduces some new GLUT functions. * */ #include // This will let us output stuff to the console #include // Need this to do sine and cosine #include // Need this to call tolower() #include // Include the GLUT and OpenGL libraries using namespace std; /* Constrants */ const double PI = acos(-1.0); /* Enumertions */ enum WhatToDraw_t { POINTS, LINES, TRIANGLES, QUADS, POLYS }; /* Global Variables */ // This variable tells us what to draw: WhatToDraw_t whatToDraw = POINTS; // What size should our points be: float pointSize = 1.0; // How wide should our lines be: float lineWidth = 1.0; // How many sides should our polygon have: int polySides = 5; /* Function Prototypes */ // Initialize the state of OpenGL: bool initOpenGL(); // Our GLUT reshape function: void reshape(int new_width, int new_height); // Our GLUT display function: void display(); // Our GLUT keyboard function: void key(unsigned char key, int x, int y); // Some drawing functions: void drawPoints(); void drawLines(); void drawTriangles(); void drawQuads(); void drawPoly(int num_sides); int main(int argc, char **argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // This function sets the size (width, height) of the window we are about to create. // Right here we set the size to 800 pixels wide and 600 pixels high: glutInitWindowSize(800, 600); // This function sets the position (xy-coordinate) of the upper-left corner of the // window we are about to create. This particular call sets to the upper-left // corner to be at (50, 50) in screen pixels: glutInitWindowPosition(50, 50); glutCreateWindow("OpenGL Basics"); // This function tells the GLUT to call the function reshape() whenever our window is // resized. It passes the new width and new height of the window to reshape as // arguments. glutReshapeFunc(reshape); glutDisplayFunc(display); // Tell the GLUT to call key every time a key is pressed: glutKeyboardFunc(key); initOpenGL(); glutMainLoop(); return 0; } bool initOpenGL(){ // Output our OpenGL Vender and Version: cout << "OpenGL Vender:\t\t" << glGetString(GL_VENDOR) << endl; cout << "OpenGL Renderer:\t" << glGetString(GL_RENDERER) << endl; cout << "OpenGL Version:\t\t" << glGetString(GL_VERSION) << endl; // Enable depth testing (using the depth buffer to see if something needs to drawn or not: glEnable(GL_DEPTH_TEST); // Call our reshape function to setup the viewport and projection matrix: reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)); // Setup the model view matrix: glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, // Position the camera's eye at (0,0,5) 0.0, 0.0, 0.0, // Set the center of the scene to be at (0,0,0) 0.0, 1.0, 0.0); // Set the up vector of the camera to the positive Y direction return true; } void reshape(int new_width, int new_height){ // Output what is happening: cout << "Resizing window to " << new_width << " pixels X " << new_height << " pixels" << endl; // Setup our viewport. Just make one viewport that is as big as the entire // window: glViewport(0, 0, new_width, new_height); // Setup the projeciton matrix: glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( 60.0, // Field of view in degrees // Calculate the aspect ratio from the width and height of the window: static_cast(new_width)/static_cast(new_height), // Aspect ratio 1.0, // Position of near clipping plane 10.0); // Position of far clipping plane } void display(){ // Output what is happening: cout << "Drawing our scene..." << endl; // Set our clear color: glClearColor(0.0, 0.0, 0.0, 0.0); // Clear the previously drawn scene: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Draw the new scene: glColor3f(1.0, 1.0, 1.0); switch(whatToDraw){ case POINTS: drawPoints(); break; case LINES: drawLines(); break; case TRIANGLES: drawTriangles(); break; case QUADS: drawQuads(); break; case POLYS: drawPoly(polySides); break; } glutSwapBuffers(); } void key(unsigned char key, int x, int y){ key = tolower(key); switch(key){ case 'p': whatToDraw = POINTS; break; case 'l': whatToDraw = LINES; break; case 't': whatToDraw = TRIANGLES; break; case 'q': whatToDraw = QUADS; break; case 'g': whatToDraw = POLYS; break; case '-': // Decrease the point size, line width, and number of polygon sides: if(pointSize > 1.0) pointSize -= 0.1; if(lineWidth > 1.0) lineWidth -= 0.1; if(polySides > 3) --polySides; break; case '=': case '+': // Increase the point size, line width, and number of polygon sides: pointSize += 0.1; lineWidth += 0.1; ++polySides; break; } glutPostRedisplay(); } // Drawing functions: void drawPoints(){ glPointSize(pointSize); glBegin(GL_POINTS); glVertex3f(0.0, 1.0, 0.0); glVertex3f(0.5, 0.0, 0.0); glVertex3f(-0.5, 0.0, 0.0); glEnd(); } void drawLines(){ glLineWidth(lineWidth); glLineStipple(1, 0xFFFF); glBegin(GL_LINES); // We need two vertices to make each line: glVertex3f(0.0, 1.0, 0.0); glVertex3f(0.5, 0.0, 0.0); glVertex3f(1.0, 1.0, 0.0); glVertex3f(1.0, 0.5, 0.0); glVertex3f(-1.0, -1.0, 0.0); glVertex3f(-0.5, -0.5, 0.5); glEnd(); } void drawTriangles(){ glFrontFace(GL_CCW); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); */ glBegin(GL_TRIANGLES); glVertex3f(0.0, 1.0, 0.0); glVertex3f(-0.5, 0.0, 0.0); glVertex3f(0.5, 0.0, 0.0); glEnd(); } void drawQuads(){ glFrontFace(GL_CCW); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); */ glBegin(GL_QUADS); glVertex3f(-0.5, 0.5, 0.0); glVertex3f(-0.5, -0.5, 0.0); glVertex3f(0.5, -0.5, 0.0); glVertex3f(0.5, 0.5, 0.0); glEnd(); } void drawPoly(int num_sides){ glFrontFace(GL_CCW); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); */ glBegin(GL_POLYGON); for(double angle = 0; angle < 2*PI; angle += ((2*PI)/num_sides)){ glVertex3f(cos(angle), sin(angle), 0.0); } glEnd(); }