3
votes

This is somewhat a duplicate of this question.

I am trying to make a windowless console application to check up on OpenGL version supported. In order to do this I need to set up a render context - but without creating a window. I am trying to use desktop handle, which I won't write to.

I forgot to set pixel format in previous example - that is probable reason why creation of render context failed - however even with pixel format set, I cannot activate it. wglMakeCurrent(hDC, hRC) just returns 0.

Here is the complete source code dump:

    #include <iostream>
    #include <GL/GLee.h>

    #include <windows.h>

HDC hDC = NULL;
HGLRC hRC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance;

int res = 0;
int pf = 0;
PIXELFORMATDESCRIPTOR pfd = {
    sizeof(PIXELFORMATDESCRIPTOR),
    1,                     /* version */
    PFD_DRAW_TO_WINDOW |
    PFD_SUPPORT_OPENGL |
    PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,
    24,                    /* 24-bit color depth */
    0, 0, 0, 0, 0, 0,      /* color bits */
    0,                     /* alpha buffer */
    0,                     /* shift bit */
    0,                     /* accumulation buffer */
    0, 0, 0, 0,            /* accum bits */
    32,                    /* z-buffer */
    0,                     /* stencil buffer */
    0,                     /* auxiliary buffer */
    PFD_MAIN_PLANE,        /* main layer */
    0,                     /* reserved */
    0, 0, 0                /* layer masks */
};


std::string trash;

int main(int argc, char**argv) {

hInstance = GetModuleHandle(NULL);  // Grab An Instance For Our Window

hWnd = GetDesktopWindow();          // Instead of CreateWindowEx

if (!(hDC = GetDC(hWnd))) {
    std::cout << "Device context failed" << std::endl;

    std::cout << std::endl << "Press ENTER to exit" << std::endl;
    std::getline(std::cin, trash);
    return 1;
}

// pixel format
pf = ChoosePixelFormat(hDC, &pfd);
res = SetPixelFormat(hDC, pf, &pfd);

if (!(hRC = wglCreateContext(hDC))) {
    std::cout << "Render context failed" << std::endl;

    std::cout << std::endl << "Press ENTER to exit" << std::endl;
    std::getline(std::cin, trash);
    return 1;
}

if(!wglMakeCurrent(hDC,hRC)) { // fail: wglMakeCurrent returns 0
    std::cout << "Activating render context failed" << std::endl;

    std::cout << std::endl << "Press ENTER to exit" << std::endl;
    std::getline(std::cin, trash);
    return 1;
}

std::cout << "OpenGL 1.2 support ... ";
if (GLEE_VERSION_1_2) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 1.3 support ... ";
if (GLEE_VERSION_1_3) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 1.4 support ... ";
if (GLEE_VERSION_1_4) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 1.5 support ... ";
if (GLEE_VERSION_1_5) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 2.0 support ... ";
if (GLEE_VERSION_2_0) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 2.1 support ... ";
if (GLEE_VERSION_2_1) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 3.0 support ... ";
if (GLEE_VERSION_3_0) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << std::endl << "Press ENTER to exit" << std::endl;
std::getline(std::cin, trash);

// cleanup
wglMakeCurrent(NULL, NULL);     /* make our context not current */
wglDeleteContext(hRC);      /* delete the rendering context */
ReleaseDC(hWnd, hDC);               /* release handle to DC */

return 0;

}


edit: I know that wglMakeCurrent() fails if either of the handles passed to it is invalid or if the rendering context that is to become current is presently current for another thread, but I am not really sure which of these is true in this case.

2
how does your wglCreateContext call fail? Does it return 0? does it crash? something else? I added a comment in your code with this question as well. - jwfearn
What's wrong with temporarily making a tiny window and then cleaning it up once you get your information? - Judge Maygarden
yes, it fails with 0 - however, I forgot to set pixel format, now Activating render context fails with 0.. I'll update the question and code - may be my stupidity kicking in today after all. - Keyframe
@monjardin I am making this in a console application where I would like to avoid spawning any window at all if possible. - Keyframe
Why does a console application have to know what the OpenGL version is? - user82238

2 Answers

6
votes

One must not create a OpenGL context on the desktop window. To create a OpenGL context, one must set the windows's pixelformat, which is strictly forbidden to be done on the desktop window.

If you want to do offscreen rendering, use a PBuffer instead of a window, or create a window you don't make visible and use a Frame Buffer Object (FBO) as render target.

2
votes

Does it work if you use CreateWindow() rather than GetDesktopWindow()?

I would say GetDesktopWindow() is extremely unlikely to work. I would expect that to be unlike a normal window and the value you receive to be a special handle value.

If push comes to shove, just open a window without WS_VISIBLE. No one will be the wiser.

P.s. I note you're making this a console application. I will be quite surprised if console applications work with anything graphical, be it OpenGL or just the Windows 2D drawing API.

P.s.s I'm pretty sure Windows applications can write (one way or another) to the stdout of the command line they're run from. You could simply write a normal windows app, but just emit your output to stdout.