我有点问题。
我有一个带OpenGL子窗口的窗口, 到目前为止,所有Opengl窗口都会在窗口的右下角呈现纹理。
如果我从左到右快速调整窗口的大小,纹理有时会向左移动,就像它不能快速重新绘制,甚至知道我直接绘制到opengl上下文。
我删除问题的唯一方法是在主窗口调整大小时对opengl窗口的InvalidateRect,但我不知道为什么修复这个问题,因为我正在绘制到opengl上下文所以我不需要让它自己画出来之后我已经描绘了上下文。
如果bHandled
为false,则调用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();
}
答案 0 :(得分:1)
您的问题可能与以下事实有关:每次在调整大小期间移动鼠标时,都会导致窗口重新绘制2次。
首先,当您调整窗口区域时,Windows会自动使窗口区域无效(您可以使用应始终为OpenGL窗口设置的类样式CS_HREDRAW和CS_VREDRAW来控制它,因为调整大小通常需要完整窗口重绘)。
然后你(冗余地)手动使窗口rect无效。然后你强制它绘画 - 现在排队的未来油漆。
OpenGL窗口的OnPaint处理程序应该看起来像:
int ControllerGL::OnPaint(WPARAM wParam, LPARAM lParam, bool & bHandled)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd,&ps);
wglMakeCurrent(hdc,hglrc);
scene->Display();
SwapBuffers(hdc);
wglMakeCurrent(hdc,NULL);
EndPaint(hwnd,&ps);
bHandled = true;
return 0;
}
我将它作为练习来正确封装hwnd和hglrc,以这种方式编写它会明确地显示SwapBuffers在DC上运行,而不是在隐式OpenGL上下文中运行,并且wglMakeCurrent应该使用动态获取的窗口作用域DC。
大多数OpenGL样本非常非常懒,并且使用类DC并且只是让openGL内容一直“活动”,但是一旦线程上的两个窗口试图执行OpenGL,这将会失败。最好省略CS_OWNDC(如果有的话)并在实际需要时获取(和释放)DC。
即。如果你想更传统地处理WM_SIZE(类似于glut Reshape回调)你会这样做:
int ControllerGL::OnSize(WPARAM wParam, LPARAM lParam, bool & bHandled)
{
bHandled = true;
int width = LOWORD(lParam);
int height = HIWORD(lParam);
HDC hdc = GetDC(hwnd);
wglMakeCurrent(hdc,hglrc);
scene->Reshape(width,height);
wglMakeCurrent(hdc,NULL);
ReleaseDC(hwnd,hdc);
return 0;
}
从ControllerGL
到我称之为scene
的所有其他来电,您致电modelGL
同样会被包裹。