Presentation on theme: "The Buffers and Operations"— Presentation transcript:
1The Buffers and Operations An Interactive Introduction to OpenGL ProgrammingThe Buffers and OperationsBlendingDepthTestDitheringLogical OperationsScissorStencilAlphaFragmentFramebufferIn order for a fragment to make it to the frame buffer, it has a number of testing stages and pixel combination modes to go through.The tests that a fragment must pass are:scissor test - an additional clipping testalpha test - a filtering test based on the alpha color componentstencil test - a pixel mask testdepth test - fragment occlusion testEach of these tests is controlled by a glEnable() capability.If a fragment passes all enabled tests, it is then blended, dithered and/or logically combined with pixels in the framebuffer. Each of these operations can be enabled and disabled.
2UsagePart of the OpenGL philosophy is to provide tools without dictating their use.These tools can be used in many ways.Often the name (“depth buffer”) suggests the most common use, but there is nothing “wrong” with using a tool quite differently.
3OpenGL Buffers OpenGL has 4 types of buffers: Color buffersDepth bufferStencil bufferAccumulation bufferEach buffer has an intended function; however, you may use the buffers in any way you wish.In order to be used, a buffer must be allocated.Do this in your glutInitDisplayMode call.
4OpenGL Tests Related to the buffers are the OpenGL tests: Scissor testAlpha testDepth testStencil testA test is an expression with a boolean value that OpenGL evaluates for every fragment.If the result is true, then the test passes, and the fragment continues down the pipeline.Otherwise, the test fails, and fragment is discarded.All tests are done in the fragment-processing part of the pipeline.In order to have any effect, a test must be enabled.Do this with glEnable.
6Masking BuffersMost buffers have masks associated with them. If flag is GL_FALSE, buffer writing is disabled.The mask determines whether a buffer (or part of a buffer) is ever written.For example, glColorMask(false, true, true, true); means that the R portion of the color buffer will not be changed.Note: The mask affects all commands that would change the buffer, even glClear.void glIndexMask(GLuint mask);void glColorMask(GLboolean red, GLboolean green,GLboolean blue, GLboolean alpha);void glDepthMask(GLboolean flag);void glStencilMask(GLuint mask);
7Buffers ClearingThe buffers to clear are specified by bitwise-or’ing together. For example, glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT);The value to store in each pixel of a buffer is set by a separate command for each buffer: glClearColor glClearDepth glClearStencil glClearAccum
8Copyright @ 2001 by Jim X. Chen: firstname.lastname@example.org ParameterMeaningGL_RED_BITS,Number of bits per R, G, B, or AGL_GREEN_BITS,component in the color buffersGL_BLUE_BITS,GL_ALPHA_BITSGL_DEPTH_BITSNo of bits per pixel in the depth bufferGL_STENCIL_BITSNo of bits per pixel in the stencil bufferGL_ACCUM_RED_BITS,No of bits per R, G, B, or AGL_ACCUM_GREEN_BITS,component in theGL_ACCUM_BLUE_BITS,accumulation bufferGL_ACCUM_ALPHA_BITSglGetIntegerv() to query your OpenGL system about per-pixel buffer storage for a particular buffer8by Jim X. Chen:
9Copyright @ 2001 by Jim X. Chen: email@example.com Color Buffers (Framebuffers)Stereoscopic viewing has left and right color buffersfor the left and right stereo images.Double-buffered systems have front & back buffers.Up to four optional, non-displayable auxiliary colorbuffers can also be supported.Stencil BufferOne use for the stencil buffer is to restrict drawing tocertain portions of the screen, just as a cardboardstencil can be used with a can of spray paint to makefairly precise painted images.You can store an image of the windshield’s shape inthe stencil buffer, and then draw the entire scene.9by Jim X. Chen:
10Copyright @ 2001 by Jim X. Chen: firstname.lastname@example.org Accumulation BufferThe accumulation buffer holds RGBA color data justlike the color buffers do in RGBA mode.It’s typically used for accumulating a series ofimages into a final, composite image.You can perform operations like scene antialiasingby supersampling an image and then averaging thesamples to produce the values that are finallypainted into the pixels of the color buffers.You don’t draw directly into the accumulation buffer;accumulation operations are always performed inrectangular blocks, usually transfers of data to orfrom a color buffer.1010by Jim X. Chen:
11Copyright @ 2001 by Jim X. Chen: email@example.com Testing and Operating on FragmentsScissor TestIf a fragment lies inside the rectangle, it passes thescissor test.void glScissor(GLint x, GLint y, GLsizei width,GLsizei height); Sets the location and size of thescissor rectangle. The parameters define the lowerleft corner (x, y), and the width and height of therectangle.Pixels that lie inside the rectangle pass the scissortest. Scissoring is enabled and disabled by passingGL_SCISSOR to glEnable() and glDisable().The scissor test is just a version of a stencil testusing a rectangular region of the screen. It’s fairlyeasy to create a blindingly fast hardwareimplementation of scissoring, while a given systemmight be much slower at stenciling -- perhapsbecause the stenciling is performed in software.1111by Jim X. Chen:
12The Scissor Test The scissor test is by far the simplest of the tests. It allows you to restrict drawing to a rectangular portion of the viewport.To enable: glEnable(GL_SCISSOR_TEST);Then: glScissor(x, y, width, height);Parameters are as in the glViewport command.(x,y) is the lower-left corner of the rectangle.The scissor test passes if the pixel is within the rectangle; otherwise, it fails.The scissor test is really just a quick, simple version of stenciling.2 Feb 2004CS 481/681
13Copyright @ 2001 by Jim X. Chen: firstname.lastname@example.org Alpha TestIn RGBA mode, the alpha test allows you to accept orreject a fragment based on its alpha value.void glAlphaFunc(GLenum func, GLclampf ref);Sets the reference value and comparison function for the alpha test.The reference value ref is clamped to be between 0 and 1.ParameterMeaningGL_NEVERNever accept the fragmentGL_ALWAYSAlways accept the fragmentGL_LESSAccept fragment if fragment alpha <GL_LEQUALAccept fragment if fragment alpha <=reference alphaGL_EQUALAcceptfragment if fragment alpha =GL_GEQUALAccept fragment if fragment alpha >=GL_GREATERAccept fragment if fragment alpha >GL_NOTEQUALAccept fragment if fragment alpha !=1313by Jim X. Chen:
14An Interactive Introduction to OpenGL Programming Alpha TestReject pixels based on their alpha valueglAlphaFunc( func, value )glEnable( GL_ALPHA_TEST )use alpha as a mask in texturesAlpha values can also be used for fragment testing. glAlphaFunc() sets a value which, if glEnable(GL_ALPHA_TEST) has been called, will test every fragment’s alpha against the value set, and if the test fails, the fragment is discarded.The functions which glAlphaFunc() can use are:GL_NEVER GL_LESSGL_EQUAL GL_LEQUALGL_GREATER GL_NOTEQUALGL_GEUQAL GL_ALWAYSThe default is GL_ALWAYS, which always passes fragments.Alpha testing is particularly useful when combined with texture mapping with textures which have an alpha component. This allows your texture map to act as a localized pixel mask. This technique is commonly used for objects like trees or fences, where modeling the objects (and all of its holes) becomes prohibitive.CPUDLPoly.PerVertexRasterFragFBPixelTexture
15Copyright @ 2001 by Jim X. Chen: email@example.com Stencil Testvoid glStencilFunc(GLenum func, GLint ref, GLuint mask);The ref value is compared to the value in thestencil buffer using the comparison func, but thecomparison applies only to those bits where thecorresponding bits of the mask are 1.The function can be GL_NEVER, GL_ALWAYS,GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL,GL_GREATER, or GL_NOTEQUAL.The stencil test is enabled and disabled by passingGL_STENCIL_TEST to glEnable() and glDisable().void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);Specifies how the data in the stencil buffer is modifiedwhen a fragment passes or fails the stencil test. The fail, zfail, and zpass can be GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, or GL_INVERT. They correspond to keeping the current value, replacing it with zero, replacing it with the reference value, incrementing it, decrementing it, or bitwise-inverting it.1515by Jim X. Chen:
16Controlling Stencil Buffer An Interactive Introduction to OpenGL ProgrammingControlling Stencil BufferglStencilFunc(func, ref, mask)compare value in buffer with ref using funconly applied for bits in mask which are 1func is one of standard comparison functionsglStencilOp(fail, zfail, zpass)Allows changes in stencil buffer based on passing or failing stencil and depth tests: GL_KEEP, GL_INCRThe two principal functions for using the stencil buffer are glStencilFunc()which controls how the bits in the stencil buffer are used to determine if a particular pixel in the framebuffer is writable.glStencilOp()controls how the stencil buffer values are updated, based on three tests:1) did the pixel pass the stencil test specified with glStencilFunc()2) did the pixel fail the depth test for that pixel.3) did the pixel pass the depth test for that pixel. This would mean that the pixel in question would have appeared in the image.
17An Interactive Introduction to OpenGL Programming Creating a MaskglInitDisplayMode( …|GLUT_STENCIL|… );glEnable( GL_STENCIL_TEST );glClearStencil( 0x0 );glStencilFunc( GL_ALWAYS, 0x1, 0x1 );glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );draw maskIn this example, we specify a simple stencil mask. We do this by specifying that regardless of which tests the pixel passes or fails, we replace its value in the stencil buffer with the value 0x1. This permits us to render the shape of the pixel mask we want directly into the stencil buffer (in a manner of speaking).
18An Interactive Introduction to OpenGL Programming Using Stencil MaskDraw objects where stencil = 1glStencilFunc( GL_EQUAL, 0x1, 0x1 )Draw objects where stencil != 1glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);After the stencil mask is specified, we can use the mask to selectively update pixels. With the first set of commands, we only update the pixels where the stencil buffer is set to 0x01 in the stencil buffer.In the second example, we set the stencil state up to render only to pixels where the stencil value is not 0x01.
19Copyright @ 2001 by Jim X. Chen: firstname.lastname@example.org Depth Testvoid glDepthFunc(GLenum func);Sets the comparison function for the depth test. Thevalue for func must be GL_NEVER, GL_ALWAYS,GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL,GL_GREATER, or GL_NOTEQUAL.An incoming fragment passes the depth test if its zvalue has the specified relation to the value alreadystored in the depth buffer. The default is GL_LESS.In this case, the z value represents the distance fromthe object to the viewpoint.1919by Jim X. Chen:
20Copyright @ 2001 by Jim X. Chen: email@example.com The Accumulation BufferImages is generated in one of the standard colorbuffers, and these are accumulated, one at atime, into the accumulation buffer.When the accumulation is finished, the result iscopied back into a color buffer for viewing.To reduce rounding errors, the accumulationbuffer may have higher precision (more bits percolor) than the standard color buffers.A photographer typically creates a multipleexposure by taking several pictures of the samescene without advancing the film. If anything inthe scene moves, that object appears blurred.2020by Jim X. Chen:
21Copyright @ 2001 by Jim X. Chen: firstname.lastname@example.org void glAccum(GLenum op, GLfloat value);Controls the accumulation buffer. The opparameter selects the operation, and valueis a number to be used in that operation.The possible operations are GL_ACCUM, GL_LOAD, GL_RETURN,GL_ADD, and GL_MULT:·GL_ACCUM reads each pixel from the buffercurrently selected for reading, multiplies the R, G, B,and alpha values by value, and adds the result to theaccumulation buffer.·GL_LOAD does the same thing, except that thevalues replace those in the accumulation bufferrather than being added to them.·GL_RETURN takes values from the accumulationbuffer, multiplies them by value, and places theresult in the color buffer(s) enabled for writing.·GL_ADD and GL_MULT simply add or multiply thevalue of each pixel in the accumulation buffer byvalue, and then return it to the accumulation buffer.For GL_MULT, value is clamped to be in the range [-1.0,1.0]. For GL_ADD, no clamping occurs.2121by Jim X. Chen:
22Copyright @ 2001 by Jim X. Chen: email@example.com Scene AntialiasingFirst clear the accumulation buffer and enable the frontbuffer for reading and writing. Then loop several times(say, n) through code that draws the image in a slightlydifferent position, accumulating the data withglAccum(GL_ACCUM, 1.0/n);and finally callingglAccum(GL_RETURN, 1.0);To decide what n should be, you need to trade off speed(the more times you draw the scene, the longer it takesto obtain the final image) and quality (the more times youdraw the scene, the smoother it gets, until you makemaximum use of the accumulation buffer’s resolution).Motion Blur2222by Jim X. Chen:
23Copyright @ 2001 by Jim X. Chen: firstname.lastname@example.org Suppose you want to make a motion-blurred imageextending over a small interval of time.Instead of spatially jittering the images, jitter themtemporally. The entire scene can be madesuccessively dimmer by callingglAccum (GL_MULT, decayFactor); wheredecayFactor is a number between 0.0 & 1.0.Smaller numbers for decayFactor cause the objectto appear to be moving faster. You can transfer thecompleted scene with the object’s current positionand “vapor trail” of previous positions from theaccumulation buffer to the standard color buffer withglAccum (GL_RETURN, 1.0);The image looks correct even if the items move atdifferent speeds, or if some of them are accelerated.As before, the more jitter points you use, the betterthe final image.You can combine motion blur with antialiasing byjittering in both the spatial and temporal domains,but you pay for higher quality with longer renderingtimes.2323by Jim X. Chen:
24Copyright @ 2001 by Jim X. Chen: email@example.com Depth of FieldA photograph made with a camera is in perfect focusonly for items lying on a single plane a certaindistance from the film. The farther an item is fromthis plane, the more out of focus it is.The depth of field for a camera is a region about theplane of perfect focus where items are out of focusby a small enough amount.The accumulation buffer can be used to approximatewhat you would see in a photograph where items aremore and more blurred as their distance from aplane of perfect focus increases.It isn’t an exact simulation of the effects produced ina camera, but the result looks similar.To achieve this result, draw the scene repeatedlyusing calls with different arg values to glFrustum().Choose the arguments so that the position of theviewpoint varies slightly around its true position andso that each frustum shares a common rectanglethat lies in the plane of perfect focus.2424by Jim X. Chen:
25Copyright @ 2001 by Jim X. Chen: firstname.lastname@example.org Soft ShadowsTo accumulate soft shadows due to multiple light sources,render the shadows with one light turned on at a time, andaccumulate them together.2525by Jim X. Chen:
26An Interactive Introduction to OpenGL Programming DitheringglEnable( GL_DITHER )Dither colors for better looking resultsUsed to simulate more available colorsDithering is a technique to trick the eye into seeing a smoother color when only a few colors are available. Newspaper’s use this trick to make images look better. OpenGL will modify a fragment’s color value with a dithering table before it is written into the framebuffer.
27Logical Operations on Pixels An Interactive Introduction to OpenGL ProgrammingLogical Operations on PixelsCombine pixels using bitwise logical operationsglLogicOp( mode )Common modesGL_XORGL_ANDLogical operations allows pixels to be combined with bitwise logical operations, like logical ands, ors and nots. The fragment’s color bits are combined with the pixel’s color bits using the logical operation, and then written into the framebuffer.GL_XOR is a useful logical operation for creating “rubber banding” type techniques, where you only momentarily want to modify a pixel, and then return back to its original value.There are several OpenGL logical operation modes:GL_CLEAR GL_SET GL_COPY,GL_COPY_INVERTED GL_NOOP GL_INVERTGL_AND GL_NAND GL_ORGL_NOR GL_XOR GL_AND_INVERTEDGL_AND_REVERSE GL_EQUIV GL_OR_REVERSEGL_OR_INVERTED