【发布时间】:2018-09-07 02:52:01
【问题描述】:
我有一个小问题。
我有一个带有 OpenGL 子窗口的窗口, 到目前为止,Opengl 窗口所做的只是在窗口的右下角渲染一个纹理。
如果我从左到右快速调整窗口大小,纹理有时会向左移动,这就像它的重绘速度不够快,即使我知道我直接绘制到 opengl 上下文。
我解决此问题的唯一方法是在调整主窗口大小时使 opengl 窗口的 InvalidateRect 无效,但我不确定为什么这会解决问题,因为我正在绘制到 opengl 上下文,所以我不应该需要让它在之后绘制它自己我已经根据上下文进行了绘制。
如果bHandled 为假,则调用 defWndProc,否则返回函数
主窗口 WM_SIZE
int ControllerMainWnd::OnSize(WPARAM wParam, LPARAM lParam, bool & bHandled)
{
bHandled = true;
int width = LOWORD(lParam);
int height = HIWORD(lParam);
//Set OpenGL Window Size
::SetWindowPos(glHandle, 0, 0, 0, width, height, SWP_NOZORDER);
//Invalidate OpenGL Window
::InvalidateRect(glHandle, 0, FALSE); // if i comment this out my texture sometime moves
return 0;
}
OpenGL 窗口
int ControllerGL::OnPaint(WPARAM wParam, LPARAM lParam, bool & bHandled)
{
//bHandled = true;
//LRESULT lRes = defWinProc(WM_PAINT, wParam, lParam);
Paint();
//return lRes;
return 0;
}
int ControllerGL::OnSize(WPARAM wParam, LPARAM lParam, bool & bHandled)
{
bHandled = true;
int width = LOWORD(lParam);
int height = HIWORD(lParam);
modelGL->setWindowSize(width, height);
Paint();
return 0;
}
int ControllerGL::OnEraseBkgnd(WPARAM wParam, LPARAM lParam, bool & bHandled)
{
bHandled = true;
return 1L;
}
auto ControllerGL::Paint() -> void
{
openGLcontext->activateContext();
modelGL->draw();
openGLcontext->swapBuffers();
}
【问题讨论】:
-
你为什么还要打电话给
InvalidateRect,你从来没有验证过呢?该区域在您的代码中总是无效。无需告诉系统,它已经知道了什么。除非您开始验证无效区域。 We've been through this 已经。 -
因为在没有 InvalidateRect 的情况下,当窗口快速调整大小时,纹理会移动/闪烁一点。所以我在问为什么
-
更明确 - 始终在
WM_PAINT处理程序中使用BeginPaint和EndPaint- 这是验证无效区域所必需的 - 并正确裁剪到要更新的区域。跨度> -
@ChrisBecke 我用 openGl 上下文而不是 windows api 绘图。所以我还需要使用 beginPaint?
-
您不需要,但您应该验证无效区域,以防止您的应用不断收到
WM_PAINT消息流。