Name

    EXT_colorspace

Name Strings

    WGL_EXT_colorspace

Contact

    Christophe Riccio (christophe 'dot' riccio 'at' unity3d 'dot' com)

Contributors

    Piers Daniell, NVIDIA Corporation
    Slawomir Grajewski, Intel

IP Status

    No known IP claims.

Status

    Shipping

Version

    2016-11-30

Number

    OpenGL Extension #498

Dependencies

    WGL_ARB_pixel_format is required.

    This extension is written against WGL_ARB_pixel_format extension.

    OpenGL dependencies:

        OpenGL 3.0 is required

    OpenGL ES dependencies:

        OpenGL ES 3.0 or GL_EXT_sRGB is required.

Overview

    Applications may wish to use sRGB format default framebuffers to
    more easily achieve sRGB rendering to display devices. This
    extension allows creating pixel formats which will be rendered to
    in sRGB by OpenGL/ES contexts supporting that capability.

New Procedures and Functions

    None.

New Tokens

    Accepted as an attribute name by wglGetPixelFormatAttribivARB,
    wglGetPixelFormatAttribivARB and wglChoosePixelFormatARB

        WGL_COLORSPACE_EXT                      0x309D

    Accepted as attribute values for WGL_COLORSPACE_ARB by
    wglGetPixelFormatAttribivARB, wglGetPixelFormatAttribivARB and
    wglChoosePixelFormatARB

        WGL_COLORSPACE_SRGB_EXT                 0x3089
        WGL_COLORSPACE_LINEAR_EXT               0x308A

        (these enums are aliases of the corresponding VG colorspace
        attribute values from EGL 1.3 and OpenGL/ES colorspace
        attribute values from EGL_KHR_gl_colorspace)

Additions to the WGL Specification

    Following:
        WGL_AUX_BUFFERS_ARB
        The number of auxiliary buffers.

    Add a new attribute:
        WGL_COLORSPACE_EXT
        Buffers color space. This can be set to WGL_COLORSPACE_SRGB_EXT or
        WGL_COLORSPACE_LINEAR_EXT.

    Following:
        WGL_AUX_BUFFERS_EXT            integer     minimum

    Add:
        WGL_COLORSPACE_EXT             enum        exact

    Before paragraph:
        Attributes that are specified in neither <piAttribIList>...

    Add paragraph:

    WGL_COLORSPACE_EXT specifies the color space used by OpenGL and
    OpenGL ES when rendering to the surface. If its value is
    WGL_COLORSPACE_SRGB_EXT, then a non-linear, perceptually uniform
    color space is assumed, with a corresponding
    GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING value of GL_SRGB. If its value
    is WGL_COLORSPACE_LINEAR_EXT, then a linear color space is assumed,
    with a corresponding GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING value of
    GL_LINEAR. The default value of WGL_COLORSPACE_EXT is
    WGL_COLORSPACE_LINEAR_EXT for OpenGL ES and OpenGL. With OpenGL pixel
    formats with WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT set are capable of supporting
    sRGB encoding when GL_FRAMEBUFFER_SRGB is enabled.

    Only OpenGL and OpenGL ES contexts which support sRGB
    rendering must respect requests for WGL_COLORSPACE_SRGB_EXT, and
    only to sRGB formats supported by the context (normally just SRGB8)
    Older versions not supporting sRGB rendering will ignore this
    surface attribute. Applications using OpenGL must additionally
    enable GL_FRAMEBUFFER_SRGB to perform sRGB rendering, even when an
    sRGB surface is bound; this enable is not required (or supported)
    for OpenGL ES.

    WGL itself does not distinguish multiple colorspace models. Refer to
    the 'sRGB Conversion' sections of the OpenGL 4.3 and OpenGL ES 3.0
    specifications for more information.

