| 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 |