Presentation is loading. Please wait.

Presentation is loading. Please wait.

Fall 2009 revised1 Introduction to OpenGL (Part 4) Ref: OpenGL Programming Guide (The Red Book)

Similar presentations

Presentation on theme: "Fall 2009 revised1 Introduction to OpenGL (Part 4) Ref: OpenGL Programming Guide (The Red Book)"— Presentation transcript:

1 Fall 2009 revised1 Introduction to OpenGL (Part 4) Ref: OpenGL Programming Guide (The Red Book)

2 2 Topics Part 1 Introduction Geometry Viewing Light & Material Display List Part 2 Alpha Channel Polygon Offset Part 3 Image Texture Mapping Part 4 Framebuffers Selection & Feedback

3 3 OpenGL Framebuffers

4 4 Types of Buffers color (front/back, left/right, aux) Front/back: animation Left/right: stereo vision Aux: not available on PC (use framebuffer object FBO instead) depth buffer: depth test VC: 24 bits available Value : [0.0,1.0] stencil buffer: restrict drawing to certain portions of the screen VC: 8 bits available accumulation buffer: accumulating composite image

5 5 Using Framebuffers clearing buffers clearing individual buffer is expensive Use glClear with bitwise-ORed masks to clear multiple buffers selecting color buffers for writing/clearing glDrawBuffer: useful in FBO (framebuffer object)

6 6 Masking Buffers Before OpenGL writes data into the enabled color, depth, or stencil buffers, a masking operation is applied to the data, as specified with one of the following commands. A bitwise logical AND is performed with each mask and the corresponding data to be written

7 7 Masking Buffers (cont) void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); void glDepthMask(GLboolean flag); void glStencilMask(GLuint mask); If a 1 appears in mask, the corresponding bit in the stencil buffer is written; where a 0 appears, the bit is not written. The default values of all the GLboolean masks are GL_TRUE, and the default values for the two GLuint masks are all 1's

8 8 Only Green Mask TRUE

9 9 Per-fragment Operation Sequence Fragments: the pieces after rasterization, sent to framebuffers if they survive these tests glScissor restrict drawing to part of the window a simpler (and faster) version of stencil test (that does not need stencil buffer) application: gui panel Dithering and logical op not covered here

10 10 Scissor Test While the scissor test is enabled, only pixels that lie within the scissor box can be modified by drawing commands. Including glClear (shown right) Note: validity of current raster position is determined by frustum (world coordinate); while scissor test affects the window coordinate Single-pixel window: glScissor (x,y,1,1); See also stencil_close

11 11 Fragment Operations (cont) Alpha test: accept/reject a fragment based on its alpha value implement transparency  use this test to filter opaque objects see-through decal (billboarding): reject the transparent fragments (from ruining the depth buffer) Stencil Test require stencil buffer glStencilFunc, glStencilOp

12 12 Stenciling

13 13 Basic Applications Restrict rendering to limited portions of the screen “ Stenciling ” Decal Shadow and lightmap

14 14 Mimicking Stencil Compose stencil template Control template then render Multi-pass rendering silhouette

15 15 Decal Using Stencil Buffers Stencil to resolve z-fighting

16 16 Shadow and Lightmap Shadow and light blended with the textured polygon underneath

17 17 Technical Details glStencilFunc (fun, ref, mask) func Specifies the test function. Eight tokens are valid: GL_NEVER, GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL, GL_EQUAL, GL_NOTEQUAL, and GL_ALWAYS.  If it's GL_LESS, for example, then the fragment passes if reference value is less than the value in stencil buffer ref Specifies the reference value for the stencil test. ref is clamped to the range [0, 2 n - 1], where n is the number of bitplanes in the stencil buffer.  VC: n = 8 mask Specifies a mask that is ANDed with both the reference value and the stored stencil value when the test is done

18 18 Technical Details (cont) glStencilOp (fail, zfail, zpass) fail Specifies the action to take when the stencil test fails. zfail Specifies stencil action when the stencil test passes, but the depth test fails. zpass Specifies stencil action when both the stencil test and the depth test pass, or when the stencil test passes and either there is no depth buffer or depth testing is not enabled. Six symbolic constants are accepted: GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, and GL_INVERT. Set value to ref Bitwise invert

19 19 Stenciling Steps to draw 2 coplanar rectangles: 1. Make the stencil for yellow one first (by drawing the green polygon) 2. Draw the yellow one with the stencil 3. Draw the green one

20 20 Stenciling (cont) Stencil bufferColor buffer