Sample Code

    bool SetupPixelFormat(HDC DC, bool Linear)
    {

        int const Attrib[] = {WGL_NUMBER_PIXEL_FORMATS_ARB};
        int FormatCount = 0;
        BOOL Result = wglGetPixelFormatAttribivARB(DC, NULL, NULL, 1, Attrib, &FormatCount);
        if(Result != GL_TRUE)
            return false;

        std::vector<int> PixelFormats(static_cast<std::size_t>(FormatCount));

        int Attributes[] =
        {
            WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
            WGL_ACCELERATION_ARB,   WGL_FULL_ACCELERATION_ARB,
            WGL_DOUBLE_BUFFER_ARB,  GL_TRUE,
            WGL_RED_BITS_ARB,       8,
            WGL_GREEN_BITS_ARB,     8,
            WGL_BLUE_BITS_ARB,      8,
            WGL_ALPHA_BITS_ARB,     8,
            WGL_DEPTH_BITS_ARB,     24,
            WGL_STENCIL_BITS_ARB,   8,
            WGL_SAMPLES_ARB,        1,
            WGL_STEREO_ARB,         GL_FALSE,
            WGL_COLORSPACE_EXT,     Linear ? WGL_COLORSPACE_LINEAR_EXT : WGL_COLORSPACE_SRGB_EXT
            0, 0
        };

        UINT ActualFormatCount = 0;
        Result = wglChoosePixelFormatARB(DC, Attributes, NULL, FormatCount, &PixelFormats[0], &ActualFormatCount);
        if(Result != GL_TRUE || ActualFormatCount <= 0)
            return false;

        PIXELFORMATDESCRIPTOR PixelFormatDesc =
        {
            sizeof(PIXELFORMATDESCRIPTOR), 1,
            PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA, 32,
            0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0,
            kDepthBits, kStencilBits,
            0, PFD_MAIN_PLANE, 0, 0, 0, 0
        };

        // Select the first PixelFormat
        return SetPixelFormat(DC, 0, &PixelFormatDesc) == GL_TRUE;
    }

    bool IsDefaultFramebufferLinear()
    {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        GLint Encoding = 0;

        // Just like for framebuffer object, return GL_SRGB is the framebuffer support sRGB update and blending and GL_LINEAR is no sRGB conversion can be performed
        glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &Encoding);
        return Encoding == GL_LINEAR;
    }

Issues

 1) Why do we need this extension?

    On Windows, OpenGL ES implementation can not perform linear to sRGB
    conversion on the default framebuffer (eg: back bufffer) due to the lack of
    glEnable(GL_FRAMEBUFFER_SRGB) toogle.

    As a result, an application needs to render into a sRGB framebuffer object
    that support sRGB update and blending and then execute a shader simply to
    copy the sRGB frmaebuffer object to the default framebuffer.

    This extension allows to explicitly set the default framebuffer colorspace
    to automatically performa the sRGB conversion without an intermediate
    framebufer object.

 2) What's the default colorspace of the default framebuffer with OpenGL and
    OpenGL ES?

    With OpenGL ES (WGL_CONTEXT_ES_PROFILE_BIT_EXT)
    the default colorspace is WGL_COLORSPACE_LINEAR_EXT

    With OpenGL (WGL_CONTEXT_CORE_PROFILE_BIT_ARB or
    WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB), the default colorspace
    is WGL_COLORSPACE_SRGB_EXT for WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT
    pixel formats and WGL_COLORSPACE_LINEAR_EXT otherwise.

    RESOLVED

 3) Does all the context support sRGB?

    This extension requires OpenGL 3.0, OpenGL ES 3.0 or GL_EXT_sRGB.

    RESOLVED: Yes.

 4) Does we want to support more colorspace than sRGB?

    The field of color spaces is very vivid these days for good reasons
    but new color space in OpenGL is not the purpose of this extension.

    https://developer.nvidia.com/sites/default/files/akamai/gameworks/hdr/UHDColorForGames.pdf

    RESOLVED: Not in this extension, deferred.

 5) What's the interaction with glEnable(GL_FRAMEBUFFER_SRGB) defined in
    GL_ARB_framebuffer_sRGB and GL_EXT_sRGB_write_control?

    RESOLVED:
    - According the the specifications "If the value of
    FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is not SRGB, or FRAMEBUFFER_SRGB is
    disabled, no linearization is performed."

    - Accoding to WGL_EXT_framebuffer_sRGB "if FRAMEBUFFER_SRGB_EXT is enabled
    and the boolean FRAMEBUFFER_SRGB_CAPABLE_EXT state for the drawable is true,
    the R, G, and B destination color values (after conversion from fixed-point to
    floating-point) are considered to be encoded for the sRGB color space"

 6) What's the default colorspace in the pixel formats list?

    Default values in the pixel formats list are expressed by listing first a
    pixel format realying on this value. The default value is
    WGL_COLORSPACE_LINEAR_EXT.

 7) How this extension is externally visible?

    The following speudo code express how this extension interacts with others features:

    if Default Framebuffer
    {
         if OpenGL
             IF EnableSRGB && (sRGBCapable || sRGBColorspace) THEN perform framebuffer sRGB conversions.
         else if OpenGL ES
             IF sRGBColorspace THEN perform framebuffer sRGB conversions.
    }
    else
    {
         if OpenGL
             IF EnableSRGB && FormatSRGB THEN perform framebuffer sRGB conversions.
         else if OpenGL ES
             IF FormatSRGB THEN perform framebuffer sRGB conversions.
    }

    Additionnally, this extension add a number of new pixel formats for
    WGL_COLORSPACE_LINEAR_EXT and WGL_COLORSPACE_SRGB_EXT which pixel formats
    variation relying WGL_COLORSPACE_LINEAR_EXT are listed first.

Revision History

    2016-11-30 - criccio
      + Clarify default pixel formats
      + Add issue 6 and 7
      + Clarify issue 5

    2016-08-30 - criccio
      + Add issue 5

    2016-07-14 - criccio
      + Initial draft based on EGL_KHR_gl_colorspace

