使用QOpenGLFrameBufferObject类进行Qt5 OpenGL多采样。

时间:2023-02-05 19:36:01

I need to perform multisampling in a Qt5 project but I am not sure how to use QOpenGLFrameBufferObject to perform FSAA. There is no example on how to do this as far as I searched and the documentation only mentions: “If you want to use a framebuffer object with multisampling enabled as a texture, you first need to copy from it to a regular framebuffer object using QOpenGLContext::blitFramebuffer().” My code currently looks like this:

我需要在Qt5项目中执行多采样,但我不确定如何使用QOpenGLFrameBufferObject来执行FSAA。在我搜索的过程中,没有关于如何做到这一点的示例,文档中只提到:“如果您想要使用具有多采样功能的framebuffer对象作为纹理,那么您首先需要使用QOpenGLContext::blitFramebuffer()将它复制到一个常规的framebuffer对象中。“我的代码现在看起来是这样的:

//Enable FSAA for better output
int vp[4];
glGetIntegerv(GL_VIEWPORT, vp);
if(m_lpFBO == NULL)
{
    //MultiSampling set to 4 now
    QOpenGLFramebufferObjectFormat format;
    format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
    format.setMipmap(true);
    format.setSamples(4);
    format.setTextureTarget(GL_TEXTURE_2D);
    format.setInternalTextureFormat(GL_RGBA32F_ARB);

    //Create the FBO
    m_lpFBO = new QOpenGLFramebufferObject(vp[2], vp[3], format);
    m_lpFBOSurface = new QGLFramebufferObjectSurface(m_lpFBO);
}

QRect rc(0, 0, vp[2], vp[3]);
QGLSubsurface sub(lpPainter->currentSurface(), rc);


m_lpFBO->bind();
sub.setFramebufferObject(m_lpFBO);
lpPainter->pushSurface(&sub);

//Draw as usual
.
. 
.

lpPainter->popSurface();


//Now Copy
QOpenGLFramebufferObject::blitFramebuffer(lpPainter->currentSurface()->framebufferObject(), rc, m_lpFBO, rc);

1 个解决方案

#1


4  

You do not need to use a QGLFramebufferObjectSurface to perform the necessary downsampling, as you can just use two QGLFramebufferObjects. QOpenGLFramebufferObject::blitFramebuffer (which calls glBlitFramebuffer) will automagically manage downsampling (or upsampling) from a source framebuffer target to a destination frame buffer target. blitFramebuffer also lets you dictate how conversion is computed using (GL_NEAREST or GL_LINEAR) and what attachments are to be transfered (a bitwise combination of GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT).

您不需要使用QGLFramebufferObjectSurface来执行必要的向下采样,因为您可以只使用两个QGLFramebufferObjects。:blitFramebuffer(调用glBlitFramebuffer)将自动管理从源帧缓冲区目标到目标帧缓冲目标的向下采样(或向上采样)。blitFramebuffer还允许您指定如何使用(GL_NEAREST或GL_LINEAR)来计算转换,以及要传输哪些附件(GL_COLOR_BUFFER_BIT、GL_DEPTH_BUFFER_BIT、GL_STENCIL_BUFFER_BIT的位组合)。

So, for your needs you want to create 2 QOpenGLFramebufferObjects where one will contains the multisampled texture being rendered to, and one will contain the downsampled result texture. Then you will use QOpenGLFramebufferObject::blitFramebuffer to downsample the source texture into the result texture.

因此,对于您的需求,您需要创建2个QOpenGLFramebufferObjects,其中一个将包含被渲染到的多采样纹理,其中一个将包含向下采样的结果纹理。然后,您将使用QOpenGLFramebufferObject::blitFramebuffer将源纹理向下采样到结果纹理中。

Here is a quick example:

这里有一个简单的例子:

//MultiSampling set to 4 now
QOpenGLFramebufferObjectFormat muliSampleFormat;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setMipmap(true);
format.setSamples(4);
format.setTextureTarget(GL_TEXTURE_2D);
format.setInternalTextureFormat(GL_RGBA32F_ARB);


QOpenGLFramebufferObject multiSampledFBO = QOpenGLFramebufferObject(width,height muliSampleFormat);


QOpenGLFramebufferObjectFormat downSampledFormat;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setMipmap(true);
format.setTextureTarget(GL_TEXTURE_2D);
format.setInternalTextureFormat(GL_RGBA32F_ARB);

QOpenGLFramebufferObject downSampledFBO = QOpenGLFramebufferObject(width,height downSampledFormat);

Then, every time you need to downsample (after rendering to your multisampled texture) simply do something like this. (using your preferred filtering)

然后,每次你需要向下采样(在渲染到你的多采样纹理之后),只需做这样的事情。(使用您的首选过滤)

QOpenGLFramebufferObject::blitFramebuffer(downSampledFBO,multiSampledFBO,GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT,GL_NEAREST);

#1


4  

You do not need to use a QGLFramebufferObjectSurface to perform the necessary downsampling, as you can just use two QGLFramebufferObjects. QOpenGLFramebufferObject::blitFramebuffer (which calls glBlitFramebuffer) will automagically manage downsampling (or upsampling) from a source framebuffer target to a destination frame buffer target. blitFramebuffer also lets you dictate how conversion is computed using (GL_NEAREST or GL_LINEAR) and what attachments are to be transfered (a bitwise combination of GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT).

您不需要使用QGLFramebufferObjectSurface来执行必要的向下采样,因为您可以只使用两个QGLFramebufferObjects。:blitFramebuffer(调用glBlitFramebuffer)将自动管理从源帧缓冲区目标到目标帧缓冲目标的向下采样(或向上采样)。blitFramebuffer还允许您指定如何使用(GL_NEAREST或GL_LINEAR)来计算转换,以及要传输哪些附件(GL_COLOR_BUFFER_BIT、GL_DEPTH_BUFFER_BIT、GL_STENCIL_BUFFER_BIT的位组合)。

So, for your needs you want to create 2 QOpenGLFramebufferObjects where one will contains the multisampled texture being rendered to, and one will contain the downsampled result texture. Then you will use QOpenGLFramebufferObject::blitFramebuffer to downsample the source texture into the result texture.

因此,对于您的需求,您需要创建2个QOpenGLFramebufferObjects,其中一个将包含被渲染到的多采样纹理,其中一个将包含向下采样的结果纹理。然后,您将使用QOpenGLFramebufferObject::blitFramebuffer将源纹理向下采样到结果纹理中。

Here is a quick example:

这里有一个简单的例子:

//MultiSampling set to 4 now
QOpenGLFramebufferObjectFormat muliSampleFormat;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setMipmap(true);
format.setSamples(4);
format.setTextureTarget(GL_TEXTURE_2D);
format.setInternalTextureFormat(GL_RGBA32F_ARB);


QOpenGLFramebufferObject multiSampledFBO = QOpenGLFramebufferObject(width,height muliSampleFormat);


QOpenGLFramebufferObjectFormat downSampledFormat;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setMipmap(true);
format.setTextureTarget(GL_TEXTURE_2D);
format.setInternalTextureFormat(GL_RGBA32F_ARB);

QOpenGLFramebufferObject downSampledFBO = QOpenGLFramebufferObject(width,height downSampledFormat);

Then, every time you need to downsample (after rendering to your multisampled texture) simply do something like this. (using your preferred filtering)

然后,每次你需要向下采样(在渲染到你的多采样纹理之后),只需做这样的事情。(使用您的首选过滤)

QOpenGLFramebufferObject::blitFramebuffer(downSampledFBO,multiSampledFBO,GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT,GL_NEAREST);