我为我的应用程序编写了一个基于 OpenGL 的矢量图形渲染器。它需要渲染到帧缓冲区对象而不是直接渲染到屏幕。由于我在 Qt 中编写应用程序,因此我使用 QGLFramebufferObject,它是 OpenGL 帧缓冲区对象的包装类。
我创建了一个最小的示例,它显示了在渲染更复杂的东西时我也得到了错误的结果(例如,使用片段着色器将颜色设置为非一个 alpha 值)。我只是在黑色清除屏幕上渲染一个红色圆圈和一个半透明的绿色圆圈,然后在 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%):
请注意,此图像不是完全不透明的,因此这里是相同的图像,后面添加了一个棋盘:
即使两个圆圈重叠的区域也不是完全不透明的。而且抗锯齿看起来很丑。
这是怎么发生的?我该如何解决这个问题?
我已经尝试过:
- 不同的混合功能。
- 显式禁用 QGLFramebufferObject 上的深度缓冲区、模板缓冲区和采样。我不确定 QGLFramebufferObject 默认格式是否添加了我不想要的东西。