Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

45
Fall 2007 revised 1 Introduction to OpenGL (part 2) Ref: OpenGL Programming G uide (The Red Book)

Transcript of Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

Page 1: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

Fall 2007 revised 1

Introduction to OpenGL(part 2)

Ref: OpenGL Programming Guide (The Red Book)

Page 2: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

2

Topics

Part 1 Introduction Geometry Viewing Light & Material

Part 2 Display List Alpha Channel Polygon Offset

Part 3 Image Texture Mapping

Part 4 FrameBuffers Selection & Feedback

Page 3: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

3

OpenGL

Display Lists

Page 4: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

4

Display List API

Gluint glGenLists(int n); Request n display lists

glNewList (Gluint, GL_COMPILE); Compile the display list

glEndList(); End compilation

macro mechanism in OpenGL

Page 5: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

5

DISPLAY LIST

Compare the following two versions:

Which one is more

efficient?

Page 6: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

6

Display List (cont)

philosophy: designed to optimize

performance over the network (displaylist stored on server)

not modifiable

at least as fast as immediate mode

This is also known as retained mode

save complicated calculations

nested display list is possible (list 7-3)not all OpenGL commands can be stored in DisplayList (Chap. 7)good practice to Push Matrix/Attrib in the beginning when creating a displaylist and Pop Matrix/Attrib before closing

See next page

Page 7: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

7

Managing Display List IndicesglGenLists, glIsList, glDeleteListsother less-used functions: glListBase, glCallListsother uses of displaylist: encapuslating mode changes: list7-9

Page 8: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

8

OpenGL

Alpha ChannelBlending, Anti-aliasing, Fog

Page 9: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

9

Alpha ChannelBlending is useful for:

Displaying transparent objects

On-screen display (help)

See-thru textures Anti-aliasing Displaying shadows

N/A for color-indexed modeAlpha in GLUT

Page 10: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

10

glBlendFunc (sfactor,dfactor)

Specify source & destination blending factors source: fragment being processed destination: those already stored in

framebuffer (Sr, Sg, Sb, Sa); (Dr, Dg, Db, Da)

a

b

g

r

da

b

g

r

sd

d

d

d

a

b

g

r

s

s

s

s

a

b

g

r

a

b

g

r

Page 11: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

11

Blending Factors

Not all combinations make sense!

Page 12: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

12

Typical Use of Blending Factors

two equally blended objects (alpha.c) GL_SRC_ALPHA (src) + GL_ONE_MINUS_SRC_ALPHA (dest) Set Sa = 0.5

Three equally blended objects GL_SRC_ALPHA (src) + GL_ONE (dest) Set Sa = 1/3

Brush that adds color in each pass GL_SRC_ALPHA (src) + GL_ONE_MINUS_ALPHA (dest) Sa = 0.1

Multiplicative blend (srcdest)GL_ZERO (src) + GL_SRC_COLOR (dest) (RdRs, GdGs, BdBs, AdAs)

Page 13: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

13

Example: alpha.c

Left first

Right first

glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Left: (1,1,0,3/4) Right (0,1,1,3/4)

(0,0,0,0)(1,1,0,3/4)

(3/4,3/4,0,9/16)1/4

3/4

1/4

3/4(3/16,15/16,3/4,…)

(0,1,1,3/4)

(0,0,0,0)(0,1,1,3/4)

(0,3/4,3/4,9/16)1/4

3/4

1/4

3/4(3/4,15/16,3/16,…)

(1,1,0,3/4)

Page 14: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

14

static int leftFirst = GL_TRUE;

/* Initialize alpha blending function.

*/static void init(void){ glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA,

GL_ONE_MINUS_SRC_ALPHA); glShadeModel (GL_FLAT); glClearColor (0.0, 0.0, 0.0, 0.0);}

static void drawLeftTriangle(void){ /* draw yellow triangle on LHS

of screen */

glBegin (GL_TRIANGLES); glColor4f(1.0, 1.0, 0.0, 0.75); glVertex3f(0.1, 0.9, 0.0); glVertex3f(0.1, 0.1, 0.0); glVertex3f(0.7, 0.5, 0.0); glEnd();}

void keyboard(unsigned char key, int x, int y)

{

switch (key) {

case 't':

case 'T':

leftFirst = !leftFirst;

glutPostRedisplay();

break;

}

}

int main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA);

glutInitWindowSize (200, 200);

glutCreateWindow (argv[0]);

init();

glutReshapeFunc (reshape);

glutKeyboardFunc (keyboard);

glutDisplayFunc (display);

glutMainLoop();

return 0;

}

