2

我有一个 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 事件,但在调整大小然后单击并拖动后,相同的效果仍然存在。

4

2 回答 2

3

快速浏览一下您的代码,我注意到您的 resize 事件处理程序除了要求再次刷新之外没有做任何事情。这对我来说似乎不正确。调整大小处理程序通常会进行一些计算,在请求刷新之前调用一个或多个子窗口的调整大小处理程序等等。所以,我认为你的问题是画布在重绘之前没有调整大小。这可以解释为什么你的场景被剪辑了。不知道修复是什么 - 希望这将是一个足够的提示,以便您可以朝着正确的方向寻找。

于 2013-02-24T17:14:02.890 回答
1

好的,结果证明这是我的一个非常非常愚蠢的错误。

在这一行

glViewport(x, y, w, -h);

我不小心将高度设置为负值。删除负号解决了这个问题。我不知道为什么它会导致作物。我认为高度为负值会阻止我看到任何东西,但它有效,所以我猜我不能抱怨。再次感谢大家的帮助!

于 2013-02-24T18:20:41.063 回答