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

Introduction to OpenGL (part 2)

  • Upload
    tara

  • View
    60

  • Download
    2

Embed Size (px)

DESCRIPTION

Introduction to OpenGL (part 2). Ref: OpenGL Programming Guide (The Red Book). 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. Topics. OpenGL. - PowerPoint PPT Presentation

Citation preview

Page 1: Introduction to OpenGL (part 2)

Fall 2007 revised 1

Introduction to OpenGL(part 2)

Ref: OpenGL Programming Guide (The Red Book)

Page 2: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

3

OpenGL

Display Lists

Page 4: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

5

DISPLAY LIST

Compare the following two versions:

Which one is more

efficient?

Page 6: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

7

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

Page 8: Introduction to OpenGL (part 2)

8

OpenGL

Alpha ChannelBlending, Anti-aliasing, Fog

Page 9: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

11

Blending Factors

Not all combinations make sense!

Page 12: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

15

Example [F1: Help]

F1

any

Page 16: Introduction to OpenGL (part 2)

16

[F1: help] cont

glutSpecialFunc

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

glutKeyboardFunc

Page 17: Introduction to OpenGL (part 2)

19

Rendering Translucent Objects

should give

translucent

Page 18: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

26

Fog

Simulate limited visibilityCan improve performance Not show objects

if too fogged

Fog, haze, mist, smoke, pollution

Page 25: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

28

Fog Tip

Set clear color the same as fog color

Page 27: Introduction to OpenGL (part 2)

29

OpenGL

Polygon Offset

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

Page 28: Introduction to OpenGL (part 2)

30

Z-Fighting

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

Page 29: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

32

Z-Fighting: Code and Result

Page 31: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

37

Example

wireframe w/o polygonoffset w/ polygonoffset

Page 36: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

40

Z-fighting Solutions

Before AfterTurn off depth test

Stencil test (later)

Polygon offset

Page 39: Introduction to OpenGL (part 2)

41

End of Part 2

Page 40: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

43

Experiment

= 1

= 0.5BACK

Page 42: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

45

“Bald Al” Syndrome

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

Should be like this …

Z-fighting artifacts

Page 44: Introduction to OpenGL (part 2)

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: Introduction to OpenGL (part 2)

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