2013-10-12 67 views
0

所有教程都向您展示了如何创建OpenGL上下文来覆盖窗口的整个空间。更改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); 

没有显示出来的空间,但应该有一个红色的框,因为这是我在我的鲜明的色彩设置。

+1

当你理解Win32中设备上下文句柄的真正含义时,你会明白为什么这没有多大意义。它是窗口客户区域(默认情况下)定义的可绘制曲面(借用D3D /现代Windows DWM术语)的句柄。调整与其关联的窗口的大小时,表面会自动调整大小,但没有办法解决这个问题。你确实有一种解决这个问题的方法,就是使用'GetDCEx(...)'并定义一个作为客户矩形一部分的剪辑区域。但是,更好的解决方案只是重新定义视口。 –

+1

请注意,当我说“窗口”时,我不会将讨论局限于应用程序窗口。任何具有HWND的事物都有一个与它关联的DC,因此,如果需要,您可以创建一个子窗口,它是应用程序窗口的一部分,并使用DC作为此窗口;这是如何绘制到OpenGL控件/小部件在MFC,Qt等框架中的作品。 –

+0

我对我的文章做了一个小的编辑。我希望现在更清楚,OpenGL窗口应该在的位置(应用程序窗口右下角的0,192)不包含任何内容,但它应该是黑色的,不是? – Jimmay

回答

3

,这里是在错误的顺序:

glClear(GL_COLOR_BUFFER_BIT); 

SwapBuffers(hdc); 

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

UpdateWindow(hwnd); 
UpdateWindow(openGLHwnd); 

当你做出这些OpenGL调用窗口是不可见,也就是说它没有可用的帧缓冲空间,所以你所有的绘图调用都会进入涅v。此外,UpdateWindow调用告诉Windows,该窗口的内容很脏,Windows应放弃其内容,并在Windows的下一个完整重绘迭代循环中发送WM_PAINT事件。

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

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

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

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