diff options
Diffstat (limited to 'src/opengl/gl2paintengineex')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 94 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 3 |
2 files changed, 80 insertions, 17 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index db306a5..10259d2 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1364,10 +1364,30 @@ void QGL2PaintEngineExPrivate::updateDepthScissorTest() else glDisable(GL_DEPTH_TEST); - if (q->state()->scissorTestEnabled) + if (q->state()->scissorTestEnabled) { + QRect bounds = q->state()->rectangleClip; + if (bounds.isNull() || !q->painter()->hasClipping()) { + if (use_system_clip) + bounds = systemClip.boundingRect(); + else + bounds = QRect(0, 0, width, height); + } + glEnable(GL_SCISSOR_TEST); - else + setScissor(bounds); + } else { glDisable(GL_SCISSOR_TEST); + } +} + +void QGL2PaintEngineExPrivate::setScissor(const QRect &rect) +{ + const int left = rect.left(); + const int width = rect.width(); + const int bottom = height - (rect.top() + rect.height()); + const int height = rect.height(); + + glScissor(left, bottom, width, height); } void QGL2PaintEngineEx::clipEnabledChanged() @@ -1383,9 +1403,10 @@ void QGL2PaintEngineEx::clipEnabledChanged() if (d->use_system_clip) { state()->currentDepth = -0.5f; } else { - glDisable(GL_DEPTH_TEST); state()->depthTestEnabled = false; } + + d->updateDepthScissorTest(); } } @@ -1457,9 +1478,42 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) if ((d->use_system_clip && rect.contains(d->systemClip.boundingRect())) || rect.contains(QRect(0, 0, d->width, d->height))) return; + + if (state()->rectangleClip.isValid()) { + state()->rectangleClip = state()->rectangleClip.intersected(rect.toRect()); + + state()->hasRectangleClip = true; + state()->scissorTestEnabled = true; + + glEnable(GL_SCISSOR_TEST); + d->setScissor(state()->rectangleClip); + + return; + } } } + if (!state()->hasRectangleClip) + state()->rectangleClip = QRect(); + + if (state()->rectangleClip.isValid() && op != Qt::NoClip && op != Qt::ReplaceClip) { + QPainterPath path; + path.addRect(state()->rectangleClip); + + state()->rectangleClip = QRect(); + d->updateDepthScissorTest(); + + glDepthFunc(GL_ALWAYS); + + state()->maxDepth = 0.5f; + d->writeClip(qtVectorPathForPath(path), state()->maxDepth); + state()->currentDepth = 0.25f; + state()->depthTestEnabled = true; + + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + } + switch (op) { case Qt::NoClip: if (d->use_system_clip) { @@ -1480,6 +1534,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) break; case Qt::ReplaceClip: d->systemStateChanged(); + state()->rectangleClip = QRect(); state()->maxDepth = 0.5f; glDepthFunc(GL_ALWAYS); d->writeClip(path, state()->maxDepth); @@ -1518,27 +1573,30 @@ void QGL2PaintEngineExPrivate::systemStateChanged() q->state()->depthTestEnabled = false; q->state()->scissorTestEnabled = false; q->state()->needsDepthBufferClear = true; + q->state()->hasRectangleClip = false; glDisable(GL_SCISSOR_TEST); q->state()->currentDepth = -0.5f; q->state()->maxDepth = 0.5f; - if (use_system_clip) { - QRect bounds = systemClip.boundingRect(); - if (systemClip.numRects() == 1 - && bounds == QRect(0, 0, width, height)) - { - q->state()->needsDepthBufferClear = true; - } else { - glEnable(GL_SCISSOR_TEST); + q->state()->rectangleClip = QRect(0, 0, width, height); - const int left = bounds.left(); - const int width = bounds.width(); - const int bottom = height - (bounds.top() + bounds.height()); - const int height = bounds.height(); + if (use_system_clip) { + if (systemClip.numRects() == 1) { + QRect bounds = systemClip.boundingRect(); + if (bounds == QRect(0, 0, width, height)) { + use_system_clip = false; + return; + } - glScissor(left, bottom, width, height); + q->state()->rectangleClip = bounds; + q->state()->scissorTestEnabled = true; + updateDepthScissorTest(); + } else { + q->state()->rectangleClip = QRect(); + q->state()->scissorTestEnabled = true; + updateDepthScissorTest(); QTransform transform = q->state()->matrix; q->state()->matrix = QTransform(); @@ -1560,7 +1618,6 @@ void QGL2PaintEngineExPrivate::systemStateChanged() glEnable(GL_DEPTH_TEST); q->state()->depthTestEnabled = true; - q->state()->scissorTestEnabled = true; q->state()->matrix = transform; q->transformChanged(); @@ -1635,6 +1692,8 @@ QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &oth currentDepth = other.currentDepth; maxDepth = other.maxDepth; canRestoreClip = other.canRestoreClip; + rectangleClip = other.rectangleClip; + hasRectangleClip = other.hasRectangleClip; } QOpenGL2PaintEngineState::QOpenGL2PaintEngineState() @@ -1645,6 +1704,7 @@ QOpenGL2PaintEngineState::QOpenGL2PaintEngineState() currentDepth = -0.5f; maxDepth = 0.5f; canRestoreClip = true; + hasRectangleClip = false; } QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState() diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 6a96877..a5fe8a1 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -86,6 +86,8 @@ public: qreal maxDepth; bool canRestoreClip; + QRect rectangleClip; + bool hasRectangleClip; }; class Q_OPENGL_EXPORT QGL2PaintEngineEx : public QPaintEngineEx @@ -222,6 +224,7 @@ public: void writeClip(const QVectorPath &path, float depth); void updateDepthScissorTest(); + void setScissor(const QRect &rect); void regenerateDepthClip(); void systemStateChanged(); uint use_system_clip : 1; |