在QGLFramebufferObject上渲染时,错误的Alpha混合 [英] Wrong alpha blending when rendering on a QGLFramebufferObject

查看:297
本文介绍了在QGLFramebufferObject上渲染时,错误的Alpha混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的应用程序编写了一个基于OpenGL的矢量图形渲染器.它需要渲染到帧缓冲区对象,而不是直接渲染到屏幕.由于我是用Qt编写应用程序的,因此我使用了QGLFramebufferObject,它是OpenGL帧缓冲对象的包装类.

I write an OpenGL based vector graphics renderer for my application. It needs to render to a framebuffer object rather to the screen directly. Since I write the application in Qt, I use a QGLFramebufferObject which is a wrapper class for a OpenGL framebuffer object.

我创建了一个最小的示例,该示例显示了渲染更复杂的内容时也会得到的错误结果(例如,使用片段着色器将颜色设置为非1的alpha值).我只在黑色透明屏幕上绘制一个红色圆圈和一个半透明的绿色圆圈,然后在FBO上相同:

I created a minimal example which shows a wrong result I also get when rendering more complex stuff (for example using a fragment shader which sets colors with a non-one alpha value). I just render a red circle and a half-transparent green one on a black cleared screen, and then the same on the 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%):

The result looks like this on the screen (scaled 400%):

QGLFramebufferObject的呈现看起来像这样(也缩放了400%):

The rendering to the QGLFramebufferObject looks like this (also scaled 400%):

请注意,此图片并非完全不透明,因此此处是同一张图片,并在其后添加了一个棋盘格:

Note that this image is not fully opaque, so here it is the same image with a checkerboard added behind it:

即使两个圆圈重叠的区域也不是完全不透明的.而且抗锯齿看起来很丑.

Even the area in which the two circles overlap isn't fully opaque. And the anti-aliasing looks pretty ugly.

这是怎么发生的?以及我该如何解决?

我已经尝试过:

  • 不同的混合功能.
  • 显式禁用QGLFramebufferObject上的深度缓冲区,模板缓冲区和采样.我不确定QGLFramebufferObject的默认格式是否添加了我不需要的内容.

推荐答案

尝试以下操作:

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

这将强制使用特定的像素格式,并且还通过使用多重采样来禁用渲染到纹理(否则QT始终渲染到纹理).那可能会产生不同的结果.您也可以尝试使用该格式.

This forces a specific pixel format and also disables rendering to a texture by using multisampling (otherwise QT always renders to a texture). That might produce different results. You can also experiment with the format.

另外,您的硬件是什么?我的最大点大小只有64个像素(GTX 260),您正尝试渲染100个像素点.那可能是个问题.是否生成任何OpenGL错误?在小点上也会发生同样的事情吗?

Also, what is your hardware? My maximal point size is only 64 pixels (GTX 260), you are trying to render 100 pixel points. That might be an issue. Are any OpenGL errors generated? Does the same happen on small points?

您也可以尝试提示(如果在QT中可能):

You might also try hinting (if it's possible in QT):

glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

但是我不希望这会改变任何事情.

But i wouldn't expect this to change anything.

这篇关于在QGLFramebufferObject上渲染时,错误的Alpha混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