Introduction to opengl part 4
Download
1 / 60

Introduction to OpenGL (Part 4) - PowerPoint PPT Presentation


  • 154 Views
  • Uploaded on

Introduction to OpenGL (Part 4). Ref: OpenGL Programming Guide (The Red Book). 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. Topics. OpenGL.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Introduction to OpenGL (Part 4)' - pules


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Introduction to opengl part 4

Introduction to OpenGL(Part 4)

Ref: OpenGL Programming Guide (The Red Book)

Fall 2009 revised


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

Topics


Opengl

OpenGL

Framebuffers


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

Types of Buffers


Using framebuffers
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)


Masking buffers
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


Masking buffers cont
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



Per fragment operation sequence
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


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);

Scissor Test

See also stencil_close


Fragment operations cont

Alpha test: within the scissor box can be modified by drawing commands.

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

Fragment Operations (cont)


Stenciling
Stenciling within the scissor box can be modified by drawing commands.


Basic applications
Basic Applications within the scissor box can be modified by drawing commands.

Restrict rendering to limited portions of the screen

  • “Stenciling”

  • Decal

  • Shadow and lightmap


Mimicking stencil
Mimicking Stencil within the scissor box can be modified by drawing commands.

  • Compose stencil template

  • Control template then render

  • Multi-pass rendering

silhouette


Decal using stencil buffers
Decal Using Stencil Buffers within the scissor box can be modified by drawing commands.

Stencil to resolve z-fighting


Shadow and lightmap
Shadow and Lightmap within the scissor box can be modified by drawing commands.

Shadow and light blended with the textured polygon underneath


Technical details
Technical Details within the scissor box can be modified by drawing commands.

  • 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, 2n - 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


Technical details cont
Technical Details (cont) within the scissor box can be modified by drawing commands.

  • 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


Stenciling1
Stenciling within the scissor box can be modified by drawing commands.

  • Steps to draw 2 coplanar rectangles:

    • Make the stencil for yellow one first (by drawing the green polygon)

    • Draw the yellow one with the stencil

    • Draw the green one


Stenciling cont
Stenciling (cont) within the scissor box can be modified by drawing commands.

Stencil buffer

Color buffer


Decaling
Decaling within the scissor box can be modified by drawing commands.

