【问题标题】:X11 window resizing stuttersX11窗口大小调整口吃
【发布时间】:2016-04-04 23:40:18
【问题描述】:

我正在 X11 中创建一个 openGL 窗口并使用 glxswapbuffers 进行双缓冲。

问题是:渲染看起来不错,但我得到 openGL 内容弹跳和调整大小时窗口边框口吃。

我尝试过滤 ConfigureNotify 事件,延迟它们,使用 glXSwapInterval 设置 vsync 关闭...没有任何效果。

这是我正在使用的代码

void Window::redraw() { // Called by any control which needs redrawing
  XEvent event;
  memset(&event, 0, sizeof(event));
  event.type = Expose;
  event.xexpose.display = display;
  XSendEvent(display, window, False, ExposureMask, &event);
}

void Window::resize(int width, int height) {
  this->Width = width;
  this->Height = height;
}

bool Window::wndProc(XEvent *evt) {
  switch (evt->type) {

      case Expose: {

        if (evt->xexpose.count == 0) { // handle last one only

          while (XCheckTypedWindowEvent(display, window, Expose, evt));

            if (Width != oldWidth || Height != oldHeight)
              resizeViewportAndUpdateDimensions();

          Renderer.drawGLStuff();

          this->redraw();
        }

        return true;

      } break;

      case ConfigureNotify: {
        this->resize(evt->xconfigure.width, evt->xconfigure.height);

        this->redraw();
        return true;
      } break;
  }
}

请注意,这是一个与this previous post 不同的问题(与调整大小相关),我通过XCheckTypedWindowEvent 解决了这个问题。

【问题讨论】:

  • 这也发生在其他窗口系统中,只是让你知道(例如 Win32 和 Quartz)。调整大小时,帧缓冲区已损坏并且其内容未定义。您需要在处理调整大小消息的同时对损坏做出响应,而这通常不能直观地工作。
  • 例如,在 Win32 中,您实际上必须设置一个辅助线程来泵送渲染,因为 Windows 在用户拖动框架时会停止发送事件,并且您只会在释放后才收到新消息。跨度>
  • @AndonM.Coleman 谢谢,但如何respond to damage?这是什么意思?
  • 损坏是指窗口的内容被无效。这可能是因为另一个窗口移动到它上面(通常不是合成窗口管理器的问题)或因为调整了窗口大小。重绘通常是您对损坏做出反应的方式,但调整大小事件通常是模态的。我很想给出一个实际的答案,但我只在 OS X 和 Windows 中处理过这个问题。

标签: linux opengl x11


【解决方案1】:

https://tronche.com/gui/x/xlib/events/window-state-change/configure.html

https://tronche.com/gui/x/xlib/events/structure-control/resize.html

从我可以从这两个链接中读到的内容,ConfigureNotify 会在更改完成时发生。 ResizeRequest 在尝试调整大小时发生。具体来说:

X 服务器可以向需要的客户端报告 ResizeRequest 事件 有关另一个客户端尝试更改大小的信息 窗口。

我不喜欢“CAN 报告”的声音,但我想你应该试一试。不要忘记按照链接中的说明设置正确的事件位。至于捕获事件时应该做什么,我不太确定......我会清除前端缓冲区并等待调整大小完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2013-01-27
    相关资源
    最近更新 更多