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

hgqdbh6s  于 2022-11-04  发布在  其他
关注(0)|答案(2)|浏览(216)

在开发OpenGL应用程序时,我创建了一个窗口,使用GetDC获取相关的设备上下文,并在GetDC返回的设备上下文句柄上创建了一个OpenGL上下文。一切正常。在创建OpenGL上下文之前,我将调用SetPixelFormat。文档中说明SetPixelFormat只能调用一次(我认为每个设备上下文句柄调用一次)。
对于只有一个设备的系统来说,这非常简单,但是对于有两个或更多设备的系统呢?这是如何工作的?
首先,我不知道所创建的窗口是如何与设备上下文相关联的。我想枚举系统上的每一个可用设备,查询每个设备的每一种像素格式,然后在设置了每个设备上下文后创建窗口。在这种情况下,我不必担心设备像素格式,我可以设置多个设备具有兼容的像素格式(用于在OpenGL上下文之间共享对象)。
是否可以枚举可用的视频设备?我还没有找到任何Windows API用于枚举图形设备以获取GetDC返回的相同句柄...是否可以将窗口与特定的视频设备上下文关联?

ulydmbyx

ulydmbyx1#

设备上下文是相当动态的对象,在应用程序的生命周期中创建和释放。DC可以是显示DC(使用监视器API或CreateDC创建)、窗口DC(使用GetDC api从窗口管理器DC缓存检索)和内存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为应用程序中的每个窗口维护一个单独的上下文。这意味着您需要将HGRRC与每个窗口对象一起存储(作为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;
ckx4rj1h

ckx4rj1h2#

描述像素格式
https://learn.microsoft.com/nb-no/windows/win32/opengl/examining-a-devices-supported-pixel-formats

// local variables  
int                      iMax ; 
PIXELFORMATDESCRIPTOR    pfd; 
int                      iPixelFormat ; 

// initialize a pixel format index variable  
iPixelFormat = 1; 

// keep obtaining and examining pixel format data...  
do { 
    // try to obtain some pixel format data  
    iMax = DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd); 

    // if there was some problem with that...   
    if (iMax == 0) 

        // return indicating failure  
        return(FALSE); 

    // we have successfully obtained pixel format data  

    // let's examine the pixel format data...  
    myPixelFormatExaminer (&pfd); 
    }  

// ...until we've looked at all the device context's pixel formats  
while (++iPixelFormat <= iMax);

相关问题