summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-06-12 12:05:22 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-06-12 12:41:52 (GMT)
commitd834d94bde645d43dd981154bd0ba99d8e81f040 (patch)
tree5164895fa6ba6582b40fe285296a680c409ff420
parent8a2993a6c53e1a5641bd1c500ad4bd54e799299b (diff)
downloadQt-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.cpp2
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp11
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h17
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp26
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h2
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);