【问题标题】:viewport or projection not resizing correctly on window resize in wxWidgets视口或投影在 wxWidgets 中调整窗口大小时未正确调整大小
【发布时间】:2013-02-09 20:09:58
【问题描述】:

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

【问题讨论】:

    标签: opengl wxwidgets


    【解决方案1】:

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

    在这一行

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我的印象是调整大小处理程序是在所有正常调整大小处理发生后调用的。就像回调一样。不是这样吗?
      • 另外,我在尝试纠正您的建议后更新了我的帖子。
      • 不。调整大小处理程序调整窗口大小。您已经使用不进行大小调整的新处理程序重新实现了原始调整大小处理程序。
      • 我明白了。好吧,无论如何,如果我删除调整大小处理程序,如果在其他地方刷新它不应该工作吗?
      猜你喜欢
      • 2019-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-02
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      • 2016-09-14
      相关资源
      最近更新 更多