21 21 Decaling [0] Base: (-5,0)  (5,6) [1] R: (-3,1)  (2,4) [2] G: (1,2)  (3,5) [3] B: (0,0)  (4,3) Foreground blocker 1.Draw everything else (set up the depth buffer) 2.Draw base; set the blocker id to be 8; rest 0 3.Arrange the decal id in increasing order 4.The decals can be drawn in any order Test the progra m …

22 Color buffer Stencil buffer StencilOp(fail, zfail, zpass) Foreground blocker

23 Color buffer Stencil buffer StencilOp(fail, zfail, zpass) Foreground blocker Drawn in different order!

24 24 Generating Silhouette Stencil Buffer Debug with GLIntercept

25 25 See also Different line style Hidden line removal Haloed lines Cheap silhouette

26 26 Stencil Planar Shadow Shadow matrix to project model onto a flat shadow receiver Blending + stencil buffer techniques involved

27 27 CSG (constructive solid geometry) Cone SUBTRACT Sphere Sphere UNION Cone Cone INTERSECT Sphere

28 28 Reflection Easy hack, draw dino twice, second time has glScalef(1,-1,1) to reflect through the floor Dinosaur is reflected by the planar floor. Notice right image’s reflection falls off the floor!

29 29 Stencil Reflection Clear stencil to zero. Draw floor polygon with stencil set to one. Only draw reflection where stencil is one. Reflection and shadow

30 30 [Shadow Volume Using Stencil Buffers] Triangle blocking light source. “Shadow” volume projected by triangle from the light source. Use stencil to tag whether pixel is inside or outside of the shadow volume. Two passes: light pixels outside volume; no lighting for pixels inside the volume.

31 31 More Complicated Case

32 32 Hybrid Shadows Shadow volumesPlanar projected shadows

33 33 Accumulation Buffer series of images generated on standard color buffers; accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

34 34 Accumulation Buffer (cont) scene antialiasing, motion blur, photographic depth of field [softshadow, jittering] analogy: multiple exposures takes longer, but higher quality accum.buffer may have higher precision 16 bits for each RGBA channels scene antialiasing by spatially jittering the image

35 35 Accumulation Buffer APIs glClearAccum (0,0,0,0); glGetIntegerv (GL_ACCUM_RED_BITS, &value); 16 for each RGBA channels glAccum(GL_ACCUM, 1.f/counts); glAccum(GL_RETURN, 1.f);

36 36 Accumulation Buffer depth of field scene antialiasing motion blur

37 37 Ref

38 38 FSAA with Multi-Sampling(ref)ref glMultiSample

39 39 Motion Blur w/o Accum.Buffer Details: scene dynamically render to texture; modulate with a polygon (1,1,1,a)

40 40 Scene Anti-aliasing Can be done in real-time w/o accumulation buffer By outlining the silhouette edges See Tom HallTom Hall FPS: 10.8 FPS: 9.6

41 41 OpenGL Selection and Feedback

42 42 How to do Picking? Revisit unproject.c A line segment between (x1, y1, zNear) and (x2, y2, zFar) Check which object got hit Complexity problem?! Can do better? Simple tracking on XZ plane

43 43 Selection (Basic Idea) draw scene into framebuffer enter selection mode and redraw the scene the content of framebuffer unchanged until you exit the selection mode when exit, returns a list of primitives that intersected the viewing volume as an array of names (integer) and hit records Picking: a variation of selection triggered by mouse; mouse defines v.volume

44 44 Selection (Steps) glSelectBuffer (maxselects, selectbuffer) glRenderMode (GL_SELECT) glInitNames, glPushName (0) Something needs to be pushed on the empty stack (otherwise, it cannot be “ loaded ” ) define viewing volume Need to save current projection matrix for further rendering … issue drawing commands Load a name; then draw something; if the thing drawn is in v.volume, it generates a hit (with the name) glRenderMode (GL_RENDER) Return the number of hits process select buffer for hits

45 45 Name Stack name: GLuint glInitNames causes the name stack to be initialized to its default empty state glPushName/glPopName as the name implies glLoadName replace the top of the stack need to push something right after InitNames for first load commands ignored unless in selection mode

46 46 Hit Record Primitive intersecting v.vol causes a hit stack pointer points to the beginning of selection array and updates when hit occurs culled polygons generate no hit composite objects (w/ single name) generate one hit hit records aren ’ t updated until glRenderMode is called each hit record: number of names on the name stack min and max window-coord z values  [0,1] contents of name stack w/ bottommost element first