static void drawRightTriangle(void){ /* draw cyan triangle on RHS of screen */

glBegin (GL_TRIANGLES); glColor4f(0.0, 1.0, 1.0, 0.75); glVertex3f(0.9, 0.9, 0.0); glVertex3f(0.3, 0.5, 0.0); glVertex3f(0.9, 0.1, 0.0); glEnd();}

void display(void){ glClear(GL_COLOR_BUFFER_BIT);

if (leftFirst) { drawLeftTriangle(); drawRightTriangle(); } else { drawRightTriangle(); drawLeftTriangle(); } glFlush();}

Page 15: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

15

Example [F1: Help]

F1

any

Page 16: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

16

[F1: help] cont

glutSpecialFunc

glEnable (GL_BLEND);glBlendFunc (GL_SRC_ALPHA, GL_ONE);

glutKeyboardFunc

Page 17: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

19

Rendering Translucent Objects

should give

translucent

Page 18: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

20

Render solid objects firstDepth test on

Depth buffer writeable

Render translucent objects (in any order)Depth test on

Depth buffer readableglDepthMask(GL_FALSE);

glDepthMask(GL_TRUE);

Step1 : Step2 :

Page 19: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

21

To Distinguish between Opaque and Translucent Objects

Keep different groupsUse alpha test & multipass rendering

• Opaque pass: glAlphaFunc (GL_EQUAL, 1.0f)• Transl. pass: glAlphaFunc (GL_LESS, 1.0f)

• Opaque pass: glAlphaFunc (GL_EQUAL, 1.0f)• Transl. pass: glAlphaFunc (GL_LESS, 1.0f)

Page 20: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

22

void display(void){ GLfloat mat_solid[] = { 0.75, 0.75, 0.0, 1.0 }; GLfloat mat_zero[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_transparent[] = { 0.0, 0.8, 0.8, 0.6 }; GLfloat mat_emission[] = { 0.0, 0.3, 0.3, 0.6 };

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix (); glTranslatef (-0.15, -0.15, solidZ); glMaterialfv(GL_FRONT, GL_EMISSION, mat_zero); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_solid); glCallList (sphereList); glPopMatrix ();

glPushMatrix (); glTranslatef (0.15, 0.15, transparentZ); glRotatef (15.0, 1.0, 1.0, 0.0); glRotatef (30.0, 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_transparent); glEnable (GL_BLEND); glDepthMask (GL_FALSE); glBlendFunc (GL_SRC_ALPHA, GL_ONE); glCallList (cubeList); glDepthMask (GL_TRUE); glDisable (GL_BLEND); glPopMatrix ();

glutSwapBuffers();}

alpha3D.c (partial)

Page 21: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

23

AntialiasingAliasing: jaggedness caused by discrete pixelsAntialiasing techniques:

Point, line, polygon; scene (more later)

line smoothing coverage value multiply fragment’s

alpha value by its coverage

glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA,

GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT,

GL_DONT_CARE);

arrgb.c

Page 22: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

24

Smoothing

Line Smoothing glEnable (GL_LINE_SMOOTH);

glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA,

GL_ONE_MINUS_SRC_ALPHA);

Point Smoothing glEnable

(GL_POINT_SMOOTH); (no need for blending)

PointSize range [1,63]LineWidth range [0.5,10]

Page 23: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

25

Remarks on glHint

Certain aspects of GL behavior, when there is room for interpretation, can be controlled with hints mode can be one of the following: GL_FASTEST: The most efficient option

should be chosen. GL_NICEST: The most correct, or highest

quality, option should be chosen. GL_DONT_CARE: The client doesn't have a

preference.

Page 24: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

26

Fog

Simulate limited visibilityCan improve performance Not show objects

if too fogged

Fog, haze, mist, smoke, pollution

Page 25: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

27

Fog (cont)different types & modes of fog

glEnable(GL_FOG); { GLfloat fogColor[4] = {0.5, 0.5,

0.5, 1.0};

fogMode = GL_EXP; glFogi (GL_FOG_MODE, fogMode); glFogfv (GL_FOG_COLOR,

fogColor); glFogf (GL_FOG_DENSITY, 0.35); glHint (GL_FOG_HINT,

GL_DONT_CARE); glFogf (GL_FOG_START, 1.0); glFogf (GL_FOG_END, 5.0); }

Ci: incoming fragment (RGBA)Cf: fog color (RGBA)

Let z be the distance in eye coordinates from the origin to the fragment being fogged (fragment depth)

Page 26: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

28

Fog Tip

Set clear color the same as fog color

Page 27: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

29

OpenGL

Polygon Offset

useful for rendering hidden-line images, for applying decals to surfaces, and for rendering solids with highlighted edges.

Page 28: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

30

Z-Fighting

Supposed to be like this … Because the polygons are coplanar, the depth of fragments are difficult to differentiate

