开发OpenGL应用程序,我创建一个窗口,使用GetDC获取关联的设备上下文,并在GetDC返回的设备上下文句柄上创建OpenGL上下文。一切都好。 在创建OpenGL上下文之前,我将调用SetPixelFormat。文档说SetPixelFormat只能被调用一次(我认为每个设备上下文句柄一次)。
好。对于只有一个设备的系统来说,它非常简单,但是有两个或更多设备的系统呢?这怎么可行?
首先,我不知道创建的窗口如何与设备上下文相关联。我想要枚举系统中的每个可用设备,查询每个设备的每个像素格式,然后在设置每个设备上下文后创建窗口。在这种情况下,我不必担心设备像素格式,我可以设置多个设备以获得兼容的像素格式(用于在OpenGL上下文之间共享对象)。
是否可以枚举可用的视频设备?我没有找到任何用于枚举图形设备的Windows API来获取GetDC返回的相同句柄... 可以将窗口与特定的视频设备上下文相关联吗?
答案 0 :(得分:0)
设备上下文是相当动态的对象,在应用程序生命周期中创建和处理。 DC可以是显示DC(使用监视器API或CreateDC创建),窗口DC(从Window管理器DC缓存中检索使用GetDC api)和内存DC(使用CreateCompatibleDC创建)。
SetPixelFormat需要一个窗口DC。也就是说,它需要您要进行OpenGL渲染的窗口的窗口DC。您必须为您创建的每个窗口调用一次,并且只调用一次。
在你的框架Window :: OnCreate方法中,或在你的WM_CREATE处理程序中,或者当CreateWindow返回时,你会得到这样的代码:
HGLRC InitWindowForOpenGL(HWND hwnd)
{
HGLRC glctx;
PIXELFORMATDESCRIPTOR pfd = { /*initialization data*/ };
HDC hdc = GetDC(hwnd); // get a DC to use with OpenGL
int pf = ChoosePixelFormat(hdc,&pfd);
SetPixelFormat(hdc,pf,&pfd); //sets the pixel format of the associated window
glctx = wglCreateContext(hdc)
ReleaseDC(hdc,hwnd);
return glctx;
}
OpenGL为应用程序中的每个窗口维护一个单独的上下文。这意味着您需要将HGLRC与每个窗口对象一起存储(作为CWnd(或等效)派生类的成员),并确保在调用任何 OpenGL函数之前使适当的上下文成为当前的
网上的许多OpenGL示例代码只是将gl上下文存储在一个全局变量中,如果你想扩展到在多个窗口中使用OpenGL,这是非常有限的。如果你只使用一个窗口,那么在应用启动时简单地调用wglMakeCurrent并忘记它就可以了。
如果要支持多个OpenGL窗口,则需要在调用窗口的任何OpenGL代码之前设置上下文:
HDC SetGLContext(HWND hwnd, HGLRC hglrc, HDC hdc=NULL)
{
if(!hdc)
hdc = GetDC(hwnd);
wglMakeCurrent(hdc,hglrc);
return hdc;
}
void ResetGLContext(HWND hwnd, HDC hdc)
{
wglMakeCurrent(hdc,NULL);
if(hdc)
ReleaseDC(hwnd,hdc);
}
您的WindoProc可能包含以下条目:
HDC hdc;
case WM_PAINT:
hdc = BeginPaint(m_hwnd,&ps);
SetGLContext(m_hwnd,m_hglctx,hdc);
PaintOpenGLScene();
ResetGLContext(m_hwnd,NULL); // dont pass the DC as its owned by EndPaint
EndPaint(m_hwnd,&ps);
return 0;
case WM_TIMER:
hdc = SetGLContext(m_hwnd,m_hglctx,NULL);
DoOnIdleRendering();
ResetGLContext(m_hwnd,hdc);
return 0;