アプリケーション用に 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 のデフォルト フォーマットが不要なものを追加するかどうかはわかりません。