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