Difference between revisions of "Framebuffer"

From OpenGL.org
Jump to: navigation, search
(Fragment shader outputs: Imported from FBO page.)
(Section on buffer reading and so forth. Also a section on bind points.)
Line 2: Line 2:
  
 
{{stub}}
 
{{stub}}
 +
 +
== Bind points ==
 +
 +
{{apifunc|glBindFramebuffer}} is used to bind framebuffers to the context. They can be bound to one of two targets: {{enum|GL_DRAW_FRAMEBUFFER}} and {{enum|GL_READ_FRAMEBUFFER}}. The draw framebuffer is used as the destination for rendering, [[#Clearing|clearing]], and other writing operations. The read framebuffer is used as the source for reading operations.
 +
 +
Binding to the {{enum|GL_FRAMEBUFFER}} target is equivalent to binding that framebuffer to ''both'' {{enum|GL_DRAW_FRAMEBUFFER}} and {{enum|GL_READ_FRAMEBUFFER}}. Note that most other uses of {{enum|GL_FRAMEBUFFER}} mean the draw framebuffer; this is the case when it means both.
  
 
== Images ==
 
== Images ==
Line 7: Line 13:
 
== Colorspace ==
 
== Colorspace ==
  
== Buffer reading ==
+
== Clearing ==
  
Pixel data can be read from a framebuffer and stored into CPU memory (or a [[Pixel Buffer Object|buffer object]]). The framebuffer being read from is the framebuffer bound to {{enum|GL_READ_FRAMEBUFFER}}; remember that binding to {{enum|GL_FRAMEBUFFER}} binds to both the read and the draw.
 
  
To begin reading pixels, use this command:
 
  
{{funcdef|void {{apifunc|glReadPixels}}(GLint {{param|x}}, GLint {{param|y}}, GLsizei {{param|width}}, GLsizei {{param|height}}, GLenum {{param|format}}, GLenum {{param|type}}, GLvoid * {{param|data}})}}
+
== Read color buffer ==
  
This performs a [[Pixel Transfer]] read operation; as such, the destination {{param|data}} can be an offset into a [[Pixel Buffer Object]] if you so desire.
+
Certain operations, like pixel reads or blits, will read from a particular color image of the framebuffer. Which color image they read from is defined by the current read buffer. The framebuffer's read buffer is specified by:
  
Framebuffers can have many images to read from. Which image is read from depends in part on the {{param|format}} parameter. If {{param|format}} is {{enum|GL_DEPTH_COMPONENT}}, then the depth buffer is read from. If it is {{enum|GL_STENCIL_INDEX}}, then the stencil buffer is read from. If it is {{enum|GL_DEPTH_STENCIL}} then both the depth and stencil buffers are read from.
+
{{funcdef|void {{apifunc|glReadBuffer}}(GLenum {{param|mode}});}}
  
Framebuffers can have multiple color buffers. As such, if the {{param|format}} is some form of color buffer, then the specific image being read from is determined by the current read buffer of the framebuffer. This is defined by this function:
+
{{warning|This sets the read buffer for the framebuffer currently bound to {{enum|GL_READ_FRAMEBUFFER}}. So make sure that the framebuffer you want is bound to that buffer.}}
  
{{funcdef|void {{apifunc|glReadBuffer}}(GLenum {{param|mode}});}}
+
The read buffer is part of the framebuffer's state, so each framebuffer will remember its previously set read buffer.
  
This sets the read buffer for the framebuffer currently bound to {{enum|GL_READ_FRAMEBUFFER}}. The read buffer is part of the framebuffer's state.
+
If the {{enum|GL_READ_FRAMEBUFFER}} is the default framebuffer, then {{param|mode}} must be the name of a [[Default_Framebuffer#Color_buffers|color buffer name]]. It may be [[Default_Framebuffer#Multiple_buffer_aliases|one of the multiple buffer aliases]], which degrades as specified. If the read framebuffer is an FBO, then {{param|mode}} must be {{enum|GL_COLOR_ATTACHMENT''i''}}.
  
If the {{enum|GL_READ_FRAMEBUFFER}} is the default framebuffer, then {{param|mode}} must be the name of a specific color images, not one of the color images that refers to multiple buffers. So {{enum|GL_BACK}} cannot be used; it must be either {{enum|GL_BACK_LEFT}} or {{enum|GL_BACK_RIGHT}}. If the read framebuffer is an FBO, then {{param|mode}} must be {{enum|GL_COLOR_ATTACHMENT''i''}}.
+
{{param|mode}} may also be {{enum|GL_NONE}}, which indicates that no reading can be performed from color buffers on this framebuffer.
  
 
== Fragment shader outputs ==
 
== Fragment shader outputs ==
Line 37: Line 41:
 
This function sets the first {{param|n}} entires of the mapping table. The indices of the enumerators correspond to the output fragment colors from the vertex shader. Thus, {{param|n}} can only be as large as {{enum|GL_MAX_DRAW_BUFFERS}}. The entries in the {{param|bufs}} array are enumerators referring to buffer names in the framebuffer.
 
This function sets the first {{param|n}} entires of the mapping table. The indices of the enumerators correspond to the output fragment colors from the vertex shader. Thus, {{param|n}} can only be as large as {{enum|GL_MAX_DRAW_BUFFERS}}. The entries in the {{param|bufs}} array are enumerators referring to buffer names in the framebuffer.
  
The values in {{param|bufs}} must name specific images. The [[Default Framebuffer]] has a number of enumerators for images that name groups of images. These cannot be used; you must use {{enum|GL_BACK_LEFT}} rather than {{enum|GL_BACK}}. [[Framebuffer Objects]] use {{enum|GL_COLOR_ATTACHMENT''i''}} image names. An entry in the list can be {{enum|GL_NONE}}, which means that the output (if the shader outputs a value for it at all) is discarded.
+
The values in {{param|bufs}} must name specific color images. For the default framebuffer, image names cannot be the [[Default_Framebuffer#Multiple_buffer_aliases|one of the multiple buffer aliases]]; you must use {{enum|GL_BACK_LEFT}} rather than {{enum|GL_BACK}}. [[Framebuffer Objects]] use {{enum|GL_COLOR_ATTACHMENT''i''}} image names. An entry in the list can be {{enum|GL_NONE}}, which means that the output (if the shader outputs a value for it at all) is discarded.
  
If you are only setting up one draw buffer, you may use {{apifunc|glDrawBuffer}}. It takes one enumeration value and sets the fragment color 0 to draw to that buffer. All other fragment colors are set to {{enum|GL_NONE}}.
+
If you are only setting up one draw buffer, you may use {{apifunc|glDrawBuffer}}. It takes one enumeration value and sets the fragment color 0 to draw to that buffer. All other fragment colors are set to {{enum|GL_NONE}}. For the default framebuffer, the [[Default_Framebuffer#Multiple_buffer_aliases|multiple buffer aliases]] can be used (though it is not advised to do so). They will cause drawing operations to write to all of the specified buffers.
  
 
The state set by {{apifunc|glDrawBuffers}} is part of the state of the framebuffer. So you can generally set this up once and leave it set.
 
The state set by {{apifunc|glDrawBuffers}} is part of the state of the framebuffer. So you can generally set this up once and leave it set.
 +
 +
== Buffer reading ==
 +
 +
Pixel data can be read from a framebuffer and stored into CPU memory (or a [[Pixel Buffer Object|buffer object]]). The framebuffer being read from is the framebuffer bound to {{enum|GL_READ_FRAMEBUFFER}}; remember that binding to {{enum|GL_FRAMEBUFFER}} binds to both the read and the draw.
 +
 +
To begin reading pixels, use this command:
 +
 +
{{funcdef|void {{apifunc|glReadPixels}}(GLint {{param|x}}, GLint {{param|y}}, GLsizei {{param|width}}, GLsizei {{param|height}}, GLenum {{param|format}}, GLenum {{param|type}}, GLvoid * {{param|data}})}}
 +
 +
This performs a [[Pixel Transfer]] read operation; as such, the destination {{param|data}} can be an offset into a [[Pixel Buffer Object]] if you so desire.
 +
 +
Framebuffers can have many images to read from. Which image is read from depends in part on the {{param|format}} parameter. If {{param|format}} is {{enum|GL_DEPTH_COMPONENT}}, then the depth buffer is read from. If it is {{enum|GL_STENCIL_INDEX}}, then the stencil buffer is read from. If it is {{enum|GL_DEPTH_STENCIL}} then both the depth and stencil buffers are read from.
 +
 +
If {{param|format}} is a color format, then the current [[#Read color buffer]] is used. If the current read buffer is {{enum|GL_NONE}}, then a {{enum|GL_INVALID_OPERATION}} error will occur.
  
 
== Blitting ==
 
== Blitting ==

Revision as of 21:29, 17 February 2013

A Framebuffer is a series of images that can be used as the destination for rendering. OpenGL has two kinds of framebuffers: the Default Framebuffer, which is provided by the OpenGL Context; and user-created framebuffers called Framebuffer Objects (FBOs). The images for default framebuffers are part of the context and usually represent a window or display device. The images for FBOs come from either Textures or Renderbuffers, and are never visible.

Bind points

glBindFramebuffer is used to bind framebuffers to the context. They can be bound to one of two targets: GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER. The draw framebuffer is used as the destination for rendering, clearing, and other writing operations. The read framebuffer is used as the source for reading operations.

Binding to the GL_FRAMEBUFFER target is equivalent to binding that framebuffer to both GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER. Note that most other uses of GL_FRAMEBUFFER mean the draw framebuffer; this is the case when it means both.

Images

Colorspace

Clearing

Read color buffer

Certain operations, like pixel reads or blits, will read from a particular color image of the framebuffer. Which color image they read from is defined by the current read buffer. The framebuffer's read buffer is specified by:

void glReadBuffer(GLenum mode​);
Warning: This sets the read buffer for the framebuffer currently bound to GL_READ_FRAMEBUFFER. So make sure that the framebuffer you want is bound to that buffer.

The read buffer is part of the framebuffer's state, so each framebuffer will remember its previously set read buffer.

If the GL_READ_FRAMEBUFFER is the default framebuffer, then mode​ must be the name of a color buffer name. It may be one of the multiple buffer aliases, which degrades as specified. If the read framebuffer is an FBO, then mode​ must be GL_COLOR_ATTACHMENTi.

mode​ may also be GL_NONE, which indicates that no reading can be performed from color buffers on this framebuffer.

Fragment shader outputs

The final step of the rendering pipeline is writing the fragment data to the current GL_DRAW_FRAMEBUFFER framebuffer. Because framebuffers only store one depth and stencil image, there is only one destination for the depth and stencil fragment outputs. The fragment color data is more complicated. The framebuffer stores a mapping table that maps fragment shader color outputs to specific named images in the framebuffer.

A fragment shader has a list of output fragment colors, which are indexed on the half-open range [0, GL_MAX_DRAW_BUFFERS). The framebuffer's table maps from these indices to named color images in the framebuffer. To set this mapping table, use this function:

  void glDrawBuffers( GLsizei n​, const GLenum *bufs​ );

This function sets the first n​ entires of the mapping table. The indices of the enumerators correspond to the output fragment colors from the vertex shader. Thus, n​ can only be as large as GL_MAX_DRAW_BUFFERS. The entries in the bufs​ array are enumerators referring to buffer names in the framebuffer.

The values in bufs​ must name specific color images. For the default framebuffer, image names cannot be the one of the multiple buffer aliases; you must use GL_BACK_LEFT rather than GL_BACK. Framebuffer Objects use GL_COLOR_ATTACHMENTi image names. An entry in the list can be GL_NONE, which means that the output (if the shader outputs a value for it at all) is discarded.

If you are only setting up one draw buffer, you may use glDrawBuffer. It takes one enumeration value and sets the fragment color 0 to draw to that buffer. All other fragment colors are set to GL_NONE. For the default framebuffer, the multiple buffer aliases can be used (though it is not advised to do so). They will cause drawing operations to write to all of the specified buffers.

The state set by glDrawBuffers is part of the state of the framebuffer. So you can generally set this up once and leave it set.

Buffer reading

Pixel data can be read from a framebuffer and stored into CPU memory (or a buffer object). The framebuffer being read from is the framebuffer bound to GL_READ_FRAMEBUFFER; remember that binding to GL_FRAMEBUFFER binds to both the read and the draw.

To begin reading pixels, use this command:

void glReadPixels(GLint x​, GLint y​, GLsizei width​, GLsizei height​, GLenum format​, GLenum type​, GLvoid * data​)

This performs a Pixel Transfer read operation; as such, the destination data​ can be an offset into a Pixel Buffer Object if you so desire.

Framebuffers can have many images to read from. Which image is read from depends in part on the format​ parameter. If format​ is GL_DEPTH_COMPONENT, then the depth buffer is read from. If it is GL_STENCIL_INDEX, then the stencil buffer is read from. If it is GL_DEPTH_STENCIL then both the depth and stencil buffers are read from.

If format​ is a color format, then the current #Read color buffer is used. If the current read buffer is GL_NONE, then a GL_INVALID_OPERATION error will occur.

Blitting

Framebuffers can be bound to two separate targets with glBindFramebuffer: GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER. Binding to GL_FRAMEBUFFER is equivalent to binding the framebuffer to both.

The reason for the separation of these targets is to allow data in one framebuffer to be blitted to another framebuffer.

A blit operation is a special form of copy operation; it copies a rectangular area of pixels from one framebuffer to another. This function also has some very specific properties with regard to multisampling.

You bind the source framebuffer to GL_READ_FRAMEBUFFER, then bind the destination framebuffer to GL_DRAW_FRAMEBUFFER. The read framebuffer is the source of the blit, and the draw framebuffer is the destination. The read and draw framebuffers can be the same.

After binding the framebuffers, you call this function:

void glBlitFramebuffer(
     GLint srcX0​, GLint srcY0​, GLint srcX1​, GLint srcY1​,
     GLint dstX0​, GLint dstY0​, GLint dstX1​, GLint dstY1​,
     GLbitfield mask​, GLenum filter​);

The pixels in the rectangular area specified by the src​ values are copied to the rectangular area specified by the dst​ values. The mask​ parameter is a bitfield that specifies which kinds of buffers you want copied: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT, or some combination. The filter​ parameter specifies how you want filtering performed if the two rectangles are not the same size.

One thing to keep in mind is this: blit operations only read from the color buffer specified by glReadBuffer in the read FBO and will only write to the color buffers specified by glDrawBuffers in the write FBO. If multiple draw buffers are specified, then multiple color buffers are updated. This assumes that mask​ included the color buffer. The depth and stencil buffers of the source framebuffers are blitted to the destination if the mask​ specifies them.

The glReadBuffer state is stored with the FBO/default framebuffer, just like the glDrawBuffers state.

Note that it is perfectly valid to read from the default framebuffer and write to an FBO, or vice-versa.

Format Considerations

Blitting is not the same as performing a pixel transfer operation. The conversion between source and destination format is more limited. Blitting depth and stencil buffers works as expected: values are converted from one bitdepth to the other as needed. Conversion between color formats is different.

A blit operation can only convert between formats within 3 groups. Signed integral and unsigned integral formats make up two groups, with all normalized and floating-point formats making up the third. Thus, it is legal to blit from an GL_RGB8 buffer to a GL_RGB32F and vice versa. But it is not legal to blit a GL_RGB8 from or to a GL_RGBI8 format image.

The data during blitting is converted according to simple rules. Blitting from a floating-point format to a normalized integer format will cause clamping, either to [0, 1] for unsigned normalized or [-1, 1] for signed normalized.

Multisampling Considerations

Multisampling is supported with the Default Framebuffer (through WGL/GLX_multisample) and/or Framebuffer Objects (through multisampled renderbuffers or textures, where supported).

As explained in the article on Multisampling, a multisampled buffer must be resolved into a single sample before it can be displayed. When the default framebuffer uses multisampling, this resolving operation is automatic, occurring during framebuffer swapping (though reading from the framebuffer can cause it to happen anyway).

Each framebuffer has a specific number of multisample samples (for Framebuffer Objects, they cannot be framebuffer-complete if all of the attached images do not have the same number of samples). When you blit between two framebuffers with the same number of samples, the copy is done directly; the destination buffer gets the same information the source had.

It is an error to blit between buffers with different numbers of samples, unless one of them has zero samples. You get this by not attaching multisampled images to an FBO, or not using a multisampled Default Framebuffer.

If one of the framebuffers has zero samples, what happens depends on which framebuffer has zero samples. If the read framebuffer is the one with zero samples, then the draw framebuffer has all of its samples per-pixel replaced with the values from the read framebuffer. However, if the draw framebuffer is the one with zero samples, then it causes the multisampled framebuffer to have its multisamples resolved into a single sample per pixel into the draw framebuffer. This explicit resolution is very useful when wanting to display multisampled buffers.

As with all multisample behavior, none of this works at all unless glEnable(GL_MULTISAMPLE) is in effect (which is the default).