[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

  • Draw everything else (set up the depth buffer)

  • Draw base; set the blocker id to be 8; rest 0

  • Arrange the decal id in increasing order

  • The decals can be drawn in any order

Test the program…


2 within the scissor box can be modified by drawing commands.

2

2

2

2

2

Foreground

blocker

3

3

3

3

3

0

0

0

0

0

0

0

0

0

0

3

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

1

0

1

0

1

0

1

0

0

0

0

0

0

0

0

0

0

0

0

0

1

1

1

1

1

0

8

8

8

8

8

8

8

0

0

0

8

8

8

8

8

8

8

0

0

StencilOp(fail, zfail, zpass)

Color buffer

Stencil buffer


2 within the scissor box can be modified by drawing commands.

2

2

2

2

2

Foreground

blocker

3

3

3

3

3

0

0

0

0

0

0

0

0

0

0

3

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

1

0

1

0

1

0

1

0

0

0

0

0

0

0

0

0

0

0

0

0

1

1

1

1

1

0

8

8

8

8

8

8

8

0

0

0

8

8

8

8

8

8

8

0

0

StencilOp(fail, zfail, zpass)

Color buffer

Stencil buffer

Drawn in different order!


Generating silhouette
Generating Silhouette within the scissor box can be modified by drawing commands.

Stencil Buffer

Debug with GLIntercept


See also

Different line style within the scissor box can be modified by drawing commands.

Hidden line removal

Haloed lines

Cheap silhouette

See also


Stencil planar shadow

Shadow matrix to project model onto a flat shadow receiver within the scissor box can be modified by drawing commands.

Blending + stencil buffer techniques involved

Stencil Planar Shadow


Reflection
Reflection within the scissor box can be modified by drawing commands.

Dinosaur is reflected by the planar floor.

Easy hack, draw dino twice, second time hasglScalef(1,-1,1) to reflect through the floor

Notice right image’s reflection falls off the floor!


Stencil reflection
Stencil Reflection within the scissor box can be modified by drawing commands.

Clear stencil to zero.Draw floor polygon with stencil set to one.Only draw reflection where stencil is one.

Reflection and shadow


Shadow volume using stencil buffers
[Shadow Volume Using Stencil Buffers] within the scissor box can be modified by drawing commands.

Triangle blockinglight source.

Use stencil to tag whetherpixel is inside or outsideof the shadow volume.

Two passes: light pixels outsidevolume; no lighting forpixels inside the volume.

“Shadow” volumeprojected by trianglefrom the light source.


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

Accumulation Buffer


Accumulation buffer cont

scene antialiasing, motion blur, photographic depth of field accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

[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

Accumulation Buffer (cont)


Accumulation buffer apis
Accumulation Buffer APIs accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

  • 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);


Accumulation buffer1
Accumulation Buffer accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

scene antialiasing

motion blur

depth of field


Ref accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing


Fsaa with multi sampling ref
FSAA with Multi-Sampling( accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewingref)

  • glMultiSample


Motion blur w o accum buffer
Motion Blur w/o Accum.Buffer accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

Details:

scene dynamically render to texture;

modulate with a polygon (1,1,1,a)


Scene anti aliasing
Scene Anti-aliasing accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

  • Can be done in real-time w/o accumulation buffer

    • By outlining the silhouette edges

  • See Tom Hall

FPS: 10.8

FPS: 9.6


Opengl1

OpenGL accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

Selection and Feedback


How to do picking

Revisit unproject.c accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

A line segment between (x1, y1, zNear) and (x2, y2, zFar)

Check which object got hit

Complexity problem?!

Can do better?

How to do Picking?

Simple tracking on XZ plane


Selection basic idea
Selection (Basic Idea) accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

  • 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


Selection steps
Selection (Steps) accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

  • 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


Name stack
Name Stack accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

  • 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


Hit record

Primitive intersecting v.vol causes a hit accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

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

Hit Record


void selectObjects(void) accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

{

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();

}

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");

}

}


Process hits
Process Hits accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

  • 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,…]


About the depth value refs 1 2
About the depth value (refs: accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing1,2)

  • 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)


Picking
Picking accumulated one at a time into the accumulation buffers; result copied back into a color buffer for viewing

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)


Glupickmatrix

creates a projection matrix that can be used to restrict drawing to a small region of the viewport

gluPickMatrix

Often called from mouse callback; need to convert glut to OpenGL mouse coordinates


void drawSquares(GLenum mode) { drawing to a small region of the viewport

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();

}


Example picking spheres and cubes
Example: picking spheres and cubes drawing to a small region of the viewport


Hints on using selection
Hints on Using Selection drawing to a small region of the viewport

  • 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


Feedback

key difference: what information is sent back drawing to a small region of the viewport

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

[Feedback]


void drawGeometry (GLenum mode) drawing to a small region of the viewport

{

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, -100.0, -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");

}

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);

}

/* 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);

print3DcolorVertex (size, &count, buffer);

}

else if (token == GL_LINE_RESET_TOKEN) {

printf ("GL_LINE_RESET_TOKEN\n");

print3DcolorVertex (size, &count, buffer);

print3DcolorVertex (size, &count, buffer);

}

}

}


Feedback cont

feedback + picking drawing to a small region of the viewport

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

Feedback (cont)


End of part 4

End of Part 4 drawing to a small region of the viewport


Glintercept
GLIntercept drawing to a small region of the viewport

  • 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


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


Gliconfig xmlframe ini
gliConfig_XMLFrame.ini the directory where EXE resides

By default, it only does color buffer logging

If you need to see depth and/or stencil buffers,

modify these two lines.


Example stencil silhouette
Example (Stencil Silhouette) the directory where EXE resides

(pre,post,diff)

Red means no difference

Green means same pixels

Click to enlarge


Example cont
Example (cont) the directory where EXE resides

BACK


ad