qgraphicsshadereffect.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/opengl/qgraphicsshadereffect.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtOpenGL module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qgraphicsshadereffect_p.h"-
35-
36#ifndef QT_NO_GRAPHICSEFFECT-
37-
38#include "qglshaderprogram.h"-
39#include "gl2paintengineex/qglcustomshaderstage_p.h"-
40#define QGL_HAVE_CUSTOM_SHADERS 1-
41#include <QtGui/qpainter.h>-
42#include <QtWidgets/qgraphicsitem.h>-
43#include <private/qgraphicseffect_p.h>-
44-
45QT_BEGIN_NAMESPACE-
46-
47/*#-
48 \class QGraphicsShaderEffect-
49 \inmodule QtOpenGL-
50 \brief The QGraphicsShaderEffect class is the base class for creating-
51 custom GLSL shader effects in a QGraphicsScene.-
52 \since 4.6-
53 \ingroup multimedia-
54 \ingroup graphicsview-api-
55-
56 The specific effect is defined by a fragment of GLSL source code-
57 supplied to setPixelShaderFragment(). This source code must define a-
58 function with the signature-
59 \c{lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords)}-
60 that returns the source pixel value-
61 to use in the paint engine's shader program. The shader fragment-
62 is linked with the regular shader code used by the GL2 paint engine-
63 to construct a complete QGLShaderProgram.-
64-
65 The following example shader converts the incoming pixmap to-
66 grayscale and then applies a colorize operation using the-
67 \c effectColor value:-
68-
69 \code-
70 static char const colorizeShaderCode[] =-
71 "uniform lowp vec4 effectColor;\n"-
72 "lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) {\n"-
73 " vec4 src = texture2D(imageTexture, textureCoords);\n"-
74 " float gray = dot(src.rgb, vec3(0.212671, 0.715160, 0.072169));\n"-
75 " vec4 colorize = 1.0-((1.0-gray)*(1.0-effectColor));\n"-
76 " return vec4(colorize.rgb, src.a);\n"-
77 "}";-
78 \endcode-
79-
80 To use this shader code, it is necessary to define a subclass-
81 of QGraphicsShaderEffect as follows:-
82-
83 \code-
84 class ColorizeEffect : public QGraphicsShaderEffect-
85 {-
86 Q_OBJECT-
87 public:-
88 ColorizeEffect(QObject *parent = 0)-
89 : QGraphicsShaderEffect(parent), color(Qt::black)-
90 {-
91 setPixelShaderFragment(colorizeShaderCode);-
92 }-
93-
94 QColor effectColor() const { return color; }-
95 void setEffectColor(const QColor& c)-
96 {-
97 color = c;-
98 setUniformsDirty();-
99 }-
100-
101 protected:-
102 void setUniforms(QGLShaderProgram *program)-
103 {-
104 program->setUniformValue("effectColor", color);-
105 }-
106-
107 private:-
108 QColor color;-
109 };-
110 \endcode-
111-
112 The setUniforms() function is called when the effect is about-
113 to be used for drawing to give the subclass the opportunity to-
114 set effect-specific uniform variables.-
115-
116 QGraphicsShaderEffect is only supported when the GL2 paint engine-
117 is in use. When any other paint engine is in use (GL1, raster, etc),-
118 the drawItem() method will draw its item argument directly with-
119 no effect applied.-
120-
121 \sa QGraphicsEffect-
122*/-
123-
124static const char qglslDefaultImageFragmentShader[] = "\-
125 lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) { \-
126 return texture2D(imageTexture, textureCoords); \-
127 }\n";-
128-
129#ifdef QGL_HAVE_CUSTOM_SHADERS-
130-
131class QGLCustomShaderEffectStage : public QGLCustomShaderStage-
132{-
133public:-
134 QGLCustomShaderEffectStage-
135 (QGraphicsShaderEffect *e, const QByteArray& source)-
136 : QGLCustomShaderStage(),-
137 effect(e)-
138 {-
139 setSource(source);-
140 }
never executed: end of block
0
141-
142 void setUniforms(QGLShaderProgram *program) Q_DECL_OVERRIDE;-
143-
144 QGraphicsShaderEffect *effect;-
145};-
146-
147void QGLCustomShaderEffectStage::setUniforms(QGLShaderProgram *program)-
148{-
149 effect->setUniforms(program);-
150}
never executed: end of block
0
151-
152#endif-
153-
154class QGraphicsShaderEffectPrivate : public QGraphicsEffectPrivate-
155{-
156 Q_DECLARE_PUBLIC(QGraphicsShaderEffect)-
157public:-
158 QGraphicsShaderEffectPrivate()-
159 : pixelShaderFragment(qglslDefaultImageFragmentShader)-
160#ifdef QGL_HAVE_CUSTOM_SHADERS-
161 , customShaderStage(0)-
162#endif-
163 {-
164 }
never executed: end of block
0
165-
166 QByteArray pixelShaderFragment;-
167#ifdef QGL_HAVE_CUSTOM_SHADERS-
168 QGLCustomShaderEffectStage *customShaderStage;-
169#endif-
170};-
171-
172/*#-
173 Constructs a shader effect and attaches it to \a parent.-
174*/-
175QGraphicsShaderEffect::QGraphicsShaderEffect(QObject *parent)-
176 : QGraphicsEffect(*new QGraphicsShaderEffectPrivate(), parent)-
177{-
178}
never executed: end of block
0
179-
180/*#-
181 Destroys this shader effect.-
182*/-
183QGraphicsShaderEffect::~QGraphicsShaderEffect()-
184{-
185#ifdef QGL_HAVE_CUSTOM_SHADERS-
186 Q_D(QGraphicsShaderEffect);-
187 delete d->customShaderStage;-
188#endif-
189}
never executed: end of block
0
190-
191/*#-
192 Returns the source code for the pixel shader fragment for-
193 this shader effect. The default is a shader that copies-
194 its incoming pixmap directly to the output with no effect-
195 applied.-
196-
197 \sa setPixelShaderFragment()-
198*/-
199QByteArray QGraphicsShaderEffect::pixelShaderFragment() const-
200{-
201 Q_D(const QGraphicsShaderEffect);-
202 return d->pixelShaderFragment;
never executed: return d->pixelShaderFragment;
0
203}-
204-
205/*#-
206 Sets the source code for the pixel shader fragment for-
207 this shader effect to \a code.-
208-
209 The \a code must define a GLSL function with the signature-
210 \c{lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords)}-
211 that returns the source pixel value to use in the paint engine's-
212 shader program. The following is the default pixel shader fragment,-
213 which draws a pixmap with no effect applied:-
214-
215 \code-
216 lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) {-
217 return texture2D(imageTexture, textureCoords);-
218 }-
219 \endcode-
220-
221 \sa pixelShaderFragment(), setUniforms()-
222*/-
223void QGraphicsShaderEffect::setPixelShaderFragment(const QByteArray& code)-
224{-
225 Q_D(QGraphicsShaderEffect);-
226 if (d->pixelShaderFragment != code) {
d->pixelShaderFragment != codeDescription
TRUEnever evaluated
FALSEnever evaluated
0
227 d->pixelShaderFragment = code;-
228#ifdef QGL_HAVE_CUSTOM_SHADERS-
229 delete d->customShaderStage;-
230 d->customShaderStage = 0;-
231#endif-
232 }
never executed: end of block
0
233}
never executed: end of block
0
234-
235/*#-
236 \reimp-
237*/-
238void QGraphicsShaderEffect::draw(QPainter *painter)-
239{-
240 Q_D(QGraphicsShaderEffect);-
241-
242#ifdef QGL_HAVE_CUSTOM_SHADERS-
243 // Set the custom shader on the paint engine. The setOnPainter()-
244 // call may fail if the paint engine is not GL2. In that case,-
245 // we fall through to drawing the pixmap normally.-
246 if (!d->customShaderStage) {
!d->customShaderStageDescription
TRUEnever evaluated
FALSEnever evaluated
0
247 d->customShaderStage = new QGLCustomShaderEffectStage-
248 (this, d->pixelShaderFragment);-
249 }
never executed: end of block
0
250 bool usingShader = d->customShaderStage->setOnPainter(painter);-
251-
252 QPoint offset;-
253 if (sourceIsPixmap()) {
sourceIsPixmap()Description
TRUEnever evaluated
FALSEnever evaluated
0
254 // No point in drawing in device coordinates (pixmap will be scaled anyways).-
255 const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset);-
256 painter->drawPixmap(offset, pixmap);-
257 } else {
never executed: end of block
0
258 // Draw pixmap in device coordinates to avoid pixmap scaling.-
259 const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset);-
260 QTransform restoreTransform = painter->worldTransform();-
261 painter->setWorldTransform(QTransform());-
262 painter->drawPixmap(offset, pixmap);-
263 painter->setWorldTransform(restoreTransform);-
264 }
never executed: end of block
0
265-
266 // Remove the custom shader to return to normal painting operations.-
267 if (usingShader)
usingShaderDescription
TRUEnever evaluated
FALSEnever evaluated
0
268 d->customShaderStage->removeFromPainter(painter);
never executed: d->customShaderStage->removeFromPainter(painter);
0
269#else-
270 drawSource(painter);-
271#endif-
272}
never executed: end of block
0
273-
274/*#-
275 Sets the custom uniform variables on this shader effect to-
276 be dirty. The setUniforms() function will be called the next-
277 time the shader program corresponding to this effect is used.-
278-
279 This function is typically called by subclasses when an-
280 effect-specific parameter is changed by the application.-
281-
282 \sa setUniforms()-
283*/-
284void QGraphicsShaderEffect::setUniformsDirty()-
285{-
286#ifdef QGL_HAVE_CUSTOM_SHADERS-
287 Q_D(QGraphicsShaderEffect);-
288 if (d->customShaderStage)
d->customShaderStageDescription
TRUEnever evaluated
FALSEnever evaluated
0
289 d->customShaderStage->setUniformsDirty();
never executed: d->customShaderStage->setUniformsDirty();
0
290#endif-
291}
never executed: end of block
0
292-
293/*#-
294 Sets custom uniform variables on the current GL context when-
295 \a program is about to be used by the paint engine.-
296-
297 This function should be overridden if the shader set with-
298 setPixelShaderFragment() has additional parameters beyond-
299 those that the paint engine normally sets itself.-
300-
301 \sa setUniformsDirty()-
302*/-
303void QGraphicsShaderEffect::setUniforms(QGLShaderProgram *program)-
304{-
305 Q_UNUSED(program);-
306}
never executed: end of block
0
307-
308QT_END_NAMESPACE-
309-
310#endif // QT_NO_GRAPHICSEFFECT-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9