0

所有教程都向您展示了如何创建 OpenGL 上下文以覆盖整个窗口空间。

例如,使用树视图,您可以这样做:

HWND treeViewHwnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, 0, WS_CHILD | WS_VISIBLE, 0, 0, 192, rc.bottom, hwnd, NULL, hInstance, NULL);

创建占据屏幕一部分的树视图(192 宽)。

但是对于 OpenGL,我似乎无法创建从 192,0 到应用程序窗口右下角的上下文。这是代码:

HWND openGLHwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "openGLHwnd", 0, CS_OWNDC | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE, 192, 0, rc.right, rc.bottom, hwnd, NULL, hInstance, NULL);

HDC hdc;
HGLRC hrc;

PIXELFORMATDESCRIPTOR pfd;
int format;

hdc = GetDC(openGLHwnd);

memset(&pfd, '\0', sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, format, &pfd);

hrc = wglCreateContext(hdc);
if(hrc == NULL) return 0;
if(wglMakeCurrent(hdc, hrc) == FALSE) return 0;

glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_COLOR_MATERIAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_NORMALIZE);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, rc.right, rc.bottom);
gluPerspective(45.0f, (GLfloat)rc.right / (GLfloat)rc.bottom, 0.1f, 1024.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);

glClear(GL_COLOR_BUFFER_BIT);

SwapBuffers(hdc);

ShowWindow(hwnd, nCmdShow);
ShowWindow(openGLHwnd, SW_SHOW);

UpdateWindow(hwnd);
UpdateWindow(openGLHwnd);

空间中什么都没有显示,尽管应该有一个红色框,因为这是我设置的清晰颜色。

4

2 回答 2

3

这是错误的顺序:

glClear(GL_COLOR_BUFFER_BIT);

SwapBuffers(hdc);

ShowWindow(hwnd, nCmdShow);
ShowWindow(openGLHwnd, SW_SHOW);

UpdateWindow(hwnd);
UpdateWindow(openGLHwnd);

当您进行这些 OpenGL 调用时,Window 是不可见的,即它没有可用的帧缓冲区空间进行绘制,因此您的所有绘图调用都进入了必杀技。这些UpdateWindow调用还告诉 Windows,Window 的内容是脏的,Windows 应该丢弃它们的内容,并在 Windows 的下一个完整重绘迭代循环中发送 WM_PAINT 事件。

正确的顺序是在进行任何 OpenGL 绘图调用之前显示窗口。但是您根本不应该在窗口创建代码中进行任何绘图调用。

此外glViewport,您的调用参数与窗口的大小不匹配。它在宽度方向上大了 192 像素。没问题,因为视口只定义了坐标映射。但这绝对不是您可能想要的。

最后但同样重要的是,确保 OpenGL 窗口的类样式CS_OWNDC设置了标志。顺便说一句:你在哪里为你的 OpenGL 窗口创建窗口类?我没有看到代码。

于 2013-10-12T11:31:07.540 回答
2

好的,所以我们只能获得评论。是时候坐下来写一个草稿答案了……

第二个参数CreateWindowEx (...)是窗口类的名称,实际上我没有看到您在代码的任何地方创建它。为此,您需要进行如下调用:

WNDCLASS wc;

wc.style         = CS_OWNDC;
wc.lpfnWndProc   = GlobalWndProc; // No idea what you call this in your app
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = GetModuleHandle (NULL);
wc.hIcon         = LoadIcon        (NULL, IDI_WINLOGO);
wc.hCursor       = NULL;
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName  = NULL;
wc.lpszClassName = "openGLHwnd";

RegisterClass (&wc);

就目前而言,CreateWindowEx (...)应该会失败,因为您试图为其分配一个从未注册过的窗口类名称。

完成后,您可以调用:

HWND openGLHwnd = CreateWindowEx (WS_EX_CLIENTEDGE, "openGLHwnd", 0,
                                  (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD |
                                   WS_VISIBLE),
                                  192,       0,
                                  rc.right,  rc.bottom,
                                  hwnd,      NULL,
                                  hInstance, NULL);
于 2013-10-12T11:28:13.140 回答