summaryrefslogtreecommitdiffstats
path: root/src/effects/shadereffectitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects/shadereffectitem.cpp')
-rw-r--r--src/effects/shadereffectitem.cpp49
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);