阅读GetDC / ReleaseDC我应该总是看到后者,并且窗口上的CS_OWNDC被认为是邪恶的:
https://blogs.msdn.microsoft.com/oldnewthing/20060601-06/?p=31003
查看我的代码,我看到我抓住从GetDC检索到的DC,我已将其发送到wglCreateContextAttribARB。我假设在DC上创建了上下文,因此随后从驱动程序中释放它将是不礼貌的。我的假设是否正确?目前,当我销毁其他OpenGL资源时,我正在调用ReleaseDC。
此外,在我的库的其他地方,我调用GetDC来实例化一个GDI + Graphics对象,然后在我完成绘制时再次释放它。我认为出于性能原因在绘制调用之间保留DC和Graphics对象会很好,只能在WM_DISPLAYCHANGE等上重新创建它。
那么,是否有关于该领域最佳实践的权威指南?我努力释放GDI + DC但坚持OpenGL DC的方式似乎有些不一致。
答案 0 :(得分:2)
OpenGL和GDI +表现不同。
在OpenGL中,您需要一个带有DC
附加的上下文。这意味着在上下文存在时DC
必须存在。因此,对于OpenGL绘制的窗口,您需要CS_OWNDC
样式。
删除上下文后调用ReleaseDC
。
在MS Windows中使用GDI +就像任何常见的DC
一样:检索DC,绘制它,释放该DC。在这个场景中,CS_OWNDC
的使用可能是邪恶的,正如你发布的link所指出的那样。
MS GDI +使用图形硬件的方式(即创建上下文或其他)对你来说无关紧要。
编辑由于Chris Becke的评论:
不需要使用CS_OWNDC
引用https://msdn.microsoft.com/es-es/library/windows/desktop/dd374387(v=vs.85).aspx:
hdc参数必须引用OpenGL支持的绘图表面。 它不一定是传递给wglCreateContext的hdc hglrc已创建,但它必须位于同一设备上且具有相同的功能 像素格式。
建议使用CS_OWNDC。
在Windows 9x的旧时代,获取和发布设备上下文既昂贵又缓慢。拥有固定直流更有效率。在窗口注册时使用CS_OWNDC
标志是获得固定直流的方法。
CS_OWNDC
用法提供私有设备上下文(请参阅https://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx#class_styles)。
引用MS文档(https://msdn.microsoft.com/en-us/library/windows/desktop/dd162872(v=vs.85).aspx):
尽管私有设备上下文使用起来很方便,但确实如此 系统资源方面的内存密集型,需要800或更多 要存储的字节数。建议使用私有设备上下文 性能考虑超过存储成本。
您必须意识到必须避免ReleaseDC
私有设备上下文:
应用程序可以检索私有设备上下文的句柄 在创建窗口后的任何时候使用GetDC功能。该 应用程序必须只检索一次句柄。此后,它可以 保持和使用句柄任意次。因为是私人设备 上下文不是显示设备上下文缓存的一部分 应用程序需要永远不会通过使用 ReleaseDC功能。
在通过检索DC
绘制到一个独特窗口的常见场景中,设置curent上下文,绘制,交换缓冲区并释放DC
的用法CS_OWNDC而不是GetDC& ReleaseDC是很自然的。
也可能是使用wglGetCurrentDC()
(例如由extern库)而不管您的GetDC / ReleaseDC代码的情况。通常不会发生任何问题。但是如果当前的gl-context为NULL(就像在ReleaseDC之后那样),那么wglGetCurrentDC()
将会失败。
没有CS_OWNDC的代码 用于两个窗口具有相同的像素格式将如下所示:
myGLContext = wglCreateContext(...)
//Draw to window A
HDC hdcA = GetDC(hWndA)
wglMakeCurrent(hdcA, myGLContext)
... render...
SwapBuffers(hdcA)
ReleaseDC(hWndA, hdcA)
//Draw to window B
HDC hdcB = GetDC(hWndB)
wglMakeCurrent(hdcB, myGLContext)
... render...
SwapBuffers(hdcB)
ReleaseDC(hWndA, hdcA)
wglMakeCurrent(hdcB, NULL)