Page 29: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

31

Z-Fighting (cont)

Coplanar polygons have the same z-(depth-) valuesThe depth test may give unpredictable results due to floating point inaccuracy Detailed discussion

Page 30: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

32

Z-Fighting: Code and Result

Page 31: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

33

Basics of Polygon Offset

It's difficult to render coplanar primitives in OpenGL for two reasons:

floating point round-off errors from the two polygons can generate different depth values for overlapping pixels.

With depth test enabled, some of the second polygon's pixels will pass the depth test, while some will fail…

For coplanar lines and polygons, vastly different depth values for common pixels can result. This is because depth values from polygon rasterization derive from the polygon's plane equation, while depth values from line rasterization derive from linear interpolation

Page 32: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

34

Basics of Polygon Offset (cont)

Setting the depth function to GL_LEQUAL or GL_EQUAL won't resolve the problem. The visual result is referred to as stitching, bleeding, or Z fighting.

It allows an application to define a depth offset, which can apply to filled primitives. It can be separately enabled or disabled on fill/line/point polygons. An application can render coplanar primitives by first rendering one primitive, then by applying an offset and rendering the second primitive.

Page 33: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

35

Parameters in glPolygonOffset

void glPolygonOffset(GLfloat factor, GLfloat units); When enabled, the depth value of each fragment is added to a calculated offset value. The offset is added before the depth test is performed and before the depth value is written into the depth buffer. The offset value o is calculated by: o = m * factor + r * units where m is the maximum depth slope of the polygon and r is the smallest value guaranteed to produce a resolvable difference in window coordinate depth values. The value r is an implementation-specific constant.

Pos offset: pushed away

from youNeg. offset: pull

towards you

Page 34: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

36

Illustration

result

Polygon with no offset

x

y

z

x

y

zresult

negative offset (reduced depth)

positive offset (increased

depth)

Polygon with offset

Page 35: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

37

Example

wireframe w/o polygonoffset w/ polygonoffset

Page 36: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

38

Polygon Offset (cont)

Polygon offset only works with polygonal primitives:

GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, and GL_POLYGON.

Polygon offset will work when you render them with glPolygonMode set to GL_FILL, GL_LINE, or GL_POINT.

Polygon offset will not affect the depth values of GL_POINTS, GL_LINES, GL_LINE_STRIP, or GL_LINE_LOOP.

If you are trying to render point or line primitives over filled primitives, use polygon offset to push the filled primitives back.

Page 37: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

39

Side Effects of Polygon Offset

Because polygon offset alters the correct Z value calculated during rasterization, the resulting Z value, which is stored in the depth buffer will contain this offset and can adversely affect the resulting image.

polygon offset may cause some primitives to pass the depth test entirely when they normally would not, or vice versa. When models intersect, polygon offset can cause an inaccurate rendering of the intersection point.

Page 38: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

40

Z-fighting Solutions

Before AfterTurn off depth test

Stencil test (later)

Polygon offset

Page 39: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

41

End of Part 2

Page 40: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

42

glutInitDisplayMode

GLUT_RGBA is the same as GLUT_RGB Color buffer has

RGB, 3-component only

To request an alpha buffer, one must use GLUT_ALPHA explicitly

From glut.h

Page 41: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

43

Experiment

= 1

= 0.5BACK

Page 42: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

44

Depth Buffer Artifact

Depth buffering can fail to resolve objects whose z values are nearly the same.Since the depth buffer stores z values with limited precision, z values are rounded as they are stored. The z values may round to the same number, causing depth buffering artifacts.To query the number of bitplanes of depth buffer: [24 on my platform]int depth;glGetIntegerv (GL_DEPTH_BITS, &depth);

Page 43: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

45

“Bald Al” Syndrome

gluPerspective (60,1,.00001, 10000);

Should be like this …

Z-fighting artifacts

Page 44: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

46

From the documentation of glFrustum:

• Depth buffer precision is affected by the values specified for zNear and zFar. The greater the ratio of zFar to zNear is, the less effective the depth buffer will be at distinguishing between surfaces that are near each other.

• If r = zFar/zNear roughly log (r) bits of depth buffer precision are lost. Because r approaches infinity as zNear approaches 0, zNear must never be set to 0.

• Set zNear and zFar wisely!

Note this is for perspective projection only. Orthographic projection has no such problems.

Page 45: Fall 2007 revised1 Introduction to OpenGL (part 2) Ref: OpenGL Programming Guide (The Red Book)

47

Experiment

Two pairs of closely placed (10-4 apart) quads, one placed near zNear, one placed near zFar

Note the back one has poor resolution (zfighting) when zFar/zNear ratio is big

Depth buffer has worse resolution near the far plane in perspective projection

BACK