【问题标题】:Win32 C++ console clearing screen without blinkingWin32 C++控制台清屏不闪烁
【发布时间】:2013-04-14 09:54:23
【问题描述】:

我见过一些主机游戏,它们的屏幕会自行刷新/清除,而不会出现烦人的闪烁。我已经尝试了很多解决方案,这是我现在得到的:

while(true)
{
    if(screenChanged) //if something needs to be drawn on new position
    {
    COORD coordScreen = { 0, 0 };
    DWORD cCharsWritten;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD dwConSize;
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    GetConsoleScreenBufferInfo(hConsole, &csbi);
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
    FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
    GetConsoleScreenBufferInfo(hConsole, &csbi);
    FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
    SetConsoleCursorPosition(hConsole, coordScreen);
    } 

    ///printf all the time graphics on their right position with SetConsoleCursorPosition

    Sleep(33.3f);
}  

不过,我还是会眨眼。有人有什么想法吗?

【问题讨论】:

  • 这些游戏可能不是作为 Windows 控制台应用程序编写的,而是作为使用各种图形模式并将像素直接写入图形内存的 DOS 应用程序。
  • @Captain 重读第一句话。源代码不是他见过的“主机游戏”,源代码是他尝试过的。
  • @NemanjaBoric 是的,100% 绝对有可能。
  • 为什么需要清空控制台?这就是闪烁的来源。如果您希望大对象干净地移动,您将需要双缓冲(根据现有答案),例如,使移动的垂直字符线永远不会显示扭结,但其影响通常是最小的。在大多数情况下,您只需在绘制帧之间不清除屏幕即可。

标签: c++ windows winapi console-application


【解决方案1】:

您正在寻找双缓冲

【讨论】:

    【解决方案2】:

    你想做相当于双缓冲。使用 CreateConsoleScreenBuffer 和 SetConsoleActiveScreenBuffer api 调用,您可以修改屏幕外缓冲区,然后切换缓冲区,就像我们过去糟糕的日子一样 :) 这里有一篇文章解释了如何:http://msdn.microsoft.com/en-us/library/windows/desktop/ms685032%28v=vs.85%29.aspx

    【讨论】:

      【解决方案3】:

      发生这种情况的原因是,在您清除控制台屏幕和实际绘制到它的时间之间,显示器会刷新。通常这会发生得如此之快,以至于您永远看不到它,但偶尔您会在正确的时间执行它并且您会遇到闪烁。

      一个不错的选择是创建一个与控制台屏幕大小和宽度相同的屏幕外缓冲区,在此处进行所有文本输出和更新,然后使用WriteConsoleOutput 将整个缓冲区发送到控制台屏幕。确保您考虑到屏幕缓冲区必须同时保存文本和属性信息,格式与控制台相同。

      BOOL WINAPI WriteConsoleOutput(
        _In_     HANDLE hConsoleOutput,
        _In_     const CHAR_INFO *lpBuffer,
        _In_     COORD dwBufferSize,
        _In_     COORD dwBufferCoord,
        _Inout_  PSMALL_RECT lpWriteRegion
      );
      

      【讨论】:

      • ncurses 不就是这样做的吗?
      • 不确定,我没有查看 WinAPI 特定的 ncurses 部分
      • 对此的常用术语是“双缓冲”。这是消除看到部分渲染屏幕(在本例中为空白屏幕)的经典方法。
      猜你喜欢
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 2012-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多