480 likes | 599 Views
OpenGL. Kurt Akeley CS248 Lecture 2 27 September 2007 http://graphics.stanford.edu/courses/cs248-07/. OpenGL. OpenGL Is a mechanism to create images in a frame buffer Is an API to access that mechanism Is well specified OpenGL Is not a window system Is not a user interface
E N D
OpenGL Kurt Akeley CS248 Lecture 2 27 September 2007 http://graphics.stanford.edu/courses/cs248-07/
OpenGL OpenGL • Is a mechanism to create images in a frame buffer • Is an API to access that mechanism • Is well specified OpenGL • Is not a window system • Is not a user interface • Is not a display mechanism • Does not even own the framebuffer • It is owned by the window system so it can be shared • But OpenGL defines its attributes carefully
OpenGL GLUT White-square code // Draw a white square against a black background #include <windows.h> #include <stdio.h> #define GLUT_DISABLE_ATEXIT_HACK // yuck! #include <GL/glut.h> void draw() { glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho(0, 4, 0, 4, -1, 1); glBegin(GL_POLYGON); glVertex2i(1, 1); glVertex2i(3, 1); glVertex2i(3, 3); glVertex2i(1, 3); glEnd(); glFlush(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutCreateWindow("whitesquare"); glutDisplayFunc(draw); glutMainLoop(); }
OpenGL portion of white-square code glClear(GL_COLOR_BUFFER_BIT); // black background glLoadIdentity(); // allow multipass glOrtho(0, 4, 0, 4, -1, 1); // int cast to double glBegin(GL_POLYGON); // draw white square glVertex2i(1, 1); glVertex2i(3, 1); glVertex2i(3, 3); glVertex2i(1, 3); glEnd(); glFlush(); // force completion
Red-book example 1-1 OpenGL code glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); glBegin(GL_POLYGON); glVertex3f(0.25, 0.25, 0.0); glVertex3f(0.75, 0.25, 0.0); glVertex3f(0.75, 0.75, 0.0); glVertex3f(0.25, 0.75, 0.0); glEnd(); glFlush(); // force completion
OpenGL 2.0 Spec, Table 6.21. Framebuffer Control State tables COLOR_CLEAR_VALUE 0,0,0,0
State tables OpenGL 2.0, Table 6.5. Current Values and Associated Data
A snippet from the OpenGL 2.0 spec Vertices are specified by giving their coordinates in two, three, or four dimensions. This is done using one of several versions of the Vertex command: void Vertex{234}{sifd}( T coords ); void Vertex{234}{sifd}v( T coords ); A call to any Vertex command specifies four coordinates: x, y, z, and w. The x coordinate is the first coordinate, y is second, z is third, and w is fourth. A call to Vertex2 sets the x and y coordinates; the z coordinate is implicitly set to zero and the w coordinate to one.
OpenGL shaded-quad code glClearColor(1, 1, 1, 1); // white glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glOrtho(0, 100, 0, 100, -1, 1); glBegin(GL_TRIANGLE_STRIP); glColor3f(0, 0.5, 0); // dark green glVertex2i(11, 31); glVertex2i(37, 71); glColor3f(0.5, 0, 0); // dark red glVertex2i(91, 38); glVertex2i(65, 71); glEnd(); glFlush();
OpenGL vertex pipeline Application Emphasis is on data types Diagram ignores • Pixel pipeline • Texture memory • Display lists • … Display is not part of OpenGL Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display
Vertex assembly (data types) Application struct { float x,y,z,w; float r,g,b,a;} vertex; Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display
Vertex assembly (OpenGL) Application Vertex assembly • Force input to canonical format • Convert to internal representation • E.g., x, y to float • Initialize unspecified values • E.g., z = 0, w=1 • Insert current modal state • E.g., color to 0,0.5,0,1 • Or create using evaluators Error detection • INVALID_ENUM • INVALID_VALUE • INVALID_OPERATION • Especially between Begin and End Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display
Vertex assembly (in our case) Application glColor3f(0, 0.5, 0);glVertex2i(11, 31);glVertex2i(37, 71);glColor3f(0.5, 0, 0); // no effect Vertex assembly Vertex operations Primitive assembly Primitive operations struct { float x,y,z,w; // 11, 31, 0, 1 float r,g,b,a; // 0, 0.5, 0, 1} vertex; Rasterization Fragment operations struct { float x,y,z,w; // 37, 71, 0, 1 float r,g,b,a; // 0, 0.5, 0, 1} vertex; Framebuffer Display
Vertex operations Application OpenGL • Transform coordinates • 4x4 matrix arithmetic • Compute (vertex) lighting • Compute texture coordinates • … In our case: • Scale (arbitrary 100x100) coordinates to fit window • No lighting, no texture coordinates Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display
or struct { vertex v0,v1; } line; or struct { vertex v0; } point; Primitive assembly (data types) Application struct { float x,y,z,w; float r,g,b,a;} vertex; Vertex assembly Vertex operations Primitive assembly struct { vertex v0,v1,v2; } triangle; Primitive operations Rasterization Fragment operations Framebuffer Display
Primitive assembly Application OpenGL • Group vertexes into primitives: • points, • lines, or • triangles • Decompose polygons to triangles • Duplicate vertexes in strips or fans In our case: • Create two triangles from a strip: Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization 1 3 Fragment operations glBegin(GL_TRIANGLE_STRIP);glColor(green);glVertex2i(…); // 0glVertex2i(…); // 1glColor(red);glVertex2i(…); // 2glVertex2i(…); // 3glEnd(); Framebuffer Display 2 0
Primitive operations Application OpenGL • Clip to the window boundaries • Actually to the frustum surfaces • Perform back-face / front-face ops • Culling • Color assignment for 2-side lighting In our case • Nothing happens Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display
Rasterization (data types) Application struct { float x,y,z,w; float r,g,b,a;} vertex; Vertex assembly Vertex operations Primitive assembly struct { vertex v0,v1,v2 } triangle; Primitive operations Rasterization struct { short int x,y; float depth; float r,g,b,a;} fragment; Fragment operations Framebuffer Display
Rasterization Application OpenGL • Determine which pixels are included in the primitive • Generate a fragment for each such pixel • Assign attributes (e.g., color) to each fragment In our case: Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display
Fragment operations Application OpenGL • Texture mapping • Fragment lighting (OpenGL 2.0) • Fog • Scissor test • Alpha test In our case, nothing happens: Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display
Framebuffer (2-D array of pixels) Application struct { float x,y,z,w; float r,g,b,a;} vertex; Vertex assembly Vertex operations struct { vertex v0,v1,v2 } triangle; Primitive assembly Primitive operations struct { short int x,y; float depth; float r,g,b,a;} fragment; Rasterization Fragment operations Framebuffer struct { int depth; byte r,g,b,a;} pixel; Display
Fragment framebuffer operations Application OpenGL • Color blending • Depth testing (aka z-buffering) • Conversion to pixels In our case, conversion to pixels: Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Key idea: images are built in the framebuffer, not just placed there! Fragment operations Framebuffer Display
OpenGL is mechanism Application Programmer specifies operation modes: • Vertex • Transformation • Lighting • Primitive • Back-face culling • Fragment • Shading (texture and lighting) • Framebuffer (blending and depth testing) Great example is the diagram at the back of the old (out of print) “blue book” … Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Display
Abstraction From the OpenGL specification, Section 1.5: Thus OpenGL is an abstraction • It doesn’t specify what does happen • It specifies what appears to happen “An implementation must produce results conforming to those produced by the specified methods, but there may be ways to carry out a particular computation that are more efficient than the one specified.”
SP SP SP SP SP SP SP SP SP SP SP SP SP SP SP SP TF TF TF TF TF TF TF TF L1 L1 L1 L1 L1 L1 L1 L1 L2 L2 L2 L2 L2 L2 FB FB FB FB FB FB Implementation = abstraction Application Host Vertex assembly Data Assembler Setup / Rstr / ZCull Vtx Thread Issue Geom Thread Issue Pixel Thread Issue Vertex operations Primitive assembly Thread Processor Primitive operations Rasterization Fragment operations Framebuffer NVIDIA GeForce 8800 OpenGL Pipeline
Declarative vs. imperative abstractions Declarative (what, not how) • Descriptive: specify input and desired result • E.g., OmitHiddenSurfaces(); • Example systems: • RenderMan scene description • Inventor and Performer scene graphs Imperative (how, not what) • Procedural: specify actions to create the result • E.g., EnableDepthBuffer(); • Example systems • PostScript and Xlib • OpenGL and Direct3D
Graphics software stacks web application application Gears of War VRML scene graph Unreal engine OpenGL 2.1 graphics API Direct3D 10 GeForce 8800 GPU Radeon 9600
Specific, high leverage General, low leverage Levels of abstraction Declarative web application Gears of War VRML Unreal engine OpenGL 2.1 Direct3D 10 GeForce 8800 Radeon 9600 Imperative
OpenGL 2.1 GeForce 8800 An imperative API defines an architecture We mean architecture in the Brooks/Blaauw sense: • Separate from and above implementation OpenGL defines an architecture: Can separate architecture’s interface and mechanism: • Direct3D 10 (interface) • WGF 2.0 (mechanism)
Additional OpenGL mechanisms Pixel pipeline Client-server operation Display lists Error behavior and reporting
OpenGL pixel pipeline Pixel pipeline Application Vertex pipeline Pixel assembly(unpack) Vertex assembly Vertex operations Primitive assembly Pixel operations Primitive operations Pixel pack Rasterization Texture memory Fragment operations Application Framebuffer Display
Client-server operation Application OpenGL Client Client side Network Server side OpenGL Server Display (you)
Display lists Application glNewList(listname, …); glColor3f(…); glVertex3f(…); … glEndList(); glCallList(listname); OpenGL Client Client side Network Server side OpenGL Server Displayliststate Display (you)
Error behavior and reporting No undefined operations • Architectural integrity • Application portability Queried, not returned • Why ? Enumerated error types • INVALID_ENUM • INVALID_VALUE • INVALID_OPERATION Should query after rendering Application OpenGL Client Network OpenGL Server Display (you)
Check for errors after rendering void CheckErrors() { bool got_error = false; while (int i = glGetError()) { got_error = true; fprintf(stderr, "ERROR: 0x%x\n", i); } if (got_error) exit(1); } Example application-defined error routine
OpenGL abstraction properties Immediate mode Orthogonality Programmability Details • Ordered operation • Modal state model • Synchronous operation
Immediate mode Different meanings to different people • Begin/End command sequences • Abstraction doesn’t maintain object descriptions • Vertex arrays stored on client side • Display lists don’t count • Implementation doesn’t queue indefinitely • E.g., doesn’t wait for all primitives before beginning to render Application OpenGL Client Network OpenGL Server Display (you)
Orthogonality Pixel pipeline Application Vertex pipeline Pixel assembly(unpack) Vertex assembly All vertexes are treated equally (e.g., lighted) Vertex operations Primitive assembly All primitives (including pixels) are rasterized Pixel operations Primitive operations Pixel pack Rasterization Texture memory Fragment operations Application All fragments are treated equally (e.g., z-buffered) Framebuffer Display
Programmability Application Programmable “shaders,” of course Multi-pass composition • Intended from the start • Requires repeatability • Invariance and equivariance • Appendix A in OpenGL spec Vertex assembly Vertex operations Primitive assembly Primitive operations Rasterization Fragment operations Framebuffer Application programmable
Abstraction details Ordered operation • Implementation may be out of order • But results must be as though computed in order Modal state model • Also in-order • Pipeline implementations require care Synchronous operation (as in synchronous i/o) • Data bound at call • Queries stall until data are ready and returned
Interface details Object naming (programmer-assigned, why) Lots of geometry-specification entry points (why)
Other things you should know Programming tips (Red book, Appendix G) • Correctness tips (e.g., pixel-exact 2-D rendering) • Performance tips (user/implementer contract) Extensions (www.opengl.org) • Recent ones include history and examples • Great way to understand graphics algorithms
Summary OpenGL is an imperative abstraction (aka architecture) • Mechanism (the OpenGL pipeline) • Interface (API) to feed and manage the mechanism The pipeline is best understood in terms of data types: • Vertex • Primitive (point, line, triangle) • Fragment • Pixel You should trust and be familiar with the OpenGL specification
Reading assignment Before Tuesday’s class, read • FvD 14.10 Aliasing and antialiasing • Return to the OpenGL specification • E.g., state tables Optional: • Set up your OpenGL/GLUT programming environment