fieldtensor
fieldtensor

Reputation: 4050

wglCreateContextAttribsARB() gives me 4.4 when I ask for 2.0

On my machine when I call wglCreateContextAttribsARB() asking for a 2.0 context, I get back 2.1.2.

That seems seems close enough to correct, so it doesn't worry me. Yet, the same exact code when called on a friend's machine gives a 4.4 context. Does that make sense, or should I be looking for a bug somewhere? The code is given below. GKGLLoader and GKGLContext modules are ones that I wrote myself, and you'll probably be able to figure out how they work just by looking at their usage, so I won't post their source files (unless someone thinks it might be relevant).

#include <GraphicsKit/GKGLLoader.h>
#include <GraphicsKit/GKGLContext.h>

static
LRESULT CALLBACK DemoWindowProc(
    HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
{
    if( msg == WM_CLOSE )
    {
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(win, msg, wparam, lparam);
}

ATOM
RegisterDemoWindowClass(void)
{
    WNDCLASSEX cls;

    cls.cbSize = sizeof(cls);
    cls.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    cls.lpfnWndProc = DemoWindowProc;
    cls.cbClsExtra = 0;
    cls.cbWndExtra = 0;
    cls.hInstance = GetCurrentProcess();
    cls.hIcon = NULL;
    cls.hCursor = LoadCursor(NULL, IDC_ARROW);
    cls.hbrBackground = GetStockObject(BLACK_BRUSH);
    cls.lpszMenuName = NULL;
    cls.lpszClassName = L"GraphicsDemo";
    cls.hIconSm = NULL;

    return RegisterClassEx(&cls);
}

HWND
CreateDemoWindow(void)
{
    HWND win;

    win = CreateWindowEx(
        WS_EX_APPWINDOW | WS_EX_OVERLAPPEDWINDOW,
        L"GraphicsDemo",
        L"GraphicsDemo",
        WS_TILEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 500,
        NULL, NULL, GetCurrentProcess(), NULL
    );

    return win;
}

BOOL
ChooseDemoPixelFormat(HWND win, int* formatID)
{
    unsigned numFormats;

    int attribList[] =
    {
        WGL_DRAW_TO_WINDOW_ARB, TRUE,
        WGL_SUPPORT_OPENGL_ARB, TRUE,
        WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
        WGL_DOUBLE_BUFFER_ARB, TRUE,
        WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB,
        WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
        WGL_COLOR_BITS_ARB, 24,
        WGL_RED_BITS_ARB, 8,
        WGL_GREEN_BITS_ARB, 8,
        WGL_BLUE_BITS_ARB, 8,
        WGL_ALPHA_BITS_ARB, 8,
        0, 0
    };

    if(wglChoosePixelFormatARB(
        GetDC(win), attribList, NULL, 1, formatID, &numFormats))
    {
        if( numFormats == 0 )
        {
            _cprintf(
                "wglChoosePixelFormatARB() returned no "
                "formats [GetLastError(): (0x%X)]\n",
                (unsigned)GetLastError());

            SetLastError(ERROR_NOT_SUPPORTED);

            return FALSE;
        }

        return TRUE;
    }

    return FALSE;
}

HGLRC
CreateDemoContext(HWND win)
{
    int attribList[] = {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 2,
        WGL_CONTEXT_MINOR_VERSION_ARB, 0,
        0
    };

    return wglCreateContextAttribsARB(GetDC(win), NULL, attribList);
}

int
APIENTRY
WinMain(
    HINSTANCE instance,
    HINSTANCE prevInstance,
    LPSTR cmdline,
    int showCmd)
{
    GKGLContext* dummyCtx;
    GKGLLoader* loader;

    MSG msg;

    GKGLContext* ctx;
    HWND win;
    HGLRC glrc;

    PIXELFORMATDESCRIPTOR pfd;
    int formatID;

    AllocConsole();

    if( ! RegisterDemoWindowClass() )
    {
        MessageBox(
            NULL, L"RegisterDemoWindowClass() failed", L"ERROR", MB_OK);
        return 0;
    }

    win = CreateDemoWindow();
    if( win == NULL )
    {
        MessageBox(
            NULL, L"CreateDemoWindow() failed", L"ERROR", MB_OK);
        return 0;
    }

    dummyCtx = GKGLContextNewDummy();
    if( dummyCtx == NULL )
    {
        MessageBox(NULL, L"GKGLDummyWindow() failed", L"ERROR", MB_OK);
        return 0;
    }

    loader = GKGLLoaderNew();
    GKGLSetContext(dummyCtx);
    #define GKGLProc(major, minor, name, ret, params, paramNames) dummyCtx->name = (void*)GKGLLoaderProcAddress(loader, # name, major, minor);
    #define GKGLVoidProc(major, minor, name, ret, params, paramNames) dummyCtx->name = (void*)GKGLLoaderProcAddress(loader, # name, major, minor);
    #include <GraphicsKit/GKGLProcs.h>
    #include <GraphicsKit/GKWGLProcs.h>
    #undef GKGLProc
    #undef GKGLVoidProc

    if( ! ChooseDemoPixelFormat(win, &formatID) )
    {
        MessageBox(
            NULL, L"ChooseDemoPixelFormat() failed", L"ERROR", MB_OK);
        return 0;
    }

    if( ! SetPixelFormat(GetDC(win), formatID, &pfd) )
    {
        MessageBox(
            NULL, L"SetPixelFormat() failed", L"ERROR", MB_OK);
        return 0;
    }

    glrc = CreateDemoContext(win);
    if( glrc == NULL )
    {
        MessageBox(
            NULL, L"CreateDemoContext() failed", L"ERROR", MB_OK);
        return 0;
    }

    GKGLSetContext(NULL);
    wglDeleteContext(dummyCtx->glrc);
    DestroyWindow(dummyCtx->win);

    ctx = GKGLContextNew(win, glrc);
    GKGLSetContext(ctx);
    #define GKGLProc(major, minor, name, ret, params, paramNames) ctx->name = (void*)GKGLLoaderProcAddress(loader, # name, major, minor);
    #define GKGLVoidProc(major, minor, name, ret, params, paramNames) ctx->name = (void*)GKGLLoaderProcAddress(loader, # name, major, minor);
    #include <GraphicsKit/GKGLProcs.h>
    #include <GraphicsKit/GKWGLProcs.h>
    #undef GKGLProc
    #undef GKGLVoidProc

    _cprintf("OpenGL Vendor:    %s\n", glGetString(GL_VENDOR));
    _cprintf("OpenGL Renderer:  %s\n", glGetString(GL_RENDERER));
    _cprintf("OpenGL Version:   %s\n", glGetString(GL_VERSION));
    _cprintf("OpenGL Shading Language: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));

    ShowWindow(win, showCmd);

    while( TRUE )
    {
        if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
        {
            if( msg.message == WM_QUIT )
                break;

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        glClearColor(0, 1, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        SwapBuffers(GetDC(win));
    }

    return msg.wParam;
}

Upvotes: 1

Views: 457

Answers (1)

derhass
derhass

Reputation: 45362

That is well within the spec, as long as that 4.4 context is a compatibility profile one. From the WGL_ARB_create_context extension spec:

If a version less than or equal to 3.0 is requested, the context returned may implement any of the following versions:

  • Any version no less than that requested and no greater than 3.0.
  • Version 3.1, if the GL_ARB_compatibility extension is also implemented.
  • The compatibility profile of version 3.2 or greater.

Upvotes: 4

Related Questions