47 47 void drawScene (void) { glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (40.0, 4.0/3.0, 1.0, 100.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gluLookAt (7.5, 7.5, 12.5, 2.5, 2.5, -5.0, 0.0, 1.0, 0.0); glColor3f (0.0, 1.0, 0.0);/* green */ drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -5.0); glColor3f (1.0, 0.0, 0.0);/* red */ drawTriangle (2.0, 7.0, 3.0, 7.0, 2.5, 8.0, -5.0); glColor3f (1.0, 1.0, 0.0);/* yellow */ drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, 0.0); drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -10.0); drawViewVolume (0.0, 5.0, 0.0, 5.0, 0.0, 10.0); } void processHits (GLint hits, GLuint buffer[]) { unsigned int i, j; GLuint names, *ptr; printf ("hits = %d\n", hits); ptr = (GLuint *) buffer; for (i = 0; i < hits; i++) {/* for each hit */ names = *ptr; printf (" number of names for hit = %d\n", names); ptr++; printf(" z1 is %g;", (float) *ptr/0x7fffffff); ptr++; printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++; printf (" the name is "); for (j = 0; j < names; j++) {/* for each name */ printf ("%d ", *ptr); ptr++; } printf ("\n"); } void selectObjects(void) { GLuint selectBuf[512]; GLint hits; glSelectBuffer (512, selectBuf); (void) glRenderMode (GL_SELECT); glInitNames(); glPushName(0); glPushMatrix (); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0.0, 5.0, 0.0, 5.0, 0.0, 10.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glLoadName(1); drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -5.0); glLoadName(2); drawTriangle (2.0, 7.0, 3.0, 7.0, 2.5, 8.0, -5.0); glLoadName(3); drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, 0.0); drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -10.0); glPopMatrix (); hits = glRenderMode (GL_RENDER); processHits (hits, selectBuf); } void display(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawScene (); selectObjects (); glFlush(); }

