Name EXT_draw_buffers2 Name Strings GL_EXT_draw_buffers2 Contact Mike Strauss, NVIDIA Corporation (mstrauss 'at' nvidia.com) Status Multi vendor extension Shipping for GeForce 8 Series (November 2006) Version Last Modified Date: 7/9/2008 NVIDIA Revision: 10 Number 340 Dependencies The extension is written against the OpenGL 2.0 Specification. OpenGL 2.0 is required. Overview This extension builds upon the ARB_draw_buffers extension and provides separate blend enables and color write masks for each color output. In ARB_draw_buffers (part of OpenGL 2.0), separate values can be written to each color buffer, but the blend enable and color write mask are global and apply to all color outputs. While this extension does provide separate blend enables, it does not provide separate blend functions or blend equations per color output. New Procedures and Functions void ColorMaskIndexedEXT(uint buf, boolean r, boolean g, boolean b, boolean a); void GetBooleanIndexedvEXT(enum value, uint index, boolean *data); void GetIntegerIndexedvEXT(enum value, uint index, int *data); void EnableIndexedEXT(enum target, uint index); void DisableIndexedEXT(enum target, uint index); boolean IsEnabledIndexedEXT(enum target, uint index); New Tokens None. Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation) None. Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization) None. Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment Operations and the Frame Buffer) Modify the thrid paragraph of section 4.1.8 (Blending), p206, to read as follows: Blending is dependent on the incoming fragment's alpha value and that of the corresponding currently stored pixel. Blending applies only in RGBA mode; in color index mode it is bypassed. Blending is enabled or disabled for an individual draw buffer using void EnableIndexedEXT(GLenum target, GLuint index); void DisableIndexedEXT(GLenum target, GLuint index); is the symbolic constant BLEND and is an integer i specifying the draw buffer associated with the symbolic constant DRAW_BUFFERi. If the color buffer associated with DRAW_BUFFERi is one of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK (specifying multiple color buffers), then the state enabled or disabled is applicable for all of the buffers. Blending can be enabled or disabled for all draw buffers using Enable or Disable with the symbolic constant BLEND. If blending is disabled for a particular draw buffer, or if logical operation on color values is enabled (section 4.1.10), proceed to the next operation. Modify the first paragraph of section 4.1.8 (Blending - Blending State), p209, to read as follows: The state required for blending is two integers for the RGB and alpha blend equations, four integers indicating the source and destination RGB and alpha blending functions, four floating-point values to store the RGBA constant blend color, and n bits indicating whether blending is enabled or disabled for each of the n draw buffers. The initial blend equations for RGB and alpha are both FUNC_ADD. The initial blending functions are ONE for the source RGB and alpha functions, and ZERO for the destination RGB and alpha functions. The initial constant blend color is (R, G, B, A) = (0, 0, 0, 0). Initially, blending is disabled for all draw buffers. Modify the first paragraph of section 4.2.2 (Fine Control of Buffer Updates) to read as followS: Three commands are used to mask the writing of bits to each of the logical draw buffers after all per-fragment operations have been performed. The commands void IndexMask(uint mask); void ColorMask(boolean r, boolean g, boolean b, boolean a); void ColorMaskIndexedEXT(uint buf, boolean r, boolean g, boolean b, boolean a); control writes to the active draw buffers. The least significant n bits of , where n is the number of bits in a color index buffer, specify a mask. Where a 1 appears in this mask, the corresponding bit in the color index buffer (or buffers) is written; where a 0 appears, the bit is not written. This mask applies only in color index mode. In RGBA mode, ColorMask and ColorMaskIndexedEXT are used to mask the writing of R, G, B and A values to the draw buffer or buffers. ColorMaskIndexedEXT sets the mask for a particular draw buffer. The mask for DRAW_BUFFERi is modified by passing i as the parameter . , , , and indicate whether R, G, B, or A values, respectively, are written or not (a value of TRUE means that the corresponding value is written). The mask specified by , , , and is applied to the color buffer associated with DRAW_BUFFERi. If DRAW_BUFFERi is one of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK (specifying multiple color buffers) then the mask is applied to all of the buffers. ColorMask sets the mask for all draw buffers to the same values as specified by , , , and . Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions) None. Additions to Chapter 6 of the OpenGL 2.0 Specification (State and State Requests) Modify the second paragraph of section 6.1.1 (Simple Queries) p244 to read as follows: ... is a pointer to a scalar or array of the indicated type in which to place the returned data. void GetBooleanIndexedvEXT(enum target, uint index, boolean *data); void GetIntegerIndexedvEXT(enum target, uint index, int *data); are used to query indexed state. is the name of the indexed state and is the index of the particular element being queried. is a pointer to a scalar or array of the indicated type in which to place the returned data. In addition boolean IsEnabled(enum value); can be used to determine if is currently enabled (as with Enable) or disabled. boolean IsEnabledIndexedEXT(enum target, uint index); can be used to determine if the index state corresponding to and is enabled or disabled. Additions to Appendix A of the OpenGL 2.0 Specification (Invariance) None. Additions to the AGL/GLX/WGL Specifications None. GLX Protocol UNDER DEVELOPMENT Errors The error INVALID_ENUM is generated by EnableIndexedEXT and DisableIndexedEXT if the parameter is not BLEND. The error INVALID_OPERATION is generated by EnableIndexedEXT and DisableIndexeEXT if the parameter is BLEND and the parameter is outside the range [0, MAX_DRAW_BUFFERS-1]. The error INVALID_ENUM is generated by IsEnabledIndexedEXT if the parameter is not BLEND. The error INVALID_OPERATION is generated by IsEnabledIndexedEXT if the parameter is BLEND and the parameter is outside the range [0, MAX_DRAW_BUFFERS-1]. The error INVALID_OPERATION is generated by DrawBufferColorMaskEXT if the parameter is outside the range [0, MAX_DRAW_BUFFERS-1]. The error INVALID_ENUM is generated by GetBooleanIndexedvEXT if the parameter is not BLEND. The error INVALID_OPERATION is generated by GetBooleanIndexedvEXT if the parameter is BLEND and the parameter is outside the range [0, MAX_DRAW_BUFFERS-1]. New State Modify (table 6.20, p281), modifying the entry for BLEND and adding a new one. Get Target Type Get Command Value Description Section Attribute ---------- ---- ------------------- ----- ---------------------------------- ------- ------------------- BLEND B IsEnabled False Blending enabled for draw buffer 0 4.1.8 color-buffer/enable BLEND B IsEnabledIndexedEXT False Blending enabled for draw buffer i 4.1.8 color-buffer/enable where i is specified as Modify (table 6.21, p282), modifying the entry for COLOR_WRITEMASK and adding a new one. Get Value Type Get Command Value Description Section Attribute --------------- ---- --------------------- ----- ---------------------------------- ------- ------------ COLOR_WRITEMASK 4xB GetBooleanv True Color write mask for draw buffer 0 4.2.2 color-buffer COLOR_WRITEMASK 4xB GetBooleanIndexedvEXT True Color write mask for draw buffer i 4.2.2 color-buffer where i is specified as Issues 1. Should the extension provide support for per draw buffer index masks as well as per draw buffer color masks? RESOLVED: No. Color index rendering is not interesting enough to warrant extending the API in this direction. 2. Should the API for specifying separate color write masks be based on DrawBuffers() (specifying an array of write masks at once)? RESOLVED: No. There are two ways to mimic the DrawBuffers() API. A function, ColorMasks(), could take an an element count and an array of four element boolean arrays as parameters. Each four element boolean array contains a set of red, green, blue, and alpha write masks for a specific color buffer. An alternative is a ColorMasks() function that takes an element count and four parallel boolean arrays with one array per color channel. Neither approach is particularly clean. A cleaner approach, taken by ColorMaskIndexedEXT(), is to specify a color mask for a single draw buffer where the draw buffer is specified as a parameter to the function. 3. How should ColorMask() affect the per color buffer write masks? RESOLVED: ColorMask() should set all color buffer write masks to the same values. This is backwards compatible with the way ColorMask() behaves in the absence of this extension. 4. What should GetBooleanv return when COLOR_WRITEMASK is queried? RESOLVED: COLOR_WRITEMASK should return DRAW_BUFFER0_COLOR_WRITEMASK_EXT. This is backwards compatible with the way the query works without this extension. To query the writemask associated with a particular draw buffer, an application can use GetBooleanIndexedvEXT. 5. How are separate blend enables controlled? Should a new function be introduced, or do Enable() and Disable() provide sufficient functionality? RESOLVED: This extension introduces new functions EnableIndexedEXT and DisableIndexedEXT that can be used to enable/disable individual states of a state array. These functions are introduced because there is a trend towards introducing arrays of state. Rather than creating enums for each index in the array, it is better to give applications a mechanism for accessing a particular element of the state array given the name of the state and an index into the array. 6. What effect does enabling or disabling blending using BLEND have on per draw buffer blend enables? RESOLVED: BLEND, used with Enable() and Disable(), should enable or disable all per draw buffer blend enables. This is similar to the way that ColorMask() affects the per draw buffer write masks. 7. What does DRAW_BUFFERi mean in the context of functions like ColorMaskIndexedEXT? PROPOSED: When DrawBuffersARB is called with a list of buffers to be used for MRT rendering, DRAW_BUFFERi implies an index into the list of buffers. That is, DRAW_BUFFER0 refers to the zeroeth buffer in the array passed to DrawBuffersARB (or any of the other ways to specify multiple render targets). MAX_DRAW_BUFFERS is also to be understood in this context to mean the number of currently active draw buffers. Revision History Rev. Date Author Changes ---- -------- -------- ----------------------------------------- 10 07/11/08 joburgess Added a clarification of ColorMaskIndexedEXT / DrawBuffersARB interaction. 9 02/09/07 pbrown Updated status section (now released). 8 10/23/06 pbrown Fixed typo in the prototype for GetIntegerIndexedvEXT -- should be an integer pointer. Moved issues to the end. 7 10/21/06 barthold Added revision history 1-6 mstrauss Internal spec development.