是否有一种优雅的方式来处理Windows OpenGL应用程序中的全屏模式和窗口模式之间的切换?

Azu*_*tor 14 c c++ opengl winapi fullscreen

我想知道是否可以在OpenGL窗口中使用全屏模式和窗口模式之间来回切换(我使用C++和win32编写Windows),而不会破坏OpenGL上下文,因此不得不重新加载资源(纹理, VBO等)在这个过程中?

这是不合需要的,因为它引入了在全屏和窗口模式之间切换的延迟,可能是长的,并且通过忘记重新初始化某些东西而使得更容易搞砸.

作为后续的一部分,是否有某些视觉效果被打破这样做?

在过去的几天里,我已经做了很多搜索和阅读,尽管SDL和其他框架有很多问题导致出现同样的问题(我还没有使用它们,但是......),最好的我设法找到一个可能的领导者在后台打开1x1窗口以保留上下文,同时销毁或创建一个辅助窗口.从我发现的评论来看,这看起来似乎不可靠,而且无论如何看起来都非常笨拙.

有没有一种正确的方法来执行此操作,或者是通常给定的示例方法来破坏窗口并重新创建它,包括破坏OpenGL上下文并重新创建它?

Tob*_*gel 16

基本上它只是调整窗口大小并指定边框不可见的标志.

SetWindowLongPtr(hWnd, GWL_STYLE, 
    WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE);
MoveWindow(hWnd, 0, 0, width, height, TRUE);
Run Code Online (Sandbox Code Playgroud)

把它放回去:

RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = width;
rect.bottom = height;
SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
MoveWindow(hWnd, 0, 0, rect.right-rect.left, rect.bottom-rect.top, TRUE);
Run Code Online (Sandbox Code Playgroud)

或者对于不可调整大小的窗口:

SetWindowLongPtr(hWnd, GWL_STYLE, WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE);
AdjustWindowRect(&rect, WS_CAPTION | WS_POPUPWINDOW, FALSE);
MoveWindow(hWnd, 0, 0, rect.right-rect.left, rect.bottom-rect.top, TRUE);
Run Code Online (Sandbox Code Playgroud)

然后只调整OpenGL视口设置的大小.

如果您也想设置显示模式,请使用:

// change display mode if destination mode is fullscreen
if (fullscreen) {
    DEVMODE dm;
    dm.dmSize = sizeof(DEVMODE);
    dm.dmPelsWidth = width;
    dm.dmPelsHeight = height;
    dm.dmBitsPerPel = bitsPerPixel;
    dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
    success = ChangeDisplaySettings(&dm, 0) == DISP_CHANGE_SUCCESSFUL;
}

// reset display mode if destination mode is windowed
if (!fullscreen)
    success = ChangeDisplaySettings(0, 0) == DISP_CHANGE_SUCCESSFUL;
Run Code Online (Sandbox Code Playgroud)

  • 我发现了一些额外的信息.显然,当使用SetWindowLongPtr()时,您想要使用SetWindowPos()而不是MoveWindow().此外,使用ChangeDisplaySettings(NULL,0)在调整窗口大小后,似乎可以解决脏背景问题. (4认同)
  • 这真的是全屏还是只是一个屏幕大小的无边框窗口?这有很大的不同. (4认同)