枚举设备,并获取其上下文

时间:2010-01-04 09:26:32

标签: windows opengl

开发OpenGL应用程序,我创建一个窗口,使用GetDC获取关联的设备上下文,并在GetDC返回的设备上下文句柄上创建OpenGL上下文。一切都好。 在创建OpenGL上下文之前,我将调用SetPixelFormat。文档说SetPixelFormat只能被调用一次(我认为每个设备上下文句柄一次)。

好。对于只有一个设备的系统来说,它非常简单,但是有两个或更多设备的系统呢?这怎么可行?

首先,我不知道创建的窗口如何与设备上下文相关联。我想要枚举系统中的每个可用设备,查询每个设备的每个像素格式,然后在设置每个设备上下文后创建窗口。在这种情况下,我不必担心设备像素格式,我可以设置多个设备以获得兼容的像素格式(用于在OpenGL上下文之间共享对象)。

是否可以枚举可用的视频设备?我没有找到任何用于枚举图形设备的Windows API来获取GetDC返回的相同句柄... 可以将窗口与特定的视频设备上下文相关联吗?

1 个答案:

答案 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;