Introduction to OpenGL (part 2)

Preview:

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

Fall 2007 revised 1

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

3

OpenGL

Display Lists

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

5

DISPLAY LIST

Compare the following two versions:

Which one is more

efficient?

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

7

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

8

OpenGL

Alpha ChannelBlending, Anti-aliasing, Fog

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

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

11

Blending Factors

Not all combinations make sense!

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)

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)

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

15

Example [F1: Help]

F1

any

16

[F1: help] cont

glutSpecialFunc

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

glutKeyboardFunc

19

Rendering Translucent Objects

should give

translucent

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 :

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)

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)

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

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]

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.

26

Fog

Simulate limited visibilityCan improve performance Not show objects

if too fogged

Fog, haze, mist, smoke, pollution

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)

28

Fog Tip

Set clear color the same as fog color

29

OpenGL

Polygon Offset

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

30

Z-Fighting

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

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

32

Z-Fighting: Code and Result

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

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.

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

36

Illustration

result

Polygon with no offset

x

y

z

x

y

zresult

negative offset (reduced depth)

positive offset (increased

depth)

Polygon with offset

37

Example

wireframe w/o polygonoffset w/ polygonoffset

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.

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.

40

Z-fighting Solutions

Before AfterTurn off depth test

Stencil test (later)

Polygon offset

41

End of 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

43

Experiment

= 1

= 0.5BACK

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

45

“Bald Al” Syndrome

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

Should be like this …

Z-fighting artifacts

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.

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

Recommended