我有一个 wxWigets 应用程序,使用 contrib 包中的 wxGLCanvas 小部件。每次刷新小部件时,我都会在渲染场景之前重新创建投影矩阵和视口。问题是,在调整框架大小后,无论是通过拖动或最大化还是 w/e,小部件都正确调整了大小,但视口或投影(无法真正辨别哪个)没有调整大小,因此场景最终被裁剪.
现在来看一些代码。
我的 wxGLCanvas 小部件的构造函数如下所示:
int attrib_list[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER };
RenderCanvas::RenderCanvas(wxFrame* parent) : wxGLCanvas(parent, idRender, wxPoint(200, -1), wxSize(800, 600), wxFULL_REPAINT_ON_RESIZE, wxT("GLCanvas"), attrib_list)
{
Connect(idRender, wxEVT_PAINT, wxPaintEventHandler(RenderCanvas::PaintIt));
Connect(idRender, wxEVT_SIZE, wxSizeEventHandler(RenderCanvas::Resize));
Connect(idRender, wxEVT_LEFT_DOWN, wxMouseEventHandler(RenderCanvas::OnMouseLeftDown));
Connect(idRender, wxEVT_LEFT_UP, wxMouseEventHandler(RenderCanvas::OnMouseLeftUp));
Connect(idRender, wxEVT_MOTION, wxMouseEventHandler(RenderCanvas::OnMouseMotion));
}
我像这样覆盖 PaintIt 方法:
void RenderCanvas::PaintIt(wxPaintEvent& event)
{
SetCurrent();
wxPaintDC(this);
Render();
Refresh(false);
}
和调整大小方法:
void RenderCanvas::Resize(wxSizeEvent& event)
{
Refresh();
}
上面使用的 Render 方法如下所示:
void RenderCanvas::Render()
{
Prepare2DViewport(0,GetClientSize().y,GetClientSize().x, 0);
glClear(GL_COLOR_BUFFER_BIT);
//Renders stuff...
glFlush();
SwapBuffers();
}
最后,调用 glViewport 和 glOrtho 函数的 Prepare2DViewport 是:
void RenderCanvas::Prepare2DViewport(int x, int h, int w, int y)
{
glClearColor(0.7f, 0.7f, 0.7f, 1.0f); // Grey Background
glEnable(GL_TEXTURE_2D); // textures
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glViewport(x, y, w, -h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(x, (float)w, y, (float)h, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
还应该注意的是,我尝试使用 GetSize() 而不是 GetClientSize() 但效果是一样的。另外,我在 Ubuntu 12.04 上,而 wxWidgets 正在使用 GTK
更新:
还应该注意的是,我也实现了单击/拖动功能(未显示),每次单击或拖动鼠标时,都会刷新小部件。话虽如此,我尝试断开 wxEVT_SIZE 事件,但在调整大小然后单击并拖动后,相同的效果仍然存在。