15-462: Computer Graphics Originally by: Kristin Siu, Eric Butler Edited and given by: Ilya Gershgorin Ilya: Mon. 8pm-10pm GHC 5205 Wuming: Wed. 8pm-10pm GHC 5205 OpenGL Overview The OpenGL Pipeline Drawing Primitives Transformations, Lighting, and Materials Projects Your best resource for OpenGL is this book. You’ll need it for most class projects. But you don’t have to buy it because there’s an online version! (Not the most recent, but it covers everything you’ll need) A software API with many functions that allow communication with graphics hardware. Cross-platform Commonly used in many graphics applications Games CAD Visualization OpenGL was designed to produce reasonably looking 3D images quickly and simply. A lot of its design is a rough approximation of how visual phenomena behave in the real world. Meant to only handle rendering, nothing else. ▪ So no window management, event-handling, etc. Meant to abstract away graphics hardware into a standard, clean interface. Most functions manipulate global state. 3 types of functions: Those that modify global state. Those that query global state. Those that cause something to be rendered. ▪ e.g., glEnd or glDrawElements Rendering is object-based Vertices and fragments are processed in parallel, independently of each other No global effects Basic Process: Evaluation of uniform and attribute data Processing of vertices Assembly of vertices into primitives Rasterization of primitives into fragments Processing of fragments Composition of fragments into the frame buffer Objects in OpenGL are built by assembly vertices into primitives. Example: A triangle is a primitive with 3 vertices. There are 2 primary types of data passed to OpenGL to render. Attribute Data Per-vertex information. e.g., position, normal, color, texture coordinate. Uniform Data Data that is the same for entire primitive. e.g., transformation matrix, diffuse color. Per-vertex operations are run on each vertex. Example: Transformations ▪ Figures out where vertex is relative to screen. ▪ Rotation, scaling, translation ▪ Camera projection Then vertices are assembled into primitives, where more processing occurs. e.g., clipping, depth culling. 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. After primitive assembly, primitives are converted into fragments, which are the part of a pixel that represents a single primitive. Then per-fragment operations are performed, which includes things such as texturing. OpenGL composites the fragments and stores its final output in buffers. Buffers are 2D arrays of data, generally correlating to per-pixel information. Can use buffers to store the results of intermediate stages for use in later rendering passes. You’ll get to see this in project 3. The final frame buffer is output to the screen. Note: this it not automatically cleared each frame. It must be manually cleared with glClear. Examples of common uses of buffers: Color buffers ▪ Contain information about the color of pixel Depth (Z) buffer ▪ Stores depth information of each pixel, which is used to correctly draw closer objects in front of farther ones Stencil buffer ▪ Used for cropping with complicated shapes Accumulation buffer ▪ Used to store intermediate results for use in later passes. Buffers are simply arrays with some specified format; they can be used for any purpose. There are many ways to specify vertex attribute data and render primitives. We’ll show you a few, though what you use it up to you. The methods here are the older, slower, but easier-to-use and better-supported methods. The simplest way to draw primitives is to use the OpenGL begin and end calls. Attributes specified begin glBegin/glEnd pair. Specify all vertex attributes, ending each vertex with glVertex. Can draw several of same primitive in one begin/end pair.// Sample drawing function void display_triangle() { glBegin( GL_TRIANGLES ); glColor3f( 0.0f, 0.0f, 1.0f ); // sets color to blue glVertex2f( 0.0f, 0.0f ); // draw a vertex at 0,0 glColor3f( 1.0f, 0.0f, 0.0f ); // sets color to red glVertex2f( 0.0f, 1.0f ); // draw a vertex at 0,1 // this will use same color as previous vertex glVertex2f( 1.0f, 0.0f ); glEnd(); } Pros: Very simple to use for simple objects. Can easily specify attributes. Cons: Very cumbersome to specify many objects Code is verbose. Extremely slow. ▪ Several function calls per-vertex, which add up really fast. ▪ Have to send all vertex data from CPU to GPU every frame. Major downside of glBegin/End: for anything but simple models, we need a ton 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. This gets even worse for models with thousands of vertices! OpenGL vertex arrays allow you to specify vertex data using arrays and few function calls. Place all attribute data into an array. Render the entire set of primitives at once. Several ways to specify arrays: glVertexPointer (and siblings such as glNormalPointer) to specify separate arrays for each attribute. glInterleavedArrays to store all attributes in a single array. Vertex array objects to store data on GPU. Several ways to draw primitives: 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
View Full Document