| Name | |
| EXT_framebuffer_object | |
| Name Strings | |
| GL_EXT_framebuffer_object | |
| Contributors | |
| Kurt Akeley | |
| Jason Allen | |
| Bob Beretta | |
| Pat Brown | |
| Matt Craighead | |
| Alex Eddy | |
| Cass Everitt | |
| Mark Galvan | |
| Michael Gold | |
| Evan Hart | |
| Jeff Juliano | |
| Mark Kilgard | |
| Dale Kirkland | |
| 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 | |
| Daniel Vogel | |
| Eric Werness | |
| Cliff Woolley | |
| Contacts | |
| Jeff Juliano, NVIDIA Corporation (jjuliano 'at' nvidia.com) | |
| Jeremy Sandmel, Apple Computer (jsandmel 'at' apple.com) | |
| Status | |
| Complete. | |
| Approved by the ARB "superbuffers" Working Group on January 31, 2005. | |
| Despite being controlled by the ARB WG, this is not an officially | |
| approved ARB extension at this time, thus the "EXT" tag. | |
| Version | |
| Last Modified Date: October 6, 2016 | |
| Revision: #123 | |
| Number | |
| 310 | |
| 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_framebuffer_object and OpenGL 3.0 core affect the definition of | |
| this extension. | |
| ARB_texture_rectangle affects the definition of this extension. | |
| ARB_vertex_shader affects the definition of this extension. | |
| EXT_packed_depth_stencil affects the definition of this extension. | |
| NV_float_buffer affects the definition of this extension. | |
| NV_texture_shader affects the definition of this extension. | |
| Written based on the wording of the OpenGL 1.5 specification. | |
| Overview | |
| This extension defines a simple 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 z-offset (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 BindFramebufferEXT 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. | |
| EXT_framebuffer_object, on the other hand, is both simpler to use | |
| and more efficient than ARB_render_texture. The | |
| EXT_framebuffer_object API is contained wholly within the GL API and | |
| has no (non-portable) window-system components. Under | |
| EXT_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. | |
| Glossary of Helpful Terms | |
| logical buffer: | |
| One of the color, depth, or stencil buffers of the | |
| framebuffer. | |
| framebuffer: | |
| The collection of logical buffers and associated state | |
| defining where the output of GL rendering is directed. | |
| texture: | |
| an object which consists of one or more 2D arrays of pixel | |
| images and associated state that can be used as a source of | |
| data during the texture-mapping process described in section | |
| 3.8. | |
| texture image: | |
| one of the 2D arrays of pixels that are part of a texture | |
| object as defined in section 3.8. Texture images contain | |
| and define the texels of the texture object. | |
| renderbuffer: | |
| A new type of storage object which contains a single 2D | |
| array of pixels and associated state that can be used as a | |
| destination for pixel data written during the rendering | |
| process described in Chapter 4. | |
| renderbuffer image: | |
| The 2D array of pixels that is part of a renderbuffer | |
| object. A renderbuffer image contains and defines the | |
| pixels of the renderbuffer object. | |
| framebuffer-attachable image: | |
| A 2D pixel image that can be attached to one of the logical | |
| buffer attachment points of a framebuffer object. Texture | |
| images and renderbuffer images are two examples of | |
| framebuffer-attachable images. | |
| attachment point: | |
| The set of state which references a specific | |
| framebuffer-attachable image, and allows that | |
| framebuffer-attachable image to be used to store the | |
| contents of a logical buffer of a framebuffer object. There | |
| is an attachment point state vector for each color, depth, | |
| and stencil buffer of a framebuffer. | |
| attach: | |
| The act of connecting one object to another object. | |
| An "attach" operation is similar to a "bind" operation in | |
| that both represent a reference to the attached or bound | |
| object for the purpose of managing object lifetimes and both | |
| enable manipulation of the state of the attached or bound | |
| object. | |
| However, an "attach" is also different from a "bind" in that | |
| "binding" an unused object creates a new object, while | |
| "attaching" does not. Additionally, "bind" establishes a | |
| connection between a context and an object, while "attach" | |
| establishes a connection between two objects. | |
| Finally, if object "A" is attached to object "B" and object | |
| "B" is bound to context "C", then in most respects, we treat | |
| "A" as if it is <implicitly> bound to "C". | |
| framebuffer attachment completeness: | |
| Similar to texture "mipmap" or "cube" completeness from | |
| section 3.8.10, defines a minimum set of criteria for | |
| framebuffer attachment points. (for complete definition, | |
| see section 4.4.4.1) | |
| framebuffer completeness: | |
| Similar to texture "mipmap cube completeness", defines a | |
| composite set of "completeness" requirements and | |
| relationships among the attached framebuffer-attachable | |
| images. (for complete definition, see section 4.4.4.2) | |
| Issues | |
| Breaking from past convention, the very large issues section has | |
| been moved to the end of the document. It can be found after | |
| Examples, before Revision History. | |
| New Procedures and Functions | |
| boolean IsRenderbufferEXT(uint renderbuffer); | |
| void BindRenderbufferEXT(enum target, uint renderbuffer); | |
| void DeleteRenderbuffersEXT(sizei n, const uint *renderbuffers); | |
| void GenRenderbuffersEXT(sizei n, uint *renderbuffers); | |
| void RenderbufferStorageEXT(enum target, enum internalformat, | |
| sizei width, sizei height); | |
| void GetRenderbufferParameterivEXT(enum target, enum pname, int *params); | |
| boolean IsFramebufferEXT(uint framebuffer); | |
| void BindFramebufferEXT(enum target, uint framebuffer); | |
| void DeleteFramebuffersEXT(sizei n, const uint *framebuffers); | |
| void GenFramebuffersEXT(sizei n, uint *framebuffers); | |
| enum CheckFramebufferStatusEXT(enum target); | |
| void FramebufferTexture1DEXT(enum target, enum attachment, | |
| enum textarget, uint texture, | |
| int level); | |
| void FramebufferTexture2DEXT(enum target, enum attachment, | |
| enum textarget, uint texture, | |
| int level); | |
| void FramebufferTexture3DEXT(enum target, enum attachment, | |
| enum textarget, uint texture, | |
| int level, int zoffset); | |
| void FramebufferRenderbufferEXT(enum target, enum attachment, | |
| enum renderbuffertarget, uint renderbuffer); | |
| void GetFramebufferAttachmentParameterivEXT(enum target, enum attachment, | |
| enum pname, int *params); | |
| void GenerateMipmapEXT(enum target); | |
| New Types | |
| None. | |
| New Tokens | |
| Accepted by the <target> parameter of BindFramebufferEXT, | |
| CheckFramebufferStatusEXT, FramebufferTexture{1D|2D|3D}EXT, | |
| FramebufferRenderbufferEXT, and | |
| GetFramebufferAttachmentParameterivEXT: | |
| FRAMEBUFFER_EXT 0x8D40 | |
| Accepted by the <target> parameter of BindRenderbufferEXT, | |
| RenderbufferStorageEXT, and GetRenderbufferParameterivEXT, and | |
| returned by GetFramebufferAttachmentParameterivEXT: | |
| RENDERBUFFER_EXT 0x8D41 | |
| Accepted by the <internalformat> parameter of | |
| RenderbufferStorageEXT: | |
| STENCIL_INDEX1_EXT 0x8D46 | |
| STENCIL_INDEX4_EXT 0x8D47 | |
| STENCIL_INDEX8_EXT 0x8D48 | |
| STENCIL_INDEX16_EXT 0x8D49 | |
| Accepted by the <pname> parameter of GetRenderbufferParameterivEXT: | |
| RENDERBUFFER_WIDTH_EXT 0x8D42 | |
| RENDERBUFFER_HEIGHT_EXT 0x8D43 | |
| RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 | |
| RENDERBUFFER_RED_SIZE_EXT 0x8D50 | |
| RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 | |
| RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 | |
| RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 | |
| RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 | |
| RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 | |
| Accepted by the <pname> parameter of | |
| GetFramebufferAttachmentParameterivEXT: | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 | |
| Accepted by the <attachment> parameter of | |
| FramebufferTexture{1D|2D|3D}EXT, FramebufferRenderbufferEXT, and | |
| GetFramebufferAttachmentParameterivEXT | |
| COLOR_ATTACHMENT0_EXT 0x8CE0 | |
| COLOR_ATTACHMENT1_EXT 0x8CE1 | |
| COLOR_ATTACHMENT2_EXT 0x8CE2 | |
| COLOR_ATTACHMENT3_EXT 0x8CE3 | |
| COLOR_ATTACHMENT4_EXT 0x8CE4 | |
| COLOR_ATTACHMENT5_EXT 0x8CE5 | |
| COLOR_ATTACHMENT6_EXT 0x8CE6 | |
| COLOR_ATTACHMENT7_EXT 0x8CE7 | |
| COLOR_ATTACHMENT8_EXT 0x8CE8 | |
| COLOR_ATTACHMENT9_EXT 0x8CE9 | |
| COLOR_ATTACHMENT10_EXT 0x8CEA | |
| COLOR_ATTACHMENT11_EXT 0x8CEB | |
| COLOR_ATTACHMENT12_EXT 0x8CEC | |
| COLOR_ATTACHMENT13_EXT 0x8CED | |
| COLOR_ATTACHMENT14_EXT 0x8CEE | |
| COLOR_ATTACHMENT15_EXT 0x8CEF | |
| DEPTH_ATTACHMENT_EXT 0x8D00 | |
| STENCIL_ATTACHMENT_EXT 0x8D20 | |
| Returned by CheckFramebufferStatusEXT(): | |
| FRAMEBUFFER_COMPLETE_EXT 0x8CD5 | |
| FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 | |
| FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 | |
| FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 | |
| FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA | |
| FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB | |
| FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC | |
| FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD | |
| Accepted by GetIntegerv(): | |
| FRAMEBUFFER_BINDING_EXT 0x8CA6 | |
| RENDERBUFFER_BINDING_EXT 0x8CA7 | |
| MAX_COLOR_ATTACHMENTS_EXT 0x8CDF | |
| MAX_RENDERBUFFER_SIZE_EXT 0x84E8 | |
| Returned by GetError(): | |
| INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 | |
| Additions to Chapter 2 of the 1.5 Specification (OpenGL Operation) | |
| "The GL interacts with two classes of framebuffers: | |
| window-system-provided framebuffers and application-created | |
| framebuffers. There is always one window-system-provided | |
| framebuffer, while application-created framebuffers can 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 window-system-provided framebuffer | |
| are ultimately controlled by the window-system that allocates | |
| framebuffer resources. It is the window-system that determines | |
| which portions of this framebuffer the GL may access at any given | |
| time and that communicates to the GL how those portions are | |
| structured. Therefore, there are no GL commands to configure the | |
| window-system-provided framebuffer. Similarly, display of | |
| framebuffer contents on a CRT monitor (including the transformation | |
| of individual framebuffer values by such techniques as gamma | |
| correction) is not addressed by the GL. Framebuffer configuration | |
| occurs outside of the GL in conjunction with the window-system. | |
| The initialization of a GL context itself occurs when the | |
| window-system allocates a window for GL rendering and is influenced | |
| by the state of the window-system-provided framebuffer." | |
| Additions to Chapter 3 of the OpenGL 1.5 Specification (Rasterization) | |
| In section 3.6.4, page 102, add the following text to the definiton | |
| of DrawPixels: | |
| "If the object bound to FRAMEBUFFER_BINDING_EXT is not "framebuffer | |
| complete" (as defined in section 4.4.4.2), then an attempt to call | |
| DrawPixels will generate the error | |
| INVALID_FRAMEBUFFER_OPERATION_EXT." | |
| In section 3.8.8, add the following text immediately before the | |
| subsection "Mipmapping" on page 151: | |
| "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 FRAMEBUFFER_BINDING_EXT names an application-created | |
| framebuffer object <F>. | |
| * The texture is attached to one of the attachment points, <A>, of | |
| framebuffer object <F>. | |
| * TEXTURE_MIN_FILTER is NEAREST or LINEAR, and the value of | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT for attachment point | |
| <A> is equal to the value of TEXTURE_BASE_LEVEL | |
| -or- | |
| 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_EXT for attachment point | |
| <A> is within the 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: | |
| "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." | |
| 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 GenerateMipmapEXT(enum target); | |
| where <target> is one of TEXTURE_1D, TEXTURE_2D, TEXTURE_CUBE_MAP, | |
| or TEXTURE_3D. Mipmap generation affects the texture image attached | |
| to <target>. For cube map textures, INVALID_OPERATION is generated | |
| if the texture bound to <target> is not cube complete, as defined in | |
| section 3.8.10. | |
| Mipmap generation replaces texture array levels level[base] + 1 | |
| through q with arrays derived from the level[base] array, as | |
| described above under Automatic Mipmap Generation. All other mipmap | |
| arrays, including the level[base] array, are left unchanged by this | |
| computation. For arrays in the range level[base] through q, | |
| inclusive, automatic and manual mipmap generation generate the same | |
| derived arrays, given identical level[base] arrays." | |
| Modify the third paragraph of section 3.8.12, page 157, 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." | |
| Additions to Chapter 4 of the OpenGL 1.5 Specification (Per-Fragment | |
| Operations and the Framebuffer) | |
| On page 170, in the introduction to chapter 4, modify the first | |
| three paragraphs to read as follows: | |
| "The framebuffer consists of a set of pixels arranged as a | |
| two-dimensional array. The height and width of this array may vary | |
| from one GL implementation to another. 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 also vary | |
| depending on the particular GL implementation or context. | |
| Further there are two classes of framebuffers: the default | |
| framebuffer supplied by the window-system-provided and | |
| application-created framebuffer objects. Every GL context has a | |
| single default window-system-provided framebuffer. Applications can | |
| optionally create additional non-displayable framebuffer objects. | |
| (For more information on application-created framebuffer objects see | |
| section 4.4) | |
| Corresponding bits from each pixel in the framebuffer are grouped | |
| together into a bitplane; each bitplane contains a single bit from | |
| each pixel. These bitplanes are grouped into several logical | |
| buffers. These are the color, depth, stencil, and accumulation | |
| 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 | |
| window-system-provided framebuffer or to an application-created | |
| framebuffer object. | |
| For the default window-system-provided framebuffer, the color | |
| buffers are: the front left buffer, the front right buffer, the back | |
| left buffer, the back right buffer, and some number of auxiliary | |
| buffers. Typically, the contents of the front buffers are displayed | |
| on a color monitor while the contents of the back buffers are | |
| invisible. (Monoscopic contexts display only the front left buffer; | |
| stereoscopic contexts display both the front left and the front | |
| right buffers.) The contents of the auxiliary buffers are never | |
| visible. All color buffers must have the same number of bitplanes, | |
| although an implementation or context may choose not to provide | |
| right buffers, back buffers, or auxiliary buffers at all. Further, | |
| an implementation or context may not provide depth, stencil, or | |
| accumulation buffers. | |
| For application-created framebuffer objects, the color buffers are | |
| not visible, and consequently the names of the color buffers are not | |
| related to a display device. The names of the color buffers of an | |
| application-created framebuffer object are: COLOR_ATTACHMENT0_EXT | |
| through COLOR_ATTACHMENTn_EXT. The names of the depth and stencil | |
| buffers are DEPTH_ATTACHMENT_EXT and STENCIL_ATTACHMENT_EXT. For | |
| more information about the buffers of an application-created | |
| framebuffer object, see section 4.4.2. To be considered framebuffer | |
| complete (see section 4.4.4), all color buffers attached to an | |
| application-created framebuffer object must have the same number of | |
| bitplanes. Depth and stencil buffers may optionally be attached to | |
| application-created framebuffers as well. | |
| Color buffers consist of either unsigned integer color indices or R, | |
| G, B, and, optionally, A unsigned integer values. The number of | |
| bitplanes in each of the color buffers, the depth buffer, the | |
| stencil buffer, and the accumulation buffer is dependent on the | |
| currently bound framebuffer. For the default framebuffer, the | |
| number of bitplanes is fixed. For application-created framebuffer | |
| objects, however, the number of bitplanes in a given logical buffer | |
| may change if the state of the corresponding framebuffer attachment | |
| or attached image changes (see sections 4.4.2 and 4.4.5). If an | |
| accumulation buffer is provided, it must have at least as many | |
| bitplanes per R, G, and B color component as do the color buffers." | |
| Add a new paragraph to the end of section 4.1.1, page 171: | |
| "While an application-created framebuffer object is bound to | |
| FRAMEBUFFER_EXT, the pixel ownership test always passes. The pixels | |
| of application-created frambuffer objects are always owned by the | |
| GL, not the window system. Only while the window-system-provided | |
| framebuffer named zero is bound to FRAMEBUFFER_EXT does the window | |
| system control pixel ownership." | |
| Change section 4.1.5, page 174, third paragraph, first two sentences | |
| to read as follows: | |
| "<ref> is an integer reference value that is used in the unsigned | |
| stencil comparison. Stencil comparison operations and queries of | |
| <ref> use the value of <ref> clamped to the range [0, (2^s) - 1], | |
| where s is the current number of bits in the stencil buffer." | |
| 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. However, if the DRAW_BUFFERS state selects a | |
| single framebuffer-attachable image more than once, then an | |
| undefined value is written to those color buffers at the fragment's | |
| (x[w], y[x]) coordinates." | |
| Change section 4.2.1, to read as follows: | |
| "The first such operation is controlling the buffer into which color | |
| values are written. This is accomplished with | |
| void DrawBuffer( enum buf ); | |
| <buf> defines a buffer or set of buffers for writing. <buf> must be | |
| one of the values from tables 4.4 or 10.nnn. Otherwise, | |
| INVALID_ENUM is generated. In addition, acceptable values for <buf> | |
| depend on whether the GL is using the default window-system-provided | |
| framebuffer (i.e., FRAMEBUFFER_BINDING_EXT is zero), or an | |
| application-created framebuffer object (i.e., | |
| FRAMEBUFFER_BINDING_EXT is non-zero). In the initial state, the GL | |
| is bound to the the window-system-provided framebuffer. For more | |
| information about application-created framebuffer objects, see | |
| section 4.4. | |
| If the GL is bound to the window-system-provided framebuffer, then | |
| <buf> must be one the values listed in table 4.4, which summarizes | |
| the constants and the buffers they indicate. In this case, <buf> is | |
| a symbolic constant specifying zero, one, two, or four buffers for | |
| writing. These constants refer to the four potentially visible | |
| buffers front left, front right, back left, and back right, and to | |
| the auxiliary buffers. Arguments other than AUXi that omit | |
| reference to LEFT or RIGHT refer to both left and right buffers. | |
| Arguments other than AUXi that omit reference to FRONT or BACK refer | |
| to both front and back buffers. AUXi enables drawing only to | |
| auxiliary buffer i. Each AUXi adheres to AUXi = AUX0 + i. | |
| If the GL is bound to an application-created framebuffer object, | |
| <buf> must be one of the values listed in table 10.nnn, which | |
| summarizes the constants and the buffers they indicate. In this | |
| case, <buf> is a symbolic constant specifying a single color buffer | |
| for writing. Specifying COLOR_ATTACHMENTi_EXT enables drawing only | |
| to the image attached to the framebuffer at COLOR_ATTACHMENTi_EXT. | |
| Each COLOR_ATTACHMENTi_EXT adheres to COLOR_ATTACHMENTi_EXT = | |
| COLOR_ATTACHMENT0_EXT + i. The intial value of DRAW_BUFFER for | |
| application-created framebuffer objects is COLOR_ATTACHMENT0_EXT. | |
| Symbolic Constant Meaning | |
| ----------------- ------- | |
| NONE no buffer | |
| COLOR_ATTACHMENT0 output fragment color to image attached | |
| at color attachment point 0 | |
| COLOR_ATTACHMENT1 output fragment color to image attached | |
| at color attachment point 1 | |
| ... ... | |
| COLOR_ATTACHMENTn output fragment color to image attached | |
| at color attachment point n, where | |
| n is MAX_COLOR_ATTACHMENTS - 1 | |
| ------------------------------------------------------------------- | |
| Table 10.nnn: Arguments to DrawBuffer(s) and ReadBuffer when the | |
| context is bound to an application-created framebuffer object, and | |
| the buffers they indicate | |
| If the GL is bound to the window-system-provided 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 by | |
| the window-system (including those listed in table 10.nnn), then the | |
| error INVALID_OPERATION results. | |
| If the GL is bound to the application-created framebuffer and | |
| DrawBuffer is supplied with a constant from table 4.4, or | |
| COLOR_ATTACHMENTm where m is greater than or equal to | |
| MAX_COLOR_ATTACHMENTS, then the error INVALID_OPERATION results. | |
| If DrawBuffer is supplied with a constant that is neither legal for | |
| the window-system provided framebuffer nor legal for an | |
| application-created framebuffer object, then the error INVALID_ENUM | |
| results. | |
| The command | |
| void DrawBuffers( sizei n, const enum *bufs ); | |
| defines the draw buffers to which all fragment colors are written. | |
| <n> specifies the number of buffers in <bufs>. <bufs> is a pointer | |
| to an array of symbolic constants specifying the buffer to which | |
| each fragment color is written. | |
| Each enumerant listed in <bufs> must be one of the values from | |
| tables 10.nnn or 11.nnn. Otherwise, INVALID_ENUM is generated. | |
| Further, acceptable values for the constants in <bufs> depend on | |
| whether the GL is using the default window-system-provided | |
| framebuffer (i.e., FRAMEBUFFER_BINDING_EXT is zero), or an | |
| application-created framebuffer object (i.e., | |
| FRAMEBUFFER_BINDING_EXT is non-zero). For more information about | |
| application-created 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 window-system-provided framebuffer, and the buffers that | |
| they indicate. | |
| If the GL is bound to the default window-system-provided | |
| framebuffer, then the each of the constants must be one of the | |
| values listed in table 11.nnn | |
| If the GL is bound to an application-created framebuffer object, | |
| then each of the constants must be one of the values listed in table | |
| 10.nnn. | |
| In both cases, the draw buffers being defined correspond in order to | |
| the respective fragment colors. The draw buffer for fragment colors | |
| beyond <n> is set to NONE. | |
| The maximum number of draw buffers is implementation dependent and | |
| must be at least 1. The number of draw buffers supported can be | |
| queried by calling GetIntegerv with the symbolic constant | |
| MAX_DRAW_BUFFERS. INVALID_VALUE is generated if <n> is greater | |
| than MAX_DRAW_BUFFERS. | |
| Except for NONE, a buffer may not appear more then once in the array | |
| pointed to by <bufs>. Specifying a buffer more then once will | |
| result in the error INVALID_OPERATION. | |
| If fixed-function fragment shading is being performed, DrawBuffers | |
| specifies a set of draw buffers into which the fragment color is | |
| written. | |
| If a fragment shader writes to "gl_FragColor", DrawBuffers specifies | |
| a set of draw buffers into which the single fragment color defined | |
| by "gl_FragColor" is written. If a fragment shader writes to gl | |
| FragData, DrawBuffers specifies a set of draw buffers into which | |
| each of the multiple fragment colors defined by "gl_FragData" are | |
| separately written. If a fragment shader writes to neither gl | |
| FragColor nor "gl_FragData", the values of the fragment colors | |
| following shader execution are undefined, and may differ for each | |
| fragment color. | |
| For both window-system-provided and application-created | |
| framebuffers, the constants FRONT, BACK, LEFT, RIGHT, and | |
| FRONT_AND_BACK are not valid in the <bufs> array passed to | |
| DrawBuffers, and will result in the error INVALID_OPERATION. This | |
| restriction is because these constants may themselves refer to | |
| multiple buffers, as shown in table 4.4. | |
| If the GL is bound to the window-system-provided 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, then the error INVALID_OPERATION results. | |
| If the GL is bound to the application-created framebuffer and | |
| DrawBuffers is supplied with a constant from table 11.nnn, or | |
| COLOR_ATTACHMENTm where m is greater than or equal to | |
| MAX_COLOR_ATTACHMENTS, then the error INVALID_OPERATION results. | |
| If DrawBuffers is supplied with a constant that is neither legal for | |
| the window-system provided framebuffer nor legal for an | |
| application-created framebuffer object, then the error INVALID_ENUM | |
| 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 is an integer | |
| for each supported fragment color. For the default | |
| window-system-provided 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 application-created framebuffer | |
| objects, the initial value of draw buffer for fragment color zero is | |
| COLOR_ATTACHMENT0_EXT. For both the window-system-provided | |
| framebuffer and application-created framebuffers, the initial state | |
| of draw buffers for fragment colors other then zero is NONE." | |
| Modify section 4.2.2, page 185, third paragraph to read as follows: | |
| "The command | |
| void StencilMask( uint mask ); | |
| controls the writing of particular bits into the stencil planes. The | |
| least significant s bits of mask comprise an integer mask (s is the | |
| number of bits in the stencil buffer), just as for IndexMask. The | |
| initial state is for the stencil plane mask to be 32 ones." | |
| In section 4.3.2, page 190, modify the first two paragraphs of the | |
| definition of ReadBuffer to read as follows: | |
| "The command | |
| void ReadBuffer( enum src ); | |
| takes a symbolic constant as argument. <src> must be one of the | |
| values from tables 4.4 or 10.nnn. Otherwise, INVALID_ENUM is | |
| generated. Further, the acceptable values for <src> depend on | |
| whether the GL is using the default window-system-provided | |
| framebuffer (i.e., FRAMEBUFFER_BINDING_EXT is zero), or an | |
| application-created framebuffer object (i.e., | |
| FRAMEBUFFER_BINDING_EXT is non-zero). For more information about | |
| application-created framebuffer objects, see section 4.4. | |
| If the object bound to FRAMEBUFFER_BINDING_EXT is not "framebuffer | |
| complete" (as defined in section 4.4.4.2), then ReadPixels generates | |
| the error INVALID_FRAMEBUFFER_OPERATION_EXT. If ReadBuffer is | |
| supplied with a constant that is neither legal for the window-system | |
| provided framebuffer, nor legal for an application-created | |
| framebuffer object, then the error INVALID_ENUM results. | |
| When FRAMEBUFFER_BINDING_EXT is zero, i.e. the default | |
| window-system-provided framebuffer, <src> must be one of the values | |
| listed in table 4.4. 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 | |
| window-system-provided framebuffer, the initial setting for | |
| ReadBuffer is FRONT if there is no back buffer and BACK otherwise. | |
| When the GL is using an application-created framebuffer object, | |
| <src> must be one of the values listed in table 10.nnn, including | |
| NONE. In a manner analogous to how the DRAW_BUFFERs state is | |
| handled, specifying COLOR_ATTACHMENTi_EXT enables reading from the | |
| image attached to the framebuffer at COLOR_ATTACHMENTi_EXT. | |
| ReadPixels generates INVALID_OPERATION if it attempts to select a | |
| color buffer while READ_BUFFER is NONE. For application-created | |
| framebuffer objects, the initial setting for ReadBuffer is | |
| COLOR_ATTACHMENT0_EXT. | |
| 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 FRAMEBUFFER_BINDING_EXT 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", add a paragraph before | |
| "Conversion of RGBA values" on page 191: | |
| "When 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. The internal component values are | |
| converted to red, green, blue, and alpha values as specified in the | |
| row of table 12.nnn corresponding to the internal format of the | |
| image attached to READ_BUFFER." | |
| Add the following text to section 4.3.3, page 194, inside the | |
| definiton of CopyPixels: | |
| "Furthermore, 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*. INVALID_FRAMEBUFFER_OPERATION_EXT will be | |
| generated if an attempt is made to execute one of these operations, | |
| or CopyPixels, while the object bound to FRAMEBUFFER_BINDING_EXT is | |
| not "framebuffer complete" (as defined in section 4.4.4.2)." | |
| 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, stencil, accum, and aux logical buffers. 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 operations described in chapter 4 affect the images attached to | |
| the framebuffer object bound to the target FRAMEBUFFER_EXT. By | |
| default, framebuffer bound to the target FRAMEBUFFER_EXT is zero, | |
| specifying the default implementation dependent framebuffer provided | |
| by the windowing system. When the framebuffer bound to target | |
| FRAMEBUFFER_EXT is not zero, but instead names an | |
| application-created framebuffer object, then the operations | |
| described in chapter 4 affect the application-created framebuffer | |
| object rather than the default framebuffer. | |
| The namespace for framebuffer objects is the unsigned integers, with | |
| zero reserved by the GL to refer to the default framebuffer. A | |
| framebuffer object is created by binding an unused name to the | |
| target FRAMEBUFFER_EXT. The binding is effected by calling | |
| void BindFramebufferEXT(enum target, uint framebuffer); | |
| with <target> set to FRAMEBUFFER_EXT and <framebuffer> set to the | |
| unused 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. There are | |
| MAX_COLOR_ATTACHMENTS_EXT color attachment points, plus one each for | |
| the depth and stencil attachment points. | |
| BindFramebufferEXT may also be used to bind an existing framebuffer | |
| object to <target>. If the bind is successful no change is made to | |
| the state of the bound framebuffer object and any previous binding | |
| to <target> is broken. The current FRAMEBUFFER_EXT binding can be | |
| queried using GetIntegerv(FRAMEBUFFER_BINDING_EXT). | |
| While a framebuffer object is bound to the target FRAMEBUFFER_EXT, | |
| 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. In | |
| particular, 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 | |
| currently bound framebuffer object. The framebuffer object bound to | |
| the target FRAMEBUFFER_EXT is used as the destination of fragment | |
| operations and as the source of pixel reads such as ReadPixels, as | |
| described in chapter 4. | |
| In the initial state, the reserved name zero is bound to the target | |
| FRAMEBUFFER_EXT. There is no application-created framebuffer object | |
| corresponding to the name zero. Instead, the name zero refers to | |
| the window-system-provided framebuffer. All queries and operations | |
| on the framebuffer while the name zero is bound to the target | |
| FRAMEBUFFER_EXT operate on this default framebuffer. On some | |
| implementations, the properties of the default | |
| window-system-provided framebuffer can change over time (e.g., in | |
| response to window-system events such as attaching the context to a | |
| new window-system drawable.) | |
| Application-created framebuffer objects (i.e., those with a non-zero | |
| name) differ from the default window-system-provided framebuffer in | |
| a few important ways. First and foremost, unlike the | |
| window-system-provided framebuffer, application-created-framebuffers | |
| 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, | |
| application-created 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_EXT | |
| through COLOR_ATTACHMENTn_EXT. | |
| - The only depth buffer bitplanes are the ones defined by the | |
| framebuffer attachment point DEPTH_ATTACHMENT_EXT. | |
| - The only stencil buffer bitplanes are the ones defined by | |
| the framebuffer attachment point STENCIL_ATTACHMENT_EXT. | |
| - There is no multisample buffer so the value of the | |
| implementation-dependent state variables SAMPLES and | |
| SAMPLE_BUFFERS are both 0 | |
| - 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. | |
| Framebuffer objects are deleted by calling | |
| void DeleteFramebuffersEXT(sizei n, uint *framebuffers); | |
| <framebuffers> contains <n> names of framebuffer objects to be | |
| deleted. After a framebuffer object is deleted, it has no | |
| attachments, and its name is again unused. If a framebuffer that is | |
| currently bound to the target FRAMEBUFFER_EXT is deleted, it is as | |
| though BindFramebufferEXT had been executed with the <target> of | |
| FRAMEBUFFER_EXT and <framebuffer> of zero. Unused names in | |
| <framebuffers> are silently ignored, as is the value zero. | |
| The command | |
| void GenFramebuffersEXT(sizei n, uint *ids); | |
| returns <n> previously unused framebuffer object names in <ids>. | |
| These names are marked as used, for the purposes of | |
| GenFramebuffersEXT only, but they acquire state and type only when | |
| they are first bound, just as if they were unused. | |
| 4.4.2 Attaching Images to Framebuffer Objects | |
| Framebuffer-attachable images may be attached to, and detached from, | |
| application-created framebuffer objects. In contrast, the image | |
| attachments of the window-system-provided framebuffer may not be | |
| changed by the GL. | |
| A single framebuffer-attachable image may be attached to multiple | |
| application-created framebuffer objects, potentially avoiding some | |
| data copies, and possibly decreasing memory consumption. | |
| For each logical buffer, the framebuffer object stores a set of | |
| state which defines the logical buffer's "attachment point". The | |
| "attachment point" state contains enough information to identify the | |
| single image attached to the attachment point, or to indicate that | |
| no image is attached. The per-logical buffer "attachment point" | |
| state is listed in table 5.nnn | |
| There are two types of framebuffer-attachable images: the image of a | |
| renderbuffer object, and an image of a texture object. | |
| 4.4.2.1 Renderbuffer Objects | |
| A renderbuffer is a data storage object containing a single image of | |
| a renderable internal format. GL provides the methods described | |
| below to allocate and delete a renderbuffer's image, and to attach a | |
| renderbuffer's image to a framebuffer object. | |
| The name space for renderbuffer objects is the unsigned integers, | |
| with zero reserved for the GL. A renderbuffer object is created by | |
| binding an unused name to RENDERBUFFER_EXT. The binding is effected | |
| by calling | |
| void BindRenderbufferEXT( enum target, uint renderbuffer ); | |
| with <target> set to RENDERBUFFER_EXT and <renderbuffer> set to the | |
| unused name. If <renderbuffer> is not zero, then the resulting | |
| renderbuffer object is a new state vector, initialized with a | |
| zero-sized memory buffer, and comprising the state values listed in | |
| Table 8.nnn. Any previous binding to <target> is broken. | |
| BindRenderbufferEXT may also be used to bind an existing | |
| renderbuffer object. If the bind is successful, no change is made | |
| to the state of the newly bound renderbuffer object, and any | |
| previous binding to <target> is broken. | |
| While a renderbuffer object is bound, GL operations on the target to | |
| which it is bound affect the bound renderbuffer object, and queries | |
| of the target to which a renderbuffer object is bound return state | |
| from the bound object. | |
| The name zero is reserved. A renderbuffer object cannot be created | |
| with the name zero. If <renderbuffer> is zero, then any previous | |
| binding to <target> is broken and the <target> binding is restored | |
| to the initial state. | |
| In the initial state, the reserved name zero is bound to | |
| RENDERBUFFER_EXT. There is no renderbuffer object corresponding to | |
| the name zero, so client attempts to modify or query renderbuffer | |
| state for the target RENDERBUFFER_EXT while zero is bound will | |
| generate GL errors, as described in section 6.1.3. | |
| Using GetIntegerv, the current RENDERBUFFER_EXT binding can be | |
| queried as RENDERBUFFER_BINDING_EXT. | |
| Renderbuffer objects are deleted by calling | |
| void DeleteRenderbuffersEXT( sizei n, const uint *renderbuffers ); | |
| where <renderbuffers> contains n names of renderbuffer objects to be | |
| deleted. After a renderbuffer object is deleted, it has no | |
| contents, and its name is again unused. If a renderbuffer that is | |
| currently bound to RENDERBUFFER_EXT is deleted, it is as though | |
| BindRenderbufferEXT had been executed with the <target> | |
| RENDERBUFFER_EXT and <name> of zero. Additionally, special care | |
| must be taken when deleting a renderbuffer if the image of the | |
| renderbuffer is attached to a framebuffer object. (See section | |
| 4.4.2.2 for details). Unused names in <renderbuffers> are silently | |
| ignored, as is the value zero. | |
| The command | |
| void GenRenderbuffersEXT( sizei n, uint *renderbuffers ); | |
| returns <n> previously unused renderbuffer object names in | |
| <renderbuffers>. These names are marked as used, for the purposes | |
| of GenRenderbuffersEXT only, but they acquire renderbuffer state | |
| only when they are first bound, just as if they were unused. | |
| The command | |
| void RenderbufferStorageEXT(enum target, enum internalformat, | |
| sizei width, sizei height); | |
| establishes the data storage, format, and dimensions of a | |
| renderbuffer object's image. <target> must be RENDERBUFFER_EXT. | |
| <internalformat> must be color-renderable, depth-renderable, or | |
| stencil-renderable (as defined in section 4.4.4). <width> and | |
| <height> are the dimensions in pixels of the renderbuffer. If | |
| either <width> or <height> is greater than | |
| MAX_RENDERBUFFER_SIZE_EXT, the 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. RenderbufferStorageEXT deletes | |
| any existing data store for the renderbuffer and the contents of the | |
| data store after calling RenderbufferStorageEXT are undefined. | |
| Sized Base S | |
| Internal Format Internal format Bits | |
| --------------- --------------- ---- | |
| STENCIL_INDEX1_EXT STENCIL_INDEX 1 | |
| STENCIL_INDEX4_EXT STENCIL_INDEX 4 | |
| STENCIL_INDEX8_EXT STENCIL_INDEX 8 | |
| STENCIL_INDEX16_EXT 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 actual resolution in bits of each component of the | |
| allocated image can be queried with GetRenderbufferParameteriv as | |
| described in section 6.1.3. | |
| 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 FramebufferRenderbufferEXT(enum target, | |
| enum attachment, | |
| enum renderbuffertarget, | |
| uint renderbuffer); | |
| <target> must be FRAMEBUFFER_EXT. INVALID_OPERATION is generated if | |
| the current value of FRAMEBUFFER_BINDING_EXT is zero when | |
| FramebufferRenderbufferEXT is called. <attachment> should be set to | |
| one of the attachment points of the framebuffer listed in table | |
| 1.nnn. <renderbuffertarget> must be RENDERBUFFER_EXT and | |
| <renderbuffer> should be set to the name of the renderbuffer object | |
| to be attached to the framebuffer. <renderbuffer> must be either | |
| zero or the name of an existing renderbuffer object of type | |
| <renderbuffertarget>, otherwise INVALID_OPERATION is generated. If | |
| <renderbuffer> is zero, then the value of <renderbuffertarget> is | |
| ignored. | |
| If <renderbuffer> is not zero and if FramebufferRenderbufferEXT is | |
| successful, then the renderbuffer named <renderbuffer> will be used | |
| as the logical buffer identified by <attachment> of the framebuffer | |
| currently bound to <target>. The value of | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT for the specified attachment | |
| point is set to RENDERBUFFER_EXT and the value of | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT is set to <renderbuffer>. All | |
| other state values of the attachment point specified by <attachment> | |
| are set to their default values listed in table 5.nnn. No change is | |
| made to the state of the renderbuffer object and any previous | |
| attachment to the <attachment> logical buffer of the framebuffer | |
| object bound to framebuffer <target> is broken. If, on the other | |
| hand, the attachment is not successful, then no change is made to | |
| the state of either the renderbuffer object or the framebuffer | |
| object. | |
| Calling FramebufferRenderbufferEXT with the <renderbuffer> name zero | |
| will detach the image, if any, identified by <attachment>, in the | |
| framebuffer currently bound to <target>. All state values of the | |
| attachment point specified by <attachment> in the object bound to | |
| <target> are set to their default values listed in table 5.nnn. | |
| 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 FramebufferRenderbufferEXT() had been called, with | |
| a <renderbuffer> of 0, for each attachment point to which this image | |
| was attached in the currently bound framebuffer. In other words, | |
| this renderbuffer image is first detached from all attachment points | |
| in the currently bound framebuffer. Note that the renderbuffer | |
| image is specifically *not* detached from any non-bound | |
| framebuffers. Detaching the image from any non-bound framebuffers | |
| is the responsibility of the application. | |
| Name of attachment | |
| -------------------------------------------------------------------------------------- | |
| COLOR_ATTACHMENT0_EXT ... COLOR_ATTACHMENTn_EXT (where n is from 0 to MAX_COLOR_ATTACHMENTS_EXT-1) | |
| DEPTH_ATTACHMENT_EXT | |
| STENCIL_ATTACHMENT_EXT | |
| -------------------------------------------------------------------------------------- | |
| Table 1.nnn: "List of framebuffer attachment points" | |
| 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 FramebufferTexture1DEXT(enum target, enum attachment, | |
| enum textarget, uint texture, | |
| int level); | |
| void FramebufferTexture2DEXT(enum target, enum attachment, | |
| enum textarget, uint texture, | |
| int level); | |
| void FramebufferTexture3DEXT(enum target, enum attachment, | |
| enum textarget, uint texture, | |
| int level, int zoffset); | |
| In all three routines, <target> must be FRAMEBUFFER_EXT. | |
| INVALID_OPERATION is generated if the current value of | |
| FRAMEBUFFER_BINDING_EXT is zero when FramebufferTexture{1D|2D|3D}EXT | |
| is called. <attachment> must be one of the attachment points of the | |
| framebuffer listed in table 1.nnn. | |
| In all three routines, if <texture> is zero, then <textarget>, | |
| <level>, and <zoffset> are ignored. If <texture> is not zero, then | |
| <texture> must either name an existing texture object with a target | |
| of <textarget>, or <texture> must name an existing cube map texture | |
| and <textarget> must be one of: TEXTURE_CUBE_MAP_POSITIVE_X, | |
| TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z, | |
| TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_Y, or | |
| TEXTURE_CUBE_MAP_NEGATIVE_Z. Otherwise, GL_INVALID_OPERATION is | |
| generated. | |
| <level> specifies the mipmap level of the texture image to be | |
| attached to the framebuffer. | |
| If <textarget> is TEXTURE_RECTANGLE_ARB, then <level> must be zero. | |
| If <textarget> is TEXTURE_3D, then <level> must be greater than or | |
| equal to zero and less than or equal to log base 2 of | |
| MAX_3D_TEXTURE_SIZE. If <textarget> is one of | |
| TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, | |
| TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X, | |
| TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z, then | |
| <level> must be greater than or equal to zero and less than or equal | |
| to log base 2 of MAX_CUBE_MAP_TEXTURE_SIZE. For all other values of | |
| <textarget>, <level> must be greater than or equal to zero and no | |
| larger than log base 2 of MAX_TEXTURE_SIZE. Otherwise, | |
| INVALID_VALUE is generated. | |
| <zoffset> specifies the z-offset of a 2-dimensional image within a | |
| 3-dimensional texture. INVALID_VALUE is generated if <zoffset> is | |
| larger than MAX_3D_TEXTURE_SIZE-1. | |
| For FramebufferTexture1DEXT, if <texture> is not zero, then | |
| <textarget> must be TEXTURE_1D. | |
| For FramebufferTexture2DEXT, if <texture> is not zero, then | |
| <textarget> must be one of: TEXTURE_2D, TEXTURE_RECTANGLE_ARB, | |
| TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, | |
| TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_X, | |
| TEXTURE_CUBE_MAP_NEGATIVE_Y, or TEXTURE_CUBE_MAP_NEGATIVE_Z. | |
| For FramebufferTexture3DEXT, if <texture> is not zero, then | |
| <textarget> must be TEXTURE_3D. | |
| If <texture> is not zero, and if FramebufferTexture{1D|2D|3D}EXT is | |
| successful, then the specified texture image will be used as the | |
| logical buffer identified by <attachment> of the framebuffer | |
| currently bound to <target>. The value of | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT for the specified attachment | |
| point is set to TEXTURE and the value of | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT is set to <texture>. | |
| Additionally, the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL for | |
| the named attachment point is set to <level>. If <texture> is a | |
| cubemap texture then, the value of | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE the named attachment | |
| point is set to <textarget>. If <texture> is a 3D texture, then the | |
| value of FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET for the named | |
| attachment point is set to <zoffset>. All other state values of the | |
| attachment point specified by <attachment> are set to their default | |
| values listed in table 5.nnn. No change is made to the state of the | |
| texture object, and any previous attachment to the <attachment> | |
| logical buffer of the framebuffer object bound to framebuffer | |
| <target> is broken. If, on the other hand, the attachment is not | |
| successful, then no change is made to the state of either the | |
| texture object or the framebuffer object. | |
| Calling FramebufferTexture{1D|2D|3D}EXT with <texture> name zero | |
| will detach the image identified by <attachment>, if any, in the | |
| framebuffer currently bound to <target>. All state values of the | |
| attachment point specified by <attachment> are set to their default | |
| values listed in table 5.nnn. | |
| 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{1D|2D|3D}EXT() had been called, with a | |
| <texture> of 0, 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 | |
| Special precautions need to be taken to avoid attaching a texture | |
| image to the currently bound framebuffer while the texture object is | |
| currently bound and enabled for texturing. Doing so could lead to | |
| the creation of a "feedback loop" between the writing of pixels by | |
| the GL's rendering operations and the simultaneous reading of those | |
| same pixels when used as texels in the currently bound texture. In | |
| this scenario, the framebuffer will be considered framebuffer | |
| complete (see section 4.4.4), but the values of fragments rendered | |
| while in this state will be undefined. The values of texture | |
| samples may be undefined as well, as described in section 3.8.8. | |
| Specifically, the values of rendered fragments are undefined if all | |
| of the following conditions are true: | |
| - an image from texture object <T> is attached to the currently | |
| bound framebuffer at attachment point <A>, and | |
| - the texture object <T> is currently bound to a texture unit | |
| <U>, and | |
| - the current fixed-function texture state or programmable | |
| vertex and/or fragment processing state makes it possible(*) | |
| to sample from the texture object <T> bound to texture unit | |
| <U> | |
| while either of the following conditions are true: | |
| - the value of TEXTURE MIN FILTER for texture object <T> is | |
| NEAREST or LINEAR, and the value of | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT for attachment point | |
| <A> is equal to the value of TEXTURE_BASE_LEVEL for the | |
| texture object <T>, or | |
| - the value of TEXTURE_MIN_FILTER for texture object <T> is one | |
| of NEAREST_MIPMAP_NEAREST, NEAREST_MIPMAP LINEAR, LINEAR | |
| MIPMAP_NEAREST, or LINEAR_MIPMAP_LINEAR, and the value of | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT for attachment point | |
| <A> is within the the range specified by the current values of | |
| TEXTURE_BASE_LEVEL to q, inclusive, for the texture object | |
| <T>. (q is defined in the Mipmapping discussion of section | |
| 3.8.8), | |
| (*) For the purpose of this discussion, we consider it "possible" | |
| to sample from the texture object <T> bound to texture unit <U>" | |
| if any of the following are true: | |
| - programmable vertex and fragment processing is disabled | |
| and the target of texture object <T> is enabled according | |
| to the texture target precedence rules of section 3.8.15, | |
| or | |
| - if FRAGMENT_PROGRAM_ARB is enabled and the currently bound | |
| fragment program contains any instructions that | |
| sample from the texture object <T> bound to <U>, | |
| or | |
| - if the active fragment or vertex shader contains | |
| any instructions that might sample from the texture object <T> bound | |
| to <U> if even those instructions might only be executed | |
| conditionally. | |
| Note that if TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL exclude any | |
| levels containing image(s) attached to the currently bound | |
| framebuffer, then the above conditions will not be met, (i.e., the | |
| above rule will not cause the values of rendered fragments to be | |
| undefined.) | |
| 4.4.4 Framebuffer Completeness | |
| A framebuffer 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. A framebuffer must be complete to effectively be used | |
| as the destination for GL framebuffer rendering operations and the | |
| source for GL framebuffer read operations. | |
| The internal formats of the attached images can affect the | |
| completeness of the framebuffer, so it is useful to first define the | |
| relationship between the internal format of an image and the | |
| attachment points to which it can be attached. | |
| * The following base internal formats from table 3.15 are | |
| "color-renderable": RGB, RGBA, FLOAT_R_NV, FLOAT_RG_NV, | |
| FLOAT_RGB_NV, and FLOAT_RGBA_NV. The sized internal formats | |
| from table 3.16 that have a color-renderable base internal | |
| format are also color-renderable. No other formats, including | |
| compressed internal formats, are color-renderable. | |
| * An internal format is "depth-renderable" if it is | |
| DEPTH_COMPONENT, or if it is one of the sized internal formats | |
| from table 3.16 that has a depth-renderable base internal | |
| format. No other formats are depth-renderable. | |
| * An internal format is "stencil-renderable" if it is | |
| STENCIL_INDEX, or if it is one of the sized internal formats | |
| from table 2.nnn that has a stencil-renderable base internal | |
| format. No other formats are stencil-renderable. | |
| 4.4.4.1 Framebuffer Attachment Completeness | |
| If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT for the | |
| framebuffer attachment point <attachment> is not NONE, then it is | |
| said that a framebuffer-attachable image, named <image>, is attached | |
| to the framebuffer at the attachment point. <image> is identified | |
| by the state in <attachment> as described in section 4.4.2. | |
| The framebuffer attachment point <attachment> is said to be | |
| "framebuffer attachment complete" if the value of | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT for <attachment> is NONE | |
| (i.e., no image is attached), or if all of the following conditions | |
| are true: | |
| * <image> is a component of an existing object with the name | |
| specified by FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, and of the | |
| type specified by FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT. | |
| * The width and height of <image> must be non-zero. | |
| * If FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is TEXTURE and | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT names a 3-dimensional | |
| texture, then FRAMEBUFFER_ATTACHMENT_TEXTURE_ZOFFSET_EXT must be | |
| smaller than the depth of the texture. | |
| * If <attachment> is one of COLOR_ATTACHMENT0_EXT through | |
| COLOR_ATTACHMENTn_EXT, then <image> must have a color-renderable | |
| internal format. | |
| * If <attachment> is DEPTH_ATTACHMENT_EXT, then <image> must have | |
| a depth-renderable internal format. | |
| * If <attachment> is STENCIL_ATTACHMENT_EXT, then <image> must | |
| have a stencil-renderable internal format. | |
| 4.4.4.2 Framebuffer Completeness | |
| In this subsection, each rule is followed by an error enum enclosed | |
| in { brackets }. Sections 4.4.4.2 and 4.4.4.3 explains the | |
| relevance of the error enums. | |
| The framebuffer object <target> is said to be "framebuffer complete" | |
| if it is the window-system-provided framebuffer, or if all the | |
| following conditons are true: | |
| * All framebuffer attachment points are "framebuffer attachment | |
| complete". | |
| { FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT } | |
| * There is at least one image attached to the framebuffer. | |
| { FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT } | |
| * All attached images have the same width and height. | |
| { FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT } | |
| * All images attached to the attachment points | |
| COLOR_ATTACHMENT0_EXT through COLOR_ATTACHMENTn_EXT must have | |
| the same internal format. | |
| { FRAMEBUFFER_INCOMPLETE_FORMATS_EXT } | |
| * The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT must not be | |
| NONE for any color attachment point(s) named by DRAW_BUFFERi. | |
| { FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT } | |
| * If READ_BUFFER is not NONE, then the value of | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT must not be NONE for the | |
| color attachment point named by READ_BUFFER. | |
| { FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT } | |
| * The combination of internal formats of the attached | |
| images does not violate an implementation-dependent set of | |
| restrictions. | |
| { FRAMEBUFFER_UNSUPPORTED_EXT } | |
| The enum in { brackets } after each clause of the framebuffer | |
| completeness rules specifies the return value of | |
| CheckFramebufferStatusEXT (see below) that is generated when that | |
| clause is violated. If more than one clause is violated, it is | |
| implementation-dependent exactly which enum will be returned by | |
| CheckFramebufferStatusEXT. | |
| Performing any of the following actions may change whether the | |
| framebuffer is considered complete or incomplete. | |
| - Binding to a different framebuffer with BindFramebufferEXT. | |
| - Attaching an image to the framebuffer with | |
| FramebufferTexture{1D|2D|3D}EXT or FramebufferRenderbufferEXT. | |
| - Detaching an image from the framebuffer with | |
| FramebufferTexture{1D|2D|3D}EXT or FramebufferRenderbufferEXT. | |
| - Changing the width, height, or internal format of a texture | |
| image that is attached to the framebuffer by calling | |
| {Copy|Compressed}TexImage{1D|2D|3D}. | |
| - Changing the width, height, or internal format of a renderbuffer | |
| that is attached to the framebuffer by calling | |
| RenderbufferStorageEXT. | |
| - 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. | |
| 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_EXT. There | |
| must exist, however, at least one combination of internal formats | |
| for which the framebuffer cannot be FRAMEBUFFER_UNSUPPORTED_EXT. | |
| Because of the "implementation-dependent" clause of the framebuffer | |
| completeness test in particular, and because framebuffer | |
| completeness can change when the set of attached images is modified, | |
| it is strongly advised, though is not required, that an application | |
| check to see if the framebuffer is complete prior to rendering. The | |
| status of the framebuffer object currently bound to <target> can be | |
| queried by calling | |
| enum CheckFramebufferStatusEXT(enum target); | |
| If <target> is not FRAMEBUFFER_EXT, INVALID_ENUM is generated. If | |
| CheckFramebufferStatusEXT is called within a Begin/End pair, | |
| INVALID_OPERATION is generated. If CheckFramebufferStatusEXT | |
| generates an error, 0 is returned. | |
| Otherwise, an enum is returned that identifies whether | |
| or not the framebuffer bound to <target> is complete, and if not | |
| complete the enum identifies one of the rules of framebuffer | |
| completeness that is violated. If the framebuffer is complete, then | |
| FRAMEBUFFER_COMPLETE_EXT is returned. | |
| 4.4.4.3 Effects of Framebuffer Completeness on Framebuffer Operations | |
| If the currently bound framebuffer is not framebuffer complete, then | |
| it is an error to attempt to use the framebuffer for writing or | |
| reading. 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_EXT 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 | |
| FRAMEBUFFER_BINDING_EXT, to the state of the currently bound | |
| framebuffer object, or to an image attached to the currently bound | |
| framebuffer object. | |
| When FRAMEBUFFER_BINDING_EXT is zero, the values of the state | |
| variables listed in table 9.nnn are implementation defined. | |
| When FRAMEBUFFER_BINDING_EXT 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 FRAMEBUFFER_BINDING_EXT 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 | |
| FRAMEBUFFER_BINDING_EXT, the state of the currently bound | |
| framebuffer object, and the state of the images attached to the | |
| currently bound framebuffer object. | |
| XXX [from jon leech] describe derivation of red green and blue size | |
| 4.4.6 Mapping between Pixel and Element in Attached Image | |
| When FRAMEBUFFER_BINDING_EXT 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 = (zoffset - b) | |
| where b is the texture image's border width, and zoffset is the | |
| value of FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET for the selected | |
| logical buffer. For a two-dimensional texture, k and zoffset are | |
| irrelevant; for a one-dimensional texture, j, k, and zoffset are | |
| both irrelevant. | |
| (x[w], y[w]) corresponds to a border texel if x[w] or y[w] or | |
| zoffset is less than the border size, or if x[w] or y[w] or zoffset | |
| is greater than the border size plus the width or height or depth, | |
| resp., of the texture image. | |
| Conversion to Framebuffer-Attachable Image Components | |
| When an enabled color value is written to the framebuffer while | |
| 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 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 1.5 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: ..., GenFramebuffersEXT, BindFramebufferEXT, | |
| DeleteFramebuffersEXT, CheckFramebufferStatusEXT, | |
| GenRenderbuffersEXT, BindRenderbufferEXT, DeleteRenderbuffersEXT, | |
| RenderbufferStorageEXT, FramebufferTexture1DEXT, | |
| FramebufferTexture2DEXT, FramebufferTexture3DEXT, | |
| FramebufferRenderbufferEXT, GenerateMipmapEXT..." | |
| Additions to Chapter 6 of the OpenGL 1.5 Specification (State and State | |
| Requests) | |
| Add to section 6.1.3, Enumerated Queries: | |
| In the list of state query functions, add: | |
| "void GetFramebufferAttachmentParameterivEXT(enum target, | |
| enum attachment, | |
| enum pname, | |
| int *params); | |
| <target> must be FRAMEBUFFER_EXT. <attachment> must be one | |
| of the attachment points of the framebuffer listed in table | |
| 1.nnn. <pname> must be one of the following: | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT, | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT, | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT. | |
| If the framebuffer currently bound to <target> is zero, then | |
| INVALID_OPERATION is generated. | |
| Upon successful return from | |
| GetFramebufferAttachmentParameterivEXT, if <pname> is | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT, then param will | |
| contain one of NONE, TEXTURE, or RENDERBUFFER_EXT, | |
| identifying the type of object which contains the attached | |
| image. | |
| If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is | |
| RENDERBUFFER_EXT, then | |
| If <pname> is FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, | |
| <params> will contain the name of the renderbuffer | |
| object which contains the attached image. | |
| Otherwise, INVALID_ENUM is generated. | |
| If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT is | |
| TEXTURE, then | |
| If <pname> is FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, | |
| then <params> will contain the name of the texture | |
| object which contains the attached image. | |
| If <pname> is FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, | |
| then <params> will contain the mipmap level of the | |
| texture object which contains the attached image. | |
| If <pname> is | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT and the | |
| texture object named | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT is a cube map | |
| texture, then <params> will contain the cube map face of | |
| the cubemap texture object which contains the attached | |
| image. Otherwise <params> will contain the value zero. | |
| If <pname> is | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT and the | |
| texture object named | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT is a | |
| 3-dimensional texture, then <params> will contain the | |
| zoffset of the 2D image of the 3D texture object which | |
| contains the attached image. Otherwise <params> will | |
| contain the value zero. | |
| Otherwise, INVALID_ENUM is generated. | |
| void GetRenderbufferParameterivEXT(enum target, enum pname, | |
| int* params); | |
| <target> must be RENDERBUFFER_EXT. <pname> must be one of | |
| the symbolic values in table 8.nnn. | |
| If the renderbuffer currently bound to <target> is zero, | |
| then INVALID_OPERATION is generated. | |
| Upon successful return from GetRenderbufferParameterivEXT, | |
| if <pname> is RENDERBUFFER_WIDTH_EXT, | |
| RENDERBUFFER_HEIGHT_EXT, or | |
| RENDERBUFFER_INTERNAL_FORMAT_EXT, then <params> will contain | |
| the width in pixels, height in pixels, or internal format, | |
| respectively, of the image of the renderbuffer currently | |
| bound to <target>. | |
| Upon successful return from GetRenderbufferParameterivEXT, | |
| if <pname> is RENDERBUFFER_RED_SIZE_EXT, | |
| RENDERBUFFER_GREEN_SIZE_EXT, RENDERBUFFER_BLUE_SIZE_EXT, | |
| RENDERBUFFER_ALPHA_SIZE_EXT, RENDERBUFFER_DEPTH_SIZE_EXT, or | |
| RENDERBUFFER_STENCIL_SIZE_EXT, then <params> will contain | |
| the actual resolutions, (not the resolutions specified when | |
| the image array was defined), for the red, green, blue, | |
| alpha depth, or stencil components, respectively, of the | |
| image of the renderbuffer currently bound to <target>. | |
| Otherwise, INVALID_ENUM is generated." | |
| After section 6.1.13 and before section 6.1.14 (which should be | |
| renumbered 6.1.16), add two new sections: | |
| 6.1.14 Framebuffer Object Queries | |
| The command | |
| boolean IsFramebufferEXT( uint framebuffer ); | |
| returns TRUE if <framebuffer> is the name of a framebuffer | |
| object. If <framebuffer> is zero, or if <framebuffer> is a | |
| non-zero value that is not the name of a framebuffer object, | |
| IsFramebufferEXT return FALSE. | |
| 6.1.15 Renderbuffer Object Queries | |
| The command | |
| boolean IsRenderbufferEXT( uint renderbuffer ); | |
| returns TRUE if <renderbuffer> is the name of a renderbuffer | |
| object. If <renderbuffer> is zero, or if <renderbuffer> is a | |
| non-zero value that is not the name of a renderbuffer object, | |
| IsRenderbufferEXT return FALSE. | |
| Errors | |
| The error INVALID_OPERATION is generated if FRAMEBUFFER_BINDING_EXT | |
| is zero and DrawBuffer or DrawBuffers is called with a <buf> | |
| constant (other than NONE) that does not correspond to a buffer | |
| allocated to the GL by the window-system, including the constants | |
| COLOR_ATTACHMENT0_EXT through COLOR_ATTACHMENTn_EXT, where n is | |
| MAX_COLOR_ATTACHMENTS_EXT - 1. | |
| The error INVALID_OPERATION is generated if FRAMEBUFFER_BINDING_EXT | |
| is non-zero and DrawBuffer, DrawBuffers, or ReadBuffer is called | |
| with a <buf> constant (other than NONE) that is not in the range | |
| COLOR_ATTACHMENT0_EXT through COLOR_ATTACHMENTn_EXT, where n is | |
| MAX_COLOR_ATTACHMENTS_EXT - 1. | |
| The error INVALID_ENUM is generated if DrawBuffer or ReadBuffer is | |
| called with a <buf> constant that is not listed in table 4.4 or | |
| 10.nnn. | |
| The error INVALID_ENUM is generated if DrawBuffers is called with a | |
| <buf> constant that is not listed in table 10.nnn or 11.nnn. | |
| The error INVALID_FRAMEBUFFER_OPERATION_EXT is generated if the | |
| value of FRAMEBUFFER_STATUS_EXT is not FRAMEBUFFER_COMPLETE_EXT when | |
| any attempts to render to or read from the framebuffer are made. | |
| The error INVALID_OPERATION is generated if | |
| GetFramebufferAttachmentParameterivEXT is called while the value of | |
| FRAMEBUFFER_BINDING_EXT is zero. | |
| The error INVALID_OPERATION is generated if | |
| FramebufferRenderbufferEXT or FramebufferTexture{1D|2D|3D}EXT is | |
| called while the value of FRAMEBUFFER_BINDING_EXT is zero. | |
| The error INVALID_OPERATION is generated if RenderbufferStorageEXT | |
| or GetRenderbufferParameterivEXT is called while the value of | |
| RENDERBUFFER_BINDING_EXT is zero. | |
| The error INVALID_ENUM is generated if | |
| GetFramebufferAttachmentParameterivEXT is called with an | |
| <attachment> other than COLOR_ATTACHMENT0_EXT through | |
| COLOR_ATTACHMENTn_EXT, where n is MAX_COLOR_ATTACHMENTS_EXT - 1. | |
| The error INVALID_ENUM is generated if | |
| GetFramebufferAttachmentParameterivEXT is called with a <pname> | |
| other than FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT when the type of | |
| the attached object at the named attachment point is | |
| RENDERBUFFER_EXT. | |
| The error INVALID_ENUM is generated if | |
| GetFramebufferAttachmentParameterivEXT is called with a <pname> | |
| other than FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT, or | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT when the type of the | |
| attached object at the named attachment point is TEXTURE. | |
| The error INVALID_ENUM is generated if GetRenderbufferParameterivEXT | |
| is called with a <pname> other than RENDERBUFFER_WIDTH_EXT, | |
| RENDERBUFFER_HEIGHT_EXT, or RENDERBUFFER_INTERNAL_FORMAT_EXT, | |
| GL_RENDERBUFFER_RED_SIZE, GL_RENDERBUFFER_GREEN_SIZE, | |
| GL_RENDERBUFFER_BLUE_SIZE, GL_RENDERBUFFER_ALPHA_SIZE, | |
| GL_RENDERBUFFER_DEPTH_SIZE, or GL_RENDERBUFFER_STENCIL_SIZE. | |
| The error INVALID_VALUE is generated if RenderbufferStorageEXT is | |
| called with a <width> or <height> that is greater than | |
| MAX_RENDERBUFFER_SIZE_EXT. | |
| The error INVALID_ENUM is generated if RenderbufferStorageEXT is | |
| called with an <internalformat> that is not RGB, RGBA, | |
| DEPTH_COMPONENT, STENCIL_INDEX, 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, or STENCIL_INDEX. | |
| The error INVALID_OPERATION is generated if | |
| FramebufferRenderbufferEXT is called and <renderbuffer> is not the | |
| name of a renderbuffer object or zero. | |
| The error INVALID_OPERATION is generated if | |
| FramebufferTexture{1D|2D|3D}EXT is called and <texture> is not the | |
| name of a texture object or zero. | |
| The error INVALID_VALUE is generated if | |
| FramebufferTexture{1D|2D|3D}EXT is called with a <level> that is | |
| less than zero and <texture> is not zero. | |
| The error INVALID_VALUE is generated if FramebufferTexture2DEXT is | |
| called with a <level> that is not zero and <textarget> is | |
| TEXTURE_RECTANGLE_ARB and <texture> is not zero. | |
| The error INVALID_VALUE is generated if FramebufferTexture{1D|2D}EXT | |
| is called with a <level> that is greater than the log base 2 of | |
| MAX_TEXTURE_SIZE and <texture> is respectively a non-zero 1D or 2D | |
| texture object name. | |
| The error INVALID_VALUE is generated if FramebufferTexture2DEXT | |
| is called with a <level> that is greater than the log base 2 of | |
| MAX_CUBE_MAP_TEXTURE_SIZE and <texture> is a non-zero cubemap | |
| texture object name. | |
| The error INVALID_VALUE is generated if FramebufferTexture3DEXT is | |
| called with a <level> greater than the log base 2 of the | |
| MAX_3D_TEXTURE_SIZE and <texture> is not zero. | |
| The error INVALID_VALUE is generated if FramebufferTexture3DEXT is | |
| called with a <zoffset> that is larger than MAX_3D_TEXTURE_SIZE-1 | |
| and <texture> is not zero. | |
| The error INVALID_ENUM is generated if CheckFramebufferStatusEXT is | |
| called and <target> is not FRAMEBUFFER_EXT. | |
| The error INVALID_OPERATION is generated if | |
| CheckFramebufferStatusEXT 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 RenderbufferStorageEXT. | |
| The error INVALID_OPERATION is generated if GenerateMipmapEXT is | |
| called with a <target> of TEXTURE_CUBE_MAP and the texture object | |
| currently bound to TEXTURE_CUBE_MAP is not "cube complete" as | |
| defined in section 3.8.10 | |
| New State | |
| (add new table 3.nnn, "Framebuffer (state per framebuffer target binding point)") | |
| Get Value Type Get Command Initial Value Description Section Attribute | |
| ------------------------------- ------ ------------- -------------- -------------------- ------------ --------- | |
| FRAMEBUFFER_BINDING_EXT Z GetIntegerv 0 name of framebuffer 4.4.1 - | |
| object bound to | |
| FRAMEBUFFER_EXT | |
| target | |
| (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 4.3.2 pixel | |
| [1] prior to this extension, the DRAW_BUFFERi state was described in table 6.21 "Framebuffer Control" (of OpenGL 2.0 spec) | |
| [2] prior to this extension, the READ_BUFFER state was described in table 6.26 "Pixel" (of OpenGL 2.0 spec) | |
| (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_EXT Z GetFramebufferAttachmentParameterivEXT NONE type of 4.4.2.2 and - | |
| image attached to 4.4.2.3 | |
| framebuffer attachment | |
| point | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT Z GetFramebufferAttachmentParameterivEXT 0 name of object 4.4.2.2 and - | |
| attached to 4.4.2.3 | |
| framebuffer attachment | |
| point | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT Z GetFramebufferAttachmentParameterivEXT 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_EXT Z+ GetFramebufferAttachmentParameterivEXT TEXTURE_ cubemap face of 4.4.2.2 and - | |
| CUBE_MAP_ texture image 4.4.2.3 | |
| POSITIVE_X attached, if object | |
| attached is cubemap | |
| texture. | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT Z GetFramebufferAttachmentParameterivEXT 0 zoffset of 4.4.2.2 and - | |
| texture image 4.4.2.3 | |
| attached, if object | |
| attached is 3D | |
| texture. | |
| (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_EXT Z GetIntegerv 0 renderbuffer object 4.4.2.1 - | |
| bound to | |
| RENDERBUFFER_EXT | |
| (insert new table 8.nnn, "Renderbuffers (state per renderbuffer object)") | |
| Get Value Type Get Command Initial Value Description Section Attribute | |
| ------------------------------- ------ ------------- ------------- -------------------- ------------ --------- | |
| RENDERBUFFER_WIDTH_EXT Z GetRenderbufferParameterivEXT 0 width of renderbuffer 4.4.2.1 - | |
| RENDERBUFFER_HEIGHT_EXT Z GetRenderbufferParameterivEXT 0 height of renderbuffer 4.4.2.1 - | |
| RENDERBUFFER_INTERNAL_FORMAT_EXT Z+ GetRenderbufferParameterivEXT RGBA internal format 4.4.2.1 - | |
| of renderbuffer | |
| RENDERBUFFER_RED_SIZE_EXT Z GetRenderbufferParameterivEXT 0 size in bits of 4.4.2.1 - | |
| renderbuffer image's | |
| red component | |
| RENDERBUFFER_GREEN_SIZE_EXT Z GetRenderbufferParameterivEXT 0 size in bits of 4.4.2.1 - | |
| renderbuffer image's | |
| green component | |
| RENDERBUFFER_BLUE_SIZE_EXT Z GetRenderbufferParameterivEXT 0 size in bits of 4.4.2.1 - | |
| renderbuffer image's | |
| blue component | |
| RENDERBUFFER_ALPHA_SIZE_EXT Z GetRenderbufferParameterivEXT 0 size in bits of 4.4.2.1 - | |
| renderbuffer image's | |
| alpha component | |
| RENDERBUFFER_DEPTH_SIZE_EXT Z GetRenderbufferParameterivEXT 0 size in bits of 4.4.2.1 - | |
| renderbuffer image's | |
| depth component | |
| RENDERBUFFER_STENCIL_SIZE_EXT Z GetRenderbufferParameterivEXT 0 size in bits of 4.4.2.1 - | |
| renderbuffer image's | |
| stencil component | |
| Move the following existing state from "Implementation Dependent | |
| Values", tables 6.31-6.36 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 | |
| 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_EXT Z+ GetIntegerv 1 Maximum number of 4.4.2.2 - | |
| attachment points | |
| for color buffers | |
| when using framebuffer | |
| objects | |
| New Implementation Dependent State | |
| Get Value Type Get Command Minimum Value Description Section Attribute | |
| --------- ---- ----------- ------------- ------------------- ------- --------- | |
| MAX_RENDERBUFFER_SIZE_EXT Z+ GetIntegerv 1 Maximum width and 4.4.2.1 - | |
| height of | |
| renderbuffers | |
| supported by | |
| the implementation | |
| Additions to the AGL/GLX/WGL Specifications and dependencies on | |
| WGL_ARB_make_current_read, GLX_SGI_make_current_read, and GLX 1.3 | |
| The color, depth, stencil, aux, and accum logical buffers defined by | |
| the <draw> and <read> drawables passed to glXMakeContextCurrent, | |
| glXMakeCurrent, and glXMakeCurrentRead are ignored while the value | |
| of FRAMEBUFFER_BINDING_EXT 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_framebuffer_object and OpenGL 3.0 | |
| 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 ARB_texture_rectangle | |
| If ARB_texture_rectangle is not supported, then all references to | |
| TEXTURE_RECTANGLE_ARB should be ignored. | |
| Dependencies on EXT_packed_depth_stencil | |
| If EXT_packed_depth_stencil is not supported, then all references to | |
| DEPTH_STENCIL internal formats should be ignored. | |
| Dependencies on NV_float_buffer | |
| If NV_float_buffer is not supported, then all references to the | |
| following internal formats should be ignored: FLOAT_R_NV, | |
| FLOAT_RG_NV, FLOAT_RGB_NV, and FLOAT_RGBA_NV. | |
| Dependencies on NV_texture_shader | |
| The following base internal formats are not color-renderable, | |
| depth-renderable, or stencil-renderable: HILO_NV, DSDT_NV, | |
| DSDT_MAG_NV, and DSDT_MAG_INTENSITY_NV. | |
| GLX Protocol | |
| Seventeen new GL commands are added. | |
| The following ten rendering commands are sent to the sever as part | |
| of a glXRender request: | |
| BindRenderbufferEXT | |
| 2 12 rendering command length | |
| 2 4316 rendering command opcode | |
| 4 ENUM target | |
| 4 CARD32 renderbuffer | |
| DeleteRenderbufferEXT | |
| 2 8+n*4 rendering command length | |
| 2 4317 rendering command opcode | |
| 4 CARD32 n | |
| n*4 LISTofCARD32 renderbuffers | |
| RenderbufferStorageEXT | |
| 2 20 rendering command length | |
| 2 4318 rendering command opcode | |
| 4 ENUM target | |
| 4 ENUM internalFormat | |
| 4 CARD32 width | |
| 4 CARD32 height | |
| BindFramebufferEXT | |
| 2 12 rendering command length | |
| 2 4319 rendering command opcode | |
| 4 ENUM target | |
| 4 CARD32 framebuffer | |
| DeleteFramebufferEXT | |
| 2 8+n*4 rendering command length | |
| 2 4320 rendering command opcode | |
| 4 CARD32 n | |
| n*4 LISTofCARD32 framebuffers | |
| FramebufferTexture1DEXT | |
| 2 24 rendering command length | |
| 2 4321 rendering command opcode | |
| 4 ENUM target | |
| 4 ENUM attachement | |
| 4 ENUM textarget | |
| 4 CARD32 texture | |
| 4 CARD32 level | |
| FramebufferTexture2DEXT | |
| 2 24 rendering command length | |
| 2 4322 rendering command opcode | |
| 4 ENUM target | |
| 4 ENUM attachement | |
| 4 ENUM textarget | |
| 4 CARD32 texture | |
| 4 CARD32 level | |
| FramebufferTexture3DEXT | |
| 2 28 rendering command length | |
| 2 4323 rendering command opcode | |
| 4 ENUM target | |
| 4 ENUM attachement | |
| 4 ENUM textarget | |
| 4 CARD32 texture | |
| 4 CARD32 level | |
| 4 CARD32 zoffset | |
| FramebufferRenderbufferEXT | |
| 2 20 rendering command length | |
| 2 4324 rendering command opcode | |
| 4 ENUM target | |
| 4 ENUM attachment | |
| 4 ENUM renderbuffertarget | |
| 4 CARD32 renderbuffer | |
| GenerateMipmapEXT | |
| 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: | |
| IsRenderbufferEXT | |
| 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 | |
| GenRenderbuffersEXT | |
| 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 | |
| GetRenderbufferParameterivEXT | |
| 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 | |
| IsFramebufferEXT | |
| 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 | |
| GenFramebuffersEXT | |
| 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 | |
| CheckFramebufferStatusEXT | |
| 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 | |
| GetFramebufferAttachementParameterivEXT | |
| 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 glCheckFramebufferStatusEXT. | |
| #define CHECK_FRAMEBUFFER_STATUS() \ | |
| { \ | |
| GLenum status; \ | |
| status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); \ | |
| switch(status) { \ | |
| case GL_FRAMEBUFFER_COMPLETE_EXT: \ | |
| break; \ | |
| case GL_FRAMEBUFFER_UNSUPPORTED_EXT: \ | |
| /* 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 | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); | |
| // Set up color_tex and depth_rb for render-to-texture | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT0_EXT, | |
| GL_TEXTURE_2D, color_tex, 0); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
| GL_DEPTH_ATTACHMENT_EXT, | |
| GL_RENDERBUFFER_EXT, depth_rb); | |
| // Check framebuffer completeness at the end of initialization. | |
| CHECK_FRAMEBUFFER_STATUS(); | |
| <draw to the texture and renderbuffer> | |
| // Re-enable rendering to the window | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
| glBindTexture(GL_TEXTURE_2D, color_tex); | |
| <draw to the window, reading from the color_tex> | |
| (2) Application that supports both RBBCTT (render back buffer, copy to | |
| texture) and RTT (render to texture). The migration path from RBBCTT | |
| to RTT is easy. | |
| if (useFramebuffer) { | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT0_EXT, | |
| GL_TEXTURE_2D, color_tex, 0); | |
| CHECK_FRAMEBUFFER_STATUS(); | |
| } | |
| draw_to_texture(); | |
| glBindTexture (GL_TEXTURE_2D, color_tex); | |
| if (useFramebuffer) { | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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. | |
| glGenFramebuffersEXT(1, &fb); | |
| glGenTextures(1, &color_tex); | |
| glGenRenderbuffersEXT(1, &depth_rb); | |
| glGenRenderbuffersEXT(1, &stencil_rb); | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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); | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT0_EXT, | |
| GL_TEXTURE_2D, color_tex, 0); | |
| // initialize depth renderbuffer | |
| glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb); | |
| glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, | |
| GL_DEPTH_COMPONENT24, 512, 512); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
| GL_DEPTH_ATTACHMENT_EXT, | |
| GL_RENDERBUFFER_EXT, depth_rb); | |
| // initialize stencil renderbuffer | |
| glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil_rb); | |
| glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, | |
| GL_STENCIL_INDEX, 512, 512); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
| GL_STENCIL_ATTACHMENT_EXT, | |
| GL_RENDERBUFFER_EXT, stencil_rb); | |
| // Check framebuffer completeness at the end of initialization. | |
| CHECK_FRAMEBUFFER_STATUS(); | |
| loop { | |
| glBindTexture(GL_TEXTURE_2D, 0); | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); | |
| <draw to the texture> | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
| glBindTexture(GL_TEXTURE_2D, color_tex); | |
| <draw to the window, reading from the color texture> | |
| } | |
| (4) Render-to-texture loop with automatic mipmap generation. There | |
| are N framebuffers, N mipmap color textures, and a single shared | |
| depth renderbuffer. The depth renderbuffer is not a mipmap. | |
| GLuint fb_array[N]; | |
| GLuint color_tex_array[N]; | |
| GLuint depth_rb; | |
| glGenFramebuffersEXT(N, fb_array); | |
| glGenTextures(N, color_tex_array); | |
| glGenRenderbuffersEXT(1, &depth_rb); | |
| // initialize color textures | |
| for (int i=0; i<N; i++) { | |
| glBindTexture(GL_TEXTURE_2D, color_tex_array[N]); | |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0, | |
| GL_RGB, GL_INT, NULL); | |
| // establish a mipmap chain for the texture | |
| glGenerateMipmapEXT(GL_TEXTURE_2D); | |
| } | |
| // initialize depth renderbuffer | |
| glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb); | |
| glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, | |
| GL_DEPTH_COMPONENT24, 512, 512); | |
| // setup framebuffers, sharing depth | |
| for (int i=0; i<N; i++) { | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_array[i]); | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT0_EXT, | |
| GL_TEXTURE_2D, color_tex_array[i], 0); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
| GL_DEPTH_ATTACHMENT_EXT, | |
| GL_RENDERBUFFER_EXT, depth_rb); | |
| } | |
| // Check framebuffer completeness at the end of initialization. | |
| CHECK_FRAMEBUFFER_STATUS(); | |
| loop { | |
| glBindTexture(GL_TEXTURE_2D, 0); | |
| for (int i=0; i<N; i++) { | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_array[i]); | |
| <draw to texture i> | |
| } | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
| // automatically generate mipmaps | |
| for (int i=0; i<N; i++) { | |
| glBindTexture(GL_TEXTURE_2D, color_tex_array[i]); | |
| glGenerateMipmapEXT(GL_TEXTURE_2D); | |
| } | |
| <draw to the window, reading from the color textures> | |
| } | |
| (5) Render-to-texture loop with custom mipmap generation. | |
| The depth renderbuffer is not a mipmap. | |
| glGenFramebuffersEXT(1, &fb); | |
| glGenTextures(1, &color_tex); | |
| glGenRenderbuffersEXT(1, &depth_rb); | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 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); | |
| glGenerateMipmapEXT(GL_TEXTURE_2D); | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT0_EXT, | |
| GL_TEXTURE_2D, color_tex, 0); | |
| // initialize depth renderbuffer | |
| glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb); | |
| glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, | |
| GL_DEPTH_COMPONENT24, 512, 512); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
| GL_DEPTH_ATTACHMENT_EXT, | |
| GL_RENDERBUFFER_EXT, depth_rb); | |
| // Check framebuffer completeness at the end of initialization. | |
| CHECK_FRAMEBUFFER_STATUS(); | |
| loop { | |
| glBindTexture(GL_TEXTURE_2D, 0); | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT0_EXT, | |
| GL_TEXTURE_2D, color_tex, 0); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
| GL_DEPTH_ATTACHMENT_EXT, | |
| GL_RENDERBUFFER_EXT, depth_rb); | |
| <draw to the base level of the color texture> | |
| // custom-generate successive mipmap levels | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
| GL_DEPTH_ATTACHMENT_EXT, | |
| GL_RENDERBUFFER_EXT, 0); | |
| glBindTexture(GL_TEXTURE_2D, color_tex); | |
| foreach (level > 0, in order of increasing values of level) { | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT0_EXT, | |
| GL_TEXTURE_2D, color_tex, level); | |
| glTexParameteri(TEXTURE_2D, TEXTURE_BASE_LEVEL, level-1); | |
| glTexParameteri(TEXTURE_2D, TEXTURE_MAX_LEVEL, level-1); | |
| <draw to level> | |
| } | |
| glTexParameteri(TEXTURE_2D, TEXTURE_BASE_LEVEL, 0); | |
| glTexParameteri(TEXTURE_2D, TEXTURE_MAX_LEVEL, max); | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
| <draw to the window, reading from the color texture> | |
| } | |
| (6) Pseudo-code example of one method of responding to | |
| FRAMEBUFFER_UNSUPPORTED_EXT | |
| bool done = false; | |
| bool success = false; | |
| int configurationNumber = 0; | |
| GLenum status; | |
| while (!done) | |
| { | |
| for (each framebuffer-attachable image) | |
| { | |
| ChooseInternalFormatForFramebufferAttachableImage(configurationNumber); | |
| CreateFramebufferAttachableImage(); | |
| AttachFramebufferAttachableImageToFramebuffer(); | |
| } | |
| status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); | |
| switch(status) | |
| { | |
| case GL_FRAMEBUFFER_COMPLETE_EXT: | |
| success = true; | |
| done = true; | |
| break; | |
| case GL_FRAMEBUFFER_UNSUPPORTED_EXT: | |
| 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 | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); | |
| // Set up depth_tex for render-to-texture | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_DEPTH_ATTACHMENT_EXT, | |
| GL_TEXTURE_2D, depth_tex, 0); | |
| // No color buffer to draw to or read from | |
| glDrawBuffer(GL_NONE); | |
| glReadBuffer(GL_NONE); | |
| // Check framebuffer completeness at the end of initialization. | |
| CHECK_FRAMEBUFFER_STATUS(); | |
| <draw something> | |
| // Re-enable rendering to the window | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
| glBindTexture(GL_TEXTURE_2D, depth_tex); | |
| <draw to the window, reading from the depth_tex> | |
| (8) FBO and ARB_draw_buffers | |
| // Given: color_texA - TEXTURE_2D color texture object | |
| // Given: color_texB - TEXTURE_2D color texture object | |
| // depth_rb - GL_DEPTH renderbuffer object | |
| // fb - framebuffer object | |
| // Set up the framebuffer object | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT0_EXT, | |
| GL_TEXTURE_2D, color_texA, 0); | |
| glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | |
| GL_COLOR_ATTACHMENT1_EXT, | |
| GL_TEXTURE_2D, color_texB, 0); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, | |
| GL_DEPTH_ATTACHMENT_EXT, | |
| GL_RENDERBUFFER_EXT, depth_rb); | |
| // Enable both attachments as draw buffers | |
| GLenum drawbuffers = {GL_COLOR_ATTACHMENT0_EXT, | |
| GL_COLOR_ATTACHMENT1_EXT}; | |
| glDrawBuffers(2, drawbuffers); | |
| // Check framebuffer completeness at the end of initialization. | |
| CHECK_FRAMEBUFFER_STATUS(); | |
| // Enable fragment program that writes to both gl_FragData[0] | |
| // and gl_FragData[1] | |
| <draw something> | |
| // Disable fragment program | |
| // Re-enable rendering to the window | |
| glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
| // Bind both textures, each to a different texture unit | |
| glActiveTexture(GL_TEXTURE0); | |
| glBindTexture(GL_TEXTURE_2D, color_texA); | |
| glActiveTexture(GL_TEXTURE1); | |
| glBindTexture(GL_TEXTURE_2D, color_texB); | |
| <draw to the window> | |
| Issues | |
| (1) We obviously won't call this "ARB_compromise_buffers", so | |
| what name should we use? | |
| RESOLUTION: resolved, EXT_framebuffer_object | |
| Possibilities considered include: | |
| EXT_framebuffer | |
| EXT_framebuffer_object | |
| EXT_renderable_buffers | |
| EXT_renderbuffer | |
| EXT_superbuffers (hah!) | |
| EXT_renderable_image | |
| EXT_render_image | |
| The lead candidates were EXT_renderable_image and | |
| EXT_framebuffer_object Since this extension introduced both | |
| new concepts into OpenGL, this was a bit of a toss up. | |
| EXT_framebuffer_object was chosen based on a weak precedent | |
| given by EXT_texture_object and ARB_vertex_buffer_object | |
| (2) Many developers complain about the OpenGL/glX/WGL/agl pbuffer | |
| API, which they use both to do "render to texture" and to do | |
| general offscreen (non-windowed) accelerated rendering. This | |
| extension is intended to subsume, some and perhaps all of, the | |
| functionality currently handled by pbuffers. Should this | |
| extension (initially?) support only render-to-texture or should | |
| it try to provide an OpenGL API to fully replace the pbuffer | |
| API? | |
| RESOLUTION: This extension should fully replace the pbuffer API. | |
| The implication of this decision is that this API should provide | |
| a way to support rendering to offscreen buffers that are not | |
| textures. | |
| (3) As a consequence of issue (2), this extension adds the concept of | |
| share-able, non-texturable renderable entitites that can be | |
| used as color buffers, depth buffers, stencil buffers, etc. | |
| The OpenGL spec refers to these entities as "logical buffers". | |
| What should this spec call them? | |
| RESOLUTION: "renderbuffer", (one word) | |
| We could just call them "logical buffers", but is there a | |
| better name? | |
| The group considered: | |
| logical buffer - possible, kind of general | |
| render buffer - clear, (one word or two?) | |
| renderable - clear, but may conflict with glx "drawable" | |
| drawable - confusing: glx "drawable" == gl "framebuffer" | |
| render surface - possible | |
| render target - possible | |
| image buffer - may get confused with Tex"Image" | |
| image - may get confused with Tex"Image" | |
| surface buffer - too verbose? | |
| surface - too general | |
| others??? | |
| The group felt "render buffer " (or possibly "renderbuffer") | |
| provides for the clearest expression of the purpose for | |
| these buffers. | |
| We finally decided on "renderbuffer" because we didn't want | |
| to use "render" as an adjective to describe a generic | |
| buffer, but rather decided to coin a new compound word to | |
| describe this concept. | |
| (4) How should the specification refer to the group of | |
| various types of objects that can be attached to the framebuffer | |
| attachment points? | |
| RESOLUTION: The specification will use the phrase | |
| "framebuffer-attachable images" to mean the 2D array of | |
| pixels (image) of a "renderbuffer", a "texture", or any | |
| other items that could be attached to a framebuffer. | |
| Options considered include: | |
| "render target" | |
| "renderable image" | |
| "framebuffer-attachable | |
| Initially, we chose the phrase "render target" for this but | |
| felt it didn't accurately capture the concept of a 2D array | |
| of pixels that was simultaneously useable as the storage of | |
| a texture object and the destination of rendering. | |
| We then tried to borrow the "image" language of OpenGL which | |
| describes texture's pixel arrays as "images" and we chose | |
| the term "renderable image". | |
| However, in the end, we felt that the salient characteristic | |
| of these images was that we could attach them to a | |
| framebuffer and settled on the term "framebuffer-attachable | |
| image". | |
| (5) How should the specification refer to the places in a framebuffer | |
| that can hold a framebuffer-attachable image? | |
| RESOLUTION: This state is called an "attachment point" of | |
| the framebuffer. | |
| "attachment points" will be be used to describe the | |
| framebuffer state that holds a connection to a given | |
| framebuffer-attachable image (a renderbuffer image or a | |
| texture image). The framebuffer attachment points include | |
| the framebuffer's color buffers, stencil buffer, depth | |
| buffer, and aux buffer. | |
| The word "attach" is being used to refer to connecting one | |
| object to another. "bind" refers to connecting an object to | |
| the context state. A texture image can be attached to a | |
| framebuffer object, but a framebuffer object is bound into | |
| the context state vector. | |
| (6) This extension adds the concept of collections of "logical | |
| buffers", to replace the window-system provided collection | |
| (drawable, or window) of logical buffers. What should we call | |
| these? | |
| RESOLUTION: "framebuffer" | |
| For the "collection of logical buffers" object, the group | |
| considered the names: "framebuffer", "renderTarget", | |
| "drawable". We chose "framebuffer" since this is consistent | |
| with how the OpenGL specification already uses the word | |
| framebuffer. | |
| (7) This extension introduces two new object types into the OpenGL: | |
| renderbuffer objects and framebuffer objects. For handling | |
| these objects, there are two main object manipulation | |
| methodology precedents to choose from: | |
| 1) "texture/program/vbo" object model: | |
| app-supplied int handles, | |
| Gen/is/Bind/Delete functions | |
| 2) "GLSL" object model: | |
| driver-supplied GLhandle handles, | |
| Create/Delete/Attach, etc | |
| Which methodology should this extension use for each new object? | |
| RESOLUTION: Use Option (1), "texture" object methodology, | |
| for both "renderbuffer" objects and framebuffer objects. | |
| This is consistent with the June, 2004 ARB meeting vote to | |
| use the "texture" object methodlogy as the default object | |
| methodology. | |
| (8) Do we need separate framebuffer objects? | |
| RESOLUTION: yes. | |
| The framebuffer object is an object to encapsulate the state | |
| of the framebuffer and the collection of | |
| framebuffer-attachable images attached to the logical buffer | |
| attachment points. A question was raised early on about | |
| whether we should have separate, shareable framebuffer | |
| objects or we should fold a single framebuffer "object" | |
| state vector into the context. | |
| We decided to leave framebuffer objects in the API, with the | |
| understanding that we could easily remove them from the API | |
| and the spec later if a convincing case was argued for | |
| removing it. | |
| There are several reasons why framebuffer objects were | |
| introduced: | |
| FB1. It can be "expensive" (for some definition of | |
| expensive) to validate the framebuffer and all its | |
| attached objects. There is a desire to be able to | |
| easily recognize that a particular state. combination | |
| has been seen and validated previously. | |
| FB2. There is some subset of GL context state which only | |
| makes sense in its relationship to the current | |
| framebuffer and attached images (red bits, green | |
| bits, blue bits, etc, presence or absence of aux | |
| buffers or depth buffers, current value of draw | |
| buffer(s), read buffer, etc. etc). It would be nice | |
| if this state "tracked" changes to the current | |
| framebuffer configuration by being part of the | |
| framebuffer object state. | |
| FB3. For a while, we considered adding "intrinsic" or | |
| "implicit" buffer storage to the framebuffer. This | |
| would be used for buffers that were either hidden | |
| from the user, like the multisample buffer, or | |
| perhaps needed to be explicitly formatted by the | |
| driver. If we did have this kind of "intrinsic" | |
| storage, then framebuffers would be a lot like | |
| textures and would have the same kinds of pressures | |
| to minimize vram, sharing storage across objects and | |
| contexts as textures did. In fact, they would be | |
| similar to cube map texture objects which had 6 | |
| attached face images, or mipmaped textures which had | |
| a set of mipmap level images. In the end we decided | |
| not to use intrinsic buffers, - see issue (13) - but | |
| we might decide to add them back in the future. For | |
| instance, one option for supporting multisampling is | |
| to use an implicit multisample buffer. | |
| FB4. We realized that most of the "hard" issues introduced | |
| by this extension were completely orthogonal to the | |
| presence or absence of framebuffer objects. All of | |
| the same issues apply regardless of whether there is | |
| a single non-default framebuffer as part of the | |
| context or multiple framebuffer objects. These | |
| issues about attaching, (binding) objects, | |
| reformatting attached (or bound) images via | |
| TexImage/RenderbufferStorage, pixel format | |
| combinations, framebuffer completeness, and the | |
| relationship between a non-"default" framebuffer and | |
| the legacy window sytem framebuffer and pixel format | |
| all come in to play either way. So there is actually | |
| little implementation or conceptual cost incurred by | |
| the introduction of these framebuffer objects. | |
| There were also a few reasons why we considered *not* adding | |
| framebuffer objects: | |
| NoFB1. In the absence of "intrinsic" buffers, framebuffer | |
| objects only really consist of the attachment | |
| state. It is convenient to encapsulate this state | |
| into an object, but one could ask if it's any more | |
| convenient than say a "blend state" object or a | |
| "texture unit attachment state" object, which to | |
| date, we have chosen not to add into OpenGL. | |
| NoFB2. As a "state-only" object, there's a question about | |
| how much state should be included - at least the | |
| attachment state should be included, but what about | |
| draw buffers state, what about the viewport state, | |
| what about other state? Since drawing the line is | |
| hard, we questioned whether we needed these | |
| objects. | |
| NoFB3. Some amount of the functionality of the framebuffer | |
| objects could be implemented by the application | |
| with the appropriate use of display lists. | |
| In weighing (FB1), expense of validating framebuffer state, | |
| versus (NoFB1), not wanting to introduce "state only" | |
| objects, we realized that framebuffer validation is more | |
| expensive than the blend state (for which there is no object | |
| in GL) and less expensive than a fragment program (for which | |
| there is an object in GL). While it's not exactly clear | |
| precisely where on the spectrum of "expense" the framebuffer | |
| validation lies, we decided that it may be expensive enough | |
| to justify creating a new object type. So we retained | |
| framebuffer objects in the API now, with the understanding | |
| that if we change our minds it's easier to rip them out | |
| later than it is to add them back in later. | |
| (9) Should the routine which allocates a renderbuffer accept an | |
| image to initialize the buffer, analogous to how TexImage | |
| works? | |
| RESOLUTION: no, it should allocate uninitialized storage | |
| We could have allowed a renderbuffer "image" specification | |
| routine, but this would essentially serve the same purpose | |
| as a combined "allocate renderbuffer followed by DrawPixels" | |
| routine so we decided it was extraneous. The primary | |
| purpose of these buffers is to store rendered output anyway, | |
| so there was not sufficient demand to support an optimized | |
| path for data initialization. See related issue (10). | |
| (10) What should we call the routine that allocates storage for the | |
| renderbuffer? This routine would be the moral equivalent of | |
| glTexImage. | |
| RESOLUTION: RenderbufferStorage() | |
| Options included: | |
| RenderbufferStorage() | |
| RenderbufferImage() | |
| others??? | |
| This is really a function of how we resolve issue (9). | |
| RenderbufferImage would be appropriate if the allocation | |
| routine could take an image to initialize the renderbuffer. | |
| RenderbufferStorage would be more appropriate if the | |
| allocation routine does not take an image. | |
| Since the group decided supporting an "initialization" image | |
| for a "renderbuffer" was too much overlapping functionality | |
| with DrawPixels, RenderbufferStorage was chosen. | |
| (11) The routine(s) which attach a texture to a framebuffer | |
| attachment point need to describe which image in the texture | |
| they are using, i.e., which cube map face, mipmap level, or 3D | |
| texture z-slice/depthoffset/image. Should we have one routine | |
| that handles all of these with some arguments ignored for | |
| specific texture types/targets? Or should we have a parallel | |
| set of routines for 1D/2D/3D, like TexImage does? | |
| RESOLUTION: Option (b) 3 routines for texture, 1 for | |
| renderbuffer | |
| Originally, we chose option (b) for reasons of | |
| similarity to glTexImage1D/2D/3D. For TexImage2D and | |
| FramebufferTexture2D, the texture target was used to | |
| select a face on a cube map texture object. Since | |
| glTexImage1D/3D used TEXTURE_1D/TEXTURE_3D texture | |
| targets, we did the same for FramebufferTexture1D/3D. We | |
| also included the texture target in case it was needed | |
| for future expandability. | |
| However, some felt uncomfortable with this resolution | |
| since it adds 3 framebuffer attachment calls for | |
| textures, so we reopened the issue. | |
| Originally we just considered options (a) and (b). We | |
| then reconsidered a few additional flavors: (c), (d), | |
| and (e) | |
| Options include: | |
| a) one routine with arguments that are sometimes "ignored" | |
| For instance <image> is ignored for non-3D textures | |
| and <face> is ignored for non-cube maps, etc. | |
| This gives us: | |
| void FramebufferTexture(enum target, enum attachment, | |
| uint texture, | |
| uint level, enum face, uint image); | |
| b) routines for 1D/2D/3D, use FramebufferTexture2D for 2D, | |
| Cube, Rectangle | |
| Requires use of a texture target to distinguish cube map | |
| faces on FramebufferTexture2D | |
| Includes "redundant" texture target for 1D/3D variants | |
| for consistency and precedent with TexImage1D/3D. | |
| This gives us: | |
| void FramebufferTexture1D(enum target, enum attachment, | |
| enum textarget, uint texture, uint level); | |
| void FramebufferTexture2D(enum target, enum attachment, | |
| enum textarget, uint texture, uint level); | |
| void FramebufferTexture3D(enum target, enum attachment, | |
| enum textarget, uint texture, uint level, uint image); | |
| c) same as (b) but add a dedicated routine for Cubemaps | |
| Question: since we added a Cubemap version, do we need a | |
| Rectangle variant as well? | |
| This gives us: | |
| void FramebufferTexture1D(enum target, enum attachment, | |
| enum textarget, uint texture, uint level); | |
| void FramebufferTexture2D(enum target, enum attachment, | |
| enum textarget, uint texture, uint level); | |
| void FramebufferTextureCubemap(enum target, enum attachment, | |
| enum textarget, uint texture, uint level); | |
| void FramebufferTexture3D(enum target, enum attachment, | |
| enum textarget, uint texture, uint level, uint image); | |
| d) same as (c) but with no texture target parameter | |
| Question: since we added a Cubemap version, do we need a | |
| Rectangle variant as well? | |
| This gives us: | |
| void FramebufferTexture1D(enum target, enum attachment, | |
| uint texture, uint level); | |
| void FramebufferTexture2D(enum target, enum attachment, | |
| uint texture, uint level); | |
| void FramebufferTextureCubemap(enum target, enum attachment, | |
| uint texture, enum face, uint level); | |
| void FramebufferTexture3D(enum target, enum attachment, | |
| uint texture, uint level, uint image); | |
| e) one FramebufferTexture routine with additional arguments | |
| passed in via another routine. | |
| There are no "ignored" arguments in this routine. | |
| The arguments which would be "ignored" by this function | |
| are passed in as selector state by a separate function. | |
| These could be specified as a FramebufferParameter | |
| (implying that they are stored as framebuffer state), or | |
| as a piece of context state that is copied into the | |
| framebuffer attachment point at FramebufferTexture time. | |
| Of the two, context state is much more desirable since | |
| ARB_render_texture made the mistake of putting the | |
| selection state in the pbuffer, and this has real | |
| usability issues for multicontext applications. | |
| This gives us (two routines) | |
| void FramebufferTexture(enum target, enum attachment, | |
| uint texture, uint level); | |
| and | |
| void FramebufferParameter(enum target, enum pname, uint param); | |
| where pname can be one of | |
| GL_{attachment}_TEXTURE_CUBEMAP_FACE | |
| GL_{attachment}_TEXTURE_3D_IMAGE | |
| and param represents the cube map face or z-slice image. | |
| Also, option (e) raises 2 questions: | |
| 1. Since the rest of the selection state would come in | |
| through another function, we have to ask when can | |
| these selector state variables be changed? | |
| We had previously decided that we want to pass | |
| selection state in atomically with the attachment | |
| request. To be consistent with this earlier | |
| decision, this would imply that these variables could | |
| not be changed dynamically but would be "snapshotted" | |
| into the framebuffer attachment point at at | |
| FramebufferTexture time. This snapshot could be | |
| thought of as similar to the way ActiveTexture works. | |
| This is also similar to the snapshot of the | |
| transformed raster pos vertex that occurs at | |
| glRasterPos time. It is a copy of one piece of state | |
| into another piece of state, not just a "switch" than | |
| can be updated later that indicates where other state | |
| should be stored. | |
| 2. Is the rationale to consolidate FramebufferTexture | |
| from 3 routines to 1 also a reason to consolidate | |
| FramebufferTexture and FramebufferRenderbuffer into a | |
| single attachment routine? I.e., should there just | |
| be one routine called FramebufferAttachableImage()? | |
| If we did this, then we could also move <level> out | |
| of the argument list and rename the function to, | |
| perhaps, FramebufferAttach. | |
| void FramebufferAttach(enum target, enum attachment, | |
| enum objectType, uint name); | |
| and we'd need to create another enum for | |
| FramebufferParameter | |
| GL_{attachment}_TEXTURE_LEVEL | |
| or, avoiding the use of verbs in the function | |
| name, perhaps: | |
| void FramebufferAttachableImage(enum target, enum attachment, | |
| enum objectType, uint name); | |
| Rationale: | |
| (a) was discarded because it was not very extensible in the | |
| event we need to add additional texture selection state in | |
| the future (for instance, what if we add TEXTURE_4D | |
| targets?) | |
| (c) and (d) were discarded because the introduction of a | |
| special cubemap routine was undesirable since we were | |
| considering issue in an attempt to *reduce* the number of | |
| entry points. Additionally, (d) was discarded because it | |
| was felt the texture targets were still required. | |
| (e) was discarded because the intent was that attachment | |
| (and the consequent framebuffer validation) was a | |
| "heavy-weight" operation. By using a separate routine to | |
| set part of the attachment state, developers may be | |
| incorrectly encouraged to assume some attachment state could | |
| be changed more easily than others. It was felt it wasn't | |
| worth this possible misunderstanding just to save some | |
| function entry points. | |
| In the end, it was determined that (b) was the lesser of two | |
| (five?) evils. (b) also has precedent in the specification | |
| of texture images via gl{Copy}TexImage. Finally, (b) is | |
| pretty clearly extensible to new attachment routines for | |
| future object types. | |
| (12) Do we need a "format group" or "format restriction" API? | |
| RESOLUTION: Yes, but put it in a separate extension for | |
| reasons of schedule. | |
| This extension introduces the ability to construct a | |
| collection of logical buffers using images of various | |
| formats into a framebuffer in a very flexible manner. It is | |
| by design more flexible than used to be possible to do by | |
| querying for available pixel formats in the window-system | |
| glX/WGL/agl API's. As a result, it is possible to construct | |
| a framebuffer that is actually not supportable by the | |
| implementation and the reasons for the configuration being | |
| unsupportable are entirely implementation dependent. | |
| This is why we originally added the CheckFramebufferStatus | |
| API. So that the application at least has the ability to | |
| determine that a particular, otherwise legal, configuration | |
| of framebuffer attachments actually will not work on this | |
| implementation. | |
| However, this extension does not provide any very helpful | |
| mechanism to find out why things are not supported or what | |
| to do to reconfigure the attachments into a supported | |
| configuration. | |
| This is a very difficult problem to solve. glX/WGL/agl | |
| solved this problem by allowing the application to specify a | |
| request for a configuration and letting implementation | |
| provide a "best match". Additionally, glX and WGL also | |
| allow for the enumeration of all possible supported | |
| configurations. | |
| Various schemes like these were considered but they were all | |
| quite complicated (possibly as complicated as the windowing | |
| system API's we are trying to replace). Consequently, we | |
| decided to investigate some additional approaches. | |
| One of these approaches is to specify "allocation and usage" | |
| hints prior to the routines which allocate buffers | |
| (TexImage/RenderbufferStorage) that will somehow indicate an | |
| intended configuration and then let the implementation use | |
| this additional information when selecting internal formats | |
| for textures and renderbuffers. The GL already has the | |
| freedom to pick any internal format it wants for textures | |
| and renderbuffers (subject to invariance requirements), and | |
| so we would like to leverage this freedom and influence the | |
| choice with an additional channel of information. | |
| One example, though not the only one, is some API to let the | |
| application specify it would like to be able to use a color | |
| buffer, depth, and stencil buffer. The implementation would | |
| take advantage of this information when allocating textures | |
| and renderbuffers and only choose internal formats for | |
| color, depth, and stencil textures and renderbuffers that | |
| could be guaranteed to be used together. For instance, the | |
| user could call: | |
| FormatRestriction(GL_COLOR | GL_DEPTH | STENCIL); | |
| or perhaps | |
| FormatRestriction(GL_32_BITS_COLOR_DEPTH_STENCIL); | |
| and then when the user called TexImage with a color buffer, | |
| the GL would only pick color formats that could definitely | |
| be used with depth and stencil buffers. The effect of this | |
| API would be to "restrict" the avaible choices to the GL to | |
| the subset of compatible formats. In this way, the | |
| possibility of encountering an implementation-dependent | |
| reason for failing "framebuffer completeness" would be | |
| greatly reduced or perhaps entirely eliminated. | |
| In any event, specifying this "FormatRestriction" API was | |
| going to take additional time and we wished to get this base | |
| EXT_framebuffer_object specification done and shipping as | |
| soon as possible. So we agreed to defer this "format | |
| restriction" API specification to a later extension, with | |
| the intent to develop this API or some other solution to | |
| this problem as soon as possible. | |
| (13) Do we need intrinsic buffers in addition to renderbuffers? | |
| RESOLUTION: no | |
| When intrinsic buffers were initially proposed, the format | |
| and dimensions of an intrinsic buffer could mutate in order | |
| to provide compatibility with the other images attached to a | |
| framebuffer object. After much debate and a series of | |
| votes, intrinsic buffers had lost both of those properties. | |
| (See issue 36.) In the end the working group decided that | |
| the crippled form of intrinsic buffers do not provide enough | |
| added value to justify their existence. | |
| (14) Is it necessary to require that all the logical buffers of a | |
| framebuffer object have the same dimensions? | |
| RESOLUTION: Yes. Matching dimensions are required for | |
| simplicity. If the dimensions do not match, the framebuffer | |
| object will not be "framebuffer complete". | |
| It could be useful to use a single large depth buffer when | |
| rendering to many textures of several different sizes. This | |
| is something that could be added later by a layered | |
| extension that relaxes the matching dimension restriction. | |
| Supporting heterogeneous sized logical buffers requires | |
| defining where in a larger buffer the smaller results are | |
| written, and deciding what guarantees can be made and what | |
| should be left undefined. | |
| (15) What happens when TexImage or CopyTexImage is called on a | |
| texture image that is attached as an image of the | |
| currently bound framebuffer object? | |
| RESOLUTION: resolved, {Copy}TexImage will redefine the | |
| texture image, which can affect the completeness of the | |
| framebuffer to which it is attached, and possibly cause the | |
| currently bound framebuffer to start failing the framebuffer | |
| completeness test. | |
| As far as {Copy}TexImage (or RenderbufferStorage) are | |
| concerned, there is nothing "special" about a texture image | |
| (or renderbuffer) attached to a framebuffer object. Attempts | |
| to redefine attached images in this manner should succeed. | |
| However, if the redefined image is no longer appropriate for | |
| the relevant attachment point in the framebuffer it is | |
| attached to, then it's possible the framebuffer may start | |
| failing the framebuffer completeness test. | |
| Another option that was considered involved having TexImage | |
| and CopyTexImage result in INVALID_OPERATION and do nothing | |
| when the target texture is bound for render-to-texture. This | |
| idea was rejected because, in the multicontext case, one | |
| context could change the attachments of a shared framebuffer | |
| and cause another context to suddenly start generating | |
| errors on {Copy}TexImage calls. This extension has tried to | |
| avoid introducing asynchronous generation of gl errors. | |
| Still another option that was considered was "orphaning" the | |
| old texture memory such that it could still be used as a | |
| framebuffer attachment but the texture would get newly | |
| allocated storage. However, this implied a side-ways copy | |
| of the texture object memory or the image for its continued | |
| use as a framebuffer-attachable image, and was therefore | |
| rejected. | |
| For the purposes of comparison, consider that | |
| ARB_render_texture faced a similar question and resolved it | |
| by implicitly unbinding the texture from the pbuffer when | |
| TexImage is called. | |
| (16) What happens when TexImage or CopyTexImage is called on a | |
| texture object that is attached as an image of a | |
| framebuffer object that is not bound to the current context? | |
| RESOLUTION: resolved, {Copy}TexImage will redefine the | |
| texture image, which can affect the completeness of the | |
| framebuffer object to which it is attached. When the | |
| framebuffer object is bound to the context, it may start | |
| failing the framebuffer completeness test. If the | |
| framebuffer object is bound in another context at the time | |
| {Copy}TexImage is called, then the framebuffer object may | |
| start failing the framebuffer completeness test in the other | |
| context. | |
| The rationale for this decision is the same as for issue | |
| (15). | |
| However, since in this case the relevant framebuffer is not | |
| current, there is no guarantee that this framebuffer | |
| revalidation or invalidation will happen until the next time | |
| the framebuffer is bound to a context. | |
| The texture (or renderbuffer) state is changed immediately, | |
| regardless of whether the texture image (or renderbuffer) is | |
| attached to a framebuffer object. However, a context other | |
| than the one issuing the {Copy}TexImage operation might not | |
| notice the state change until after it has (re)bound the | |
| framebuffer object or reattached the texture image. | |
| This is intended to be similar to what happens in the | |
| multicontext case when the state of a shared texture object | |
| is changed by another context. There is no guarantee that | |
| texture state change will be visible in the current context | |
| until the current context binds the texture object again. | |
| (17) Why is render to vertex array missing? | |
| RESOLUTION: Render to vertex array is separate functionality | |
| from render to logical buffer or render to texture. RTVA | |
| can be added as a separate extension. The framework is | |
| general enough to support more than one way of adding RTVA, | |
| without deciding today on the details of a particular RTVA | |
| implementation. | |
| One idea is to define a way to interpret a vertex array or | |
| buffer object, which is inherently byte-oriented linear, as | |
| a framebuffer, which is inherently component-oriented and | |
| dimensioned, and then call FramebufferArrayEXT like this: | |
| FramebufferArrayEXT(FRAMEBUFFER_EXT, COLOR, buffer_obj); | |
| Another idea is to define a general way to interpret a | |
| component-oriented dimensioned image, such as a texture or a | |
| color buffer, as a byte-oriented vertex stream. Using this | |
| approach one would render vertex attributes to a | |
| renderbuffer, to a texture image, or to an AUX buffer, and | |
| then use the image data directly as a vertex array. | |
| There is controversy over which RTVA method(s) should be | |
| supported. One goal of EXT_framebuffer_object is to ship | |
| render-to-texture and render-to-logical-buffer functionality | |
| today while leaving the door open to add one or more RTVA | |
| solutions in the future. | |
| (18) What function should perform the action of attaching a texture | |
| image to a framebuffer for rendering purposes? | |
| RESOLUTION: The new FramebufferTexture*EXT functions perform | |
| this action. | |
| Options that were considered include overloading | |
| BindTexture, using a FramebufferParameter function, and | |
| adding a new function. | |
| BindTexture is problematic because it creates a new texture | |
| object with default state if the name is previously unused, | |
| but the default state has no dimensions, dimensionality, or | |
| format. | |
| One reason that FramebufferTexture*EXT was well-received is | |
| because it sets, in one atomic operation, all framebuffer | |
| attachment state for both texture image and renderbuffer | |
| type of attachments. Given the polymorphic nature of | |
| framebuffer-attachable images, this guarantees that all | |
| framebuffer attachment state is in a consistent | |
| configuration, without having to define confusing precedent | |
| rules between competing (texture image and renderbuffer) | |
| pieces of framebuffer attachment state, or having to create | |
| enables (either a tri-state enable or separate enables again | |
| with precedence) to select texture image or renderbuffer | |
| attachment state as the "active" set of state. | |
| This decision also makes it simpler to specify how a | |
| framebuffer-attachable image is detached from a | |
| framebuffer--it would be confusing if detaching a texture | |
| image resulted in *attaching* a renderbuffer simply because | |
| texture image attachment state takes precedence over | |
| renderbuffer image attachment state. | |
| (19) What should happen if the texture argument given to | |
| FramebufferTextureEXT is an unused texture name? And | |
| similarly, what should happen if the renderbuffer argument | |
| given to FramebufferRenderbufferEXT is an unused renderbuffer | |
| name? | |
| RESOLUTION: resolved, (a) this is an error. | |
| Options included: | |
| a) throw an error at Framebuffer{Texture|Renderbuffer} | |
| b) texture/renderbuffer is created just like | |
| Bind{Texture|Renderbuffer} | |
| c) no error, but the framebuffer cannot be "framebuffer | |
| complete" until a texture/renderbuffer by that name | |
| has been created and satisfies the rules of | |
| framebuffer completeness. | |
| This is interesting because on the one hand we might like to | |
| adopt the model that we simply catch all the invalid state | |
| combinations when determining framebuffer completeness, | |
| i.e., option (c). This has a certain consistency but then | |
| what does it mean to call FramebufferTexture{1D|2D|3D} when | |
| the target of the texture name is not yet known? How should | |
| the other arguments to those calls be validated? | |
| Option (b) was rejected as it would introduce a second way | |
| to create a texture/renderbuffer object. I.e., both | |
| BindTexture and FramebufferTexture would create the texture | |
| object. | |
| Since there are "target aware" FramebufferTexture{1D|2D|3D} | |
| calls, the app already has to know the target prior to | |
| calling FramebufferTexture. Also, the texture target of a | |
| given object is immutable once set. An app can not set it | |
| and then change it later so this is really just an issue | |
| with the order in which they call the relevant functions. | |
| Consequently, requiring that the user call BindTexture prior | |
| to calling FramebufferTexture does not seem to be a burden. | |
| So this should be an error, since it's probably a mistake on | |
| the user's part in the first place. | |
| (20) What should happen if the texture argument given to | |
| FramebufferTextureEXT is the name of an existing texture | |
| object, but the texture has no texture image (i.e., TexImage | |
| has never been called)? Similarly what should happen if the | |
| renderbuffer argument given to FramebufferRenderbufferEXT is | |
| the name of an existing renderbuffer, but the named | |
| renderbuffer has no storage (i.e., RenderbufferStorage has | |
| never been called?) | |
| RESOLUTION: resolved, option (c) - no error, but the | |
| framebuffer object cannot be "framebuffer complete" until | |
| the state of the texture image satisfies the rules of | |
| framebuffer completeness. | |
| Same options as issue (19), these include: | |
| a) throw an error at Framebuffer{Texture|Renderbuffer} | |
| b) texture/renderbuffer is created just like | |
| Bind{Texture|Renderbuffer} | |
| c) no error, but the framebuffer cannot be "framebuffer | |
| complete" until the texture image or renderbuffer | |
| satisfies the rules of framebuffer completeness. | |
| This is an issue because you could be attempting to attach a | |
| texture (or renderbuffer) to a framebuffer attachment point | |
| prior to the application having called TexImage (or | |
| RenderbufferStorage) to define the width/height/format of | |
| the framebuffer-attachable image. | |
| At first, this seems similar to issue (19), so we could | |
| throw an error in this case too. It is different for two | |
| reasons however. First, there are default values for the | |
| texture object and renderbuffer object state. Second, the | |
| values of the width/height/format/etc for the texture object | |
| are mutable, unlike the texture target of the texture | |
| object. There is really no difference between the case | |
| where GL uses the default values for an object, and the case | |
| where the user explictly set the state equivalent to the | |
| default values using TexImage (or RenderbufferStorage). | |
| Because this state is mutable, it must be tested anyway when | |
| framebuffer completeness is determined. | |
| Therefore, we simply defer the check for whether the | |
| texture/renderbuffer state is appropriate for the | |
| framebuffer attachment point until determination of | |
| framebuffer completeness. If the state is not valid, then | |
| the framebuffer will not be complete, regardless of whether | |
| or not TexImage/RenderbufferStorage has been used to create | |
| storage for the texture level (renderbuffer). | |
| (21) What happens when DeleteTextures is called on a texture that is | |
| attached to a framebuffer object? Similarly, what happens when | |
| DeleteRenderbuffers is called on a renderbuffer that is | |
| attached to a framebuffer object? | |
| RESOLUTION: resolved, see issue (77) | |
| (22) How do you detach a texture or renderbuffer from a framebuffer | |
| object? Should we use two routines or create a detach routine? | |
| RESOLUTION: resolved, 2 routines | |
| If the user calls either FramebufferTexture with a zero | |
| texture name, or FramebufferRenderbuffer with a zero | |
| renderbuffer name, then the it as if nothing is attached to | |
| the specified attachment point. | |
| There was a concern that having two routines be able to set | |
| the framebuffer attachment state to "none" was confusing. | |
| However, the idea is simply that for any object that can be | |
| attached to a framebuffer, there should be a routine that | |
| can set up the attachment and return the framebuffer to the | |
| default "nothing attached" state. | |
| The implication here is that the default state for | |
| framebuffer attachments is: | |
| attachment object type = GL_NONE, and | |
| attached object name = 0 | |
| (23) Should it be legal for the framebuffer state to pass through | |
| invalid configurations? (I.e., depth and color buffer sizes | |
| don't match, etc) | |
| RESOLUTION: resolved, "yes" | |
| It's easier for the application if the render target state | |
| is allowed to pass through invalid configurations when | |
| transitioning between two valid configurations. A | |
| consistency check is defined to determine if a configuration | |
| is valid. | |
| As long as everything is valid at render time, transient | |
| invalid states are allowed. | |
| (24) What happens when you try to draw to a framebuffer that | |
| is not "framebuffer complete"? | |
| RESOLUTION: resolved, rendering is disabled, and an error is | |
| generated. See issue (64) as this issue is essentially a | |
| duplicate of that one. | |
| (25) What should happen on a query of framebuffer state while the | |
| framebuffer is invalid? For instance, what does a query of | |
| RED_BITS return if the currently bound framebuffer is not | |
| "framebuffer complete"? | |
| RESOLUTION: resolved, there's no issue here. Attempts to | |
| query bit depths should return the "real" answers. | |
| For instance, if there's no color buffer attached to the | |
| framebuffer attachment point, then attempts to return | |
| RED_BITS could return zero. If there is a color-renderable | |
| image attached, then RED_BITS would return whatever the | |
| RED_BITS are, regardless of the valid/invalid state of the | |
| framebuffer. | |
| Other options include returning some kind of magic value or | |
| generating an error if the framebuffer is invalid. However, | |
| any "magic value" would simply be a duplicated query for the | |
| framebuffer completeness status. Also, returning an error | |
| would be problematic because another context can make a | |
| framebuffer invalid and we have been trying to avoid any API | |
| in which one context can cause another context to start | |
| generating errors asynchronously. | |
| (26) What happens when you try to read (e.g. ReadPixels) from a | |
| framebuffer that is not "framebuffer complete"? Reads cannot | |
| be "disabled" or "ignored" in the same way that rendering can. | |
| RESOLUTION: resolved, generate a GL error. See issue (65). | |
| Originally this was resolved as "undefined pixels are | |
| generated, but no error" | |
| Initially, generating an error was rejected for a few | |
| reasons. First, it is asymmetric with the behavior for | |
| drawing - when the framebuffer is not complete, drawing is | |
| disabled. We would like to be consistent here. Second, | |
| there are no other cases where ReadPixels or | |
| CopyTex{Sub}Image will generate an error based on the state | |
| of the framebuffer and we didn't want to introduce one. | |
| Third, there is already a pixel ownership requirement in | |
| order to get defined results back from reading the | |
| framebuffer, so if we simply behave as if incomplete | |
| framebuffer fails ths pixel ownership test, then we can | |
| leverage that already specified behavior for reading the | |
| framebuffer. | |
| For these reasons, we initially choose to have reads from an | |
| incomplete framebuffer return undefined pixel values and not | |
| generate a GL error. | |
| However, once we subsequntly resolved issue (64) to say that | |
| rendering with an incomplete framebuffer generates an error, | |
| we decided again for reasons of symmetry that reading from | |
| an incomplete framebuffer should also generate an error. | |
| (And most likely the same error.) | |
| So in the end, we decided that reads (e.g., ReadPixels and | |
| CopyTex{Sub}Image) in this case would result in an error to | |
| be named in issue (65). | |
| See also related issue (73), describing ReadPixels of color | |
| data from a complete framebuffer while READ_BUFFER is NONE. | |
| (27) What happens when you query the number of bits per channel | |
| (e.g., DEPTH_BITS) prior to the consistency check being run | |
| when intrinsic buffers are in use, since implementations are | |
| allowed to select a number of bits for an intrinsic buffer at | |
| consistency check time to give a better chance of a consistent | |
| state being reached? | |
| RESOLUTION: This is not an issue since we don't have | |
| intrinsic buffers, see issue (13). We are keeping this | |
| issue in the issues list just in case we ever go back and | |
| add something like this to a future API. | |
| If we would have retained the intrinsic buffer api (i.e., | |
| glFramebufferStorage) or if some future API adds it back in, | |
| then one possible resolution of this problem would have been | |
| to simply say that a query of the number of bits prior to | |
| the consistency check being run will produce an answer that | |
| is subject to change. | |
| This is preferable to some other possible resolutions that | |
| have been discussed (e.g., having the query cause a | |
| validation to occur implicitly, thereby "baking" in the | |
| answer) because it is the one least likely to introduce | |
| unexpected side-effects to an operation as seemingly | |
| innocuous as a query. | |
| A possible variant of this proposed resolution would have | |
| been to have the query return a number of bits that is | |
| guaranteed to be less than or equal to the actual number of | |
| bits that will eventually be used. This may or may not be a | |
| useful guarantee. We could have also had the query return 0 | |
| or -1 as a signal that the framebuffer is incomplete. | |
| Again, this is all moot since we decided against this style | |
| of intrinsic buffers in this extension. | |
| (28) What should the <image> parameter to FramebufferTexture3DEXT | |
| actually be called? | |
| RESOLUTION: resolved, "zoffset" | |
| This parameter could have been called <image> or <slice>. | |
| <depth> or <zoffset> might also be appropriate. The reason | |
| the answer here is non-obvious is that normally 3D textures | |
| are specified all at once, not one 2D "slice" at a time | |
| (TexImage3D takes one big array that represents all three | |
| dimensions at once, for example), and because texture | |
| coordinates for TEXTURE_3D targets are normalized | |
| floating-point numbers, just as they are with TEXTURE_2D | |
| targets, not integer indices. | |
| The GL uses the term "image" to mean "slice" in a few | |
| instances. For example, pixel unpack parameters | |
| UNPACK_SKIP_IMAGE and UNPACK_IMAGE_HEIGHT describe state | |
| related to the "slices" a 3d texture. | |
| However, in some ways the act of rendering into a texture is | |
| most similar to CopyTexSubImage3D, which also redefines a | |
| texture's contents (but never its format or dimensions) based | |
| on the contents of the framebuffer. The "zoffset" parameter | |
| to CopyTexSubImage selects a particular 2D image (depth | |
| "slice") of a 3-dimensional texture. "zoffset" is a | |
| coordinate, and the parameter to FramebufferTexture3DEXT is | |
| also a coordinate. "Image" typically refers to an array of | |
| pixels. | |
| We already use the term "image" throughout this extension to | |
| talk about 2d arrays of pixels beyond their use in 3D | |
| textures. It is a little confusing to overload "image" to | |
| also mean Z coordinate in FramebufferTexture3DEXT. | |
| For the sum of these reasons, we decided "zoffset" is a | |
| better name than "image", for the parameter to | |
| FramebufferTexture3DEXT. | |
| (29) Should GenerateMipmap functionality be included in this | |
| extension or put in it's own extension? | |
| RESOLUTION: resolved, yes, include this functionality | |
| It is arguably useful separately, i.e., without all this | |
| machinery. However, it's also kind of required here to have | |
| some kind of way to deal with the interaction with | |
| SGIS_generate_mipmap. Probably we should just include it | |
| here. (maybe also a separate extension?) | |
| It's easier to define when automatic mipmap generation | |
| happens for a traditional non-rendered texture than it is | |
| for a texture that is modified by rendering-to-texture. If | |
| GENERATE_MIPMAP were to cause a rendered-texture's mipmaps | |
| to be automatically generated, presumably generation would | |
| occur when either the texture is detached from the | |
| framebuffer or when the framebuffer is unbound. If neither | |
| of these events occur, should automatic mipmap generation | |
| also occur when the texture is bound to a texture unit (of | |
| same or different context?) | |
| It's believed the recommended way of achieving maximum | |
| performance using this extension is to make all attachments | |
| during initialization, and then not change attachments in | |
| the steady state. This reasoning is, after all, a major | |
| reason for introducing framebuffer objects. If an | |
| application does not detach textures from framebuffers, then | |
| what event triggers mipmap generation? An explicit | |
| GenerateMipmap works well here. | |
| Would the base level have to actually be modified in order | |
| for mipmap generation to occur? How should "modified" be | |
| defined? | |
| If the application rendered to each level of the texture | |
| before detaching the texture or unbinding the framebuffer, | |
| would automatic mipmap generation happen anyway? (This | |
| implies the application needs to set GENERATE_MIPMAP to | |
| FALSE before rendering to the texture, but maybe that's OK.) | |
| Historical background: One reason for introducing | |
| GenerateMipmap in the context of the original uber_buffers | |
| proposal was that uber_buffers lacked a Begin-time | |
| consistency check, but instead prevented the framebuffer | |
| from ever getting into an inconsistent state (once | |
| validated). Operations such as TexImage that can change the | |
| dimensions and format of a tetxture's levels were disallowed | |
| when the texture was attached to a framebuffer. Since | |
| automatic mipmap generation can change the dimensions and | |
| format of a texture's levels, that meant that automatic | |
| mipmap generation could not be performed in some cases, but | |
| there was no good way to communicate this error to the | |
| application. Hence there really was a need for a separate | |
| GenerateMipmap function. This restriction does not apply | |
| to the current API because the semantics of an incomplete | |
| framebuffer are different now. Nevertheless, we decided to | |
| retain this manual mipmap generation as part of this | |
| extension. | |
| (30) Do the calls to deal with renderbuffers need a target | |
| parameter? It seems unlikely this will be used for anything. | |
| RESOLUTION: resolved, yes | |
| Whether we call it a "target" or not, there is *some* piece | |
| of state in the context to hold the current renderbuffer | |
| binding. This is required so that we can call routines like | |
| RenderbufferStorage and {Get}RenderbufferParameter() without | |
| passing in an object name. It is also possible we may | |
| decide to use the renderbuffer target parameter to | |
| distinguish between multisample and non multisample buffers. | |
| Given those reasons, the precedent of texture objects, and | |
| the possibility we may come up with some other renderbuffer | |
| target types in the future, it seems prudent and not all | |
| that costly to just include the target type now. | |
| (31) What should happen if you call FramebufferTexture{1D|2D|3D} | |
| with a texture name of zero? | |
| RESOLUTION: This will detach the image from the specified | |
| attachment point in the currently bound framebuffer object. | |
| For reference, this reason this is problematic because there | |
| is not really a "texture object zero" | |
| Texture name zero does not define an object but defines | |
| context state (one texture named zero, per target, per | |
| context). The textures referred to by the name zero are | |
| never shared across contexts. So the behavior of | |
| framebuffer objects shared by multiple contexts where each | |
| is attached to the context's texture named zero seems odd at | |
| best, and confusing at worst. As such, it was decided to | |
| not allow a framebuffer to attach to texture named zero. | |
| Another option would have been to make this an error. If we | |
| had done this, then we would need a specific function to | |
| detach a texture from an attachment point. That is, we | |
| would have needed to create something like a dedicated | |
| DetachFramebufferAttachableImage() entry point. | |
| (32) Should there be a renderbuffer object with the name of zero? | |
| RESOLUTION: NO. | |
| By way of symmetry with textures, renderbuffer zero, if it | |
| existed, would not be an object. It would be a | |
| non-shareable piece of the context state. There would be | |
| one renderbuffer named zero per target per context. | |
| If we can't share renderbuffer name zero, then also by way | |
| of symmetry with textures, we would not want to support | |
| attaching renderbuffer name zero to a framebuffer. | |
| So, if it can't be used as a rendering destination, then a | |
| renderbuffer name zero would seem to serve no purpose as a | |
| state container. | |
| However, we'd like to retain the use of name zero in certain | |
| routines with special semantics, particularly for detaching | |
| non-zero renderbuffer objects from the framebuffer and | |
| context. See issue (33). | |
| On implication of this decision is that state | |
| setting/getting routines that operate on the currently bound | |
| renderbuffer should throw a GL error if no renderbuffer is | |
| bound/attached. A similar choice was made in the | |
| ARB_vertex_buffer_objects specification which also had | |
| special semantics for object zero. | |
| Also note, another option considered was making object zero | |
| a full fledged, shareable object just like the non-zero | |
| object names. This was rejected as being too different from | |
| texture/program vbo's/etc., possibly leading to confusion. | |
| (33) What should happen if you call FramebufferRenderbuffer or | |
| BindRenderbuffer with a renderbuffer name of zero? | |
| RESOLUTION: This will detach the image from the | |
| specified attachment point in the currently bound | |
| framebuffer object. | |
| This is resolved exactly the same way as issue (31) was | |
| resolved for textures, and for the same reasons. | |
| Similarly, calling BindRenderbuffer with a name of zero will | |
| unbind the currently bound renderbuffer from the context. | |
| (34) Should there be a way to query a framebuffer object for its | |
| attached texture and/or renderbuffers? If so, how, and | |
| what should be the query result when attached textures or | |
| renderbuffers have been deleted? | |
| RESOLUTION: resolved, yes | |
| In general, OpenGL lets you query settable state, so | |
| we allow this. | |
| To see what this query should look like, see related | |
| issue (51) | |
| This issue also raises the question about what values should | |
| be returned for attached objects if the named objects have | |
| since been deleted. This can happen if the textures were | |
| attached to non-currently bound framebuffers or attached to | |
| framebuffers in other contexts. Three possible solutions | |
| include: | |
| a) Don't support this query. | |
| b) Return zero if no texture has ever been attached. | |
| Return zero if the attached texture has been deleted. | |
| c) Return zero if no texture has ever been attached. | |
| Return the name of the texture that was attached even | |
| though it has been deleted. | |
| Option (a) was rejected as we would like settable state | |
| to be queriable. | |
| So, for this extension originally we choose option (c). | |
| However, we have since decided, in issue (21), that | |
| DeleteTexture and DeleteRenderbuffer will first detach | |
| the texture/renderbuffer from any attached framebuffer | |
| objects *in this context*. In principle, the | |
| application can't tell the difference between the | |
| texture getting deleted now or later, so whether the | |
| texture is actually detached from the current | |
| framebuffer now and other framebuffers when they are | |
| bound, or the texture is actually detached from all | |
| framebuffers at once is moot. In practice, this means | |
| that options (b) and (c) are essentially | |
| indistinguishable for a single context case. | |
| However, it's worth noting that if the texture is | |
| deleted and attached to a framebuffer which is current | |
| in another context, the standard rules about undefined | |
| behavior of state modifcations of shared objects in | |
| other contexts will still applye. | |
| This means that the texture may or may not be detached | |
| (and thus deleted) from that other context's current | |
| framebuffer until the next BindFramebuffer (or | |
| FramebufferTexture/FramebufferRenderbuffer?) in the | |
| other context. | |
| (35) Earlier proposals included a way to create some memory and then | |
| attach it to a texture object. Should this extension include | |
| this feature? | |
| RESOLUTION: no. | |
| This was considered when this extension was intended | |
| to be a more general purpose memory manager. Since this | |
| extension has been retasked to focus in on render-to-X | |
| functionality, this feature was not necessary. | |
| (36) Earlier proposals had renderable memory constructs which could | |
| change internal format or dimensions to meet intra-framebuffer | |
| compatibiltiy requirements of individual vendors' hardware | |
| platforms. Should this extension have these kind of malleable | |
| format objects? | |
| RESOLUTION: no. | |
| Such malleability leads to invariance problems when formats | |
| change. For example, if bits per pixel is decreased then | |
| increased back to the original value, some precision is | |
| lost. | |
| Some IHVs wanted to require format conversion of existing | |
| contents in all cases where the format changes. This sort | |
| of invariance would be an acceptable side-effect. The | |
| suggestion was to think of the action of rendering to a | |
| texture as an extended non-atomic TexImage call. TexImage | |
| is allowed to change the format of an existing texture | |
| image. It was claimed that such intrinsic buffers are more | |
| convenient in many applicaitons than are the explicitly | |
| managed renderbuffers. | |
| Other IHVs expressed a strong opinion against implicit | |
| format conversions, but instead wanted to invalidate the | |
| buffer's contents whenever the format changed. It was | |
| difficult to define the set of operations that might cause | |
| the format to change, so it was difficult to define when the | |
| contents could become invalidated. If the contents were | |
| invalidated by a format change, the API under consideration | |
| made it cumbersome for the application to detect and handle | |
| this condition. In the end, under the buffer content | |
| invalidation approach, application code would not be any | |
| better off than if the appliation instead used the explicit | |
| renderbuffers. For the type of intrinsic buffers that could | |
| not change format and dimensions dynamically, the claim that | |
| intrinsic buffers were more convenient than renderbuffers | |
| was no longer true. | |
| The working group voted for the latter: no implicit format | |
| changes. Instead the format would be immutable once it is | |
| known. | |
| A secondary issue is the question: are the buffer contents | |
| invalidated when the dimensions change, are the contents | |
| scaled, or are the contents are clipped/padded (with some | |
| sort of gravity). This issue could be avoided by requiring | |
| explicit, rather than implicit, resize of intrinsic buffers. | |
| The working group voted for no implicit change in the | |
| dimensions of intrinsic buffers, and finally for the removal | |
| of intrinsic buffers altogether. | |
| (37) In order to abstract hardware dependent compatibility | |
| requirements, this API introduces a function called | |
| CheckFramebufferStatus to check for compatibility prior to | |
| rendering. CheckFramebufferStatus returns a value which | |
| indicates whether or not the framebuffer object is "framebuffer | |
| complete", and framebuffer completeness depends in part on | |
| hardware dependent constraints. The hardware dependent aspect | |
| represents a new concept in OpenGL. Therefore, should an app | |
| be required to call this function to help "enforce" the notion | |
| that apps should be on the lookout for failure? | |
| RESOLUTION: no. Calling CheckFramebufferStatus is not | |
| required. | |
| The group considered requiring a call to | |
| CheckFramebufferStatus after changing framebuffer state or | |
| attachment points in order to "enable" rendering. It was | |
| hoped that requiring a call to CheckFramebufferStatus would | |
| push developers to write code which is more platform | |
| independent. Ultimately though, since the API can't require | |
| applications to actually observe and deal with a validation | |
| failure, that it was not worth it to make this function call | |
| required. There was also feedback from some developers that | |
| requiring this call would be cumbersome and undesirable. | |
| Note, however, that the framebuffer is effectively validated | |
| implicitly at every rendering (and reading) entry point. | |
| These include glBegin, gl{Multi}Draw{Arrays|Elements}, | |
| gl{Draw|Copy|Read}Pixels, glCopyPixels, glReadPixels, | |
| glCopyTex{Sub}Image, etc. | |
| Applications are strongly advised to test framebuffer | |
| completeness with CheckFramebufferStatus after setting up or | |
| changing the configuration of a framebuffer object, and to | |
| handle the possible failure cases with a fallback plan that | |
| selects a different set of internal formats of attached | |
| images. See usage example 6. Section 4.4.4.2 lists the | |
| operations that can cause the framebuffer's status to | |
| change. | |
| In addition, a "format group" API, has been proposed as a | |
| means of programmatically determining a set of internal | |
| formats that are guaranteed to be compatible with respect to | |
| framebuffer completeness. This API would be specified in a | |
| layered extension as suggested in issue (12) | |
| (38) Do we need to support multiple render targets, i.e., | |
| ARB_draw_buffers? | |
| RESOLUTION: Yes. | |
| ARB_draw_buffers is going to be part of OpenGL 2.0 so we'd | |
| better support it. | |
| (39) How should we support ARB_draw_buffers? | |
| RESOLUTION: refactored into the following issues: | |
| (53), (54), (55), (56), and (57) | |
| (40) (How) should we support accum buffers? | |
| RESOLUTION: defer this until (shortly) after this extension. | |
| Accum buffers appears to be very simple to specify and | |
| implement. Basically, we would need to add a new internal | |
| ACCUM format that can be passed to RenderbufferStorage. We | |
| would also need to add an ACCUM attachment point in the | |
| framebuffer that could be used to point to one of these | |
| ACCUM format renderbuffers. A new ACCUM format is needed | |
| because the ACCUM buffer is defined by GL to be signed | |
| floating point value, unlike other internal formats. | |
| Also note, the above solution is the exact same one we are | |
| using for STENCIL buffers as well (i.e., an internal format | |
| enum and an attachment point). | |
| We could also decide if this new ACCUM internal format can | |
| be used with textures in addition to renderbuffers, for | |
| creating images that can be attached to the accum buffer | |
| attachment point. | |
| Supporting accum was deferred for this extension, primarily | |
| for time-to-market reasons, and as it was not critical for | |
| most render-to-texture applications. However, we intend to | |
| work on some kind of "EXT_accum_renderbuffer" extension | |
| shortly. | |
| Since this was deferred, we need to define what happens when | |
| you call the various Accum operations on a non-default | |
| framebuffer object. We considered adding spec language that | |
| would generate an error on Accum operations. However, it | |
| seems like we can simply leverage whatever legacy behavior | |
| is currently defined for when the pixel format has no accum | |
| buffer. This is the case in this extension as we have | |
| defined no way to attach or enable an accum buffer. Chapter | |
| 4 on page 188 already says that "If there is no accumulation | |
| buffer, or if the GL is in color index mode, Accum generates | |
| the error INVALID OPERATION", so we don't actually need any | |
| additional language of our own. | |
| (41) (How) should we support multisample buffers? | |
| RESOLUTION: defer this until (shortly) after this extension. | |
| Supporting multisample was deferred for this extension, | |
| primarily for time-to-market reasons and because it's not | |
| entirely clear what is the "best" API for exposing | |
| multisample. However, we intend to work on some kind of | |
| "EXT_multisample_renderbuffer" extension shortly. | |
| Since this feature was deferred, we need to define what | |
| happens when you try to enable multisample on a non-default | |
| framebuffer object. For now we need some way to *not* do | |
| multisampling. This can either be that we set SAMPLES 1 and | |
| SAMPLE_BUFFERS to 0, or we say that | |
| Enable/Disable(MULTISAMPLE) is ignored. This is actually | |
| related to issue (62) - should SAMPLE_BUFFERS change when | |
| using a non-default framebuffer or when attachments change? | |
| When/if we define and export "EXT_multisample_renderbuffer" | |
| extension, this state will again have significance. | |
| A discussion of how we might support this feature follows: | |
| There are several considerations here: First, we'd like | |
| something simple to specify, implement, and use. Second, | |
| we'd like to not delay this extension's approval, | |
| implementation or adoption for this particular feature. | |
| Third, we are trying to replace pbuffer functionality, which | |
| does support multisampling (at least in principle), so we'd | |
| like to not take a step backward in functionality if | |
| possible. | |
| However, this extension is *not* trying to "improve" the | |
| traditional multisample support. If we do anything, we will | |
| simply expose the existing multisample buffer semantics | |
| without causing undue implementation burden. | |
| Finally, if an implementation is currently taking short-cuts | |
| to GL's traditional "per-pixel-resolve" multisample | |
| semantics, we'd like for this extension to continue to allow | |
| the exact same short-cuts (to whatever extent the core GL | |
| spec does or does not allow those short-cuts). If someone | |
| later decides to go an revamp multisampling support in | |
| general, they can update this extension at the same time. | |
| Given the above, it appears that the options include: | |
| A) Don't support it. In other words, you can't use | |
| mulitsampling and EXT_framebuffer_object. The | |
| multisample state is either ignored, or causes the | |
| framebuffer to not be complete, or generates some kind | |
| of error. | |
| B) Create a separate multisample renderbuffer that can be | |
| attached to a new framebuffer attachment point. | |
| The reason that we might need a separate | |
| RESOLUTION_BUFFER is that all renderable color buffer | |
| formats might not be usable for multisampling on all | |
| implementations. | |
| Also, this option would allow multiple framebuffers to | |
| share the storage for multisample buffers under the | |
| control of the application. | |
| Depth sample buffers and stencil sample buffers | |
| wouldn't necessarily need resolution buffers, but that | |
| could be added by some future extension. | |
| This option has several variants: | |
| B1) Create MULTISAMPLE and/or RESOLUTION_BUFFER | |
| internal formats for renderbuffer objects that | |
| can be used with RenderbufferStorage. The | |
| samples buffer and the resolution buffer would be | |
| allocated and attached to the framebuffer | |
| separately. Having them be separate allows the | |
| samples to be deleted after rendering if desired. | |
| One issue with this option is that somehow you'd | |
| need to specify the number of samples maybe using | |
| glFramebufferParameter or | |
| glRenderbufferParameter. | |
| B2) Perhaps, instead of using a single internal | |
| format called MULTISAMPLE, use a set of internal | |
| formats like MULTISAMPLE_1_SAMPLE, | |
| MULTISAMPLE_2_SAMPLE, MULTISAMPLE_4_SAMPLE, etc. | |
| This is problematic for supporting depth/stencil | |
| multisampling unless we want an explosion of | |
| color/depth/stencil multisample internal formats. | |
| It's also problematic if MRT draw buffers need to | |
| be multisampled because we'd need a number of | |
| enums able to support 1 to N draw buffers times | |
| the number of sample patterns we support. | |
| B3) Have RenderbufferStorage always take a number of | |
| samples. We could do this if option (B2) is | |
| insufficient due to the need to support DEPTH or | |
| STENCIL multisampling, which we probably will. | |
| We would then allow the internal format to choose | |
| DEPTH, STENCIL, or RGBA/etc. This is clean but | |
| it means that the user would always need to | |
| specify a number of samples even when the value | |
| is "1". | |
| B4) Pass in a variable length argument list to the | |
| renderbuffer allocation routine, and some of the | |
| arguments would indicate intended usage | |
| (COLOR/DEPTH/MULTISAMPLE) others would indicate | |
| internal format (RGBA/DEPTH24) and others would | |
| indicate number of samples. This is how | |
| EXT_compromise_buffers dealt with this problem, | |
| though people didn't seem to like this variable | |
| length argument list. EXT_render_target didn't | |
| deal with this problem so doesn't offer any | |
| guidance here. | |
| B5) Create a new RENDERBUFFER_MULTISAMPLE | |
| renderbuffer target type and a corresponding | |
| allocation routine, perhaps called | |
| RenderbufferMultisampleStorage(). This is | |
| analogous to how textures have their own | |
| allocation routine per target type | |
| (TexImage1D/2D/3D, etc). | |
| With this option, we could preclude | |
| non-multisample targets from being attached to | |
| non-multisample attachment points as well. | |
| B6-B10) Any of the above options can be implemented | |
| with either a single monolithic mulitsample | |
| buffer that contains the samples for all draw | |
| buffers, depth and stencil and a single | |
| attachment point, *OR* with independent | |
| multisample buffers for each draw buffer and | |
| depth and stencil and independent attachment | |
| points for each. | |
| C) Use some kind of "behind the scenes" mulitsample buffer. | |
| This option also has several variants: | |
| C1) An "implicit" multisample buffer that is simply a | |
| property of the framebuffer object. Each | |
| framebuffer object could have its own multisample | |
| buffer(s). Multisampling would be enabled with | |
| some kind of FramebufferParameter call. This | |
| implies that each framebuffer has memory | |
| allocated with it. It further implies that the | |
| contents of the multisample buffer are | |
| framebuffer state and are thus retained with the | |
| framebuffer object. | |
| C2) We don't say anything except that we say the | |
| value of the glEnable(MULTISAMPLE) is still | |
| respected and we render as directed. This is | |
| similar to (C1) but we don't go so far as to say | |
| that the multisample buffer(s) is/are retained | |
| per framebuffer object. In other words, a call | |
| to BindFramebuffer() and changes to framebuffer | |
| attachments may or may not retain multisample | |
| buffer contents. Valid implmentations of this | |
| would include a multisample buffer per | |
| framebuffer or one per context. | |
| D) something else (hopefully simpler?) | |
| (42) What set of framebuffer targets should the initial extension | |
| support? | |
| RESOLUTION: resolved, (D) single target | |
| Basic possibilities include: | |
| (A) DRAW_AND_READ_FRAMEBUFFER_EXT | |
| (B) DRAW_FRAMEBUFFER_EXT | |
| READ_FRAMEBUFFER_EXT | |
| (C) DRAW_FRAMEBUFFER_EXT | |
| READ_FRAMEBUFFER_EXT | |
| DRAW_AND_READ_FRAMEBUFFER_EXT | |
| (D) FRAMEBUFFER_EXT | |
| The fundamental question is: must framebuffer binding points | |
| mimic the expressiveness of the window-system function | |
| MakeContextCurrent, which is described in the glX spec and | |
| the ARB_make_current_read extension? | |
| It was not immediately clear how to specify the distinction | |
| between a READ and a DRAW framebuffer in the context of the | |
| existing read/draw buffer semantics, given that this | |
| extension relaxes the "compatibility" requirement between | |
| read and draw drawables. How would the value of RED_BITS | |
| for the read framebuffer be queried if it is different than | |
| the value of RED_BITS for the draw framebuffer? What | |
| exactly is the set of implementation dependent state (see | |
| the "Implementation Dependent *" state tables in chapter 6) | |
| that can differ between read and draw framebuffer objects? | |
| When using MakeContextCurrent, the context's and drawable's | |
| FBconfig (or pixel format) must be "compatible" or else the | |
| results are implementation dependent. But | |
| EXT_framebuffer_object cannot afford to swing such a large | |
| "undefined" stick, because it is more likely that | |
| framebuffer objects are incompatible in this sense, and | |
| because the "pixel format compatility" of a framebuffer | |
| object is dynamic--by changing attachments or redefining the | |
| internal format of an attached texture image. | |
| The value added by ARB_make_current_read through | |
| MakeContextCurrent is less relevant to | |
| EXT_framebuffer_object. EXT_framebuffer_object enables | |
| rendering to a texture, and textures are objects with a | |
| clearly defined mechanism for use as the source of a pixel | |
| copy: rather than using CopyPixels to move pixels from the | |
| READ_BUFFER to the DRAW_BUFFER(s), an application can simply | |
| use the source data as a texture and then draw a | |
| screen-aligned textured quad to the framebuffer. | |
| Additionally, adding separate DRAW and READ bindings in the | |
| future is pretty straightforward. One solution would be to | |
| say that FRAMEBUFFER_EXT is the DRAW framebuffer, and name | |
| the new READ framebuffer FRAMEBUFFER_READ_EXT. Add a new | |
| BindFramebuffer-like function which takes two framebuffer | |
| names--one for DRAW and one for READ. The current | |
| BindFramebuffer function binds a single object to both | |
| FRAMEBUFFER_EXT and FRAMEBUFFER_READ_EXT. | |
| So, we defer the additional targets until need has been | |
| proven, and go with the simpler option (D) for now. | |
| (43) In order for a framebuffer object to be "framebuffer complete", | |
| must all textures attached to the framebuffer be mipmap | |
| complete (or mipmap cube complete if cubemap texture)? | |
| RESOLUTION: resolved, no | |
| The reason this is a consideration is that some | |
| architectures require framebuffer-attachable images to be | |
| located in graphics memory when rendered to, and it may be | |
| more convenient to allocate and store a texture in graphics | |
| memory only if the texture is mipmap (cube) complete--i.e., | |
| the size and format of all levels are consistent in the | |
| normal sense of texture compeleteness. | |
| However, since framebuffer attachment points only really | |
| deal with single images of a texture level, it seems | |
| excessive to require the state of the other levels of a | |
| texture to affect the validty of the framebuffer object | |
| itself. | |
| Addtionally, the same difficulties around "incomplete" | |
| textures already apply to traditional CopyTexSubImage, and | |
| we have been trying to make the render-to-texture semantics | |
| similar to CopyTexSubImage. | |
| Therefore, we chose not to treat render to texture any | |
| differently than CopyTexSubImage and do not require that the | |
| attached texture is mipmap (cube) complete. | |
| (44) What should happen if a texture that is currently bound to the | |
| context is also used as an image attached to the | |
| currently bound framebuffer? In other words, what happens if a | |
| texture is used as both a source for texturing and a | |
| destination for rendering? | |
| RESOLUTION: resolved, (b2) - results are undefined because | |
| the framebuffer is not "framebuffer complete". | |
| Originally this was resolved as causing framebuffer to fail | |
| the completeness test--i.e., rendering would be disabled (b1) | |
| As background, the reason this is an issue in the first | |
| place is that simultaneously reading from, and writing to, | |
| the same texture image is likely to be problematic on | |
| multiple vendors' hardware without paying performance | |
| penalties for excessive synchronization and/or data copying. | |
| There are, however, certain cases where this functionality | |
| would arguably be useful, supportable, and well-defined. In | |
| particular, we can consider the case of custom mipmap | |
| generation using one level's image as source data to render | |
| into other levels of the same texture. | |
| So, at a minimum, we would like to support rendering to a | |
| currently bound texture object if the source texture object | |
| has the BASE_LEVEL and MAX_LEVEL texture parameters set such | |
| that the level being used as a framebuffer-attachable image | |
| is excluded from texture fetches. | |
| This was our original rationale: | |
| a1) is problematic because one context could modify the | |
| base/max level on a shared texture causing another | |
| context which is using the texture as a destination to | |
| throw an error. This idea was rejected as it | |
| essentially meant that the error would need to be | |
| thrown at render timer which people found unacceptable. | |
| b1) has the same kind of multicontext behavior but no | |
| error. One context can cause a framebuffer shared in | |
| another context to become invalid, but this is already | |
| true and can happen for a variety of reasons if the | |
| participating framebuffer-attachable images and/or | |
| framebuffer attachments are modified by either context. | |
| At the time, we also considered the following | |
| questions: should the specification require the | |
| framebuffer to fail the framebuffer completeness test? | |
| Or is the framebuffer simply "allowed" to not be | |
| complete in this case? The latter choice would imply | |
| that the framebuffer might still be considered | |
| "framebuffer complete" on some implementations. See | |
| issue (46) | |
| c1) is the easiest to specify and has an advantage that | |
| some implementations may be relying on this behavior | |
| already. However, this was rejected as it is the least | |
| portable of the three options. | |
| We originally chose option (b1), though we considered that | |
| later on, individual hardware vendors may offer layered | |
| extensions that change this "framebuffer completeness" | |
| failure into a success with either defined or undefined | |
| rendering behavior. | |
| However, this issue was re-opened becaues the subsequent | |
| resolution of issue (66) was that there should be no | |
| "context-dependent" reasons for framebuffer incompleteness. | |
| If we had stuck with option (b1), then we would be making | |
| the framebuffer completeness predicated on a piece of | |
| context state (the current texture binding). Consider the | |
| case where texture T is attached to a framebuffer. Then | |
| this would have meant that a framebuffer could be complete | |
| in one context (that didn't have texture T bound as a | |
| texture) and incomplete in another context (that did have | |
| texture T bound). | |
| When reconsidering this issue, we realized that we would not | |
| throw an error at Begin time without disabling rendering, so | |
| we really only considered the following revised set of | |
| options: | |
| a2) throw an error and disable rendering, but don't | |
| affect framebuffer completeness | |
| b2) the behavior is undefined | |
| The issue was resolved the second time as: | |
| b2) Undefined behavior | |
| Another option that was briefly considered was to make this | |
| another type of error (unrelated to trying to render with an | |
| incomplete framebuffer). However, part of the rationale for | |
| throwing an error at glBegin time when trying to render with | |
| an incomplete framebuffer was that if you already have to | |
| test for framebuffer completeness, then throwing an error is | |
| no additional implementation burden. Yet, since it was | |
| decided that the "texture-from-destination" condition is not | |
| part of framebuffer completeness - issue (66) - then it is | |
| an additional burden to perform the | |
| "texture-from-destination" check just so that an error can | |
| be generated. The concern was some implementations might | |
| not need to check for this case at all and we didn't want to | |
| burdern those implementations with an additional Begin-time | |
| error check. | |
| Also, for what it's worth, if we had left the | |
| "texture-from-destination" case in the framebuffer | |
| completeness test then any language describing how | |
| framebuffer completeness is affected when a currently bound | |
| texture is used as both source and destination needs to be | |
| explicit that the texture has to be currently bound *and* | |
| enabled. For instance, consider the case where a user has a | |
| cubemap texture object name N bound to unit X and a 2D | |
| texture object name M also bound to unit X. What if the | |
| user would like to use the 2D texture M as a source while | |
| rendering to the faces of the cubemap texture N? We would | |
| like to support this scenario, so the language about a | |
| currently bound texture object would have needed to take the | |
| target into account. And to make matters more interesting, | |
| this means we would have needed to take texture enables and | |
| fragment shaders into account in this decision. In the end, | |
| we decided that "context-state" would not affect the | |
| defintion of framebuffer completeness we avoided this | |
| complexity (or at least moved it out of the framebuffer | |
| completeness test). | |
| (45) Are framebuffer configurations with no color attachments allowed? | |
| RESOLUTION: resolved, yes | |
| The reason this is an issue is that the GL spec assumes | |
| there is always a color buffer. If a framebuffer with no | |
| images attached to any of the color buffer attachment points | |
| can be "framebuffer complete", then the core GL spec will | |
| need to be modified to relax the assumption that a color | |
| buffer always exists. | |
| However, since one of the possible likely uses of this | |
| extnesion is to support depth texture rendering and stencil | |
| rendering for shadowing techniques, it seems like requiring | |
| an unused "dummy" color buffer in some cases is both | |
| inconvenient and a waste of memory. | |
| Therefore, framebuffers do not require color attachments to | |
| be valid. Perhaps though we should require that a | |
| framebuffer with *no* attachments is invalid. | |
| It also should be stated that attempting to render without | |
| the "appropriate" buffers attached needs to be defined. For | |
| instance, presumably, for depth rendering with no depth | |
| buffer attached, the depth test is disabled, as it is in | |
| traditional GL. | |
| (46) In the framebuffer completeness criteria, this extension | |
| introduces the idea that rendering can fail for implementation | |
| dependent reasons. Framebuffer completeness also considers | |
| implementation *independent* reasons for failure. | |
| Do we need to make special distinction between the cases where | |
| a framebuffer is not complete because of implementation | |
| dependent or because of implementation indepenent reasons? | |
| RESOLUTION: resolved, yes, though this is really tied into | |
| how we resolve the minimum requirements for supporting this | |
| extension. See issue (61) | |
| Examples where a framebuffer may be incomplete on some | |
| implementations but not others include: | |
| - 16 bit z-buffer used with 8 bit stencil buffer | |
| - 32 bit color buffer with 16 bit depth buffer | |
| - others? | |
| Examples where framebuffer MUST be incomplete on all | |
| implementations include: | |
| - color-renderable image attached to a non-color | |
| attachment point | |
| - depth-renderable image attached to a non-depth | |
| attachment point | |
| - stencil-renderable image attached to a non-stencil | |
| attachment point | |
| - all images attached to a framebuffer do not have the | |
| same dimensions | |
| - multiple render targets of different bit depths | |
| - texture image attached to the framebuffer is part of a | |
| currently bound and enabled texture and the image is | |
| within the range of mipmap levels that can be fetched | |
| by rendering. | |
| To make this determination we need to describe the criteria | |
| we should use to determine whether a framebuffer *can* or | |
| *must* be incomplete. | |
| The arguments for putting state vectors into the "can" fail | |
| case is that a later extension can come along and simply | |
| relax those portions of the framebuffer completeness | |
| definiton with no additional API. State vectors classified | |
| as "must" fail cases would at least require the later | |
| extension to add an additional enable to start passing. | |
| (47) Certain state-modification operations can cause a change to the | |
| validated state of a framebufffer. (I.e., can make a | |
| framebuffer that was complete become incomplete, or | |
| vice-versa). Do we want to list exactly which | |
| state-modification routines can cause this to happen? If so | |
| what is the list? | |
| RESOLUTION: resolved, the answer is: yes we want to | |
| delineate exactly which routines can cause validation state | |
| changes. | |
| Currently any routine which changes any of the following | |
| state can potentially cause framebuffer completness to | |
| change: | |
| framebuffer state | |
| state changes to attached objects | |
| currently bound fragment program | |
| texture enable state | |
| The list of operations that can cause framebuffer a change | |
| to framebuffer completeness are spelled out in section | |
| 4.4.4.2. | |
| (48) What information should be returned from | |
| CheckFramebufferStatusEXT()? | |
| New RESOLUTION: resolved: 8 possible enum values, see issue | |
| (55) | |
| Previous RESOLUTION: resolved, return one of three enumerated values: | |
| 1. GL_FRAMEBUFFER_COMPLETE_EXT | |
| 2. GL_FRAMEBUFFER_UNSUPPORTED_EXT | |
| 3. GL_FRAMEBUFFER_INCOMPLETE_EXT | |
| where the three values mean the following: | |
| 1. framebuffer is complete and supported | |
| 2. framebuffer is not supported for implementation *dependent* reason | |
| 3. framebuffer is incomplete for implementation *independent* reason | |
| We considered the following two sets of enums: | |
| Set 1: | |
| GL_FRAMEBUFFER_COMPLETE_EXT | |
| GL_FRAMEBUFFER_NOT_COMPLETE_EXT | |
| GL_FRAMEBUFFER_NOT_SUPPORTED_EXT | |
| Set 2: | |
| GL_FRAMEBUFFER_COMPLETE_EXT | |
| GL_FRAMEBUFFER_INCOMPLETE_EXT | |
| GL_FRAMEBUFFER_UNSUPPORTED_EXT | |
| New resolution is Set 2. | |
| NOTE: In order to fully resolve issue (55), we expanded this set | |
| of enums to identify all of the implementation-independent | |
| causes for a failure of the framebuffer completeness test. | |
| Originally, we had decided to have a query where the | |
| query returns one of three possible values | |
| One possible set of names that could be returned included: | |
| FRAMEBUFFER_COMPLETE, and | |
| FRAMEBUFFER_HW_DEPENDENT, and | |
| FRAMEBUFFER_HW_INDEPENDENT | |
| How much information we return from CheckFramebufferStatus | |
| is a function of how we expect the return value to be used. | |
| A framebuffer object that is not complete for implementation | |
| *indepednent* reasons is really an indication of a | |
| programming error (like mismatched sizes) and should only | |
| occur during development phase of an application. The | |
| correct response to this failure is to modify the | |
| application to fix the bug. After application development, | |
| a framebuffer object that is not complete for implementation | |
| *dependent* reasons is possible. However, it's not yet | |
| clear whether we can easily characterize these reasons for | |
| failure in a programmatic fashion that would really offer | |
| the application enough information to do something different | |
| at runtime. Perhaps a human readable info log, intended | |
| just as an application debugging aid, would be more | |
| appropriate. | |
| We also considered whether we needed two separate queries: | |
| One that queried whether the framebuffer was complete | |
| according to the spec, and one that queried whether the | |
| framebuffer was supported. This was a little problematic as | |
| it might not be possible to answer the | |
| "IsFramebufferSupported" query until the framebuffer was | |
| complete. A possible solution would have been to return | |
| UNKNOWN from the "IsFramebufferSupported" query until the | |
| "IsFramebufferComplete" query returned TRUE. | |
| In any event, we decided a single query was a simpler | |
| solution. | |
| In addition, the proposed "format group / format | |
| restriction" API (see issue 12) should make the | |
| implementation-dependent framebuffer incomplete case much | |
| less likely (and perhaps impossible) to occur. | |
| Note that if a framebuffer's state violates more than one of | |
| the framebuffer completeness rules described in section | |
| 4.4.4.2, then it is undefined which of the enumerated value | |
| corresponding to one of the violated rules will be returned | |
| by CheckFramebufferStatusEXT. Since the initial state of a | |
| framebuffer violates multiple rules from section 4.4.4.2, | |
| it is therefore undefined exactly which value is returned if | |
| CheckFramebufferStatusEXT is called while bound to a newly | |
| created framebuffer object. | |
| (49) When this extension is used in conjunction with MRT (multiple | |
| render targets), it would naively be possible to create a | |
| framebuffer that had different color bit depths/formats for | |
| various color attachment points. Should this be allowed? | |
| RESOLUTION: resolved, no, not in this extension. | |
| A soon to follow extension may add this feature. | |
| This feature could be supported by simply not requiring that | |
| all of the FRAMEBUFFER_COLOR_ATTACHMENTn images share the | |
| same internal format. We decided against doing so, however. | |
| ARB_draw_buffers and OpenGL-2.0 do not provide any mechanism | |
| to support rendering to multiple color buffers of different | |
| formats. Consequently, we chose not to extend OpenGL in | |
| this manner as part of the EXT_framebuffer_object extension. | |
| Presumably, a future layered extension could easily add this | |
| feature. There are some open questions about exactly how | |
| this might work. For instance, what should a query of | |
| RED_BITS return if the attached color-renderable images have | |
| different formats? In any event, we leave the details of | |
| rendering to differently formatted MRT for a future | |
| extension to define. | |
| (50) This extension introduces the concept of attaching one GL | |
| object (texture, renderbuffer) to another GL object | |
| (framebuffer). In many ways this situation is analogous to a | |
| previously poorly specified situation where a GL object could | |
| be attached to multiple contexts and the issues this raises | |
| with deletion and state propogation are similar. Several | |
| issues resolutions have been predicated on the assumption that | |
| as we specify this container/member relationship, the | |
| generation of GL errors should never be triggered in one | |
| context based on the asychronous actions of another context. | |
| Is this a valid premise? | |
| In other words, should we be using the prevention of | |
| asynchronously generated GL errors as a design constraint? | |
| RESOLUTION: resolved, no. | |
| We didn't officially decide on this as a design constraint. | |
| However, we essentially decided it by proxy. We decided in | |
| issue (26) and (66) that an incomplete framebuffer can cause | |
| GL errors on rendering or reading the framebuffer. | |
| Consequently, this means a framebuffer shared by two | |
| contexts can be made incomplete by either context, and | |
| therefore each context can effectively cause the other | |
| context to start generating errors asynchronously. | |
| We would expect that the state of framebuffer completness, | |
| like all the state of all shared objects, is not | |
| "guaranteed" to show up in another context until that | |
| context makes an "atomic" request to the server (like a | |
| BindFramebuffer for instance). Until that point, it is | |
| undefined whether the state change will show up in the other | |
| context, just like any state change made on a shared texture | |
| object. | |
| (51) What api should we use to query the attachments of | |
| the currently bound framebuffer? | |
| RESOLUTION: resolved, (b) | |
| This is an issue because the relevant state | |
| for a specific attachment point is a function | |
| of the type of object attached to that that attachment point. | |
| The attachment point state needs to select a | |
| an image from an object which may have | |
| a collection of images, for instance | |
| the faces of a cube map texture. | |
| This introduces a kind of "polymorphism" into the | |
| framebuffer attachment point that is problematic | |
| for queries. | |
| We have a few options: | |
| a) Some kind of single atomic query that | |
| returns a variable number of values in an array: | |
| GetFramebufferParameteriv(enum target, | |
| enum pname, | |
| int* params); | |
| where | |
| <target> = a framebuffer target | |
| <pname> = {attachment_point} | |
| Upon success "params" will contain an array of | |
| values where | |
| params[0] = {NONE | TEXTURE | RENDERBUFFER} | |
| if params[0] == TEXTURE then | |
| params[1] = texture object name | |
| params[2] = level | |
| params[3] = face | |
| params[4] = image | |
| else if params[0] = RENDERBUFFER then | |
| params[1] = renderbuffer name | |
| Elements of the params array not explicitly defined | |
| above will have undefined values. | |
| One problem with (a) is that we would potentially also | |
| need a query to identify how many state variables will | |
| come back in this query. Consider the case where in the | |
| future we add a new attachable object type that needs | |
| more selections tate or even add new selection state to | |
| existing object types. Applications coded to expect a | |
| maximum of n values returned today may break in the | |
| future unless they have a way to dynamically learn how | |
| many attachment state params will come back from the | |
| query. | |
| b) individual queries for all the possible attachment | |
| state values. | |
| We create a new routine to add a new <attachment> | |
| argument, otherwise we'd have an explosion of | |
| permutations of attachment points and possible attachment | |
| selection state values | |
| This could look like | |
| void GetFramebufferAttachmentParameteriv(enum target, | |
| enum attachment, | |
| enum pname, | |
| int *param); | |
| where | |
| <target> = a framebuffer target | |
| <attachment> = {attachment_point} | |
| <pname> = one of | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT | |
| Upon success, param will be filled out as follows: | |
| if pname is FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT, | |
| then param will contain one of: | |
| { NONE | TEXTURE | RENDERBUFFER }, | |
| else if pname is | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, and | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = TEXTURE, | |
| then param will contain: | |
| { name of attached texture } | |
| else if pname is | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, and | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = | |
| RENDERBUFFER, then param will contain: | |
| { renderbuffer object name } | |
| else if pname is | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, and | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = TEXTURE, | |
| then param will contain: | |
| { selected mipmap level of attached texture } | |
| else if pname is | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT, | |
| and FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = | |
| TEXTURE, then param will contain: | |
| { selected face of attached cube map texture } | |
| { 0 if texture target is not TEXTURE_CUBE_MAP } | |
| else if pname is | |
| FRAMEBUFFER_ATTACHMENT_TEXTURE_ZOFFSET_EXT, and | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = TEXTURE, | |
| then param will contain: | |
| { selected z-slice/image of attached 3D texture } | |
| { 0 if texture is not 3-dimensional } | |
| otherwise, param will contain the value 0. | |
| One problem with option (b) is that it is a little | |
| heavy-handed as every piece of state needs its own query | |
| and enum | |
| Given the above choices, and the problems of extending option | |
| (a) in the future, (b) is probably the better of the two | |
| choices. It really only adds a few enums, and though it does | |
| require an independent function call to obtain each piece of | |
| state, this is well-precedented behavior throughout GL. | |
| (52) Should manual mimpap generation via GenerateMipmap apply to | |
| textures regardless of whether they are attached to framebuffer | |
| objects? Should automatic mimpap generation apply to all | |
| textures regardless of whether they are attached to framebuffer | |
| objects? | |
| RESOLUTION: resolved, (a) - both apply to both. | |
| This is an issue because the introduction of GenerateMipmap is | |
| intended both to address long standing complaints about the | |
| existing "automatic" mipmap generation API and to provide a | |
| clear trigger for render to texture API's to know when to do | |
| the mipmap generation. | |
| These API's could be considered completely orthogonally. It's | |
| clear how they could interoperate. The question is should they | |
| interoperate, or should one supercede the other? | |
| There are a couple of ways to address this issue: | |
| a) "automatic" mipmap generation applies always and is | |
| triggered by any gl{Copy}Tex{Sub}Image call if | |
| GENERATE_MIPMAP is set to TRUE. "Manual" mipmap | |
| generation applies always and is triggered by a call to | |
| GenerateMipmap | |
| b) "automatic" mipmap generation applies only | |
| to textures which are not attached to framebuffer | |
| objects, calls to GenerateMipmap on "unattached" textures | |
| are ignored. | |
| "manual" mipmap generation applies only to textures which | |
| are attached to framebuffer objects, the value of | |
| GENERATE_MIPMAP for "attached" textures is ignored | |
| c) Like option (b), but allow GenerateMipmap to | |
| apply to all textures and only let automatic mipmap | |
| generation apply to "non-attached" textures. | |
| d) Create an enable or other piece of state | |
| to toggle between allowing automatic and allowing manual | |
| generation. | |
| We disregarded (d) because it's not clear why an application | |
| that had the freedom to set this new enable bit wouldn't | |
| simply just turn off the legacy automatic mimpap generation | |
| to start with. | |
| Of the remaining choices, (a) is the most "orthogonal". The | |
| intent of adding GenerateMipmap is to provide a cleaner and | |
| saner interface to mipmap generation that we would encourage | |
| developers to use over the automatic method. Given that, it | |
| seems like restricting the "manual" generation to certain | |
| cases doesn't serve that goal, so we wish to allow its use | |
| on any textures, attached or not. | |
| (53) When supporting ARB_draw_buffers, do we need the level of | |
| indirection between fragment color outputs and attached | |
| mages provided in that API? | |
| RESOLUTION: yes | |
| ARB_draw_buffers allows the user to set up an "indirection | |
| table" between the fragment color outputs ("result.color[n]" | |
| in ARB_fragment_program, and "gl_FragData[n]" in GLSL) and | |
| the attached draw buffers (FRONT, BACK, LEFT, RIGHT, etc). | |
| Since EXT_framebuffer_object is creating new non-visible | |
| framebuffer objects for which the legacy attachment points | |
| may not be appropriate, we could consider naming the | |
| attachment points by numerical index (COLOR0 ... COLORn) in | |
| which case we could consider dropping this level of | |
| indirection and allowing the fragment shader to output | |
| directly into the numerically specified COLOR0 attachment | |
| point with no indirection. | |
| However, this indirection is deemed to be useful becaues it | |
| allows the application to redirect the fragment color | |
| outputs without changing either the fragment shader itself | |
| or the current framebuffer attachments, both of which are | |
| believed to be heavier-weight state change operations than | |
| simply changing the indirection table via glDrawBuffers.. | |
| Therefore, we elect to retain this level of indirection. | |
| This leaves open the question of what to call the attachment | |
| points. See issue (54). | |
| (54) What should we name the logical buffer attachment points, | |
| bearing in mind the relationship to ARB_draw_buffers? | |
| RESOLUTION: resolved, option (E), which is a modified | |
| version of (C). Specifically, we use the names | |
| COLOR_ATTACHMENT0_EXT through COLOR_ATTACHMENTn_EXT, | |
| DEPTH_ATTACHMENT_EXT, and STENCIL_ATTACHMENT_EXT (and any | |
| future attachment points also get the ATTACHMENT suffix). | |
| The reason this is an issue is that prior to | |
| EXT_framebuffer_object, the names of the various color | |
| logical buffer "attachment points" were heavily influenced | |
| by their intended usage in a graphical window-system. | |
| Logical buffers for BACK and FRONT_LEFT make sense in the | |
| context of double buffering and stereo presentation, but | |
| their use in off-screen rendering situations is | |
| anachronistic at best and perhaps even confusing. | |
| There are several options: | |
| Option (A): stick with the "legacy" names | |
| This would have us use all of the legacy names which are | |
| used to identify a single buffer: FRONT_LEFT, | |
| FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, and AUX0..AUXn. | |
| This option would require no change to DrawBuffersARB(). | |
| Option (B): AUXn names | |
| If we wish to avoid using the legacy names, one option | |
| is to re-use another numerically named set of color | |
| buffers, the AUX buffers, and only allow framebuffer | |
| objects to support AUX0..AUXn attachment points. | |
| This has the advantage of being easy to specify, and | |
| numerically delimit, but is a little strange as | |
| framebuffer objects could conceivably support the same | |
| number of AUX buffers as the implementation supports | |
| multiple render targets. This would have the awkward | |
| consequence of allowing framebuffer objects to support | |
| more AUX buffers than the default framebuffer could | |
| support via the pixel format selection mechanism. | |
| This option would require no specific change to | |
| DrawBuffers but might require non-default framebuffers | |
| to support more AUX buffers than the default framebuffer | |
| controlled by the window-system pixel format. | |
| Option (C): COLORn names | |
| Another option is to rename the color buffer attachment | |
| points for application-created framebuffer objects to | |
| COLOR0..COLORn. This has the advantage of avoiding the | |
| legacy window-centric names, and avoiding the confusion | |
| with AUX buffers. When considered in conjunction with | |
| the decision in issue (53) to support a level of | |
| indirection when using ARB_draw_buffers, however, the | |
| user of the names COLOR0..COLORn may be confusing. For | |
| instance, if an ARB fragment program contains color | |
| output to "result.color[3]", it will not necessarily | |
| output to COLOR3. It will actually write to the buffer | |
| specified by DrawBuffersARB for DRAW_BUFFER3 which may | |
| or may not be COLOR3. | |
| This option would require an update to DrawBuffers to | |
| accept the new COLOR0..COLORn values as valid draw | |
| buffers and would require a change to DrawBuffers to | |
| disallow the "legacy" names. Or at the very least we | |
| would need some language to describe what happens if the | |
| DrawBuffers are using the legacy names when the | |
| currently bound framebuffer is not the default window | |
| system framebuffer. | |
| Option (D): DATAn names | |
| Yet another option is to call these attachment points | |
| DATA0..DATAn. This is the same as option (C) but uses | |
| the word DATA instead of COLOR. This has the advantage | |
| of avoiding the above problems with COLOR0..COLORN, but | |
| introduces a similar conflict with GLSL which uses the | |
| "gl_FragData[n]" name for its output. Additionally, | |
| since we only support multiple render targets for color | |
| logical buffers, it may be that using the word DATA is | |
| considered too abstract/general. | |
| Option (E): add ATTACHMENT to *ALL* names | |
| In order to avoid the confusion of option (C) and (D), | |
| we can choose to be more verbose. We can add the word | |
| _ATTACHMENT to distinguish these enums from the color | |
| outputs of a fragment program or fragment shader. For | |
| symmetry we also add _ATTACHMENT to the DEPTH and | |
| STENCIL (and any other to-be-added) attachment points. | |
| Similar to (C) and (D), this option requires an update | |
| to DrawBuffers to at least accept the new enum values. | |
| We could choose to make it illegal to specify the legacy | |
| values for non-default framebuffers as well. This is | |
| essentially covered by issue (55). | |
| Here is an pseudo-code example using option (E): | |
| // Assume presence of color renderbuffers | |
| // with names 1000, 2000, 3000, 4000 | |
| GLuint db[4] = | |
| { COLOR_ATTACHMENT4, COLOR_ATTACHMENT7, | |
| COLOR_ATTACHMENT1, COLOR_ATTACHMENT2 }; | |
| glDrawBuffers(4, db); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, COLOR_ATTACHMENT4, | |
| GL_RENDERBUFFER_EXT, 1000); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, COLOR_ATTACHMENT7, | |
| GL_RENDERBUFFER_EXT, 2000); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, COLOR_ATTACHMENT1, | |
| GL_RENDERBUFFER_EXT, 3000); | |
| glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, COLOR_ATTACHMENT2, | |
| GL_RENDERBUFFER_EXT, 4000); | |
| Then in ARB_fragment_program | |
| result.color[0] writes to COLOR_ATTACHMENT4 (i.e., renderbuffer 1000) | |
| result.color[1] writes to COLOR_ATTACHMENT7 (i.e., renderbuffer 2000) | |
| result.color[2] writes to COLOR_ATTACHMENT1 (i.e., renderbuffer 3000) | |
| result.color[3] writes to COLOR_ATTACHMENT2 (i.e., renderbuffer 4000) | |
| And in ARB_fragment_shader | |
| gl_FragData[0] writes to COLOR_ATTACHMENT4 (i.e., renderbuffer 1000) | |
| gl_FragData[1] writes to COLOR_ATTACHMENT7 (i.e., renderbuffer 2000) | |
| gl_FragData[2] writes to COLOR_ATTACHMENT1 (i.e., renderbuffer 3000) | |
| gl_FragData[3] writes to COLOR_ATTACHMENT2 (i.e., renderbuffer 4000) | |
| See also issue (57) for discussion on querying the number of | |
| available color buffers. | |
| (55) What should happen if the current DRAW_BUFFER(s) point to a | |
| non-existent logical buffer? Likewise for READ_BUFFER. | |
| RESOLUTION: resolved | |
| partial resolution #1: DrawBuffer(s)/ReadBuffer throws | |
| an error if the buffer does not "exist" for all | |
| framebuffers (default and non-default). | |
| Should it be an error to call drawBuffer on a | |
| non-default framebuffer if named buffer does not | |
| exist? | |
| Resolved: yes | |
| partial resolution #2: The test for having a valid draw | |
| and read buffer should be part of framebuffer | |
| completeness test. | |
| Should be part of completeness test and should all 5 | |
| indpenent reasons add 5 enums? | |
| Resolved: yes | |
| partial resolution #3: we should create an enum for | |
| each implementation independent reason for failing | |
| the framebuffer completeness test of section 4.4.4.1 | |
| Current names (could change...) | |
| FRAMEBUFFER_COMPLETE_EXT | |
| FRAMEBUFFER_INCOMPLETE_ATTACHMENTS_EXT | |
| FRAMEBUFFER_INCOMPLETE_IMAGES_EXT | |
| FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT | |
| FRAMEBUFFER_INCOMPLETE_FORMATS_EXT | |
| FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT | |
| FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT | |
| FRAMEBUFFER_UNSUPPORTED_EXT | |
| NOTE: as per resolution of issue (78) | |
| FRAMEBUFFER_INCOMPLETE_ATTACHMENTS_EXT | |
| became | |
| FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT | |
| and | |
| FRAMEBUFFER_INCOMPLETE_IMAGES_EXT | |
| was dropped. | |
| This issue is intertwined with issue (56), which discusses | |
| whether the DRAW_BUFFER and READ_BUFFER are context or | |
| framebuffer object state. | |
| First, some background: If DRAW_BUFFER state is part of the | |
| context state vector rather than the framebuffer object | |
| state vector (see issue 56), then there are three ways to | |
| cause DRAW_BUFFER to reference a color buffer attachment | |
| point that "does not exist" in the currently bound | |
| framebuffer. If DRAW_BUFFER is part of the framebuffer | |
| object state vector, then (A) still applies but (B) and (C) | |
| do not. | |
| A) The first case is by detaching, from the currently | |
| bound framebuffer object, the image that is attached to | |
| attachment point named by the value of DRAW_BUFFER. If | |
| an image is attached to COLOR_ATTACHMENTn_EXT in the | |
| current framebuffer object and DRAW_BUFFER is set to | |
| COLOR_ATTACHMENTn_EXT, and then the application | |
| detaches the image from COLOR_ATTACHMENTn_EXT, then | |
| DRAW_BUFFER will end up specifying a buffer that "does | |
| not exist" in the currently bound framebuffer object. | |
| There is no analogue to this case in OpenGL prior to | |
| EXT_framebuffer_object. Before this extension, the | |
| pixel format or fbconfig of a window or pbuffer is | |
| immutable once one of these drawables has been created. | |
| By design, framebuffer objects (which essentially | |
| represent a new type of drawable) have mutable "pixel | |
| formats". | |
| B) The second case is by binding between two user-created | |
| framebuffer objects, where the two framebuffer objects | |
| do not have images attached to the same set of color | |
| attachment points. If an image is attached to | |
| COLOR_ATTACHMENTn_EXT in the current framebuffer object | |
| and DRAW_BUFFER is set to COLOR_ATTACHMENTn_EXT, and | |
| then the user binds to a new framebuffer for which | |
| there is no image attached to COLOR_ATTACHMENTn_EXT, | |
| then DRAW_BUFFER will end up specifying a buffer that | |
| "does not exist" in the newly bound framebuffer object. | |
| This is morally equivalent to calling MakeCurrent to | |
| bind a context to a different drawable (window or | |
| pbuffer) which does not have bitplanes for the color | |
| buffer named by the context's value of DRAW_BUFFER. | |
| For example, MakeCurrent to a double-buffered window, | |
| set DRAW_BUFFER to BACK, then MakeCurrent to a | |
| single-buffered window. | |
| C) The third case is by binding between the default | |
| framebuffer and a user-created framebuffer object. The | |
| attachment points of a user-created framebuffer object | |
| are named COLOR_ATTACHMENTn_EXT, DEPTH_ATTACHMENT_EXT, | |
| STENCIL_ATTACHMENT_EXT, etc. These are also the legal | |
| values of DRAW_BUFFER when a user-created framebuffer | |
| object is bound. The default framebuffer, on the other | |
| hand, does not use the _ATTACHMENT names but instead | |
| uses names such as FRONT_LEFT, BACK_RIGHT, and AUXn as | |
| legal DRAW_BUFFER values. Because the two sets of | |
| names do not overlap, no value of DRAW_BUFFER is valid | |
| for both the default framebuffer and a user-created | |
| framebuffer object. | |
| This is somewhat equivalent to case (B), except that in | |
| case (C) there is a guarantee that DRAW_BUFFER will | |
| become invalid, whereas in case (B) it is only | |
| _possible_ that DRAW_BUFFER will become invalid. | |
| The very problem of invalid DRAW and READ buffers was | |
| already a feature of OpenGL (and the window-system APIs) | |
| before the introduction of the EXT_framebuffer_object | |
| extension. The GLX specification specifically addresses | |
| what happens when MakeCurrent is used to bind a context to a | |
| different drawable (window or pbuffer) which does not | |
| possess one of the color buffers referenced by the context's | |
| current values of DRAW_BUFFER and READ_BUFFER. GLX | |
| addresses this by saying that no GL error is generated, but | |
| invalid DRAW_BUFFER behaves as if DRAW_BUFFER were NONE, and | |
| reads produce undefined results when READ_BUFFER is invalid. | |
| Now, back to the question of how EXT_framebuffer_object | |
| should handle the situation when a framebuffer object is | |
| bound and DRAW_BUFFER or READ_BUFFER is not valid while | |
| bound to a user-created framebuffer object. | |
| Obviously one option is to resolve the issue the same way is | |
| handled by MakeCurrent in the GLX spec. Invalid DRAW_BUFFER | |
| acts as if DRAW_BUFFER were NONE, and invalid READ_BUFFER | |
| causes read operations to generate undefined results. | |
| A second option is to modify the framebuffer completeness | |
| test to fail if the current DRAW_BUFFER or READ_BUFFER | |
| reference an attachment point to which no image is attached. | |
| This solution would also result in no rendering being | |
| performed, but would also generate a GL error when rendering | |
| is attempted while in this state, as determined by issue | |
| (64). When rendering to a framebuffer object, invalid | |
| DRAW_BUFFER would cause generation of GL errors; but when | |
| rendering to a window, invalid DRAW_BUFFER would not cause | |
| generation of GL errors. | |
| Consider also that, because of the resolution of issue (66), | |
| depending on how issue (56) is decided, failing the | |
| framebuffer completeness test due to a "non-existent" | |
| DRAW_BUFFER or READ_BUFFER may not be a viable option, | |
| because the framebuffer completeness test is not allowed to | |
| examine context state. | |
| Additionally, there are two sub-issues that fall out of this | |
| issue: | |
| sub-issue 1: Error at DrawBuffer call time or not? | |
| sub-issue 2: DRAW_BUFFER in or out of completeness test? | |
| [sub-issue 1]: First, what should be the behavior of | |
| DrawBuffer(s) and ReadBuffer if the specified buffer does | |
| not exist at the time DrawBuffer(s) or ReadBuffer is called? | |
| For default framebuffer (window-system drawables), an error | |
| is currently thrown. We can not (or do not wish to) change | |
| this legacy behavior of window-system supplied drawables. | |
| Consequently, we must resolve several questions here: | |
| For instance: | |
| - Should we do the same thing (error at DrawBuffer time) | |
| for user framebuffer objects? | |
| - Is this decision influenced by the fact that | |
| user-created framebuffer objects can change their | |
| attachments one buffer at a time while window-system | |
| supplied drawables can not (i.e., must change all | |
| attachments atomically)? | |
| - Also, on other places in this API, such as assembling | |
| a framebuffer from framebuffer-attachable images, we | |
| have allowed the system to move through "invalid" | |
| states without generating an error as long as the | |
| system was back in a "valid" state by rendering time | |
| (or "validation" time). Should we adhere to that | |
| principle here, or is this case different somehow? | |
| - Do we wish to retain the legacy window-system | |
| DrawBuffer(s) behavior for application-created | |
| framebuffer objects for the sake of maintaining | |
| consistency? i.e., Does the benefit of treating | |
| default and non-default framebuffers consistently | |
| outweigh the earlier decision to delay validation of | |
| "invalid" states? | |
| - Both resolutions are examples of "state combination" | |
| errors where an error may or may not be generated | |
| depending on the order state-changing function calls | |
| are made. For instance, in the legacy behavior | |
| DrawBuffers does or does not throw an error on user | |
| framebuffer objects depending on when you call | |
| DrawBuffer relative to when you made your image | |
| attachments. On the other hand, if we decided to not | |
| throw an error at DrawBuffer time for user framebuffer | |
| objects, then DrawBuffer does or does not throw an | |
| error depending on whether one is bound to a default | |
| or non-default framebuffer. Is one of these "state | |
| combination" errors better or worse than the other? | |
| [sub-issue 2]: Should having a DRAW_BUFFER that names a | |
| non-existent buffer cause the framebuffer completeness test | |
| to fail? | |
| Since image attachments can be changed after | |
| DrawBuffer(s) is called, even if we throw an error at | |
| Drawbuffer(s) time, we still must decide how to handle | |
| having an invalid DRAW_BUFFER at render (or "validation") | |
| time. Our options include failing the completeness test, | |
| (thus disabling rendering and generating an error at render | |
| time) or just behaving as if DRAW_BUFFER is NONE (thus | |
| disabling rendering but generating no error at render time). | |
| If the answer is "fail completeness test", then since | |
| currently framebuffer completeness can only be affected by | |
| framebuffer state, then one of two things has to happen: | |
| Either the drawbuffer state must be framebuffer object | |
| state, or we have to revisit our decision that framebuffer | |
| completeness is solely a property of the framebuffer state | |
| and can not be affected by "per context" state. | |
| If the answer is "do not fail completeness test", then the | |
| practical consequence of this decision is that having an | |
| invalid DRAW_BUFFER behaves as if DRAW_BUFFER is NONE, and | |
| no error is generated at render time. Also, in this case, | |
| DRAW-BUFFER state can be either per-context or | |
| per-framebuffer object state without violating any | |
| previously decided issues. | |
| (56) Should the value of DRAW_BUFFER, the corresponding draw buffers | |
| indirection table for ARB_draw_buffers, and the value of | |
| READ_BUFFER, be part of the context state vector or part of the | |
| the framebuffer object state vector? | |
| RESOLUTION: resolved, per-framebuffer object | |
| This issue is intertwined with issue (55), which discusses | |
| what happens when the DRAW_BUFFER or READ_BUFFER references | |
| a color buffer that "does not exist" in the current | |
| framebuffer. | |
| Please first read the "First, some background" section of | |
| issue (55), which could be, but is not, replicated here. | |
| Note that depending on how issue (56) is decided, cases (B) | |
| and (C) from issue (55) might become moot. Specifically, if | |
| the DRAW_BUFFER and READ_BUFFER state are added to the | |
| framebuffer object state vector, then neither case (B) nor | |
| case (C) remains relevant. Only case (A) would continue to | |
| be an issue. | |
| The discussion over this issue centered around the following | |
| areas: | |
| i) There must be a unique per-context value of DRAW_BUFFER | |
| for the default window-system-provided framebuffer. | |
| In GL, before EXT_framebuffer_object, the DRAW_BUFFER | |
| was considered context state because: | |
| 1) When two contexts are rendering to the same drawable, | |
| each context can use a different value of | |
| DRAW_BUFFER. | |
| 2) When MakeCurrent alternately binds a single context | |
| to each of two different drawables, after MakeCurrent | |
| DRAW_BUFFER retains the value it had immediately | |
| before calling MakeCurrent. This is true even if the | |
| last time the context was bound to a given drawable, | |
| DRAW_BUFFER had a different value than it does when | |
| that drawable is next bound to the context. | |
| Therefore, a per-context value of DRAW_BUFFER must | |
| exist, and must be in effect when the | |
| FRAMEBUFFER_BINDING_EXT is zero. | |
| Two ways of satisfying this requirement that we have | |
| considered include: | |
| A) DRAW_BUFFER is part of the context state vector, but | |
| is not part of the framebuffer object state vector. | |
| B) Every framebuffer, including the per-context default | |
| window-system-provided framebuffer, has its own value | |
| for DRAW_BUFFER. | |
| ii) MakeCurrent vs. BindFramebuffer | |
| As described above, the context state vector must | |
| contain a value for DRAW_BUFFER that applies to the | |
| default window-system-provided framebuffer, which is | |
| used after a call to BindFramebuffer(0). When | |
| MakeCurrent is used to bind the context to a different | |
| drawable (window or pbuffer), the context's value of | |
| DRAW_BUFFER remains unchanged. In other words, the | |
| choice of drawable does not affect the value of | |
| DRAW_BUFFER. | |
| An application-created framebuffer object is another | |
| type of drawable. When the framebuffer binding is | |
| changed via BindFramebuffer, issue (56) speaks to the | |
| way in which DRAW_BUFFER is or is not updated. If | |
| DRAW_BUFFER is part of the context state vector, then | |
| DRAW_BUFFER remains unchanged after calling | |
| BindFramebuffer, just like it remains unchanged after | |
| calling MakeCurrent. On the other hand, if DRAW_BUFFER | |
| is part of the framebuffer object state vector, then | |
| after calling BindFramebuffer DRAW_BUFFER may change | |
| along with the rest of the per-framebuffer state (i.e., | |
| the image attachments). | |
| By defining DRAW_BUFFER as context state, the behavior | |
| of BindFramebuffer and MakeCurrent are similar, with | |
| respect to their effect on the value of DRAW_BUFFER. | |
| On the other hand, by defining DRAW_BUFFER as | |
| framebuffer object state, then BindFramebuffer and | |
| MakeCurrent differ in their impact on the value of | |
| DRAW_BUFFER. | |
| iii) Multiple contexts and shared framebuffer objects | |
| If DRAW_BUFFER is part of the framebuffer object state | |
| vector, then a single value of DRAW_BUFFER, like all of | |
| the framebuffer object state, will be shared by any | |
| context bound to a given framebuffer object. This can | |
| be considered either a feature or a restriction | |
| depending on whether or not it is desirable for multiple | |
| contexts to be able to share a single the value of | |
| DRAW_BUFFER. | |
| Note that WGL_ARB_pbuffer plus WGL_ARB_render_texture | |
| API has limitations due to the fact that the texture | |
| image selection state is stored in the pbuffer drawable. | |
| For example, that API does not support six different | |
| contexts (in six different threads) simultaneously | |
| rendering to the six faces of a cube map pbuffer. It | |
| offers no way to share the images without also sharing | |
| the pbuffer, and the pbuffer contains a single set of | |
| texture image selection state. | |
| EXT_framebuffer_object differs from ARB_render_texture, | |
| however, however, in that EXT_framebuffer_object allows | |
| the same images of a texture to be attached to multiple | |
| framebuffer objects. Consequently, the above cubemap | |
| example can be implemented in EXT_framebuffer_object in | |
| one or two ways, depending on the resolution of issue | |
| (56): | |
| 1) Create six framebuffer objects. Attach a different | |
| face of a cubemap texture to each of the six | |
| framebuffer objects. Each of the six contexts binds | |
| to a unique framebuffer object. Technically, this | |
| option is available whether DRAW_BUFFER is context or | |
| framebuffer state. However, if it is context state, | |
| then there is no reason to create six framebuffer | |
| objects since the value of the DRAW_BUFFER will | |
| already be unique per context. | |
| 2) On the other hand, if DRAW_BUFFER is defined as | |
| context state, then a second option is available. | |
| Using a single framebuffer object, attach each face | |
| of the cube map texture to a different attachment | |
| point in the framebuffer object. Each of the six | |
| contexts binds to the same framebuffer object, but | |
| each context uses a different value of DRAW_BUFFER. | |
| iv) Frequency of DrawBuffer calls: | |
| Whether DRAW_BUFFER is part of context or framebuffer | |
| state will have an effect on how often one must call | |
| DrawBuffer after modifying framebuffer state. | |
| If DRAW_BUFFER is part of the context state vector, then | |
| DRAW_BUFFER is guaranteed to become invalid after | |
| calling BindFramebuffer to switch between the default | |
| framebuffer and a user-created framebuffer object [i.e., | |
| this is case (C) in issue (55)]. DRAW_BUFFER may become | |
| invalid after switching between two user-created | |
| framebuffer objects if the framebuffer objects do not | |
| have images attached to the same set of color attachment | |
| points. When DRAW_BUFFER is invalid, it is necessary to | |
| call DrawBuffer to set DRAW_BUFFER to a valid value or | |
| else rendering is disabled. | |
| If, on the other hand, DRAW_BUFFER is part of the | |
| framebuffer object state vector, then it should never be | |
| necessary to call DrawBuffer after calling | |
| BindFramebuffer. DRAW_BUFFER would only become invalid | |
| if an image was detached from the framebuffer, or if | |
| MakeCurrent bound the default framebuffer to a drawable | |
| with a different set of color buffers. (The latter was | |
| possible prior to this extension.) | |
| Note that there are several state-modifying routines | |
| that may also need to get called after a framebuffer | |
| state change, like Viewport, Scissor, etc. We are not | |
| proposing that these other routines be part of | |
| framebuffer state. One could think of DrawBuffer as | |
| being similar to these other routines which you may also | |
| need to call when you bind between framebuffer objects. | |
| On the other hand, some have questioned whether an | |
| invalid DRAW_BUFFER is really in the same class of | |
| problems as an out-of-bounds viewport or scissor | |
| because: 1) an invalid viewport or scissor never | |
| generates a GL error, and 2) prior to the | |
| EXT_framebuffer_object extension an invalid DRAW_BUFFER | |
| would generate INVALID_ENUM inside DrawBuffer. | |
| v) Effect on framebuffer completeness test: | |
| By resolution of issue (66), if the draw buffer is | |
| context state, then the fact that the draw buffer names | |
| a non-existent buffer can not affect the result of the | |
| framebuffer completeness test. Note that this still | |
| could be considered a "do not render" case, but would | |
| separate from the framebuffer completeness test. | |
| If the draw buffer(s) and read buffer are part of the | |
| framebuffer object state then having a draw or read | |
| buffer name a non-existent buffer can (if we choose) be | |
| part of the framebuffer (in)completeness test. | |
| Note, by resolution of issue (64), failing the | |
| framebuffer completeness test causes a GL error to be | |
| generated when draw or read operations are attempted. | |
| Prior to EXT_framebuffer_object, it was already possible | |
| to have an invalid value of DRAW_BUFFER if a call to | |
| MakeCurrent bound the context to a drawable that did not | |
| contain a color buffer corresponding to the context's | |
| value of DRAW_BUFFER. However, no GL error would be | |
| generated if DRAW_BUFFER obtained an invalid value | |
| through this method. | |
| vi) Draw buffer(s) error behavior: | |
| Prior to the EXT_framebuffer_object extension, it was an | |
| error to call DrawBuffer or ReadBuffer with a value that | |
| did not correspond to one of the logical color buffers | |
| of the currently bound drawable (window or pbuffer). | |
| Although it was not possible to set DRAW_BUFFER to an | |
| invalid value by calling DrawBuffer, it was actually | |
| possible for DRAW_BUFFER to have an invalid value after | |
| a call to MakeCurrent, as describe in issue (55). | |
| It has not been decided yet whether | |
| EXT_framebuffer_object will relax the requirement that | |
| the argument to DrawBuffer references a color buffer | |
| that "exists" in the currently drawable. | |
| In working group discussions, there was a perception | |
| that such an error during DrawBuffer can be generated | |
| only if DRAW_BUFFER is part of the framebuffer object | |
| state vector. Then when the default framebuffer (window | |
| or pbuffer) is current, the legal values of the argument | |
| to DrawBuffer would be determined by the pixel format or | |
| fbconfig. When a user-created framebuffer object is | |
| current, the legal values of DrawBuffer would either be | |
| any of the COLOR_ATTACHMENTn_EXT names or only the names | |
| of attachment points to which an image is presently | |
| attached. | |
| However, given the precedent set by MakeCurrent and | |
| DRAW_BUFFER, it seems reasonable to retain the | |
| preexisting requirement that the argument to DrawBuffer | |
| names a buffer that "exists" in the current drawable. | |
| In other words, there already exists precedent that says | |
| it is OK for DrawBuffer to generate an error in all the | |
| cases described in the preceeding paragraph, even if | |
| DRAW_BUFFER is defined as part of the context state | |
| vector. | |
| (57) Should we have a query to define the maximum number of | |
| attachable color buffers (to support ARB_draw_buffers)? | |
| RESOLUTION: yes, MAX_COLOR_ATTACHMENTS. | |
| Currently an application can query the GL for the maximum | |
| number of supported AUX buffers. An application can also | |
| query for MAX_DRAW_BUFFERS_ARB in the ARB_draw_buffers | |
| extension. Given that we have named the color logical | |
| buffer attachment points, COLOR_ATTACHMENT0_EXT through | |
| COLOR_ATTACHMENTn_EXT, it seems natural that we should have | |
| a query to find the maximum value "n". | |
| One thought was that we might be able to use | |
| MAX_DRAW_BUFFERS_ARB to store this value, but that value | |
| really describes the maximum number of colors that can be | |
| simultaneously output which is not the same thing as the | |
| number of buffers which can be attached and then selected | |
| among using DrawBuffersARB(). | |
| This question is related to issue (54), which covers the | |
| names of the user-created framebuffer object color | |
| attachment points. Using the names COLOR_ATTACHMENT0_EXT | |
| through COLOR_ATTACHMENTn_EXT rather than the legacy color | |
| buffer attachment names (FRONT_LEFT et. al.) for | |
| user-created framebuffer objects has an advantage that the | |
| number of color buffer attachment points could be queried | |
| independent of the number of AUX buffers and existence of | |
| front/back & left/right color buffers as specified in the | |
| pixelformat. The number of available offscreen attachment | |
| points really should be independent of the properties of the | |
| current drawable's pixelformat, especially since MakeCurrent | |
| can bind a context to a drawable with a different | |
| pixelformat and thus different set of color buffers. | |
| One implication of this query is that the value of | |
| MAX_COLOR_ATTACHMENTS_EXT is possibly still dependent on the | |
| context/pixel format but independent of the currently bound | |
| framebuffer. In other words, MAX_COLOR_ATTACHMENTS_EXT can | |
| not change simply because the user called BindFramebuffer(). | |
| Or can it? See issue (62) | |
| (58) What should we do about rendering to textures with borders? | |
| (besides attempt to fervently wish them out of existence, I mean) | |
| RESOLUTION: resolved, borders are fully supported | |
| Should we allow rendering to textures with borders at | |
| all? | |
| Resolved: yes | |
| If we allow this, can you render to the border pixels? | |
| Resolved: yes | |
| The reason this is an issue is that (a) everyone hates | |
| supporting borders, and (b) it's not clear what it means to | |
| render to a texture with borders. | |
| To disallow rendering to a texture image with non-zero | |
| border size, we could add a test for non-zero border size to | |
| the definition framebuffer completeness. This might be | |
| preferrable to an error at FramebufferTexture, since the | |
| user could always redefine the texture to have borders after | |
| attachment, and so the framebuffer completeness test is | |
| necessary anyway. | |
| However, since borders do exist today and we are not | |
| planning to rip them out of OpenGL everywhere else, we | |
| decided to support them. It seemed odd that you could still | |
| specify borders via TexImage but not render into the same | |
| texture so we leave them supported. Note that it's quite | |
| possible that implementations which don't support borders | |
| may continue to either not support them or fall to software | |
| rasterization. | |
| If someday we decide to disallow borders in general, they | |
| will be disallowed from this extension as well. | |
| One additional note: section 3.8.2, page 137, of the OpenGL | |
| 1.5 specification, states that {Copy}TexSubImage uses | |
| negative offsets to refer to border texels. We choose not | |
| to do this because negative window-coordinates are | |
| undefined. (NOTE: Are negative window coordinates actually | |
| undefined? Or are they just not commonly used in practice?) | |
| (59) Should we support named bit depths for stencil renderbuffers? | |
| RESOLUTION: resolved, yes, choose 4 common formats. | |
| We intend to support using renderbuffers to store stencil | |
| data. This means we need to consider what kind of "internal | |
| format" request we provide for stencil formatted | |
| renderbuffers. | |
| We choose to allow a "named" format request for the internal | |
| format. This is essentially equivalent to the named | |
| internal format request of the TexImage calls. It is merely | |
| a request and the driver will attempt to satisfy it as best | |
| as possible but may approximate the requested format with | |
| another format. Additionally, this request is subject to | |
| the same invariance constraints as the texture internal | |
| format requests. | |
| For the initial extension we choose the following four sized | |
| internal formats, as well as the base internal format | |
| STENCIL_INDEX: | |
| STENCIL_INDEX1_EXT | |
| STENCIL_INDEX4_EXT | |
| STENCIL_INDEX8_EXT | |
| STENCIL_INDEX16_EXT | |
| (60) If depth buffer is disabled when a user-created framebuffer | |
| object is bound and an image is attached to GL_DEPTH, does the | |
| depth buffer factor into framebuffer validity determination or | |
| is the depth buffer ignored? Similar for other types of | |
| logical buffers. | |
| RESOLUTION: resolved, consider all attached images when | |
| determining framebuffer completeness, even if the images are | |
| "irrelevant" based on the state of the framebuffer. | |
| The main reason to consider not paying attention to certain | |
| images (i.e., ignoring the image attached to the depth | |
| buffer when depth test is disabled) would be developer | |
| convenience. The developer wouldn't need to explicitly | |
| detach a buffer, but could set the state to ignore it | |
| (disable depth test, or disable color mask, reset draw | |
| buffer, etc). | |
| However, this raises the possibility that by simply changing | |
| this other state (depth test, stencil test, color mask, etc) | |
| the query for framebuffer completeness could change values. | |
| This was deemed undesirable. We'd like to be able to | |
| minimize the amount of state changes that can cause the | |
| framebuffer completeness query to change. | |
| Another strange effect of ignoring "irrelevant" images when | |
| considering framebuffer completeness is that we could get an | |
| undesirable interaction between draw buffer and the pixel | |
| format for the framebuffer. A framebuffer is considered | |
| incomplete if the color buffers do not all have the same | |
| internal format. But, consider the following case: | |
| - an application attaches a floating point | |
| color-renderable image to COLOR_ATTACHMENT1, and | |
| - the application attaches a fixed point | |
| color-renderable image to COLOR_ATTACHMENT2 and | |
| - the application sets the DRAW_BUFFER to | |
| COLOR_ATTACHMENT1, then | |
| If we ignored the attached images not pointed to by | |
| DRAW_BUFFER(s} when evalutating framebuffer completeness, we | |
| could consider this framebuffer complete. This framebuffer | |
| would use floating point rendering. Now, if the application | |
| simply changes the DRAW_BUFFER to COLOR-ATTACHMENT2, then we | |
| would also say the framebuffer is complete but now the | |
| framebuffer would be using fixed point rendering. We didn't | |
| want to allow a change to DRAW_BUFFER to effectively change | |
| the pixel format. On the other hand if we always considered | |
| all attached images, then in this case described above, the | |
| framebuffer would always be incomplete while the formats of | |
| the color-renderable images were inconsistent. | |
| To avoid the above complications, we choose to have | |
| framebuffer completeness queries consider all attached | |
| buffers, regardless of whether they would be "used" | |
| according to the current state vector or not. | |
| (61) What are the "minimum requirements" to support this extension? | |
| RESOLUTION: resolved, language added to end of 4.4.4.2 | |
| For instance, is it a requirement that there must be at | |
| least one renderable color, depth, and stencil format that | |
| can all work together? is it a requirement that you must be | |
| able to render to *any* "color-renderable" texture format? | |
| Since this extension specifically pulling in functionality | |
| that used to be in the domain of the window sytem, we would | |
| like to use as a starting point for our requrirements, the | |
| language from the GLX 1.3 spec, page 15, which lists the | |
| minimum requirements langauge for a conformant GLX | |
| implementation. | |
| Questions to answer: | |
| - is the GLX spec a good starting point? | |
| - do we want the same requirements as the GLX spec? | |
| - do we want stronger requirements than the GLX spec? | |
| - do we want some kind of requirement that states that | |
| to support this extension, there must be at least one | |
| "gl conformant" framebuffer configuration that can be | |
| constructed on a given implementation? If so, how do | |
| we phrase this? | |
| Anyway, the GLX spec states: | |
| "Servers are required to export at least one GLXFBConfig | |
| that supports RGBA rendering to windows and passes | |
| OpenGL conformance (i.e., the GLX RENDER TYPE attribute | |
| must have the GLX RGBA BIT set, the GLX DRAWABLE TYPE | |
| attribute must have the GLX WINDOW BIT set and the GLX | |
| CONFIG CAVEAT attribute must not be set to GLX NON | |
| CONFORMANT CONFIG). This GLXFBConfig must have at least | |
| one color buffer, a stencil buffer of at least 1 bit, a | |
| depth buffer of at least 12 bits, and an accumulation | |
| buffer; auxiliary buffers are optional, and the alpha | |
| buffer may have 0 bits. The color buffer size for this | |
| GLXFBConfig must be as large as that of the deepest | |
| TrueColor, DirectColor, PseudoColor, or StaticColor | |
| visual supported on framebuffer level zero (the main | |
| image planes), and this confguration must be available | |
| on framebuffer level zero." | |
| So if we did a direct translation of these requirements into | |
| our spec, we'd end up with something approximately like the | |
| following: | |
| Although GL defines a wide variety of internal formats | |
| for textures and renderbuffers, some implementations may | |
| not support particular combinations of internal formats | |
| for the images attached to the framebuffer. For a | |
| framebuffer with these unsupported combinations of | |
| internal formats, calls to CheckFramebufferStatusEXT() | |
| will return FRAMEBUFFER_UNSUPPORTED_EXT. | |
| There must exist, however, at least one combinations of | |
| internal formats for the images attached to the | |
| framebuffer for which CheckFramebufferStatusEXT() will | |
| *not* return FRAMEBUFFER_UNSUPPORTED_EXT. | |
| Specifically, implementations are required to support at | |
| least one set of internal formats for the images | |
| attached to a framebuffer such that | |
| - the image attached to the color buffer supports | |
| RGBA rendering, and | |
| - the image attached to the color buffer has at | |
| least as many bits as the deepest visual supported | |
| by the window-system, although the alpha buffer | |
| can have 0 bits, and | |
| - the image attached to the depth buffer has at | |
| least 12 bits, and | |
| - the image attached to the stencil buffer has at | |
| least 1 bit, and | |
| - rendering to this framebuffer passes OpenGL | |
| conformance." | |
| However, it looks like no one is seriously using the | |
| NON_CONFORMANT_CONFIG bit under GLX or AGL, and on WGL, | |
| there is no such bit, so we'd like to "assume" conformance | |
| and drop the last clause. Additionally, we'd like to just | |
| piggy back on the existing requirements without duplicating | |
| them here so we will simplify this language to leave out the | |
| last paragraph and list of clauses altogether. | |
| We do wish to retain the notion that there must be some | |
| configuration for which FRAMEBUFFER_UNSUPPORTED_EXT is not | |
| returned. | |
| (62) Exactly which, if any, queriable state can change after a call | |
| to BindFramebuffer and/or a change in framebuffer attachments? | |
| RESOLUTION: resolved, at the Sept. 2004 ARB meeting we | |
| resolved in principle that there is a small subset of | |
| "framebuffer-related" state that can change. We just need | |
| to define exactly the subset. The current subset as listed | |
| in section 4.4.5 is below: | |
| AUX_BUFFERS | |
| MAX_DRAW_BUFFERS | |
| MAX_COLOR_ATTACHMENTS | |
| RGBA_MODE | |
| INDEX_MODE | |
| DOUBLEBUFFER | |
| STEREO | |
| SAMPLE_BUFFERS | |
| SAMPLES | |
| {RED|GREEN|BLUE|ALPHA}_BITS | |
| DEPTH_BITS | |
| STENCIL_BITS | |
| ACCUM_{RED|GREEN|BLUE|ALPHA}_BITS | |
| The reason this is an issue is that traditionally there are | |
| some GL context state queries that are dependent on pixel | |
| format and window-system state. For instance, doing a | |
| GetIntegerv of DEPTH_BITS returns the bit depth of the | |
| window-system allocated depth buffer which is a function of | |
| the pixel format. If DEPTH_BITS is zero, this means that no | |
| depth buffer was present in the pixel format. Other context | |
| state queries like MAX_DRAW_BUFFERS, MAX_ACCUM_BUFFERS, | |
| SAMPLES, etc are all possibly functions of the current pixel | |
| format, and have traditionally been constant over the | |
| lifetime of a given context. | |
| However, this extension specifically subsumes some of the | |
| operations and state of the window-system pixel format | |
| mechanism. So an obvious question is: what should these | |
| queries return for things like DEPTH_BITS and | |
| MAX_DRAW_BUFFERS when using a non-default framebuffer | |
| object? | |
| If we allow these queries to return a value that is a | |
| function of the current framebuffer object, then a | |
| consequence is that the values returned by these queries can | |
| change after a call to BindFramebuffer and/or a change in | |
| the attachments of the currently bound framebuffer object. | |
| This may be desirable: for instance, a user may rightly | |
| expect that querying RED_BITS returns the red bits of the | |
| currently attached color buffer(s). But is the user also | |
| expecting that MAX_DRAW_BUFFERS might change? What about | |
| SAMPLES or SAMPLE_BUFFERS? What about | |
| MAX_COLOR_ATTACHMENTS? | |
| Consider that in developing ARB_draw_buffers it was stated | |
| that some implementations might want to set MAX_DRAW_BUFFERS | |
| to 1 for pixel formats that also supported multisampling. | |
| This would allow implementations to control which | |
| capabilities they exported. What facilities do we have for | |
| this in this extension - can MAX_DRAW_BUFFERS change if we | |
| supported multisampling on a non-default framebuffer object? | |
| Fundamentally, all of the state in table 6.28-6.31 of the | |
| OpenGL 1.5 spec (the MAX_* queries) can in theory change as | |
| the result of the pixel format changing. Since this | |
| extension does an effective pixel format change, what if any | |
| of this state can/should be allowed to change when | |
| framebuffer attachments are changed? | |
| (63) Should we change ValidateFramebuffer into an explicit | |
| enum-based query for framebuffer completeness? | |
| RESOLUTION: resolved, separate API function rather than a | |
| Get query, to emphasize the "on-demand" state examination. | |
| We did choose a different name for ValidateFramebuffer(). | |
| In issue (67) we decided to rename this function | |
| CheckFramebufferStatus(). | |
| For reference the reason this is an issue is that, as | |
| originally described, ValidateFramebuffer (now called | |
| CheckFramebufferStatus) served three purposes: | |
| First, it forced an "on-demand" examination of the current | |
| framebuffer state (including framebuffer attachment state) | |
| and the state of the attached images. On some | |
| implementations this examination might be expensive, and | |
| therefore there was a desire to control exactly when the | |
| operation would occur. | |
| Second, because of the implementation dependent reasons that | |
| a framebuffer might be considered not complete, | |
| ValidateFramebuffer served as a query for an application to | |
| determine at run-time if a seemingly compatible combination | |
| of attached images is actually incompatible on the current | |
| GL implementation. | |
| Third, ValidateFramebuffer was more than just a query. It | |
| was a function that would set a piece of framebuffer state | |
| that "enabled" rendering if the framebuffer was determined | |
| to be complete. After certain changes to framebuffer state, | |
| or in the initial default state, unless ValidateFramebuffer | |
| was called prior to rendering, and unless framebuffer | |
| validation "passed", rendering would be disabled. | |
| However, now that it is no longer required to call | |
| ValidateFramebuffer prior to rendering, ValidateFramebuffer | |
| doesn't really set any state. The third reason is no longer | |
| pertinent. | |
| This leaves us with the first and second reasons. The first | |
| reason in particular seems to be driven by convenience. It | |
| is convenient to be able to control when this operation | |
| happens, but it is arguably also convenient to be able to | |
| force the examination/validation of a wide variety of other | |
| pieces of GL state, yet we don't have specific on-demand | |
| "ValidateTexture" or "ValidateBlendState" routines. In | |
| addition, on some implementations framebuffer validation may | |
| be less expensive than originally thought. | |
| So if we ignore the first reason for a moment, we are left | |
| the second reason for ValidateFramebuffer - a query of the | |
| framebuffer completeness. We do wish to retain this query | |
| somehow, so we could choose to leave it in its current form, | |
| or we could choose to make it look like other more | |
| traditional queries, i.e., some kind of GetInteger, | |
| GetFramebuffer, or GetFramebufferParameter call. | |
| If we feel like the first reason is still valid, we could | |
| also choose to retain a ValidateFramebuffer call to get the | |
| "on-demand" state examination and still choose to make | |
| separate query for the framebuffer completeness. | |
| Either way, if we decide to make an enum-based query we need | |
| to choose the form. We could choose to use GetInteger and | |
| query for COMPLETENESS. (If we do this, we'd need a | |
| "per-target" variant of the enum, i.e., | |
| FRAMEBUFFER_COMPLETE, and if a read framebuffer target is | |
| added later, READ_FRAMEBUFFER_COMPLETE would need to be | |
| added as well.) This would be similar to how texture | |
| bindings are queried on a per target basis as in | |
| GetIntegerv(TEXTURE_BINDING_2D, ¶m). Another option is | |
| to add a target-aware query routine, i.e., | |
| GetFramebufferiv(FRAMEBUFFER, COMPLETE, ¶m); this is | |
| similar to what the ARB vertex/fragment program API's did to | |
| query per-target state like PROGRAM_NATIVE_INSTRUCTIONS_ARB. | |
| (64) Should it be a GL error to attempt to render with an incomplete | |
| framebuffer? | |
| RESOLUTION: resolved, "YES" | |
| In looking at other GL resources that can be considered | |
| "incomplete" for rendering, there were two precedents to | |
| draw on here: (a) textures and (b) programs/shaders. | |
| a) For textures, the GL behaves as if the incomplete | |
| resource is simply not available. That is, if an | |
| application attempts to render with an incomplete texture, | |
| then the GL behaves as if texturing is simply disabled. No | |
| error is thrown. | |
| b) For ARB_vertex_program and ARB_fragment_program, and GLSL | |
| shaders, if a program or shader is invalid, then the GL | |
| throws an error at "Begin" time. | |
| Originally, we choose style (a): treat an incomplete | |
| framebuffer similar to a "pixel ownership test failure". | |
| This means that no fragments are generated, reads of the | |
| framebuffer generate undefined pixels, and no error is | |
| thrown. | |
| [NOTE: Technically, according to the GL spec, the fate of | |
| rendered fragments that fail the pixel ownership test is | |
| left up to the window-system and is therefore implementation | |
| dependent. A better way to handle this is to mimic | |
| make_current_read's language "as if DRAW_BUFFER is NONE"] | |
| However, since the a query of framebuffer completeness can | |
| only answer the question "is the framebuffer complete right | |
| now?", but doesn't indicate whether the application may have | |
| attempted to render with an incomplete framebuffer earlier, | |
| we decided to throw an error in this case as an aid to the | |
| developer. Throwing an error has an advantage in that the | |
| error state is retained, like all GL errors until the user | |
| calls GetError(). | |
| Another option that was considered was to extend the | |
| framebuffer completeness query to indicate that the | |
| framebuffer is complete now, but was incomplete during | |
| earlier rendering. The downside of this option was that | |
| then there would then be two return values for the query | |
| that would mean "framebuffer complete right now". So in the | |
| end, we simply decided to leverage the existing GetError | |
| semantics to capture this "sticky" error behavior. | |
| One additional concern was that gl errors are traditionally | |
| only used to indicate programming errors on the part of the | |
| application, but the framebuffer completeness test may have | |
| failed simply because of implementation dependencies through | |
| no fault of the application. We decided to adopt the notion | |
| is that it is an error to attempt to render with an | |
| incomplete framebuffer, on all implementations, and so it | |
| actually *is* a programming error if an application does not | |
| attempt to deal with an incomplete framebuffer prior to | |
| rendering. | |
| (65) If it is an error to render to or read from an incomplete | |
| framebuffer, should we use INVALID_OPERATION or create a new | |
| error? | |
| RESOLUTION: resolved, INVALID_FRAMEBUFFER_OPERATION_EXT | |
| We resolved to create a new error at the September ARB | |
| meeting and then resolved the name of the error within | |
| the work group. | |
| We agreed that if we throw an error here, we'd like a | |
| new error enum, particularly because the error may have | |
| been triggered by a framebuffer which is incomplete for | |
| implementation dependent reasons. | |
| Some options for the new error name which were discussed: | |
| OPERATION_ON_INCOMPLETE_FRAMEBUFFER | |
| INCOMPLETE_FRAMEBUFFER | |
| IMPLEMENTATION_DEPENDENT_FAILURE | |
| INVALID_FRAMEBUFFER | |
| INVALID_FRAMEBUFFER_OPERATION | |
| (66) There are several issues related to how we treat DrawBuffer(s) | |
| and other context state with respect to framebuffer | |
| completeness. We'd like a self-consistent model here and this | |
| may affect the resolution of issue (8), (44), (55), and (56). | |
| RESOLUTION: resolved, (d) - no context state in framebuffer | |
| completeness test, but context state can affect whether | |
| rendering takes place, does not take place, or is undefined. | |
| Note option (d) required us to revisit issue (44). | |
| The first question we had to answer was: | |
| Is it desireable that "framebuffer completeness" be | |
| purely a property of the set of framebuffer state (which | |
| includes the state of the images attached to the | |
| framebuffer)? Or can a framebuffer's completeness | |
| depend on "non-framebuffer" context state as well? | |
| For instance, there are currently two pieces of context | |
| state that can affect framebuffer completeness: texture | |
| binding state and draw buffer state. | |
| First, in issue (44), we decided that attaching an image of | |
| a currently bound and enabled texture to a framebuffer can | |
| cause a framebuffer to be incomplete. The texture binding | |
| is context state and there are pieces of the texture object | |
| state (base level, max level) that can also affect the | |
| determination of framebuffer completeness. (Additionally if | |
| we add render-to-vertex-array functionality later, we might | |
| expect to have a framebuffer completeness requirement that | |
| examines the state of the currently bound vertex array.) | |
| One way to avoid this context dependency is to revisit issue | |
| (44) and say that this "texture-from-destination" case | |
| simply generates undefined rendering but does not affect | |
| framebuffer completeness. This would replace the "expressly | |
| disabled" rendering and framebuffer incompleteness with | |
| "undefined rendering", but would also let implementations | |
| avoid checking context state during the validation of the | |
| framebuffer state. | |
| The second piece of context state that might cause | |
| framebuffer validation failures is the draw buffer(s) and/or | |
| read buffer state. It has been suggested in issue (55) that | |
| if the draw buffers specify attachment points with no | |
| attached images, then the framebuffer might be considered | |
| incomplete. If we choose to do this, then we would have | |
| context state influencing framebuffer completeness state. | |
| However, if we resolve issue (56) to say that the draw | |
| buffer state is part of the framebuffer object state, then | |
| the draw buffer is no longer context state and this | |
| particular dependency of framebuffer completeness on context | |
| state goes away. | |
| The above discussion leaves us with several self-consistent, | |
| but different sets of decisions: | |
| (a) Remove context dependencies from framebuffer | |
| completeness. | |
| To do this we would: | |
| - Move draw buffer state from context into | |
| framebuffer: issue (56) | |
| - Make "texture-from-destination" undefined instead | |
| of a reason for framebuffer incompleteness: issue | |
| (44) | |
| - Presumably, if we created a render-to-vertex-array | |
| extension layered on this one, we would likely | |
| also make rendering into the currently bound | |
| vertex array undefined as well. | |
| With option (a), we can say that having draw buffer | |
| set to an non-existent buffer is a reason for | |
| framebuffer incompleteness and there are no context | |
| dependencies. This would resolve issue (55). | |
| (b) Allow context dependencies in framebuffer | |
| completeness. | |
| Essentially this means that the result of a query of | |
| framebuffer completeness is dependent on the context | |
| making the query - or put another way, the | |
| framebuffer completeness state is context state not | |
| framebuffer state. | |
| If we choose this option (b), then we are esentially | |
| free to resolve issues (44), (55), and (56) | |
| however we want. In other words: | |
| - draw buffer can be either context or | |
| framebuffer state: issue (56) | |
| - "texture-from-destination" can be either | |
| undefined or a reason for framebuffer | |
| incompleteness | |
| - draw buffer specifying a non-existent buffer | |
| can be a reason for framebuffer incompleteness | |
| or could result in undefined behavior: issue | |
| (55) | |
| (c) Remove the framebuffer object and make the | |
| framebuffer state part of the context. | |
| This option redefines the issue by not making a | |
| distinction between framebuffer "object" state and | |
| "context" state, therefore framebuffer completeness | |
| depends only on "context" state because all of the | |
| "framebuffer" state is now "context" state. | |
| This would mean that there is now a subset of state | |
| in the context that can be considered the | |
| "framebuffer state" of the context. This is the set | |
| of state that would presumably be pushed/popped | |
| under a theoretical FRAMEBUFFER_BIT for | |
| PushAttrib(). | |
| Regardless of whether there is a framebuffer object, | |
| framebuffer completeness may or may not still depend | |
| on pieces of other "context" state that are not part | |
| of subset of context state related to the | |
| "non-default" framebuffer (for instance, texture | |
| bindings and/or draw buffer state). | |
| If we choose this option (c), | |
| - we remove the framebuffer object: issue (8) | |
| This means: | |
| - removing gen/is/bind/delete framebuffer | |
| object | |
| - moving the attachment state into the | |
| context | |
| - creating new context bind points for | |
| framebuffer attachments and creating new | |
| BindFramebufferAttachableImage calls or | |
| using the FramebufferTexture() calls to do | |
| context binds of framebuffer-attachable | |
| images | |
| - we decide whether there is a single set of | |
| draw/read buffer context state or a 2nd set of | |
| draw/read buffer context state to be used for | |
| "non-default" framebuffer objects. Either way | |
| it's "context" state but we need to know if we | |
| have one set of state or two. This is a | |
| variation on issue (56). | |
| - as in option (b), "texture-from-destination" | |
| can be either undefined or a reason for | |
| framebuffer incompleteness | |
| - as in option (b), a draw buffer specifying a | |
| non-existent buffer can either be a reason for | |
| framebuffer incompleteness or could result in | |
| undefined behavior: issue (55) | |
| - all the framebuffer attachments become context | |
| state | |
| - we add a framebuffer enable/disable bit to use | |
| to distinguish between the "default" and | |
| "non-default" framebuffer | |
| (d) Create a new category of reasons that you can't use | |
| a framebuffer for rendering in a specific context, | |
| but that are not part of the test for "framebuffer | |
| completeness" | |
| Essentially, this is a kind of hybrid of options (a) | |
| and (b). There are no context dependent reasons for | |
| framebuffer incompleteness, but at the same time | |
| there are some additional context-dependent | |
| constraints on using a framebuffer. In other words, | |
| a framebuffer can be complete but still not suitable | |
| for rendering by a given context. | |
| This creates two categories of tests that can be | |
| used to disable rendering - the set of | |
| context-independent test that are used to determine | |
| framebuffer completeness, and the set of tests that | |
| are context-dependent and not used to determine | |
| framebuffer completeness. | |
| An open question is: should we add a separate query | |
| for this second set of context-dependent tests | |
| and/or a "meta-query" that would cover both sets. | |
| This "meta-query" would return "true" if and only if | |
| the framebuffer is complete *and* it can be used in | |
| this context. | |
| Note that while the "is framebuffer complete" query | |
| is required by the fact that a framebuffer can be | |
| incomplete because of implementation dependent | |
| reasons, the second query of the context-dependent | |
| test results and the "meta query" are primarily | |
| debugging aids, though perhaps convenient ones. | |
| The framebuffer completeness query is analogous to | |
| asking if a texture is "mipmap complete". The | |
| question, "can I render into my framebuffer", is | |
| analgous to asking the question, "is texturing | |
| enabled." A bound texture may be "complete", but | |
| texturing can still be disabled due to an | |
| unfortunate combination of non-texture-object | |
| context state. Option (d) is basically saying the | |
| same thing of framebuffer objects. | |
| To implement option (d), we'd do the following: | |
| - If draw buffer is defined as "context state" it | |
| can not affect framebuffer completeness, but if | |
| draw buffer is defined as framebuffer state it | |
| might affect framebuffer completeness. See issues | |
| (55) and (56). | |
| - Make "texture-from-destination" undefined instead | |
| of a reason for framebuffer incompleteness: issue | |
| (44). Technically, this could still be an error | |
| unrelated to framebuffer completeness, but we are | |
| trying to avoid creating a precedent for arbitrary | |
| "errors at begin time". When this case was | |
| included in the "framebuffer completeness" | |
| validation, the additional cost of generating the | |
| error was free. But if this | |
| "texture-from-destination" case is not part of | |
| framebuffer completeness, then it is an additional | |
| cost at begin time to detect this in order to flag | |
| an error (and/or disable rendering). To avoid | |
| this cost, we would make this undefined. | |
| - Presumably, if we later create a | |
| render-to-vertex-array extension layered on this | |
| one, we would likely also choose the same | |
| resolution for rendering into the currently bound | |
| vertex array as we choose for the currently bound | |
| texture. | |
| (67) In issue (63) we decided we want to use a dedicated API | |
| function to test framebuffer completeness. We might want to | |
| change the name of "ValidateFramebuffer" however. If so, what | |
| name should we use? | |
| RESOLUTION: resolved, CheckFramebufferStatus() | |
| One reason we decided to retain an explicit API function | |
| instead of just using a GetInteger style query is to | |
| emphasis the "on-demand" state examination that takes place | |
| when making this query. | |
| However, some were uncomfortable with the name | |
| ValidateFramebuffer for this purpose. Some felt that it | |
| implied a requirement to call the function, and others felt | |
| it was too similar in name to the GLSL function | |
| ValidateProgram which served a related but slightly | |
| different purpose. So we chose a new name. | |
| Some options we considered: | |
| ValidateFramebufferCompleteness() | |
| CheckFramebufferCompleteness() | |
| CheckFramebufferStatus() | |
| IsFramebufferComplete() | |
| (68) Exactly which levels should by generated by GenerateMipmapEXT? | |
| RESOLUTION: resolved, from TEXTURE_BASE_LEVEL+1 through q | |
| Automatic mipmap generation via GENERATE_MIPMAP generates | |
| from TEXTURE_BASE_LEVEL+1 through p, which is the 1x1 level. | |
| However, applications frequently don't want to waste | |
| computation generating past q, which is the min of | |
| TEXTURE_MAX_LEVEL and p. The only recourse is to accept the | |
| performance hit or to not use GENERATE_MIPMAP. | |
| Arguably GENERATE_MIPMAP should have been specified to | |
| generate only through q. We have the opportunity to "fix" | |
| this problem by "correctly" specifying the new function | |
| GenerateMipmapEXT to generate only from TEXTURE_BASE_LEVEL+1 | |
| through q. | |
| As the specification of GenerateMipmapEXT is currently | |
| written, GenerateMipmapEXT only generates levels | |
| TEXTURE_BASE_LEVEL+1 through q. | |
| (69) What should we call the framebuffer objects to distinguish | |
| them from the default framebuffer? | |
| RESOLUTION: resolved, "application-created" | |
| Currently we call these "application-created" framebuffers | |
| Some places in the spec have also referred these as | |
| "GL-allocated" framebuffers. Whichever term we use, we | |
| should use it consistently. | |
| Some terms we considered: | |
| "application-created" framebuffers | |
| "application-allocated" framebuffers | |
| "non-default" framebuffers | |
| "GL-created" framebuffers | |
| "GL-allocated" framebuffers | |
| "dynamically-created" framebuffers | |
| etc. | |
| The GL spec already talks about "creating" textures, not | |
| "allocating" them, so "*-created" seems like a better | |
| choice. | |
| It's a bit of a toss-up between "GL-created" and | |
| "application-created". Technically, the "GL" really creates | |
| and manages these objects but it only does so at the request | |
| of the application. Going with "application-created" for | |
| now. | |
| (70) With which, if any, attribute bit does the framebuffer binding | |
| push and pop? The same question applies to the current | |
| renderbuffer? | |
| RESOLUTION: resolved, don't push/pop framebuffer binding | |
| bit for now. If desired, we may add this in the ARB/core | |
| update of this spec. | |
| There are a few precedents to choose from. | |
| The ARB_vertex/fragment_program extensions chose to *not* | |
| push/pop the current program object binding. It's not clear if | |
| this was intentional or which existing attribute bit was | |
| appropriate to use or if there was a desire to not create a new | |
| attribute bit. | |
| ARB_vertex_buffer_object buffer objects and GL core texture | |
| objects do push/pop the bindings with the existing VERTEX_ARRAY | |
| and TEXTURE bits respectively. In addition, the texture enables | |
| are push/pop'ed with the TEXTURE bit. | |
| If we do wish to push/pop the FRAMEBUFFER_BINDING_EXT state we | |
| probably need a new FRAMEBUFFER bit. | |
| We could also consider adding a RENDERBUFFER_BIT to cover the | |
| current renderbuffer binding or allow this renderbuffer binding | |
| to push/pop with the FRAMEBUFFER bit. However, it's less clear | |
| that push/pop'ing the renderbuffer binding is useful since the | |
| renderbuffer binding is not used for rendering. The | |
| renderbuffer binding is only used to set the current | |
| renderbuffer for renderbuffer storage allocation and queries. | |
| Also, there are a related set of questions about how much state | |
| should push/pop with a new FRAMEBUFFER bit. Should we push/pop | |
| all of the framebuffer object state in addition to the current | |
| binding? Similar to the way vertex array's can be attached to | |
| VBO's, use of VBO, framebuffers can be attached to other GL | |
| objects. The TEXTURE_BIT covers both per object (min/mag | |
| filter) and per context (texture environment and enable) state. | |
| It's not clear if this is useful or desirable to have per-object | |
| state push/pop. With the addition of object semantics, it seems | |
| like the need for push/pop of object state is reduced. | |
| In the end, since we'd need to create a new bit anyway, we | |
| decided to defer adding push/pop semantics until we understand | |
| the implementation ramifications better. If we decide to create | |
| the bit later on in the ARB or Core revision of this extension, | |
| we can add it in a backward-compatible fashion. | |
| (71) Should we spell out precisely which rendering and reading | |
| routines can cause us to generate an error at the time the | |
| rendering or reading functions are called? | |
| RESOLUTION: resolved, keep the same language as ARB | |
| vertex/fragment program and GLSL for now, with the | |
| addtitions relevant for reading the framebuffer, but | |
| recommend the ARB look at this when doing the next core GL | |
| spec revision. | |
| Currently GL has a few cases that can cause errors at render | |
| time. Specifically, attempting to render with a mapped vertex | |
| buffer object, an invalid low-level vertex or fragment program, | |
| or an invalid GLSL program object all generate errors at "Begin" | |
| time. | |
| This extension adds a new error at "begin" time. Attempting to | |
| render with an "incomplete" framebuffer generates | |
| INVALID_FRAMEBUFFER_OPERATION_EXT. In addition, this extension | |
| adds the same error at "read" time if the application tries to | |
| read from an "incomplete" framebuffer. | |
| The ARB vertex program, ARB fragment program, and GLSL extension | |
| specs state that an app which tries to use an "invalid" object | |
| can generate errors when Begin, RasterPos, or any command that | |
| performs an explicit Begin is called. | |
| This extension has adopted similar language. So the question | |
| asked by this issue is: do we need ot be more explicit. | |
| There are some ambiguities. For instance, it is an error to | |
| write pixels using an "implicit Begin" operation like DrawArrays | |
| if the current vertex program is invalid, but it is not an error | |
| to do an Accum operation which also writes pixels to the | |
| framebuffer. | |
| This issue applies to all of these extensions. | |
| Options include: | |
| - listing all routines which can render or read from the | |
| framebuffer and stating that they can cause an error if | |
| the framebuffer is incomplete, solving the problem for | |
| this extension only. | |
| - adding to the GL core a table of "routines that read | |
| pixels" and "routines that write pixels" and referencing | |
| those tables in the language for each of these extensions. | |
| Because each extension is doing something a little different, | |
| it's not even clear if the second option is a viable option. | |
| It's possible each extension would need its own list of routines | |
| which can generate errors anyway. | |
| Basically, this is a larger problem than this | |
| EXT_framebuffer_object extension. For now, we choose to use the | |
| same (vague-ish) language adopted by the | |
| ARB_vertex/fragment_program and GLSL extnesions. | |
| We do recommend, however, that the ARB address this issue in the | |
| next GL core revision. | |
| (72) Should the framebuffer completeness test include a clause that | |
| says "at least one color attachment" has been made? Or "at | |
| least one attachment of any type"? Or is the framebuffer | |
| still complete when there are no attachments at all? | |
| RESOLUTION: resolved, a framebuffer must have at least one | |
| color-renderable, depth-renderable, or stencil-renderable | |
| image attached to be complete. | |
| While a framebuffer with only depth, or only color | |
| attachments seems plausible, we couldn't come up with a | |
| sensible use for a framebuffer with no attachments at all, | |
| so the assumption is that this is an unintended error on the | |
| part of the application. Therefore, we choose to make it | |
| part of the framebuffer completeness test. | |
| We could make this its own clause in the framebuffer | |
| completeness test. If we choose to do so, we should | |
| probably come up with a new FRAMEBUFFER_INCOMPLETE_* to | |
| conform to our previous practice of keeping one enum per | |
| clause. | |
| However, since this is really related to the attachment | |
| state, we could just piggy back this on the first clause and | |
| same all the attachment points must be "attachment complete" | |
| and there must be at least one color, depth, or stencil | |
| buffer attached. | |
| If we choose this latter option, we can continue to use the | |
| FRAMEBUFFER_INCOMPLETE_ATTACHMENT enum to cover this case. | |
| (73) This clause from framebuffer completeness (before it was | |
| reworded, see below): | |
| * The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT must | |
| not be NONE for any color attachment point named by | |
| READ_BUFFER. | |
| basically requires at least one color attachment is non-NULL. | |
| But this is not what we want. So what should we do? | |
| RESOLUTION: resolved, (4a) READ_BUFFER can be NONE | |
| The reason is: READ_BUFFER is not allowed to be NONE, which in | |
| turn means to be framebuffer complete, READ_BUFFER must be | |
| COLOR_ATTACHMENTn_EXT for some n which has an image attached. | |
| However, we don't wish to preclude a no-color framebuffer. | |
| What should we do? | |
| Options include: | |
| 4a) Allow READ_BUFFER of NONE, reads of color from the | |
| framebuffer when read buffer is none, generate error | |
| INVALID_OPERATION | |
| 4b) Generate an error when a read operation (ReadPixels, | |
| CopyPixels, etc) is attempted while the color | |
| attachment point referenced by the READ_BUFFER does | |
| not have an attached image. | |
| 4c) Reverse earlier decision to allow complete | |
| framebuffer not to have any color attachments. | |
| Instead, require at least one color attachment. | |
| READ_BUFFER must point to a valid color attachment | |
| or else the framebuffer object is incomplete. | |
| (4c) seems to require the user attach a color buffer just to be | |
| able to read the depth buffer of a depth-only framebuffer. | |
| (4b) seems to suffer from the same problem (unless we move the | |
| "valid read buffer" test out of the completeness test). | |
| Of these choices, (4a) seems to be the most palatable. We | |
| choose the allow the value of READ_BUFFER to be NONE, but reads | |
| of color buffers when READ_BUFFER is NONE will generate an | |
| error, in order to be consistent with the decision in issues | |
| (26) and (65). | |
| Note: that clause was eventually reworded to say: | |
| * If READ_BUFFER is not NONE, then the value of | |
| FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT must not be NONE for | |
| the color attachment point named by READ_BUFFER. | |
| (74) What should CheckFramebufferStatusEXT return if | |
| FRAMEBUFFER_BINDING_EXT is zero? | |
| Secondary question: what should CheckFramebufferStatusEXT | |
| return if there is an error? | |
| RESOLUTION: resolved, default fb returns COMPLETE always, | |
| and CheckFramebufferStatusEXT returns | |
| FRAMEBUFFER_STATUS_ERROR if there is an error (bad target) | |
| This goes to a larger question of whether all framebuffers | |
| including the default window-system-provided framebuffer | |
| have a "completeness" state, or if "completeness" is only a | |
| property which applies to application-created framebuffers. | |
| For the case where the current FRAMEBUFFER_BINDING_EXT is | |
| zero, options include: | |
| - CheckFramebufferStatusEXT returns an error when | |
| FRAMEBUFFER_BINDING_EXT is zero. | |
| - CheckFramebufferStatusEXT always returns | |
| FRAMEBUFFER_COMPLETE_EXT when FRAMEBUFFER_BINDING_EXT | |
| is zero. | |
| For the case CheckFramebufferStatusEXT generates an error, | |
| options include: | |
| - reworking CheckFramebufferStatus into a "get" style | |
| routine that returns a value (or not) in an input | |
| parameter like GetIntegerv | |
| - returning a known value like NONE or 0 | |
| - returning undefined results | |
| (75) How are state values for the stencil index write mask and | |
| stencil reference value affected by this extension? | |
| RESOLUTION: | |
| a) index write mask is stored as 32 bit value, default | |
| is all 1's, and | |
| b) reference value is not clamped on specification but | |
| rather is clamped on use and query, and | |
| c) we need to add the stencil reference value | |
| to the state table that lists the state values that | |
| might change after a framebuffer state change | |
| The reason this is an issue is that the current GL | |
| specification indicates that the stencil index write mask | |
| and the stencil reference value are masked/clamped according | |
| to the number of stencil bitplanes. However, in this | |
| extension the number of stencil bitplanes can now change | |
| dynamically as the image attached to the framebuffer is | |
| changed. | |
| For instance, if these values are clamped/masked according | |
| to the bitdepth of the currently attached stencil buffer, | |
| what should happen if the user later attaches a stencil | |
| buffer of a different bit depth? Must the stencil reference | |
| value or index write mask be respecified? | |
| For the index write mask: we decide to treat this value as | |
| "all 1's" as the current specification allows, but further | |
| define the number of 1's to be 32 (the minimum width of an | |
| integer in GL), and a likely maximum stencil bitdpeth for | |
| the forseeable future. This should retain backward | |
| compatbility and still handle the case where the bitdepth of | |
| the stencil buffer can change dynamically. | |
| For the stencil reference value, we decide to treat this | |
| state similar to way various clamped colors are treated in | |
| the ARB floating point pixel extensions. Specifically, the | |
| state values are clamped against the current logical buffer | |
| bitdepths as they are used for rendering and queried, but | |
| are not clamped on specification. This means that these | |
| state values do not need to be respecified just because the | |
| logical buffer bit depth changes, and retains backward | |
| compatibility to the behavior prior to this extension. | |
| We will update the appropriate sections of the specification | |
| to describe this behavior. | |
| (76) Currently framebuffer objects are shared, should we make them | |
| not shared across contexts? | |
| RESOLUTION: yes, framebuffers are shared like display lists | |
| and textures are shared. | |
| Initially it was suggested that some complicated | |
| multi-context semantics might be avoided if if the namespace | |
| for framebuffer objects were not shared across contexts. | |
| Specifically, some members of the group felt that by not | |
| sharing framebuffer objects, we could avoid the situation | |
| where: | |
| a) one context can change the draw buffer of a | |
| framebuffer object in use by another context. | |
| b) one context can change the attachments of a | |
| framebuffer object which may be in use by another | |
| context. | |
| However, after some discussion, we realized that even if we | |
| didn't share framebuffer objects, there were still | |
| interactions similar to those listed above because the | |
| underlying images could still be shared. Consequently, one | |
| context could still affect the completeness and attachments | |
| of the framebuffers in another context by modifying or | |
| deleting the framebuffer-attachable images shared by both | |
| contexts. | |
| So in the end, we decided to retain the share-ability of | |
| framebuffer objects rather than introduce an asymmetry with | |
| other GL objects like textures. | |
| ADDITIONAL COMMENTS: | |
| See the "Dependencies on ARB_framebuffer_object and OpenGL 3.0" | |
| section above for the interaction behaviour between EXT and | |
| non-EXT FBO interfaces. | |
| (77) If the application deletes an object and that object contains | |
| an image which is attached to a framebuffer object, exactly | |
| when and how is the image detached from the framebuffer? | |
| RESOLUTION: resolved, option (1): images are detached from | |
| the currently bound framebuffer on delete, but images remain | |
| attached to any non-bound framebuffers. | |
| This is issue is somewhat related to the multi-context | |
| object-sharing discussion currently going on in the ARB. | |
| This extension presupposes that framebuffer attachments | |
| represent a reference to the attached image (or more | |
| correctly - a reference to the object containing the | |
| attached image). Since having a reference to an object | |
| affects when the object (and/or its name) is deleted, object | |
| deletion semantics are tied into the notion when the state | |
| describing these references is modified. In other words, | |
| the semantics of when objects are deleted are affected by | |
| the details concerning when a change to the framebuffer | |
| attachment state takes place. | |
| Prior to the EXT_framebuffer_object and GLSL extensions, the | |
| only way in which an object not currently bound to this GL | |
| context could be modified, was when the object was modified | |
| by another GL context. | |
| Both the EXT_framebuffer_object and GLSL extensions allow an | |
| object (texture, renderbuffer, shader) to be attached to a | |
| "container" object (framebuffer, program). With the | |
| introduction of "attachment", an object could be bound to | |
| the context at more than one binding point. For example, a | |
| texture can be bound to TEXTURE_2D_BINDING, and it can also | |
| be indirectly bound through the FRAMEBUFFER_BINDING if it is | |
| attached to the framebuffer object bound to the | |
| FRAMEBUFFER_BINDING. | |
| Furthermore, a texture can be attached (by reference) to a | |
| framebuffer object that is not bound to any context, while | |
| at the same time the texture *is* bound to context's | |
| TEXTURE_2D_BINDING. Because the texture state is a part of | |
| the framebuffer object's state, it is now possible for | |
| modification of a texture through TEXTURE_2D_BINDING to | |
| cause modification of a framebuffer object, even though the | |
| framebuffer object is not bound to any context at the time | |
| it is modified. | |
| One conceptual model for dealing with this situation is to | |
| treat attachment similar to bind, but instead of binding to | |
| a context, you are "binding" to another object. For the | |
| purposes of managing object references, object lifetimes, | |
| state propogation semantics, etc., these attachments can be | |
| considered to be "just like" a bind operation. [A "bind" | |
| and an "attach" are not exactly equivalent, however; see | |
| issue (82) for a further discussion on Bind vs. Attach.] | |
| If we agree on the above conceptual model, then we may wish | |
| to look to the multi-context situation for guidance on how | |
| to treat state changes to non-currently-bound framebuffer | |
| objects. | |
| Unfortunately, the multi-context semantics are poorly | |
| defined by OpenGL. If we decide to use them as a guide, we | |
| should at least define what they are and this is why the | |
| larger ARB is looking at this issue now. | |
| For EXT_framebuffer_object, there are three choices for | |
| behavior. In each case, we defer to the larger ARB the | |
| details about when an object name is available for reuse. | |
| For the purposes of this discussion, we are looking only at | |
| state changes governing the attachments. The three choices | |
| are listed below: | |
| For the sake of concrete simplicity, this discussion | |
| speaks to the images of a texture object; but it applies | |
| equally to the image of a renderbuffer object. | |
| If you delete a texture object while one of the texture's | |
| images is attached to a framebuffer object (or multiple | |
| framebuffer objects), then: | |
| (1) The image is automatically detached from the currently | |
| bound framebuffer object only. | |
| If the image is also attached to any other framebuffer | |
| objects, then the image is NOT automatically detached | |
| from those. | |
| The application is responsible for manually detaching | |
| images from the other framebuffer objects, by | |
| rebinding each framebuffer in turn and performing an | |
| explicit detach operation. | |
| Until the application manually detaches the image from | |
| the other framebuffers, those framebuffers continue to | |
| use the image for rendering. The other framebuffer | |
| objects have a reference to the image until the image | |
| has been detached from them. In this way, attachment | |
| behaves as if the image was "bound to the framebuffer | |
| object". | |
| (2) The image is automatically detached from the currently | |
| bound framebuffer object. Also during DeleteTexture, | |
| the image is automatically detached from any other | |
| framebuffer object to which it is attached; however, | |
| the image is not guaranteed to be detached from the | |
| other framebuffer objects until the next time those | |
| framebuffer objects are bound via BindFramebufferEXT. | |
| Similar to option (1), in order to "really" delete the | |
| object, the application is responsible for rebinding | |
| all the framebuffer objects to which the deleted image | |
| was attached. However, unlike option (1), the | |
| application need not actually perform an explicit | |
| detach operation. The application can merely bind the | |
| framebuffer. | |
| Until the application actually rebinds the framebuffer | |
| the images are not actually detached and deleted. The | |
| other framebuffer objects continue to hold a reference | |
| (like a binding) to the image until the next time the | |
| framebuffer objects are bound. | |
| (3) The image is automatically detached from all | |
| framebuffers objects during DeleteTextures, including | |
| the currently bound framebuffer as well as any other | |
| framebuffers to which the image is attached. | |
| The application need not explicitly bind to, and | |
| detach the image from, any framebuffer that is not | |
| bound at the time DeleteTextures was called. | |
| Because the framebuffer object has a reference to the | |
| texture object, and the texture object's state is | |
| considered part of the framebuffer object's state, | |
| this resolution implies that DeleteTextures may | |
| modifiy the state of a framebuffer object that is not | |
| the currently bound object. | |
| With reference to the object-sharing discussion that is | |
| going on in the ARB right now, for (a)-style | |
| implementations, options (2) and (3) are indistinguishable. | |
| However, for (b)-style implementations, implementing (3) | |
| would require textures to store a list of all attached | |
| framebuffers while (2) would not. | |
| Options (2) and (3) essentially treat the currently-bound | |
| and non-currently-bound framebuffers the same--i.e., | |
| deleting the image (ultimately) detaches it from all | |
| framebuffer. This may be desirable as a convenience to the | |
| application. | |
| On the other hand, Option (1) treats the currently bound | |
| framebuffer special, in that deletions are performed | |
| automatically much like textures are unbound automatically | |
| from the current context's binding points, but they are not | |
| unbound automatically from other contexts' binding points. | |
| Also, Option (1) leaves the application in control of when | |
| the images are detached, which also may be desirable. | |
| We choose option (1) because it is the simplest, and it also | |
| does not unduly burden implementations regardless of their | |
| choice of (a) versus (b) object-sharing model. | |
| If an implementation has the (a)-style object sharing model, | |
| then the fact that images remain attached to non-bound | |
| objects has no affect on when the object name may be | |
| re-used. If the implementation has a (b)-style | |
| object-sharing model, then the outstanding attachments will | |
| delay re-use of the object name until the image has been | |
| detached. Regardless of whether the ARB chooses (a) or (b) | |
| behavior, or even if the ARB chooses to leave this behavior | |
| undefined, we can "piggy-back" on the name-reuse semantics | |
| they decide. | |
| Also, option (1) means that if the application deletes a | |
| texture while one of the texture's images is attached to a | |
| framebuffer object that is not bound, then the application | |
| may continue to render into the image after the framebuffer | |
| is bound again, regardless of the (a) vs. (b) choice. | |
| Finally, note that if a context deletes an object containing | |
| an image attached to the currently bound framebuffer, then | |
| we first detach the image from the bound framebuffer. This | |
| means that the state change to the framebuffer (the detach | |
| operation) is guaranteed to be picked up by any other | |
| context the next time the framebuffer is bound in one of the | |
| other contexts. | |
| (78) Should we collapse the notions of "framebuffer-attachable image | |
| completeness" and "framebuffer attachment completeness" into a | |
| single type of completeness (probably retaining the name | |
| "framebuffer attachment completeness" | |
| RESOLUTION: resolved, yes, eliminate "framebuffer-attachable | |
| image completeness" and add a "non-zero-area" requirement to | |
| the "framebuffer attachement completeness" test. | |
| Originally this extension had several layers of which | |
| affected framebuffer completness. They were: | |
| - framebuffer-attachable image completeness | |
| * image has non-zero width/height/depth | |
| * image has color, depth, or stencil format | |
| * image is not from a proxy texture | |
| - framebuffer attachment completeness | |
| * attached image is textures/renderbuffer | |
| * attached image is from existing object | |
| * attached image has format appropriate | |
| for attachment point (depth buffer | |
| has depth format, etc) | |
| - framebuffer completeness | |
| * all attachment points are "attachment complete" | |
| * all images are "framebuffer-attachable image complete" | |
| * all color buffers have same format | |
| * draw buffer is attached | |
| * read buffer is attached | |
| * framebuffer format combination is supported | |
| However, upon further reflection of the | |
| "framebuffer-attachable image completeness" tests, we | |
| realized that | |
| a) the requirement that the renderble image is not a | |
| "proxy" texture was already covered by the fact that | |
| it's illegal to attach a proxy texture to a | |
| framebuffer, and | |
| b) the requirement that the format be color, depth, or | |
| stencil is essentially already covered by the | |
| "framebuffer attachment completeness" test | |
| requirement that the format is appropriate for the | |
| attachment point. | |
| This left only the "non-zero-area" test, so we decided to | |
| fold this requirement into the "framebuffer attachement | |
| completeness" test and eliminate the concept of | |
| "framebuffer-attachable image completeness". This decision | |
| required the elimination of one of the | |
| FRAMEBUFFER_INCOMPLETE_* enums as they correspond to the | |
| conditions in the "framebuffer completeness" test of section | |
| 4.4.4 | |
| (79) Should the internal format chosen by GL for a texture (or | |
| renderbuffer) be invariant with respect to the state of the | |
| current framebuffer and its attached images? | |
| RESOLUTION: yes, the choice of internal format must be | |
| invariant with respect to framebuffer state changes. | |
| This means that the GL must choose texture internal format | |
| based only on the arguments to TexImage and ignore the | |
| current framebuffer state in this selection process. | |
| Similarly, the GL must choose renderbuffer internal format | |
| based only on the arguments to RenderbufferStorage and | |
| ignore the current framebuffer state in this selection | |
| process. | |
| This issue is a variant of issue (62). The OpenGL 2.0 | |
| specification (p.152, paragraph 4) states that: | |
| "A GL implementation may vary its allocation of | |
| internal component resolution or compressed internal | |
| format based on any TexImage3D, TexImage2D (see below), | |
| or TexImage1D (see below) parameter (except target), | |
| but the allocation and chosen compressed image format | |
| must not be a function of any other state and cannot be | |
| changed once they are established." | |
| Consider that prior to this extension, some implementations | |
| may have considered the the bitdepths of the logical buffers | |
| of the framebuffer or the bitdepth of the display when | |
| choosing an internal format for textures. Since, in | |
| practice, these bitdepths typically were immutable for the | |
| lifetime of a GL context, the invariance requirements were | |
| met. | |
| With the introduction of EXT_framebuffer_object, however, | |
| the logical buffer bitdepths can change over the lifetime of | |
| the context. So this issue examines whether or not | |
| framebuffer state is allowed to affect texture internal | |
| format selection. | |
| After some discussion, we felt it was too problematic to | |
| introduce this type of invariance. So this extension makes | |
| no modifications to the invariance language, and adds | |
| similar invariance language applicable to renderbuffer | |
| objects. As long as the app provides the same arguments to | |
| TexImage{1D|2D|3D} or RenderbufferStorage, then the GL must | |
| always choose the same internal format. | |
| Note, however, that the GL is not required to provide the | |
| same internal format resolution for renderbuffers as it does | |
| for textures. | |
| (80) Should attachment routines be display-list'able? | |
| RESOLUTION: no, in fact none of the routines introduced in | |
| this extension are included in display lists. | |
| Initially, we were just considering whether or not the | |
| framebuffer attachement routines should be included in | |
| display lists. The rationale for not including them was | |
| that since query routines can not be in display lists, and | |
| well-behaved apps should call the query routine | |
| CheckFramebufferStatusEXT() after calling making changes to | |
| framebuffer attachments, it was not possible to write a | |
| well-behaved app that uses display lists to build up and use | |
| a framebuffer. So, one possible solution was to simply | |
| disallow from display lists the routines that change change | |
| the result of CheckFramebufferStatusEXT(). | |
| However, we realized on further consideration that other | |
| routines which can affect the results of | |
| CheckFramebufferStatusEXT are already allowed in display | |
| lists. Namely, the routines which affect textures (TexImage | |
| and friends). So, disallowing the attachment routines is a | |
| partial solution at best. | |
| We also looked for various precedents and found some mixed | |
| results: | |
| - VBO bind operations are not display-list'able, but | |
| this is primarily because the VBO bindings are | |
| considered client-state | |
| - texture bindings are display-list'able | |
| In the end, though we decided to not include the routines | |
| introduced by this extension in display lists for reasons of | |
| simplicity more than anything else. | |
| It's possible we may need to add support for display lists | |
| back in during promotion of this extension if we determine | |
| that it is needed later, but for now, we leave this out. | |
| (81) How should PushAttrib and PopAttrib work with this extension? | |
| RESOLUTION: mostly deferred for now, may revisit later | |
| This extension introduces no new push/pop attrib bits to | |
| cover the state introduced by this extension (for instance | |
| there is no FRAMEBUFFER_BIT). So the only real question to | |
| answer is what effect should Push/Pop attrib have on any | |
| existing state as it relates to this extension. | |
| In particular, how should Push/PopAttrib of the | |
| COLOR_BUFFER_BIT which covers the DRAW_BUFFER and | |
| READ_BUFFER state interact with this extension? Does the | |
| COLOR_BUFFER_BIT affect the per-object DRAW_BUFFER and | |
| READ_BUFFER state? | |
| Currently, the answer is yes. PushAttrib(COLOR_BUFFER_BIT) | |
| saves the DRAW_BUFFER value of the currently bound | |
| framebuffer object. If the app later calls PopAttrib() this | |
| saved value will be restored even if the framebuffer bound | |
| at the time PopAttrib is called is different from the | |
| framebuffer bound at the time PushAttrib was called. | |
| In other words, one are considering whether or not it is | |
| strange that PushAttrib(COLOR_BUFFER_BIT) affects a piece of | |
| per-object state. Note that this is somewhat similar to the | |
| way that a PushAttrib(TEXTURE_BIT) can save off | |
| per-texture-object state and a later call to PopAttrib can | |
| restore that per-object state even if the texture bound at | |
| PopAttrib time has since been changed/ deleted/modified in | |
| some way. | |
| There are some differences with the texture analogy though. | |
| Namely, the TEXTURE_BIT does include the texture bindings so | |
| at least the texture object binding is restored in | |
| conjunction with the per-texture-object state. Also, some | |
| may consider the fact that the TEXTURE_BIT affects | |
| per-texture-object state more intuitive than the fact that | |
| the COLOR_BUFFER_BIT affects per-framebuffer-object state. | |
| Also, there is a larger discussion going on in the ARB right | |
| now about whether PushAttrib/PopAttrib save references to | |
| existing bound objects or only the state values which name | |
| an existing bound object. | |
| For now, we have deferred further discussion of the | |
| PushAttrib/PopAttrib semantics in this extension until the | |
| larger issues are cleared up. | |
| (82) What is the relationship between a "binding" and an | |
| "attachment"? | |
| RESOLUTION: resolved, the concept of attachment is described | |
| below, though final implications will be affected by larger | |
| ARB discussions about object sharing and multiple context | |
| semantics. | |
| "Attaching" is 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 principle, | |
| we treat "A" as if it is <implicitly> bound to "C". | |
| The larger ARB is currently attempting to more clearly | |
| define the mutliple context semantics as they relate to | |
| object sharing and binding. The final implications for | |
| EXT_framebuffer_object may not be clear until those | |
| discussions are resolved. This extension may need an | |
| update once those issues are addressed. | |
| (83) We use a non-zero framebuffer binding to enable the use of this | |
| extension. Should we instead consider using an explicit | |
| enable? | |
| RESOLVED: no, retain the "non-zero-binding means enable" | |
| semantics. | |
| Currently we enable the use of an application-created | |
| framebuffer by binding a non-zero framebuffer object to | |
| FRAMEBUFFER_EXT binding point. If the framebuffer binding | |
| is zero, then the extension is disabled (i.e., we use the | |
| window-system-provided framebuffer). | |
| It might be cleaner to be able to say things like, "when | |
| FRAMEBUFFER_OBJECT is enabled", rather than "when the | |
| framebuffer binding is not zero", and add an explicit | |
| enable. Doing so would also allow changing framebuffer | |
| object attachments while FBO is disabled, which might result | |
| in the driver doing less validation while the application is | |
| setting up framebuffer objects. It would also provide a | |
| cleaner way to explain that the permitted DRAW_BUFFER and | |
| READ_BUFFER values change when the extension is | |
| enabled/disabled. | |
| There are a few object model precedents to choose from: | |
| Textures and ARB Vertex and Framgment Program extensions use | |
| the explicit enable state. However, Vertex Buffer Objects, | |
| Pixel Buffer Objects, and GLSL Vertex and Fragment shaders | |
| use a non-zero-binding to enable the use of those features. | |
| If we used an explicit enable, then we could allow creation | |
| of an object named zero. Precedent dictates that an object | |
| named zero is never shared in the context share group. All | |
| other framebuffer objects are shared across the share group. | |
| It might be cleaner to disallow creation of an object named | |
| zero anyway. | |
| Since binding to zero disables the extension, one way to | |
| think about this is that there is an object named zero which | |
| is managed through MakeCurrent, MakeContextCurrent, and the | |
| window manager. All other objects are managed through | |
| FramebufferTexture, FramebufferRenderbuffer, and the | |
| operations that define/modify texture and renderbuffer | |
| images. When looked at in this light, lack of an explicit | |
| enable is not as strange. | |
| (84) Do we need to add any language to describe the y-orientation of | |
| framebuffer-attachable images? Specifically, what coordinate | |
| system is used by images attached to the framebuffer? | |
| Resolution: unresolved | |
| GL defines the rendering origin at the lower-left corner. | |
| Yet, because of the differences between orientation storage | |
| of textures and images, pbuffer rendering is often | |
| implemented using a "y-inverted" coordinate system. Is this | |
| y-inversion exposed in the API? | |
| Is the origin in the lower-left? Upper-left? Do we need to | |
| say anything about this at all, or is it already covered by | |
| existing GL language? | |
| Currently there is place-holder text in section 4.4.2.3 | |
| The intent of this specification is simply to mirror the | |
| y-orientation issues of the pbuffer style render to texture | |
| API's. What's unclear is whether this requires any new | |
| language in this specification or not. | |
| (85) Explain what happens when the FBO has a different width/height | |
| from the window? | |
| An FBO takes on the width/height of its attachments. This | |
| width/height can be different than the width/height of the | |
| window (of framebuffer "zero"). | |
| In such cases, after calling BindFramebuffer, it is the | |
| application's responsibility to set the glViewport and the | |
| glScissor (if necessary) to match that of the new | |
| framebuffer binding. | |
| Some background: The default viewport for a context is | |
| defined by the dimensions of the window to which the context | |
| is first made current. When the window is resized, or when | |
| the context is bound to a different window, the viewport | |
| does not change automatically. It has always been the | |
| application's responsibility to set the viewport after one | |
| of these events. FBO is no different; after BindFramebuffer | |
| it is the application's responsibility to set the viewport | |
| if the new framebuffer binding has a different width/height | |
| than the old binding.. | |
| (86) Are any one- or two- component formats color-renderable? | |
| Presently none of the one- or two- component texture formats | |
| defined in unextended OpenGL is color-renderable. The R | |
| and RG float formats defined by the NV_float_buffer | |
| extension are color-renderable. | |
| Although an early draft of the FBO specification permitted | |
| rendering into alpha, luminance, and intensity formats, this | |
| this capability was pulled when it was realized that it was | |
| under-specified exactly how rendering into these formats | |
| would work. (specifically, how R/G/B/A map to I/L/A) | |
| To resolve this we seem to have two options: | |
| A) Add new R and RG formats like NV_float_buffer did. | |
| B) For the existing one- and two- component formats, define | |
| the mapping from RGBA components to ILA components. | |
| The superbuffers group has informally decided that option A | |
| is preferable. | |
| (87) What happens if a single image is attached more than once to a | |
| framebuffer object? | |
| RESOLVED: The value written to the pixel is undefined. | |
| There used to be a rule in section 4.4.4.2 that resulted in | |
| FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT if a single | |
| image was attached more than once to a framebuffer object. | |
| FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 | |
| * A single image is not attached more than once to the | |
| framebuffer object. | |
| { FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT } | |
| This rule was removed in version #117 of the | |
| EXT_framebuffer_object specification after discussion at the | |
| September 2005 ARB meeting. The rule essentially required an | |
| O(n*lg(n)) search. Some implementations would not need to do that | |
| search if the completeness rules did not require it. Instead, | |
| language was added to section 4.10 which says the values | |
| written to the framebuffer are undefined when this rule is | |
| violated. | |
| Revision History | |
| #123, October 6, 2016: Jon Leech | |
| - Remove STENCIL_REF from list of state moved to become framebuffer | |
| dependent (Bug 8422). | |
| #122, May 3, 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) | |
| #121, 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). | |
| #120, April 22, 2008: Jeremy Sandmel & Jon Leech | |
| - Update errors section so detaching renderbuffers and textures | |
| using object name zero is not an error. | |
| #119, February 13, 2007: Jon Leech | |
| - Corrected typos in 'GenerateMipmap'. | |
| #118, April 5, 2006: jjuliano | |
| - Improve language related to which formats are | |
| color-renderable, and describe format conversions when reading | |
| from and writing to the framebuffer. Lays groundwork for | |
| making additional formats color-renderable. | |
| - Add section 4.4.6. | |
| - Selecting same attachment multiple times via DRAW_BUFFERs | |
| writes undefined value to the buffer. | |
| - Clarify effect of framebuffer completeness on values of state | |
| table 9.nnn. | |
| - Describe interaction with NV_float_buffer and | |
| NV_texture_shader. | |
| #117, September 26, 2005: jjuliano | |
| - Remove FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT. | |
| - Add language to section 4.10 explaining that duplicate | |
| attachments result in undefined behavior | |
| - Add issue (87) to discuss the change. | |
| - List EXT_packed_depth_stencil as affecting this extension. | |
| #116, September 16, 2005: jjuliano | |
| - Add example (8) demonstrating FBO + ARB_draw_buffers. | |
| - Add issue (85) discussing window and FBO of different sizes. | |
| - Add issue (86) about one- and two- component texture formats. | |
| - State that OpenGL 1.1 is required. | |
| #115, July 25, 2005: jjuliano | |
| - Improve wording around ReadPixels of color data while | |
| READ_BUFFER is NONE. (INVALID_OPERATION). Clarify that it is | |
| legal to read depth/stencil while READ_BUFFER is NONE. | |
| - In section 4.4.4.2 (Framebuffer Completeness), clarify that | |
| READ_BUFFER can be NONE, and if NONE then framebuffer | |
| completeness does not require a color attachment. | |
| #114, June 16, 2005: jjuliano | |
| - Eliminate the name STENCIL_INDEX_EXT. The name STENCIL_INDEX | |
| is already defined in the core specification. | |
| - Add some missing errors to the errors section. | |
| - Add _ARB suffix to TEXTURE_RECTANGLE, and describe interactions | |
| with ARB_texture_rectangle. | |
| - In errors section, say that it is an error if cube map texture | |
| passed to GenerateMipmapEXT is not cube complete. | |
| #113, May 27, 2005: jsandmel, jjuliano, chris niederauer, alex eddy, barthold lichtenbelt | |
| - improved langage and added some tables (10.nnn and 11.nnn) in | |
| another attempt to clarify the DrawBuffer(s)/ReadBuffer error | |
| semantics | |
| - added additional errors to the summary at the end | |
| - fixed typo in FramebufferTexture3D where <zoffset> was | |
| compared against MAX_3D_TEXTURE_SIZE and should have been | |
| compared against (MAX_3D_TEXTURE_SIZE - 1). | |
| - note that issue (21) is a duplicate of issue (77) and | |
| mark issue (21)'s resolution with a reference to issue (77) | |
| - the resolution of issue (75) indicated that STENCIL_REF is now | |
| dependent on the current framebuffer state, but STENCIL_REF | |
| was inadvertantly left off of table 9.nnn | |
| - fixed the bullet item in section 4.4.1 that stated that when bound to | |
| an application-created framebufer, the value of SAMPLES is 1. | |
| it should have said 0. | |
| - added missing queries of renderbuffer bit depths that were | |
| inadvertantly left out of the spec. | |
| #112, April 28, 2005: jsandmel, jjuliano, chris niederauer | |
| - updated contributors list | |
| - Improve language pertaining to "render to texture source" loop. | |
| - Fixed typo where CheckFramebufferStatusEXT was accidentally | |
| listed twice in additions to chapter 5's list of | |
| non-display-listed commands | |
| - fixed typo in prototype conventions | |
| - as per workgroup meeting decision on April 4, 2005, | |
| DrawBuffer(s) and ReadBuffer no longer generate an error when | |
| specifying an attachment point for which there is no image | |
| attached. The rationale is that the user can always attach | |
| (or detach) after DrawBuffer(s)/ReadBuffer is called anyway. | |
| We retain the test in CheckFramebufferStatusEXT that makes | |
| sure the buffers are attached prior to rendering, however. | |
| - as per workgroup email list discussions April 20, 2005, added | |
| BindFramebuffer/BindRenderbuffer to the list of | |
| display-listable functions. They were inadvertantly left off | |
| the list. Adding them back to be consistent with resolution | |
| of issue (80). | |
| - added missing language to FramebufferTexture discussion to | |
| correct section where we compared width/height/level values to | |
| MAX_TEXTURE_SIZE instead of MAX_CUBE_MAP_TEXTURE_SIZE for cube | |
| maps attached to framebuffer. | |
| - as per workgroup meeting decision on April 26, 2005, | |
| CheckFramebufferStatusEXT will generate an error if called | |
| within a Begin/End pair, since it is (intentionally) not | |
| listed in the exclusion list for functions that can be called | |
| within Begin/End in section 2.6.3 | |
| - as per workgroup meeting decision on April 26, 2005, since | |
| section 2.6.3 states that routines that return a value should | |
| return 0 if the routine generates an error, | |
| CheckFramebufferStatusEXT should return zero and not | |
| FRAMEBUFFER_STATUS_ERROR_EXT. Since we don't need | |
| FRAMEBUFFER_STATUS_ERROR_EXT anymore, we are removing this | |
| enum from the spec. | |
| - added missing error language to spec body and fixed incorrect | |
| language in "Errors" section to clarify that specifying enums | |
| to DrawBuffer(s) and ReadBuffer that are NEVER legal is an | |
| INVALID_ENUM, while specifying values that only illegal | |
| because of the current framebuffer binding are an | |
| INVALID_OPERATION. | |
| - Fix minor typos in DrawBuffer(s) and ReadBuffer definitions. | |
| #111, February 28, 2005: jjuliano, jsandmel | |
| - Add example 7 illustrating "depth-only" framebuffer object. | |
| #110, February 28, 2005: jsandmel, jjuliano, brian paul | |
| - no functional changes | |
| - integrated Brian Paul's fixes for typos and noted | |
| that invalid operation is generated if the <textarget> | |
| and type of texture don't match in FramebufferTexture | |
| - default internalformat for renderbuffer is RGBA not "1" since | |
| "1" is not a legal internalformat for renderbuffers | |
| - note that the unsinged base internal formats of RGB, RGBA, | |
| DEPTH_COMPONENT, and STENCIL_INDEX are legal internal formats | |
| for renderbuffers. They were intended to be legal all along | |
| but the language indicated otherwise. | |
| #109, January 31, 2005: jsandmel, jjuliano | |
| - added language to issue (48) to indidcate that | |
| CheckFramebufferStatus will return an undefined result for a | |
| framebuffer in the intial state since a framebuffer in the | |
| initial state violates multiple completeness rules | |
| #108, January 31, 2005: jjuliano | |
| - fix typos pointed out by various people (thanks) | |
| #107, January 17, 2005: jjuliano, jsandmel | |
| - fix resolution of issue (28) to say "zoffset", not "image" | |
| - more cleanup of issue resolutions | |
| #106, January 17, 2005: jjuliano | |
| - per working group decision, clean up issue resolutions | |
| - minor whitespace and punctuation cleanup | |
| #105, January 17, 2005: jjuliano | |
| - add XXX documenting "undefined-ness" of rendering | |
| vs. texturing | |
| - minor language clarification and typo fix | |
| #104, January 14, 2005: jjuliano, jsandmel | |
| - white space clean up (plus a few capitalizations) | |
| - no functional changes in this revision | |
| #103, January 14, 2005: jjuliano, jsandmel, barthold lichtenbelt, jon leech | |
| - add missing "NONE" case to DrawBuffer language | |
| - permit ReadBuffer(NONE) for application-created framebuffers | |
| - spec body: actually state that DrawPixels, ReadPixels, | |
| CopyPixels, and derivatives of CopyPixels all generate | |
| INVALID_FRAMEBUFFER_OPERATION_EXT if called while framebuffer | |
| is not complete | |
| - clarify error semantics for DrawBuffer(s) when there is no | |
| image attached to the framebuffer attachment point named by | |
| DrawBuffer(s) | |
| - improve error language regarding the <level> parameter of | |
| FramebufferTexture | |
| - State that table 4.nnn is part of the per-framebuffer-object | |
| state vector | |
| - Delete dangling references to table 3.nnn | |
| - In section 4.4.4.2, adjust wording to understand that | |
| DeleteTextures deletes an object, not image | |
| - Convert some left-over window-system-* to | |
| window-system-provided | |
| - Adjust some whitespace and punctuation | |
| - renumbered tables to remove the hole now that the old table of | |
| CheckFramebufferStatus enums has been deleted. | |
| - incorporate remainder of barthold's edits removing more | |
| "framebuffer-attachble" references from the issues list | |
| - moved comment describing the purpose of the | |
| CheckFramebufferStatus enums in the framebuffer completeness | |
| test closer to their initial use in the spec. | |
| - Eliminate two XXX comments that addressed by this revision | |
| #102, January 13, 2005: jjuliano, jsandmel, barthold lichtenbelt, jon leech | |
| - replacement of "renderable image" with "framebuffer-attachable | |
| image" | |
| - removed lots of (now redundant) instances of | |
| "framebuffer-attachable" | |
| - streamlined the grammar in several places to account for | |
| "framebuffer-attachable" change | |
| - incorporated outstanding edits from barthold's review of #73 | |
| and #98 | |
| - made FramebufferTexture and FramebufferRenderbuffer use "uint" | |
| for texture and renderbuffer names for consistency with | |
| Gen/Is/Bind/Delete. For some reason, in revision #77 we | |
| had incorrectly changed these from uint to ints. | |
| - renamed FRAMEBUFFER_INCOMPLETE_MULTIPLE_ATTACHMENT to | |
| FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT | |
| - fixed DeleteTextures and DeleteRenderbuffers language to | |
| reflect resolution of issue (77), by adding forward reference | |
| to the section that describes attachment (that already had | |
| that right language). | |
| - fixed the different language in FramebufferRenderbuffer and | |
| FramebufferTexture that described the state when binding a | |
| zero object (dropped the reference to object type of NONE | |
| since that *is* the default and it already said the state was | |
| set to default values) | |
| - reworked section 4.4.2 overview to simplify intro to | |
| attaching images to framebuffers | |
| - reworded intro to section 4.4.2.1 Renderbuffer Objects | |
| - fixed several instances of "render buffer" to "renderbuffer" | |
| - replaced language in framebuffer attachment routines that | |
| bounded the upper value of <level> to use the parallel | |
| language from page 185 of the OpenGL 2.0 spec. | |
| - simplified first clause of framebuffer compelteness test to | |
| just require at least one image attached to framebuffer | |
| - reordered CheckFramebufferStatusEXT section and moved | |
| description of FRAMEBUFFER_UNSUPPORTED_EXT to be part of | |
| framebuffer completeness section description | |
| - deleted table 3.nnn which lsted the return values of | |
| CheckFramebufferStatusEXT since this info is already included | |
| in the framebuffer completeness test itself and was really | |
| just a duplicate copy in table form. | |
| - added several errors which were missing from the error summary | |
| at the end of the spec | |
| #101, January 12, 2005: jjuliano, jsandmel | |
| - Clarify language related to BindRenderbuffer(<target>, 0) | |
| - Small grammatical change related to object vs. object's image. | |
| #100, January 11, 2005: jsandmel, jjuliano | |
| - added new enums and clauses to framebuffer completeness test | |
| to catch mutliple and missing attachements | |
| - reshuffled existing enums to account for new enums | |
| - clarified issue (84) it indicate that the intent is to mimic | |
| the pbuffer orientation style | |
| #99, January 11, 2005: jsandmel, jjuliano | |
| - use more expelict language mapping window coordinates to | |
| texture image texels at the end of section 4.4.2.3 | |
| - fixed typos | |
| - coalesced interactions with AGL/GLX/WGL with interactions with | |
| WGL/GLX_make_current_read extensions | |
| - addressed and removed some more remaining XXX comments | |
| - added note to issue (58) saying that {Copy}TexSubImage | |
| uses negative offsets to address border texels | |
| - added issue (84) - do we need any language describing | |
| orientation of renderable images? (I.e., are they y-inverted?) | |
| #98, January 7, 2005: jsandmel | |
| - remove more outstanding XXX comments | |
| - updated section 4.4 to better define applicatino-created and | |
| window-system-provided framebuffers in the overview of | |
| framebuffer objects | |
| - further clarifications to issue (49) concerning MRT support | |
| - removed stale XXX comment from issue (75) about stencil mask | |
| language | |
| #97, January 7, 2005: jjuliano | |
| - Resolve some XXX comments, by adding missing spec language and | |
| clarifying existing spec language. | |
| #96, January 6, 2005: jjuliano, ian romanick | |
| - renumbered sections to reflect earlier removal of the section | |
| on renderable image completeness. | |
| - fixed prototype of CheckFramebufferStatusEXT in spec (bool->enum) | |
| #95, January 6, 2005: jsandmel, jjuliano | |
| - added missing change notes from #94 | |
| - fixed more typos | |
| - updated issue (48) - it had been resolved already but need | |
| some updated some language from the resolution to reflect our | |
| final decision | |
| - marked issue (55) as resolved (it had been resolved a while | |
| ago but was left as unresolved) | |
| - resolved issue (82) - bind vs. attach. final spec | |
| implications may get updated when we resolved the larger ARB | |
| discussions over multicontext behavior and object sharing | |
| #94, January 4, 2005: jjuliano | |
| - language clarification and word smithing. | |
| - note that rendering to the border of a texture uses | |
| an origin within the border texels | |
| - updated comments in sample code for clarity | |
| - updated issue (16) to clarify how CopyTexImage possibly | |
| affects framebuffer completeness, and simplified remaining | |
| language | |
| - updated issue (77) to better capture the effects of | |
| deleting attached renderable images | |
| - updated issue (79) to better capture the invariance of | |
| renderable image internal format selection | |
| - added additional clarifications to issue (83) to describe how | |
| an explicit enable/disable API would work | |
| #93, December 23, 2004: jsandmel | |
| - improved stencil ref value clamping language yet again to | |
| indicate that queries are clamped | |
| - moved old XXX comment about an explicit enable into a new | |
| resolved issue (83) | |
| - removed a condition of framebuffer attachment completness | |
| concerning the legality of the LEVEL param which I | |
| overzealously added in revision #92 | |
| - resolved issue (77) - images are detached from current | |
| framebuffer only, user must do manual detachment for | |
| non current framebuffers | |
| - clarified issue (79) to note that GL need not choose the same | |
| format for both renderbuffers and textures as the text seemed | |
| to imply before. | |
| - clarified issue (16) to note that state changes to non-bound | |
| framebuffers are somewhat similar to state changes made by | |
| another context to shared objects (possibly) bound by this | |
| context. | |
| - clarified resolution of issues (15) and (16) which talk about | |
| how {Copy}TexImage into textures affect the framebuffers to | |
| which textures are attached. | |
| #92, December 23, 2004: jsandmel | |
| - updated "Dependencies" section to add descriptions for | |
| interactions with other extensions | |
| - fixed a stale reference to "accum" in overview | |
| - improved language in overview that seemed to imply that | |
| this extension required a data copy to do render to texture | |
| - removed stale XXX comment about framebuffer sharing since | |
| issue (76) is resolved | |
| - added proposed language for "attach" definition in glossary | |
| - removed stale glossary entry for "renderable image completeness" | |
| now that issue (78) is resolved | |
| - Updated chapter 2 to use proposed language changes describing | |
| interactions with the framebuffer in the context of this | |
| extension. | |
| - clarified that GenerateMipmap only requires cubemap textures | |
| to be cubemap complete | |
| - removed unnecessary reference to proxy texture in GenerateMipmap | |
| - clarified language about stencil ref value clamping | |
| - removed various other stale XXX comments | |
| - added note that RENDERBUFFER_BINDING_EXT can be queried | |
| - included alternate beahviors in language influenced by issue | |
| (77) | |
| - defined the error that occurs on FramebufferTexture when | |
| a level is specified that is too big | |
| - added requirement to framebuffer attachment completeness | |
| that FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT must be | |
| less than q for symmetry with the requirement that the | |
| z-offset is smaller than the depth of the texture | |
| - added section numbers to state tables | |
| - indicated there are no attribute bits for the state tables | |
| - added proposed language for issue (82) | |
| - added proposed language for issue (77) | |
| #91, December 22, 2004: jsandmel | |
| - added updated stencil language to reflect resolution of | |
| issue (75) - stencil ref value and writemask clamping | |
| - added language to section 4.4.2.1 indicating that internal | |
| format selection for renderbuffers follows the same invariance | |
| rules as textures | |
| - updated framebuffer completeness language to reflect resolution | |
| of sissue (78) | |
| - added test to framebuffer attachment completeness indicating | |
| that the z-offset identifying an image within a 3D texture must | |
| be less than the texture's depth | |
| - added routines to list of non-display-list'able routines | |
| as per resolution of issue (80) | |
| - deleted note about OpenGL ES in issue (76) | |
| - cleaned up the proposed language for issue (77) based on | |
| feedback from Jeff Juliano | |
| #90, December 22, 2004: jsandmel | |
| - removed plural from FRAMEBUFFER_INCOMPLETE_ATTACHMENT[S] | |
| - added FRAMEBUFFER_STATUS_ERROR_EXT to enumerants list | |
| - resolved issue (78) - collapsing "renderable image | |
| completeness" test and removed FRAMEBUFFER_INCOMPLETE_IMAGES | |
| enum as per meeting Dec. 21, 2004 | |
| - fixed up some typos | |
| - wrote up and resolved issue (76) - framebuffers are shared | |
| like textures as per meeting Dec. 21, 2004 | |
| - wrote up issue (77) - detachment on deletion | |
| - wrote up and resolved issue (79) - textures are invariant | |
| with respect to framebuffer state | |
| - wrote up and resolved issue (80) - no routines in this | |
| extension are display-list'able | |
| - wrote up and deferred issue (81) - push/pop attrib | |
| - added issue (82) - bind vs. attach defintions | |
| #89, December 16, 2004: jjuliano, jsandmel, ian romanick | |
| - added glx protocol for this extension | |
| - added issue (75) - stencil ref value and write mask state | |
| - added issue (76) - sharing framebuffer objects | |
| - added issue (77) - deletes affect on detaching images | |
| - added issue (78) - collapsing "completeness" tests | |
| #88, December 06, 2004: jjuliano, jsandmel | |
| - revised examples again for clarity, added example (6) to show | |
| one way to handle CheckFramebufferStatusEXT | |
| #87, December 03, 2004: jjuliano, jsandmel | |
| - incorporated language edit feedback from john rosasco | |
| - changed a few instances of "rendering to texture" to "render | |
| to texture" | |
| - added XXX notes about sections that still need cleanup | |
| - clarified definition of renderbuffer and its image in overview | |
| - clarified comparison of MakeCurrent and BindFramebuffer in | |
| overview | |
| - fixed misc typos | |
| - renamed TEXTURE_ZOFFSET to TEXTURE_3D_ZOFFSET for consistency | |
| with TEXTURE_CUBE_MAP_FACE | |
| - added note to update section 2.1 to talk about configuring | |
| framebuffer (need forward reference to chapeter 4). | |
| - changed several instances "the GL is using ... framebuffer" to | |
| "the GL is bound to ... framebuffer" | |
| - changed several instances of "When [A], if [B], [C]" into "If | |
| [A] and [B], then [C]" | |
| #86, December 02, 2004: jon leech | |
| - assigned "real" enum values | |
| - fixed some minor typos | |
| #85, December 01, 2004: jjuliano, jsandmel | |
| - Improve error checking in examples | |
| - whitespace cleanup | |
| #84, December 01, 2004: jjuliano | |
| - DrawBuffer(s) while bound to user-created framebuffer object | |
| generates an error if the named color attachment does not have | |
| have anything attached to it when DrawBuffer is invoked. | |
| - Likewise for ReadBuffer. | |
| #83, November 30, 2004: jjuliano | |
| - improve wording of issue (28) - zoffset vs image of a | |
| 3-dimensional texture | |
| - update examples to use the new attach target enums, and | |
| to check framebuffer status | |
| #82, November 30, 2004: jsandmel | |
| - renumbered tables to start with 1.nnn instead of 2.nnn | |
| - resolved issue (74) - return value of CheckFramebufferStatus() | |
| - re-opened and re-resolved issue (28) - zoffset vs image of a | |
| 3d texture | |
| - fixed reference of CopyTexImage to CopyTexSubImage in intro | |
| - added 16 enums for COLOR_ATTACHMENTn_EXT as per meeting | |
| november 29, 2004 | |
| - clarified language about number of attachment points in | |
| description of BindFramebufferEXT(). | |
| #81, November 30, 2004: jsandmel | |
| - re-added *-renderable clause to "renderable image completeness" | |
| test. | |
| - clarified language in intro that describes selecting an | |
| image from a texture | |
| - fixed a few more typos | |
| #80, November 30, 2004: jjuliano | |
| - Improve definition of CheckFramebufferStatusEXT. | |
| FRAMEBUFFER_STATUS_ERROR_EXT is returned if <target> is | |
| invalid. Framebuffer zero always produces | |
| FRAMEBUFFER_COMPLETE_EXT. | |
| - Rename 3D_IMAGE to ZOFFSET. More consistent with | |
| CopyTex(Sub)Image. | |
| - In definition of GetFramebufferAttachmentParameterivEXT, | |
| explain that zero is returned when face or zoffset is queried, | |
| but texture is not cube map or 3-dimensional, resp. This | |
| matches the informal description in issue (51). | |
| - Eliminate table 1.nnn, and modify references to instead | |
| reference table 6.nnn. I have not renumbered all the tables | |
| yet, so that the diffs are more obvious. Renumbering can | |
| happen in the next change. | |
| - Eliminate *-renderable clause from Renderable Image | |
| Completeness. This is already covered under Framebuffer | |
| Attachment Completeness. | |
| - For each clause in Framebuffer Completeness, add references to | |
| specific error generated when that clause is violated. | |
| #79, November 23, 2004: jsandmel, jjuliano | |
| - more typos fixed | |
| - added placeholder enumeration of all tables so that every | |
| table was not named XXX.XXX. They are now named M.nnn where M | |
| is incremented sequentially for each table. | |
| - stated that order of return of CheckFramebufferStatus enums is | |
| "implementatino-dependent" instead of "undefined" | |
| - added state table for framebuffer object state (as opposed to | |
| table of framebuffer attachment point state), added | |
| DRAW_BUFFERi and READ_BUFFER state to this table. | |
| #78, November 22, 2004: jsandmel | |
| - re-opened and re-resolved issue (4) - renamed | |
| "renderable-images" to "framebuffer-attachable images" | |
| - resolved issue (70) - defer support of framebuffer binding | |
| push/pop semantics | |
| #77, November 22, 2004: jsandmel, jjuliano | |
| - fixed up typos and address other issues found by Barthold | |
| - changed errors of GetFramebufferAttachmentParameterivEXT | |
| to be INVALID_ENUM instead of INVALID_VALUE where appropriate | |
| - added missing INVALID_ENUM GetRenderbufferParameterivEXT error | |
| case to list of errors | |
| - dropped framebuffer status state from state table (The reason | |
| is: technically this is not state queriable with a standard | |
| Get call and doesn't really need to be stored, an | |
| implementation could calculate this result on the fly in | |
| principle.) | |
| - added issue (74) - what does it mean to call | |
| CheckFramebufferStatusEXT on framebuffer zero (default | |
| framebuffer) and what if CheckFramebufferStatusEXT generates | |
| an error? | |
| - cleaned up a bunch more "window-system-provided" references | |
| - changed a bunch of "bit plane" references --> "bitplane" | |
| - more updates to glossary section (not complete yet) | |
| - Added boolean return values to IsRenderbuffer and | |
| IsFramebuffer prototypes | |
| - Changed object id's in FramebufferTexture* and | |
| FramebufferRenderbuffer from uint to int to be consistent with | |
| texture routines. | |
| - changed typo in Get*Parameter routines: "param" --> "params" | |
| - added missing COLOR_ATTACHMENTn_EXT enums to new tokens list | |
| - clarified difference and similarities between automatic and | |
| manual mipmap generation in section 3.8.8 | |
| - added lots of missing EXT's | |
| - clarified use of <textarget> in FramebufferTexture when | |
| <texture> is zero and <renderbuffer> target in | |
| FramebufferRenderbuffer when <renderbuffer> is zero. | |
| (<textarget> and <renderbuffertarget> are ignored in this case> | |
| - added a sentence defining that order of return for enums in | |
| CheckFramebufferStatusEXT is undefined if multiple clauses of | |
| framebuffer completeness test fail | |
| #76, November 19, 2004: jsandmel | |
| - as per group meeting Nov. 19, 2004, rename "render buffer" to | |
| "renderbuffer". This is the only substantive change in this | |
| revision. Unfortunately, this had a lot of white-space | |
| collateral damage. Also, this reopens and closes issue (3). | |
| #75, November 18, 2004: jsandmel | |
| - added missing enums to New Tokens section | |
| - clarified wgl/agl/glx language additions section to note that | |
| the window-system draw/read drawables are ignored when bound | |
| to an application-created framebuffer object | |
| - resolved issue (69) - "application-create" framebuffers | |
| - added more description of issue (70) - push/pop binding bits? | |
| - resolved issue (71) - defining which draw/reading routines can | |
| throw errors | |
| - resolve issue (72) - require at least one color, depth, or | |
| stencil attachment | |
| - resolved issue (73) - allow READ_BUFFER to be none so | |
| user can read from a non-color buffer in a framebuffer | |
| with no color attachments | |
| - added section on ReadBuffer whose absence had unfortunately | |
| gone unnoticed until now. | |
| - added missing "initial state" language for draw buffer to | |
| section 4.2 | |
| - cleaned up several references to FRAMEBUFFER_EXT that should | |
| have been either "the target FRAMEBUFFER_EXT" or | |
| "FRAMEBUFFER_BINDING_EXT" | |
| #74, November 18, 2004: jsandmel, jjuliano | |
| - fixed up typos found by Ian Romanick | |
| - changed several instances of "GL-allocated framebuffer" to | |
| "application-created framebuffer" for consistency. | |
| NOTE: However, we might want to pick a new term for these | |
| everywhere. Added issue (69) for this. | |
| - added a MAX_RENDERBUFFER_SIZE_EXT implementation constant | |
| to catch errors to RenderbufferStorageEXT. | |
| - added issue (70), (71), (72), (73) for issues found | |
| by Jeff | |
| #73, November 15, 2004: jsandmel | |
| - split out CheckFramebufferStatus enums as per work group | |
| meeting November 15, 2004 | |
| - added note to self to go back and clean up issue (48) | |
| #72, November 15, 2004: jsandmel | |
| - added "valid draw/read buffer" test to framebuffer | |
| completeness test as per resolution of issue (55) as per | |
| meeting on November 11, 2004. | |
| - added new enums to CheckFramebufferStatus for each of the | |
| implementation-independent failure cases as per resolution of | |
| issue (55) as per meeting on November 11, 2004. | |
| (these may be placeholder names for now) | |
| - added additional partial resolutions to issue (55) as | |
| per meeting on November 11, 2004 | |
| - added XXX note to update state tables with whatever the | |
| final final resolution of the DRAW_BUFFER location is. | |
| #71, November 9, 2004: jsandmel | |
| - cleaned up contributors list | |
| - resolved issue (61) on minimum requirements as per work group | |
| meeting on November 6, 2004 | |
| - added partial resolution and additional description to | |
| issue (55) as per meeting on November 8, 2004 | |
| #70, November 2, 2004: jsandmel, jjuliano | |
| - clarified opening language of chapter 4 to name non-visible | |
| buffers | |
| - improved language about when the number of bits in a bitplane | |
| can change | |
| - removed "SUBPIXEL_BITS" from table of state that can change | |
| on framebuffer state change as per working group | |
| meeting November 1, 2004 and marked issue (62) as resolved | |
| - marked issue (56) - draw buffer state location as framebuffer | |
| object state as per working group meeting November 1, 2004 | |
| #69, November 1, 2004: jsandmel | |
| - added placeholder "min requirements" text to issue (61) | |
| - marked issue (68) as resolved since it was resolved during | |
| week of Oct 18, 2004. | |
| - incorporated feedback from Brian Paul on various typos, | |
| prototype mismatches, missing "EXT"s, and missing | |
| IsRenderbuffer language (to chapter 6) | |
| - added missing IsFramebufferLanguage to chapter 6 | |
| #68, October 29, 2004: jjuliano, jsandmel | |
| - additional clarifications to opening of chapter 4 | |
| - various other minor word substitutions | |
| #67, October 28, 2004: jjuliano | |
| - additional clarifications to issue (56) | |
| #66, October 27, 2004: jsandmel | |
| - added most (all?) of the necessary state tables to the end of | |
| the spec (also removed old state table notation) | |
| - made references to the state tables as 6.3XX until we know the | |
| final table numbering | |
| - fleshed out the language of the intro to chapter 4 describing | |
| the color logical buffers and attachable color buffers | |
| - at the beginning of chapter 4, modified core spec language to | |
| note that the bitplane depths are no longer fixed | |
| - moved XXX note about invariance to end of start of chapter 4 | |
| - slightly reworded description of FRAMEBUFFER_UNSUPPORTED_EXT | |
| - moved table of "framebuffer dependent state variables" | |
| from spec body into state tables at end of spec | |
| - added most (all?) of the known errors to the "Errors" | |
| section of the spec. | |
| #65, October 25, 2004: jsandmel | |
| - changes to resolve issue (67) - ValidateFramebuffer is now | |
| called CheckFramebufferStatus(). | |
| - updated section 4.2.1 to include DrawBuffers (plural) language | |
| from OpenGL 2.0 spec. Note: we either need to update whole | |
| spec to be based on OpenGL 2.0 spec, or else revise the | |
| DrawBuffer(s) language to refer to the ARB_draw_buffers | |
| extension sepc language. | |
| - added (possibly temp) reference to errors on ReadPixels when | |
| using an incomplete framebuffer | |
| - added note to section 4.4.1 that describes pixel ownership | |
| test success when using application-created framebuffers | |
| - added table of enum values returned from | |
| CheckFramebufferStatus() as per resolution of issue (48) | |
| - resolved issue (65) - name of error on incomplete framebuffer | |
| operations | |
| - clarified that issue (24) is really a duplicate of (64). | |
| - resolved issue (48) | |
| - added note to write up issue (61) language for review | |
| #64, October 19, 2004: jsandmel, jjuliano | |
| - more rewording and clarifications of issue (56) | |
| #63, October 15, 2004: jjuliano | |
| - more rewording and clarifications of issue (55) and (56) | |
| #62, October 14, 2004: jsandmel | |
| - more rewording and clarifications of issue (55) and (56) | |
| #61, October 13, 2004: jjuliano | |
| - Dramatically reword issues (55) and (56). | |
| - Add issue (68) addressing which levels are generated by | |
| GenerateMipmapEXT | |
| #60, October 11, 2004: jsandmel | |
| - revised write up of issue (56) to capture recent work group | |
| discussions about draw buffer state location | |
| - resolved issue (48) as per work group meeting Oct. 11, 2004 | |
| #59, October 11, 2004: jjuliano | |
| - added note about possibly wanting to have explicit enable for | |
| framebuffer objects instead of using zero in section 4.2.1 | |
| - cleaned up list of differences between framebuffer object and | |
| default framebuffer | |
| - separated out attach/detach cases in list of diffs between | |
| default framebuffer and framebuffer objects | |
| - added reminder note about invariance clause modifications | |
| for section 4.4.5 | |
| - added reminder note about modifications for wgl spec | |
| - cleaned up language in issue (26) about reading from | |
| incomplete framebuffer | |
| - clarified resolution of issue (44) - texture from destination | |
| - replaced various instances of framebuffer "invalid" with | |
| framebuffer "incomplete" | |
| - other misc. typos, white space clean up | |
| #58, October 8, 2004: jsandmel, jjuliano | |
| - reopened and resolved issue (26) - incomplete framebuffer | |
| read is an error? | |
| - reopened, updated, and resolved issue (44) - "texture from | |
| destination" is undefined | |
| - marked issue (50) as resolved, since it basically was | |
| - updated and resolved issue (64) - incomplete framebuffer | |
| rendering is an error? | |
| - tentatively resolved issue (65) - name of error when | |
| trying to use an incomplete error | |
| - resolved issue (66) - clarified what state can | |
| cause framebuffer incompleteness | |
| - created issue (67) - name of ValidateFramebuffer | |
| - implemented preliminary draw buffer language in section 4.2.1 | |
| - added more language in section 4.4.1 to describe differences | |
| between window-system and application-created framebuffers | |
| - updated "texture-from-destination" language in section 4.4.3 | |
| to reflect new resolution of issue (44). | |
| - removed clause describing "texture from destination" | |
| constraints from framebuffer completeness test in section | |
| 4.4.4.1 to reflect resolution of issue (44). | |
| - added list of operations which can change framebuffer | |
| completeness to section 4.4.4.2 | |
| - Added language to section 4.4.4.3 indicating that rendering to | |
| or reading from an incomplete framebuffer is an error, as per | |
| resolution of issue (64) and (26) | |
| - Added more description of implementation dependent state which | |
| can change in section 4.4.5 and refer to framebuffer | |
| completeness section in 4.4.4.2 to identify when this state | |
| can change | |
| - added MAX_COLOR_ATTACHMENTS to list of state variables that | |
| might change if framebuffer state changes | |
| - added error conditions to queries when framebuffer zero or | |
| renderbuffer zero is bound (since there is no framebuffer | |
| zero or renderbuffer zero). | |
| - added placeholder for Additions to the AGL/GLX/WGL | |
| Specifications | |
| - fixed up misc. typos and whitespace | |
| #57, October 1, 2004: jjuliano | |
| - added additional discussion in issue (66) | |
| - fixed up misc. typos and whitespace | |
| #56, September 29, 2004: jsandmel | |
| - added additional option (d) to issue (66) as per our work | |
| group discussions on Sept 30, 2004. | |
| #55, September 29, 2004: jsandmel | |
| - added meta-issue (66) which deals with framebuffer | |
| completeness dependencies on the context state. | |
| - added section 4.4.5 about state variables which may change if | |
| framebuffer state changes. | |
| - dropped some redundant exposition in issue (55) | |
| - resolved issue (60) and wrote up the description of the issue | |
| - removed ACCUM_FORMAT from list of new enums per resolution of | |
| issue (40) | |
| #54, September 27, 2004: jsandmel | |
| - added issue (64) - error to render with incomplete framebuffer? | |
| - added issue (65) - what should the error be? | |
| - added note to ask if we need to reopen (26) about reading | |
| from invalid framebuffer in light of resolution of (64). | |
| #53, September 17, 2004: jsandmel | |
| - updated "attach" definition in glossary | |
| - fixed up some minor typos, whitespace issues | |
| - in issue (15)/(16) indicate tex state changes can affect | |
| framebuffer completeness, not just cause it to fail (they | |
| might cause it to succeed). | |
| - add clarification about the type of intrinsic buffers that | |
| were removed in issue (36) | |
| - updated language describing use of ACCUM format for textures | |
| in issue (40) | |
| - reworded reference to "billboarding" in issue (42) | |
| - clarified the draw buffer(s) issue (55) to indicate | |
| possible problems even after DrawBuffer(s) is called. | |
| - pacified some of the language surrounding issue (63) and the | |
| rationale for using ValidateFramebuffer or a GetInteger style | |
| query. | |
| #52, September 17, 2004: jjuliano | |
| - edits based on review of a subset of the issues section | |
| - edits to the diffs from version #51 | |
| - added note to overview comparing render-to-texture to | |
| CopyTexImage | |
| - added "attach" term to glossary section | |
| - replaced ARB's with EXT's in issue (1) | |
| - distinguished between bind and attach in isuse (5) | |
| - various replacements of "texture" with "texture image" | |
| - various replacements of "framebufer (in)valid" language with | |
| framebuffer (in)completeness language | |
| - added additional rationale to issue (18) about framebuffer | |
| renderable image attachment | |
| - clarified issue (27) that the resolution is no error is | |
| generated | |
| - added note to issue (40) that we might want to use ACCUM | |
| format for textures | |
| - added description of complications with having draw and read | |
| framebuffer targets in issue (42) | |
| - added additional language describing issue (63) concerning the | |
| reasons for using ValidateFramebuffer versus the reasons for | |
| using an explicit query API for framebuffer completeness. | |
| #51, September 16, 2004: jsandmel | |
| - resolved issue (26) - reading from incomplete framebuffer | |
| - clarified issue (55) - draw buffer set to non-existent buffer | |
| - added issue (63) - should we make ValidateFramebuffer a query? | |
| - marked issue (46) as resolved, since there's not much left to | |
| do except resolve the minimum requirements issue (61). | |
| #50, September 16, 2004: jjuliano | |
| - edits based on version #49 diffs, as well as... | |
| - replace uses of "fail ValidateFramebuffer" with references to | |
| "framebuffer completeness" | |
| - reformat whitespace of some very long and very indented issues | |
| - remove "MERGE from some other proposed API" comments | |
| #49, September 16, 2004: jsandmel | |
| - added DeleteTexture and DeleteRenderbuffers spec language to | |
| describe detaching from framebuffers first | |
| - added place holders in various places to correspond | |
| with lots of resolved issues | |
| - added stencil S format table | |
| - renamed section 4.4.3 | |
| - clarified framebuffer attachment and renderable image | |
| requirements for completeness | |
| - added requirement to completeness to have all | |
| color attachments with the same format | |
| - added missing write ups for various issues (8), (9), (12) | |
| - in issue (40), clarified that accum language from 1.5 spec | |
| already covers the error behavior we need to defer accum support | |
| - in issue (41), clarified multisample language from 1.5 could | |
| cover the behavior we need to defer multisample support if we | |
| set SAMPLE_BUFFERS to 0 for non-default framebuffers | |
| #48, September 15, 2004: jjuliano | |
| - edits based on review of chapter 4. | |
| #47, September 15, 2004: jjuliano | |
| - edits based on review of all sections except for chapter 4, | |
| Issues. | |
| - clarified, reordered overview | |
| - added missing enums for framebuffer attachment point state | |
| queries to list of new enums | |
| - indicated that GenerateMipmap will only generate | |
| levels base through q instead of base through p | |
| #46, September 15, 2004: jjuliano | |
| - move issues section to end of document. | |
| (issues section accounts for >50% of the document!) | |
| #45, September 13, 2004: jsandmel, jjuliano | |
| - typos and white space updates | |
| - clarified language about the framebuffer object bound to <target> | |
| in section 4.4.4.2 | |
| - clarified isssue (62) on which state can change and when | |
| #44, September 13, 2004: jsandmel | |
| - resolved issue (40) accum buffers - deferred per group | |
| decision | |
| - resolved issue (41) multisample buffers - deferred per group | |
| decision | |
| - resolved issue (57) maximum attachable color buffers query per | |
| group decision | |
| - opened issue (62) which queries can change state after | |
| BindFramebuffer | |
| #43, September 13, 2004: jsandmel, jjuliano | |
| - typos, cleanup | |
| - fixed up use of COLOR/AUX/DATAN to use lower n as GL spec. | |
| - clarified definitions of color/depth renderable | |
| - indicate renderable images don't have to be attached to be | |
| "renderable image complete" | |
| - replaced requirement on texture images that they simply need | |
| non-zero dimensions instead of saying they have been "defined" | |
| already | |
| #42, September 13, 2004: jsandmel | |
| - updated Framebuffer validation language | |
| - added "complete" terms to glossary in overview | |
| #41, September 9, 2004: jjuliano | |
| - re-add and rewrite section 4.4.4 on "Framebuffer | |
| Validation" | |
| #40, September 9, 2004: jsandmel | |
| - fixed extra "GL" typos noted by Brian Paul | |
| - resolved issue (54) - color attachment names | |
| - resolved issue (58) - textures with borders | |
| - resolved issue (59) - stencil formats | |
| - added issue (61) - minimum requirements | |
| #39, September 9, 2004: jsandmel, jjuliano | |
| - misc. typos and white space fixed | |
| #38, September 8, 2004: jsandmel, jjuliano | |
| - clarifed section 4.4.3 to indicate that if mipmapping | |
| disabled, the framebuffer texture attachment rules are | |
| slightly different. | |
| - fleshed out multisample buffer support options for | |
| issue (41) after more discussions | |
| #37, September 8, 2004: jsandmel | |
| - renamed attachment enums again to add FRAMEBUFFER_ on the | |
| front to further qualify their namespace. | |
| - updated table of attachment point state to include default | |
| values | |
| - added language to "Texturing From an Attached Renderable | |
| Image" (section 4.4.3) | |
| #36, September 8, 2004: jjuliano | |
| - update chapter 3 language on mipmap generation | |
| - modify example 5 to not use depth buffer when | |
| custom-generating mipmap | |
| - add issue 60 on whether or not disabled depth attachment | |
| factors into framebuffer validity determination | |
| #35, September 7, 2004: jsandmel | |
| - updated chapter 6 language on querying renderbuffer and | |
| framebuffer attachment state. | |
| - made references to "id 0" into "name zero" for easier | |
| searching and consistency with core GL spec | |
| - renamed the enums for framebuffer attachment state to add | |
| "ATTACHMENT" to each to qualify the name space of the enums. | |
| These might not be the final names. | |
| #34, September 7, 2004: jsandmel, jjuliano | |
| - further clarified framebuffer attachment language | |
| - specify that attachment routines set "rest" of | |
| attachment state to default values | |
| #33, September 7, 2004: jsandmel | |
| - added examples to issue (54) about framebuffer attachment names | |
| #32, September 7, 2004: jsandmel | |
| - further clarified framebuffer attachment language | |
| #31, September 3, 2004: jsandmel | |
| - added issue (58) about texture borders | |
| - added issue (59) about stencil internal formats | |
| - updated new tokens section to reflect recent issue resolutions | |
| - added attachment state table to section 4.4.2 | |
| - added langauge describing renderbuffer and texture attachment | |
| routines | |
| #30, September 3, 2004: jjuliano | |
| - more typos and white space cleanup | |
| - issue (46): make it clear that validation failure occurs | |
| because of a mismatch in dimensions, rather than size | |
| - clarified language on draw buffer error semantics in issue | |
| (55) | |
| - included more language describing issue (57) about querying | |
| for max number of attachable drawbuffers. | |
| #29, September 2, 2004: jsandmel, jjuliano | |
| - typos fixed and whitespace clean up | |
| - factored issue (39) on ARB_draw_buffers into separate | |
| issues (53), (54), (55), (56), (57) | |
| - fleshed out issue (40) - on ACCUM buffers, tentatively | |
| we will support this if there is time | |
| - made a few ValidationFailures in isseu (46) more | |
| explicit | |
| - added issue (53) - indirection for ARB_draw_buffers? | |
| - added issue (54) - name of color attachment points? | |
| - added issue (55) - error behavior for DRAW_BUFFER | |
| - added issue (56) - is DRAW_BUFFER context state or framebuffer | |
| state? | |
| #28, September 2, 2004: jsandmel | |
| - Improve language describing framebuffer and renderbuffer | |
| objects | |
| #27, August 26, 2004: jsandmel, jjuliano | |
| - re-resolved issue (11) - we use 3 framebuffer attachment | |
| routines for textures, 1 for renderbuffers, also cleaned up | |
| the rationale language for this choice | |
| - resolved issue (30) - renderbuffer state routines take a target | |
| - resolved issue (42) - we use a single framebuffer target enum | |
| - resolved issue (43) - incomplete attached textures will | |
| not cause ValidateFramebuffer failures | |
| - resolved issue (45) - framebuffers with no color buffer attached | |
| will be allowed | |
| - deferred and expanded issue (48) - what info should | |
| ValidateFramebuffer return. | |
| - resolved issue (51) - use individual queries for attachment | |
| state | |
| - resolve issue (52) - auto and manual mipmap generation | |
| can peacefully coexist | |
| - deleted obsolete mipmap generation language from spec text | |
| as this needs to be reworked anyway | |
| #26, August 26, 2004: jsandmel | |
| - corrected some depth_offset --> image terms, since that | |
| is the current resolution of issue (28), unless we reopen it. | |
| - clean up issue (11) language | |
| - moved query of attachments api sub issue from (34) to | |
| its own issue (51) | |
| - removed obsolete note on issue (44) | |
| - fleshed out another alternative attachment query API in issue | |
| (51) | |
| - created issue (52) on when auto/manual mip generation applies | |
| - began more spec language edits to mip generation and framebuffer | |
| object definition (this may be throwaway language depending | |
| on the resolution of some outstanding issues) | |
| #25, August 24, 2004: jjuliano | |
| - Fill in chapter 4. | |
| - Replace some references to "logical buffer" with | |
| "renderbuffer". | |
| - Modification to issue (44). | |
| - Incorporate feedback from Eric Werness: improvements to | |
| examples. | |
| - Incorporate feedback from Jason Allen: issue (42) option D | |
| (GL_FRAMEBUFFER_EXT), and removal of FramebufferBuf. | |
| #24, August 23, 2004: jjuliano | |
| - First stab at text for additions to chapters 2, 3, and 5. | |
| - Fill in examples 1-5. | |
| - Add description of GetFramebufferBufferParametervEXT to | |
| chapter 6. | |
| - Add EXT suffix in some places it was missing. | |
| #23, August 20, 2004: jjuliano | |
| - fix minor typos | |
| - added additional comments regarding reopened issue (11) | |
| - changed some references from z-slice to depth offset | |
| #22, August 19, 2004: jsandmel | |
| - reopened and expanded the options for issue (11) about one vs | |
| many FramebufferTexture attachment routines | |
| - clarified issue (16) does not imply that texture/renderbuffer | |
| state updates are delayed on attached renderable images | |
| - clarified issue (21) to not specifically imply that a call | |
| to BindFramebuffer is required to delete a renderable image | |
| attached to a framebuffer. | |
| - resolved issue (28) "slices" are now referred to as "images" | |
| - resolved issue (29) - GenerateMipmap is included in this | |
| extension | |
| - added and resolved issue (49) - MRT of different formats are | |
| not supported | |
| - added issue (50) - meta issue about whether async generation | |
| of GL errors should be avoided in this api. | |
| #21, August 19, 2004: jsandmel | |
| - incorporated feedback from Barthold (typos fixed) | |
| - incorporated feedback from Barthold (ARB_compromise_buffers->EXT_framebuffer_object) | |
| - incorporated feedback from Barthold (slice->image) | |
| - incorporated feedback from Barthold (other ARB->EXT changes) | |
| #20, August 19, 2004: jjuliano | |
| - fill in issue (13) and (36) - intrinsic buffers | |
| #19, August 18, 2004: jjuliano | |
| - fixed minor typos in issue (15) | |
| - further clarified design rationale in issue (16) | |
| #18, August 18, 2004: jjuliano, jsandmel | |
| - cleaned up language for issues (15) and (16) | |
| #17, August 18, 2004: jsandmel | |
| - cleaned up stale references to ARB_compromise_buffers. | |
| - resolved issues (1) - extension name | |
| - resolved issues (15) - {Copy}TexImage behavior on current framebuffer | |
| - resolved issues (16) - {Copy}TexImage behavior on non-current framebuffer | |
| - (re)resolved issues (21) - Delete object behavior on attached objects | |
| - resolved issues (22) - 1 or 2 detach objects routines | |
| - resolved issues (25) - query on invalid framebuffers | |
| - cleaned up issue (34) language on attachment query API | |
| #16, August 18, 2004: jsandmel | |
| - renamed EXT_framebuffer_object as per group decision | |
| #15, August 8, 2004: jsandmel | |
| - fixed minor typos found by jeff | |
| - expanded discussion on issue (20) to distinguish | |
| width/height/format of texture is mutable unlike texture | |
| target as suggested by jeff | |
| #14, August 5, 2004: jsandmel | |
| - In several issues, make sure ask the same questions about | |
| renderbuffers when we are talking about textures. We want to | |
| resolve these issues symmetrically in almost all cases. | |
| - resolved issue (19) about unused texture/renderbuffer names | |
| - resolved issue (20) about attaching default state objects to | |
| framebuffers | |
| - resolved issue (21) about deleting attached texture/renderbuffer | |
| objects | |
| - fixed typo indicating when issue (33) was resolved | |
| - resolved issue (34) about querying framebuffer objects | |
| for attachments | |
| - resolved issue (44) about using a texture object as a source | |
| texture and destination renderable image | |
| - resolved issue (47) about delineating exactly which state | |
| modifying routines can cause framebuffer revalidation | |
| - added issue (48) about the returned information from | |
| ValidateFramebuffer(). | |
| #13, August 3, 2004: jsandmel | |
| - added related issue in issue (44) - we need to consider | |
| texture objects bound to different targets on the same unit | |
| not just currently bound texture, when calculating | |
| source/destionation circuits. | |
| - in issue (44), option (b), indicate a possibly variant is | |
| to allow but not require ValidateFramebuffer to fail | |
| - cleaned up the "must fail" and "can fail" cases in | |
| issue (46). | |
| - added issue (47) - do we need to list exactly which | |
| state modification routines can cause ValidateFramebuffer | |
| to change its answer? | |
| #12, August 3, 2004: jsandmel | |
| - added issue about when validation failures "can" occur vs. "must" | |
| occur. | |
| #11, August 2, 2004: jsandmel | |
| - removed non-contact emails from contributor list | |
| - "methodology" -> "model" in issue (7) | |
| - resolved issues (31,32,33), there is no renderbuffer name zero, | |
| and binding/attaching to it simply unbinds/detaches the previously | |
| bound/attached object. | |
| - added issue (44) about using the same texture object as both | |
| a source and destination | |
| - added issue (45) about scenarios where having no renderable | |
| image attached to the color buffer attachment point might be | |
| acceptable | |
| #10, July 30, 2004: jjuliano | |
| - flesh out details of issue (29) about GenerateMipmap | |
| - add issue (43) about mipmap cube complete textures and | |
| framebuffer consistency check. | |
| #9, July 30, 2004: jsandmel | |
| - renumbered issues to account for remaval and addition of issues | |
| - dropped issue [used to be (14)] as it was a duplicate of issue | |
| [now (38)] about support for multiple render targets. | |
| - added issue (32) about whether and how to support a | |
| renderbuffer with the name zero (is it an object?) | |
| #8, July 30, 2004: jjuliano | |
| - tightened up language in overview regarding use of renderable | |
| images | |
| - clarified in overview that window and framebuffer can | |
| have different formats | |
| - fixed various typos, grammar, spelling errors | |
| - indicated we should drop issue (14) about MRT, same as issue (37) | |
| - indicate -1 is one option for return value on nonsense queries | |
| of non-validated framebuffer state | |
| #7, July 29, 2004: jsandmel | |
| - add some more terms to the glossary list | |
| - white space and various grammar clean ups (minor) | |
| - note that we need resolution on the switch from | |
| "render target" to "renderable image" | |
| - cleaned up language for issue (31) and (32) | |
| #6, July 29, 2004: jsandmel | |
| - reworked, clarified, streamlined overview section to read better | |
| - cleaned up some white space problems | |
| #5, July 29, 2004: jsandmel | |
| - fixed bad numbering in issues list | |
| #4, July 29, 2004: jsandmel | |
| - cleaned up issues after incorporating feedback | |
| #3, July 28, 2004: jsandmel | |
| - began merging render target and compromise buffers issues lists | |
| - added contributors from EXT_render_target list | |
| - added some extension dependencies | |
| - borrowed overview from EXT_render_target, reworded to | |
| make more appropriate for differences with this spec | |
| - added placeholders for sample code | |
| - resolved a few issues here | |
| - removed intrinsic buffers per group decision july 26,2004 | |
| - retained framebuffer objects per group decision july 26,2004 | |
| - made FramebufferTexture into 3 functions per group decision july 26, 2004 | |
| #2, July 22, 2004: jsandmel | |
| - removed all old EXT-compromise_buffer language, but | |
| some of this will get reformed and added back in | |
| - removed example temporarily, again this will get reformed and | |
| added back in. | |
| - LogicalBuffer renamed to "Renderbuffer" | |
| - began fleshing out issues list | |
| #1, July 22, 2004: jsandmel | |
| - very first revision | |
| - derived from EXT_compromise_buffers but really a mishmash of | |
| all the proposals under discussion |