diff options
Diffstat (limited to 'src/effects/shadereffectitem.cpp')
-rw-r--r-- | src/effects/shadereffectitem.cpp | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/effects/shadereffectitem.cpp b/src/effects/shadereffectitem.cpp index 8c179d8..4670a14 100644 --- a/src/effects/shadereffectitem.cpp +++ b/src/effects/shadereffectitem.cpp @@ -183,6 +183,7 @@ ShaderEffectSource::ShaderEffectSource(QObject *parent) , m_size(0, 0) , m_static(false) , m_fbo(0) + , m_multisampledFbo(0) , m_renderer(0) , m_refs(0) , m_dirtyTexture(true) @@ -195,6 +196,7 @@ ShaderEffectSource::~ShaderEffectSource() if (m_refs && m_sourceItem) QxItemPrivate::get(m_sourceItem)->derefFromEffectItem(); delete m_fbo; + delete m_multisampledFbo; delete m_renderer; } @@ -402,17 +404,38 @@ void ShaderEffectSource::update() Q_ASSERT(m_renderer); const QGLContext *ctx = QGLContext::currentContext(); - if (m_renderer->openGLFeatures() == 0) + if (m_renderer->openGLFeatures() == 0) { m_renderer->initializeGLFunctions(ctx); + QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); + m_multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample") + && extensions.contains("GL_EXT_framebuffer_blit"); + } if (!m_fbo) { - // TODO: Implement support for multisampling. - QGLFramebufferObjectFormat format; - format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - format.setMipmap(m_mipmap != None); - m_fbo = new QGLFramebufferObject(m_size, format); + if (ctx->format().sampleBuffers() && m_multisamplingSupported) { + // If mipmapping was just enabled, m_fbo might be 0 while m_multisampledFbo != 0. + if (!m_multisampledFbo) { + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + format.setSamples(ctx->format().samples()); + m_multisampledFbo = new QGLFramebufferObject(m_size, format); + } + { + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::NoAttachment); + format.setMipmap(m_mipmap != None); + m_fbo = new QGLFramebufferObject(m_size, format); + } + } else { + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + format.setMipmap(m_mipmap != None); + m_fbo = new QGLFramebufferObject(m_size, format); + } } + Q_ASSERT(m_size == m_fbo->size()); + Q_ASSERT(m_multisampledFbo == 0 || m_size == m_multisampledFbo->size()); QRectF r(0, 0, m_sourceItem->width(), m_sourceItem->height()); r.adjust(-m_margins.width(), -m_margins.height(), m_margins.width(), m_margins.height()); @@ -420,7 +443,13 @@ void ShaderEffectSource::update() m_renderer->setProjectMatrixToRect(r); m_renderer->setClearColor(Qt::transparent); - m_renderer->renderScene(BindableFbo(const_cast<QGLContext *>(QGLContext::currentContext()), m_fbo)); + if (m_multisampledFbo) { + m_renderer->renderScene(BindableFbo(const_cast<QGLContext *>(QGLContext::currentContext()), m_multisampledFbo)); + QRect r(0, 0, m_size.width(), m_size.height()); + QGLFramebufferObject::blitFramebuffer(m_fbo, r, m_multisampledFbo, r); + } else { + m_renderer->renderScene(BindableFbo(const_cast<QGLContext *>(QGLContext::currentContext()), m_fbo)); + } if (m_mipmap != None) { QGLFramebufferObject::bindDefault(); glBindTexture(GL_TEXTURE_2D, m_fbo->texture()); @@ -458,7 +487,8 @@ void ShaderEffectSource::updateSizeAndTexture() size.setHeight(1); if (m_fbo && m_fbo->size() != size) { delete m_fbo; - m_fbo = 0; + delete m_multisampledFbo; + m_fbo = m_multisampledFbo = 0; } if (m_size.width() != size.width()) { m_size.setWidth(size.width()); @@ -472,7 +502,8 @@ void ShaderEffectSource::updateSizeAndTexture() } else { if (m_fbo) { delete m_fbo; - m_fbo = 0; + delete m_multisampledFbo; + m_fbo = m_multisampledFbo = 0; } if (!m_sourceImage.isEmpty()) { m_texture = QGLTexture2DPtr(new QGLTexture2D); |