320 likes | 600 Views
OpenGL introduction. Mark Nelson mjas@itu.dk. 3d API landscape. DirectX OpenGL OpenGL ES WebGL. 3d API purposes. Portable way of accessing 3d graphics hardware Implementation of common operations But this is becoming less emphasized. OpenGL structure.
E N D
OpenGL introduction • Mark Nelson • mjas@itu.dk Fall 2012 www.itu.dk
3d API landscape DirectX OpenGL OpenGL ES WebGL
3d API purposes Portable way of accessing 3d graphics hardware Implementation of common operations But this is becominglessemphasized
OpenGL structure OpenGL itself is the 3d API An OpenGL target or context is what you draw into Usually has an attached surface, but not strictly identical to it Stores render state parameters
OpenGL structure OpenGL doesn’t cover OS-specific operations Opening and resizing windows Handling input Either target a specific platform (e.g. Win32* calls) Or use a utility library glut, freeglut, SDL
OpenGL structure Other stuff GLU is a utility library shipped with OpenGL (glu* functions) GLSL is the shader language (replaces Cg/etc.) Extensions can add functionality If you use any, consider an extension manager like GLEW
Built-in functionality, versus general API Recall the discussion of hardware sprites, 2d collision detection, and similar features in old consoles Some similar patterns of development in OpenGL (Also compare the RISC v. CISC debate)
Classic OpenGL Fixed-function pipeline Implementation of textbook-standard rendering Immediate mode Context is updated by directly calling update functions
Hardware T&L • Late-90s / most-of-2000s trend towards GPU T&L • Fixed pipeline • Definelights, shading modes, textures, etc. • GPU computeslightness of polygons
Immediate-mode rendering Immediate-mode rendering Renders to screen, well, immediately Triangle is sent to GPU textured/lit/transformed/etc. Rendered to framebuffer To avoid flickering, SDL provides double-buffering Render to off-screen buffer Then call SDL_GL_SwapBuffers();
Immediate-mode rendering There is a current transformation/view matrix glLoadIdentity() initializes/resets it glTranslatef(), glRotatef(), gluLookAt(), etc., modify it glBegin() / glVertex3f() / glEnd() drawimmediately Using current transformation/view matrix
Disadvantages of immediate mode Resends triangles to GPU every frame Data-transfer inefficiency Recalculates everything every frame Computational inefficiency GPU doesn’t know anything about the full scene No opportunities for optimization / parallelization
Display lists One way of speeding things up Series of GL calls stored on GPU Created via macro-recording Give a display list ID, record series of gl*() commands to it
Display lists glNewList(id, GL_COMPILE); // or GL_COMPILE_AND_EXECUTE // now run a bunch of gl*() commands here glEndList() In the future, call glCallList(id); to run the recorded commands
Display lists Example usage Display list per object Change it only when the object changes Advantages Don’t have to resend data every time GPU can pre-compute things that don’t change GPU sees a series of commands at once, so can optimize
Display list drawbacks Not the full solution Still a serial programming model Modern GPUs are massively parallel Difficult to optimize display-list code to internal GPU parallel architecture
What the GPU really wants An array of triangles, all ahead of time Some information about what to do with each one Then it can split up the work between its units
Vertex array objects Give the GPU an array of vertices glGenVertexArrays() / glBindVertexArray() Generates names and tells the GPU to bind one to the current context glGenBuffers() / glBindBuffer() / glBufferData() Associate a data buffer with the currently bound vertex array object Can store other buffers with the vertex array
Vertex array objects Use array drawing comments that operate on currently bound array objects glDrawArrays(GL_TRIANGLES, 0, N); Treats every three elements of the array as a triangle Sends them to be drawn all at once
Indexed array rendering Further optimization Triangles often share vertices and edges With glDrawArrays(), every triangle needs its own three vertices, no sharing Duplicate vertices mean more space, and extra vertex shading Solution One buffer of unique vertices, not associated with triangles Separate index buffer pointing to vertices for each triangle
Indexed array rendering glGenBuffers() / glBindBuffer() / glBufferData() again With parameters specifying an index buffer glDrawElements() instead of glDrawArrays() Will pull out every 3 indexes from the index buffer as a triangle Look up corresponding vertices in the vertex buffer Vertex shaders not called again for reused vertices
Shader-based OpenGL The retained-mode pipeline stores arrays of triangles Vertex shaders called for every vertex in the buffer object Fixed-function pipeline no longer makes sense Hides underlying flexibility/functionality (massively parallel shader calls) Increases complexity of implementation
Shader-based OpenGL The old fixed-function pipeline is now treated as just one possible shader program Shaders are a programmable rendering/T&L API Can be written in GLSL Required if doing OpenGL ES or WebGL Necessary for non-standard effects (e.g. cel-shading)
Kinds of shaders Vertex shaders Geometry shaders Pixel/fragment shaders
Vertex shaders • Run for eachvertex, computelighting/etc. • Can implement the old fixed-pipeline approach • Or do anythingelse • GPU as massively parallel programmingenvironment
Geometry shaders • Likevertexshaders, but canproduce new vertices/polys • Optional step • Uses: • Volumetricshadows • On-GPU detailenhancements
Pixel/fragment shaders • Operate in 2d space, but w/ some 3d information • Possible to think of them as: • Fragment shader: shading one fragment of a triangle, e.g. by applying bump mapping • Pixel shader: adding arbitrary image-processing effects to the post-render 2 image
Post-processing pixel shader effects • Most noticeable are effects that don’t make sense in 3d • Instead of a ”correct” render, modify the rendered image • Film grain • Full-image color shifts • Enhanced edges • E.g.: Add noise by changing 1/50 pixels to a random value
Shader input/output Uniform variables Constant and read-only per primitive and per draw call Attribute variables Per-vertex information Read-only, in the vertex shader Varying variables Read/write in the vertex shader Read-only, with perspective-correct interpolation, in fragment shader
Summary • Modern GPU is a massively parallel but simple processor • Feed it triangles, and then run small shader programs • Some utility functions still exist, both in glu*() and in GLSL, for computing view matrices and similar