这有点与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()会失败,但我不是确实在这种情况下哪一个是真的。
答案 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。