Graphics‎ > ‎Graphic API‎ > ‎OpenGl‎ > ‎

Framebuffer

If you loose it look at 0xA0000


The thing one is rendering to is called the Framebuffer. There is a default framebuffer created for the display window of opengl but one can create extra ones to do off-screen rendering. The other ones are called Framebuffer Objects (FBO). A framebuffer can contain a number of color buffers, a depth buffer and a stencil buffer.

Clearing a Framebuffer 
To clear a framebuffer use glClear. It takes or'ed bitflags that selects what buffers to clear. The flags are GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT and  GL_STENCIL_BUFFER_BIT. The value to clear each buffer to is set with glClearColor, glClearDepth and glClearStencil. glClearBuffer* can be used to clear invidual color buffers if one has more then one. glClearBufferi can be used to clear both depth and stencil buffer at the same
time.

void glClear(GLbitfield mask);
void glClearColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha);
void glClearDepth(GLdouble depth);
void glClearStencil(GLint s);


Color
Blending
Blending is when one what is drawn with what is already in the color buffer. Blending is enabled with GL_BLEND. It is activated on all color buffers but one can specify separate blend parameters for each buffer with the functions that end in i.

glEnable(GL_BLEND);

Blend Equation
To mix the colors of the source (fragment) and the destination (color buffer) the following Blend Equation is used. C stands for color and F for factor. o is out value, s is source and d is destination. Fs and Fd can be changed and the + operation can also be changed.

Co = Cs * Fs + Cd * Fd.

The + operation in the equation is the default one but you can change it with glBlendEquation. Allowed settings are GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN and GL_MAX. With glBlendFuncSeparate it is possible to set seperate operations on the RGB and alpha components.

void glBlendEquation(GLenum mode);

With glBlendFunc it is possible to set Fs and Fd in the blend equation. The values are not set directly, instead one use enums to select where the values should be taken from. Using glBlendFuncSeparate it is possible to select different values for the RGB and alpha components.

void glBlendFunc(GLenum sfactor,GLenum dfactor);
void glBlendColor(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha);

Transparency
When the object is either opaque or fully transparent the discard command can be used in the fragment shader. Throw away any fragment with a alpha value above 0.5. The good thing with that is objects can be drawn in any order.

    if(diffuseColor.a > 0.5)
        discard;

For partial transparency use blending and sort objects with the most distant object drawn first.

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);


Depth
Used for Visible Surface Determination with Z-Buffering. Enable it with GL_DEPTH_TEST. It also possible to disable writing to the depth buffer with glDepthMask.

glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT); 
void glClearDepth(GLdouble depth);
void glDepthMask(GLboolean flag);

With glDepthFunc it is possible to select when OpenGL should pass or discard a fragment against the
depth buffer. Default is GL_LESS.

void glDepthFunc(GLenum func);

Stencil
The options for the stencil buffer can be set for back-facing polygons and front-facing polygons. To set them to different values use the glStencil*Separate function. If both values should be the same you can use the glStencil* functions instead.

Select the test

void glStencilFunc(GLenum func,GLint ref,GLuint mask);

Select the action

void glStencilMask(GLuint mask);

Mask out what is written


void glStencilOp(GLenum sfail,GLenum dpfail,GLenum dppass);



Framebuffer Objects
With FBO one create do off-screen rendering. It has the normal OpenGL functions to create and destroy them.

Bind
Set a FBO for drawing (GL_DRAW_FRAMEBUFFER), reading (GL_READ_FRAMEBUFFER) or both GL_FRAMEBUFFER. Using 0 as a framebuffer binds target to the default framebuffer.

glBindFrameBuffer

Attaching
A FBO contains no image storage on it's own so one must attach textures or renderbuffer objects to it. Each one is given an attachment point that select where in the FBO the image will be connected. By using a id of 0 one can detach anything from the selected attachment point. To attach the renderbuffers use glFrameBufferRenderBuffer. To attach textures use glFramebufferTexture*D or glFramebufferTextureLayer​ to attatch a layer in 3D texture or a array texture. Attatchement is one of the following.
  • GL_COLOR_ATTACHMENT*: The * is colorbuffer from zero to max color attatchments.
  • GL_DEPTH_ATTACHMENT: Depth buffer.
  • GL_STENCIL_ATTACHMENT: Stencil buffer.
  • GL_DEPTH_STENCIL_ATTATCHMENT: For packed depth-stencil buffers.
Status
When everything in the FBO is setup the final step is to validate it's status as complete. If it is complete it can now be used for drawing and reading. If not check the error value to solve the problem.

    GLenum glCheckFramebufferStatus​(GLenum target​);

Multiple-Render Targets (MRT)
When there is multiple colors buffers to write to the fragment shaders need to know where to put things. The simple way is to use a layout qualifier to direct values to the right color buffer.

layout (location = 0)    out vec4 color;
layout (location = 1)    out vec4 normal;


Renderbuffer Objects
When using a FBO and there is no need to sample from the image it is possible to use a RenderBuffer object instead of a texture. To create the storage for a renderbuffer objects used the following functions depending on the need for multisample support.

Create

glGenRenderBuffers
glIsRenderBuffer
glDeleteRenderBuffers

Bind
glBindRenderBuffer

Storage

Memory is allocated to a renderbuffer with glRenderBufferStorage or glRenderBufferStorageMultisample. The internalformat must be correct for the way the renderbuffer will be used.

    void glRenderbufferStorage​(GLenum target​, GLenum internalformat​, GLsizei width​, GLsizei height​);
    void glRenderbufferStorageMultisample​(GLenum target​, GLsizei samples​, GLenum internalformat​, GLsizei width​, GLsizei height​);

Reference


Comments