summaryrefslogtreecommitdiffstats
path: root/src/graphicsitems/nodes/qxpainternode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphicsitems/nodes/qxpainternode.cpp')
-rw-r--r--src/graphicsitems/nodes/qxpainternode.cpp68
1 files changed, 61 insertions, 7 deletions
diff --git a/src/graphicsitems/nodes/qxpainternode.cpp b/src/graphicsitems/nodes/qxpainternode.cpp
index 74d2c3a..2b3edf7 100644
--- a/src/graphicsitems/nodes/qxpainternode.cpp
+++ b/src/graphicsitems/nodes/qxpainternode.cpp
@@ -48,8 +48,13 @@ QxPainterNode::QxPainterNode(QxPaintItem *item)
: GeometryNode()
, m_item(item)
, m_fbo(0)
+ , m_multisampledFbo(0)
, m_size(1, 1)
, m_opacity(1.0)
+ , m_linear_filtering(false)
+ , m_smoothPainting(false)
+ , m_extensionsChecked(false)
+ , m_multisamplingSupported(false)
{
setFlag(Node::UsePreprocess);
setMaterial(&m_material);
@@ -58,6 +63,7 @@ QxPainterNode::QxPainterNode(QxPaintItem *item)
QxPainterNode::~QxPainterNode()
{
delete m_fbo;
+ delete m_multisampledFbo;
}
void QxPainterNode::preprocess()
@@ -66,17 +72,42 @@ void QxPainterNode::preprocess()
return;
if (!m_fbo) {
- m_fbo = new QGLFramebufferObject(m_size, QGLFramebufferObject::CombinedDepthStencil);
- if (!m_fbo->isValid()) {
- delete m_fbo;
- m_fbo = 0;
- return;
+ 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();
}
- QPainter fbo_painter(m_fbo);
- if (m_item->smooth())
+ QPainter fbo_painter;
+ if (m_multisampledFbo)
+ fbo_painter.begin(m_multisampledFbo);
+ else
+ fbo_painter.begin(m_fbo);
+
+ if (m_smoothPainting)
fbo_painter.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
fbo_painter.setCompositionMode(QPainter::CompositionMode_Source);
fbo_painter.fillRect(QRectF(QPointF(0, 0), m_fbo->size()), Qt::transparent);
@@ -84,6 +115,11 @@ void QxPainterNode::preprocess()
m_item->paint(&fbo_painter);
fbo_painter.end();
+ if (m_multisampledFbo) {
+ QRect r(0, 0, m_size.width(), m_size.height());
+ QGLFramebufferObject::blitFramebuffer(m_fbo, r, m_multisampledFbo, r);
+ }
+
m_item->setDirty(false);
}
@@ -113,7 +149,9 @@ void QxPainterNode::setSize(const QSize &size)
m_size = size;
delete m_fbo;
+ delete m_multisampledFbo;
m_fbo = 0;
+ m_multisampledFbo = 0;
if (geometry()->isNull())
updateGeometryDescription(Utilities::getTexturedRectGeometryDescription(), GL_UNSIGNED_SHORT);
@@ -144,3 +182,19 @@ void QxPainterNode::setLinearFiltering(bool linearFiltering)
m_materialO.setLinearFiltering(linearFiltering);
setMaterial(m_opacity == 1 ? &m_material : &m_materialO);
}
+
+void QxPainterNode::setSmoothPainting(bool s)
+{
+ if (s == m_smoothPainting)
+ return;
+
+ m_smoothPainting = s;
+
+ if (m_multisamplingSupported) {
+ delete m_fbo;
+ delete m_multisampledFbo;
+ m_fbo = 0;
+ m_multisampledFbo = 0;
+ markDirty(DirtyMaterial);
+ }
+}