diff options
author | Trond Kjernåsen <trond@trolltech.com> | 2009-08-28 11:28:43 (GMT) |
---|---|---|
committer | Trond Kjernåsen <trond@trolltech.com> | 2009-08-28 13:47:02 (GMT) |
commit | 033725f5947d4a4e0c21f426664851b42b164d08 (patch) | |
tree | cec7e8b079de65251ce5ac099304068b95f32103 | |
parent | df66f388bb135d7f22632d7d98ffa0e4d8a417f3 (diff) | |
download | Qt-033725f5947d4a4e0c21f426664851b42b164d08.zip Qt-033725f5947d4a4e0c21f426664851b42b164d08.tar.gz Qt-033725f5947d4a4e0c21f426664851b42b164d08.tar.bz2 |
Fixed QGLWidget::renderText() when using the GL 2 paint engine.
QGLWidget::renderText() needs to respect the current depth and scissor
tests that the user has set. Therefore we needs some special casing in
the GL 2 paint engine to handle the custom depth testing. The private
setRenderTextActive() has been added for this purpose.
Reviewed-by: Samuel
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 85 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 8 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 36 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject.cpp | 2 |
4 files changed, 108 insertions, 23 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index cc9b014..b5a6b1f 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -219,6 +219,11 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) pex->transferMode(BrushDrawingMode); +#ifndef QT_OPENGL_ES_2 + if (pex->inRenderText) + glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_SCISSOR_BIT); +#endif + glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); @@ -268,6 +273,11 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) glViewport(0, 0, pex->width, pex->height); pex->updateDepthScissorTest(); + +#ifndef QT_OPENGL_ES_2 + if (pex->inRenderText) + glPopAttrib(); +#endif } void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) @@ -836,6 +846,11 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) glEnable(GL_STENCIL_TEST); prepareForDraw(currentBrush->isOpaque()); + +#ifndef QT_OPENGL_ES_2 + if (inRenderText) + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Depth), zValueForRenderText()); +#endif composite(vertexCoordinateArray.boundingRect()); glDisable(GL_STENCIL_TEST); @@ -873,9 +888,21 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(QGL2PEXVertexArray& ve glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d glDisable(GL_BLEND); +#ifndef QT_OPENGL_ES_2 + if (inRenderText) { + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_DEPTH_TEST); + } +#endif + // Draw the vertecies into the stencil buffer: drawVertexArrays(vertexArray, GL_TRIANGLE_FAN); +#ifndef QT_OPENGL_ES_2 + if (inRenderText) + glPopAttrib(); +#endif + // Enable color writes & disable stencil writes glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } @@ -981,9 +1008,19 @@ void QGL2PaintEngineExPrivate::drawVertexArrays(QGL2PEXVertexArray& vertexArray, glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); } - - - +float QGL2PaintEngineExPrivate::zValueForRenderText() const +{ +#ifndef QT_OPENGL_ES_2 + // Get the z translation value from the model view matrix and + // transform it using the ortogonal projection with z-near = 0, + // and z-far = 1, which is used in QGLWidget::renderText() + GLdouble model[4][4]; + glGetDoublev(GL_MODELVIEW_MATRIX, &model[0][0]); + return -2 * model[3][2] - 1; +#else + return 0; +#endif +} /////////////////////////////////// Public Methods ////////////////////////////////////////// @@ -1002,8 +1039,8 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) if (brush.style() == Qt::NoBrush) return; - - ensureActive(); + if (!d->inRenderText) + ensureActive(); d->setBrush(&brush); d->fill(path); d->setBrush(&(state()->brush)); // reset back to the state's brush @@ -1154,7 +1191,8 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem { Q_D(QGL2PaintEngineEx); - ensureActive(); + if (!d->inRenderText) + ensureActive(); QOpenGL2PaintEngineState *s = state(); const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); @@ -1203,6 +1241,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte if (cache->width() == 0 || cache->height() == 0) return; + if (inRenderText) + transferMode(BrushDrawingMode); transferMode(TextDrawingMode); if (glyphType == QFontEngineGlyphCache::Raster_A8) @@ -1241,6 +1281,11 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte prepareForDraw(false); // Text always causes src pixels to be transparent +#ifndef QT_OPENGL_ES_2 + if (inRenderText) + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Depth), zValueForRenderText()); +#endif + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::MaskTexture), QT_MASK_TEXTURE_UNIT); if (vertexCoordinateArray.data() != oldVertexCoordinateDataPtr) @@ -1286,12 +1331,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) glViewport(0, 0, d->width, d->height); -// glClearColor(0.0, 1.0, 0.0, 1.0); -// glClear(GL_COLOR_BUFFER_BIT); -// d->ctx->swapBuffers(); -// qDebug("You should see green now"); -// sleep(5); - d->brushTextureDirty = true; d->brushUniformsDirty = true; d->matrixDirty = true; @@ -1304,10 +1343,12 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->use_system_clip = !systemClip().isEmpty(); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDepthFunc(GL_LEQUAL); - glDepthMask(false); + if (!d->inRenderText) { + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glDepthFunc(GL_LEQUAL); + glDepthMask(false); + } #if !defined(QT_OPENGL_ES_2) glDisable(GL_MULTISAMPLE); @@ -1612,7 +1653,11 @@ void QGL2PaintEngineExPrivate::regenerateDepthClip() void QGL2PaintEngineExPrivate::systemStateChanged() { Q_Q(QGL2PaintEngineEx); - use_system_clip = !systemClip.isEmpty(); + + if (q->paintDevice()->devType() == QInternal::Widget) + use_system_clip = false; + else + use_system_clip = !systemClip.isEmpty(); glDisable(GL_DEPTH_TEST); q->state()->depthTestEnabled = false; @@ -1728,6 +1773,12 @@ QPainterState *QGL2PaintEngineEx::createState(QPainterState *orig) const return s; } +void QGL2PaintEngineEx::setRenderTextActive(bool active) +{ + Q_D(QGL2PaintEngineEx); + d->inRenderText = active; +} + QOpenGL2PaintEngineState::QOpenGL2PaintEngineState(QOpenGL2PaintEngineState &other) : QPainterState(other) { diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 66e7a51..68447bc 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -141,6 +141,8 @@ public: QPixmapFilter *createPixmapFilter(int type) const; + void setRenderTextActive(bool); + private: Q_DISABLE_COPY(QGL2PaintEngineEx) }; @@ -156,7 +158,8 @@ public: ctx(0), currentBrush(0), inverseScale(1), - shaderManager(0) + shaderManager(0), + inRenderText(false) { } ~QGL2PaintEngineExPrivate(); @@ -191,6 +194,8 @@ public: inline void useSimpleShader(); inline QColor premultiplyColor(QColor c, GLfloat opacity); + float zValueForRenderText() const; + QGL2PaintEngineEx* q; QGLDrawable drawable; int width, height; @@ -240,6 +245,7 @@ public: GLuint lastTexture; bool needsSync; + bool inRenderText; }; QT_END_NAMESPACE diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 8cf3b45..4324371 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1666,7 +1666,6 @@ QGLContext::QGLContext(const QGLFormat &format) QGLContext::~QGLContext() { - Q_D(QGLContext); // remove any textures cached in this context QGLTextureCache::instance()->removeContextTextures(this); QGLTextureCache::deleteIfEmpty(); // ### thread safety @@ -4073,6 +4072,10 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, bool auto_swap = autoBufferSwap(); QPaintEngine *engine = paintEngine(); +#ifndef QT_OPENGL_ES + if (engine->type() == QPaintEngine::OpenGL2) + static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true); +#endif QPainter *p; bool reuse_painter = false; if (engine->isActive()) { @@ -4098,6 +4101,13 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, setAutoBufferSwap(false); // disable glClear() as a result of QPainter::begin() d->glcx->d_func()->clear_on_painter_begin = false; + if (engine->type() == QPaintEngine::OpenGL2) { + qt_save_gl_state(); +#ifndef QT_OPENGL_ES_2 + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +#endif + } p = new QPainter(this); } @@ -4121,7 +4131,13 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, delete p; setAutoBufferSwap(auto_swap); d->glcx->d_func()->clear_on_painter_begin = true; + if (engine->type() == QPaintEngine::OpenGL2) + qt_restore_gl_state(); } +#ifndef QT_OPENGL_ES + if (engine->type() == QPaintEngine::OpenGL2) + static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false); +#endif } /*! \overload @@ -4154,6 +4170,10 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con win_y = height - win_y; // y is inverted QPaintEngine *engine = paintEngine(); +#ifndef QT_OPENGL_ES + if (engine->type() == QPaintEngine::OpenGL2) + static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(true); +#endif QPainter *p; bool reuse_painter = false; #ifndef QT_OPENGL_ES @@ -4172,6 +4192,8 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con setAutoBufferSwap(false); // disable glClear() as a result of QPainter::begin() d->glcx->d_func()->clear_on_painter_begin = false; + if (engine->type() == QPaintEngine::OpenGL2) + qt_save_gl_state(); p = new QPainter(this); } @@ -4210,9 +4232,15 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con } else { p->end(); delete p; + if (engine->type() == QPaintEngine::OpenGL2) + qt_restore_gl_state(); setAutoBufferSwap(auto_swap); d->glcx->d_func()->clear_on_painter_begin = true; } +#ifndef QT_OPENGL_ES + if (engine->type() == QPaintEngine::OpenGL2) + static_cast<QGL2PaintEngineEx *>(engine)->setRenderTextActive(false); +#endif } QGLFormat QGLWidget::format() const @@ -4443,10 +4471,10 @@ QPaintEngine *QGLWidget::paintEngine() const #elif defined(QT_OPENGL_ES_2) return qt_gl_2_engine(); #else - if (!qt_gl_preferGL2Engine()) - return qt_gl_engine(); - else + if (qt_gl_preferGL2Engine()) return qt_gl_2_engine(); + else + return qt_gl_engine(); #endif } diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 0db5659..2b38e3d 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -896,7 +896,7 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const return qt_buffer_2_engine(); #else Q_D(const QGLFramebufferObject); - if (d->ctx->d_func()->internal_context || qt_gl_preferGL2Engine()) + if (qt_gl_preferGL2Engine()) return qt_buffer_2_engine(); else return qt_buffer_engine(); |