summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@trolltech.com>2009-08-28 13:51:22 (GMT)
committerGunnar Sletta <gunnar@trolltech.com>2009-08-28 13:51:22 (GMT)
commit31a0ef1d1dd55096652c1c4f0501fce2937a1b23 (patch)
treef728a2e5829e26ed75bfd465d07b336fc77e599f /src/opengl
parent7c2620578ba0698a14c1d4ff5c7a4e260f06ad31 (diff)
parentbd3cd571ac061b0ed0e8c001c90c4edeafae67d7 (diff)
downloadQt-31a0ef1d1dd55096652c1c4f0501fce2937a1b23.zip
Qt-31a0ef1d1dd55096652c1c4f0501fce2937a1b23.tar.gz
Qt-31a0ef1d1dd55096652c1c4f0501fce2937a1b23.tar.bz2
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt into 4.6
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp85
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h8
-rw-r--r--src/opengl/qgl.cpp56
-rw-r--r--src/opengl/qglframebufferobject.cpp10
4 files changed, 130 insertions, 29 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 612ba1b..f2aabd2 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
@@ -1156,7 +1193,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);
@@ -1205,6 +1243,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)
@@ -1243,6 +1283,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)
@@ -1288,12 +1333,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;
@@ -1306,10 +1345,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);
@@ -1614,7 +1655,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;
@@ -1730,6 +1775,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 b4c7e10..f3265b4 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1672,7 +1672,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
@@ -2185,6 +2184,9 @@ GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format)
The \a format parameter sets the internal format for the
texture. The default format is \c GL_RGBA.
+ The binding \a options are a set of options used to decide how to
+ bind the texture to the context.
+
The texture that is generated is cached, so multiple calls to
bindTexture() with the same QImage will return the same texture
id.
@@ -2235,7 +2237,7 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint forma
\overload
Generates and binds a 2D GL texture to the current context, based
- on \a image.
+ on \a pixmap.
*/
GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, BindOptions options)
{
@@ -4076,6 +4078,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()) {
@@ -4101,6 +4107,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);
}
@@ -4124,7 +4137,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
@@ -4157,6 +4176,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
@@ -4175,6 +4198,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);
}
@@ -4213,9 +4238,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
@@ -4260,8 +4291,12 @@ GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format)
return d->glcx->bindTexture(image, target, format, QGLContext::DefaultBindOption);
}
+/*!
+ \overload
-
+ The binding \a options are a set of options used to decide how to
+ bind the texture to the context.
+ */
GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format, QGLContext::BindOptions options)
{
Q_D(QGLWidget);
@@ -4297,6 +4332,15 @@ GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format
return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption);
}
+/*!
+ \overload
+
+ Generates and binds a 2D GL texture to the current context, based
+ on \a pixmap. The generated texture id is returned and can be used in
+
+ The binding \a options are a set of options used to decide how to
+ bind the texture to the context.
+ */
GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format,
QGLContext::BindOptions options)
{
@@ -4433,10 +4477,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 52363cb..2b38e3d 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -516,12 +516,12 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
framebuffer objects more portable.
\endlist
+ When using a QPainter to paint to a QGLFramebufferObject you should take
+ care that the QGLFramebufferObject is created with the CombinedDepthStencil
+ attachment for QPainter to be able to render correctly.
Note that you need to create a QGLFramebufferObject with more than one
sample per pixel for primitives to be antialiased when drawing using a
- QPainter, unless if the QPainter::HighQualityAntialiasing render hint is
- set. The QPainter::HighQualityAntialiasing render hint will enable
- antialiasing as long as the \c{GL_ARB_fragment_program} extension is
- present. To create a multisample framebuffer object you should use one of
+ QPainter. To create a multisample framebuffer object you should use one of
the constructors that take a QGLFramebufferObject parameter, and set the
QGLFramebufferObject::samples() property to a non-zero value.
@@ -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();