切换到全屏模式后清除屏幕?

时间:2011-08-27 15:19:59

标签: c++ c winapi opengl fullscreen

所以我运行的OpenGL应用程序可以在全屏模式和窗口模式之间切换。它目前通过调整窗口大小和更改样式来实现。

然而,当从全屏模式切换到窗口模式时,似乎没有使屏幕无效,这使得我在切换后留在屏幕上的东西停留在屏幕上。 有趣的是,它只在单一监视器模式下表现出这种行为。如果我正在运行多个显示器,它会无效,并清除我的绘图。

我不认为这是一个驱动程序错误,因为它发生在使用两个独立显卡的两台独立计算机上(虽然不可否认它们都是nVidia。),我认为我在某处做错了。

我尝试过一系列方法让Windows清除以前全屏图纸的屏幕,但似乎没有任何效果。 InvalidateRect(),RedrawWindow(),ChangeDisplaySettings()...... 具体做法是:

InvalidateRect(m_hwnd, &rectx, true); // rect being the dimensions of either the screen or my window.
InvalidateRect(HWND_DESKTOP, NULL, TRUE); // Doesn't seem to do anything.
RedrawWindow(NULL, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
ChangeDisplaySettings(NULL, 0);

嗯,实际上,在调整大小之前,似乎有效的一件事是ShowWindow(hwnd,SW_HIDE)。然而,暂时失去焦点,允许其他应用程序获取我的应用程序的输入,并且似乎是一个糟糕的方式来解决它。 我应该注意到,当我看到这种行为时,我没有做任何实际的显示模式更改;只保持目前的全屏分辨率。

在我出错的地方,我有点无能为力。简化代码:

if(m_isFullscreen)
{
    ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
}
else
{
    ChangeDisplaySettings(&m_dmSavedScreenSettings, 0);
}
if(m_isFullscreen)
{
    dwExStyle = WS_EX_APPWINDOW;
    dwStyle = WS_POPUP;
    ShowCursor(false);
}
else
{
    dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
    dwStyle = WS_OVERLAPPEDWINDOW;
    if(m_isRunning) // Because ShowCursor uses a counter to indicate, and windowed mode defaults to cursor on, we don't need to increment the counter and double it being on.
    {
        ShowCursor(true);
    }
}

RECT rect;
rect.left = 0;
rect.top = 0;
if(m_isFullscreen) { rect.right = 1280; } else { rect.right = 640; }
if(m_isFullscreen) { rect.bottom = 1024; } else { rect.bottom = 480; }
AdjustWindowRectEx(&rect, dwStyle, false, dwExStyle);

SetWindowLongPtr(m_hwnd, GWL_STYLE, dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
SetWindowLongPtr(m_hwnd, GWL_EXSTYLE, dwExStyle);
if(m_isFullscreen)
{
    MoveWindow(m_hwnd, 0, 0, 1280, 1024, true);
}
else
{
    MoveWindow(m_hwnd, 0, 0, 640, 480, true); // windowed
}

这或多或少都是如此。一些其他支持代码和错误检查,但这就是我正在做的...在m_hwnd从NULL分配之前保存dmSavedSettings,而不是之后。我的初始窗口创建工作正常,全屏工作正常。它只是在全屏后回到Windowed就是问题。

2 个答案:

答案 0 :(得分:2)

如果在窗口类中设置空背景画笔,则不会自动清除窗口。您必须添加一个调用OpenGL显示处理程序的WM_PAINT处理程序,该处理程序将清除视口( glClearColor )并重绘。

答案 1 :(得分:2)

正如datenwolf在另一个答案的评论中提到的那样,你想在使用SetWindowLongPtr()时使用SetWindowPos()而不是MoveWindow()。

我的脏背景问题是通过在调整窗口大小后调用ChangeDisplaySettings(NULL,0)来解决的。之前做的很少,但之后似乎工作正常。