diff options
author | Gunnar Sletta <gunnar@trolltech.com> | 2009-08-28 13:51:22 (GMT) |
---|---|---|
committer | Gunnar Sletta <gunnar@trolltech.com> | 2009-08-28 13:51:22 (GMT) |
commit | 31a0ef1d1dd55096652c1c4f0501fce2937a1b23 (patch) | |
tree | f728a2e5829e26ed75bfd465d07b336fc77e599f /src/opengl | |
parent | 7c2620578ba0698a14c1d4ff5c7a4e260f06ad31 (diff) | |
parent | bd3cd571ac061b0ed0e8c001c90c4edeafae67d7 (diff) | |
download | Qt-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.cpp | 85 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 8 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 56 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject.cpp | 10 |
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(); |