2

contrib パッケージの wxGLCanvas ウィジェットを使用した wxWigets アプリケーションがあります。ウィジェットが更新されるたびに、シーンをレンダリングする前に投影マトリックスとビューポートを再作成します。問題は、フレームのサイズが変更された後、ドラッグ、最大化、または 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();
}

また、GetClientSize() の代わりに GetSize() を使用してみましたが、効果は同じであることに注意してください。また、私はUbuntu 12.04を使用しており、wxWidgetsはGTKを使用しています

アップデート:

また、クリック/ドラッグ機能も実装されており (表示されていません)、マウスがクリックまたはドラッグされるたびに、ウィジェットが更新されることにも注意してください。そうは言っても、wxEVT_SIZE イベントを切断しようとしましたが、サイズを変更してからクリックしてドラッグした後も、同じ効果が持続します。

4

2 に答える 2

3

コードを一目見ただけで、サイズ変更イベント ハンドラーが別の更新を要求する以上のことをしていないことがわかります。これは私には正しくないようです。通常、サイズ変更ハンドラーは何らかの計算を行い、1 つまたは複数の子ウィンドウのサイズ変更ハンドラーを呼び出すなどして、更新を要求します。だから、あなたの問題は、再描画される前にキャンバスのサイズが変更されていないことだと思います。これにより、シーンが切り取られた理由が説明されます。修正がどうなるかわからない - うまくいけば、これがヒントになり、正しい方向に進むことができる.

于 2013-02-24T17:14:02.890 に答える
1

さて、それは私の側の非常に愚かな間違いであることが判明しました。

この行で

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

高さを誤って負の値に設定してしまいました。マイナス記号を削除すると、問題が修正されました。なぜそれが作物を引き起こしたのか私にはわかりません。高さを負にすると何も見えなくなると思いますが、うまくいくので文句は言えません。助けてくれてありがとう!

于 2013-02-24T18:20:41.063 に答える