diff options
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 1 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject.cpp | 11 | ||||
-rw-r--r-- | src/opengl/qglpixmapfilter.cpp | 77 | ||||
-rw-r--r-- | src/opengl/qglshaderprogram.cpp | 52 | ||||
-rw-r--r-- | src/opengl/qpaintengine_opengl.cpp | 14 | ||||
-rw-r--r-- | src/opengl/qpaintengine_opengl_p.h | 2 | ||||
-rw-r--r-- | src/opengl/qpixmapdata_gl.cpp | 34 |
7 files changed, 78 insertions, 113 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 5e790cf..e41d0b4 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1385,6 +1385,7 @@ void QGL2PaintEngineEx::ensureActive() d->device->ensureActiveTarget(); if (d->needsSync) { + d->transferMode(BrushDrawingMode); glViewport(0, 0, d->width, d->height); glDepthMask(false); glDepthFunc(GL_LESS); diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 4b8a67e..e4cef5f 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -66,6 +66,11 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool); #define QGL_FUNC_CONTEXT QGLContextGroup *ctx = d_ptr->ctx; +#ifndef QT_NO_DEBUG +#define QT_RESET_GLERROR() \ +{ \ + while (glGetError() != GL_NO_ERROR) {} \ +} #define QT_CHECK_GLERROR() \ { \ GLenum err = glGetError(); \ @@ -74,6 +79,10 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool); __FILE__, __LINE__, (int)err); \ } \ } +#else +#define QT_RESET_GLERROR() {} +#define QT_CHECK_GLERROR() {} +#endif /*! \class QGLFramebufferObjectFormat @@ -407,7 +416,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, target = texture_target; // texture dimensions - while (glGetError() != GL_NO_ERROR) {} // reset error state + QT_RESET_GLERROR(); // reset error state glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo); diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 6ebc397..43f1990 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -68,17 +68,15 @@ void QGLPixmapFilterBase::drawImpl(QPainter *painter, const QPointF &pos, const processGL(painter, pos, src, source); } -class QGLPixmapColorizeFilter: public QGLPixmapFilter<QPixmapColorizeFilter> +class QGLPixmapColorizeFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapColorizeFilter> { public: QGLPixmapColorizeFilter(); + void setUniforms(QGLShaderProgram *program); + protected: bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const; - -private: - mutable QGLShaderProgram m_program; - int m_colorUniform; }; class QGLPixmapConvolutionFilter: public QGLPixmapFilter<QPixmapConvolutionFilter> @@ -105,7 +103,6 @@ class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter< { public: QGLPixmapBlurFilter(); - ~QGLPixmapBlurFilter(); void setUniforms(QGLShaderProgram *program); @@ -115,13 +112,13 @@ protected: private: static QByteArray generateBlurShader(int radius, bool gaussianBlur); - mutable QGLShader *m_shader; - mutable QSize m_textureSize; mutable bool m_horizontalBlur; - QGLShaderProgram *m_program; + mutable bool m_haveCached; + mutable int m_cachedRadius; + mutable Qt::TransformationMode m_cachedQuality; }; extern QGLWidget *qt_gl_share_widget(); @@ -183,41 +180,38 @@ static void qgl_drawTexture(const QRectF &rect, int tx_width, int tx_height, con } static const char *qt_gl_colorize_filter = - "uniform sampler2D texture;" - "uniform vec3 color;" - "void main(void)" + "uniform lowp vec4 colorizeColor;" + "uniform lowp float colorizeStrength;" + "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)" "{" - " vec2 coords = gl_TexCoord[0].st;" - " vec4 src = texture2D(texture, coords);" - " float gray = dot(src.rgb, vec3(0.212671, 0.715160, 0.072169));" - " vec3 colorizeed = 1.0-((1.0-gray)*(1.0-color));" - " gl_FragColor = vec4(colorizeed, src.a);" + " lowp vec4 srcPixel = texture2D(src, srcCoords);" + " lowp float gray = dot(srcPixel.rgb, vec3(0.212671, 0.715160, 0.072169));" + " lowp vec3 colorized = 1.0-((1.0-gray)*(1.0-colorizeColor.rgb));" + " return vec4(mix(srcPixel.rgb, colorized * srcPixel.a, colorizeStrength), srcPixel.a);" "}"; QGLPixmapColorizeFilter::QGLPixmapColorizeFilter() { - m_program.addShader(QGLShader::FragmentShader, qt_gl_colorize_filter); - m_program.link(); - m_program.enable(); - m_program.setUniformValue(m_program.uniformLocation("texture"), GLint(0)); // GL_TEXTURE_0 - m_colorUniform = m_program.uniformLocation("color"); + setSource(qt_gl_colorize_filter); } -bool QGLPixmapColorizeFilter::processGL(QPainter *, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const +bool QGLPixmapColorizeFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const { - bindTexture(src); - - QColor col = color(); - m_program.enable(); - m_program.setUniformValue(m_colorUniform, col.redF(), col.greenF(), col.blueF()); + QGLPixmapColorizeFilter *filter = const_cast<QGLPixmapColorizeFilter *>(this); - QRectF target = (srcRect.isNull() ? QRectF(src.rect()) : srcRect).translated(pos); - qgl_drawTexture(target, src.width(), src.height(), srcRect); - m_program.disable(); + filter->setOnPainter(painter); + painter->drawPixmap(pos, src); + filter->removeFromPainter(painter); return true; } +void QGLPixmapColorizeFilter::setUniforms(QGLShaderProgram *program) +{ + program->setUniformValue("colorizeColor", color()); + program->setUniformValue("colorizeStrength", float(strength())); +} + // generates convolution filter code for arbitrary sized kernel QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const { QByteArray code; @@ -311,17 +305,26 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *, const QPointF &pos, const } QGLPixmapBlurFilter::QGLPixmapBlurFilter() -{ -} - -QGLPixmapBlurFilter::~QGLPixmapBlurFilter() + : m_haveCached(false), m_cachedRadius(5), + m_cachedQuality(Qt::FastTransformation) { } bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const { QGLPixmapBlurFilter *filter = const_cast<QGLPixmapBlurFilter *>(this); - filter->setSource(generateBlurShader(radius(), quality() == Qt::SmoothTransformation)); + + int radius = this->radius(); + Qt::TransformationMode quality = this->quality(); + + if (!m_haveCached || radius != m_cachedRadius || + quality != m_cachedQuality) { + // Only regenerate the shader from source if parameters have changed. + m_haveCached = true; + m_cachedRadius = radius; + m_cachedQuality = quality; + filter->setSource(generateBlurShader(radius, quality == Qt::SmoothTransformation)); + } QGLFramebufferObjectFormat format; format.setInternalTextureFormat(GLenum(src.hasAlphaChannel() ? GL_RGBA : GL_RGB)); @@ -384,8 +387,6 @@ void QGLPixmapBlurFilter::setUniforms(QGLShaderProgram *program) program->setUniformValue("delta", 1.0, 0.0); else program->setUniformValue("delta", 0.0, 1.0); - - m_program = program; } static inline qreal gaussian(qreal dx, qreal sigma) diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 0b7fe87..ebcd723 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -70,16 +70,7 @@ QT_BEGIN_NAMESPACE program is activated in the current QGLContext by calling QGLShaderProgram::enable(): - \code - QGLShader shader(QGLShader::VertexShader); - shader.compile(code); - - QGLShaderProgram program(context); - program.addShader(shader); - program.link(); - - program.enable(); - \endcode + \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 0 \section1 Writing portable shaders @@ -107,49 +98,12 @@ QT_BEGIN_NAMESPACE \section1 Simple shader example - \code - program.addShader(QGLShader::VertexShader, - "attribute highp vec4 vertex;\n" - "attribute mediump mat4 matrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = matrix * vertex;\n" - "}"); - program.addShader(QGLShader::FragmentShader, - "uniform mediump vec4 color;\n" - "void main(void)\n" - "{\n" - " gl_FragColor = color;\n" - "}"); - program.link(); - program.enable(); - - int vertexLocation = program.attributeLocation("vertex"); - int matrixLocation = program.attributeLocation("matrix"); - int colorLocation = program.uniformLocation("color"); - \endcode + \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 1 With the above shader program active, we can draw a green triangle as follows: - \code - static GLfloat const triangleVertices[] = { - 60.0f, 10.0f, 0.0f, - 110.0f, 110.0f, 0.0f, - 10.0f, 110.0f, 0.0f - }; - - QColor color(0, 255, 0, 255); - - QMatrix4x4 pmvMatrix; - pmvMatrix.ortho(rect()); - - program.setAttributeArray(vertexLocation, triangleVertices, 3); - program.setUniformValue(matrixLocation, pmvMatrix); - program.setUniformValue(colorLocation, color); - - glDrawArrays(GL_TRIANGLES, 0, 3); - \endcode + \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2 \section1 Partial shaders diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index ff00f29..bd3883a 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -5625,20 +5625,6 @@ void QOpenGLPaintEnginePrivate::ensureDrawableTexture() #endif } -QPixmapFilter *QOpenGLPaintEngine::createPixmapFilter(int type) const -{ -#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) - if (QGLContext::currentContext()) - return QGLContext::currentContext()->d_func()->createPixmapFilter(type); - else - return 0; -#else - Q_UNUSED(type); - return 0; -#endif -} - - QT_END_NAMESPACE #include "qpaintengine_opengl.moc" diff --git a/src/opengl/qpaintengine_opengl_p.h b/src/opengl/qpaintengine_opengl_p.h index c8f460a..4fea638 100644 --- a/src/opengl/qpaintengine_opengl_p.h +++ b/src/opengl/qpaintengine_opengl_p.h @@ -136,8 +136,6 @@ public: void drawEllipse(const QRectF &rect); - QPixmapFilter *createPixmapFilter(int type) const; - #ifdef Q_WS_WIN HDC handle() const; #else diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 0bc46e1..3bc0d4f 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -98,7 +98,7 @@ QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5))); // wasting too much space? - if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 2.5) + if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4) sz = requestSize; if (sz != fboSize) { @@ -149,6 +149,7 @@ void QGLPixmapGLPaintDevice::beginPaint() if (data->needsFill()) { const QColor &c = data->fillColor(); float alpha = c.alphaF(); + glDisable(GL_SCISSOR_TEST); glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); glClear(GL_COLOR_BUFFER_BIT); } @@ -157,8 +158,23 @@ void QGLPixmapGLPaintDevice::beginPaint() // uploaded from an image or rendered into before), we need to // copy it from the texture to the render FBO. + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_BLEND); + +#if !defined(QT_OPENGL_ES_2) + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, data->width(), data->height(), 0, -999999, 999999); +#endif + + glViewport(0, 0, data->width(), data->height()); + // Pass false to bind so it doesn't copy the FBO into the texture! - context()->drawTexture(QPointF(0.0, 0.0), data->bind(false)); + context()->drawTexture(QRect(0, 0, data->width(), data->height()), data->bind(false)); } } @@ -169,12 +185,11 @@ void QGLPixmapGLPaintDevice::endPaint() data->copyBackFromRenderFbo(false); - data->m_renderFbo->release(); - qgl_fbo_pool()->release(data->m_renderFbo); - data->m_renderFbo = 0; - // Base's endPaint will restore the previous FBO binding QGLPaintDevice::endPaint(); + + qgl_fbo_pool()->release(data->m_renderFbo); + data->m_renderFbo = 0; } QGLContext* QGLPixmapGLPaintDevice::context() const @@ -452,8 +467,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const if (!ctx->d_ptr->fbo) glGenFramebuffers(1, &ctx->d_ptr->fbo); - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture.id, 0); const int x0 = 0; @@ -461,7 +476,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const const int y0 = 0; const int y1 = h; - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); + if (!m_renderFbo->isBound()) + glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); glDisable(GL_SCISSOR_TEST); |