blob: 54a4c37f3b73f3bfd710797eae0c90969a77b9a5 [file] [log] [blame]
Name
ARB_framebuffer_object
Name Strings
GL_ARB_framebuffer_object
Contributors
Kurt Akeley
Jason Allen
Rob Barris
Bob Beretta
Pat Brown
Matt Craighead
Alex Eddy
Cass Everitt
Mark Galvan
Michael Gold
Evan Hart
Jeff Juliano
John Kessenich
Mark Kilgard
Dale Kirkland
Daniel Koch
Jon Leech
Bill Licea-Kane
Barthold Lichtenbelt
Kent Lin
Rob Mace
Teri Morrison
Chris Niederauer
Brian Paul
Paul Puey
Ian Romanick
John Rosasco
R. Jason Sams
Jeremy Sandmel
Mark Segal
Avinash Seetharamaiah
Folker Schamel
Eskil Steenberg
Daniel Vogel
Eric Werness
Cliff Woolley
Contacts
Rob Barris (rbarris 'at' gmail.com)
Daniel Koch, TransGaming Inc.
Notice
Copyright (c) 2008-2013 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Status
Approved by the ARB on August 4, 2008
Version
Last Modified Date: October 6, 2016
Revision: #38
Number
ARB Extension #45
Dependencies
OpenGL 1.1 is required.
WGL_ARB_make_current_read affects the definition of this extension.
GLX 1.3 / GLX_SGI_make_current_read affects the definition of this
extension.
ATI_draw_buffers affects the definition of this extension.
ARB_draw_buffers affects the definition of this extension.
ARB_fragment_program affects the definition of this extension.
ARB_fragment_shader affects the definition of this extension.
ARB_texture_rectangle affects the definition of this extension.
ARB_vertex_shader affects the definition of this extension.
NV_float_buffer affects the definition of this extension.
ARB_color_buffer_float affects the definition of this extension.
NV_texture_shader affects the definition of this extension.
This extension modifies NV_packed_depth_stencil.
ARB_depth_texture affects the definition of this extension.
SGIX_depth_texture affects the definition of this extension.
ARB_texture_rg affects the definition of this extension.
EXT_texture_array affects the definition of this extension.
EXT_texture_integer affects the definition of this extension.
ARB_framebuffer_sRGB affects the definition of this extension.
Written based on the wording of the OpenGL 2.1 specification.
Overview
ARB_framebuffer_object is an extension intended to address the following
goals:
- Reflect FBO-related functionality found in the OpenGL 3.0 specification.
- Integrate multiple disjoint extensions into a single ARB extension.
These extensions are:
EXT_framebuffer_object
EXT_framebuffer_blit
EXT_framebuffer_multisample
EXT_packed_depth_stencil
- Where appropriate, relax some of the constraints expressed by previous
FBO-related extensions. In particular the requirement of matching
attachment dimensions and component sizes has been relaxed, to allow
implementations the freedom to support more flexible usages where
possible.
ARB_framebuffer_object defines an interface for drawing to rendering
destinations other than the buffers provided to the GL by the
window-system.
In this extension, these newly defined rendering destinations are
known collectively as "framebuffer-attachable images". This
extension provides a mechanism for attaching framebuffer-attachable
images to the GL framebuffer as one of the standard GL logical
buffers: color, depth, and stencil. (Attaching a
framebuffer-attachable image to the accum logical buffer is left for
a future extension to define). When a framebuffer-attachable image
is attached to the framebuffer, it is used as the source and
destination of fragment operations as described in Chapter 4.
By allowing the use of a framebuffer-attachable image as a rendering
destination, this extension enables a form of "offscreen" rendering.
Furthermore, "render to texture" is supported by allowing the images
of a texture to be used as framebuffer-attachable images. A
particular image of a texture object is selected for use as a
framebuffer-attachable image by specifying the mipmap level, cube
map face (for a cube map texture), and layer (for a 3D texture)
that identifies the image. The "render to texture" semantics of
this extension are similar to performing traditional rendering to
the framebuffer, followed immediately by a call to CopyTexSubImage.
However, by using this extension instead, an application can achieve
the same effect, but with the advantage that the GL can usually
eliminate the data copy that would have been incurred by calling
CopyTexSubImage.
This extension also defines a new GL object type, called a
"renderbuffer", which encapsulates a single 2D pixel image. The
image of renderbuffer can be used as a framebuffer-attachable image
for generalized offscreen rendering and it also provides a means to
support rendering to GL logical buffer types which have no
corresponding texture format (stencil, accum, etc). A renderbuffer
is similar to a texture in that both renderbuffers and textures can
be independently allocated and shared among multiple contexts. The
framework defined by this extension is general enough that support
for attaching images from GL objects other than textures and
renderbuffers could be added by layered extensions.
To facilitate efficient switching between collections of
framebuffer-attachable images, this extension introduces another new
GL object, called a framebuffer object. A framebuffer object
contains the state that defines the traditional GL framebuffer,
including its set of images. Prior to this extension, it was the
window-system which defined and managed this collection of images,
traditionally by grouping them into a "drawable". The window-system
API's would also provide a function (i.e., wglMakeCurrent,
glXMakeCurrent, aglSetDrawable, etc.) to bind a drawable with a GL
context (as is done in the WGL_ARB_pbuffer extension). In this
extension however, this functionality is subsumed by the GL and the
GL provides the function BindFramebufferARB to bind a framebuffer
object to the current context. Later, the context can bind back to
the window-system-provided framebuffer in order to display rendered
content.
Previous extensions that enabled rendering to a texture have been
much more complicated. One example is the combination of
ARB_pbuffer and ARB_render_texture, both of which are window-system
extensions. This combination requires calling MakeCurrent, an
operation that may be expensive, to switch between the window and
the pbuffer drawables. An application must create one pbuffer per
renderable texture in order to portably use ARB_render_texture. An
application must maintain at least one GL context per texture
format, because each context can only operate on a single
pixelformat or FBConfig. All of these characteristics make
ARB_render_texture both inefficient and cumbersome to use.
ARB_framebuffer_object, on the other hand, is both simpler to use
and more efficient than ARB_render_texture. The
ARB_framebuffer_object API is contained wholly within the GL API and
has no (non-portable) window-system components. Under
ARB_framebuffer_object, it is not necessary to create a second GL
context when rendering to a texture image whose format differs from
that of the window. Finally, unlike the pbuffers of
ARB_render_texture, a single framebuffer object can facilitate
rendering to an unlimited number of texture objects.
This extension differs from EXT_framebuffer_object by splitting the
framebuffer object binding point into separate DRAW and READ
bindings (incorporating functionality introduced by
EXT_framebuffer_blit). This allows copying directly from one
framebuffer to another. In addition, a new high performance blit
function is added to facilitate these blits and perform some data
conversion where allowed.
This extension also enables usage of multisampling in conjunction with
renderbuffers (incorporating functionality from
EXT_packed_depth_stencil), as follows:
The new operation RenderbufferStorageMultisample() allocates
storage for a renderbuffer object that can be used as a multisample
buffer. A multisample render buffer image differs from a
single-sample render buffer image in that a multisample image has a
number of SAMPLES that is greater than zero. No method is provided
for creating multisample texture images.
All of the framebuffer-attachable images attached to a framebuffer
object must have the same number of SAMPLES or else the framebuffer
object is not "framebuffer complete". If a framebuffer object with
multisample attachments is "framebuffer complete", then the
framebuffer object behaves as if SAMPLE_BUFFERS is one.
In traditional multisample rendering, where
DRAW_FRAMEBUFFER_BINDING is zero and SAMPLE_BUFFERS is one, the
GL spec states that "the color sample values are resolved to a
single, displayable color each time a pixel is updated." There are,
however, several modern hardware implementations that do not
actually resolve for each sample update, but instead postpones the
resolve operation to a later time and resolve a batch of sample
updates at a time. This is OK as long as the implementation behaves
"as if" it had resolved a sample-at-a-time. Unfortunately, however,
honoring the "as if" rule can sometimes degrade performance.
In contrast, when DRAW_FRAMEBUFFER_BINDING is an
application-created framebuffer object, MULTISAMPLE is enabled, and
SAMPLE_BUFFERS is one, there is no implicit per-sample-update
resolve. Instead, the application explicitly controls when the
resolve operation is performed. The resolve operation is affected
by calling BlitFramebuffer where the source is a multisample
application-created framebuffer object and the destination is a
single-sample framebuffer object (either application-created or
window-system provided).
This design for multisample resolve more closely matches current
hardware, but still permits implementations which choose to resolve
a single sample at a time. If hardware that implements the
multisample resolution "one sample at a time" exposes
ARB_framebuffer_object, it could perform the implicit resolve
to a driver-managed hidden surface, then read from that surface when
the application calls BlitFramebuffer.
Another motivation for granting the application explicit control
over the multisample resolve operation has to do with the
flexibility afforded by ARB_framebuffer_object. Previously, a
drawable (window or pbuffer) had exclusive access to all of its
buffers. There was no mechanism for sharing a buffer across
multiple drawables. Under ARB_framebuffer_object, however, a
mechanism exists for sharing a framebuffer-attachable image across
several framebuffer objects, as well as sharing an image between a
framebuffer object and a texture. If we had retained the "implicit"
resolve from traditional multisampled rendering, and allowed the
creation of "multisample" format renderbuffers, then this type of
sharing would have lead to two problematic situations:
* Two contexts, which shared renderbuffers, might perform
competing resolve operations into the same single-sample buffer
with ambiguous results.
* It would have introduced the unfortunate ability to use the
single-sample buffer as a texture while MULTISAMPLE is ENABLED.
Using BlitFramebuffer as an explicit resolve to serialize access to
the multisampled contents and eliminate the implicit per-sample
resolve operation, we avoid both of these problems.
This extension also enables usage of packed depth-stencil formats in
renderbuffers (incorporating functionality from
EXT_packed_depth_stencil), as follows:
Many OpenGL implementations have chosen to interleave the depth and
stencil buffers into one buffer, often with 24 bits of depth
precision and 8 bits of stencil data. 32 bits is more than is
needed for the depth buffer much of the time; a 24-bit depth buffer,
on the other hand, requires that reads and writes of depth data be
unaligned with respect to power-of-two boundaries. On the other
hand, 8 bits of stencil data is more than sufficient for most
applications, so it is only natural to pack the two buffers into a
single buffer with both depth and stencil data. OpenGL never
provides direct access to the buffers, so the OpenGL implementation
can provide an interface to applications where it appears the one
merged buffer is composed of two logical buffers.
One disadvantage of this scheme is that OpenGL lacks any means by
which this packed data can be handled efficiently. For example,
when an application reads from the 24-bit depth buffer, using the
type GL_UNSIGNED_SHORT will lose 8 bits of data, while
GL_UNSIGNED_INT has 8 too many. Both require expensive format
conversion operations. A 24-bit format would be no more suitable,
because it would also suffer from the unaligned memory accesses that
made the standalone 24-bit depth buffer an unattractive proposition
in the first place.
Many applications, such as parallel rendering applications, may also
wish to draw to or read back from both the depth and stencil buffers
at the same time. Currently this requires two separate operations,
reducing performance. Since the buffers are interleaved, drawing to
or reading from both should be no more expensive than using just
one; in some cases, it may even be cheaper.
This extension provides a new data format, GL_DEPTH_STENCIL,
that can be used with the glDrawPixels, glReadPixels, and
glCopyPixels commands, as well as a packed data type,
GL_UNSIGNED_INT_24_8, that is meant to be used with
GL_DEPTH_STENCIL. No other data types are supported with
GL_DEPTH_STENCIL. If ARB_depth_texture or SGIX_depth_texture is
supported, GL_DEPTH_STENCIL/GL_UNSIGNED_INT_24_8 data can
also be used for textures; this provides a more efficient way to
supply data for a 24-bit depth texture.
GL_DEPTH_STENCIL data, when passed through the pixel path,
undergoes both depth and stencil operations. The depth data is
scaled and biased by the current GL_DEPTH_SCALE and GL_DEPTH_BIAS,
while the stencil data is shifted and offset by the current
GL_INDEX_SHIFT and GL_INDEX_OFFSET. The stencil data is also put
through the stencil-to-stencil pixel map.
glDrawPixels of GL_DEPTH_STENCIL data operates similarly to that
of GL_STENCIL_INDEX data, bypassing the OpenGL fragment pipeline
entirely, unlike the treatment of GL_DEPTH_COMPONENT data. The
stencil and depth masks are applied, as are the pixel ownership and
scissor tests, but all other operations are skipped.
glReadPixels of GL_DEPTH_STENCIL data reads back a rectangle
from both the depth and stencil buffers.
glCopyPixels of GL_DEPTH_STENCIL data copies a rectangle from
both the depth and stencil buffers. Like glDrawPixels, it applies
both the stencil and depth masks but skips the remainder of the
OpenGL fragment pipeline.
glTex[Sub]Image[1,2,3]D of GL_DEPTH_STENCIL data loads depth and
stencil data into a depth_stencil texture. glGetTexImage of
GL_DEPTH_STENCIL data can be used to retrieve depth and stencil
data from a depth/stencil texture.
In addition, a new base internal format, GL_DEPTH_STENCIL, can
be used by both texture images and renderbuffer storage. When an
image with a DEPTH_STENCIL internal format is attached to both
the depth and stencil attachment points of a framebuffer object,
then it becomes both the depth and stencil
buffers of the framebuffer. This fits nicely with hardware that
interleaves both depth and stencil data into a single buffer. When
a texture with DEPTH_STENCIL data is bound for texturing, only
the depth component is accessible through the texture fetcher. The
stencil data can be written with TexImage or CopyTexImage, and can
be read with GetTexImage. When a DEPTH_STENCIL image is
attached to the stencil attachment of the bound framebuffer object,
the stencil data can be accessed through any operation that reads
from or writes to the framebuffer's stencil buffer.
Glossary of Helpful Terms
logical buffer:
One of the color, depth, or stencil buffers of the
framebuffer.
framebuffer:
The collection of logical buffers and associated state
defining where the output of GL rendering is directed.
texture:
an object which consists of one or more 2D arrays of pixel
images and associated state that can be used as a source of
data during the texture-mapping process described in section
3.8.
texture image:
one of the 2D arrays of pixels that are part of a texture
object as defined in section 3.8. Texture images contain
and define the texels of the texture object.
renderbuffer:
A new type of storage object which contains a single 2D
array of pixels and associated state that can be used as a
destination for pixel data written during the rendering
process described in Chapter 4.
renderbuffer image:
The 2D array of pixels that is part of a renderbuffer
object. A renderbuffer image contains and defines the
pixels of the renderbuffer object.
framebuffer-attachable image:
A 2D pixel image that can be attached to one of the logical
buffer attachment points of a framebuffer object. Texture
images and renderbuffer images are two examples of
framebuffer-attachable images.
attachment point:
The set of state which references a specific
framebuffer-attachable image, and allows that
framebuffer-attachable image to be used to store the
contents of a logical buffer of a framebuffer object. There
is an attachment point state vector for each color, depth,
and stencil buffer of a framebuffer.
attach:
The act of connecting one object to another object.
An "attach" operation is similar to a "bind" operation in
that both represent a reference to the attached or bound
object for the purpose of managing object lifetimes and both
enable manipulation of the state of the attached or bound
object.
However, an "attach" is also different from a "bind" in that
"binding" an unused object creates a new object, while
"attaching" does not. Additionally, "bind" establishes a
connection between a context and an object, while "attach"
establishes a connection between two objects.
Finally, if object "A" is attached to object "B" and object
"B" is bound to context "C", then in most respects, we treat
"A" as if it is <implicitly> bound to "C".
framebuffer attachment completeness:
Similar to texture "mipmap" or "cube" completeness from
section 3.8.10, defines a minimum set of criteria for
framebuffer attachment points. (for complete definition,
see section 4.4.4.1)
framebuffer completeness:
Similar to texture "mipmap cube completeness", defines a
composite set of "completeness" requirements and
relationships among the attached framebuffer-attachable
images. (for complete definition, see section 4.4.4.2)
New Procedures and Functions
boolean IsRenderbuffer(uint renderbuffer);
void BindRenderbuffer(enum target, uint renderbuffer);
void DeleteRenderbuffers(sizei n, const uint *renderbuffers);
void GenRenderbuffers(sizei n, uint *renderbuffers);
void RenderbufferStorage(enum target, enum internalformat,
sizei width, sizei height);
void RenderbufferStorageMultisample(enum target, sizei samples,
enum internalformat,
sizei width, sizei height);
void GetRenderbufferParameteriv(enum target, enum pname, int *params);
boolean IsFramebuffer(uint framebuffer);
void BindFramebuffer(enum target, uint framebuffer);
void DeleteFramebuffers(sizei n, const uint *framebuffers);
void GenFramebuffers(sizei n, uint *framebuffers);
enum CheckFramebufferStatus(enum target);
void FramebufferTexture1D(enum target, enum attachment,
enum textarget, uint texture, int level);
void FramebufferTexture2D(enum target, enum attachment,
enum textarget, uint texture, int level);
void FramebufferTexture3D(enum target, enum attachment,
enum textarget, uint texture,
int level, int layer);
void FramebufferTextureLayer(enum target,enum attachment,
uint texture,int level,int layer);
void FramebufferRenderbuffer(enum target, enum attachment,
enum renderbuffertarget, uint renderbuffer);
void GetFramebufferAttachmentParameteriv(enum target, enum attachment,
enum pname, int *params);
void BlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1,
int dstX0, int dstY0, int dstX1, int dstY1,
bitfield mask, enum filter);
void GenerateMipmap(enum target);
New Types
None.
New Tokens
Accepted by the <target> parameter of BindFramebuffer,
CheckFramebufferStatus, FramebufferTexture{1D|2D|3D},
FramebufferRenderbuffer, and
GetFramebufferAttachmentParameteriv:
FRAMEBUFFER 0x8D40
READ_FRAMEBUFFER 0x8CA8
DRAW_FRAMEBUFFER 0x8CA9
Accepted by the <target> parameter of BindRenderbuffer,
RenderbufferStorage, and GetRenderbufferParameteriv, and
returned by GetFramebufferAttachmentParameteriv:
RENDERBUFFER 0x8D41
Accepted by the <internalformat> parameter of
RenderbufferStorage:
STENCIL_INDEX1 0x8D46
STENCIL_INDEX4 0x8D47
STENCIL_INDEX8 0x8D48
STENCIL_INDEX16 0x8D49
Accepted by the <pname> parameter of GetRenderbufferParameteriv:
RENDERBUFFER_WIDTH 0x8D42
RENDERBUFFER_HEIGHT 0x8D43
RENDERBUFFER_INTERNAL_FORMAT 0x8D44
RENDERBUFFER_RED_SIZE 0x8D50
RENDERBUFFER_GREEN_SIZE 0x8D51
RENDERBUFFER_BLUE_SIZE 0x8D52
RENDERBUFFER_ALPHA_SIZE 0x8D53
RENDERBUFFER_DEPTH_SIZE 0x8D54
RENDERBUFFER_STENCIL_SIZE 0x8D55
RENDERBUFFER_SAMPLES 0x8CAB
Accepted by the <pname> parameter of
GetFramebufferAttachmentParameteriv:
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
Returned in <params> by GetFramebufferAttachmentParameteriv:
SRGB 0x8C40
UNSIGNED_NORMALIZED 0x8C17
FRAMEBUFFER_DEFAULT 0x8218
INDEX 0x8222
Accepted by the <attachment> parameter of
FramebufferTexture{1D|2D|3D}, FramebufferRenderbuffer, and
GetFramebufferAttachmentParameteriv
COLOR_ATTACHMENT0 0x8CE0
COLOR_ATTACHMENT1 0x8CE1
COLOR_ATTACHMENT2 0x8CE2
COLOR_ATTACHMENT3 0x8CE3
COLOR_ATTACHMENT4 0x8CE4
COLOR_ATTACHMENT5 0x8CE5
COLOR_ATTACHMENT6 0x8CE6
COLOR_ATTACHMENT7 0x8CE7
COLOR_ATTACHMENT8 0x8CE8
COLOR_ATTACHMENT9 0x8CE9
COLOR_ATTACHMENT10 0x8CEA
COLOR_ATTACHMENT11 0x8CEB
COLOR_ATTACHMENT12 0x8CEC
COLOR_ATTACHMENT13 0x8CED
COLOR_ATTACHMENT14 0x8CEE
COLOR_ATTACHMENT15 0x8CEF
DEPTH_ATTACHMENT 0x8D00
STENCIL_ATTACHMENT 0x8D20
DEPTH_STENCIL_ATTACHMENT 0x821A
Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
MAX_SAMPLES 0x8D57
FRAMEBUFFER_BINDING 0x8CA6 // alias DRAW_FRAMEBUFFER_BINDING
DRAW_FRAMEBUFFER_BINDING 0x8CA6
READ_FRAMEBUFFER_BINDING 0x8CAA
RENDERBUFFER_BINDING 0x8CA7
MAX_COLOR_ATTACHMENTS 0x8CDF
MAX_RENDERBUFFER_SIZE 0x84E8
Returned by CheckFramebufferStatus():
FRAMEBUFFER_COMPLETE 0x8CD5
FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
FRAMEBUFFER_UNSUPPORTED 0x8CDD
FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
FRAMEBUFFER_UNDEFINED 0x8219
Returned by GetError():
INVALID_FRAMEBUFFER_OPERATION 0x0506
Accepted by the <format> parameter of DrawPixels, ReadPixels,
TexImage1D, TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D,
TexSubImage3D, and GetTexImage, by the <type> parameter of
CopyPixels, by the <internalformat> parameter of TexImage1D,
TexImage2D, TexImage3D, CopyTexImage1D, CopyTexImage2D, and
RenderbufferStorage, and returned in the <data> parameter of
GetTexLevelParameter and GetRenderbufferParameteriv:
DEPTH_STENCIL 0x84F9
Accepted by the <type> parameter of DrawPixels, ReadPixels,
TexImage1D, TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D,
TexSubImage3D, and GetTexImage:
UNSIGNED_INT_24_8 0x84FA
Accepted by the <internalformat> parameter of TexImage1D,
TexImage2D, TexImage3D, CopyTexImage1D, CopyTexImage2D, and
RenderbufferStorage, and returned in the <data> parameter of
GetTexLevelParameter and GetRenderbufferParameteriv:
DEPTH24_STENCIL8 0x88F0
Accepted by the <value> parameter of GetTexLevelParameter:
TEXTURE_STENCIL_SIZE 0x88F1
Additions to Chapter 2 of the 2.1 Specification (OpenGL Operation)
"The GL interacts with two classes of framebuffers: window
system-provided and application-created. There is at most one window
system-provided framebuffer at any time, referred to as the <default
framebuffer>. Application-created framebuffers, referred to as
<framebuffer objects>, may be created as desired. These two types of
framebuffer are distinguished primarily by the interface for configuring
and managing their state.
The effects of GL commands on the default framebuffer are ultimately
controlled by the window system, which allocates framebuffer resources,
determines what portions of the default framebuffer the GL may access at
any given time, and communicates to the GL how those portions are
structured. Therefore, there are no GL commands to initialize a GL
context or configure the default framebuffer. Similarly, display of
framebuffer contents on a physical display device (including the
transformation of individual framebuffer values by such techniques as
gamma correction) is not addressed by the GL.
Allocation and configuration of the default framebuffer occurs outside
of the GL in conjunction with the window system, using companion APIs
such as GLX, WGL, and AGL for GL implementations running on the X Window
System, Microsoft Windows, and MacOS X respectively.
Allocation and initialization of GL contexts is also done using these
companion APIs. GL contexts can typically be associated with different
default framebuffers, and some context state is determined at the time
this association is performed.
It is possible to use a GL context <without> a default framebuffer, in
which case a framebuffer object must be used to perform all rendering.
This is useful for applications needing to perform <offscreen
rendering>."
Add to table 2.3, "Summary of GL errors":
Error Description Offending command
ignored?
----------------------------- ------------------ -----------------
...
INVALID_FRAMEBUFFER_OPERATION Framebuffer object Yes
is not complete
Append the following to section 2.6.1 "Begin and End":
"Calling Begin will result in an INVALID_FRAMEBUFFER_OPERATION
error if the object bound to DRAW_FRAMEBUFFER_BINDING is not
"framebuffer complete" (see section 4.4.4.2)."
Update the bulleted list in section 2.15.4 "Shader Execution" in
the subsection titled "Texture Access" to say:
"* The sampler used in a texture lookup function is not one of
the shadow sampler types, the texture object's base internal
format is DEPTH_COMPONENT or DEPTH_STENCIL, and the
TEXTURE_COMPARE_MODE is not NONE.
* The sampler used in a texture lookup function is one of the
shadow sampler types, the texture object's base
internal format is DEPTH_COMPONENT or DEPTH_STENCIL, and the
TEXTURE_COMPARE_MODE is NONE.
* The sampler used in a texture lookup function is one of the
shadow sampler types, and the texture object's base
internal format is not DEPTH_COMPONENT or DEPTH_STENCIL.
The stencil index texture internal component is ignored if the base
internal format is DEPTH_STENCIL.
If a vertex shader uses..."
Additions to Chapter 3 of the OpenGL 2.1 Specification (Rasterization)
Update section 3.6.3 "Pixel Transfer Modes", the first paragraph of
the subsection "Color Table Specification", in the definition of
ColorTable, to say:
"... The <formats> COLOR_INDEX, DEPTH_COMPONENT, DEPTH_STENCIL,
and STENCIL_INDEX and the <type> BITMAP are not allowed."
Update section 3.6.3 "Pixel Transfer Modes", the third paragraph of
the subsection "Color Table Specification", in the definition of
ColorTable, to say:
"... <internalformat> must be one of the formats in table 3.15 or
table 3.16, other than the DEPTH_COMPONENT or DEPTH_STENCIL
formats in those tables."
Add to section 3.6.3 "Pixel Transfer Modes", at the end of the
subsection titled "Alternate Color Table Specification Commands":
"Calling CopyColorTable or CopyColorSubTable will result in an
INVALID_FRAMEBUFFER_OPERATION error if the object bound to
READ_FRAMEBUFFER_BINDING is not "framebuffer complete"
(see section 4.4.4.2)."
In section 3.6.3 "Pixel Transfer Modes", the subsection "Covolution
Filter Specification", update the first paragraph in the definition
of ConvolutionFilter2D to say:
"... The formats COLOR_INDEX, DEPTH_COMPONENT, DEPTH_STENCIL,
and STENCIL_INDEX and the type BITMAP are not allowed."
In section 3.6.3 "Pixel Transfer Modes", update the third paragraph
of the subsection "Convolution Filter Specification", in the definition
of ConvolutionFilter2D, to say:
"... <internalformat> accepts the same values as the corresponding
argument of ColorTable."
Add to section 3.6.3 "Pixel Transfer Modes", at the end of the
subsection titled "Alternate Convolution Filter Specification Commands":
"Calling CopyConvolutionFilter1D or CopyConvolutionFilter2D will
result in an INVALID_FRAMEBUFFER_OPERATION error if the object
bound to READ_FRAMEBUFFER_BINDING is not "framebuffer
complete" (see section 4.4.4.2)."
In section 3.6.3 "Pixel Transfer Modes", update the third paragraph
of the "Histogram Table Specification" subsection , in the definition of
Histogram, to say:
"... is too large for the implementation. <internalformat> accepts the
same values as the corresponding argument of ColorTable, with the
exception of the values 1, 2, 3, and 4."
In section 3.6.3 "Pixel Transfer Modes", update the second paragraph
in the subsection titled "Minmax Table Specification", in the definition
of Minmax to say:
"<internalformat> accepts the same values as the corresponding argument
of ColorTable, with the exception of the values 1, 2, 3, and 4, as well
as the INTENSITY base and sized internal formats."
In section 3.6.4 "Rasterization of Pixel Rectangles", modify the final
paragraph of the definition of DrawPixels as follows:
"... If the GL is in color index mode and <format> is not one of
COLOR_INDEX, STENCIL_INDEX, DEPTH_COMPONENT, or DEPTH_STENCIL,
then the error INVALID_OPERATION occurs. If <type> is BITMAP and
<format> is not COLOR_INDEX or STENCIL_INDEX then the error
INVALID_ENUM occurs. If <format> is DEPTH_STENCIL and <type> is
not UNSIGNED_INT_24_8 then the error INVALID_ENUM occurs. Some
additional constraints on the combinations of <format> and <type>
values that are accepted is discussed below.
"Calling DrawPixels
will result in an INVALID_FRAMEBUFFER_OPERATION error if the
object bound to DRAW_FRAMEBUFFER_BINDING is not
"framebuffer complete" (see section 4.4.4.2)."
Add a row to Table 3.5, in section 3.6.4:
type Parameter GL Type Special
--------------------------- ------- -------
... ... ...
UNSIGNED_INT_2_10_10_10_REV uint Yes
UNSIGNED_INT_24_8 uint Yes
Add a row to Table 3.6, in section 3.6.4:
Format Name Element Meaning and Order Target Buffer
--------------- ------------------------- -----------------
... ... ...
DEPTH_COMPONENT Depth Depth
DEPTH_STENCIL Depth and Stencil Index Depth and Stencil
... ... ...
In section 3.6.4 "Rasterization of Pixel Rectangles", in the subsection
titled "Unpacking", update the last paragraph on page 131 to say:
"Calling DrawPixels with a <type> matching one of the types in table 3.8
is a special case in which all the components of each group are packed
into a single unsigned byte, unsigned short, or unsigned int, depending
on the type. The number of components..."
Add a row to Table 3.8, in section 3.6.4:
type Parameter GL Type Components Pixel Formats
--------------------------- ------- ---------- -------------
... ... ... ...
UNSIGNED_INT_2_10_10_10_REV uint 4 RGBA,BGRA
UNSIGNED_INT_24_8 uint 2 DEPTH_STENCIL
Add the following diagram to Table 3.11, in section 3.6.4:
UNSIGNED_INT_24_8
31 30 29 28 27 26 ... 12 11 10 9 8 7 6 5 4 3 2 1 0
+----------------------------------+---------------+
| 1st Component | 2nd Component |
+----------------------------------+---------------+
Add a row to Table 3.12, in section 3.6.4:
Format | 1st 2nd 3rd 4th
--------------+-------------------------------
... | ... ... ... ...
BGRA | blue green red alpha
DEPTH_STENCIL | depth stencil N/A N/A
In section 3.6.4 "Rasterization of Pixel Rectangles", add the
following sentence to the end of the first paragraph in "Conversion
to floating-point":
"For groups containing both components and indices, such as
DEPTH_STENCIL, the indices are not converted."
In section 3.6.4 "Rasterization of Pixel Rectangles", update the
last paragraph in the section "Conversion to Fragments" to say:
"... Groups arising from DrawPixels with a <format> of STENCIL_INDEX
or DEPTH_STENCIL are treated specially and are described in
section 4.3.1."
Update the first paragraph of section 3.6.5 "Pixel Transfer
Operations" to say:
"The GL defines five kinds of pixel groups:
1. RGBA component: Each group comprises four color components:
red, green, blue, and alpha.
2. Depth component: Each group comprises a single depth
component.
3. Color index: Each group comprises a single color index.
4. Stencil index: Each group comprises a single stencil index.
5. Depth/stencil: Each group comprises a single depth component
and a single stencil index."
In section 3.6.5 "Pixel Transfer Operations" update the first paragraph
in the subsection "Arithmetic on Components" to say:
"This step applies only to RGBA component and depth component
groups, and to the depth components in depth/stencil groups. ..."
In section 3.6.5 "Pixel Transfer Operations" update the first paragraph
in the subsection "Arithmetic on Indices" to say:
"This step applies only to color index and stencil index groups, and
to the stencil indices in depth/stencil groups. ..."
In section 3.6.5 "Pixel Transfer Operations" update the first paragraph
in the subsection "Stencil Index Lookup" to say:
"This step applies only to stencil index groups and to the stencil
indices in depth/stencil groups. ..."
Add the following to section 3.7 "Bitmaps", following the description of
Bitmap:
"Calling Bitmap will result in an
INVALID_FRAMEBUFFER_OPERATION error if the object bound to
DRAW_FRAMEBUFFER_BINDING is not "framebuffer complete"
(see section 4.4.4.2)."
In section 3.8.1 "Texture Image Specification", update the following
paragraphs as follows:
Update the fourth paragraph to say:
"The selected groups are processed exactly as for DrawPixels,
stopping just before final conversion. Each R, G, B, A, or depth
value so generated is clamped to [0, 1], while the stencil index
values are masked by 2^n-1, where n is the number of stencil bits in
the internal format resolution (see below). If the base internal
format is DEPTH_STENCIL and <format> is not DEPTH_STENCIL,
then the values of the stencil index texture component are
undefined."
Update the fifth paragraph to say:
"Components are then selected from the resulting R, G, B, A, depth,
or stencil index values to obtain a texture with the base internal
format specified by (or derived from) <internalformat>. Table 3.15
summarizes the mapping of R, G, B, A, depth, or stencil values to
texture components, as a function of the base internal format of the
texture image. <internalformat> may be specified as one of the
eight internal format symbolic constants listed in table 3.15, as
one of ..."
Update the sixth paragraph to say:
"Textures with a base internal format of DEPTH_COMPONENT or
DEPTH_STENCIL are supported by texture image specification
commands only if <target> is TEXTURE_1D, TEXTURE_2D,
PROXY_TEXTURE_1D or PROXY_TEXTURE_2D. Using these formats in
conjunction with any other <target> will result in an
INVALID_OPERATION error."
Update the seventh paragraph to say:
Textures with a base internal format of DEPTH_COMPONENT or
DEPTH_STENCIL require either depth component data or
depth/stencil component data. Textures with other base internal
formats require RGBA component data. The error INVALID_OPERATION is
generated if one of the base internal format and <format>
is DEPTH_COMPONENT or DEPTH_STENCIL, and the other is neither
of these values."
Update the tenth paragraph to say:
"...the mapping of the R, G, B, A, depth and stencil values to
texture components..."
Add a row to table 3.15 in section 3.8.1, and update the title of the
second column:
Base Internal Format RGBA and Depth and Stencil Values Internal Components
-------------------- --------------------------------- -------------------
... ... ...
DEPTH_STENCIL Depth,Stencil D,S
... ... ...
Update the caption for table 3.15
"Table 3.15: Conversion from RGBA, depth, and stencil pixel
components to internal texture, table, or filter components. See
section 3.8.13 for a description of the texture components R, G, B,
A, L, I, D, and S."
Add a new column to table 3.16, in section 3.8.1, labeled "S bits". The
value of this column is blank for all rows except a new row:
Sized Base R G B A L I D S
Internal Format InternalFormat bits bits bits bits bits bits bits bits
---------------- -------------- ---- ---- ---- ---- ---- ---- ---- ----
... ... ... ... ... ... ... ... ... ...
DEPTH24_STENCIL8 DEPTH_STENCIL 24 8
... ... ... ... ... ... ... ... ... ...
In section 3.8.2 "Alternate Texture Image Specification Commands",
update the second paragraph, in the definition of CopyTexImage2D, to
say:
"...The image is taken from the framebuffer exactly as if these
arguments were passed to CopyPixels with argument type set to COLOR
DEPTH, or DEPTH_STENCIL, depending on <internalformat>, stopping
after pixel transfer processing is complete. RGBA data is taken
from the current color buffer, while depth component and stencil
index data are taken from the depth and stencil buffers,
respectively. If depth component data is required and no depth
buffer is present, or if stencil index data is required and there is
no stencil buffer, the error INVALID_OPERATION is generated.
Subsequent processing is identical to that described for TexImage2D,
beginning with clamping of the R, G, B, A, or depth values, and
masking of the stencil index value, from the resulting pixel
groups..."
Update the third paragraph to say:
"Subsequent processing is identical to that described for TexImage2D,
beginning with clamping of the R, G, B, A, or depth values, and masking
of the stencil index values from the resulting pixel groups..."
In section 3.8.2 "Alternate Texture Image Specification Commands",
update the seventh paragraph, in the description of the
CopyTexSubImage{2|3}D arguments, to say:
"...except that the assignment of R, G, B, A, depth, and stencil
pixel group values to the texture components is controlled by the
internalformat of the texture array, not by an argument to the
command..."
Append the following to section 3.8.2 "Alternate Texture Image
Specification Commands":
"Calling CopyTexSubImage3D, CopyTexImage2D,
CopyTexSubImage2D, CopyTexImage1D or CopyTexSubImage1D will result
in an INVALID_FRAMEBUFFER_OPERATION error if the object bound
to READ_FRAMEBUFFER_BINDING is not "framebuffer complete"
(see section 4.4.4.2)."
Update section 3.8.5 "Depth Component Textures" to say:
"Depth textures and the depth components of depth/stencil textures
can be treated as LUMINANCE, INTENSITY or ALPHA textures during
texture filtering and application. The initial state for depth and
depth/stencil textures treats them as LUMINANCE textures."
In section 3.8.8 "Texture Minification", add the following text
immediately before the subsection "Mipmapping":
"If all of the following conditions are satisfied, then the value of
the selected Tau(ijk), Tau(ij), or Tau(i) in the above equations is
undefined instead of referring to the value of the texel at location
(i), (i,j), or (i,j,k). See Chapter 4 for discussion of framebuffer
objects and their attachments.
* The current DRAW_FRAMEBUFFER_BINDING names an application-created
framebuffer object <F>.
* The texture is attached to one of the attachment points, <A>, of
framebuffer object <F>.
* The value of TEXTURE_MIN_FILTER is NEAREST or LINEAR, and the value
of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point <A>
is equal to the value of TEXTURE_BASE_LEVEL
-or-
The value of TEXTURE_MIN_FILTER is NEAREST_MIPMAP_NEAREST,
NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_NEAREST, or
LINEAR_MIPMAP_LINEAR, and the value of
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point
<A> is within the inclusive range from TEXTURE_BASE_LEVEL to q."
In subsection "Automatic Mipmap Generation" to section 3.8.8,
replace the first paragraph with the following text and footnote:
"If the value of texture parameter GENERATE MIPMAP is TRUE and a
change is made to the interior or border texels of the level_base
array of a mipmap by one of the texture image specification
operations defined in sections 3.8.1 through 3.8.3, then a complete
set of mipmap arrays (as defined in section 3.8.10) will be
computed. Array levels level_base + 1 through p are replaced with
arrays derived from the modified level_base, regardless of their
previous contents. All other mipmap arrays, including the
level_base array, are left unchanged by this computation[fn1]."
"[fn1] Automatic mipmap generation is not performed for changes
resulting from rendering operations targeting a texture array
bound as a color buffer of a framebuffer object."
Add a new subsection "Manual Mipmap Generation" to section 3.8.8,
after "Automatic Mipmap Generation":
"Manual Mipmap Generation
Mipmaps can be generated manually with the command
void GenerateMipmap(enum target);
where <target> is one of TEXTURE_1D, TEXTURE_2D, TEXTURE_CUBE_MAP, or
TEXTURE_3D. Mipmap generation affects the texture image attached to
<target>. For cube map textures, an INVALID_OPERATION error is generated
if the texture bound to <target> is not cube complete, as defined in
section 3.8.10.
Mipmap generation replaces texture array levels level_base + 1
through q with arrays derived from the level_base array, as
described above under Automatic Mipmap Generation. All other mipmap
arrays, including the level_base array, are left unchanged by this
computation. For arrays in the range level_base+1 through q,
inclusive, automatic and manual mipmap generation generate the same
derived arrays, given identical level_base arrays."
Add a new section between sections 3.8.9 and 3.8.10:
"3.8.10 DEPTH_STENCIL Textures
If the texture image has a base internal format of
DEPTH_STENCIL, then the stencil index texture component is
ignored. The texture value Tau does not include a stencil index
component, but includes only the depth component."
Update the first paragraph of section 3.8.11 "Texture State and
Proxy State" to say:
"...eight integer values describing the resolutions of each of the
red, green, blue, alpha, luminance, intensity, depth, and stencil
components of the image..."
Update the second paragraph of section 3.8.11 "Texture State and
Proxy State" to say:
"... and internal format state values, as well as state for the red,
green, blue, alpha, luminance, intensity, depth, and stencil
component resolutions."
Modify the definition of DeleteTextures in section 3.8.12 "Texture
Objects", to read:
"Texture objects are deleted by calling
void DeleteTextures( sizei n, uint *textures );
textures contains n names of texture objects to be deleted. After a
texture object is deleted, it has no contents or dimensionality, and
its name is again unused. If a texture that is currently bound to
one of the targets TEXTURE 1D, TEXTURE 2D, TEXTURE 3D, or TEXTURE
CUBE MAP is deleted, it is as though BindTexture had been executed
with the same target and texture zero. Additionally, special care
must be taken when deleting a texture if any of the images of the
texture are attached to a framebuffer object. See section 4.4.2.3
for details.
Unused names in textures are silently ignored, as is the value
zero."
In section 3.8.14 "Texture Comparison Modes", update the first
paragraph of "Depth Texture Comparison Mode" subsection to say:
"If the currently bound texture's base internal format is
DEPTH_COMPONENT or DEPTH_STENCIL..."
In the section 3.8.16 "Texture Application", update the first
paragraph of to say:
"...Otherwise, a texture value is found according to the parameter
values of the currently bound texture image of the appropriate
dimensionality using the rules given in sections 3.8.6 through
3.8.9. Note that the texture value may contain R, G, B, A, L, I, or
D components, but it does not contain an S component. If the
texture's base internal format is DEPTH_STENCIL, for the
purposes of texture application, it is as if the base internal
format were DEPTH_COMPONENT..."
In section 3.11.2 "Shader Execution", in the bulleted list
in the "Texture Access" subsection to say:
"* The sampler used in a texture lookup function is not one of the
shadow sampler types, the texture object's base internal
format is DEPTH_COMPONENT or DEPTH_STENCIL, and the
TEXTURE_COMPARE_MODE is not NONE.
* The sampler used in a texture lookup function is one of the
shadow sampler types, the texture object's base
internal format is DEPTH_COMPONENT or DEPTH_STENCIL, and the
TEXTURE_COMPARE_MODE is NONE.
* The sampler used in a texture lookup function is one of the
shadow sampler types, and the texture object's base
internal format is not DEPTH_COMPONENT or DEPTH_STENCIL.
The stencil index texture internal component is ignored if the base
internal format is DEPTH_STENCIL.
If a fragment shader uses..."
Additions to Chapter 4 of the OpenGL 2.1 Specification (Per-Fragment
Operations and the Framebuffer)
In the introduction to chapter 4, modify the first
three paragraphs to read as follows:
"The framebuffer, whether it is the default framebuffer or a framebuffer
object (see section 2.1), consists of a set of pixels arranged as a
two-dimensional array.
For purposes of this
discussion, each pixel in the framebuffer is simply a set of some
number of bits. The number of bits per pixel may vary
depending on the GL implementation, the type of framebuffer
selected, and parameters specified when the framebuffer was created.
Creation and management of the default framebuffer is outside the scope
of this specification, while creation and management of framebuffer
objects is described in detail in section 4.4
Corresponding bits from each pixel in the framebuffer are grouped
together into a <bitplane>; each bitplane contains a single bit from
each pixel. These bitplanes are grouped into several <logical
buffers>. These are the color, accumulation, depth, and stencil
buffers. The color buffer actually consists of a number of buffers,
and these color buffers serve related but slightly different
purposes depending on whether the GL is bound to the default
framebuffer or a framebuffer object.
For the default framebuffer, the color buffers are the <front left>
buffer, the <front right> buffer, the <back left> buffer, the <back
right> buffer, and some number of <auxiliary> buffers. Typically, the
contents of the front buffers are displayed on a color monitor while the
contents of the back buffers are invisible. (Monoscopic contexts display
only the front left buffer; stereoscopic contexts display both the front
left and the front right buffers.) The contents of the auxiliary buffers
are never visible. All color buffers must have the same number of
bitplanes, although an implementation or context may choose not to
provide right buffers, back buffers, or auxiliary buffers at all.
Further, an implementation or context may choose not to provide
accumulation, depth, or stencil buffers. If no default framebuffer is
associated with the GL context, the framebuffer is incomplete except
when a framebuffer object is bound (see sections 4.4.1 and 4.4.4).
Framebuffer objects are not visible, and do not have any of the color
buffers present in the default framebuffer. Instead, the buffers of an
framebuffer object are specified by attaching individual textures or
renderbuffers (see section 4.4) to a set of attachment points. A
framebuffer object has an array of color buffer attachment points,
numbered zero through <n>, a depth buffer attachment point, and a
stencil buffer attachment point. In order to be used for rendering, a
framebuffer object must be complete, as described in section 4.4.4. Not
all attachments of a framebuffer object need to be populated.
Each pixel in a color buffer consists of either an unsigned integer
color index or of up to four color components. The four color components
are named R, G, B, and A, in that order; color buffers are not required
to have all four color components. R, G, B, and A components may be
represented as signed or unsigned normalized fixed-point,
floating-point, or signed or unsigned integer values; all components
must have the same representation. Each pixel in a depth buffer consists
of a single unsigned integer value in the format described in section
2.12.1 or a floating-point value. Each pixel in a stencil buffer
consists of a single unsigned integer value. Each pixel in an
accumulation buffer consists of up to four color components. If an
accumulation buffer is present, it must have at least as many bitplanes
per component as in the color buffers.
The number of bitplanes in the accumulation, color, depth, and stencil
buffers is dependent on the currently bound framebuffer. For the default
framebuffer, the number of bitplanes is fixed. For framebuffer objects,
the number of bitplanes in a given logical buffer may change if the
image attached to the corresponding attachment point changes.
The GL has two active framebuffers; the <draw framebuffer> is the
destination for rendering operations, and the <read framebuffer> is the
source for readback operations. The same framebuffer may be used for
both drawing and reading. Section 4.4.1 describes the mechanism for
controlling framebuffer usage."
The default framebuffer is initially used as the draw and read
framebuffer [fn1], and the initial state of all provided bitplanes is
undefined. The format and encoding of buffers in the draw and read
framebuffers can be queried as described in section 6.1.3.
[fn1] The window system binding API may allow associating a GL
context with two separate ``default framebuffers'' provided by
the window system as the draw and read framebuffers, but if
so, both default framebuffers are referred to by the name zero
at their respective binding points.
Add a new paragraph to the end of section 4.1.1 "Pixel Ownership Test":
"If the draw framebuffer is a framebuffer object (see section 4.2.1),
the pixel ownership test always passes, since the pixels of framebuffer
objects are owned by the GL, not the window system. If the draw
framebuffer is the default framebuffer, the window system controls pixel
ownership."
Change section 4.1.5 "Stencil Test", the fifth paragraph,
the second and third sentences, to read as follows:
"<ref> is an integer reference value that is used in the unsigned
stencil comparison. Stencil comparison operations and queries of
of <ref> clamp its value to the range [0,(2^s)-1], where <s> is the
number of bits in the stencil buffer attached to the draw framebuffer.
Replace the first three sentences of 4.1.10 "Logical Operation":
"Finally, a logical operation is applied between the incoming
fragment's color or index values and the color or index values
stored at the corresponding location in the framebuffer. The result
replaces the values in the framebuffer at the fragment's (x[w],
y[w]) coordinates. If the selected draw buffers refer to the same
framebuffer-attachable image more than once, then the values stored
in that image are undefined."
Change section 4.2.1 "Selecting a Buffer for Writing", to read as follows:
"The first such operation is controlling the buffers into which each of
the fragment color values is written. This is accomplished with either
DrawBuffer or DrawBuffers. The command
void DrawBuffer( enum buf );
defines the set of color buffers to which fragment color zero is
written. <buf> must be one of the values from tables 4.4 or 10.nnn. In
addition, acceptable values for <buf> depend on whether the GL is using
the default framebuffer (i.e., DRAW_FRAMEBUFFER_BINDING is zero), or a
framebuffer object (i.e., DRAW_FRAMEBUFFER_BINDING is non-zero). In the
initial state, the GL is bound to the default framebuffer. For more
information about framebuffer objects, see section 4.4.
If the GL is bound to the default framebuffer, then
<buf> must be one the values listed in table 4.4, which summarizes
the constants and the buffers they indicate. In this case, <buf> is
a symbolic constant specifying zero, one, two, or four buffers for
writing. These constants refer to the four potentially visible
buffers front left, front right, back left, and back right, and to
the auxiliary buffers. Arguments other than AUXi that omit
reference to LEFT or RIGHT refer to both left and right buffers.
Arguments other than AUXi that omit reference to FRONT or BACK refer
to both front and back buffers. AUXi enables drawing only to
auxiliary buffer i. Each AUXi adheres to AUXi = AUX0 + i,
and i must be in the range 0 to the value of AUX_BUFFERS minus one.
If the GL is bound to a framebuffer object,
<buf> must be one of the values listed in table 10.nnn, which
summarizes the constants and the buffers they indicate. In this
case, <buf> is a symbolic constant specifying a single color buffer
for writing. Specifying COLOR_ATTACHMENTi enables drawing only
to the image attached to the framebuffer at COLOR_ATTACHMENTi.
Each COLOR_ATTACHMENTi adheres to COLOR_ATTACHMENTi =
COLOR_ATTACHMENT0 + i. The initial value of DRAW_BUFFER for
application-created framebuffer objects is COLOR_ATTACHMENT0.
Symbolic Constant Meaning
----------------- -------
NONE no buffer
COLOR_ATTACHMENTi (see caption) output fragment color to image attached
at color attachment point i
-------------------------------------------------------------------
Table 10.nnn: Arguments to DrawBuffer(s) and ReadBuffer when the
context is bound to a framebuffer object, and
the buffers they indicate. i in COLOR_ATTACHMENTi may range from
zero to the value of MAX_COLOR_ATTACHMENTS - 1.
If the GL is bound to the default framebuffer and
DrawBuffer is supplied with a constant (other than NONE) that does
not indicate any of the color buffers allocated to the GL context,
the error INVALID_OPERATION results.
If the GL is bound to a framebuffer object and <buf> is one of the
constants from table 4.4, then the error INVALID_OPERATION results.
If <buf> is COLOR_ATTACHMENT<m> and <m> is greater than or equal to
the value of MAX_COLOR_ATTACHMENTS, then the error INVALID_VALUE
results.
If DrawBuffer is supplied with a constant that is neither legal for
the default framebuffer nor an framebuffer object, then the error
INVALID_ENUM results.
DrawBuffer will set the draw buffer for fragment colors other than
zero to NONE.
The command
void DrawBuffers( sizei n, const enum *bufs );
defines the draw buffers to which all fragment colors are written.
<n> specifies the number of buffers in <bufs>. <bufs> is a pointer
to an array of symbolic constants specifying the buffer to which
each fragment color is written.
Each buffer listed in <bufs> must be one of the values from tables
10.nnn or 11.nnn. Otherwise, an INVALID_ENUM error is generated.
Further, acceptable values for the constants in <bufs> depend on
whether the GL is using the default
framebuffer (i.e., DRAW_FRAMEBUFFER_BINDING is zero), or an
framebuffer object (i.e.,
DRAW_FRAMEBUFFER_BINDING is non-zero). For more information about
framebuffer objects, see section 4.4.
symbolic front front back back aux
constant left right left right i
-------- ----- ----- ---- ----- ---
NONE
FRONT LEFT X
FRONT RIGHT X
BACK LEFT X
BACK RIGHT X
AUXi X
--------------------------------------------------
Table 11.nnn: Arguments to DrawBuffers, when the context is bound
to the default framebuffer, and the buffers that they indicate.
If the GL is bound to the default
framebuffer, then each of the constants must be one of the
values listed in table 11.nnn.
If the GL is bound to a framebuffer object,
then each of the constants must be one of the values listed in table
10.nnn.
In both cases, the draw buffers being defined correspond in order to
the respective fragment colors. The draw buffer for fragment colors
beyond <n> is set to NONE.
The maximum number of draw buffers is implementation dependent and
must be at least 1. The number of draw buffers supported can be
queried by calling GetIntegerv with the symbolic constant
MAX_DRAW_BUFFERS. An INVALID_VALUE error is generated if <n> is
greater than MAX_DRAW_BUFFERS.
Except for NONE, a buffer may not appear more then once in the array
pointed to by <bufs>. Specifying a buffer more then once will
result in the error INVALID_OPERATION.
If fixed-function fragment shading is being performed, DrawBuffers
specifies a set of draw buffers into which the fragment color is
written.
If a fragment shader writes to "gl_FragColor", DrawBuffers specifies
a set of draw buffers into which the single fragment color defined
by "gl_FragColor" is written. If a fragment shader writes to
"gl_FragData", DrawBuffers specifies a set of draw buffers into which
each of the multiple fragment colors defined by "gl_FragData" are
separately written. If a fragment shader writes to neither
"gl_FragColor" nor "gl_FragData", the values of the fragment colors
following shader execution are undefined, and may differ for each
fragment color.
For both the default framebuffer and framebuffer objects,
the constants FRONT, BACK, LEFT, RIGHT, and
FRONT_AND_BACK are not valid in the <bufs> array passed to
DrawBuffers, and will result in the error INVALID_OPERATION. This
restriction is because these constants may themselves refer to
multiple buffers, as shown in table 4.4.
If the GL is bound to the default framebuffer and
DrawBuffers is supplied with a constant (other than NONE) that does
not indicate any of the color buffers allocated to the GL context by
the window system, the error INVALID_OPERATION will be generated.
If the GL is bound to a framebuffer object and
DrawBuffers is supplied with a constant from table 11.nnn, or
COLOR_ATTACHMENTm where m is greater than or equal to the value of
MAX_COLOR_ATTACHMENTS, then the error INVALID_OPERATION results.
Indicating a buffer or buffers using DrawBuffer or DrawBuffers
causes subsequent pixel color value writes to affect the indicated
buffers.
Specifying NONE as the draw buffer for a fragment color will inhibit
that fragment color from being written to any buffer.
Monoscopic contexts include only left buffers, while stereoscopic
contexts include both left and right buffers. Likewise, single
buffered contexts include only front buffers, while double buffered
contexts include both front and back buffers. The type of context
is selected at GL initialization.
The state required to handle color buffer selection for each
framebuffer is an integer
for each supported fragment color. For the default
framebuffer, in the initial state, the draw
buffer for fragment color zero is FRONT if there are no back
buffers; otherwise it is BACK. For framebuffer
objects, in the initial state the draw buffer for fragment color zero is
COLOR_ATTACHMENT0. For both the default
framebuffer and framebuffers objects, the initial state
of draw buffers for fragment colors other then zero is NONE.
The value of the draw buffer selected for fragment color <i> can be
queried by calling GetIntegerv with the symbolic constant DRAW_BUFFERi.
DRAW_BUFFER is equivalent to DRAW_BUFFER0."
In section 4.2.2 "Fine Control of Buffer Updates", modify the beginning
of the paragraph defining <mask> for StencilMask and StencilMaskSeparate
as follows:
Modify the second to last paragraph of section 4.2.4 "The Accumulation
Buffer" as follows:
"If there is no accumulation buffer, or if the DRAW_FRAMEBUFFER
and READ_FRAMEBUFFER bindings (see section 4.4.4.2) do not refer to
the same object, or if the GL is in color index mode, Accum
generates the error INVALID_OPERATION."
Replace section 4.3.1 "Writing to the Stencil Buffer" with the following:
"4.3.1 Writing to the Stencil Buffer or to the Depth and Stencil
Buffers
The operation of DrawPixels was described in section 3.6.4, except
if the <format> argument was STENCIL_INDEX or DEPTH_STENCIL. In
this case, all operations described for DrawPixels take place, but
window (x,y) coordinates, each with the corresponding stencil index,
or depth value and stencil index, are produced in lieu of fragments.
Each coordinate-data pair is sent directly to the per-fragment
operations, bypassing the texture, fog, and antialiasing application
stages of rasterization. Each pair is then treated as a fragment
for purposes of the pixel ownership and scissor tests; all other
per-fragment operations are bypassed. Finally, each stencil index
is written to its indicated location in the framebuffer, subject to
the current front stencil mask (set with StencilMask or
StencilMaskSeparate). If a depth component is present, and if the
setting of DepthMask is not FALSE, the depth component is also
written to the framebuffer; the setting of DepthTest is ignored.
The error INVALID_OPERATION results if the <format> argument is
STENCIL_INDEX and there is no stencil buffer, or if <format> is
DEPTH_STENCIL and there is not both a depth buffer and a stencil
buffer."
Add to 4.3.2 "Reading Pixels", right before the subsection titled
"Obtaining Pixels from the Framebuffer":
"ReadPixels generates an INVALID_OPERATION error
if READ_FRAMEBUFFER_BINDING
(see section 4.4) is non-zero, the read framebuffer is framebuffer
complete, and the value of SAMPLE_BUFFERS for the read framebuffer
is greater than zero."
In section 4.3.2 "Reading Pixels", add the following paragraph
after the second paragraph of the section "Obtaining Pixels from
the Framebuffer":
"If the <format> is DEPTH_STENCIL, then values are taken from
both the depth buffer and the stencil buffer. If there is no depth
buffer or if there is no stencil buffer, then the error
INVALID_OPERATION occurs. If the <type> parameter is not
UNSIGNED_INT_24_8, then the error INVALID_ENUM occurs.
If there is a multisample buffer, then values are obtained from the
depth and stencil samples in this buffer. It is recommended that the
depth and stencil values of the centermost sample be used, though
implementations may choose any function of the depth and stencil
sample values at each pixel."
In section 4.3.2 "Reading Pixels" in the subsection "Obtaining Pixels
from the Framebuffer", modify the first two paragraphs of the
definition of ReadBuffer to read as follows:
"The command
void ReadBuffer( enum src );
takes a symbolic constant as argument. <src> must be one of the
values from tables 4.4 or 10.nnn. Otherwise, INVALID_ENUM is
generated. Further, the acceptable values for <src> depend on
whether the GL is using the default
framebuffer (i.e., READ_FRAMEBUFFER_BINDING is zero), or a
framebuffer object (i.e.,
READ_FRAMEBUFFER_BINDING is non-zero). For more information about
framebuffer objects, see section 4.4.
If the object bound to READ_FRAMEBUFFER_BINDING is not <framebuffer
complete> (as defined in section 4.4.4.2), then ReadPixels generates
the error INVALID_FRAMEBUFFER_OPERATION. If ReadBuffer is
supplied with a constant that is neither legal for the default
framebuffer, nor legal for a
framebuffer object, then the error INVALID_ENUM results.
When READ_FRAMEBUFFER_BINDING is zero, i.e. the default framebuffer,
<src> must be one of the values listed in table 4.4, including NONE.
FRONT_AND_BACK, FRONT, and LEFT refer to the front left buffer, BACK
refers to the back left buffer, and RIGHT refers to the front right
buffer. The other constants correspond directly to the buffers that they
name. If the requested buffer is missing, then the error
INVALID_OPERATION is generated. For the default framebuffer, the initial
setting for ReadBuffer is FRONT if there is no back buffer and BACK
otherwise.
When the GL is using a framebuffer object, <src> must be one of the
values listed in table 10.nnn, including NONE. In a manner analogous to
how the DRAW_BUFFERs state is handled, specifying COLOR_ATTACHMENTi
enables reading from the image attached to the framebuffer at
COLOR_ATTACHMENTi. For framebuffer objects, the initial setting for
ReadBuffer is COLOR_ATTACHMENT0.
ReadPixels generates an INVALID_OPERATION error if it attempts to select
a color buffer while READ_BUFFER is NONE.
ReadPixels obtains values from the selected buffer from each pixel
with lower left hand corner at (x+i, y+j) for (0 <= i < width) and
(0 <= j < height); this pixel is said to be the ith pixel in the jth
row. If any of these pixels lies outside of the window allocated to
the current GL context, or outside of the image attached to the
currently bound framebuffer object, then the values obtained for
those pixels are undefined. When READ_FRAMEBUFFER_BINDING is zero,
results are also undefined for individual pixels that are not owned
by the current context. Otherwise, ReadPixels obtains values from
the selected buffer, regardless of how those values were placed
there."
In section 4.3.2 "Reading Pixels", modify the last paragraph of the
subsection "Obtaining Pixels from the Framebuffer", to say:
"... If the GL is in color index mode, and <format> is not
DEPTH_COMPONENT, STENCIL_INDEX, or DEPTH_STENCIL, then the color
index is obtained at each pixel location."
In section 4.3.2 "Reading Pixels", add a paragraph at the end of the
subsection "Obtaining Pixels from the Framebuffer" immediately before
"Conversion of RGBA values":
"When READ_FRAMEBUFFER_BINDING is non-zero, the red, green, blue, and
alpha values are obtained by first reading the internal component
values of the corresponding value in the image attached to the
selected logical buffer. Internal components are converted to an
RGBA color by taking each R, G, B, and A component present according
to the base internal format of the buffer (as shown in table 3.15).
If G, B, or A values are not present in the internal format, they
are taken to be zero, zero, and one respectively.
In section 4.3.2 "Reading Pixels", update the first sentence of the
subsection "Conversion of RGBA values" to say:
"This step applies only if the GL is in RGBA mode, and then only if
<format> is neither STENCIL_INDEX, DEPTH_COMPONENT, nor
DEPTH_STENCIL."
In section 4.3.2 "Reading Pixels", update the section "Conversion
of Depth values" to say:
"This step applies only if <format> is DEPTH_COMPONENT or
DEPTH_STENCIL. Each element taken from the depth buffer is
taken to be a fixed-point value in [0,1] with m bits, where m is the
number of bits in the depth buffer (see section 2.11.1)."
Add a row to Table 4.6, in section 4.3.2 "Reading Pixels":
type Parameter Index Mask
----------------- ----------
... ...
INT 2^31-1
UNSIGNED_INT_24_8 2^8-1
Modify the first sentence of section 4.3.3 "Copying Pixels" as follows:
"CopyPixels transfers a rectangle of pixel values from one region
of the read framebuffer to another in the draw framebuffer."
In section 4.3.3 "Copying Pixels", update the second and third
paragraphs to say:
"<type> is a symbolic constant that must be one of COLOR, STENCIL,
DEPTH, or DEPTH_STENCIL, indicating that the values to be
transferred are colors, stencil values, depth values, or
depth/stencil values, respectively. The first four arguments have the
same interpretation as the corresponding arguments to ReadPixels.
Values are obtained from the framebuffer, converted (if
appropriate), then subjected to the pixel transfer operations
described in section 3.6.5, just as if ReadPixels were called with
the corresponding arguments. If the <type> is STENCIL or DEPTH,
then it is as if the <format> for ReadPixels were STENCIL_INDEX, or
DEPTH_COMPONENT, respectively. If the <type> is DEPTH_STENCIL,
then it is as if the <format> for ReadPixels were specified as
described in table 4.6b. If the <type> is COLOR, then if the GL is
in RGBA mode, it is as if the <format> were RGBA, while if the GL is
in color index mode, it is as if the <format> were COLOR_INDEX."
Add Table 4.6b:
DEPTH_BITS STENCIL_BITS format
---------- ------------ ---------------
zero zero DEPTH_STENCIL
zero non-zero DEPTH_COMPONENT
non-zero zero STENCIL_INDEX
non-zero non-zero DEPTH_STENCIL
Table 4.6b: Effective ReadPixels format for DEPTH_STENCIL
CopyPixels operation.
Add a row to Table 4.7 (page 224):
type Parameter GL Type Component Conversion ...
--------------------------- ------- ---------------------------
... ... ...
UNSIGNED_INT_2_10_10_10_REV uint c = (2^N - 1)f
UNSIGNED_INT_24_8 uint c = (2^N - 1)f (depth only)
Add the following text to section 4.3.3 "Copying Pixels", inside the
definition of CopyPixels:
"Finally, the behavior of several GL operations is specified "as if
the arguments were passed to CopyPixels." These operations include:
CopyTex{Sub}Image*, CopyColor{Sub}Table, and CopyConvolutionFilter*.
An INVALID_FRAMEBUFFER_OPERATION error will be generated if an attempt is
made to execute one of these operations, or CopyPixels, while the
object bound to READ_FRAMEBUFFER_BINDING (see section 4.4) is not
"framebuffer complete" (as defined in section 4.4.4.2).
An INVALID_OPERATION error will be generated if the object bound to
READ_FRAMEBUFFER_BINDING is "framebuffer complete" and the value
of SAMPLE_BUFFERS is greater than zero.
CopyPixels will generate an INVALID_FRAMEBUFFER_OPERATION error
if the object bound to DRAW_FRAMEBUFFER_BINDING (see section
4.4) is not "framebuffer complete".
Append to section 4.3.3 "Copying Pixels":
"The command
BlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1,
int dstX0, int dstY0, int dstX1, int dstY1,
bitfield mask, enum filter);
transfers a rectangle of pixel values from one
region of the read framebuffer to another in the draw framebuffer.
There are some important distinctions from CopyPixels, as
described below.
<mask> is the bitwise OR of a number of values indicating which
buffers are to be copied. The values are COLOR_BUFFER_BIT,
DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT, which are described in
section 4.2.3. The pixels corresponding to these buffers are
copied from the source rectangle bounded by the locations (srcX0,
srcY0) and (srcX1, srcY1), to the destination rectangle bounded by
the locations (dstX0, dstY0) and (dstX1, dstY1). The lower bounds
of the rectangle are inclusive, while the upper bounds are
exclusive.
When the color buffer is transferred, values are taken from the read
buffer of the read framebuffer and written to each of the draw buffers
of the draw framebuffer, just as with CopyPixels.
The actual region taken from the read framebuffer is limited to the
intersection of the source buffers being transferred, which may include
the color buffer selected by the read buffer, the depth buffer, and/or
the stencil buffer depending on <mask>.
The actual region written to the draw framebuffer is limited to the
intersection of the destination buffers being written, which may include
multiple draw buffers, the depth buffer, and/or the stencil buffer
depending on <mask>
Whether or not the source or destination regions are altered due to
these limits, the scaling and offset applied to pixels being transferred
is performed as though no such limits were present.
If the source and destination rectangle dimensions do not match,
the source image is stretched to fit the destination
rectangle. <filter> must be LINEAR or NEAREST and specifies the
method of interpolation to be applied if the image is
stretched. LINEAR filtering is allowed only for the color buffer;
if <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, and
filter is not NEAREST, no copy is performed and an
INVALID_OPERATION error is generated. If the source and
destination dimensions are identical, no filtering is applied. If
either the source or destination rectangle specifies a negative
width or height (X1 < X0 or Y1 < Y0),
the image is reversed in the corresponding direction.
If both the source and destination rectangles specify a negative
dimension for the same direction, no reversal is performed.
If a linear filter is selected and the rules of LINEAR sampling
would require sampling outside the bounds of a source buffer, it is
as though CLAMP_TO_EDGE texture sampling were being performed. If a
linear filter is selected and sampling would be required outside the
bounds of the specified source region, but within the bounds of a
source buffer, the implementation may choose to clamp while sampling
or not.
If the source and destination buffers are identical, and the
source and destination rectangles overlap, the result of the blit
operation is undefined.
Blit operations bypass the fragment pipeline. The only fragment
operations which affect a blit are the pixel ownership test and
the scissor test.
If a buffer is specified in <mask> and does not exist in both the
read and draw framebuffers, the corresponding bit is silently
ignored.
If the color formats of the read and draw framebuffers do not
match, and <mask> includes COLOR_BUFFER_BIT, pixel groups are
converted to match the destination format as in CopyPixels.
However, no pixel transfer operations are applied, and clamping
behaves as if CLAMP_FRAGMENT_COLOR_ARB is set to FIXED_ONLY_ARB.
Format conversion is not supported for all data types. If the read
buffer contains floating-point values and any draw buffer does not
contain floating-point values, or if the read buffer contains
non-floating-point values and any draw buffer contains
floating-point values, an INVALID_OPERATION error is generated.
Calling BlitFramebuffer will result in an
INVALID_FRAMEBUFFER_OPERATION error if the objects bound to
DRAW_FRAMEBUFFER_BINDING and READ_FRAMEBUFFER_BINDING are
not "framebuffer complete" (see section 4.4.4.2)."
Calling BlitFramebuffer will result in an INVALID_OPERATION
error if <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT
and the source and destination depth and stencil buffer formats do
not match.
If SAMPLE_BUFFERS for the read framebuffer is greater than zero and
SAMPLE_BUFFERS for the draw framebuffer is zero, the samples
corresponding to each pixel location in the source are converted to
a single sample before being written to the destination.
If SAMPLE_BUFFERS for the read framebuffer is zero and
SAMPLE_BUFFERS for the draw framebuffer is greater than zero, the
value of the source sample is replicated in each of the destination
samples.
If SAMPLE_BUFFERS for both the read and draw framebuffers are
greater than zero, and the values of SAMPLES for the read and draw
framebuffers are identical, the samples are copied without
modification from the read framebuffer to the draw framebuffer.
Otherwise, no copy is performed and an INVALID_OPERATION error is
generated. Note that the samples in the draw buffer are not
guaranteed to be at the same sample location as the read buffer,
so rendering using this newly created buffer can potentially
have geometry cracks or incorrect antialiasing. This may occur
if the sizes of the framebuffers do not match, if the
formats differ, or if the source and destination rectangles are
not defined with the same (X0,Y0) and (X1,Y1) bounds.
If SAMPLE_BUFFERS for either the read framebuffer or
draw framebuffer is greater than zero, no copy is performed and an
INVALID_OPERATION error is generated if the dimensions of the source
and destination rectangles provided to BlitFramebuffer are not
identical, or if the formats of the read and draw framebuffers are
not identical.
Add a new section "Framebuffer Objects" after section 4.3:
"4.4 Framebuffer Objects
As described in chapters 1 and 2, GL renders into (and reads values
from) a framebuffer. GL defines two classes of framebuffers:
window-system-provided framebuffers and application-created
framebuffers. For each GL context, there is a single framebuffer
provided by the window-system, and there may also be one or more
framebuffer objects created and managed by the application.
By default, the GL uses the window-system-provided framebuffer. The
storage, dimensions, allocation, and format of the images attached
to this framebuffer are managed entirely by the window-system.
Consequently, the state of the window-system-provided framebuffer,
including its images, can not be changed by the GL, nor can the
window-system-provided framebuffer itself, or its images, be deleted
by the GL.
The routines described in the following sections, however, can be
used to create, destroy, and modify the state and attachments of
application-created framebuffer objects.
Application-created framebuffer objects encapsulate the state of a
framebuffer in a similar manner to the way texture objects
encapsulate the state of a texture. In particular, a framebuffer
object encapsulates state necessary to describe a collection of
color, depth, and stencil logical buffers (accumulation and
auxiliary buffers are not allowed). For each
logical buffer, a framebuffer-attachable image can be attached to
the framebuffer to store the rendered output for that logical
buffer. Examples of framebuffer-attachable images include texture
images and renderbuffer images. Renderbuffers are described further
in section 4.4.2.1
By allowing the images of a renderbuffer to be attached to a
framebuffer, the GL provides a mechanism to support "off-screen"
rendering. Further, by allowing the images of a texture to be
attached to a framebuffer, the GL provides a mechanism to support
"render to texture".
4.4.1 Binding and Managing Framebuffer Objects
The default framebuffer for rendering and readback operations is
provided by the window system. In addition, named framebuffer
objects can be created and operated upon. The namespace for
framebuffer objects is the unsigned integers, with zero reserved
by the GL for the default framebuffer.
A framebuffer object is created by binding
a name returned by GenFramebuffers (see below) to
DRAW_FRAMEBUFFER or READ_FRAMEBUFFER. The binding is
effected by calling
void BindFramebuffer(enum target, uint framebuffer);
with <target> set to the desired framebuffer target and
<framebuffer> set to the framebuffer object name.
The resulting framebuffer
object is a new state vector, comprising all the state values
listed in table 4.nnn, as well as one set of the state values
listed in table 5.nnn for each attachment point of the
framebuffer, set to the same initial values. There are
MAX_COLOR_ATTACHMENTS color attachment points, plus one each
for the depth and stencil attachment points.
BindFramebuffer may also be used to bind an existing
framebuffer object to DRAW_FRAMEBUFFER or
READ_FRAMEBUFFER. If the bind is successful no change is made
to the state of the bound framebuffer object, and any previous
binding to <target> is broken.
BindFramebuffer fails and an INVALID_OPERATION error is generated if
<framebuffer> is not zero or a name returned from a previous call to
GenFramebuffers, or if such a name has since been deleted with
DeleteFramebuffers.
If a framebuffer object is bound to DRAW_FRAMEBUFFER or
READ_FRAMEBUFFER, it becomes the target for rendering or
readback operations, respectively, until it is deleted or another
framebuffer is bound to the corresponding bind point. Calling
BindFramebuffer with <target> set to FRAMEBUFFER binds the
framebuffer to both the draw and read targets.
While a framebuffer object is bound, GL operations on the target
to which it is bound affect the images attached to the bound
framebuffer object, and queries of the target to which it is bound
return state from the bound object. Queries of the values
specified in table 6.31 (Implementation Dependent Pixel Depths)
and table 8.nnn (Framebuffer-Dependent State Variables) are
derived from the framebuffer object bound to DRAW_FRAMEBUFFER.
The initial state of DRAW_FRAMEBUFFER and READ_FRAMEBUFFER
refers to the default framebuffer.
In order that access to the default framebuffer is not
lost, it is treated as a framebuffer object with the name of zero.
The default framebuffer is therefore rendered to and read from
while zero is bound to the corresponding targets. On some
implementations, the properties of the default framebuffer can
change over time (e.g., in response to window system events
such as attaching the context to a new window system drawable.)
Framebuffer objects (those with a non-zero
name) differ from the default framebuffer in
a few important ways. First and foremost, unlike the
default framebuffer, framebuffer objects
have modifiable attachment points for each logical buffer in the
framebuffer. Framebuffer-attachable images can be attached to and
detached from these attachment points, which are described further
in section 4.4.2. Also, the size and format of the images attached
to application-created framebuffers are controlled entirely within
the GL interface, and are not affected by window system events, such
as pixel format selection, window resizes, and display mode changes.
Additionally, when rendering to or reading from an application
created-framebuffer object,
- The pixel ownership test always succeeds. In other words,
framebuffer objects own all of their pixels.
- There are no visible color buffer bitplanes. This means
there is no color buffer corresponding to the back, front,
left, or right color bitplanes.
- The only color buffer bitplanes are the ones defined by the
framebuffer attachment points named COLOR_ATTACHMENT0
through COLOR_ATTACHMENTn.
- The only depth buffer bitplanes are the ones defined by the
framebuffer attachment point DEPTH_ATTACHMENT.
- The only stencil buffer bitplanes are the ones defined by
the framebuffer attachment point STENCIL_ATTACHMENT.
- There are no accum buffer bitplanes, so the value of the
implementation-dependent state variables ACCUM_RED_BITS,
ACCUM_GREEN_BITS, ACCUM_BLUE_BITS, and ACCUM_ALPHA_BITS, are
all zero.
- There are no AUX buffer bitplanes, so the value of the
implementation-dependent state variable AUX_BUFFERS is zero.
- If the attachment sizes are not all identical, rendering will be
limited to the largest area that can fit in all of the
attachments (i.e. an intersection of rectangles having a lower
left of (0,0) and an upper right of (width,height) for each
attachment)
- If the attachment sizes are not all identical, the values of
pixels outside the common intersection area after rendering are
undefined.
Framebuffer objects are deleted by calling
void DeleteFramebuffers(sizei n, uint *framebuffers);
<framebuffers> contains <n> names of framebuffer objects to be
deleted. After a framebuffer object is deleted, it has no
attachments, and its name is again unused. If a framebuffer that
is currently bound to one or more of the targets
DRAW_FRAMEBUFFER or READ_FRAMEBUFFER is deleted, it is as
though BindFramebuffer had been executed with the corresponding
<target> and <framebuffer> zero. Unused names in
<framebuffers> are silently ignored, as is the value zero.
The command
void GenFramebuffers(sizei n, uint *ids);
returns <n> previously unused framebuffer object names in <ids>.
These names are marked as used, for the purposes of
GenFramebuffers only, but they acquire state and type only when
they are first bound, just as if they were unused.
The names bound to the draw and read framebuffer bindings can be
queried by calling GetIntegerv with the symbolic constants
DRAW_FRAMEBUFFER_BINDING and READ_FRAMEBUFFER_BINDING
respectively. FRAMEBUFFER_BINDING is equivalent to
DRAW_FRAMEBUFFER_BINDING.
4.4.2 Attaching Images to Framebuffer Objects
Framebuffer-attachable images may be attached to, and detached from,
framebuffer objects. In contrast, the image
attachments of the default framebuffer may not be
changed by the GL.
A single framebuffer-attachable image may be attached to multiple
framebuffer objects, potentially avoiding some
data copies, and possibly decreasing memory consumption.
For each logical buffer, a framebuffer object stores a set of
state which defines the logical buffer's <attachment point>. The
attachment point state contains enough information to identify the
single image attached to the attachment point, or to indicate that
no image is attached. The per-logical buffer attachment point
state is listed in table 5.nnn
There are two types of framebuffer-attachable images: the image of a
renderbuffer object, and an image of a texture object.
4.4.2.1 Renderbuffer Objects
A renderbuffer is a data storage object containing a single image of
a renderable internal format. GL provides the methods described
below to allocate and delete a renderbuffer's image, and to attach a
renderbuffer's image to a framebuffer object.
The name space for renderbuffer objects is the unsigned integers,
with zero reserved for the GL. A renderbuffer object is created by
binding a name returned by GenRenderbuffers (see below)
to RENDERBUFFER. The binding is effected by calling
void BindRenderbuffer( enum target, uint renderbuffer );
with <target> set to RENDERBUFFER and <renderbuffer> set to the
unused name. If <renderbuffer> is not zero, then the resulting
renderbuffer object is a new state vector, initialized with a
zero-sized memory buffer, and comprising the state values listed in
Table 8.nnn. Any previous binding to <target> is broken.
BindRenderbuffer may also be used to bind an existing
renderbuffer object. If the bind is successful, no change is made
to the state of the newly bound renderbuffer object, and any
previous binding to <target> is broken.
While a renderbuffer object is bound, GL operations on the target to
which it is bound affect the bound renderbuffer object, and queries
of the target to which a renderbuffer object is bound return state
from the bound object.
The name zero is reserved. A renderbuffer object cannot be created
with the name zero. If <renderbuffer> is zero, then any previous
binding to <target> is broken and the <target> binding is restored
to the initial state.
In the initial state, the reserved name zero is bound to
RENDERBUFFER. There is no renderbuffer object corresponding to
the name zero, so client attempts to modify or query renderbuffer
state for the target RENDERBUFFER while zero is bound will
generate GL errors, as described in section 6.1.3.
The current RENDERBUFFER binding can be determined by calling
GetIntegerv with the symbolic constant RENDERBUFFER_BINDING.
BindRenderbuffer fails and an INVALID_OPERATION error is generated
if <renderbuffer> is not a name returned from a previous call to
GenRenderbuffers, or if such a name has since been deleted with
DeleteRenderbuffers.
Renderbuffer objects are deleted by calling
void DeleteRenderbuffers( sizei n, const uint *renderbuffers );
where <renderbuffers> contains <n> names of renderbuffer objects to be
deleted. After a renderbuffer object is deleted, it has no
contents, and its name is again unused. If a renderbuffer that is
currently bound to RENDERBUFFER is deleted, it is as though
BindRenderbuffer had been executed with the <target>
RENDERBUFFER and <name> of zero. Additionally, special care
must be taken when deleting a renderbuffer if the image of the
renderbuffer is attached to a framebuffer object (see section
4.4.2.2 for details). Unused names in <renderbuffers> are silently
ignored, as is the value zero.
The command
void GenRenderbuffers( sizei n, uint *renderbuffers );
returns <n> previously unused renderbuffer object names in
<renderbuffers>. These names are marked as used, for the purposes
of GenRenderbuffers only, but they acquire renderbuffer state
only when they are first bound, just as if they were unused.
The command
void RenderbufferStorageMultisample(enum target, sizei samples,
enum internalformat,
sizei width, sizei height);
establishes the data storage, format, dimensions, and number of
samples of a renderbuffer object's image. <target> must be
RENDERBUFFER. <internalformat> must be color-renderable, depth-
renderable, or stencil-renderable (as defined in section 4.4.4).
<width> and <height> are the dimensions in pixels of the renderbuffer.
If either <width> or <height> is greater than MAX_RENDERBUFFER_SIZE,
or if <samples> is greater than MAX_SAMPLES,
then the error INVALID_VALUE is
generated. If the GL is unable to create a data store of the
requested size, the error OUT_OF_MEMORY is generated.
Upon success, RenderbufferStorageMultisample deletes any existing
data store for the renderbuffer image and the contents of the data
store after calling RenderbufferStorageMultisample are undefined.
RENDERBUFFER_WIDTH is set to <width>, RENDERBUFFER_HEIGHT is
set to <height>, and RENDERBUFFER_INTERNAL_FORMAT is set to
<internalformat>.
If <samples> is zero, then RENDERBUFFER_SAMPLES is set to zero.
Otherwise <samples> represents a request for a desired minimum
number of samples. Since different implementations may support
different sample counts for multisampled rendering, the actual
number of samples allocated for the renderbuffer image is
implementation dependent. However, the resulting value for
RENDERBUFFER_SAMPLES is guaranteed to be greater than or equal
to <samples> and no more than the next larger sample count supported
by the implementation.
Sized Base S
Internal Format Internal format Bits
--------------- --------------- ----
STENCIL_INDEX1 STENCIL_INDEX 1
STENCIL_INDEX4 STENCIL_INDEX 4
STENCIL_INDEX8 STENCIL_INDEX 8
STENCIL_INDEX16 STENCIL_INDEX 16
----------------------------------------------------------------
Table 2.nnn Desired component resolution for each sized internal
format that can be used only with renderbuffers.
A GL implementation may vary its allocation of internal component
resolution based on any RenderbufferStorage parameter (except
target), but the allocation and chosen internal format must not be a
function of any other state and cannot be changed once they are
established.
The command
void RenderbufferStorage(enum target, enum internalformat,
sizei width, sizei height);
is equivalent to calling RenderbufferStorageMultisample with
<samples> equal to zero."
4.4.2.2 Attaching Renderbuffer Images to a Framebuffer
A renderbuffer can be attached as one of the logical buffers of the
currently bound framebuffer object by calling
void FramebufferRenderbuffer(enum target,
enum attachment,
enum renderbuffertarget,
uint renderbuffer);
<target> must be DRAW_FRAMEBUFFER, READ_FRAMEBUFFER, or
FRAMEBUFFER. FRAMEBUFFER is equivalent to
DRAW_FRAMEBUFFER.
An INVALID_OPERATION error is generated if the value of the
corresponding binding is zero. <attachment> should be set to
one of the attachment points of the framebuffer listed in table
1.nnn. <renderbuffertarget> must be RENDERBUFFER and
<renderbuffer> should be set to the name of the renderbuffer object
to be attached to the framebuffer. <renderbuffer> must be either
zero or the name of an existing renderbuffer object of type
<renderbuffertarget>, otherwise an INVALID_OPERATION error is
generated. If <renderbuffer> is zero, then the value of
<renderbuffertarget> is ignored.
If <renderbuffer> is not zero and if FramebufferRenderbuffer is
successful, then the renderbuffer named <renderbuffer> will be used
as the logical buffer identified by <attachment> of the framebuffer
currently bound to <target>. The value of
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for the specified attachment
point is set to RENDERBUFFER and the value of
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is set to <renderbuffer>. All
other state values of the attachment point specified by <attachment>
are set to their default values listed in table 5.nnn. No change is
made to the state of the renderbuffer object and any previous
attachment to the <attachment> logical buffer of the framebuffer
object bound to framebuffer <target> is broken. If
the attachment is not successful, then no change is made to
the state of either the renderbuffer object or the framebuffer
object.
Calling FramebufferRenderbuffer with the <renderbuffer> name zero
will detach the image, if any, identified by <attachment>, in the
framebuffer currently bound to <target>. All state values of the
attachment point specified by <attachment> in the object bound to
<target> are set to their default values listed in table 5.nnn.
Setting <attachment> to the value DEPTH_STENCIL_ATTACHMENT is a
special case causing both the depth and stencil attachments of the
framebuffer object to be set to <renderbuffer>, which should have
base internal format DEPTH_STENCIL.
If a renderbuffer object is deleted while its image is attached to
one or more attachment points in the currently bound framebuffer,
then it is as if FramebufferRenderbuffer had been called, with
a <renderbuffer> of 0, for each attachment point to which this image
was attached in the currently bound framebuffer. In other words,
this renderbuffer image is first detached from all attachment points
in the currently bound framebuffer. Note that the renderbuffer
image is specifically *not* detached from any non-bound
framebuffers. Detaching the image from any non-bound framebuffers
is the responsibility of the application.
Name of attachment
-----------------------------------------------------
COLOR_ATTACHMENTi (see caption)
DEPTH_ATTACHMENT
STENCIL_ATTACHMENT
DEPTH_STENCIL_ATTACHMENT
-----------------------------------------------------
Table 1.nnn: Framebuffer attachment points. <i> in
COLOR_ATTACHMENTi may range from zero to the value of
MAX_COLOR_ATTACHMENTS - 1.
4.4.2.3 Attaching Texture Images to a Framebuffer
GL supports copying the rendered contents of the framebuffer into
the images of a texture object through the use of the routines
CopyTexImage{1D|2D}, and CopyTexSubImage{1D|2D|3D}. Additionally,
GL supports rendering directly into the images of a texture object.
To render directly into a texture image, a specified image from a
texture object can be attached as one of the logical buffers of the
currently bound framebuffer object by calling one of the following
routines, depending on the type of the texture:
void FramebufferTexture1D(enum target, enum attachment,
enum textarget, uint texture,
int level);
void FramebufferTexture2D(enum target, enum attachment,
enum textarget, uint texture,
int level);
void FramebufferTexture3D(enum target, enum attachment,
enum textarget, uint texture,
int level, int layer);
In all three routines, <target> must be DRAW_FRAMEBUFFER,
READ_FRAMEBUFFER or FRAMEBUFFER. FRAMEBUFFER is
equivalent to DRAW_FRAMEBUFFER.
An INVALID_OPERATION error is generated if the
value of the corresponding binding is zero.
<attachment> must be one of the attachment points of the
framebuffer listed in table 1.nnn.
If <texture> is zero, the image identified by <attachment>, if
any, will be detached from the framebuffer currently bound to
<target>. <textarget>, <level>, and <layer> are ignored. All
state values of the attachment point specified by <attachment> are
set to their default values listed in table 5.nnn.
If <texture> is not zero, then <texture> must either name an existing
texture object with an target of <textarget>, or <texture> must name an
existing cube map texture and <textarget> must be one of
TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y,
TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X,
TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z. Otherwise,
an INVALID_OPERATION error is generated.
<level> specifies the mipmap level of the texture image to be
attached to the framebuffer.
If <textarget> is TEXTURE_RECTANGLE_ARB, then <level> must be zero.
If <textarget> is TEXTURE_3D, then <level> must be greater than or
equal to zero and less than or equal to log base 2 of the value of
MAX_3D_TEXTURE_SIZE. If <textarget> is one of
TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y,
TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X,
TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z, then
<level> must be greater than or equal to zero and less than or equal
to log base 2 of the value of MAX_CUBE_MAP_TEXTURE_SIZE. For all other
values of <textarget>, <level> must be greater than or equal to zero and
no larger than log base 2 of the value of MAX_TEXTURE_SIZE. Otherwise,
an INVALID_VALUE error is generated.
<layer> specifies the layer of a 2-dimensional image within a
3-dimensional texture. An INVALID_VALUE error is generated if
<layer> is larger than the value of MAX_3D_TEXTURE_SIZE-1.
For FramebufferTexture1D, if <texture> is not zero, then
<textarget> must be TEXTURE_1D.
For FramebufferTexture2D, if <texture> is not zero, then
<textarget> must be one of TEXTURE_2D, TEXTURE_RECTANGLE_ARB,
TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y,
TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X,
TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z.
For FramebufferTexture3D, if <texture> is not zero, then
<textarget> must be TEXTURE_3D.
If <texture> is not zero, and if FramebufferTexture{1D|2D|3D} is
successful, then the specified texture image will be used as the
logical buffer identified by <attachment> of the framebuffer
currently bound to <target>. The value of
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for the specified attachment
point is set to TEXTURE and the value of
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is set to <texture>.
Additionally, the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for
the named attachment point is set to <level>. If <texture> is a
cube map texture, then the value of
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE the named attachment
point is set to <textarget>. If <texture> is a 3D texture, then the
value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER for the named
attachment point is set to <layer>. All other state values of the
attachment point specified by <attachment> are set to their default
values listed in table 5.nnn. No change is made to the state of the
texture object, and any previous attachment to the <attachment>
logical buffer of the framebuffer object bound to framebuffer
<target> is broken. If the attachment is not
successful, then no change is made to the state of either the
texture object or the framebuffer object.
Setting <attachment> to the value DEPTH_STENCIL_ATTACHMENT is a
special case causing both the depth and stencil attachments of the
framebuffer object to be set to <texture>. <texture> must have base
internal format DEPTH_STENCIL, or the depth and stencil
framebuffer attachments will be incomplete (see section 4.4.4.1).
The command
void FramebufferTextureLayer(enum target,enum attachment,
uint texture,int level,int layer);
operates identically to FramebufferTexture3D, except that it
attaches a single layer of a three-dimensional texture, or one- or
two-dimensional array texture. <layer> is an integer indicating the
layer number, and is treated identically to the <layer> parameter in
FramebufferTexture3D. The error INVALID_VALUE is generated if
<layer> is negative. The error INVALID_OPERATION is generated if
<texture> is non-zero and is not the name of a three dimensional
texture, or one- or two-dimensional array texture.
Unlike FramebufferTexture3D, no <textarget> parameter is accepted.
If <texture> is non-zero and the command does not result in an
error, the framebuffer attachment state corresponding to
<attachment> is updated as in the other FramebufferTexture commands,
except that FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER is set to
<layer>.
If a texture object is deleted while its image is attached to one or
more attachment points in the currently bound framebuffer, then it
is as if FramebufferTexture* had been called, with a <texture> of
zero, for each attachment point to which this image was attached in
the currently bound framebuffer. In other words, this texture image
is first detached from all attachment points in the currently bound
framebuffer. Note that the texture image is specifically *not*
detached from any other framebuffer objects. Detaching the texture
image from any other framebuffer objects is the responsibility of
the application.
4.4.3 Rendering When an Image of a Bound Texture Object is Also
Attached to the Framebuffer
The mechanisms for attaching textures to a framebuffer object do not
prevent a one- or two-dimensional texture level, a face of a cube
map texture level, or a layer of a two-dimensional array or
three-dimensional texture from being attached to the draw
framebuffer while the same texture is bound to a texture unit. While
any of these conditions hold, texturing operations accessing that
image will produce undefined results, as described at the end of
section 3.8.8. Conditions resulting in such undefined behavior are
defined in more detail below. Such undefined texturing operations
are likely to leave the final results of the shader or
fixed-function fragment processing operations undefined, and should
be avoided.
Special precautions need to be taken to avoid attaching a texture
image to the currently bound framebuffer while the texture object is
currently bound and enabled for texturing. Doing so could lead to
the creation of a <feedback loop> between the writing of pixels by
the GL's rendering operations and the simultaneous reading of those
same pixels when used as texels in the currently bound texture. In
this scenario, the framebuffer will be considered framebuffer
complete (see section 4.4.4), but the values of fragments rendered
while in this state will be undefined. The values of texture
samples may be undefined as well, as described at the end of the
"Scale Factor and Level of Detail" subsection of section 3.8.8.
Specifically, the values of rendered fragments are undefined if all
of the following conditions are true:
- an image from texture object <T> is attached to the currently
bound framebuffer at attachment point <A>, and
- the texture object <T> is currently bound to a texture unit
<U>, and
- the current fixed-function texture state or programmable
vertex and/or fragment processing state makes it possible(*)
to sample from the texture object <T> bound to texture unit
<U>
while either of the following conditions are true:
- the value of TEXTURE MIN FILTER for texture object <T> is
NEAREST or LINEAR, and the value of
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point
<A> is equal to the value of TEXTURE_BASE_LEVEL for the
texture object <T>, or
- the value of TEXTURE_MIN_FILTER for texture object <T> is one
of NEAREST_MIPMAP_NEAREST, NEAREST_MIPMAP LINEAR, LINEAR
MIPMAP_NEAREST, or LINEAR_MIPMAP_LINEAR, and the value of
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point
<A> is within the range specified by the current values of
TEXTURE_BASE_LEVEL to q, inclusive, for the texture object
<T>. (q is defined in the Mipmapping discussion of section
3.8.8),
(*) For the purpose of this discussion, it is <possible>
to sample from the texture object <T> bound to texture unit <U>
if any of the following are true:
- Programmable vertex and fragment processing is disabled
and the target of texture object <T> is enabled according
to the texture target precedence rules of section 3.8.15
- FRAGMENT_PROGRAM_ARB is enabled and the currently bound
fragment program contains any instructions that
sample from the texture object <T> bound to <U>
- The active fragment or vertex shader contains any instructions
that might sample from the texture object <T> bound to <U> if even
those instructions might only be executed conditionally.
Note that if TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL exclude any
levels containing image(s) attached to the currently bound
framebuffer, then the above conditions will not be met, (i.e., the
above rule will not cause the values of rendered fragments to be
undefined.)
4.4.4 Framebuffer Completeness
A framebuffer must be <framebuffer complete> to effectively be used
as the draw or read framebuffer of the GL.
The default framebuffer is always complete if it exists; however, if no
default framebuffer exists (no window system-provided drawable is
associated with the GL context), it is deemed to be incomplete.
A framebuffer object is said to be framebuffer complete if all of
its attached images, and all framebuffer parameters required to
utilize the framebuffer for rendering and reading, are consistently
defined and meet the requirements defined below. The rules of
framebuffer completeness are dependent on the properties of the
attached images, and on certain implementation dependent
restrictions.
The internal formats of the attached images can affect the
completeness of the framebuffer, so it is useful to first define the
relationship between the internal format of an image and the
attachment points to which it can be attached.
* The following base internal formats from table 3.15 are
<color-renderable>: ALPHA, LUMINANCE, LUMINANCE_ALPHA,
INTENSITY, RED, RG, RGB, RGBA, FLOAT_R_NV, FLOAT_RG_NV,
FLOAT_RGB_NV, and FLOAT_RGBA_NV. The sized
internal formats from table 3.16 that have a color-renderable
base internal format are also color-renderable. No other
formats, including compressed internal formats, are
color-renderable.
* An internal format is <depth-renderable> if it is
DEPTH_COMPONENT or one of the formats from table 3.16 whose
base internal format is DEPTH_COMPONENT or DEPTH_STENCIL.
No other formats are depth-renderable.
* An internal format is <stencil-renderable> if it is
STENCIL_INDEX or DEPTH_STENCIL, if it is one of the
STENCIL_INDEX formats from table 2.nnn, or if it is one of the
formats from table 3.16 whose base internal format is
DEPTH_STENCIL. No other formats are stencil-renderable."
4.4.4.1 Framebuffer Attachment Completeness
If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for the
framebuffer attachment point <attachment> is not NONE, then it is
said that a framebuffer-attachable image, named <image>, is attached
to the framebuffer at the attachment point. <image> is identified
by the state in <attachment> as described in section 4.4.2.
The framebuffer attachment point <attachment> is said to be
<framebuffer attachment complete> if the value of
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for <attachment> is NONE
(i.e., no image is attached), or if all of the following conditions
are true:
* <image> is a component of an existing object with the name
specified by FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, and of the
type specified by FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE.
* The width and height of <image> must be non-zero.
* If FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME names a 3-dimensional
texture, then FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER must be
smaller than the depth of the texture.
* If <attachment> is COLOR_ATTACHMENTi, then <image> must have
a color-renderable internal format.
* If <attachment> is DEPTH_ATTACHMENT, then <image> must have
a depth-renderable internal format.
* If <attachment> is STENCIL_ATTACHMENT, then <image> must
have a stencil-renderable internal format.
4.4.4.2 Whole Framebuffer Completeness
Each rule below is followed by an error enum enclosed in { brackets }.
The meaning of these errors is explained below and under ``Effects of
Framebuffer Completeness on Framebuffer Operations'' later in section
4.4.4.
The framebuffer object <target> is said to be "framebuffer complete" if
all the following conditions are true:
* <target> is the default framebuffer, and the default framebuffer
exists.
{ FRAMEBUFFER_UNDEFINED }
* All framebuffer attachment points are framebuffer attachment
complete.
{ FRAMEBUFFER_INCOMPLETE_ATTACHMENT }
* There is at least one image attached to the framebuffer.
{ FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT }
* The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE must not be
NONE for any color attachment point(s) named by DRAW_BUFFERi.
{ FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER }
* If READ_BUFFER is not NONE, then the value of
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE must not be NONE for the
color attachment point named by READ_BUFFER.
{ FRAMEBUFFER_INCOMPLETE_READ_BUFFER }
* The combination of internal formats of the attached
images does not violate an implementation-dependent set of
restrictions.
{ FRAMEBUFFER_UNSUPPORTED }
* The value of RENDERBUFFER_SAMPLES is the same for all attached
images.
{ FRAMEBUFFER_INCOMPLETE_MULTISAMPLE }
The token in { brackets } after each clause of the framebuffer
completeness rules specifies the return value of
CheckFramebufferStatus (see below) that is generated when that
clause is violated. If more than one clause is violated, it is
implementation-dependent exactly which value will be returned by
CheckFramebufferStatus.
Performing any of the following actions may change whether the
framebuffer is considered complete or incomplete.
- Binding to a different framebuffer with BindFramebuffer.
- Attaching an image to the framebuffer with
FramebufferTexture{1D|2D|3D} or FramebufferRenderbuffer.
- Detaching an image from the framebuffer with
FramebufferTexture{1D|2D|3D} or FramebufferRenderbuffer.
- Changing the internal format of a texture image that is attached
to the framebuffer by calling {Copy|Compressed}TexImage{1D|2D|3D}.
- Changing the internal format of a renderbuffer that is attached
to the framebuffer by calling RenderbufferStorage.
- Deleting, with DeleteTextures or DeleteRenderbuffers, an object
containing an image that is attached to a framebuffer object
that is bound to the framebuffer.
- Changing READ_BUFFER or one of the DRAW_BUFFERS.
- Associating a different window system-provided drawable, or no
drawable, with the default framebuffer using a window system binding
API such as GLX, WGL, CGL, or EGL.
Although GL defines a wide variety of internal formats for
framebuffer-attachable images, such as texture images and
renderbuffer images, some implementations may not support rendering
to particular combinations of internal formats. If the combination
of formats of the images attached to a framebuffer object are not
supported by the implementation, then the framebuffer is not
complete under the clause labeled FRAMEBUFFER_UNSUPPORTED. There
must exist, however, at least one combination of internal formats
for which the framebuffer cannot be FRAMEBUFFER_UNSUPPORTED.
Because of the <implementation-dependent> clause of the framebuffer
completeness test in particular, and because framebuffer
completeness can change when the set of attached images is modified,
it is strongly advised, though is not required, that an application
check to see if the framebuffer is complete prior to rendering. The
status of the framebuffer object currently bound to <target> can be
queried by calling
enum CheckFramebufferStatus(enum target);
<target> must be DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or
FRAMEBUFFER. FRAMEBUFFER is equivalent to DRAW_FRAMEBUFFER.
If CheckFramebufferStatus is called within a Begin/End pair,
an INVALID_OPERATION error is generated. If
CheckFramebufferStatus generates an error, 0 is returned.
Otherwise, an enum is returned that identifies whether
or not the framebuffer bound to <target> is complete, and if not
complete the enum identifies one of the rules of framebuffer
completeness that is violated. If the framebuffer is complete, then
FRAMEBUFFER_COMPLETE is returned.
The values of SAMPLE_BUFFERS and SAMPLES are derived from the
attachments of the currently bound framebuffer object. If the
current DRAW_FRAMEBUFFER_BINDING is not framebuffer complete,
then both SAMPLE_BUFFERS and SAMPLES are undefined. Otherwise,
SAMPLES is equal to the value of RENDERBUFFER_SAMPLES for the
attached images (which all must have the same value for
RENDERBUFFER_SAMPLES). Further, SAMPLE_BUFFERS is one if
SAMPLES is non-zero. Otherwise, SAMPLE_BUFFERS is zero.
4.4.4.3 Effects of Framebuffer Completeness on Framebuffer Operations
Attempting to render to or read from a framebuffer which is not
framebuffer complete will generate an INVALID_FRAMEBUFFER_OPERATION
error. This means that rendering commands such as Begin,
RasterPos, any command that performs an implicit Begin, as well as
commands that read the framebuffer such as ReadPixels and
CopyTex{Sub}Image will generate the error
INVALID_FRAMEBUFFER_OPERATION if called while the framebuffer is
not framebuffer complete.
4.4.5 Effects of Framebuffer State on Framebuffer Dependent Values
The values of the state variables listed in table 9.nnn (Framebuffer
Dependent Values) may change when a change is made to
DRAW_FRAMEBUFFER_BINDING, to the state of the currently bound
framebuffer object, or to an image attached to the currently bound
framebuffer object.
When DRAW_FRAMEBUFFER_BINDING is zero, the values of the state
variables listed in table 9.nnn are implementation defined.
When DRAW_FRAMEBUFFER_BINDING is non-zero, if the currently bound
framebuffer object is not framebuffer complete, then the values of
the state variables listed in table 9.nnn are undefined.
When DRAW_FRAMEBUFFER_BINDING is non-zero and the currently bound
framebuffer object is framebuffer complete, then the values of the
state variables listed in table 9.nnn are completely determined by
DRAW_FRAMEBUFFER_BINDING, the state of the currently bound
framebuffer object, and the state of the images attached to the
currently bound framebuffer object.
The values of RED_BITS, GREEN_BITS, BLUE_BITS, and ALPHA_BITS are
defined only if all color attachments of the draw framebuffer have
identical formats, in which case the color component depths of color
attachment zero are returned. The values returned for DEPTH_BITS and
STENCIL_BITS are the depth or stencil component depth of the
corresponding attachment of the draw framebuffer, respectively. The
actual sizes of the color, depth, or stencil bit planes can be
obtained by querying an attachment point using
GetFramebufferAttachmentParameteriv,
or querying the object attached at that point. If the value of
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE at a particular attachment
point is RENDERBUFFER, the sizes may be determined by calling
GetRenderbufferParameteriv as described in section 6.1.3. If
the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE at a particular
attachment point is TEXTURE, the sizes may be determined by calling
GetTexParameter, as described in section 6.1.3.
4.4.6 Mapping between Pixel and Element in Attached Image
When DRAW_FRAMEBUFFER_BINDING is non-zero, an operation that writes
to the framebuffer modifies the image attached to the selected
logical buffer, and an operation that reads from the framebuffer
reads from the image attached to the selected logical buffer.
If the attached image is a renderbuffer image, then the window
coordinates (x[w], y[w]) corresponds to the value in the
renderbuffer image at the same coordinates.
If the attached image is a texture image, then the window
coordinates (x[w], y[w]) correspond to the texel (i, j, k), from
figure 3.10 as follows:
i = (x[w] - b)
j = (y[w] - b)
k = (layer - b)
where <b> is the texture image's border width, and <layer> is the
value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER for the selected
logical buffer. For a two-dimensional texture, <k> and <layer> are
irrelevant; for a one-dimensional texture, <j>, <k>, and <layer> are
both irrelevant.
(x[w], y[w]) corresponds to a border texel if x[w], y[w], or
<layer> is less than the border width, or if x[w], y[w], or <layer>
is greater than or equal to the border width plus the width or height or
depth, respectively, of the texture image.
Conversion to Framebuffer-Attachable Image Components
When an enabled color value is written to the framebuffer while the
draw framebuffer binding is non-zero, for each draw buffer the R, G, B,
and A values are converted to internal components as described in
table 3.15, according to the table row corresponding to the internal
format of the framebuffer-attachable image attached to the selected
logical buffer, and the resulting internal components are written to
the image attached to logical buffer. The masking operations
described in section 4.2.2 are also effective.
Conversion to RGBA Values
When a color value is read or is used as the source of a logical
operation or blending while the read framebuffer binding is non-zero,
the components of the framebuffer-attachable image that is attached to
the logical buffer selected by READ_BUFFER are first converted to R, G,
B, and A values according to table 3.21 and the internal format of the
attached image."
Additions to Chapter 5 of the OpenGL 2.1 Specification (Special Functions)
Added to section 5.4, as part of the discussion of which commands
are not compiled into display lists:
"Certain commands, when called while compiling a display list, are
not compiled into the display list but are executed immediately.
These are: ..., GenFramebuffers, BindFramebuffer,
DeleteFramebuffers, CheckFramebufferStatus,
GenRenderbuffers, BindRenderbuffer, DeleteRenderbuffers,
RenderbufferStorage, RenderbufferStorageMultisample,
FramebufferTexture1D, FramebufferTexture2D,
FramebufferTexture3D, FramebufferRenderbuffer, BlitFramebuffer,
GenerateMipmap..."
Additions to Chapter 6 of the OpenGL 2.1 Specification (State and State
Requests)
In section 6.1.3 "Enumerated Queries", modify the seventh paragraph
to say:
"For texture images with uncompressed internal formats, queries of
<value> of TEXTURE_RED_SIZE, TEXTURE_GREEN_SIZE, TEXTURE_BLUE_SIZE,
TEXTURE_ALPHA_SIZE, TEXTURE_LUMINANCE_SIZE, TEXTURE_INTENSITY_SIZE,
TEXTURE_DEPTH_SIZE, and TEXTURE_STENCIL_SIZE return the actual
resolutions of the stored image array components..."
Section 6.1.4 "Texture Queries", in the second paragraph, replace
the first second and third sentences as follows:
"Calling GetTexImage with a color format (one of RED, GREEN,
BLUE, ALPHA, RGB, BGR, RGBA, BGRA, LUMINANCE, or
LUMINANCE_ALPHA) when the internal format of the texture image
is not a color format causes the error INVALID_OPERATION.
Calling GetTexImage with a <format> of DEPTH_COMPONENT when the
base internal format of the texture image is not DEPTH_COMPONENT
or DEPTH_STENCIL causes the error INVALID_OPERATION.
Calling GetTexImage with a <format> of DEPTH_STENCIL when
the base internal format of the texture image is not
DEPTH_STENCIL causes the error INVALID_OPERATION.
GetTexImage obtains component groups from a texture image with
the indicated level-of-detail. If <format> is a color format,
then the components are assigned among R, G, B, and A according
to Table 6.1, starting with the first group in the first row,
and continuing by obtaining groups in order from each row and
proceeding from the first row to the last, and from the first
image to the last for three-dimensional textures. If <format>
is DEPTH_COMPONENT, then each depth component is assigned with
the same ordering of rows and images. If <format> is
DEPTH_STENCIL, then each depth component and each stencil
index is assigned with the same ordering of rows and images."
After section 6.1.14 and before section 6.1.15 (which should be
renumbered 6.1.17), add two new sections:
"6.1.15 Framebuffer Object Queries
The command
boolean IsFramebuffer( uint framebuffer );
returns TRUE if <framebuffer> is the name of an framebuffer
object. If <framebuffer> is zero, or if <framebuffer> is a
non-zero value that is not the name of an framebuffer object,
IsFramebuffer return FALSE.
The command
void GetFramebufferAttachmentParameteriv(enum target,
enum attachment,
enum pname,
int *params);
returns information about attachments of a bound framebuffer object.
<target> must be DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER.
FRAMEBUFFER is equivalent to DRAW_FRAMEBUFFER.
If the default framebuffer is bound to <target>, then <attachment>
must be one of FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, or
AUXi, identifying a color buffer; DEPTH, identifying the depth
buffer; or STENCIL, identifying the stencil buffer.
If a framebuffer object is bound to <target>, then <attachment> must
be one of the attachment points of the framebuffer listed in table
1.nnn.
If <attachment> is DEPTH_STENCIL_ATTACHMENT, and different objects
are bound to the depth and stencil attachment points of <target>,
the query will fail and generate an INVALID_OPERATION error. If the
same object is bound to both attachment points, information about
that object will be returned.
Upon successful return from GetFramebufferAttachmentParameteriv, if
<pname> is FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, then <param> will
contain one of NONE, FRAMEBUFFER_DEFAULT, TEXTURE, or RENDERBUFFER,
identifying the type of object which contains the attached image.
Other values accepted for <pname> depend on the type of object, as
described below.
If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is
NONE, no framebuffer is bound to <target>. In this case
querying <pname> FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
will return zero, and all other queries will generate an
INVALID_OPERATION error.
If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is not
NONE, these queries apply to all other framebuffer types:
* If <pname> is FRAMEBUFFER_ATTACHMENT_RED_SIZE,
FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, or
FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, then <param> will contain
the number of bits in the corresponding red, green, blue, alpha,
depth, or stencil component of the specified <attachment>. Zero
is returned if the requested component is not present in
<attachment>.
* If <pname> is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, <param>
will contain the format of components of the specified
attachment, one of FLOAT, INT, UNSIGNED_INT, UNSIGNED_NORMALIZED
or INDEX for floating-point, signed integer, unsigned integer,
unsigned fixed-point, or index components respectively. Only
color buffers may have index or integer components.
* If <pname> is FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, <param>
will contain the encoding of components of the specified
attachment, one of LINEAR or SRGB for linear or sRGB-encoded
components, respectively. Only color buffer components may be
sRGB-encoded; such components are treated as described in
sections 4.1.8 "Blending" and 4.1.X "sRGB Conversion" (as
modified by ARB_framebuffer_sRGB). For the default framebuffer,
color encoding is determined by the implementation. For
framebuffer objects, components are sRGB-encoded if the internal
format of a color attachment is one of the color-renderable SRGB
formats described in section 3.8.15 "sRGB Texture Color
Conversion".
If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is RENDERBUFFER,
then
* If <pname> is FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, <params> will
contain the name of the renderbuffer object which contains the
attached image.
If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE, then
* If <pname> is FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, then <params>
will contain the name of the texture object which contains the
attached image.
* If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, then
<params> will contain the mipmap level of the texture object
which contains the attached image.
* If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE and
the texture object named FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is a
cube map texture, then <params> will contain the cube map face
of the cubemap texture object which contains the attached image.
Otherwise <params> will contain the value zero.
* If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER and the
texture object named FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is a
three-dimensional texture, then <params> will contain the layer
of the 2D image of the 3D texture object which contains the
attached image. Otherwise <params> will contain the value zero.
Any combinations of framebuffer type and <pname> not described above
will generate an INVALID_ENUM error."
6.1.16 Renderbuffer Object Queries
"The command
boolean IsRenderbuffer( uint renderbuffer );
returns TRUE if <renderbuffer> is the name of a renderbuffer
object. If <renderbuffer> is zero, or if <renderbuffer> is a
non-zero value that is not the name of a renderbuffer object,
IsRenderbuffer return FALSE.
The command
void GetRenderbufferParameteriv(enum target, enum pname,
int* params);
returns information about a bound renderbuffer object. <target> must
be RENDERBUFFER and <pname> must be one of the symbolic values in
table 8.nnn. If the renderbuffer currently bound to <target> is
zero, then an INVALID_OPERATION error is generated.
Upon successful return from GetRenderbufferParameteriv, if <pname>
is RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT,
RENDERBUFFER_INTERNAL_FORMAT, or RENDERBUFFER_SAMPLES, then <params>
will contain the width in pixels, height in pixels, internal format,
or number of samples, respectively, of the image of the renderbuffer
currently bound to <target>.
If <pname> is RENDERBUFFER_RED_SIZE, RENDERBUFFER_GREEN_SIZE,
RENDERBUFFER_BLUE_SIZE, RENDERBUFFER_ALPHA_SIZE,
RENDERBUFFER_DEPTH_SIZE, or RENDERBUFFER_STENCIL_SIZE, then <params>
will contain the actual resolutions, (not the resolutions specified
when the image array was defined), for the red, green, blue, alpha
depth, or stencil components, respectively, of the image of the
renderbuffer currently bound to <target>.
Otherwise, an INVALID_ENUM error is generated."
In section 6.2 "State Tables", add a row to table 6.18 "Textures
(state per texture image)":
Get value Type Get Cmd IV Description Sec.
------------------ ------ -------------------- --- ---------------------------------- -----
... ... ... ... ... ...
TEXTURE_STENCIL_SIZE n x Z+ GetTexLevelParameter 0 texture image's stencil resolution 3.8.3
Errors
The error INVALID_OPERATION is generated if DRAW_FRAMEBUFFER_BINDING
is zero and DrawBuffer or DrawBuffers is called with a <buf>
constant (other than NONE) that does not correspond to a buffer
allocated to the GL by the window-system, including the constants
COLOR_ATTACHMENT0 through COLOR_ATTACHMENTn, where n is
MAX_COLOR_ATTACHMENTS - 1.
The error INVALID_OPERATION is generated if DRAW_FRAMEBUFFER_BINDING
is non-zero and DrawBuffer or DrawBuffer is called
with a <buf> constant (other than NONE) that is not in the range
COLOR_ATTACHMENT0 through COLOR_ATTACHMENTn, where n is
MAX_COLOR_ATTACHMENTS - 1.
The error INVALID_OPERATION is generated if READ_FRAMEBUFFER_BINDING
is non-zero and ReadBuffer is called
with a <buf> constant (other than NONE) that is not in the range
COLOR_ATTACHMENT0 through COLOR_ATTACHMENTn, where n is
MAX_COLOR_ATTACHMENTS - 1.
The error INVALID_ENUM is generated if DrawBuffer or ReadBuffer is
called with a <buf> constant that is not listed in table 4.4 or
10.nnn.
The error INVALID_ENUM is generated if DrawBuffers is called with a
<buf> constant that is not listed in table 10.nnn or 11.nnn.
The error INVALID_FRAMEBUFFER_OPERATION is generated if
BlitFramebuffer, DrawPixels, or CopyPixels is called while the
draw framebuffer is not framebuffer complete.
The error INVALID_FRAMEBUFFER_OPERATION is generated if
BlitFramebuffer, ReadPixels, CopyPixels, CopyTex{Sub}Image*,
CopyColor{Sub}Table, or CopyConvolutionFilter* is called while the
read framebuffer is not framebuffer complete.
The error INVALID_OPERATION is generated if
GetFramebufferAttachmentParameteriv is called while the value of
DRAW_FRAMEBUFFER_BINDING is zero.
The error INVALID_OPERATION is generated if
FramebufferRenderbuffer or FramebufferTexture{1D|2D|3D} is
called while the value of DRAW_FRAMEBUFFER_BINDING is zero.
The error INVALID_OPERATION is generated if RenderbufferStorage
or GetRenderbufferParameteriv is called while the value of
RENDERBUFFER_BINDING is zero.
The error INVALID_ENUM is generated if
GetFramebufferAttachmentParameteriv is called with an
<attachment> other than COLOR_ATTACHMENT0 through
COLOR_ATTACHMENTn, where n is MAX_COLOR_ATTACHMENTS - 1.
The error INVALID_ENUM is generated if
GetFramebufferAttachmentParameteriv is called with a <pname>
other than FRAMEBUFFER_ATTACHMENT_OBJECT_NAME when the type of
the attached object at the named attachment point is
RENDERBUFFER.
The error INVALID_ENUM is generated if
GetFramebufferAttachmentParameteriv is called with a <pname>
other than FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, or
FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER when the type of the
attached object at the named attachment point is TEXTURE.
The error INVALID_ENUM is generated if GetRenderbufferParameteriv
is called with a <pname> other than RENDERBUFFER_WIDTH,
RENDERBUFFER_HEIGHT, or RENDERBUFFER_INTERNAL_FORMAT,
RENDERBUFFER_RED_SIZE, RENDERBUFFER_GREEN_SIZE,
RENDERBUFFER_BLUE_SIZE, RENDERBUFFER_ALPHA_SIZE,
RENDERBUFFER_DEPTH_SIZE, or RENDERBUFFER_STENCIL_SIZE.
The error INVALID_VALUE is generated if RenderbufferStorage is
called with a <width> or <height> that is greater than
MAX_RENDERBUFFER_SIZE.
The error INVALID_ENUM is generated if RenderbufferStorage is
called with an <internalformat> that is not RGB, RGBA,
DEPTH_COMPONENT, STENCIL_INDEX, DEPTH_STENCIL, or one of the
internal formats from table 3.16 or table 2.nnn that has a base
internal format of RGB, RGBA, DEPTH_COMPONENT, STENCIL_INDEX, r
DEPTH_STENCIL.
The error INVALID_OPERATION is generated if
FramebufferRenderbuffer is called and <renderbuffer> is not the
name of a renderbuffer object.
The error INVALID_OPERATION is generated if
FramebufferTexture{1D|2D|3D} is called and <texture> is not the
name of a texture object.
The error INVALID_VALUE is generated if
FramebufferTexture{1D|2D|3D} is called with a <level> that is
less than zero.
The error INVALID_VALUE is generated if FramebufferTexture2D is
called with a <level> that is not zero and <textarget> is
TEXTURE_RECTANGLE_ARB.
The error INVALID_VALUE is generated if FramebufferTexture{1D|2D}
is called with a <level> that is greater than the log base 2 of
MAX_TEXTURE_SIZE and <texture> is a 1D or 2D texture.
The error INVALID_VALUE is generated if FramebufferTexture2D
is called with a <level> that is greater than the log base 2 of
MAX_CUBE_MAP_TEXTURE_SIZE and <texture> is a cubemap texture.
The error INVALID_VALUE is generated if FramebufferTexture3D is
called with a <level> greater than the log base 2 of the
MAX_3D_TEXTURE_SIZE.
The error INVALID_VALUE is generated if FramebufferTexture3D is
called with a <layer> that is larger than MAX_3D_TEXTURE_SIZE-1.
The error INVALID_VALUE is generated by BlitFramebuffer if
<mask> has any bits set other than those named by
COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT.
The error INVALID_OPERATION is generated if BlitFramebuffer is
called and <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT
and <filter> is not NEAREST.
The error INVALID_OPERATION is generated if BlitFramebuffer is
called and <mask> includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT
and the source and destination depth or stencil buffer formats do
not match.
The error INVALID_ENUM is generated by BlitFramebuffer if
<filter> is not LINEAR or NEAREST.
The error INVALID_OPERATION is generated if BlitFramebuffer
is called within a Begin/End pair.
The error INVALID_ENUM is generated if BindFramebuffer,
CheckFramebufferStatus, FramebufferTexture{1D|2D|3D},
FramebufferRenderbuffer, or
GetFramebufferAttachmentParameteriv is called and <target> is
not DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER.
The error INVALID_OPERATION is generated if
CheckFramebufferStatus is called within a Begin/End pair.
The error OUT_OF_MEMORY is generated if the GL is unable to create a
data store of the required size when calling RenderbufferStorage.
The error INVALID_OPERATION is generated if GenerateMipmap is
called with a <target> of TEXTURE_CUBE_MAP and the texture object
currently bound to TEXTURE_CUBE_MAP is not "cube complete" as
defined in section 3.8.10
The error INVALID_OPERATION is generated if ReadPixels,
CopyPixels, CopyTex{Sub}Image*, CopyColor{Sub}Table, or
CopyConvolutionFilter* is called while READ_FRAMEBUFFER_BINDING
is non-zero, the read framebuffer is framebuffer complete, and the
value of SAMPLE_BUFFERS for the read framebuffer is greater than
zero.
The error OUT_OF_MEMORY is generated when
RenderbufferStorageMultisample cannot create storage of the
specified size.
If both the draw and read framebuffers are framebuffer complete and
both have a value of SAMPLE_BUFFERS that is greater than zero, then
the error INVALID_OPERATION is generated if BlitFramebuffer is
called and the values of SAMPLES for the draw and read framebuffers
do not match.
If both the draw and read framebuffers are framebuffer complete and
either has a value of SAMPLE_BUFFERS that is greater than zero, then
the error INVALID_OPERATION is generated if BlitFramebuffer is
called and the formats of the draw and read framebuffers are not
identical.
If either the draw or read framebuffer is framebuffer complete and
has a value of SAMPLE_BUFFERS that is greater than zero, then the
error INVALID_OPERATION is generated if BlitFramebuffer is called
and the specified source and destination dimensions are not
identical.
If RenderbufferStorageMultisample is called with a value of
<samples> that is greater than MAX_SAMPLES, then the error
INVALID_VALUE is generated.
The error INVALID_ENUM is generated if DrawPixels or ReadPixels is
called where format is DEPTH_STENCIL and type is not
UNSIGNED_INT_24_8.
The error INVALID_OPERATION is generated if DrawPixels or ReadPixels
is called where type is UNSIGNED_INT_24_8 and format is not
DEPTH_STENCIL.
The error INVALID_OPERATION is generated if DrawPixels or ReadPixels
is called where format is DEPTH_STENCIL and there is not both a
depth buffer and a stencil buffer.
The error INVALID_OPERATION is generated if CopyPixels is called
where type is DEPTH_STENCIL and there is not both a depth buffer
and a stencil buffer.
New State
(add new table 3.nnn, "Framebuffer (state per framebuffer target binding point)")
Get Value Type Get Command Initial Value Description Section Attribute
------------------------ ---- ----------- -------------- ------------------- ------------ ---------
DRAW_FRAMEBUFFER_BINDING Z+ GetIntegerv 0 Framebuffer object bound 4.4.1 -
to DRAW_FRAMEBUFFER
READ_FRAMEBUFFER_BINDING Z+ GetIntegerv 0 Framebuffer object 4.4.1 -
to READ_FRAMEBUFFER
(insert new table 4.nnn, "Framebuffer (state per framebuffer object)")
Get Value Type Get Command Initial Value Description Section Attribute
---------------- ------ ------------- ------------- -------------------- ------------ ---------
DRAW_BUFFERi [1] 1 + xZ(10*) GetIntegerv see 4.2.1 Draw buffer selected 4.2.1 color-buffer
for color output i
READ_BUFFER [2] Z(3) GetIntegerv see 4.3.2 Read source buffer 4.3.2 pixel
[1] prior to this extension, the DRAW_BUFFERi state was
described in table 6.21 "Framebuffer Control" of the OpenGL
2.0 specification.
[2] prior to this extension, the READ_BUFFER state was described
in table 6.26 "Pixel" of the OpenGL 2.0 specification.
(insert new table 5.nnn, "Framebuffer (state per framebuffer object attachment point)")
Get Value Type Get Command Initial Value Description Section Attribute
-------------------------------------------- ---- -------------------------------------- ------------- -------------------- ------------ ---------
FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE Z GetFramebufferAttachmentParameteriv NONE type of 4.4.2.2 and -
image attached to 4.4.2.3
framebuffer attachment
point
FRAMEBUFFER_ATTACHMENT_OBJECT_NAME Z GetFramebufferAttachmentParameteriv 0 name of object 4.4.2.2 and -
attached to 4.4.2.3
framebuffer attachment
point
FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL Z GetFramebufferAttachmentParameteriv 0 mipmap level of 4.4.2.2 and -
texture image 4.4.2.3
attached, if object
attached is texture.
FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE Z+ GetFramebufferAttachmentParameteriv NONE cubemap face of 4.4.2.2 and -
texture image 4.4.2.3
attached, if object
attached is cubemap
texture.
FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER Z GetFramebufferAttachmentParameteriv 0 layer of 4.4.2.2 and -
texture image 4.4.2.3
attached, if object
attached is 3D texture.
FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING Z_2 GetFramebufferAttachmentParameteriv - Encoding of components 6.1.3 -
in the attached image
FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE Z_4 GetFramebufferAttachmentParameteriv - Data type of components 6.1.3 -
in the attached image
FRAMEBUFFER_ATTACHMENT_RED_SIZE Z+ GetFramebufferAttachmentParameteriv - Size in bits of att. 6.1.3 -
image's red component
FRAMEBUFFER_ATTACHMENT_GREEN_SIZE Z+ GetFramebufferAttachmentParameteriv - Size in bits of att. 6.1.3 -
image's green component
FRAMEBUFFER_ATTACHMENT_BLUE_SIZE Z+ GetFramebufferAttachmentParameteriv - Size in bits of att. 6.1.3 -
image's blue component
FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE Z+ GetFramebufferAttachmentParameteriv - Size in bits of att. 6.1.3 -
image's alpha component
FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE Z+ GetFramebufferAttachmentParameteriv - Size in bits of att. 6.1.3 -
image's depth component
FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE Z+ GetFramebufferAttachmentParameteriv - Size in bits of att. 6.1.3 -
image's stencil component
(insert new table 7.nnn, "Renderbuffers (state per renderbuffer target and binding point)")
Get Value Type Get Command Initial Value Description Section Attribute
---------------------------- ------ ------------- ------------- -------------------- ------------ ---------
RENDERBUFFER_BINDING Z GetIntegerv 0 renderbuffer object 4.4.2.1 -
bound to RENDERBUFFER
(insert new table 8.nnn, "Renderbuffers (state per renderbuffer object)")
Get Value Type Get Command Initial Value Description Section Attribute
---------------------------- ------ ------------- ------------- -------------------- ------------ ---------
RENDERBUFFER_WIDTH Z GetRenderbufferParameteriv 0 width of renderbuffer 4.4.2.1 -
RENDERBUFFER_HEIGHT Z GetRenderbufferParameteriv 0 height of renderbuffer 4.4.2.1 -
RENDERBUFFER_INTERNAL_FORMAT Z+ GetRenderbufferParameteriv RGBA internal format 4.4.2.1 -
of renderbuffer
RENDERBUFFER_RED_SIZE Z GetRenderbufferParameteriv 0 size in bits of 4.4.2.1 -
renderbuffer image's
red component
RENDERBUFFER_GREEN_SIZE Z GetRenderbufferParameteriv 0 size in bits of 4.4.2.1 -
renderbuffer image's
green component
RENDERBUFFER_BLUE_SIZE Z GetRenderbufferParameteriv 0 size in bits of 4.4.2.1 -
renderbuffer image's
blue component
RENDERBUFFER_ALPHA_SIZE Z GetRenderbufferParameteriv 0 size in bits of 4.4.2.1 -
renderbuffer image's
alpha component
RENDERBUFFER_DEPTH_SIZE Z GetRenderbufferParameteriv 0 size in bits of 4.4.2.1 -
renderbuffer image's
depth component
RENDERBUFFER_STENCIL_SIZE Z GetRenderbufferParameteriv 0 size in bits of 4.4.2.1 -
renderbuffer image's
stencil component
RENDERBUFFER_SAMPLES Z+ GetRenderbufferParameteriv 0 number of samples 4.4.2.1 -
Move the following existing state from "Implementation Dependent
Values", tables 6.33-6.37 to into a new table called "Framebuffer
Dependent Values", table 9.nnn.
Get Value
---------
AUX_BUFFERS
MAX_DRAW_BUFFERS
RGBA_MODE
INDEX_MODE
DOUBLEBUFFER
STEREO
SAMPLE_BUFFERS
SAMPLES
RED_BITS
GREEN_BITS
BLUE_BITS
ALPHA_BITS
INDEX_BITS
DEPTH_BITS
STENCIL_BITS
ACCUM_RED_BITS
ACCUM_GREEN_BITS
ACCUM_BLUE_BITS
ACCUM_ALPHA_BITS
To the same table called "Framebuffer Dependent Values", table 9.nnn
add the following new framebuffer dependent state.
Get Value Type Get Command Minimum Value Description Section Attribute
--------- ---- ----------- ------------- ------------------- ------- ---------
MAX_COLOR_ATTACHMENTS Z+ GetIntegerv 1 Maximum number of 4.4.2.2 -
attachment points
for color buffers
when using framebuffer
objects
MAX_SAMPLES Z+ GetIntegerv 0 Maximum number of 4.4.2.1 -
samples supported
for multisampling
New Implementation Dependent State
Get Value Type Get Command Minimum Value Description Section Attribute
--------- ---- ----------- ------------- ------------------- ------- ---------
MAX_RENDERBUFFER_SIZE Z+ GetIntegerv 64 Maximum width and 4.4.2.1 -
height of
renderbuffers
supported by
the implementation
Additions to the AGL/GLX/WGL Specifications and dependencies on
WGL_ARB_make_current_read, GLX_SGI_make_current_read, and GLX 1.3
The color, depth, stencil, aux, and accum logical buffers defined by
the <draw> and <read> drawables passed to glXMakeContextCurrent,
glXMakeCurrent, and glXMakeCurrentRead are ignored while the value
of DRAW_FRAMEBUFFER_BINDING is non-zero.
Dependencies on ATI_draw_buffers and ARB_draw_buffers
If neither ATI_draw_buffers nor ARB_draw_buffers are supported, then
all discussions of DrawBuffers should be ignored.
In addition, the language describing DrawBuffers are derived from a
combination of the ARB_draw_buffers specification and section 4.2.1
of the OpenGL 2.0 specification.
Dependencies on ARB_fragment_program, ARB_fragment_shader, and
ARB_vertex_shader
If ARB_fragment_program, ARB_fragment_shader, and ARB_vertex_shader
are all not supported, then all references to the currently bound
program or shader should be ignored.
Dependencies on ARB_texture_rectangle
If ARB_texture_rectangle is not supported, then all references to
TEXTURE_RECTANGLE_ARB should be ignored.
Dependencies on ARB_color_buffer_float
The reference to CLAMP_FRAGMENT_COLOR_ARB in section 4.3.3 applies
only if ARB_color_buffer_float is supported.
Dependencies on ARB_texture_rg
If ARB_texture_rg is not supported, delete the references to RED and
RG from the list of color-renderable base internal formats from
section 4.4.4.
Dependencies on NV_float_buffer
If NV_float_buffer is not supported, delete the references to
FLOAT_R_NV, FLOAT_RG_NV, FLOAT_RGB_NV and FLOAT_RGBA_NV from the list
of color-renderable base internal formats from section 4.4.4
Dependencies on EXT_framebuffer_object
Framebuffer objects created with the commands defined by the
GL_EXT_framebuffer_object extension are defined to be shared, while
FBOs created with commands defined by the OpenGL core or
GL_ARB_framebuffer_object extension are defined *not* to be shared.
However, the following functions are viewed as aliases (in particular
the opcodes for X are also the same) between the functions of
GL_EXT_framebuffer_object and GL_ARB_framebuffer_object:
IsRenderbufferEXT / IsRenderbuffer
DeleteRenderbuffersEXT / DeleteRenderbuffers
GenRenderbuffersEXT / GenRenderbuffers
RenderbufferStorageEXT / RenderbufferStorage
GetRenderbufferParameterivEXT / GetRenderbufferParameteriv
IsFramebufferEXT / IsFramebuffer
DeleteFramebuffersEXT / DeleteFramebuffers
GenFramebuffersEXT / GenFramebuffers
CheckFramebufferStatusEXT / CheckFramebufferStatus
FramebufferTexture1DEXT / FramebufferTexture1D
FramebufferTexture2DEXT / FramebufferTexture2D
FramebufferRenderbufferEXT / FramebufferRenderbuffer
GenerateMipmapEXT / GenerateMipmap
GetFramebufferAttachmentParameterivEXT / GetFramebufferAttachmentParameteriv
Since the above pairs are aliases, the functions of a pair are
equivalent. Note that the functions BindFramebuffer and
BindFramebufferEXT are not aliases and neither are the functions
BindRenderbuffer and BindRenderbufferEXT. Because object creation
occurs when the framebuffer object is bound for the first time, a
framebuffer object can be shared across contexts only if it was first
bound with BindFramebufferEXT. Framebuffers first bound with
BindFramebuffer may not be shared across contexts. Framebuffer
objects created with BindFramebufferEXT may subsequently be bound
using BindFramebuffer. Framebuffer objects created with
BindFramebuffer may be bound with BindFramebufferEXT provided they are
bound to the same context they were created on.
Dependencies on EXT_texture_array
If EXT_texture_array is not supported, delete all references to
one- and two-dimensional array textures.
Dependencies on EXT_texture_integer
If EXT_texture_integer is not supported, the following changes should
be made:
The definition of GetFramebufferAttachmentParameteriv should be
modified to remove any references to signed and unsigned integer
components for color buffers and the values of INT and UNSIGNED_INT
should be removed from the list of possible values for <param> when
<pname> is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE.
Dependencies on ARB_framebuffer_sRGB
If ARB_framebuffer_sRGB is not supported, the following changes should
be made:
The definition of GetFramebufferAttachmentParameteriv should be
modified to remove any reference to sRGB-encoded components or
color buffers and sRGB conversion. The value of SRGB should be
removed from the list of possible values for <param> when <pname> is
FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING.
GLX Protocol
Nineteen new GL commands are added.
The following thirteen rendering commands are sent to the server
as part of a glXRender request:
BindRenderbuffer
2 12 rendering command length
2 235 rendering command opcode
4 ENUM target
4 CARD32 renderbuffer
DeleteRenderbuffer
2 8+n*4 rendering command length
2 4317 rendering command opcode
4 CARD32 n
n*4 LISTofCARD32 renderbuffers
RenderbufferStorage
2 20 rendering command length
2 4318 rendering command opcode
4 ENUM target
4 ENUM internalFormat
4 CARD32 width
4 CARD32 height
RenderbufferStorageMultisample
2 24 rendering command length
2 4331 rendering command opcode
4 ENUM target
4 CARD32 samples
4 ENUM internalformat
4 CARD32 width
4 CARD32 height
BindFramebuffer
2 12 rendering command length
2 236 rendering command opcode
4 ENUM target
4 CARD32 framebuffer
DeleteFramebuffer
2 8+n*4 rendering command length
2 4320 rendering command opcode
4 CARD32 n
n*4 LISTofCARD32 framebuffers
FramebufferTexture1D
2 24 rendering command length
2 4321 rendering command opcode
4 ENUM target
4 ENUM attachment
4 ENUM textarget
4 CARD32 texture
4 CARD32 level
FramebufferTexture2D
2 24 rendering command length
2 4322 rendering command opcode
4 ENUM target
4 ENUM attachment
4 ENUM textarget
4 CARD32 texture
4 CARD32 level
FramebufferTexture3D
2 28 rendering command length
2 4323 rendering command opcode
4 ENUM target
4 ENUM attachment
4 ENUM textarget
4 CARD32 texture
4 CARD32 level
4 CARD32 layer
FramebufferTextureLayer
2 24 rendering command length
2 237 rendering command opcode
4 ENUM target
4 ENUM attachment
4 CARD32 texture
4 CARD32 level
4 CARD32 layer
FramebufferRenderbuffer
2 20 rendering command length
2 4324 rendering command opcode
4 ENUM target
4 ENUM attachment
4 ENUM renderbuffertarget
4 CARD32 renderbuffer
BlitFramebuffer
2 44 rendering command length
2 4330 rendering command opcode
4 CARD32 source X0
4 CARD32 source Y0
4 CARD32 source X1
4 CARD32 source Y1
4 CARD32 destination X0
4 CARD32 destination Y0
4 CARD32 destination X1
4 CARD32 destination Y1
4 CARD32 mask
4 ENUM filter
GenerateMipmap
2 8 rendering command length
2 4325 rendering command opcode
4 ENUM target
The remaining seven commands are non-rendering commands. These
commands are sent separately (i.e., not as part of a glXRender or
glXRenderLarge request), using the glXVendorPrivateWithReply
request:
IsRenderbuffer
1 CARD8 opcode (X assigned)
1 17 GLX opcode (X_GLXVendorPrivateWithReply)
2 4 request length
4 1422 vendor specific opcode
4 GLX_CONTEXT_TAG context tag
4 CARD32 renderbuffer
=>
1 1 reply
1 unused
2 CARD16 sequence number
4 0 reply length
4 BOOL32 return value
20 unused
GenRenderbuffers
1 CARD8 opcode (X assigned)
1 17 GLX opcode (X_GLXVendorPrivateWithReply)
2 4 request length
4 1423 vendor specific opcode
4 GLX_CONTEXT_TAG context tag
4 CARD32 n
=>
1 1 reply
1 unused
2 CARD16 sequence number
4 m reply length
4 unused
4 CARD32 n
16 unused
n*4 LISTofCARD32 renderbuffers
GetRenderbufferParameteriv
1 CARD8 opcode (X assigned)
1 17 GLX opcode (X_GLXVendorPrivateWithReply)
2 5 request length
4 1424 vendor specific opcode
4 GLX_CONTEXT_TAG context tag
4 ENUM target
4 ENUM pname
=>
1 1 reply
1 unused
2 CARD16 sequence number
4 m reply length, m = (n == 1 ? 0 : n)
4 unused
4 CARD32 n
if (n = 1) this follows:
4 CARD32 params
12 unused
otherwise this follows:
16 unused
n*4 LISTofCARD32 params
IsFramebuffer
1 CARD8 opcode (X assigned)
1 17 GLX opcode (X_GLXVendorPrivateWithReply)
2 4 request length
4 1425 vendor specific opcode
4 GLX_CONTEXT_TAG context tag
4 CARD32 framebuffer
=>
1 1 reply
1 unused
2 CARD16 sequence number
4 0 reply length
4 BOOL32 return value
20 unused
GenFramebuffers
1 CARD8 opcode (X assigned)
1 17 GLX opcode (X_GLXVendorPrivateWithReply)
2 4 request length
4 1426 vendor specific opcode
4 GLX_CONTEXT_TAG context tag
4 CARD32 n
=>
1 1 reply
1 unused
2 CARD16 sequence number
4 n reply length
4 unused
4 CARD32 n
16 unused
n*4 LISTofCARD32 framebuffers
CheckFramebufferStatus
1 CARD8 opcode (X assigned)
1 17 GLX opcode (X_GLXVendorPrivateWithReply)
2 4 request length
4 1427 vendor specific opcode
4 GLX_CONTEXT_TAG context tag
4 ENUM target
=>
1 1 reply
1 unused
2 CARD16 sequence number
4 0 reply length
4 ENUM return value
20 unused
GetFramebufferAttachmentParameteriv
1 CARD8 opcode (X assigned)
1 17 GLX opcode (X_GLXVendorPrivateWithReply)
2 6 request length
4 1428 vendor specific opcode
4 GLX_CONTEXT_TAG context tag
4 ENUM target
4 ENUM attachment
4 ENUM pname
=>
1 1 reply
1 unused
2 CARD16 sequence number
4 m reply length, m = (n == 1 ? 0 : n)
4 unused
4 CARD32 n
if (n = 1) this follows:
4 CARD32 params
12 unused
otherwise this follows:
16 unused
n*4 LISTofCARD32 params
Usage Examples
The following examples use a helper macro for
CHECK_FRAMEBUFFER_STATUS, defined below.
Example (6) gives a (very slightly) more robust example of handling
the possible return values for glCheckFramebufferStatus.
#define CHECK_FRAMEBUFFER_STATUS() \
{ \
GLenum status; \
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); \
switch(status) { \
case GL_FRAMEBUFFER_COMPLETE: \
break; \
case GL_FRAMEBUFFER_UNSUPPORTED: \
/* choose different formats */ \
break; \
default: \
/* programming error; will fail on all hardware */ \
assert(0); \
}
}
(1) Render to 2D texture with a depth buffer
// Given: color_tex - TEXTURE_2D color texture object
// depth_rb - GL_DEPTH renderbuffer object
// fb - framebuffer object
// Enable render-to-texture
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
// Set up color_tex and depth_rb for render-to-texture
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, color_tex, 0);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_rb);
// Check framebuffer completeness at the end of initialization.
CHECK_FRAMEBUFFER_STATUS();
<draw to the texture and renderbuffer>
// Re-enable rendering to the window
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, color_tex);
<draw to the window, reading from the color_tex>
(2) Application that supports both RBBCTT (render back buffer, copy to
texture) and RTT (render to texture). The migration path from RBBCTT
to RTT is easy.
if (useFramebuffer) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, color_tex, 0);
CHECK_FRAMEBUFFER_STATUS();
}
draw_to_texture();
glBindTexture (GL_TEXTURE_2D, color_tex);
if (useFramebuffer) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
} else { // copy tex path
glCopyTexSubImage(...);
}
(3) Simple render-to-texture loop with initialization. Create an
RGB8 texture, a 24-bit depth renderbuffer, and a stencil
renderbuffer. In a loop, alternate between rendering to, and
texturing out of, the color texture.
glGenFramebuffers(1, &fb);
glGenTextures(1, &color_tex);
glGenRenderbuffers(1, &depth_rb);
glGenRenderbuffers(1, &stencil_rb);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
// initialize color texture
glBindTexture(GL_TEXTURE_2D, color_tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0,
GL_RGB, GL_INT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, color_tex, 0);
// initialize depth renderbuffer
glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_rb);
// initialize stencil renderbuffer
glBindRenderbuffer(GL_RENDERBUFFER, stencil_rb);
glRenderbufferStorage(GL_RENDERBUFFER,
GL_STENCIL_INDEX, 512, 512);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_rb);
// Check framebuffer completeness at the end of initialization.
CHECK_FRAMEBUFFER_STATUS();
loop {
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
<draw to the texture>
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, color_tex);
<draw to the window, reading from the color texture>
}
(4) Render-to-texture loop with automatic mipmap generation. There
are N framebuffers, N mipmap color textures, and a single shared
depth renderbuffer. The depth renderbuffer is not a mipmap.
GLuint fb_array[N];
GLuint color_tex_array[N];
GLuint depth_rb;
glGenFramebuffers(N, fb_array);
glGenTextures(N, color_tex_array);
glGenRenderbuffers(1, &depth_rb);
// initialize color textures
for (int i=0; i<N; i++) {
glBindTexture(GL_TEXTURE_2D, color_tex_array[N]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0,
GL_RGB, GL_INT, NULL);
// establish a mipmap chain for the texture
glGenerateMipmap(GL_TEXTURE_2D);
}
// initialize depth renderbuffer
glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH_COMPONENT24, 512, 512);
// setup framebuffers, sharing depth
for (int i=0; i<N; i++) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_array[i]);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, color_tex_array[i], 0);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_rb);
}
// Check framebuffer completeness at the end of initialization.
CHECK_FRAMEBUFFER_STATUS();
loop {
glBindTexture(GL_TEXTURE_2D, 0);
for (int i=0; i<N; i++) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb_array[i]);
<draw to texture i>
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
// automatically generate mipmaps
for (int i=0; i<N; i++) {
glBindTexture(GL_TEXTURE_2D, color_tex_array[i]);
glGenerateMipmap(GL_TEXTURE_2D);
}
<draw to the window, reading from the color textures>
}
(5) Render-to-texture loop with custom mipmap generation.
The depth renderbuffer is not a mipmap.
glGenFramebuffers(1, &fb);
glGenTextures(1, &color_tex);
glGenRenderbuffers(1, &depth_rb);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
// initialize color texture and establish mipmap chain
glBindTexture(GL_TEXTURE_2D, color_tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0,
GL_RGB, GL_INT, NULL);
glGenerateMipmap(GL_TEXTURE_2D);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, color_tex, 0);
// initialize depth renderbuffer
glBindRenderbuffer(GL_RENDERBUFFER, depth_rb);
glRenderbufferStorage(GL_RENDERBUFFER,
GL_DEPTH_COMPONENT24, 512, 512);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_rb);
// Check framebuffer completeness at the end of initialization.
CHECK_FRAMEBUFFER_STATUS();
loop {
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, color_tex, 0);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_rb);
<draw to the base level of the color texture>
// custom-generate successive mipmap levels
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, color_tex);
foreach (level > 0, in order of increasing values of level) {
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, color_tex, level);
glTexParameteri(TEXTURE_2D, TEXTURE_BASE_LEVEL, level-1);
glTexParameteri(TEXTURE_2D, TEXTURE_MAX_LEVEL, level-1);
<draw to level>
}
glTexParameteri(TEXTURE_2D, TEXTURE_BASE_LEVEL, 0);
glTexParameteri(TEXTURE_2D, TEXTURE_MAX_LEVEL, max);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
<draw to the window, reading from the color texture>
}
(6) Pseudo-code example of one method of responding to
FRAMEBUFFER_UNSUPPORTED
bool done = false;
bool success = false;
int configurationNumber = 0;
GLenum status;
while (!done)
{
for (each framebuffer-attachable image)
{
ChooseInternalFormatForFramebufferAttachableImage(configurationNumber);
CreateFramebufferAttachableImage();
AttachFramebufferAttachableImageToFramebuffer();
}
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE:
success = true;
done = true;
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
if (configCount < MAX_NUM_CONFIGS_I_WANT_TO_TRY)
{
printf("current config not supported, trying again);
configurationNumber++;
}
else
{
printf("couldn't find a supported config\n");
success = false;
done = true;
}
break;
default:
// programming error; will fail on all hardware
FatalError();
exit(1);
}
}
if (!success)
{
printf("couldn't find a supported config\n");
FatalError();
exit(1);
}
// Current framebuffer is supported and complete!!
Draw();
(7) Render to depth texture with no color attachments
// Given: depth_tex - TEXTURE_2D depth texture object
// fb - framebuffer object
// Enable render-to-texture
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
// Set up depth_tex for render-to-texture
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, depth_tex, 0);
// No color buffer to draw to or read from
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
// Check framebuffer completeness at the end of initialization.
CHECK_FRAMEBUFFER_STATUS();
<draw something>
// Re-enable rendering to the window
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, depth_tex);
<draw to the window, reading from the depth_tex>
(8) FBO and ARB_draw_buffers
// Given: color_texA - TEXTURE_2D color texture object
// Given: color_texB - TEXTURE_2D color texture object
// depth_rb - GL_DEPTH renderbuffer object
// fb - framebuffer object
// Set up the framebuffer object
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, color_texA, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT1,
GL_TEXTURE_2D, color_texB, 0);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_rb);
// Enable both attachments as draw buffers
GLenum drawbuffers = {GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, drawbuffers);
// Check framebuffer completeness at the end of initialization.
CHECK_FRAMEBUFFER_STATUS();
// Enable fragment program that writes to both gl_FragData[0]
// and gl_FragData[1]
<draw something>
// Disable fragment program
// Re-enable rendering to the window
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
// Bind both textures, each to a different texture unit
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, color_texA);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, color_texB);
<draw to the window>
Sample Code (from framebuffer_blit)
/* Render to framebuffer object 2 */
glBindFramebuffer(DRAW_FRAMEBUFFER, 2);
RenderScene();
/* Blit contents of color buffer, depth buffer and stencil buffer
* from framebuffer object 2 to framebuffer object 1.
*/
glBindFramebuffer(GL_READ_FRAMEBUFFER, 2);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 1);
glBlitFramebuffer(0, 0, 640, 480,
0, 0, 640, 480,
GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT,
GL_NEAREST);
/* Blit contents of color buffer from framebuffer object 1 to
* framebuffer object 2, inverting the image in the X direction.
*/
glBindFramebuffer(GL_READ_FRAMEBUFFER, 1);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 2);
glBlitFramebuffer(0, 0, 640, 480,
640, 0, 0, 480,
GL_COLOR_BUFFER_BIT,
GL_NEAREST);
/* Blit color buffer from framebuffer object 1 to framebuffer
* object 3 with a 2X zoom and linear filtering.
*/
glBindFramebuffer(GL_READ_FRAMEBUFFER, 1);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 3);
glBlitFramebuffer(0, 0, 640, 480,
0, 0, 1280, 960,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
Usage Examples (from packed_depth_stencil)
(1) Attach a DEPTH_STENCIL texture image to an FBO as both the
depth and stencil buffers.
glGenFramebuffers(1, &fb);
glGenTextures(1, &tex_color);
glGenTextures(1, &tex_depthstencil);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
// Setup color texture (mipmap)
glBindTexture(GL_TEXTURE_2D, tex_color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
512, 512, 0, GL_RGBA, GL_INT, NULL);
glGenerateMipmap(GL_TEXTURE_2D);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, tex_color, 0);
// Setup depth_stencil texture (not mipmap)
glBindTexture(GL_TEXTURE_2D, tex_depthstencil);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8,
512, 512, 0, GL_DEPTH_STENCIL,
GL_UNSIGNED_INT_24_8, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, tex_depthstencil, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
GL_STENCIL_ATTACHMENT,
GL_TEXTURE_2D, tex_depthstencil, 0);
// Check framebuffer completeness at the end of initialization.
loop {
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
<render to color, depth, and stencil textures>
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, tex_color);
glGenerateMipmap(GL_TEXTURE_2D);
<draw to the window, reading from the color texture>
glBindTexture(GL_TEXTURE_2D, tex_depthstencil);
<draw to the window, reading depth from the depthstencil texture>
}
Issues
(1) What should this extension be named?
RESOLVED. We will call this ARB_framebuffer_object.
(2) What additional functionality does this extension include over
EXT_framebuffer_object?
RESOLVED.
Currently we incorporate the following layered extensions:
* EXT_framebuffer_multisample
* EXT_framebuffer_blit
* EXT_packed_depth_stencil
As well as the following features:
* Permit attachments with different width and height (mixed
dimensions)
* Permit color attachments with different formats (mixed
formats).
* Render to 1 and 2 component R/RG formats that are provided
via the ARB_texture_rg extension. L/A/LA/I will be
left for a separate (trivial) extension.
* Gen'ed names must be used for framebuffer objects and
renderbuffers.
* Added FramebufferTextureLayer.
Other features we have considered include:
* Render to Vertex Attrib (RTVA)
* Format compatibility API that can guarantee a set of textures
images have framebuffer-compatible formats.
* Infolog or other means for communicating framebuffer
incompleteness information to the application for debugging
purposes.
* A technique for page flipping framebuffer-attachable images.
* Relaxing framebuffer completeness restrictions, possibly even
remove FRAMEBUFFER_UNSUPPORTED. Maybe go so far as to remove
CheckFramebufferStatus.
Features we have rejected include:
* GetRenderbufferImage (benefit/demand does not seem to
outweigh the additional complexity.)
* READ_BUFFER == NONE for framebuffer zero.
* Attach images from a window or from a pbuffer to an
application-created framebuffer object.
(3) What are the other differences from EXT_framebuffer_object.
* Framebuffer completeness only considers the attachments named
by DRAW_BUFFERi and READ_BUFFER. Any other attachments do
not affect framebuffer completeness. (In
EXT_framebuffer_object, all attachments affected framebuffer
completeness, independent of the DRAW_BUFFERi and READ_BUFFER
state.)
* Added new queries for the sizes of the bit planes for color,
depth and stencil attachments at a framebuffer attachment point.
* Added new queries for framebuffer attachment component type and
color encoding.
* Many other minor tweaks to synchronize with the GL3 framebuffer
objects.
* ARB FBOs are not shareable.
(4) Do we need new enum values, or can we re-use the ones from the EXT
versions?
RESOLVED. This extension is designed to be compatible with
EXT_framebuffer_object, and thus we can reuse the enumerants. There
are also a number of additional enumerants added in this extension.
(5) What should a query of RED_BITS, GREEN_BITS, BLUE_BITS, ALPHA_BITS.
return if the attached color-renderable images have different
formats?
RESOLVED. The values of RED_BITS, GREEN_BIT, BLUE_BITS and
ALPHA_BITS are only defined if all color attachments of the draw
framebuffer have identical formats, in which case the color
component sizes of color attachment zero are return. This is
necessary for backwards compatibility with EXT_framebuffer_object.
The actual sizes of the color, depth, or stencil bit planes can be
obtained by querying an attachment point using
GetFramebufferAttachmentParameteriv using the new
FRAMEBUFFER_ATTACHMENT_*_SIZE enumerants, or by querying the object
attached at that point.
(6) What are the proper names for the 1 and 2 component fixed-point,
float, and pure integer texture formats?
RESOLVED: as introduced in the 3.0 spec, using RED and RG base
internal format terminology. The new RED/RG formats have also been
spun out of 3.0 as the ARB_texture_rg extension.
(7) This extension and EXT_framebuffer_object both have "bind
framebuffer" functions (BindFramebuffer and BindFramebufferEXT). Are
there any differences in functionality between the two functions?
RESOLVED: Yes. Both extensions will create a new framebuffer object
if called with an unused name. However, BindFramebuffer defined in
this extension will generate an INVALID_OPERATION error if the name
provided has not been generated by GenFramebuffer. That error did
not exist in EXT_framebuffer_object, and this extension does not
modify the behavior of BindFramebufferEXT. This difference also
applies to BindRenderbuffer from this extension vs.
BindRenderbufferEXT from EXT_framebuffer_object.
(8) Why don't the new tokens and entry points in this extension have
"ARB" suffixes like other ARB extensions?
RESOLVED: Unlike most ARB extensions, this is a strict subset of
functionality already approved in OpenGL 3.0. This extension
exists only to support that functionality on older hardware that
cannot implement a full OpenGL 3.0 driver. Since there are no
possible behavior changes between the ARB extension and core
features, source code compatibility is improved by not using
suffixes on the extension.
(9) Should color-renderable textures be limited to a subset of
color base internal formats?
RESOLVED: No, all color base internal formats and
sized internal formats should be supported by FBO; the FBO
status can report what works and doesn't work.
The glCheckFramebufferStatus provides a mechanism for FBOs to
report whether or not the FBO configuration is supported or
not (i.e. GL_FRAMEBUFFER_UNSUPPORTED). If implementations
have issues supporting certain color formats for rendering,
the existing FBO mechanism is sufficient to report their lack
of support.
Prior to revision 29, the list of color-renderable base internal
formats did not include LUMINANCE, LUMINANCE_ALPHA, or INTENSITY
(and the EXT version of FBO did not list ALPHA either).
This lead to inconsistent operation of FBO. For example, you
could use a glFramebufferTexture2D to attach a texture that
was LUMINANCE, LUMINANCE_ALPHA, or INTENSITY to an FBO and find
out via glCheckFramebufferStatus that this combination wasn't
considered color-renderable, but if an internal format for one of
these base internal formats was used with glRenderbufferStorage,
then an OpenGL error would be generated according to the
specification. Such inconsistencies are undesirable and
unnecessarily limit the render-to-texture functionality exposed by
some implementations when hardware capable of rendering to
LUMINANCE, LUMINANCE_ALPHA, and INTENSITY textures does exist.
For this reason, revision 29 (specification version 1.1) adds
these previously missing based internal formats. Developers are
warned that some implementations (specification version 1.0)
will report OpenGL errors if glRenderbufferStorage is called for
LUMINANCE, INTENSITY, LUMINANCE_ALPHA formats (or even possibly
ALPHA in the case of the EXT version of FBO).
Some thought was given to introducing a new, one-off extension
(instead of a version 1.1) to allow the LUMINANCE, INTENSITY,
LUMINANCE_ALPHA base internal formats and their respective
sized formats to be color-renderable (both otherwise introduce
no new API). Given the existence of a mechanism for determine
whether or not an FBO is supported, simply providing this version
1.1 clarification was judged to be the most expedient approach.
This approach also provides consistency with other approved
ARB specifications such as ARB_framebuffer_sRGB which describes
(see its issue #9) that formats such as GL_SLUMINANCE8.
(10) Can ARB framebuffer objects be shared between contexts?
ARB_framebuffer_object is supposed to be compatible with
EXT_framebuffer_object, but also a subset of OpenGL 3.0.
EXT_framebuffer_object (rev. 120) explicitly allows sharing in
issue 76, but the 3.0 spec explicitly disallows it in Appendix D.
Resolved: No. ARB_framebuffer_object is intended to capture the
functionality that went into GL 3.0. Furthermore, given that the
entry points and tokens in this extension and the core are identical
there is no way that an implementation could differentiate FBOs
created with this extension from those created by core GL.
ADDITIONAL COMMENTS:
See the "Dependencies on EXT_framebuffer_object" section above for
the interaction behaviour between EXT and non-EXT FBO interfaces.
Revision History
#1, October 20, 2005: jjuliano
- branch from EXT_framebuffer_object
- Delete old issues and revision history
#2, November 28, 2005: jjuliano
- Add issues 1 and 2.
- Describe RenderbufferStorage in terms of color/depth/stencil
renderable with forward reference to 4.4.4.
- Reword the definitions of color/depth/stencil renderable.
- Explicitly state how framebuffer operations write to and read
from texture images.
- Incorporate feedback from Barthold.
#3-draft2, January 16, 2006: jjuliano
- Define the conversions to/from framebuffer in terms of the
internal format(s) of the attached image(s).
- Handle color mask in RGBA to internal component conversion.
- Improve language in section 4.4.5.
- Add dependencies on more extensions.
#4c April 28, 2008: dgkoch
- merge in framebuffer_blit and update other references to
FRAMEBUFFER_EXT and FRAMEBUFFER_BINDING_EXT, eliminating all
references to the obsolete bindings.
#5 May 2, 2008: rbarris, dgkoch
- merge in framebuffer_multisample
#6 May 8, 2008: dgkoch
- rebase against OpenGL 2.1 spec
#7 May 8, 2008: dgkoch
- merge in packed_depth_stencil
#8 May 8, 2008: dgkoch
- add caveat that MSAA to MSAA blit may have issues (khronos bug
#3005)
#9 May 9, 2008: dgkoch
- renamed from EXT_fbo2 to ARB_fbo. Changed all suffixes to _ARB
instead of _EXT.
#10 May 19, 2008: rbarris
- Bugzilla 3013: allow dimension mismatches (esp. depth)
#11 May 21, 2008: dgkoch
- Bugzilla 3014: allow different color formats when using MRT.
- added Issues 4, 5
- deleted FRAMEBUFFER_INCOMPLETE_FORMATS &
FRAMEBUFFER_INCOMPLETE_DIMENSIONS
- added text for proposed resolution of Issue (5)
#12 May 22, 2008: dgkoch
- Bugzilla 3015: define one- and two- component formats to be
color-renderable
- added Issue 6
#13 May 29, 2008: Jon Leech
- Many updates and minor fixes for consistency with the 3.0 spec
draft. Replace DEPTH with DEPTH_COMPONENT in most uses. Increase
MAX_RENDERBUFFER_SIZE to 64 matching MAX_TEXTURE_SIZE (pending
resolution of bug 3454). Pose some open questions preceded by
"***".
#14 June 26: dgkoch
- change MAX_SAMPLES to 0, to indicate the multisampling is not
required. (bug 3551)
#15 July 2: Jon Leech
- More updates for 3.0 spec consistency. Define meaning of <src>
NONE and FRONT_AND_BACK for ReadBuffer() - this was an
oversight introduced with the original extension. Replace
reference to nonexistent table 12.nnn with reference to
table 3.15. Start introducing RED and RG formats from 3.0 spec.
#16 July 10: dgkoch
- backport error change for DrawBuffer in 4.2.1 (bug 3530)
#17 July 12, 2008: Jon Leech
- Use 'layer' instead of 'zoffset' terminology. Add
FramebufferTextureLayer.
- Add framebuffer attachment queries for attachment component
size / type / color encoding.
- Allow framebuffer incomplete if no default framebuffer is made
current, with new framebuffer status error.
- Allow multisample buffers in framebuffer objects.
- Global renaming / simplification to "default framebuffer" and
"framebuffer object". Did not yet re-flow those paragraphs for
ease of comparison.
- Add more introductory material about framebuffers in chapter 2.
- Remove requirement that all color attachments have the same
depth.
- Restrict FBOs and renderbuffers to Gen'ed names as agreed for
3.0.
- Update clipping / buffer intersection / filtering rules for
BlitFramebuffer.
- Allow FRAMEBUFFER as a bind pseudotarget aliasing both read
and draw framebuffer targets. Allow DEPTH_STENCIL_ATTACHMENT
as an attachment alias for both depth and stencil attachments.
- Add Pat's introductory paragraph describing feedback loops in
section 4.4.3.
- Make RED_BITS etc. context queries defined iff all draw color
buffers have the same format.
- Remove "Dependencies" sections for NV extensions since we no
longer refer to their tokens. Need to add some dependencies
sections for new ARB extensions and figure out which language
goes here and which language with those extensions (e.g.
texture_rg, framebuffer_sRGB,
- Many minor non-functional language tweaks to match 3.0 core
language.
#18 July 14, 2008: Rob Barris
- Tidy up introductory/overview section
#19 July 16, 2008: Daniel Koch, Rob Barris
- add interactions with ARB_texture_rg, EXT_texture_array and
NV_float_buffer
- restore FRAMEBUFFER enumerant and restore all the text where
it had been accepted before (removed in version 4).
- allow texture arrays via FramebufferTextureLayer
- removed reference to required format list which we don't have here.
- updated resolution of issue (6)
#20 July 16, 2008: Daniel Koch, Rob Barris
- simplification of language for logical operation when a FB-image
is attached more than once
- add interactions with EXT_texture_integer and ARB_framebuffer_sRGB
- Resolved issues (2), (4) and (5)
- Updated issue (3) (although the list is still not exhaustive)
#21 July 17, 2008: Daniel Koch
- add Issue (7) as suggested by pbrown
- restore FRAMEBUFFER_BINDING alias
- fix incorrect references to FRAMEBUFFER_BINDING
#22 July 17, 2008: Jon Leech
- minor language cleanup for consistency with the 3.0 core spec.
#23 July 24, 2008: Jon Leech
- Use new GLX rendering opcodes for BindRenderbuffer and
BindFramebuffer so they can be semantically distinguished
from the EXT entry points.
- Add GLX protocol for FramebufferTextureLayer.
#24 August 7, 2008: Jon Leech
- Remove ARB suffixes.
#25 August 8, 2008: Jon Leech
- Add missing framebuffer attachment state for component type /
encoding / size to state tables.
#26 August 8, 2008: Jon Leech
- Add missing INDEX token for legacy default framebuffer
color buffer component types.
#27 August 20, 2008: Jon Leech
- Add ALPHA to list of color-renderable base internal formats to
sync with 3.0 spec language.
#28 November 17, 2008: Mark Kilgard & Nigel Stewart
- glFramebufferTexturLayerARB -> glFramebufferTextureLayerARB
(add final e to Texture)
#29 March 12, 2009: Jon Leech
- Edits in chapter 4 intro for consistency with GL core spec
language, including removing the completeness requirement that all
color buffers of an FBO be the same depth. Reflow some text for
readability.
#30 March 31, 2009: Mark Kilgard & Jeff Juliano
- Change color-renderable to be any color texture format.
Fix some typos.
#31 May 27, 2009: Jon Leech
- Change default value of FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE
to NONE (bug 4407).
#32 July 21, 2010: Daniel Koch
- Add issue 10 clarifying that ARB fbos cannot be shared.
#33 July 22, 2011: Jon Leech
- Remove error which disallowed non-multisample <-> sample blits
(bug 7367).
#34 October 2, 2011: Jon Leech
- Bring chapter 6 language changes in sync with the OpenGL 3.0 API
specification phrasing, and fix the description of
GetFramebufferAttachmentParameteriv to use DEPTH and STENCIL as
attachment names, rather than the nonexistent DEPTH_BUFFER and
STENCIL_BUFFER tokens (Bug 8102).
#35 June 29, 2013: Jon Leech
- Rearrange New Tokens section to allow all simple queries to be
queried with GetBooleanv as well, since it's defined to work for
all of them (Bug 6838).
#36, September 23, 2013: Jon Leech
- Specify that undefined behavior results when mixing EXT and
ARB_framebuffer_object / OpenGL 3.0 API framebuffer objects
(Bug 10738).
#37, June 20, 2016: Kevin Rogvin, James Jones
- Specify behaviour of mixing EXT and ARB_framebuffer_object /
OpenGL 3.0 framebuffer objects so that the aliases of the
functions are correctly observed (Bug 1485)
#38, October 6, 2016: Jon Leech
- Remove STENCIL_REF from list of state moved to become framebuffer
dependent (Bug 8422).