Lesson 5 :
Buffers & Framebuffer

There is 4 different buffer, each for a particular use :

 

The Color Buffer store the color for each pixels of the current frame. This buffer is what you see

The color is in RGBA mode ie Red Green Blue and Alpha.
The 3 first components (RGB) can be considered as the color of the pixel. The Alpha value can be considered as the opacity or transparency of the pixel. Alpha component of the color is associated with blending.
 

The Depth Buffer holds the depth of each pixels of the frame. It is also called z buffer.

Depth buffer is associated with the Depth Test. For each pixel drawn, the Depth Test compare the current depth stored in the depth buffer with the depth of the new pixel to draw. Depending on the result of the test, the pixel is drawn or not.

We usually use the depth buffer to draw nearest pixels, pixels behind are not drawn.
 

The Stencil Buffer can be used for restricting drawing area.

This buffer store a value associated to each pixels. Typically, we begin to draw a shape and tells to set 1 where pixels (of this shape) are drawn. Then, we make read only this buffer and tells we only want to draw where value is 1. Following objects will only be drawn in the corrsponding region of '1'.
Stencil buffer is usually used in multipass rendering to achieve particular effects (See Reflection in tutorial 23).
 

Accumulation Buffer store RGBA color like for Color Buffer.

This buffer is used for scene antialiazing, motion blur (motion blur effect can be achieved with blending),





 

Clearing buffer command :
   gl.glClear(buffers)
buffers is the bitwise OR operation of : GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT and GL_ACCUM_BUFFER_BIT.

For example, clearing the color and depth buffer : gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)


Clearing value can be specified by :
    gl.glClearColor(r, g, b, a)
    gl.glClearDepth(depth)
    gl.glClearStencil(s)
    gl.glClearAccum(r, g, b, a)


Don't forget to clear all buffer used at each frame. If you don't clear them, values of the previous frame will be keeped.
 

The number of bits stored for each pixel for the depth value is specified :
    GLCapabilities glCapabilities = new GLCapabilities()
    glCapabilities.setRedBits(n)      //Default 8
    glCapabilities.setGreenBits(n)    //Default 8
    glCapabilities.setBlueBits(n)     //Default 8
    glCapabilities.setAlphaBits(n)    //Default 0
    GLDrawableFactory.getFactory().createGLCanvas(glCapabilities)
n is the number of bits allocated in the color buffer, for the specified color component. If you want to store float values, you need 8 bits.
 

When you draw a pixels, OpenGl write the color of the pixel in this buffer. Just before the color is written, OpenGl apply the color mask.
Color mask is used to filter some color's components. You can determinate which component is read only and which can be read & write.
    gl.glColorMask(r, g, b, a)

This method is usefull to disable/enable drawing in the color buffer :
    gl.glColorMask(false, false, false, false)    //'Disable' color buffer
    ...
    gl.glColorMask(true, true, true, true)        //'Enable' color buffer
 

The number of bits stored for each pixel for the depth value is specified :
    GLCapabilities glCapabilities = new GLCapabilities()
    glCapabilities.setDepthBits(n)
    GLDrawableFactory.getFactory().createGLCanvas(glCapabilities)
n is the number of bit for depth value.
 

Depth buffer have also a mask, that determinate if writing is enable in this buffer.
    gl.glDepthMask(depth)
 

This test is enable/disable with :
    gl.glEnable(GL.GL_DEPTH_TEST)
    gl.glDisable(GL.GL_DEPTH_TEST)

The depth test is used to control if a pixel should be drawn or not, based on the information stored in depth buffer.
This test compare the depth of the pixel to be drawn to the existing depth in the buffer. The comparison is specified by :
    glDepthFunc(func)
func is the test function : GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER or GL_NOTEQUAL.

If the test fails, pixel is not drawn to any buffer. If the test success, OpenGl continue to the next test.

For example, GL_LEQUAL (less or equal) make the test : pixelDepth <= bufferDepth. This means that if the pixel is behind existing pixel, it is not drawn. If the pixel is in front of existing one, pixel is drawn.
This test is usefull for drawing complexe geometry, he determinate which pixels should not be drawn (because hiden by closer pixels).
 

The number of bit planes is specified at the creation of the GLCanvas, using a GLCapabilities object :
    GLCapabilities glCapabilities = new GLCapabilities()
    glCapabilities.setStencilBits(n)
    GLDrawableFactory.getFactory().createGLCanvas(glCapabilities)
n is the number of bit planes allocated per pixels. Each plane associate a bit ('0' or '1') to a pixel. This is equivalent to the number of bits per pixel.
 

Like previous buffers, stencil buffer have a mask, that determinate if writing is enable in this buffer. This method control the writting mode of each bit plane individually.
    gl.glStencilMask(bits)
bits is a bit mask,the nth least significant bits tell wether a bit is writtable (1) or not (0). The ith bit from the right indicate the write mode of the ith bit.


Least significant bits

Ex: For a 3 bit planes stencil buffer :
 gl.glStencilMask(0x00000111) enable writting of all bits.
 gl.glStencilMask(0x00000000) disable writting of all bits.
 gl.glStencilMask(0x00000100) enable writting for only the third bit and disable writting of the first and second bits.
 

This test is enable/disable with :
    gl.glEnable(GL.GL_STENCIL_TEST)
    gl.glDisable(GL.GL_STENCIL_TEST)

Stencil test is a test, like the depth test, based on bits values in the stencil buffer.
To specify the stencil function :
  gl.glStencilFunc(func, ref, mask)
func is the test function : GL_NEVER, GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL, GL_EQUAL, GL_NOTEQUAL or GL_ALWAYS.
GL_NEVER tells the test should always fail, GL_ALWAYS tells the test should always succeed.
ref 
mask

The test done is : (ref&mask) func (stencil&mask)     //Stencil is the value in the stencil buffer

For example, gl.glStencilFunc(GL.GL_ALWAYS, 1, 1) always passes, this is used to fill the stencil buffer where you draw pixels (ie for creating a mask region).
gl.glStencilFunc(GL.GL_EQUAL, 1, 1) test (1&1) == (stencil&1) this means stencil == 1.So, if the value in the buffer is one, test pass. This function can be used to draw only where there is 1 in the buffer.


Stencil function is used in association with :
    gl.glStencilOp(fail, zfail, zpass)
fail  is the action done when stencil test fails.
zfail is the action done when stencil test pass but depth test fails.
zpass is the action done when stencil test and depth test passes.
Actions can be : GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR & GL_INVERT.

For example, gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_REPLACE) replace the stencil value by ref only if stencil and depth tests passes.

Take a look on Turorial 23 : Reflection effect for an example of use of the stencil buffer.
 

To be continued ...

 

Previous Lesson

Back

Next Lesson

Last modified on 01/07/2010
Copyright © 2004-2012 Jérôme JOUVIE - All rights reserved. http://jerome.jouvie.free.fr/