Name EXT_vertex_array_bgra Name Strings GL_EXT_vertex_array_bgra Contributors Jason Green, TransGaming Gavriel State, TransGaming Rob Barris, Blizzard Mark Krenek, Aspyr Ryan Gordon, Destineer Nicholas Vining, Destineer Contact Mark Kilgard, NVIDIA (mjk 'at' nvidia.com) Status Implemented by NVIDIA, October 2008 Version Last Modified Date: October 28, 2008 Version: 5 Number 354 Dependencies This extension is written against the OpenGL 2.1 Specification but can apply to OpenGL 1.1 and up. This extension interacts with EXT_vertex_array. This extension interacts with EXT_secondary_color. This extension interacts with NV_vertex_program. This extension interacts with ARB_vertex_program. This extension interacts with ARB_vertex_shader. Overview This extension provides a single new component format for vertex arrays to read 4-component unsigned byte vertex attributes with a BGRA component ordering. OpenGL expects vertex arrays containing 4 unsigned bytes per element to be in the RGBA, STRQ, or XYZW order (reading components left-to-right in their lower address to higher address order). Essentially the order the components appear in memory is the order the components appear in the resulting vertex attribute vector. However Direct3D has color (diffuse and specular) vertex arrays containing 4 unsigned bytes per element that are in a BGRA order (again reading components left-to-right in their lower address to higher address order). Direct3D calls this "ARGB" reading the components in the opposite order (reading components left-to-right in their higher address to lower address order). This ordering is generalized in the DirectX 10 by the DXGI_FORMAT_B8G8R8A8_UNORM format. For an OpenGL application to source color data from a vertex buffer formatted for Direct3D's color array format conventions, the application is forced to either: 1. Rely on a vertex program or shader to swizzle the color components from the BGRA to conventional RGBA order. 2. Re-order the color data components in the vertex buffer from Direct3D's native BGRA order to OpenGL's native RGBA order. Neither option is entirely satisfactory. Option 1 means vertex shaders have to be re-written to source colors differently. If the same vertex shader is used with vertex arrays configured to source the color as 4 floating-point color components, the swizzle for BGRA colors stored as 4 unsigned bytes is no longer appropriate. The shader's swizzling of colors becomes dependent on the type and number of color components. Ideally the vertex shader should be independent from the format and component ordering of the data it sources. Option 2 is expensive because vertex buffers may have to be reformatted prior to use. OpenGL treats the memory for vertex arrays (whether client-side memory or buffer objects) as essentially untyped memory and vertex arrays can be stored separately, interleaved, or even interwoven (where multiple arrays overlap with differing strides and formats). Rather than force a re-ordering of either vertex array components in memory or a vertex array format-dependent re-ordering of vertex shader inputs, OpenGL can simply provide a vertex array format that matches the Direct3D color component ordering. This approach mimics that of the EXT_bgra extension for pixel and texel formats except for vertex instead of image data. New Procedures and Functions None New Tokens Accepted by the parameter of ColorPointer, SecondaryColorPointer, and VertexAttribPointer: BGRA 0x80E1 Additions to Chapter 2 of the OpenGL 2.1 Specification (OpenGL Operation) -- Section 2.8 "Vertex Arrays" (page 24) Replace the sentence beginning "size, when present, ..." with: "size, when present, indicates the number of values per vertex that are stored in the array as well as their component ordering." Add these final sentences to the end of the same paragraph: "The error INVALID_VALUE is generated if size is BGRA and type is not UNSIGNED_BYTE. The error INVALID_VALUE is generated by VertexAttribPointer if size is BGRA and normalized is FALSE." Edit Table 2.4 "Vertex array sizes (values per vertex) and data types" as follows: * Rename the "Sizes" column to "Sizes and component ordering". * Add "BGRA" to the "Sizes and component order" column of the following rows: ColorPointer, SecondaryColorPointer, and VertexAttribPointer. These are the commands capable of accepting normalized coordinates and accepting 4 for "size" plus the special case of SecondaryColorPointer command. * Add the following sentence to the end of the table caption: "If the size parameter is BGRA, the vertex array values are always normalized irrespective of the Normalized column." "The one, two, three, or four values in an array that correspond to a single vertex comprise an array element. When the BGRA token is specified for size, it indicates four values. The values within each array element are stored sequentially in memory. However if the size is specified with BGRA, the first, second, third, and fourth values of each array element are read from the third, second, first, and fourth values in memory respectively." Additions to Chapter 3 of the OpenGL 2.1 Specification (Rasterization) None Additions to Chapter 4 of the OpenGL 2.1 Specification (Per-Fragment Operations and the Frame Buffer) None Additions to Chapter 5 of the OpenGL 2.1 Specification (Special Functions) None Additions to Chapter 6 of the OpenGL 2.1 Specification (State and State Requests) None Additions to the AGL/GLX/WGL Specifications None Additions to the OpenGL Shading Language None GLX Protocol None Errors The error INVALID_VALUE is generated when ColorPointer, SecondaryColorPointer, or VertexAttribPointer is called with size set to BGRA and type is not UNSIGNED_BYTE. The error INVALID_VALUE is generated when VertexAttribPointer is called with size set to BGRA and normalized is FALSE. Dependencies on EXT_vertex_array This extension's additional behavior for ColorPointer apply to ColorPointerEXT too. Dependencies on EXT_secondary_color This extension's additional behavior for SecondaryColorPointer applies to SecondaryColorPointerEXT too. Dependencies on NV_vertex_program This extension's additional behavior for VertexAttribPointer applies to VertexAttribPointerNV too. Dependencies on ARB_vertex_program and ARB_vertex_shader This extension's additional behavior for VertexAttribPointer applies to VertexAttribPointerARB too. New State Change tables 6.6 and 6.7 to fix Type column by making the type a k-valued integer where k is 3, 2, and 5 for color, secondary, and vertex attrib arrays respectively. (table 6.6, "Vertex Array Data", p. 271) Get Value Type Get Command Initial Value Description Sec Attribute --------- ---- ----------- ------------- --------------------- --- --------- COLOR_ARRAY_SIZE Z3 GetIntegerv 4 Color components 2.8 vertex-array per vertex SECONDARY_COLOR_ARRAY_SIZE Z2 GetIntegerv 3 Secondary color 2.8 vertex-array components per vertex (table 6.7, "Vertex Array Data (cont.)", p. 272) Get Value Type Get Command Initial Value Description Sec Attribute --------- ---- ----------- ------------- --------------------- --- --------- VERTEX_ATTRIB_ARRAY_SIZE Z5 GetIntegerv 16+ x Z5 Vertex attrib array 2.8 vertex-array size New Implementation Dependent State None Issues 1. What should this extension be called? RESOLVED: EXT_vertex_array_bgra Because the extension adds a new "vertex array" format with the "bgra" component ordering and assuming a normalized representation as BGRA with UNSIGNED_BYTE would provide for image data. 2. How should the vertex array API be changed? RESOLVED: Allow BGRA as a valid token for the size field of vertex array specification commands. While the size parameter is of type GLint, the valid sizes are in the 1 to 4 range so the GL_BGRA token is easily distinguished from the existing small integer values. This mimics the way OpenGL 1.1 changed the "components" field of glTexImage1D and glTexImage2D to specify an internalformat rather than simply a number of components from 1 to 4. This approach has the advantage of not adding any new commands or tokens since the GL_BGRA token already exists. 3. What vertex array specification commands should accept the new BGRA vertex array format for their size parameter? RESOLVED: All vertex array specification commands which accept 4 as a valid size plus the glSecondaryColorPointer command because Direct3D allows a BGRA-ordered secondary color (its specular vertex attribute) to be specified. Because DirectX 10 makes its formats highly orthogonal and it allows a corresponding format (DXGI_FORMAT_B8G8R8A8_UNORM), the BGRA vertex array format should be similarly general. 4. Should a 4-component BGRA secondary color be allowed? RESOLVED: Yes. DirectX 9 supports a 4-component secondary color. All four components should be available to a vertex shader or vertex program. Fixed-function operation without lighting enabled should pass through the secondary color alpha component. However fixed-function lighting specifies its output secondary color alpha is always output as 1 and ignores the input secondary color alpha. 5. So should 4 be allowed as a valid size parameter for glSecondaryColorPointer? RESOLVED: Not for this extension. We leave it to another extension or core revision could extend the secondary color to 4 components. 6. Should the BGRA vertex array format only work with the GL_UNSIGNED_BYTE type? RESOLVED: Yes. This is consistent with Direct3D's use of the D3DCOLOR type which is defined with a BGRA ordering and 8-bit normalized components. 7. How should the BGRA vertex array format's normalized behavior interact with the "normalized" parameter of glVertexAttribPointer? RESOLVED: Since BGRA implies normalization, it should be an error to request BGRA with the normalized parameter set to false. This ensures the following statement in the caption of table 2.4 remains true: "For generic vertex attributes, fixed-point data are normalized if and only if the VertexAttribPointer normalized flag is set." 8. Should the glVertexAttribIPointerEXT command accept GL_BGRA for its size parameter? RESOLVED: No. Because the BGRA vertex array format implies normalized component values, that is inconsistent with providing integer vertex attributes. 9. Should this apply to glVertexPointer? RESOLVED: No. glVertexPointer doesn't support GL_UNSIGNED_BYTE as a type so GL_BGRA doesn't make sense. 10. To what vertex arrays should this extension apply? RESOLVED: Just primary color (glColorPointer), secondary color (glSecondaryColorPointer), and generic vertex attribs (glVertexAttribPointer). The rationale is these are the formats that take 4 component attributes that can be normalized (making a special exception to treat the secondary color array as having 4 components for the purpose of BGRA support to match Direct3D). Texture coordinate sets and vertex positions are not normalized. Normals are normalized but only 4 coordinates. 11. What Direct3D 9 functionality provides BGRA vertex arrays? You can specify BGRA vertex arrays with either Flexible Vertex Formats (FVFs) or a Direct3D 9 Vertex Declaration. The FVF formats are D3DFVF_DIFFUSE and D3DFVF_SPECULAR. The Vertex Declaration declaration data type is D3DDECLTYPE_D3DCOLOR. Revision History Rev. Date Author Changes ---- -------- --------- ---------------------------------------- 1 1/11/07 mjk Initial version 2 1/31/07 mjk review comments; issue 9 3 7/16/08 mjk Removed TexCoordPointer behavior Added issues 10 and 11 4 10/7/08 mjk Implemented now 5 10/28/08 mjk Provide state tabe updates