Nowhere-01
Nowhere-01

Reputation: 322

wglCreateContextAttribsARB crashes in debug mode, under x64 platform

i have encountered an issue trying to debug my 64 bit application under Visual Studio 2015. When i switch it to debug mode, it crashes during window creation. Which did not happen in 32 bit mode;

Here's redacted window initialization code:

int indexPF;
WNDCLASS WinClass;

WinClass.style = CS_OWNDC | CS_PARENTDC;
WinClass.lpfnWndProc = WndProc;
WinClass.cbClsExtra = 0;
WinClass.cbWndExtra = 0;
WinClass.hInstance = hInstance;
WinClass.hIcon = LoadIcon(NULL, IDC_ICON);
WinClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WinClass.hbrBackground = (HBRUSH)GetStockObject(5);
WinClass.lpszMenuName = NULL;
WinClass.lpszClassName = "N2";

if (!RegisterClass(&WinClass))
{
    ...report error and terminate...
}

Logger::Inst() << " ~RegisterClass;" << endl;

//CREATE WINDOW

if (fullScreen)
{
    if ((hwnd = CreateWindowEx(WS_EX_LEFT, "N2", "N2",
        WS_POPUP,
        0, 0, width, height,
        NULL, NULL, hInstance, NULL)) == 0)
    {
        ...report error and terminate...
    }
}
else
{
    if ((hwnd = CreateWindowEx(WS_EX_LEFT, "N2", "N2",
        WS_OVERLAPPEDWINDOW,
        0, 0, width, height,
        NULL, NULL, hInstance, NULL)) == 0)
    {
        ...report error and terminate...
    }
}

Logger::Inst() << " ~CreateWindow;" << endl;

//PFD SETUP
PIXELFORMATDESCRIPTOR pfd =
{
    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,
    24,
    8, 0, PFD_MAIN_PLANE, 0, 0, 0x00FF00FF, 0
};

//HDC
if ((hdc = GetDC(hwnd)) == NULL)
{
    ...report error and terminate...
}

Logger::Inst() << " ~GotHDC;" << endl;

//SET PIXEL FORMAT
indexPF = ChoosePixelFormat(hdc, &pfd);
if (!indexPF)
{
    ...report error and terminate...
}

if (!SetPixelFormat(hdc, indexPF, &pfd))
{
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE;
    indexPF = ChoosePixelFormat(hdc, &pfd);

    if (!SetPixelFormat(hdc, indexPF, &pfd))
    {
        ...report error and terminate...
    }
}

Logger::Inst() << " ~SetPFD;" << endl;

//TEMP CONTEXT TO ACQUIRE POINTER
HGLRC tempContext = wglCreateContext(hdc);

if (!tempContext) {
    ...report error and terminate...
}

if (!wglMakeCurrent(hdc, tempContext)) {
    ...report error and terminate...
}

int major, minor; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor);
if (major < 4 || minor < 1) {
    ...report error and terminate...
}

const int attribs[] =
{
    WGL_CONTEXT_MAJOR_VERSION_ARB, major,
    WGL_CONTEXT_MINOR_VERSION_ARB, minor,
    WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
    0, 0
};

PFNWGLCREATEBUFFERREGIONARBPROC wglCreateContextAttribsARB = (PFNWGLCREATEBUFFERREGIONARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
if (!wglCreateContextAttribsARB) {
    ...report error and terminate...
}

**!!! CRASH HERE !!!**
if (!(hglrc = (HGLRC)wglCreateContextAttribsARB(hdc, 0, (UINT)attribs))) {
    ...report error and terminate...
}

Debugger shows it happens exactly at wglCreateContextAttribsARB(nvoglv64.dll!0000000074ccbdfa). That is a complete mystery to me. My only clue is that after switching to x64 it requires attributes passed as "UINT" instead of "const int*", i don't get that part, not even sure how conversion between each other supposed to work, seems fishy. Ideas?

Upvotes: 2

Views: 341

Answers (1)

Sam
Sam

Reputation: 3490

You've got a typo: the type for wglCreateContextAttribsARB is wrong. It should be PFNWGLCREATECONTEXTATTRIBSARBPROC.

The reason it worked when you were targeting 32-bit is because the signature of the two is essentially the same in 32-bit:

wglCreateContextAttribsARB:

typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);

wglCreateBufferRegionARB:

typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);

The second and third parameters to wglCreateContextAttribsARB are pointers (an HGLRC is a handle, which is just a pointer) and the second and third parameters to wglCreateBufferRegionARB are integers. In 32-bit, pointers are 32-bit in size, so the signatures are essentially the same.

In 64-bit, pointers are 64-bit in size, but integers are still 32-bit (assuming you're using MSVC) so those two pointers you were passing in were being truncated.

Upvotes: 4

Related Questions