3

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.

Community
  • 1
  • 1
Keyframe
  • 1,390
  • 1
  • 14
  • 28
  • 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 Apr 03 '09 at 16:46
  • What's wrong with temporarily making a tiny window and then cleaning it up once you get your information? – Judge Maygarden Apr 03 '09 at 16:52
  • 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 Apr 03 '09 at 16:54
  • @monjardin I am making this in a console application where I would like to avoid spawning any window at all if possible. – Keyframe Apr 03 '09 at 17:03
  • Why does a console application have to know what the OpenGL version is? –  Apr 03 '09 at 17:11
  • @blank in this case mostly as an excercise - later on to render off screen buffer. I have an non real-time renderer which I would like to assist with OpenGL shadow maps and stuff like that. – Keyframe Apr 03 '09 at 17:46

2 Answers2

7

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.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
2

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.

  • Yes, it does work with CreateWindowEx which I'm using instead of non-Ex. That is what I'm doing now - I'm setting up everything as I should if I would to show up a window - only that I omit ShowWindow function. I would like to bypass all of that if possible - and it must be. – Keyframe Apr 03 '09 at 17:37