所有教程都向您展示如何创建一个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);
空间中没有任何东西显示,但应该有一个红色的盒子,因为这是我设置我的清晰颜色。
答案 0 :(得分:3)
这是错误的顺序:
glClear(GL_COLOR_BUFFER_BIT); SwapBuffers(hdc); ShowWindow(hwnd, nCmdShow); ShowWindow(openGLHwnd, SW_SHOW); UpdateWindow(hwnd); UpdateWindow(openGLHwnd);
当你进行那些OpenGL调用时,Window是不可见的,即它没有可供绘制的帧缓冲空间,所以你的所有绘图调用都进入了必杀技。此外,UpdateWindow
调用告诉Windows,窗口的内容是脏的,Windows应该丢弃它们的内容并在Windows的下一个完整重绘迭代循环中发送WM_PAINT事件。
正确的顺序是在进行任何OpenGL绘图调用之前显示窗口。 但您不应该在窗口创建代码中执行任何绘图调用。
此外,您的glViewport
来电参数与窗口大小不符。它在宽度方向上的宽度大192像素。没问题,因为视口只定义了坐标映射。但这绝对不是你想要的。
最后但同样重要的是,确保OpenGL窗口的类样式设置了CS_OWNDC
标志。顺便说一句:你在哪里为OpenGL窗口创建Window类?我没有看到代码。
答案 1 :(得分: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);