5

アプリケーション用に OpenGL ベースのベクター グラフィックス レンダラーを作成しています。画面に直接ではなく、フレームバッファ オブジェクトにレンダリングする必要があります。Qt でアプリケーションを作成するので、OpenGL フレームバッファ オブジェクトのラッパー クラスである QGLFramebufferObject を使用します。

より複雑なものをレンダリングするときにも間違った結果が得られることを示す最小限の例を作成しました (たとえば、1 以外のアルファ値で色を設定するフラグメント シェーダーを使用するなど)。真っ黒なクリア画面に赤い円と半透明の緑の円をレンダリングし、FBO でも同じようにレンダリングします。

void MainWidget::initializeGL()
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0, 0, 0, 0);
}

void MainWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void MainWidget::paintGL()
{
    // DRAW ON THE SCREEN
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glPointSize(100);
        glEnable(GL_POINT_SMOOTH);
        glBegin(GL_POINTS);
        glColor4f(1, 0, 0, 1);
        glVertex2f(-.2, 0);
        glColor4f(0, 1, 0, .5);
        glVertex2f( .2, 0);
        glEnd();
    }

    QGLFramebufferObject fbo(width(), height());
    fbo.bind();

    // DRAW ON THE FBO USING THE SAME CODE AND THE SAME CONTEXT
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glPointSize(100);
        glEnable(GL_POINT_SMOOTH);
        glBegin(GL_POINTS);
        glColor4f(1, 0, 0, 1);
        glVertex2f(-.2, 0);
        glColor4f(0, 1, 0, .5);
        glVertex2f( .2, 0);
        glEnd();
    }

    fbo.release();
    fbo.toImage().save("debug.png");
}

結果は画面上で次のようになります (400% にスケーリング)。

ここに画像の説明を入力

QGLFramebufferObject へのレンダリングは次のようになります (これも 400% にスケーリングされています)。

ここに画像の説明を入力

この画像は完全に不透明ではないことに注意してください。そのため、同じ画像の後ろにチェッカーボードが追加されています。

ここに画像の説明を入力

2 つの円が重なり合う領域でさえ、完全に不透明ではありません。そして、アンチエイリアシングはかなり醜く見えます。

これはどのように起こりますか?どうすればこれを修正できますか?

私はすでに試しました:

  • 異なるブレンド関数。
  • QGLFramebufferObject で深度バッファ、ステンシル バッファ、およびサンプリングを明示的に無効にします。QGLFramebufferObject のデフォルト フォーマットが不要なものを追加するかどうかはわかりません。
4

1 に答える 1

1

次のことを試してください。

QGLFramebufferObjectFormat fmt;
fmt.setSamples(1); // or 4 or disable this line
fmt.setInternalTextureFormat(GL_RGBA8);
QGLFramebufferObject fbo(width(), height(), fmt);

これにより、特定のピクセル フォーマットが強制され、マルチサンプリングを使用してテクスチャへのレンダリングも無効になります (それ以外の場合、QT は常にテクスチャにレンダリングします)。それによって、異なる結果が生じる可能性があります。フォーマットを試すこともできます。

また、ハードウェアは何ですか?私の最大ポイント サイズはわずか 64 ピクセル (GTX 260) です。100 ピクセル ポイントをレンダリングしようとしています。それは問題かもしれません。OpenGL エラーは生成されますか? 小さなポイントでも同じことが起こりますか?

ヒントを試すこともできます (QT で可能な場合):

glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

しかし、私はこれが何かを変えるとは思っていません。

于 2012-11-09T12:40:55.070 に答える