如何使用 Windows 内存 dc (c++) 创建 OpenGL 上下文
how can I create OpenGL context using Windows memory dc (c++)
在我的 Windows MFC 应用程序的视图中 class 我使用视图的 DC 创建了一个 OpenGL 上下文:
HANDLE * hdc = GetDC()->m_hdc;
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to window (not bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls
PFD_DOUBLEBUFFER, // Double -buffered mode
PFD_TYPE_RGBA, // RGBA Color mode
24, // Want 24bit color
0,0,0,0,0,0, // Not used to select mode
0,0, // Not used to select mode
0,0,0,0,0, // Not used to select mode
32, // Size of depth buffer
0, // Not used to select mode
0, // Not used to select mode
PFD_MAIN_PLANE, // Draw in main plane
0, // Not used to select mode
0,0,0 }; // Not used to select mode
// Choose a pixel format that best matches that described in pfd
nPixelFormat = ChoosePixelFormat(hdC, &pfd);
// Set the pixel format for the device context
assert(SetPixelFormat(hdC, nPixelFormat, &pfd));
HGLRC m_hrc = wglCreateContext(hdc);
assert(m_hrc);
wglMakeCurrent(m_hdc,m_hrc);
上面的所有代码都可以正常工作,我可以按预期进行 OpenGL 绘图。
但是,我现在需要的是将DC改为内存dc,而不是window DC。确切地说,我如何使用下面的 'hmemDC' 创建一个 OpenGL 上下文,就像我上面使用 window DC:
所做的那样
CRect rct;
GetClientRect(&rct);
HDC hmemDC = CreateCompatibleDC(pDC->m_hDC);
HBITMAP hBmp = CreateCompatibleBitmap(pDC->m_hDC,rct.Width(),rct.Height());
使用上面构造的相同像素格式,我在调用 wglCreateContext() 时遇到 "Invalid pixel format" 错误,无法成功获得正确的 OpenGL 上下文。
我谷歌了很多,并尝试更改像素格式的一些值,结果是一样的。
是否可以使用 Windows 内存 DC 创建 OpenGL 上下文?如果是我应该怎么做?
编辑:
这就是我需要位图(或内存 DC)的原因:我创建了一个使用 OpenGL 的二维地图渲染库。客户想用这个库来渲染背景图,并在上面绘制自己的符号。但是,他们更喜欢使用 Windows GDI 而不是 OpenGL 来绘制符号。所以我想如果我能为他们提供位图或 Mmeory DC,他们就可以随心所欲。有更好的解决方案吗?我的方向正确吗?或者在 OpenGL 后端提供这样的 2d 库是一个完全糟糕的主意。
这无法以有用的方式完成。
您 可以 原则上通过使用 PFD_DRAW_TO_BITMAP
标志而不是 PIXELFORMATDESCRIPTOR 中的 PFD_DRAW_TO_WINDOW
来呈现位图。
但是,这样做会禁用所有硬件加速渲染。这将回退到 Microsoft 的默认 OpenGL 1.1 实现。
如果你想要硬件加速 and/or 现代 GL,你要么需要一个 window 或一些像 pbuffer 这样的屏幕外缓冲区,它可以通过 WGL_ARB_pbuffer extension. However, in modern GL, you are probably better off creating a window which is just never shown, and using a Frambeuffer Object 作为屏幕外渲染获得目标。
在任何一种情况下,您都必须将数据复制回 CPU,如果您在那里需要它作为一些位图。
简而言之:您不能为 MemDC 创建任意的 OpenGL 上下文。至少没有您真正想要使用的 OpenGL 上下文。
如果您的目标是离屏渲染,要么创建一个 PBuffer-DC;这需要首先创建一个 OpenGL 上下文,然后需要创建一个 window 并设置其像素格式。或者您可以只为它创建一个 window 和一个 OpenGL 上下文并使用帧缓冲区对象。
在我的 Windows MFC 应用程序的视图中 class 我使用视图的 DC 创建了一个 OpenGL 上下文:
HANDLE * hdc = GetDC()->m_hdc;
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to window (not bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls
PFD_DOUBLEBUFFER, // Double -buffered mode
PFD_TYPE_RGBA, // RGBA Color mode
24, // Want 24bit color
0,0,0,0,0,0, // Not used to select mode
0,0, // Not used to select mode
0,0,0,0,0, // Not used to select mode
32, // Size of depth buffer
0, // Not used to select mode
0, // Not used to select mode
PFD_MAIN_PLANE, // Draw in main plane
0, // Not used to select mode
0,0,0 }; // Not used to select mode
// Choose a pixel format that best matches that described in pfd
nPixelFormat = ChoosePixelFormat(hdC, &pfd);
// Set the pixel format for the device context
assert(SetPixelFormat(hdC, nPixelFormat, &pfd));
HGLRC m_hrc = wglCreateContext(hdc);
assert(m_hrc);
wglMakeCurrent(m_hdc,m_hrc);
上面的所有代码都可以正常工作,我可以按预期进行 OpenGL 绘图。
但是,我现在需要的是将DC改为内存dc,而不是window DC。确切地说,我如何使用下面的 'hmemDC' 创建一个 OpenGL 上下文,就像我上面使用 window DC:
所做的那样CRect rct;
GetClientRect(&rct);
HDC hmemDC = CreateCompatibleDC(pDC->m_hDC);
HBITMAP hBmp = CreateCompatibleBitmap(pDC->m_hDC,rct.Width(),rct.Height());
使用上面构造的相同像素格式,我在调用 wglCreateContext() 时遇到 "Invalid pixel format" 错误,无法成功获得正确的 OpenGL 上下文。
我谷歌了很多,并尝试更改像素格式的一些值,结果是一样的。
是否可以使用 Windows 内存 DC 创建 OpenGL 上下文?如果是我应该怎么做?
编辑: 这就是我需要位图(或内存 DC)的原因:我创建了一个使用 OpenGL 的二维地图渲染库。客户想用这个库来渲染背景图,并在上面绘制自己的符号。但是,他们更喜欢使用 Windows GDI 而不是 OpenGL 来绘制符号。所以我想如果我能为他们提供位图或 Mmeory DC,他们就可以随心所欲。有更好的解决方案吗?我的方向正确吗?或者在 OpenGL 后端提供这样的 2d 库是一个完全糟糕的主意。
这无法以有用的方式完成。
您 可以 原则上通过使用 PFD_DRAW_TO_BITMAP
标志而不是 PIXELFORMATDESCRIPTOR 中的 PFD_DRAW_TO_WINDOW
来呈现位图。
但是,这样做会禁用所有硬件加速渲染。这将回退到 Microsoft 的默认 OpenGL 1.1 实现。
如果你想要硬件加速 and/or 现代 GL,你要么需要一个 window 或一些像 pbuffer 这样的屏幕外缓冲区,它可以通过 WGL_ARB_pbuffer extension. However, in modern GL, you are probably better off creating a window which is just never shown, and using a Frambeuffer Object 作为屏幕外渲染获得目标。
在任何一种情况下,您都必须将数据复制回 CPU,如果您在那里需要它作为一些位图。
简而言之:您不能为 MemDC 创建任意的 OpenGL 上下文。至少没有您真正想要使用的 OpenGL 上下文。
如果您的目标是离屏渲染,要么创建一个 PBuffer-DC;这需要首先创建一个 OpenGL 上下文,然后需要创建一个 window 并设置其像素格式。或者您可以只为它创建一个 window 和一个 OpenGL 上下文并使用帧缓冲区对象。