summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp1
-rw-r--r--src/opengl/qglframebufferobject.cpp11
-rw-r--r--src/opengl/qglpixmapfilter.cpp77
-rw-r--r--src/opengl/qglshaderprogram.cpp52
-rw-r--r--src/opengl/qpaintengine_opengl.cpp14
-rw-r--r--src/opengl/qpaintengine_opengl_p.h2
-rw-r--r--src/opengl/qpixmapdata_gl.cpp34
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);