1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the QtOpenGL module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | //
|
---|
43 | // W A R N I N G
|
---|
44 | // -------------
|
---|
45 | //
|
---|
46 | // This file is not part of the Qt API. It exists purely as an
|
---|
47 | // implementation detail. This header file may change from version to
|
---|
48 | // version without notice, or even be removed.
|
---|
49 | //
|
---|
50 | // We mean it.
|
---|
51 | //
|
---|
52 |
|
---|
53 | /*
|
---|
54 | VERTEX SHADERS
|
---|
55 | ==============
|
---|
56 |
|
---|
57 | Vertex shaders are specified as multiple (partial) shaders. On desktop,
|
---|
58 | this works fine. On ES, QGLShader & QGLShaderProgram will make partial
|
---|
59 | shaders work by concatenating the source in each QGLShader and compiling
|
---|
60 | it as a single shader. This is abstracted nicely by QGLShaderProgram and
|
---|
61 | the GL2 engine doesn't need to worry about it.
|
---|
62 |
|
---|
63 | Generally, there's two vertex shader objects. The position shaders are
|
---|
64 | the ones which set gl_Position. There's also two "main" vertex shaders,
|
---|
65 | one which just calls the position shader and another which also passes
|
---|
66 | through some texture coordinates from a vertex attribute array to a
|
---|
67 | varying. These texture coordinates are used for mask position in text
|
---|
68 | rendering and for the source coordinates in drawImage/drawPixmap. There's
|
---|
69 | also a "Simple" vertex shader for rendering a solid colour (used to render
|
---|
70 | into the stencil buffer where the actual colour value is discarded).
|
---|
71 |
|
---|
72 | The position shaders for brushes look scary. This is because many of the
|
---|
73 | calculations which logically belong in the fragment shader have been moved
|
---|
74 | into the vertex shader to improve performance. This is why the position
|
---|
75 | calculation is in a seperate shader. Not only does it calculate the
|
---|
76 | position, but it also calculates some data to be passed to the fragment
|
---|
77 | shader as a varying. It is optimal to move as much of the calculation as
|
---|
78 | possible into the vertex shader as this is executed less often.
|
---|
79 |
|
---|
80 | The varyings passed to the fragment shaders are interpolated (which is
|
---|
81 | cheap). Unfortunately, GL will apply perspective correction to the
|
---|
82 | interpolation calusing errors. To get around this, the vertex shader must
|
---|
83 | apply perspective correction itself and set the w-value of gl_Position to
|
---|
84 | zero. That way, GL will be tricked into thinking it doesn't need to apply a
|
---|
85 | perspective correction and use linear interpolation instead (which is what
|
---|
86 | we want). Of course, if the brush transform is affeine, no perspective
|
---|
87 | correction is needed and a simpler vertex shader can be used instead.
|
---|
88 |
|
---|
89 | So there are the following "main" vertex shaders:
|
---|
90 | qglslMainVertexShader
|
---|
91 | qglslMainWithTexCoordsVertexShader
|
---|
92 |
|
---|
93 | And the the following position vertex shaders:
|
---|
94 | qglslPositionOnlyVertexShader
|
---|
95 | qglslPositionWithTextureBrushVertexShader
|
---|
96 | qglslPositionWithPatternBrushVertexShader
|
---|
97 | qglslPositionWithLinearGradientBrushVertexShader
|
---|
98 | qglslPositionWithRadialGradientBrushVertexShader
|
---|
99 | qglslPositionWithConicalGradientBrushVertexShader
|
---|
100 | qglslAffinePositionWithTextureBrushVertexShader
|
---|
101 | qglslAffinePositionWithPatternBrushVertexShader
|
---|
102 | qglslAffinePositionWithLinearGradientBrushVertexShader
|
---|
103 | qglslAffinePositionWithRadialGradientBrushVertexShader
|
---|
104 | qglslAffinePositionWithConicalGradientBrushVertexShader
|
---|
105 |
|
---|
106 | Leading to 23 possible vertex shaders
|
---|
107 |
|
---|
108 |
|
---|
109 | FRAGMENT SHADERS
|
---|
110 | ================
|
---|
111 |
|
---|
112 | Fragment shaders are also specified as multiple (partial) shaders. The
|
---|
113 | different fragment shaders represent the different stages in Qt's fragment
|
---|
114 | pipeline. There are 1-3 stages in this pipeline: First stage is to get the
|
---|
115 | fragment's colour value. The next stage is to get the fragment's mask value
|
---|
116 | (coverage value for anti-aliasing) and the final stage is to blend the
|
---|
117 | incoming fragment with the background (for composition modes not supported
|
---|
118 | by GL).
|
---|
119 |
|
---|
120 | Of these, the first stage will always be present. If Qt doesn't need to
|
---|
121 | apply anti-aliasing (because it's off or handled by multisampling) then
|
---|
122 | the coverage value doesn't need to be applied. (Note: There are two types
|
---|
123 | of mask, one for regular anti-aliasing and one for sub-pixel anti-
|
---|
124 | aliasing.) If the composition mode is one which GL supports natively then
|
---|
125 | the blending stage doesn't need to be applied.
|
---|
126 |
|
---|
127 | As eash stage can have multiple implementations, they are abstracted as
|
---|
128 | GLSL function calls with the following signatures:
|
---|
129 |
|
---|
130 | Brushes & image drawing are implementations of "qcolorp vec4 srcPixel()":
|
---|
131 | qglslImageSrcFragShader
|
---|
132 | qglslImageSrcWithPatternFragShader
|
---|
133 | qglslNonPremultipliedImageSrcFragShader
|
---|
134 | qglslSolidBrushSrcFragShader
|
---|
135 | qglslTextureBrushSrcFragShader
|
---|
136 | qglslTextureBrushWithPatternFragShader
|
---|
137 | qglslPatternBrushSrcFragShader
|
---|
138 | qglslLinearGradientBrushSrcFragShader
|
---|
139 | qglslRadialGradientBrushSrcFragShader
|
---|
140 | qglslConicalGradientBrushSrcFragShader
|
---|
141 | NOTE: It is assumed the colour returned by srcPixel() is pre-multiplied
|
---|
142 |
|
---|
143 | Masks are implementations of "qcolorp vec4 applyMask(qcolorp vec4 src)":
|
---|
144 | qglslMaskFragmentShader
|
---|
145 | qglslRgbMaskFragmentShaderPass1
|
---|
146 | qglslRgbMaskFragmentShaderPass2
|
---|
147 | qglslRgbMaskWithGammaFragmentShader
|
---|
148 |
|
---|
149 | Composition modes are "qcolorp vec4 compose(qcolorp vec4 src)":
|
---|
150 | qglslColorBurnCompositionModeFragmentShader
|
---|
151 | qglslColorDodgeCompositionModeFragmentShader
|
---|
152 | qglslDarkenCompositionModeFragmentShader
|
---|
153 | qglslDifferenceCompositionModeFragmentShader
|
---|
154 | qglslExclusionCompositionModeFragmentShader
|
---|
155 | qglslHardLightCompositionModeFragmentShader
|
---|
156 | qglslLightenCompositionModeFragmentShader
|
---|
157 | qglslMultiplyCompositionModeFragmentShader
|
---|
158 | qglslOverlayCompositionModeFragmentShader
|
---|
159 | qglslScreenCompositionModeFragmentShader
|
---|
160 | qglslSoftLightCompositionModeFragmentShader
|
---|
161 |
|
---|
162 |
|
---|
163 | Note: In the future, some GLSL compilers will support an extension allowing
|
---|
164 | a new 'color' precision specifier. To support this, qcolorp is used for
|
---|
165 | all color components so it can be defined to colorp or lowp depending upon
|
---|
166 | the implementation.
|
---|
167 |
|
---|
168 | So there are differnt frament shader main functions, depending on the
|
---|
169 | number & type of pipelines the fragment needs to go through.
|
---|
170 |
|
---|
171 | The choice of which main() fragment shader string to use depends on:
|
---|
172 | - Use of global opacity
|
---|
173 | - Brush style (some brushes apply opacity themselves)
|
---|
174 | - Use & type of mask (TODO: Need to support high quality anti-aliasing & text)
|
---|
175 | - Use of non-GL Composition mode
|
---|
176 |
|
---|
177 | Leading to the following fragment shader main functions:
|
---|
178 | gl_FragColor = compose(applyMask(srcPixel()*globalOpacity));
|
---|
179 | gl_FragColor = compose(applyMask(srcPixel()));
|
---|
180 | gl_FragColor = applyMask(srcPixel()*globalOpacity);
|
---|
181 | gl_FragColor = applyMask(srcPixel());
|
---|
182 | gl_FragColor = compose(srcPixel()*globalOpacity);
|
---|
183 | gl_FragColor = compose(srcPixel());
|
---|
184 | gl_FragColor = srcPixel()*globalOpacity;
|
---|
185 | gl_FragColor = srcPixel();
|
---|
186 |
|
---|
187 | Called:
|
---|
188 | qglslMainFragmentShader_CMO
|
---|
189 | qglslMainFragmentShader_CM
|
---|
190 | qglslMainFragmentShader_MO
|
---|
191 | qglslMainFragmentShader_M
|
---|
192 | qglslMainFragmentShader_CO
|
---|
193 | qglslMainFragmentShader_C
|
---|
194 | qglslMainFragmentShader_O
|
---|
195 | qglslMainFragmentShader
|
---|
196 |
|
---|
197 | Where:
|
---|
198 | M = Mask
|
---|
199 | C = Composition
|
---|
200 | O = Global Opacity
|
---|
201 |
|
---|
202 |
|
---|
203 | CUSTOM SHADER CODE
|
---|
204 | ==================
|
---|
205 |
|
---|
206 | The use of custom shader code is supported by the engine for drawImage and
|
---|
207 | drawPixmap calls. This is implemented via hooks in the fragment pipeline.
|
---|
208 |
|
---|
209 | The custom shader is passed to the engine as a partial fragment shader
|
---|
210 | (QGLCustomShaderStage). The shader will implement a pre-defined method name
|
---|
211 | which Qt's fragment pipeline will call:
|
---|
212 |
|
---|
213 | lowp vec4 customShader(lowp sampler2d imageTexture, highp vec2 textureCoords)
|
---|
214 |
|
---|
215 | The provided src and srcCoords parameters can be used to sample from the
|
---|
216 | source image.
|
---|
217 |
|
---|
218 | Transformations, clipping, opacity, and composition modes set using QPainter
|
---|
219 | will be respected when using the custom shader hook.
|
---|
220 | */
|
---|
221 |
|
---|
222 | #ifndef QGLENGINE_SHADER_MANAGER_H
|
---|
223 | #define QGLENGINE_SHADER_MANAGER_H
|
---|
224 |
|
---|
225 | #include <QGLShader>
|
---|
226 | #include <QGLShaderProgram>
|
---|
227 | #include <QPainter>
|
---|
228 | #include <private/qgl_p.h>
|
---|
229 | #include <private/qglcustomshaderstage_p.h>
|
---|
230 |
|
---|
231 | QT_BEGIN_HEADER
|
---|
232 |
|
---|
233 | QT_BEGIN_NAMESPACE
|
---|
234 |
|
---|
235 | QT_MODULE(OpenGL)
|
---|
236 |
|
---|
237 |
|
---|
238 | /*
|
---|
239 | struct QGLEngineCachedShaderProg
|
---|
240 | {
|
---|
241 | QGLEngineCachedShaderProg(QGLEngineShaderManager::ShaderName vertexMain,
|
---|
242 | QGLEngineShaderManager::ShaderName vertexPosition,
|
---|
243 | QGLEngineShaderManager::ShaderName fragMain,
|
---|
244 | QGLEngineShaderManager::ShaderName pixelSrc,
|
---|
245 | QGLEngineShaderManager::ShaderName mask,
|
---|
246 | QGLEngineShaderManager::ShaderName composition);
|
---|
247 |
|
---|
248 | int cacheKey;
|
---|
249 | QGLShaderProgram* program;
|
---|
250 | }
|
---|
251 | */
|
---|
252 |
|
---|
253 | static const GLuint QT_VERTEX_COORDS_ATTR = 0;
|
---|
254 | static const GLuint QT_TEXTURE_COORDS_ATTR = 1;
|
---|
255 | static const GLuint QT_OPACITY_ATTR = 2;
|
---|
256 |
|
---|
257 | class QGLEngineShaderProg;
|
---|
258 |
|
---|
259 | class QGLEngineSharedShaders : public QObject
|
---|
260 | {
|
---|
261 | Q_OBJECT
|
---|
262 | public:
|
---|
263 |
|
---|
264 | enum SnippetName {
|
---|
265 | MainVertexShader,
|
---|
266 | MainWithTexCoordsVertexShader,
|
---|
267 | MainWithTexCoordsAndOpacityVertexShader,
|
---|
268 |
|
---|
269 | // UntransformedPositionVertexShader must be first in the list:
|
---|
270 | UntransformedPositionVertexShader,
|
---|
271 | PositionOnlyVertexShader,
|
---|
272 | PositionWithPatternBrushVertexShader,
|
---|
273 | PositionWithLinearGradientBrushVertexShader,
|
---|
274 | PositionWithConicalGradientBrushVertexShader,
|
---|
275 | PositionWithRadialGradientBrushVertexShader,
|
---|
276 | PositionWithTextureBrushVertexShader,
|
---|
277 | AffinePositionWithPatternBrushVertexShader,
|
---|
278 | AffinePositionWithLinearGradientBrushVertexShader,
|
---|
279 | AffinePositionWithConicalGradientBrushVertexShader,
|
---|
280 | AffinePositionWithRadialGradientBrushVertexShader,
|
---|
281 | AffinePositionWithTextureBrushVertexShader,
|
---|
282 |
|
---|
283 | // MainFragmentShader_CMO must be first in the list:
|
---|
284 | MainFragmentShader_CMO,
|
---|
285 | MainFragmentShader_CM,
|
---|
286 | MainFragmentShader_MO,
|
---|
287 | MainFragmentShader_M,
|
---|
288 | MainFragmentShader_CO,
|
---|
289 | MainFragmentShader_C,
|
---|
290 | MainFragmentShader_O,
|
---|
291 | MainFragmentShader,
|
---|
292 | MainFragmentShader_ImageArrays,
|
---|
293 |
|
---|
294 | // ImageSrcFragmentShader must be first in the list::
|
---|
295 | ImageSrcFragmentShader,
|
---|
296 | ImageSrcWithPatternFragmentShader,
|
---|
297 | NonPremultipliedImageSrcFragmentShader,
|
---|
298 | CustomImageSrcFragmentShader,
|
---|
299 | SolidBrushSrcFragmentShader,
|
---|
300 | TextureBrushSrcFragmentShader,
|
---|
301 | TextureBrushSrcWithPatternFragmentShader,
|
---|
302 | PatternBrushSrcFragmentShader,
|
---|
303 | LinearGradientBrushSrcFragmentShader,
|
---|
304 | RadialGradientBrushSrcFragmentShader,
|
---|
305 | ConicalGradientBrushSrcFragmentShader,
|
---|
306 | ShockingPinkSrcFragmentShader,
|
---|
307 |
|
---|
308 | // NoMaskFragmentShader must be first in the list:
|
---|
309 | NoMaskFragmentShader,
|
---|
310 | MaskFragmentShader,
|
---|
311 | RgbMaskFragmentShaderPass1,
|
---|
312 | RgbMaskFragmentShaderPass2,
|
---|
313 | RgbMaskWithGammaFragmentShader,
|
---|
314 |
|
---|
315 | // NoCompositionModeFragmentShader must be first in the list:
|
---|
316 | NoCompositionModeFragmentShader,
|
---|
317 | MultiplyCompositionModeFragmentShader,
|
---|
318 | ScreenCompositionModeFragmentShader,
|
---|
319 | OverlayCompositionModeFragmentShader,
|
---|
320 | DarkenCompositionModeFragmentShader,
|
---|
321 | LightenCompositionModeFragmentShader,
|
---|
322 | ColorDodgeCompositionModeFragmentShader,
|
---|
323 | ColorBurnCompositionModeFragmentShader,
|
---|
324 | HardLightCompositionModeFragmentShader,
|
---|
325 | SoftLightCompositionModeFragmentShader,
|
---|
326 | DifferenceCompositionModeFragmentShader,
|
---|
327 | ExclusionCompositionModeFragmentShader,
|
---|
328 |
|
---|
329 | TotalSnippetCount, InvalidSnippetName
|
---|
330 | };
|
---|
331 | #if defined (QT_DEBUG)
|
---|
332 | Q_ENUMS(SnippetName)
|
---|
333 | static QByteArray snippetNameStr(SnippetName snippetName);
|
---|
334 | #endif
|
---|
335 |
|
---|
336 | /*
|
---|
337 | // These allow the ShaderName enum to be used as a cache key
|
---|
338 | const int mainVertexOffset = 0;
|
---|
339 | const int positionVertexOffset = (1<<2) - PositionOnlyVertexShader;
|
---|
340 | const int mainFragOffset = (1<<6) - MainFragmentShader_CMO;
|
---|
341 | const int srcPixelOffset = (1<<10) - ImageSrcFragmentShader;
|
---|
342 | const int maskOffset = (1<<14) - NoMaskShader;
|
---|
343 | const int compositionOffset = (1 << 16) - MultiplyCompositionModeFragmentShader;
|
---|
344 | */
|
---|
345 |
|
---|
346 | QGLEngineSharedShaders(const QGLContext *context);
|
---|
347 |
|
---|
348 | QGLShaderProgram *simpleProgram() { return simpleShaderProg; }
|
---|
349 | QGLShaderProgram *blitProgram() { return blitShaderProg; }
|
---|
350 | // Compile the program if it's not already in the cache, return the item in the cache.
|
---|
351 | QGLEngineShaderProg *findProgramInCache(const QGLEngineShaderProg &prog);
|
---|
352 | // Compile the custom shader if it's not already in the cache, return the item in the cache.
|
---|
353 |
|
---|
354 | static QGLEngineSharedShaders *shadersForContext(const QGLContext *context);
|
---|
355 |
|
---|
356 | // Ideally, this would be static and cleanup all programs in all contexts which
|
---|
357 | // contain the custom code. Currently it is just a hint and we rely on deleted
|
---|
358 | // custom shaders being cleaned up by being kicked out of the cache when it's
|
---|
359 | // full.
|
---|
360 | void cleanupCustomStage(QGLCustomShaderStage* stage);
|
---|
361 |
|
---|
362 | signals:
|
---|
363 | void shaderProgNeedsChanging();
|
---|
364 |
|
---|
365 | private:
|
---|
366 | QGLSharedResourceGuard ctxGuard;
|
---|
367 | QGLShaderProgram *blitShaderProg;
|
---|
368 | QGLShaderProgram *simpleShaderProg;
|
---|
369 | QList<QGLEngineShaderProg*> cachedPrograms;
|
---|
370 |
|
---|
371 | static const char* qShaderSnippets[TotalSnippetCount];
|
---|
372 | };
|
---|
373 |
|
---|
374 |
|
---|
375 | class QGLEngineShaderProg
|
---|
376 | {
|
---|
377 | public:
|
---|
378 | QGLEngineShaderProg() : program(0) {}
|
---|
379 |
|
---|
380 | ~QGLEngineShaderProg() {
|
---|
381 | if (program)
|
---|
382 | delete program;
|
---|
383 | }
|
---|
384 |
|
---|
385 | QGLEngineSharedShaders::SnippetName mainVertexShader;
|
---|
386 | QGLEngineSharedShaders::SnippetName positionVertexShader;
|
---|
387 | QGLEngineSharedShaders::SnippetName mainFragShader;
|
---|
388 | QGLEngineSharedShaders::SnippetName srcPixelFragShader;
|
---|
389 | QGLEngineSharedShaders::SnippetName maskFragShader;
|
---|
390 | QGLEngineSharedShaders::SnippetName compositionFragShader;
|
---|
391 |
|
---|
392 | QByteArray customStageSource; //TODO: Decent cache key for custom stages
|
---|
393 | QGLShaderProgram* program;
|
---|
394 |
|
---|
395 | QVector<uint> uniformLocations;
|
---|
396 |
|
---|
397 | bool useTextureCoords;
|
---|
398 | bool useOpacityAttribute;
|
---|
399 |
|
---|
400 | bool operator==(const QGLEngineShaderProg& other) {
|
---|
401 | // We don't care about the program
|
---|
402 | return ( mainVertexShader == other.mainVertexShader &&
|
---|
403 | positionVertexShader == other.positionVertexShader &&
|
---|
404 | mainFragShader == other.mainFragShader &&
|
---|
405 | srcPixelFragShader == other.srcPixelFragShader &&
|
---|
406 | maskFragShader == other.maskFragShader &&
|
---|
407 | compositionFragShader == other.compositionFragShader &&
|
---|
408 | customStageSource == other.customStageSource
|
---|
409 | );
|
---|
410 | }
|
---|
411 | };
|
---|
412 |
|
---|
413 | class Q_OPENGL_EXPORT QGLEngineShaderManager : public QObject
|
---|
414 | {
|
---|
415 | Q_OBJECT
|
---|
416 | public:
|
---|
417 | QGLEngineShaderManager(QGLContext* context);
|
---|
418 | ~QGLEngineShaderManager();
|
---|
419 |
|
---|
420 | enum MaskType {NoMask, PixelMask, SubPixelMaskPass1, SubPixelMaskPass2, SubPixelWithGammaMask};
|
---|
421 | enum PixelSrcType {
|
---|
422 | ImageSrc = Qt::TexturePattern+1,
|
---|
423 | NonPremultipliedImageSrc = Qt::TexturePattern+2,
|
---|
424 | PatternSrc = Qt::TexturePattern+3,
|
---|
425 | TextureSrcWithPattern = Qt::TexturePattern+4
|
---|
426 | };
|
---|
427 |
|
---|
428 | enum Uniform {
|
---|
429 | ImageTexture,
|
---|
430 | PatternColor,
|
---|
431 | GlobalOpacity,
|
---|
432 | Depth,
|
---|
433 | PmvMatrix,
|
---|
434 | MaskTexture,
|
---|
435 | FragmentColor,
|
---|
436 | LinearData,
|
---|
437 | Angle,
|
---|
438 | HalfViewportSize,
|
---|
439 | Fmp,
|
---|
440 | Fmp2MRadius2,
|
---|
441 | Inverse2Fmp2MRadius2,
|
---|
442 | InvertedTextureSize,
|
---|
443 | BrushTransform,
|
---|
444 | BrushTexture,
|
---|
445 | NumUniforms
|
---|
446 | };
|
---|
447 |
|
---|
448 | enum OpacityMode {
|
---|
449 | NoOpacity,
|
---|
450 | UniformOpacity,
|
---|
451 | AttributeOpacity
|
---|
452 | };
|
---|
453 |
|
---|
454 | // There are optimisations we can do, depending on the brush transform:
|
---|
455 | // 1) May not have to apply perspective-correction
|
---|
456 | // 2) Can use lower precision for matrix
|
---|
457 | void optimiseForBrushTransform(const QTransform::TransformationType transformType);
|
---|
458 | void setSrcPixelType(Qt::BrushStyle);
|
---|
459 | void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images
|
---|
460 | void setOpacityMode(OpacityMode);
|
---|
461 | void setMaskType(MaskType);
|
---|
462 | void setCompositionMode(QPainter::CompositionMode);
|
---|
463 | void setCustomStage(QGLCustomShaderStage* stage);
|
---|
464 | void removeCustomStage();
|
---|
465 |
|
---|
466 | GLuint getUniformLocation(const Uniform id);
|
---|
467 |
|
---|
468 | void setDirty(); // someone has manually changed the current shader program
|
---|
469 | bool useCorrectShaderProg(); // returns true if the shader program needed to be changed
|
---|
470 |
|
---|
471 | QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen
|
---|
472 | QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers
|
---|
473 | QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer
|
---|
474 |
|
---|
475 | QGLEngineSharedShaders* sharedShaders;
|
---|
476 |
|
---|
477 | private slots:
|
---|
478 | void shaderProgNeedsChangingSlot() { shaderProgNeedsChanging = true; }
|
---|
479 |
|
---|
480 | private:
|
---|
481 | QGLContext* ctx;
|
---|
482 | bool shaderProgNeedsChanging;
|
---|
483 |
|
---|
484 | // Current state variables which influence the choice of shader:
|
---|
485 | QTransform brushTransform;
|
---|
486 | int srcPixelType;
|
---|
487 | OpacityMode opacityMode;
|
---|
488 | MaskType maskType;
|
---|
489 | QPainter::CompositionMode compositionMode;
|
---|
490 | QGLCustomShaderStage* customSrcStage;
|
---|
491 |
|
---|
492 | QGLEngineShaderProg* currentShaderProg;
|
---|
493 | };
|
---|
494 |
|
---|
495 | QT_END_NAMESPACE
|
---|
496 |
|
---|
497 | QT_END_HEADER
|
---|
498 |
|
---|
499 | #endif //QGLENGINE_SHADER_MANAGER_H
|
---|