diff options
Diffstat (limited to 'src/graphicsitems/nodes/qxpainternode.cpp')
-rw-r--r-- | src/graphicsitems/nodes/qxpainternode.cpp | 119 |
1 files changed, 68 insertions, 51 deletions
diff --git a/src/graphicsitems/nodes/qxpainternode.cpp b/src/graphicsitems/nodes/qxpainternode.cpp index 2b3edf7..9190587 100644 --- a/src/graphicsitems/nodes/qxpainternode.cpp +++ b/src/graphicsitems/nodes/qxpainternode.cpp @@ -51,6 +51,7 @@ QxPainterNode::QxPainterNode(QxPaintItem *item) , m_multisampledFbo(0) , m_size(1, 1) , m_opacity(1.0) + , m_opaquePainting(false) , m_linear_filtering(false) , m_smoothPainting(false) , m_extensionsChecked(false) @@ -58,6 +59,7 @@ QxPainterNode::QxPainterNode(QxPaintItem *item) { setFlag(Node::UsePreprocess); setMaterial(&m_material); + updateGeometryDescription(Utilities::getTexturedRectGeometryDescription(), GL_UNSIGNED_SHORT); } QxPainterNode::~QxPainterNode() @@ -71,35 +73,7 @@ void QxPainterNode::preprocess() if (!m_item || !m_item->isDirty()) return; - if (!m_fbo) { - const QGLContext *ctx = QGLContext::currentContext(); - if (!m_extensionsChecked) { - QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); - m_multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample") - && extensions.contains("GL_EXT_framebuffer_blit"); - m_extensionsChecked = true; - } - - if (m_smoothPainting && 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); - m_fbo = new QGLFramebufferObject(m_size, format); - } - } else { - QGLFramebufferObjectFormat format; - format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - m_fbo = new QGLFramebufferObject(m_size, format); - } - updateTexture(); - } + Q_ASSERT(m_fbo != 0); QPainter fbo_painter; if (m_multisampledFbo) @@ -123,41 +97,82 @@ void QxPainterNode::preprocess() m_item->setDirty(false); } +void QxPainterNode::update(uint updateFlags) +{ + if (updateFlags & UpdateGeometry) + updateGeometry(); + if (updateFlags & (UpdateFBO | UpdateGeometry)) + updateFBO(); + if (updateFlags & (UpdateTexture | UpdateFBO)) + updateTexture(); +} + void QxPainterNode::updateTexture() { QSGTexture *texture = new QSGTexture; texture->setTextureId(m_fbo->texture()); texture->setTextureSize(m_fbo->size()); - texture->setAlphaChannel(m_item->opaquePainting()); + texture->setAlphaChannel(m_opaquePainting); texture->setOwnsTexture(false); texture->setStatus(QSGTexture::Ready); m_texture = QSGTextureRef(texture); - m_material.setTexture(m_texture, m_item->opaquePainting()); + m_material.setTexture(m_texture, m_opaquePainting); m_material.setLinearFiltering(m_linear_filtering); - m_materialO.setTexture(m_texture, m_item->opaquePainting()); + m_materialO.setTexture(m_texture, m_opaquePainting); m_materialO.setLinearFiltering(m_linear_filtering); m_materialO.setOpacity(m_opacity); setMaterial(m_opacity == 1 ? &m_material : &m_materialO); } -void QxPainterNode::setSize(const QSize &size) +void QxPainterNode::updateGeometry() { - if (size == m_size) - return; - - m_size = size; + Utilities::setupRectGeometry(geometry(), QRectF(0, 0, m_size.width(), m_size.height()), QSize(1, 1), QRectF(0,1,1,-1)); + markDirty(DirtyGeometry); +} +void QxPainterNode::updateFBO() +{ delete m_fbo; delete m_multisampledFbo; - m_fbo = 0; - m_multisampledFbo = 0; + m_fbo = m_multisampledFbo = 0; + + const QGLContext *ctx = QGLContext::currentContext(); + if (!m_extensionsChecked) { + QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); + m_multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample") + && extensions.contains("GL_EXT_framebuffer_blit"); + m_extensionsChecked = true; + } - if (geometry()->isNull()) - updateGeometryDescription(Utilities::getTexturedRectGeometryDescription(), GL_UNSIGNED_SHORT); - Utilities::setupRectGeometry(geometry(), QRectF(0, 0, size.width(), size.height()), QSize(1, 1), QRectF(0,1,1,-1)); + if (m_smoothPainting && 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); + m_fbo = new QGLFramebufferObject(m_size, format); + } + } else { + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + m_fbo = new QGLFramebufferObject(m_size, format); + } +} - markDirty(DirtyGeometry); +void QxPainterNode::setSize(const QSize &size) +{ + if (size == m_size) + return; + + m_size = size; + setBoundingRect(QRectF(0, 0, size.width(), size.height())); + setUpdateFlag(UpdateGeometry); } void QxPainterNode::setOpacity(qreal opacity) @@ -171,6 +186,15 @@ void QxPainterNode::setOpacity(qreal opacity) setMaterial(opacity == 1 ? &m_material : &m_materialO); } +void QxPainterNode::setOpaquePainting(bool opaque) +{ + if (opaque == m_opaquePainting) + return; + + m_opaquePainting = opaque; + setUpdateFlag(UpdateTexture); +} + void QxPainterNode::setLinearFiltering(bool linearFiltering) { if (linearFiltering == m_linear_filtering) @@ -189,12 +213,5 @@ void QxPainterNode::setSmoothPainting(bool s) return; m_smoothPainting = s; - - if (m_multisamplingSupported) { - delete m_fbo; - delete m_multisampledFbo; - m_fbo = 0; - m_multisampledFbo = 0; - markDirty(DirtyMaterial); - } + setUpdateFlag(UpdateFBO); } |