Presentation is loading. Please wait.

Presentation is loading. Please wait.

Introduction to OpenGL (part 2)

Similar presentations


Presentation on theme: "Introduction to OpenGL (part 2)"— Presentation transcript:

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

2 Topics Part 1 Part 2 Introduction Geometry Viewing Part 3
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);
macro mechanism in OpenGL Gluint glGenLists(int n); Request n display lists glNewList (Gluint, GL_COMPILE); Compile the display list glEndList(); End compilation

5 Which one is more efficient?
DISPLAY LIST Compare the following two versions: Which one is more efficient?

6 Display List (cont) philosophy: at least as fast as immediate mode
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 Indices
glGenLists, glIsList, glDeleteLists other less-used functions: glListBase, glCallLists other uses of displaylist: encapuslating mode changes: list7-9

8 Alpha Channel Blending, Anti-aliasing, Fog
OpenGL Alpha Channel Blending, Anti-aliasing, Fog

9 Alpha Channel Blending is useful for: N/A for color-indexed mode
Displaying transparent objects On-screen display (help) See-thru textures Anti-aliasing Displaying shadows N/A for color-indexed mode Alpha 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)

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 (srcdest) GL_ZERO (src) + GL_SRC_COLOR (dest) (RdRs, GdGs, BdBs, AdAs)

13 Example: alpha.c Left first Right first (0,0,0,0) (1,1,0,3/4)
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Left: (1,1,0,3/4) Right (0,1,1,3/4) Left first (0,0,0,0) (1,1,0,3/4) (3/4,3/4,0,9/16) 1/4 3/4 (3/16,15/16,3/4,…) (0,1,1,3/4) Right first (0,0,0,0) (0,1,1,3/4) (0,3/4,3/4,9/16) 1/4 3/4 (3/4,15/16,3/16,…) (1,1,0,3/4)

14 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 { glFlush(); 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();

15 Example [F1: Help] F1 any

16 [F1: help] cont a glutKeyboardFunc glutSpecialFunc
glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE); glutKeyboardFunc

17 glColor3f(1.0, 1.0, 1.0); // alpha is one by default
void text(GLuint x, GLuint y, GLfloat scale, char* format, ...) { va_list args; char buffer[255], *p; GLfloat font_scale = ; va_start(args, format); vsprintf(buffer, format, args); va_end(args); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0,w, 0, h); glMatrixMode(GL_MODELVIEW); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glTranslatef(x, y, 0.0); glScalef(scale/font_scale, scale/font_scale, scale/font_scale); for(p = buffer; *p; p++) glutStrokeCharacter(GLUT_STROKE_ROMAN, *p); glPopAttrib(); glPopMatrix(); glMatrixMode(GL_PROJECTION); glMatrixMode(GL_MODELVIEW); } USAGE: //draw scene glColor3f(1.0, 1.0, 1.0); // alpha is one by default if (performance) { text(10, 73, 20, "%.0f fps", 1.0 / ((end - last) / )); last = start; text(10, 43, 14, "Attenuation [%.2f]", fatt); text(10, 13, 14, "Tesselation [%3d]", wallgrid); bounce.c (incomplete)

18 Remark on bounce.c Writing texts on screen is not difficult
Simply turn off the depth buffer and write But if the text is be shown with the background (not blocking the 3D content … like the help screen), then blending is required

19 Rendering Translucent Objects
should give translucent

20 Step2 : Step1 : Render translucent objects (in any order)
Depth test on Depth buffer readable Render solid objects first Depth test on Depth buffer writeable glDepthMask(GL_FALSE); glDepthMask(GL_TRUE);

21 To Distinguish between Opaque and Translucent Objects
Keep different groups Use alpha test & multipass rendering Opaque pass: glAlphaFunc (GL_EQUAL, 1.0f) Transl. pass: glAlphaFunc (GL_LESS, 1.0f)

22 alpha3D.c (partial) 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 Antialiasing Aliasing: jaggedness caused by discrete pixels
Antialiasing 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); Point Smoothing
PointSize range [1,63] LineWidth range [0.5,10] 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)

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 visibility Can improve performance
Not show objects if too fogged Fog, haze, mist, smoke, pollution

27 Fog (cont) different types & modes of fog Ci: incoming fragment (RGBA)
Let z be the distance in eye coordinates from the origin to the fragment being fogged (fragment depth) 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)

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-) values
The 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 you Neg. offset: pull towards you

36 negative offset (reduced depth) positive offset (increased depth)
Illustration Polygon with no offset x y z negative offset (reduced depth) result x y z Polygon with offset positive offset (increased depth) result

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 After Before Turn off depth test Polygon offset
Stencil test (later)

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 a a = 1 a = 0.5 BACK

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 Should be like this … Z-fighting artifacts
gluPerspective (60,1,.00001, 10000);

46 From the documentation of glFrustum:
Note this is for perspective projection only. Orthographic projection has no such problems. 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!

47 Experiment Depth buffer has worse resolution near the far plane in perspective projection 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 BACK


Download ppt "Introduction to OpenGL (part 2)"

Similar presentations


Ads by Google