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

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