GetDC、ReleaseDC、CS_OWNDC 与 OpenGL 和 Gdi+
GetDC, ReleaseDC, CS_OWNDC with OpenGL and Gdi+
阅读有关 GetDC/ReleaseDC 我应该总是做后者,并且 window 上的 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的方式似乎有些不一致。
OpenGL 和 GDI+ 的行为不同。
在 OpenGL 中,您需要一个上下文,它附加 DC
。这意味着当上下文存在时 DC
必须 存在。因此,对于 OpenGL 绘制的 window,您确实需要 CS_OWNDC
样式。
删除上下文后调用 ReleaseDC
。
GDI+ 在 MS Windows 中的使用与任何常见的一样 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:
The hdc parameter must refer to a drawing surface supported by OpenGL.
It need not be the same hdc that was passed to wglCreateContext when
hglrc was created, but it must be on the same device and have the same
pixel format.
推荐CS_OWNDC用法。
在过去 Windows 9x 获取和释放设备上下文既昂贵又缓慢。有一个 fixed dc 会更有效率。在 window 注册时使用 CS_OWNDC
标志是获得 固定 dc.
的方法
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):
Although a private device context is convenient to use, it is
memory-intensive in terms of system resources, requiring 800 or more
bytes to store. Private device contexts are recommended when
performance considerations outweigh storage costs.
你必须知道你必须避免ReleaseDC
使用私有设备上下文:
An application can retrieve a handle to the private device context by
using the GetDC function any time after the window is created. The
application must retrieve the handle only once. Thereafter, it can
keep and use the handle any number of times. Because a private device
context is not part of the display device context cache, an
application need never release the device context by using the
ReleaseDC function.
在您通过检索 DC
、设置当前上下文、绘制、交换缓冲区并释放 [=11= 来绘制到唯一 window 的常见场景中] 使用 CS_OWNDC 代替 GetDC&ReleaseDC 是很自然的。
无论您的 GetDC/ReleaseDC 代码如何,都可能会出现使用 wglGetCurrentDC()
的情况(例如,通过外部库)。通常不会发生任何问题。但是,如果当前的 gl-context 为 NULL(就像您在 ReleaseDC 之后所做的那样),那么 wglGetCurrentDC()
将失败。
无代码CS_OWNDC
用于两个具有相同像素格式的 windows 将如下所示:
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)
阅读有关 GetDC/ReleaseDC 我应该总是做后者,并且 window 上的 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的方式似乎有些不一致。
OpenGL 和 GDI+ 的行为不同。
在 OpenGL 中,您需要一个上下文,它附加 DC
。这意味着当上下文存在时 DC
必须 存在。因此,对于 OpenGL 绘制的 window,您确实需要 CS_OWNDC
样式。
删除上下文后调用 ReleaseDC
。
GDI+ 在 MS Windows 中的使用与任何常见的一样 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:
The hdc parameter must refer to a drawing surface supported by OpenGL. It need not be the same hdc that was passed to wglCreateContext when hglrc was created, but it must be on the same device and have the same pixel format.
推荐CS_OWNDC用法。
在过去 Windows 9x 获取和释放设备上下文既昂贵又缓慢。有一个 fixed dc 会更有效率。在 window 注册时使用 CS_OWNDC
标志是获得 固定 dc.
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):
Although a private device context is convenient to use, it is memory-intensive in terms of system resources, requiring 800 or more bytes to store. Private device contexts are recommended when performance considerations outweigh storage costs.
你必须知道你必须避免ReleaseDC
使用私有设备上下文:
An application can retrieve a handle to the private device context by using the GetDC function any time after the window is created. The application must retrieve the handle only once. Thereafter, it can keep and use the handle any number of times. Because a private device context is not part of the display device context cache, an application need never release the device context by using the ReleaseDC function.
在您通过检索 DC
、设置当前上下文、绘制、交换缓冲区并释放 [=11= 来绘制到唯一 window 的常见场景中] 使用 CS_OWNDC 代替 GetDC&ReleaseDC 是很自然的。
无论您的 GetDC/ReleaseDC 代码如何,都可能会出现使用 wglGetCurrentDC()
的情况(例如,通过外部库)。通常不会发生任何问题。但是,如果当前的 gl-context 为 NULL(就像您在 ReleaseDC 之后所做的那样),那么 wglGetCurrentDC()
将失败。
无代码CS_OWNDC
用于两个具有相同像素格式的 windows 将如下所示:
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)