没有打开窗口的OpenGL上下文 - 当使用GetDesktopWindow制作的HWND时,wglMakeCurrent因HDC和HGLRC而失败

时间:2009-04-03 16:32:09

标签: c++ windows opengl

这有点与this question重复。

我正在尝试创建一个无窗口控制台应用程序来检查支持的OpenGL版本。为了做到这一点,我需要设置渲染上下文 - 但不创建窗口。我正在尝试使用桌面句柄,我不会写。

我忘了在前面的例子中设置像素格式 - 这可能是为什么创建渲染上下文失败的原因 - 但即使设置了像素格式,我也无法激活它。 wglMakeCurrent(hDC,hRC)只返回0.

这是完整的源代码转储:

    #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;

}


编辑我知道如果传递给它的任何一个句柄无效,或者要成为当前的渲染上下文当前是另一个线程的当前状态,wglMakeCurrent()会失败,但我不是确实在这种情况下哪一个是真的。

2 个答案:

答案 0 :(得分:6)

不得在桌面窗口上创建OpenGL上下文。要创建OpenGL上下文,必须设置窗口的pixelformat,严格禁止在桌面窗口上完成。

如果要进行屏幕外渲染,请使用PBuffer而不是窗口,或者创建一个不可见的窗口,并使用帧缓冲对象(FBO)作为渲染目标。

答案 1 :(得分:2)

如果使用CreateWindow()而不是GetDesktopWindow(),它是否有效?

我会说GetDesktopWindow()极不可能工作。我希望这与普通窗口不同,并且您获得的值是特殊的句柄值。

如果push推进,只需打开一个没有WS_VISIBLE的窗口。没有人会更聪明。

P.S。我注意到你正在把它变成一个控制台应用程序。如果控制台应用程序可以处理任何图形化,无论是OpenGL还是Windows 2D绘图API,我都会感到非常惊讶。

P.s.s我非常确定Windows应用程序可以(以这种或那种方式)写入它们运行的​​命令行的标准输出。您可以简单地编写一个普通的Windows应用程序,但只是将输出发送到stdout。