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 Specification Update Policy Khronos-approved extension specifications are updated in response to issues and bugs prioritized by the Khronos OpenGL Working Group. For extensions which have been promoted to a core Specification, fixes will first appear in the latest version of that core Specification, and will eventually be backported to the extension document. This policy is described in more detail at https://www.khronos.org/registry/OpenGL/docs/update_policy.php 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 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 parameter of BindFramebuffer, CheckFramebufferStatus, FramebufferTexture{1D|2D|3D}, FramebufferRenderbuffer, and GetFramebufferAttachmentParameteriv: FRAMEBUFFER 0x8D40 READ_FRAMEBUFFER 0x8CA8 DRAW_FRAMEBUFFER 0x8CA9 Accepted by the parameter of BindRenderbuffer, RenderbufferStorage, and GetRenderbufferParameteriv, and returned by GetFramebufferAttachmentParameteriv: RENDERBUFFER 0x8D41 Accepted by the parameter of RenderbufferStorage: STENCIL_INDEX1 0x8D46 STENCIL_INDEX4 0x8D47 STENCIL_INDEX8 0x8D48 STENCIL_INDEX16 0x8D49 Accepted by the 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 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 by GetFramebufferAttachmentParameteriv: SRGB 0x8C40 UNSIGNED_NORMALIZED 0x8C17 FRAMEBUFFER_DEFAULT 0x8218 INDEX 0x8222 Accepted by the 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 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 parameter of DrawPixels, ReadPixels, TexImage1D, TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D, TexSubImage3D, and GetTexImage, by the parameter of CopyPixels, by the parameter of TexImage1D, TexImage2D, TexImage3D, CopyTexImage1D, CopyTexImage2D, and RenderbufferStorage, and returned in the parameter of GetTexLevelParameter and GetRenderbufferParameteriv: DEPTH_STENCIL 0x84F9 Accepted by the parameter of DrawPixels, ReadPixels, TexImage1D, TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D, TexSubImage3D, and GetTexImage: UNSIGNED_INT_24_8 0x84FA Accepted by the parameter of TexImage1D, TexImage2D, TexImage3D, CopyTexImage1D, CopyTexImage2D, and RenderbufferStorage, and returned in the parameter of GetTexLevelParameter and GetRenderbufferParameteriv: DEPTH24_STENCIL8 0x88F0 Accepted by the 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 . Application-created framebuffers, referred to as , 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 a default framebuffer, in which case a framebuffer object must be used to perform all rendering. This is useful for applications needing to perform ." 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 COLOR_INDEX, DEPTH_COMPONENT, DEPTH_STENCIL, and STENCIL_INDEX and the 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: "... 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: "... 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. 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: " 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 is not one of COLOR_INDEX, STENCIL_INDEX, DEPTH_COMPONENT, or DEPTH_STENCIL, then the error INVALID_OPERATION occurs. If is BITMAP and is not COLOR_INDEX or STENCIL_INDEX then the error INVALID_ENUM occurs. If is DEPTH_STENCIL and is not UNSIGNED_INT_24_8 then the error INVALID_ENUM occurs. Some additional constraints on the combinations of and 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 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 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 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) . 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. 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 is TEXTURE_1D, TEXTURE_2D, PROXY_TEXTURE_1D or PROXY_TEXTURE_2D. Using these formats in conjunction with any other 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 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 , 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 . * The texture is attached to one of the attachment points, , of framebuffer object . * The value of TEXTURE_MIN_FILTER is NEAREST or LINEAR, and the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point 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 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 is one of TEXTURE_1D, TEXTURE_2D, TEXTURE_CUBE_MAP, or TEXTURE_3D. Mipmap generation affects the texture image attached to . For cube map textures, an INVALID_OPERATION error is generated if the texture bound to 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 ; each bitplane contains a single bit from each pixel. These bitplanes are grouped into several . 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 buffer, the buffer, the buffer, the buffer, and some number of 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 , 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 is the destination for rendering operations, and the 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: " is an integer reference value that is used in the unsigned stencil comparison. Stencil comparison operations and queries of of clamp its value to the range [0,(2^s)-1], where 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. must be one of the values from tables 4.4 or 10.nnn. In addition, acceptable values for 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 must be one the values listed in table 4.4, which summarizes the constants and the buffers they indicate. In this case, 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, must be one of the values listed in table 10.nnn, which summarizes the constants and the buffers they indicate. In this case, 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 is one of the constants from table 4.4, then the error INVALID_OPERATION results. If is COLOR_ATTACHMENT and 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 a 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. specifies the number of buffers in . is a pointer to an array of symbolic constants specifying the buffer to which each fragment color is written. Each buffer listed in 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 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 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 is greater than MAX_DRAW_BUFFERS. Except for NONE, a buffer may not appear more then once in the array pointed to by . 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 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 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 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 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 argument is STENCIL_INDEX and there is no stencil buffer, or if 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 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 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. must be one of the values from tables 4.4 or 10.nnn. Otherwise, INVALID_ENUM is generated. Further, the acceptable values for 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 (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, 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, 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 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 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 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: " 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 is STENCIL or DEPTH, then it is as if the for ReadPixels were STENCIL_INDEX, or DEPTH_COMPONENT, respectively. If the is DEPTH_STENCIL, then it is as if the for ReadPixels were specified as described in table 4.6b. If the is COLOR, then if the GL is in RGBA mode, it is as if the were RGBA, while if the GL is in color index mode, it is as if the 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. 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 . 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 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. 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 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 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 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 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 set to the desired framebuffer target and 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 is broken. BindFramebuffer fails and an INVALID_OPERATION error is generated if 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 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); contains 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 and zero. Unused names in are silently ignored, as is the value zero. The command void GenFramebuffers(sizei n, uint *ids); returns previously unused framebuffer object names in . 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 . 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 set to RENDERBUFFER and set to the unused name. If 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 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 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 is zero, then any previous binding to is broken and the 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 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 contains 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 RENDERBUFFER and 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 are silently ignored, as is the value zero. The command void GenRenderbuffers( sizei n, uint *renderbuffers ); returns previously unused renderbuffer object names in . 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. must be RENDERBUFFER. must be color-renderable, depth- renderable, or stencil-renderable (as defined in section 4.4.4). and are the dimensions in pixels of the renderbuffer. If either or is greater than MAX_RENDERBUFFER_SIZE, or if 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 , RENDERBUFFER_HEIGHT is set to , and RENDERBUFFER_INTERNAL_FORMAT is set to . If is zero, then RENDERBUFFER_SAMPLES is set to zero. Otherwise 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 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 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); 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. should be set to one of the attachment points of the framebuffer listed in table 1.nnn. must be RENDERBUFFER and should be set to the name of the renderbuffer object to be attached to the framebuffer. must be either zero or the name of an existing renderbuffer object of type , otherwise an INVALID_OPERATION error is generated. If is zero, then the value of is ignored. If is not zero and if FramebufferRenderbuffer is successful, then the renderbuffer named will be used as the logical buffer identified by of the framebuffer currently bound to . 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 . All other state values of the attachment point specified by 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 logical buffer of the framebuffer object bound to framebuffer 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 name zero will detach the image, if any, identified by , in the framebuffer currently bound to . All state values of the attachment point specified by in the object bound to are set to their default values listed in table 5.nnn. Setting 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 , 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 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. 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, 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. must be one of the attachment points of the framebuffer listed in table 1.nnn. If is zero, the image identified by , if any, will be detached from the framebuffer currently bound to . , , and are ignored. All state values of the attachment point specified by are set to their default values listed in table 5.nnn. If is not zero, then must either name an existing texture object with a target of , or must name an existing cube map texture and 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. specifies the mipmap level of the texture image to be attached to the framebuffer. If is TEXTURE_RECTANGLE_ARB, then must be zero. If is TEXTURE_3D, then 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 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 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 , 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. specifies the layer of a 2-dimensional image within a 3-dimensional texture. An INVALID_VALUE error is generated if is larger than the value of MAX_3D_TEXTURE_SIZE-1. For FramebufferTexture1D, if is not zero, then must be TEXTURE_1D. For FramebufferTexture2D, if is not zero, then 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 is not zero, then must be TEXTURE_3D. If 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 of the framebuffer currently bound to . 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 . Additionally, the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for the named attachment point is set to . If is a cube map texture, then the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE the named attachment point is set to . If is a 3D texture, then the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER for the named attachment point is set to . All other state values of the attachment point specified by 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 logical buffer of the framebuffer object bound to framebuffer 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 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 . 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. is an integer indicating the layer number, and is treated identically to the parameter in FramebufferTexture3D. The error INVALID_VALUE is generated if is negative. The error INVALID_OPERATION is generated if is non-zero and is not the name of a three dimensional texture, or one- or two-dimensional array texture. Unlike FramebufferTexture3D, no parameter is accepted. If is non-zero and the command does not result in an error, the framebuffer attachment state corresponding to is updated as in the other FramebufferTexture commands, except that FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER is set to . 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 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 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 is attached to the currently bound framebuffer at attachment point , and - the texture object is currently bound to a texture unit , and - the current fixed-function texture state or programmable vertex and/or fragment processing state makes it possible(*) to sample from the texture object bound to texture unit while either of the following conditions are true: - the value of TEXTURE MIN FILTER for texture object is NEAREST or LINEAR, and the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for attachment point is equal to the value of TEXTURE_BASE_LEVEL for the texture object , or - the value of TEXTURE_MIN_FILTER for texture object 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 is within the range specified by the current values of TEXTURE_BASE_LEVEL to q, inclusive, for the texture object . (q is defined in the Mipmapping discussion of section 3.8.8), (*) For the purpose of this discussion, it is to sample from the texture object bound to texture unit if any of the following are true: - Programmable vertex and fragment processing is disabled and the target of texture object 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 bound to - The active fragment or vertex shader contains any instructions that might sample from the texture object bound to 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 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 : 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 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 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 is not NONE, then it is said that a framebuffer-attachable image, named , is attached to the framebuffer at the attachment point. is identified by the state in as described in section 4.4.2. The framebuffer attachment point is said to be if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for is NONE (i.e., no image is attached), or if all of the following conditions are true: * 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 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 is COLOR_ATTACHMENTi, then must have a color-renderable internal format. * If is DEPTH_ATTACHMENT, then must have a depth-renderable internal format. * If is STENCIL_ATTACHMENT, then 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 is said to be "framebuffer complete" if all the following conditions are true: * 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 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 can be queried by calling enum CheckFramebufferStatus(enum 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 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 is the texture image's border width, and is the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER for the selected logical buffer. For a two-dimensional texture, and are irrelevant; for a one-dimensional texture, , , and are both irrelevant. (x[w], y[w]) corresponds to a border texel if x[w], y[w], or is less than the border width, or if x[w], y[w], or 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 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 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 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 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 is DEPTH_COMPONENT, then each depth component is assigned with the same ordering of rows and images. If 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 is the name of a framebuffer object. If is zero, or if is a non-zero value that is not the name of a 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. must be DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER. FRAMEBUFFER is equivalent to DRAW_FRAMEBUFFER. If the default framebuffer is bound to , then 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 , then must be one of the attachment points of the framebuffer listed in table 1.nnn. If is DEPTH_STENCIL_ATTACHMENT, and different objects are bound to the depth and stencil attachment points of , 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 is FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, then will contain one of NONE, FRAMEBUFFER_DEFAULT, TEXTURE, or RENDERBUFFER, identifying the type of object which contains the attached image. Other values accepted for depend on the type of object, as described below. If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, no framebuffer is bound to . In this case querying 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 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 will contain the number of bits in the corresponding red, green, blue, alpha, depth, or stencil component of the specified . Zero is returned if the requested component is not present in . * If is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, 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 is FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, 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 is FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, 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 is FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, then will contain the name of the texture object which contains the attached image. * If is FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, then will contain the mipmap level of the texture object which contains the attached image. * If is FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE and the texture object named FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is a cube map texture, then will contain the cube map face of the cubemap texture object which contains the attached image. Otherwise will contain the value zero. * If is FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER and the texture object named FRAMEBUFFER_ATTACHMENT_OBJECT_NAME is a three-dimensional texture, then will contain the layer of the 2D image of the 3D texture object which contains the attached image. Otherwise will contain the value zero. Any combinations of framebuffer type and not described above will generate an INVALID_ENUM error." 6.1.16 Renderbuffer Object Queries "The command boolean IsRenderbuffer( uint renderbuffer ); returns TRUE if is the name of a renderbuffer object. If is zero, or if 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. must be RENDERBUFFER and must be one of the symbolic values in table 8.nnn. If the renderbuffer currently bound to is zero, then an INVALID_OPERATION error is generated. Upon successful return from GetRenderbufferParameteriv, if is RENDERBUFFER_WIDTH, RENDERBUFFER_HEIGHT, RENDERBUFFER_INTERNAL_FORMAT, or RENDERBUFFER_SAMPLES, then 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 . If is RENDERBUFFER_RED_SIZE, RENDERBUFFER_GREEN_SIZE, RENDERBUFFER_BLUE_SIZE, RENDERBUFFER_ALPHA_SIZE, RENDERBUFFER_DEPTH_SIZE, or RENDERBUFFER_STENCIL_SIZE, then 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 . 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 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 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 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 constant that is not listed in table 4.4 or 10.nnn. The error INVALID_ENUM is generated if DrawBuffers is called with a 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 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 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 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 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 or that is greater than MAX_RENDERBUFFER_SIZE. The error INVALID_ENUM is generated if RenderbufferStorage is called with an 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 is not the name of a renderbuffer object. The error INVALID_OPERATION is generated if FramebufferTexture{1D|2D|3D} is called and is not the name of a texture object. The error INVALID_VALUE is generated if FramebufferTexture{1D|2D|3D} is called with a that is less than zero. The error INVALID_VALUE is generated if FramebufferTexture2D is called with a that is not zero and is TEXTURE_RECTANGLE_ARB. The error INVALID_VALUE is generated if FramebufferTexture{1D|2D} is called with a that is greater than the log base 2 of MAX_TEXTURE_SIZE and is a 1D or 2D texture. The error INVALID_VALUE is generated if FramebufferTexture2D is called with a that is greater than the log base 2 of MAX_CUBE_MAP_TEXTURE_SIZE and is a cubemap texture. The error INVALID_VALUE is generated if FramebufferTexture3D is called with a greater than the log base 2 of the MAX_3D_TEXTURE_SIZE. The error INVALID_VALUE is generated if FramebufferTexture3D is called with a that is larger than MAX_3D_TEXTURE_SIZE-1. The error INVALID_VALUE is generated by BlitFramebuffer if 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 includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT and is not NEAREST. The error INVALID_OPERATION is generated if BlitFramebuffer is called and 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 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 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 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 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 and 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 when 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 when 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(); // Re-enable rendering to the window glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 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); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, color_tex); } (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 } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // automatically generate mipmaps for (int i=0; i } (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); // 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); } glTexParameteri(TEXTURE_2D, TEXTURE_BASE_LEVEL, 0); glTexParameteri(TEXTURE_2D, TEXTURE_MAX_LEVEL, max); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } (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(); // Re-enable rendering to the window glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 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] // 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); 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); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, tex_color); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex_depthstencil); } 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 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).