【发布时间】: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 中处理过这个问题。