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