除了多重采样+ blitting之外,获取QOpenGLFramebufferObject抗锯齿纹理的替代方法

时间:2014-08-15 09:58:29

标签: c++ qt opengl-es windows-ce

我尝试在基于WinCE的设备上基于Qt 5.2.1基于窗口小部件的应用程序上进行本机GL绘图时使用的FBO纹理(QOpenGLFramebufferObject)上实现消除锯齿效果。它支持OpenGL ES 2.0。

使用两个QOpenGLFramebufferObject在Qt文档中描述的机制,一个启用了多个样本(例如4个样本),另一个没有多次采样,用作目标FBO进行下采样,然后从多个blit - 采样一个到下采样的一个不起作用
这是因为设备不支持blit操作,QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()返回false,即使它在支持blit的Win32桌面上正常消除锯齿。

有没有其他方法可以在不使用此blit操作的情况下实现抗锯齿?最好使用Qt组件来简化实施。


情况详情
应用程序将GL图纸显示为屏幕背景,并在控件窗口小部件(按钮,标签等)的顶部显示。 GL图纸本身由我们使用的第三方库完成
为此,我们使用QGraphicsViewQGraphicsScene让库绘制背景并将控件小部件添加到要在其上绘制的场景。

除了为QGLWidget的视口创建的QGraphicsView上下文之外,我们还有一个单独的GL上下文和专门为库使用而创建的FBO,因为库需要独占本身的背景。上下文共享显示列表和纹理对象,并在库绘制之前和之后切换
该库根据QTimer回调绘制,以模拟每秒所需的帧数。在绘图过程中,多次采样的FBO将在绘图完成后被绑定和释放,然后blit到下采样的。
QGraphicsScene::drawBackground()期间,将使用QGLContext::drawTexture()在视口的上下文中绘制下采样FBO的纹理。遗憾的是,这会在设备上消耗垃圾,因为不支持从多个到下采样的FBO的blit操作。

1 个答案:

答案 0 :(得分:2)

ES 2.0也不支持可用作FBO附件的多重采样纹理/渲染缓冲区。至少没有扩展名。因此,使用ES 2.0不仅缺少支持这种情况的blit。

最简单的解决方案是一直到完全超级采样。质量方面,这可以优于多次采样,因为它不仅可以平滑多边形边缘和交叉点。你要做的是分配一个纹理,它是最终渲染目标大小的倍数(通常是两倍)。渲染它,然后用“blit”对其进行下采样,用一个简单的着色器实现自己。

有一个重要的警告:它非常耗费资源。纹理是大小的4倍,因此如果渲染表面适度大,它将占用大量内存。您甚至必须小心不要超过MAX_TEXTURE_SIZE限制。随着内存使用量的增加,性能也会大大降低。

至少有一个其他选项,这种方法在广泛使用多次采样之前更常用。这个想法是你多次渲染帧,稍微偏移,然后平均这些帧。在Red Book中查找“场景抗锯齿”,了解如何使用旧式OpenGL完成此操作。该代码中使用的累积缓冲区(以及其他大多数内容)早已被弃用,但您可以与FBO实现相同的想法。