15-462: Computer GraphicsZeyang Li, Kristin Siu, Eric Butler OpenGL Overview Primitives and Drawing Transformations Lighting and Materials Project 0 Your best resource for OpenGL is this book. But you don’t have to buy it because there’s an online version! Not to be confused with the Orange Book (or the Blue Book or the Green Book…) OpenGL is a software API consisting of many functions that allow you to talk to your graphics hardware. It is cross-platform and is most commonly used in professional graphics applications. OpenGL was designed to produce reasonably looking 3D images quickly and simply. Therefore, a lot of its design is a rough approximation of how visual phenomena behave in the real world. Keep this in mind as we discuss how it works. Few OpenGL functions cause anything to be drawn. Instead, they modify state of the OpenGL driver. Draw calls use the current state. Example draw calls are glVertex, glDrawElements OpenGL stores per-pixel information in different buffers. The frame buffer is the final output to the screen. A collection of intermediate buffers store information about pixels. If we are rendering multiple frames, we need to clear the buffers before we draw a new frame. OpenGL allows us to modify the following buffers: Color buffers (multiple)▪ contain information about the color of pixel Depth (z) buffer▪ stores depth information of each pixel, allowing closer objects to be drawn over those farther away Stencil buffer▪ extra buffer used for advanced techniques Accumulation buffer▪ extra buffer used for special effects 3D drawing in OpenGL uses primitives. Primitives are points, lines, and various polygons that make up larger objects. Every primitive is defined by some number of points, or vertices, which are specified during draw calls. GL_POINTS Simply draws single vertices in the order you pass them in. GL_LINES Takes pairs of vertices and draws lines between them. GL_LINE_STRIP Takes any number of vertices and draws a series of connected line segments. GL_LINE_LOOP Same as above, but with the first and last endpoints connected. GL_TRIANGLES Takes vertices in triples and draws them as triangles. GL_QUADS Takes vertices in quadruples and draws them as four-sided polygons. GL_POLYGON Takes any number of vertices and draws the boundaries of the convex polygon that they form. Note: Order of vertices here is important. All polygons must be convex and their edges cannot intersect. Most objects can be drawn using only GL_TRIANGLES. Note: There are other primitives (GL_TRIANGLE_STRIP, GL_QUAD_STRIP, and GL_TRIANGLE_FAN). You can find more information about these in the red book Each vertex must be specified by at least a position (glVertex). OpenGL has other built in attributes: Normals Color Texture coordinates The simplest way to draw primitives is to use the OpenGL begin and end calls. Declare our primitive: glBegin( … ) Specify our vertices (and attributes) glNormal*( … ) glVertex*( … ) Declare that we are finished: glEnd()// Sample drawing functionvoid display_square() {…glBegin(GL_QUADS);glColor3f( 0.0, 0.0, 1.0 ); // sets color to blueglVertex2f( 0.0, 0.0 );glVertex2f( 0.0, 1.0 );glColor3f( 1.0, 0.0, 0.0 ); // sets color to redglVertex2f( 1.0, 1.0 );glVertex2f( 1.0, 0.0 );glEnd();} The downside of using glVertex is that for anything but simple models, we must make an enormous number of function calls. Consider a cube. Each vertex needs to be declared three times, once for each face it is a part of, resulting in 24 glVertex calls. OpenGL provides vertex array routines that allow you to specify vertex data using arrays and few function calls. You must enable your array: glEnableClientState( … )▪ Specify the type of array (GL_VERTEX_ARRAY) You must specify data for your array glVertexPointer( … )▪ Specify the number of coordinates per vertex, type, byte offset between vertices, and a pointer to the first vertex in input array All other attributes (e.g. normal) have their own arrays. There are three ways to call access elements of the vertex array: glArrayElement( … )▪ Draws a single vertex glDrawArrays( … )▪ Draws a sequence of vertices glDrawElements( … )▪ Draws a sequence of vertices based on an indexed array.▪ Generally you want to use this one.// Sample code using vertex arraysvoid init_array() {float vertices[] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.00.0, 0.0, 1.0 };glEnableClientState( GL_VERTEX_ARRAY );glVertexPointer( 3, GL_FLOAT, 0, vertices );}void display_square() {unsigned int indices[] = { 0, 1, 2 };glDrawElements( GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices );} Display lists provide a way for OpenGL to redraw arbitrary primitives with a single draw call. Display lists compile a set of commands that draw a particular object. Use them only for static (unchanging) geometry. Generate a new list glGenLists( … ) Declare a new list glNewList( … ) Draw an object in between Declare the end of the list glEndList() Anytime you want to draw your object, call: glCallList( … )int list;// Some method called during initializationvoid initialize_triangle (){list = glGenLists( 1 );glNewList( list, GL_COMPILE );glBegin( GL_TRIANGLE );glVertex2f( 0.0, 0.0 );glVertex2f( 0.0, 1.0 );glVertex2f( 1.0, 1.0 );glEnd();glEndList();}// Sample drawing functionvoid display_callback(){…glCallList( list );} Right now, we can draw simple primitives and build scenes. However, transformations of the original vertices may be required in order to properly view our objects. Transformations in OpenGL are accomplished using matrices. OpenGL tracks two different vertices for vertex transformations: ModelView Matrix (GL_MODELVIEW)▪ These concern model-related operations such as translation, rotation, and scaling, as well as viewing transformations. Projection Matrix (GL_PROJECTION)▪ Setup camera projection.// Sample code showing matrix transformationsvoid display_object(){…glMatrixMode( GL_MODELVIEW ); // Loads matrixglLoadIdentity(); // Clears the matrixglTranslatef( 0.0, 0.0, -2.0 ); // Some transformationsglRotatef( 45.0, 0.0, 0.0, 1.0 );glScalef( 2.0, 2.0, 2.0 );draw_object();} OpenGL allows for 3 basic model transformations: glTranslate* (TYPE x, TYPE y, TYPE
View Full Document