Resurrect QGLWidget::renderText()

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 <jorgen.lind@digia.com>
This commit is contained in:
Laszlo Agocs 2014-03-12 13:38:24 +01:00 committed by The Qt Project
parent 77bf302ce2
commit 3d2160056e
6 changed files with 40 additions and 15 deletions

View File

@ -534,7 +534,8 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id)
"invertedTextureSize",
"brushTransform",
"brushTexture",
"matrix"
"matrix",
"translateZ"
};
if (uniformLocations.at(id) == GLuint(-1))

View File

@ -444,6 +444,7 @@ public:
BrushTransform,
BrushTexture,
Matrix,
TranslateZ,
NumUniforms
};

View File

@ -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\

View File

@ -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()");

View File

@ -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<GLuint> unusedIBOSToClean;
const GLfloat *vertexAttribPointers[3];
GLfloat translateZ;
};

View File

@ -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<QGL2PaintEngineEx *>(p->paintEngine())->setTranslateZ(-win_z);
qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
static_cast<QGL2PaintEngineEx *>(p->paintEngine())->setTranslateZ(0);
if (!reuse_painter) {
p->end();
delete p;