diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-06-12 12:05:22 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-06-12 12:41:52 (GMT) |
commit | d834d94bde645d43dd981154bd0ba99d8e81f040 (patch) | |
tree | 5164895fa6ba6582b40fe285296a680c409ff420 | |
parent | 8a2993a6c53e1a5641bd1c500ad4bd54e799299b (diff) | |
download | Qt-d834d94bde645d43dd981154bd0ba99d8e81f040.zip Qt-d834d94bde645d43dd981154bd0ba99d8e81f040.tar.gz Qt-d834d94bde645d43dd981154bd0ba99d8e81f040.tar.bz2 |
Fixed incorrect rendering of bitmap/pattern brushes in GL 2 engine.
The pen color should be used when drawPixmap is called with a bitmap,
and the brush color should be used for texture patterns that are
bitmaps.
Task-number: 245802
Reviewed-by: Trond
-rw-r--r-- | src/gui/painting/qbrush.cpp | 2 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qglengineshadermanager.cpp | 11 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qglengineshadermanager_p.h | 8 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qglengineshadersource_p.h | 17 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 26 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 2 |
6 files changed, 57 insertions, 9 deletions
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 854d0aa..ea93764 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -217,7 +217,7 @@ struct QTexturedBrushData : public QBrushData // returns true if the brush has a pixmap (or bitmap) set as the // brush texture, false otherwise -bool qHasPixmapTexture(const QBrush& brush) +bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush& brush) { if (brush.style() != Qt::TexturePattern) return false; diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 5c541d0..b71c4c1 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -107,9 +107,11 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) code[MainFragmentShader] = qglslMainFragmentShader; code[ImageSrcFragmentShader] = qglslImageSrcFragmentShader; + code[ImageSrcWithPatternFragmentShader] = qglslImageSrcWithPatternFragmentShader; code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader; code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader; code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader; + code[TextureBrushSrcWithPatternFragmentShader] = qglslTextureBrushSrcWithPatternFragmentShader; code[PatternBrushSrcFragmentShader] = qglslPatternBrushSrcFragmentShader; code[LinearGradientBrushSrcFragmentShader] = qglslLinearGradientBrushSrcFragmentShader; code[RadialGradientBrushSrcFragmentShader] = qglslRadialGradientBrushSrcFragmentShader; @@ -296,6 +298,15 @@ bool QGLEngineShaderManager::useCorrectShaderProg() srcPixelFragShaderName = ImageSrcFragmentShader; positionVertexShaderName = PositionOnlyVertexShader; break; + case QGLEngineShaderManager::PatternSrc: + srcPixelFragShaderName = ImageSrcWithPatternFragmentShader; + positionVertexShaderName = PositionOnlyVertexShader; + break; + case QGLEngineShaderManager::TextureSrcWithPattern: + srcPixelFragShaderName = TextureBrushSrcWithPatternFragmentShader; + positionVertexShaderName = isAffine ? AffinePositionWithTextureBrushVertexShader + : PositionWithTextureBrushVertexShader; + break; case QGLEngineShaderManager::NonPremultipliedImageSrc: srcPixelFragShaderName = NonPremultipliedImageSrcFragmentShader; positionVertexShaderName = PositionOnlyVertexShader; diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index afbc918..4a55eca 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -129,9 +129,11 @@ Brushes & image drawing are implementations of "qcolorp vec4 srcPixel()": qglslImageSrcFragShader + qglslImageSrcWithPatternFragShader qglslNonPremultipliedImageSrcFragShader qglslSolidBrushSrcFragShader qglslTextureBrushSrcFragShader + qglslTextureBrushWithPatternFragShader qglslPatternBrushSrcFragShader qglslLinearGradientBrushSrcFragShader qglslRadialGradientBrushSrcFragShader @@ -265,7 +267,9 @@ public: enum MaskType {NoMask, PixelMask, SubPixelMask, SubPixelWithGammaMask}; enum PixelSrcType { ImageSrc = Qt::TexturePattern+1, - NonPremultipliedImageSrc = Qt::TexturePattern+2 + NonPremultipliedImageSrc = Qt::TexturePattern+2, + PatternSrc = Qt::TexturePattern+3, + TextureSrcWithPattern = Qt::TexturePattern+4 }; // There are optimisations we can do, depending on the brush transform: @@ -313,9 +317,11 @@ public: MainFragmentShader, ImageSrcFragmentShader, + ImageSrcWithPatternFragmentShader, NonPremultipliedImageSrcFragmentShader, SolidBrushSrcFragmentShader, TextureBrushSrcFragmentShader, + TextureBrushSrcWithPatternFragmentShader, PatternBrushSrcFragmentShader, LinearGradientBrushSrcFragmentShader, RadialGradientBrushSrcFragmentShader, diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 70cc67e..61cc63e 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -130,7 +130,7 @@ static const char* const qglslPatternBrushSrcFragmentShader = "\ uniform lowp vec4 patternColor; \ varying mediump vec2 patternTexCoords;\ lowp vec4 srcPixel() { \ - return patternColor * texture2D(brushTexture, patternTexCoords).r; \ + return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \ }\n"; @@ -278,6 +278,13 @@ static const char* const qglslTextureBrushSrcFragmentShader = "\ return texture2D(brushTexture, brushTextureCoords); \ }"; +static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\ + varying mediump vec2 brushTextureCoords; \ + uniform lowp vec4 patternColor; \ + uniform sampler2D brushTexture; \ + lowp vec4 srcPixel() { \ + return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \ + }"; // Solid Fill Brush static const char* const qglslSolidBrushSrcFragmentShader = "\ @@ -293,6 +300,14 @@ static const char* const qglslImageSrcFragmentShader = "\ return texture2D(imageTexture, textureCoords); \ }"; +static const char* const qglslImageSrcWithPatternFragmentShader = "\ + varying highp vec2 textureCoords; \ + uniform lowp vec4 patternColor; \ + uniform sampler2D imageTexture; \ + lowp vec4 srcPixel() { \ + return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \ + }\n"; + static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\ varying highp vec2 textureCoords; \ uniform sampler2D imageTexture; \ diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index bdea187..d1c6e9f 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -279,7 +279,13 @@ void QGL2PaintEngineExPrivate::setBrush(const QBrush* brush) currentBrush = brush; brushTextureDirty = true; brushUniformsDirty = true; - shaderManager->setSrcPixelType(currentBrush->style()); + if (currentBrush->style() == Qt::TexturePattern + && qHasPixmapTexture(*brush) && brush->texture().isQBitmap()) + { + shaderManager->setSrcPixelType(QGLEngineShaderManager::TextureSrcWithPattern); + } else { + shaderManager->setSrcPixelType(currentBrush->style()); + } shaderManager->optimiseForBrushTransform(currentBrush->transform()); } @@ -314,7 +320,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() if ( (style >= Qt::Dense1Pattern) && (style <= Qt::DiagCrossPattern) ) { // Get the image data for the pattern - QImage texImage = qt_imageForBrush(style, true); + QImage texImage = qt_imageForBrush(style, false); glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, true); @@ -432,6 +438,11 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() const QPixmap& texPixmap = currentBrush->texture(); + if (qHasPixmapTexture(*currentBrush) && currentBrush->texture().isQBitmap()) { + QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity); + shaderManager->currentProgram()->setUniformValue("patternColor", col); + } + QSizeF invertedTextureSize( 1.0 / texPixmap.width(), 1.0 / texPixmap.height() ); shaderManager->currentProgram()->setUniformValue("invertedTextureSize", invertedTextureSize); @@ -578,17 +589,22 @@ static inline void setCoords(GLfloat *coords, const QGLRect &rect) coords[7] = rect.bottom; } -void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque) +void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern) { transferMode(ImageDrawingMode); updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); // Setup for texture drawing - shaderManager->setSrcPixelType(QGLEngineShaderManager::ImageSrc); + shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); shaderManager->setTextureCoordsEnabled(true); prepareForDraw(opaque); + if (pattern) { + QColor col = premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity); + shaderManager->currentProgram()->setUniformValue("patternColor", col); + } + shaderManager->currentProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); GLfloat dx = 1.0 / textureSize.width(); @@ -987,7 +1003,7 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true); //FIXME: we should use hasAlpha() instead, but that's SLOW at the moment - d->drawTexture(dest, src, pixmap.size(), !pixmap.hasAlphaChannel()); + d->drawTexture(dest, src, pixmap.size(), !pixmap.hasAlphaChannel(), pixmap.depth() == 1); } void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src, diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index db39ced..8a50096 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -165,7 +165,7 @@ public: // fill, drawOutline, drawTexture & drawCachedGlyphs are the rendering entry points: void fill(const QVectorPath &path); void drawOutline(const QVectorPath& path); - void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque); + void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); void drawVertexArrays(QGL2PEXVertexArray& vertexArray, GLenum primitive); |