视口或投影未在wxWidgets中调整窗口大小时正确调整大小

时间:2013-02-24 17:04:49

标签: opengl wxwidgets

我有一个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);
}

和resize方法:

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

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

好吧,所以我发现这是一个非常非常愚蠢的错误。

在这一行

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

我不小心将高度设置为负值。删除负号修复了问题。我不确定它为什么会导致作物。我认为高度负面会阻止我看到任何东西,但它有效,所以我不能抱怨我猜。再次感谢所有人的帮助!