From 3d2160056e409ad2508a8bff4288944d37e32f85 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 12 Mar 2014 13:38:24 +0100 Subject: Resurrect QGLWidget::renderText() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The variant taking x, y, z has been broken in all Qt 5.x releases. This is now corrected by making the GL2 paint engine capable of applying a Z translation. Task-number: QTBUG-31156 Change-Id: I119566e9e9577f6cdf7e8bae56cac1e34995e622 Reviewed-by: Jørgen Lind --- .../gl2paintengineex/qglengineshadermanager.cpp | 3 ++- .../gl2paintengineex/qglengineshadermanager_p.h | 1 + .../gl2paintengineex/qglengineshadersource_p.h | 5 ++++- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 17 +++++++++++++++++ .../gl2paintengineex/qpaintengineex_opengl2_p.h | 9 ++++++++- src/opengl/qgl.cpp | 20 ++++++++------------ 6 files changed, 40 insertions(+), 15 deletions(-) (limited to 'src/opengl') diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 56f3f5ad0a..f266318ba6 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -534,7 +534,8 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) "invertedTextureSize", "brushTransform", "brushTexture", - "matrix" + "matrix", + "translateZ" }; if (uniformLocations.at(id) == GLuint(-1)) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index bbd9d86773..166d9a0593 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -444,6 +444,7 @@ public: BrushTransform, BrushTexture, Matrix, + TranslateZ, NumUniforms }; diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 90bd7edf54..aad2c1f7db 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -106,10 +106,13 @@ static const char* const qglslPositionOnlyVertexShader = "\n\ static const char* const qglslComplexGeometryPositionOnlyVertexShader = "\n\ uniform highp mat3 matrix; \n\ + uniform highp float translateZ; \n\ attribute highp vec2 vertexCoordsArray; \n\ void setPosition(void) \n\ { \n\ - gl_Position = vec4(matrix * vec3(vertexCoordsArray, 1), 1);\n\ + vec3 v = matrix * vec3(vertexCoordsArray, 1.0); \n\ + vec4 vz = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, translateZ, 1) * vec4(v, 1.0); \n\ + gl_Position = vec4(vz.xyz, 1.0);\n\ } \n"; static const char* const qglslUntransformedPositionVertexShader = "\n\ diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index fd64a4a71f..2b49e4d2d1 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1158,6 +1158,7 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) brushUniformsDirty = true; opacityUniformDirty = true; matrixUniformDirty = true; + translateZUniformDirty = true; } if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) @@ -1174,6 +1175,12 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) matrixUniformDirty = false; } + if (translateZUniformDirty && shaderManager->hasComplexGeometry()) { + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::TranslateZ), + translateZ); + translateZUniformDirty = false; + } + return changed; } @@ -2011,6 +2018,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->matrixDirty = true; d->compositionModeDirty = true; d->opacityUniformDirty = true; + d->translateZUniformDirty = true; d->needsSync = true; d->useSystemClip = !systemClip().isEmpty(); d->currentBrush = QBrush(); @@ -2375,6 +2383,15 @@ void QGL2PaintEngineExPrivate::systemStateChanged() } } +void QGL2PaintEngineEx::setTranslateZ(GLfloat z) +{ + Q_D(QGL2PaintEngineEx); + if (d->translateZ != z) { + d->translateZ = z; + d->translateZUniformDirty = true; + } +} + void QGL2PaintEngineEx::setState(QPainterState *new_state) { // qDebug("QGL2PaintEngineEx::setState()"); diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 33a8869ecf..15ed5bc57d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -158,6 +158,9 @@ public: bool isNativePaintingActive() const; bool requiresPretransformedGlyphPositions(QFontEngine *, const QTransform &) const { return false; } bool shouldDrawCachedGlyphs(QFontEngine *, const QTransform &) const; + + void setTranslateZ(GLfloat z); + private: Q_DISABLE_COPY(QGL2PaintEngineEx) }; @@ -183,7 +186,8 @@ public: snapToPixelGrid(false), nativePaintingActive(false), inverseScale(1), - lastMaskTextureUsed(0) + lastMaskTextureUsed(0), + translateZ(0) { } ~QGL2PaintEngineExPrivate(); @@ -266,6 +270,7 @@ public: bool brushUniformsDirty; bool opacityUniformDirty; bool matrixUniformDirty; + bool translateZUniformDirty; bool stencilClean; // Has the stencil not been used for clipping so far? bool useSystemClip; @@ -309,6 +314,8 @@ public: QVector unusedIBOSToClean; const GLfloat *vertexAttribPointers[3]; + + GLfloat translateZ; }; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 1fbff0f0fe..d676abee47 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4451,12 +4451,6 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) glDisable(GL_DEPTH_TEST); glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, height, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - - glLoadIdentity(); } else { setAutoBufferSwap(false); // disable glClear() as a result of QPainter::begin() @@ -4567,19 +4561,21 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con } else if (use_scissor_testing) { glEnable(GL_SCISSOR_TEST); } - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); glViewport(0, 0, width, height); - glOrtho(0, width, height, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); glAlphaFunc(GL_GREATER, 0.0); glEnable(GL_ALPHA_TEST); if (use_depth_testing) glEnable(GL_DEPTH_TEST); - glTranslated(0, 0, -win_z); + + // The only option in Qt 5 is the shader-based OpenGL 2 paint engine. + // Setting fixed pipeline transformations is futile. Instead, pass the + // extra values directly and let the engine figure the matrices out. + static_cast(p->paintEngine())->setTranslateZ(-win_z); + qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font); + static_cast(p->paintEngine())->setTranslateZ(0); + if (!reuse_painter) { p->end(); delete p; -- cgit v1.2.3