48 48 Process Hits When returning to RENDER mode, All hit records got recorded in a GLuint array as follows [# of names, zmin, zmax, names … ] Names for an object need not be a single integer [object type, object number, object part, … ]

49 About the depth value (refs: 1,2)12 The depth is taken from the Z buffer (where it lies in the range [0,1]). It gets multiplied by 2^32 -1 (0xffff ffff)and is rounded to the nearest integer. Note that the depths you get are not linearly proportional to the distance to the viewpoint due to the nonlinear nature of the z buffer (See Opengl-2.ppt, p.44) 49

50 50 Picking restrict drawing to a small region of the viewport (near the cursor) mouse click to initiate the selection mode Issues: interpreting mouse (x,y)! hierarchical pick: name stack manipulation 3D pick (picking and depth values)

51 51 gluPickMatrix creates a projection matrix that can be used to restrict drawing to a small region of the viewport Often called from mouse callback; need to convert glut to OpenGL mouse coordinates

52 52 void drawSquares(GLenum mode) { GLuint i, j; for (i = 0; i < 3; i++) { if (mode == GL_SELECT) glLoadName (i); for (j = 0; j < 3; j ++) { if (mode == GL_SELECT) glPushName (j); glColor3f ((GLfloat) i/3.0, (GLfloat) j/3.0, (GLfloat) board[i][j]/3.0); glRecti (i, j, i+1, j+1); if (mode == GL_SELECT) glPopName (); } void processHits (GLint hits, GLuint buffer[]) { unsigned int i, j; GLuint ii, jj, names, *ptr; printf ("hits = %d\n", hits); ptr = (GLuint *) buffer; for (i = 0; i < hits; i++) {/* for each hit */ names = *ptr; printf (" number of names for this hit = %d\n", names); ptr++; printf(" z1 is %g;", (float) *ptr/0x7fffffff); ptr++; printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++; printf (" names are "); for (j = 0; j < names; j++) { /* for each name */ printf ("%d ", *ptr); if (j == 0) /* set row and column */ ii = *ptr; else if (j == 1) jj = *ptr; ptr++; } printf ("\n"); board[ii][jj] = (board[ii][jj] + 1) % 3; } void pickSquares(int button, int state, int x, int y) { GLuint selectBuf[512]; GLint hits; GLint viewport[4]; if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN) return; glGetIntegerv (GL_VIEWPORT, viewport); glSelectBuffer (512, selectBuf); (void) glRenderMode (GL_SELECT); glInitNames(); glPushName(0); glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y), 5.0, 5.0, viewport); gluOrtho2D (0.0, 3.0, 0.0, 3.0); drawSquares (GL_SELECT); glMatrixMode (GL_PROJECTION); glPopMatrix (); glFlush (); hits = glRenderMode (GL_RENDER); processHits (hits, selectBuf); glutPostRedisplay(); }

53 53 Example: picking spheres and cubes

54 54 Hints on Using Selection 2D application handle your own picking 3D: organize your program and data structure so that it is easy to draw list of object in either selection or rendering mode Use name creatively

55 55 [Feedback] key difference: what information is sent back transformed primitives is sent back to an array of floating point values (window coordinate) tokens of primitive type and other data for that primitive steps glFeedbackBuffer glRenderMode (GL_FEEDBACK) draw primitives glRenderMode (GL_RENDER) parse the feedback array

56 56 void drawGeometry (GLenum mode) { glBegin (GL_LINE_STRIP); glNormal3f (0.0, 0.0, 1.0); glVertex3f (30.0, 30.0, 0.0); glVertex3f (50.0, 60.0, 0.0); glVertex3f (70.0, 40.0, 0.0); glEnd (); if (mode == GL_FEEDBACK) glPassThrough (1.0); glBegin (GL_POINTS); glVertex3f (-100.0, , ); /* will be clipped */ glEnd (); if (mode == GL_FEEDBACK) glPassThrough (2.0); glBegin (GL_POINTS); glNormal3f (0.0, 0.0, 1.0); glVertex3f (50.0, 50.0, 0.0); glEnd (); } /* Write contents of one vertex to stdout */ void print3DcolorVertex (GLint size, GLint *count, Lfloat *buffer) { int i; printf (" "); for (i = 0; i < 7; i++) { printf ("%4.2f ", buffer[size-(*count)]); *count = *count - 1; } printf ("\n"); } /* Write contents of entire buffer. (Parse tokens!) */ void printBuffer(GLint size, GLfloat *buffer) { GLint count; GLfloat token; count = size; while (count) { token = buffer[size-count]; count--; if (token == GL_PASS_THROUGH_TOKEN) { printf ("GL_PASS_THROUGH_TOKEN\n"); printf (" %4.2f\n", buffer[size-count]); count--; } else if (token == GL_POINT_TOKEN) { printf ("GL_POINT_TOKEN\n"); print3DcolorVertex (size, &count, buffer); } else if (token == GL_LINE_TOKEN) { printf ("GL_LINE_TOKEN\n"); print3DcolorVertex (size, &count, buffer); } else if (token == GL_LINE_RESET_TOKEN) { printf ("GL_LINE_RESET_TOKEN\n"); print3DcolorVertex (size, &count, buffer); } void display(void) { GLfloat feedBuffer[1024]; GLint size; glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0.0, 100.0, 0, 100.0, 0.0, 1.0); glClearColor (0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); drawGeometry (GL_RENDER); glFeedbackBuffer (1024, GL_3D_COLOR, feedBuffer); (void) glRenderMode (GL_FEEDBACK); drawGeometry (GL_FEEDBACK); size = glRenderMode (GL_RENDER); printBuffer (size, feedBuffer); }

57 57 Feedback (cont) feedback + picking more refined picking (not just pick object, but some point on the object) feedback buffer type: 2D/3D/4D + COLOR + TEXTURE glPassThrough tokens that helps parsing the feedback data feedback array syntax (table 12-2) an application: rendereps.c use feedback buffer info to write EPS

58 58 End of Part 4

59 59 GLIntercept An OpenGL debugging facility that intercepts OpenGL calls to create informative logs Comes with some built-in logging scripts Rename the one you choose to gliConfig.ini The one particular useful for stencil buffer debugging is gliConfig_XMLFrame.ini Ctrl-shift-key to create frame log View the resulting XML in IE

60 60 Copy OpenGL32.dll and the chosen/renamed gliConfig.ini to the directory where EXE resides Each ctrl-shift-F creates a Frame log Use IE to open the XML

61 61 gliConfig_XMLFrame.ini By default, it only does color buffer logging If you need to see depth and/or stencil buffers, modify these two lines.

62 62 Example (Stencil Silhouette) (pre,post,diff) Red means no difference Green means same pixels Click to enlarge

63 63 Example (cont) BACK

Download ppt "Fall 2009 revised1 Introduction to OpenGL (Part 4) Ref: OpenGL Programming Guide (The Red Book)"

Similar presentations

Ads by Google