1/****************************************************************************
2**
3** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D 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 "qshaderprogram.h"
41#include "qshaderprogram_p.h"
42#include <Qt3DCore/qpropertyupdatedchange.h>
43#include <Qt3DRender/private/qurlhelper_p.h>
44#include <QDebug>
45#include <QFile>
46#include <QFileInfo>
47#include <QUrl>
48
49/*!
50 \class Qt3DRender::QShaderProgram
51 \inmodule Qt3DRender
52 \brief Encapsulates a Shader Program.
53 \inherits Qt3DCore::QNode
54 \since 5.5
55
56 A shader program consists of several different shaders, such as vertex and fragment shaders.
57
58 Qt3D will automatically populate a set of default uniforms if they are
59 encountered during the shader instrospection phase.
60
61 \table
62 \header
63 \li {1, 1} Default Uniform
64 \li {2, 1} Associated Qt3D Parameter name
65 \li {3, 1} GLSL declaration
66
67 \row
68 \li {1, 1} ModelMatrix
69 \li {2, 1} modelMatrix
70 \li {3, 1} uniform mat4 modelMatrix;
71
72 \row
73 \li {1, 1} ViewMatrix
74 \li {2, 1} viewMatrix
75 \li {3, 1} uniform mat4 viewMatrix;
76
77 \row
78 \li {1, 1} ProjectionMatrix
79 \li {2, 1} projectionMatrix
80 \li {3, 1} uniform mat4 projectionMatrix;
81
82 \row
83 \li {1, 1} ModelViewMatrix
84 \li {2, 1} modelView
85 \li {3, 1} uniform mat4 modelView;
86
87 \row
88 \li {1, 1} ViewProjectionMatrix
89 \li {2, 1} viewProjectionMatrix
90 \li {3, 1} uniform mat4 viewProjectionMatrix;
91
92 \row
93 \li {1, 1} ModelViewProjectionMatrix
94 \li {2, 1} modelViewProjection \br mvp
95 \li {3, 1} uniform mat4 modelViewProjection; \br uniform mat4 mvp;
96
97 \row
98 \li {1, 1} InverseModelMatrix
99 \li {2, 1} inverseModelMatrix
100 \li {3, 1} uniform mat4 inverseModelMatrix;
101
102 \row
103 \li {1, 1} InverseViewMatrix
104 \li {2, 1} inverseViewMatrix
105 \li {3, 1} uniform mat4 inverseViewMatrix;
106
107 \row
108 \li {1, 1} InverseProjectionMatrix
109 \li {2, 1} inverseProjectionMatrix
110 \li {3, 1} uniform mat4 inverseProjectionMatrix;
111
112 \row
113 \li {1, 1} InverseModelViewMatrix
114 \li {2, 1} inverseModelView
115 \li {3, 1} uniform mat4 inverseModelView;
116
117 \row
118 \li {1, 1} InverseViewProjectionMatrix
119 \li {2, 1} inverseViewProjectionMatrix
120 \li {3, 1} uniform mat4 inverseViewProjectionMatrix;
121
122 \row
123 \li {1, 1} InverseModelViewProjectionMatrix
124 \li {2, 1} inverseModelViewProjection
125 \li {3, 1} uniform mat4 inverseModelViewProjection;
126
127 \row
128 \li {1, 1} ModelNormalMatrix
129 \li {2, 1} modelNormalMatrix
130 \li {3, 1} uniform mat3 modelNormalMatrix;
131
132 \row
133 \li {1, 1} ModelViewNormalMatrix
134 \li {2, 1} modelViewNormal
135 \li {3, 1} uniform mat3 modelViewNormal;
136
137 \row
138 \li {1, 1} ViewportMatrix
139 \li {2, 1} viewportMatrix
140 \li {3, 1} uniform mat4 viewportMatrix;
141
142 \row
143 \li {1, 1} InverseViewportMatrix
144 \li {2, 1} inverseViewportMatrix
145 \li {3, 1} uniform mat4 inverseViewportMatrix;
146
147 \row
148 \li {1, 1} AspectRatio \br (surface width / surface height)
149 \li {2, 1} aspectRatio
150 \li {3, 1} uniform float aspectRatio;
151
152 \row
153 \li {1, 1} Exposure
154 \li {2, 1} exposure
155 \li {3, 1} uniform float exposure;
156
157 \row
158 \li {1, 1} Gamma
159 \li {2, 1} gamma
160 \li {3, 1} uniform float gamma;
161
162 \row
163 \li {1, 1} Time \br (in nano seconds)
164 \li {2, 1} time
165 \li {3, 1} uniform float time;
166
167 \row
168 \li {1, 1} EyePosition
169 \li {2, 1} eyePosition
170 \li {3, 1} uniform vec3 eyePosition;
171
172 \row
173 \li {1, 1} SkinningPalette
174 \li {2, 1} skinningPalette[0]
175 \li {3, 1} const int maxJoints = 100; \br uniform mat4 skinningPalette[maxJoints];
176
177 \endtable
178*/
179
180/*!
181 \qmltype ShaderProgram
182 \instantiates Qt3DRender::QShaderProgram
183 \inqmlmodule Qt3D.Render
184 \brief Encapsulates a Shader Program.
185 \since 5.5
186
187 ShaderProgram class encapsulates a shader program. A shader program consists of several
188 different shaders, such as vertex and fragment shaders.
189
190 Qt3D will automatically populate a set of default uniforms if they are
191 encountered during the shader instrospection phase.
192
193 \table
194 \header
195 \li {1, 1} Default Uniform
196 \li {2, 1} Associated Qt3D Parameter name
197 \li {3, 1} GLSL declaration
198
199 \row
200 \li {1, 1} ModelMatrix
201 \li {2, 1} modelMatrix
202 \li {3, 1} uniform mat4 modelMatrix;
203
204 \row
205 \li {1, 1} ViewMatrix
206 \li {2, 1} viewMatrix
207 \li {3, 1} uniform mat4 viewMatrix;
208
209 \row
210 \li {1, 1} ProjectionMatrix
211 \li {2, 1} projectionMatrix
212 \li {3, 1} uniform mat4 projectionMatrix;
213
214 \row
215 \li {1, 1} ModelViewMatrix
216 \li {2, 1} modelView
217 \li {3, 1} uniform mat4 modelView;
218
219 \row
220 \li {1, 1} ViewProjectionMatrix
221 \li {2, 1} viewProjectionMatrix
222 \li {3, 1} uniform mat4 viewProjectionMatrix;
223
224 \row
225 \li {1, 1} ModelViewProjectionMatrix
226 \li {2, 1} modelViewProjection \br mvp
227 \li {3, 1} uniform mat4 modelViewProjection; \br uniform mat4 mvp;
228
229 \row
230 \li {1, 1} InverseModelMatrix
231 \li {2, 1} inverseModelMatrix
232 \li {3, 1} uniform mat4 inverseModelMatrix;
233
234 \row
235 \li {1, 1} InverseViewMatrix
236 \li {2, 1} inverseViewMatrix
237 \li {3, 1} uniform mat4 inverseViewMatrix;
238
239 \row
240 \li {1, 1} InverseProjectionMatrix
241 \li {2, 1} inverseProjectionMatrix
242 \li {3, 1} uniform mat4 inverseProjectionMatrix;
243
244 \row
245 \li {1, 1} InverseModelViewMatrix
246 \li {2, 1} inverseModelView
247 \li {3, 1} uniform mat4 inverseModelView;
248
249 \row
250 \li {1, 1} InverseViewProjectionMatrix
251 \li {2, 1} inverseViewProjectionMatrix
252 \li {3, 1} uniform mat4 inverseViewProjectionMatrix;
253
254 \row
255 \li {1, 1} InverseModelViewProjectionMatrix
256 \li {2, 1} inverseModelViewProjection
257 \li {3, 1} uniform mat4 inverseModelViewProjection;
258
259 \row
260 \li {1, 1} ModelNormalMatrix
261 \li {2, 1} modelNormalMatrix
262 \li {3, 1} uniform mat3 modelNormalMatrix;
263
264 \row
265 \li {1, 1} ModelViewNormalMatrix
266 \li {2, 1} modelViewNormal
267 \li {3, 1} uniform mat3 modelViewNormal;
268
269 \row
270 \li {1, 1} ViewportMatrix
271 \li {2, 1} viewportMatrix
272 \li {3, 1} uniform mat4 viewportMatrix;
273
274 \row
275 \li {1, 1} InverseViewportMatrix
276 \li {2, 1} inverseViewportMatrix
277 \li {3, 1} uniform mat4 inverseViewportMatrix;
278
279 \row
280 \li {1, 1} AspectRatio \br (surface width / surface height)
281 \li {2, 1} aspectRatio
282 \li {3, 1} uniform float aspectRatio;
283
284 \row
285 \li {1, 1} Exposure
286 \li {2, 1} exposure
287 \li {3, 1} uniform float exposure;
288
289 \row
290 \li {1, 1} Gamma
291 \li {2, 1} gamma
292 \li {3, 1} uniform float gamma;
293
294 \row
295 \li {1, 1} Time \br (in nano seconds)
296 \li {2, 1} time
297 \li {3, 1} uniform float time;
298
299 \row
300 \li {1, 1} EyePosition
301 \li {2, 1} eyePosition
302 \li {3, 1} uniform vec3 eyePosition;
303
304 \row
305 \li {1, 1} SkinningPalette
306 \li {2, 1} skinningPalette[0]
307 \li {3, 1} const int maxJoints = 100; \br uniform mat4 skinningPalette[maxJoints];
308
309 \endtable
310*/
311
312/*!
313 \enum QShaderProgram::ShaderType
314
315 This enum identifies the type of shader used.
316
317 \value Vertex Vertex shader
318 \value Fragment Fragment shader
319 \value TessellationControl Tesselation control shader
320 \value TessellationEvaluation Tesselation evaluation shader
321 \value Geometry Geometry shader
322 \value Compute Compute shader
323*/
324
325/*!
326 \enum QShaderProgram::Status
327
328 This enum identifies the status of shader used.
329
330 \value NotReady The shader hasn't been compiled and linked yet
331 \value Ready The shader was successfully compiled
332 \value Error An error occurred while compiling the shader
333*/
334
335/*!
336 \enum QShaderProgram::Format
337
338 This enum identifies the format of the shader code used.
339
340 \value GLSL OpenGL
341 \value SPIRV Vulkan, OpenGL 5
342
343 \since 5.15
344*/
345
346QT_BEGIN_NAMESPACE
347
348namespace Qt3DRender {
349
350QShaderProgramPrivate::QShaderProgramPrivate()
351 : QNodePrivate()
352 , m_status(QShaderProgram::NotReady)
353 , m_format(QShaderProgram::GLSL)
354{
355}
356
357void QShaderProgramPrivate::setLog(const QString &log)
358{
359 Q_Q(QShaderProgram);
360 if (log != m_log) {
361 m_log = log;
362 const bool blocked = q->blockNotifications(block: true);
363 emit q->logChanged(log: m_log);
364 q->blockNotifications(block: blocked);
365 }
366}
367
368void QShaderProgramPrivate::setStatus(QShaderProgram::Status status)
369{
370 Q_Q(QShaderProgram);
371 if (status != m_status) {
372 m_status = status;
373 const bool blocked = q->blockNotifications(block: true);
374 emit q->statusChanged(status: m_status);
375 q->blockNotifications(block: blocked);
376 }
377}
378
379QShaderProgram::QShaderProgram(QNode *parent)
380 : QNode(*new QShaderProgramPrivate, parent)
381{
382}
383
384QShaderProgram::~QShaderProgram()
385{
386}
387
388/*! \internal */
389QShaderProgram::QShaderProgram(QShaderProgramPrivate &dd, QNode *parent)
390 : QNode(dd, parent)
391{
392}
393
394/*!
395 Posts a scene change with parameter \a change.
396*/
397void QShaderProgram::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
398{
399 Q_D(QShaderProgram);
400 if (change->type() == Qt3DCore::PropertyUpdated) {
401 const Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(src: change);
402 if (e->propertyName() == QByteArrayLiteral("log"))
403 d->setLog(e->value().toString());
404 else if (e->propertyName() == QByteArrayLiteral("status"))
405 d->setStatus(static_cast<QShaderProgram::Status>(e->value().toInt()));
406 }
407}
408
409/*!
410 \qmlproperty string ShaderProgram::vertexShaderCode
411
412 Holds the vertex shader code used by this shader program.
413*/
414/*!
415 \property QShaderProgram::vertexShaderCode
416
417 Holds the vertex shader code used by this shader program.
418*/
419void QShaderProgram::setVertexShaderCode(const QByteArray &vertexShaderCode)
420{
421 Q_D(QShaderProgram);
422 if (vertexShaderCode != d->m_vertexShaderCode) {
423 d->m_vertexShaderCode = vertexShaderCode;
424 emit vertexShaderCodeChanged(vertexShaderCode);
425 }
426}
427
428QByteArray QShaderProgram::vertexShaderCode() const
429{
430 Q_D(const QShaderProgram);
431 return d->m_vertexShaderCode;
432}
433
434/*!
435 \qmlproperty string ShaderProgram::tessellationControlShaderCode
436
437 Holds the tesselation control shader code used by this shader program.
438*/
439/*!
440 \property QShaderProgram::tessellationControlShaderCode
441
442 Holds the tesselation control shader code used by this shader program.
443*/
444void QShaderProgram::setTessellationControlShaderCode(const QByteArray &tessellationControlShaderCode)
445{
446 Q_D(QShaderProgram);
447 if (tessellationControlShaderCode != d->m_tessControlShaderCode) {
448 d->m_tessControlShaderCode = tessellationControlShaderCode;
449 emit tessellationControlShaderCodeChanged(tessellationControlShaderCode);
450 }
451}
452
453QByteArray QShaderProgram::tessellationControlShaderCode() const
454{
455 Q_D(const QShaderProgram);
456 return d->m_tessControlShaderCode;
457}
458
459/*!
460 \qmlproperty string ShaderProgram::tessellationEvaluationShaderCode
461
462 Holds the tesselation evaluation shader code used by this shader program.
463*/
464/*!
465 \property QShaderProgram::tessellationEvaluationShaderCode
466
467 Holds the tesselation evaluation shader code used by this shader program.
468*/
469void QShaderProgram::setTessellationEvaluationShaderCode(const QByteArray &tessellationEvaluationShaderCode)
470{
471 Q_D(QShaderProgram);
472 if (tessellationEvaluationShaderCode != d->m_tessEvalShaderCode) {
473 d->m_tessEvalShaderCode = tessellationEvaluationShaderCode;
474 emit tessellationEvaluationShaderCodeChanged(tessellationEvaluationShaderCode);
475 }
476}
477
478QByteArray QShaderProgram::tessellationEvaluationShaderCode() const
479{
480 Q_D(const QShaderProgram);
481 return d->m_tessEvalShaderCode;
482}
483
484/*!
485 \qmlproperty string ShaderProgram::geometryShaderCode
486
487 Holds the geometry shader code used by this shader program.
488*/
489/*!
490 \property QShaderProgram::geometryShaderCode
491
492 Holds the geometry shader code used by this shader program.
493*/
494void QShaderProgram::setGeometryShaderCode(const QByteArray &geometryShaderCode)
495{
496 Q_D(QShaderProgram);
497 if (geometryShaderCode != d->m_geometryShaderCode) {
498 d->m_geometryShaderCode = geometryShaderCode;
499 emit geometryShaderCodeChanged(geometryShaderCode);
500 }
501}
502
503QByteArray QShaderProgram::geometryShaderCode() const
504{
505 Q_D(const QShaderProgram);
506 return d->m_geometryShaderCode;
507}
508
509/*!
510 \qmlproperty string ShaderProgram::fragmentShaderCode
511
512 Holds the fragment shader code used by this shader program.
513*/
514/*!
515 \property QShaderProgram::fragmentShaderCode
516
517 Holds the fragment shader code used by this shader program.
518*/
519void QShaderProgram::setFragmentShaderCode(const QByteArray &fragmentShaderCode)
520{
521 Q_D(QShaderProgram);
522 if (fragmentShaderCode != d->m_fragmentShaderCode) {
523 d->m_fragmentShaderCode = fragmentShaderCode;
524 emit fragmentShaderCodeChanged(fragmentShaderCode);
525 }
526}
527
528QByteArray QShaderProgram::fragmentShaderCode() const
529{
530 Q_D(const QShaderProgram);
531 return d->m_fragmentShaderCode;
532}
533
534/*!
535 \qmlproperty string ShaderProgram::computeShaderCode
536
537 Holds the compute shader code used by this shader program.
538*/
539/*!
540 \property QShaderProgram::computeShaderCode
541
542 Holds the compute shader code used by this shader program.
543*/
544void QShaderProgram::setComputeShaderCode(const QByteArray &computeShaderCode)
545{
546 Q_D(QShaderProgram);
547 if (computeShaderCode != d->m_computeShaderCode) {
548 d->m_computeShaderCode = computeShaderCode;
549 emit computeShaderCodeChanged(computeShaderCode);
550 }
551}
552
553QByteArray QShaderProgram::computeShaderCode() const
554{
555 Q_D(const QShaderProgram);
556 return d->m_computeShaderCode;
557}
558
559
560/*!
561 Sets the shader code for \a type of shader to the \a shaderCode.
562*/
563void QShaderProgram::setShaderCode(ShaderType type, const QByteArray &shaderCode)
564{
565 switch (type) {
566 case Vertex:
567 setVertexShaderCode(shaderCode);
568 break;
569 case TessellationControl:
570 setTessellationControlShaderCode(shaderCode);
571 break;
572 case TessellationEvaluation:
573 setTessellationEvaluationShaderCode(shaderCode);
574 break;
575 case Geometry:
576 setGeometryShaderCode(shaderCode);
577 break;
578 case Fragment:
579 setFragmentShaderCode(shaderCode);
580 break;
581 case Compute:
582 setComputeShaderCode(shaderCode);
583 break;
584 default:
585 Q_UNREACHABLE();
586 }
587}
588
589/*!
590 Returns the shader code for \a type.
591*/
592QByteArray QShaderProgram::shaderCode(ShaderType type) const
593{
594 Q_D(const QShaderProgram);
595 switch (type) {
596 case Vertex:
597 return d->m_vertexShaderCode;
598 case TessellationControl:
599 return d->m_tessControlShaderCode;
600 case TessellationEvaluation:
601 return d->m_tessEvalShaderCode;
602 case Geometry:
603 return d->m_geometryShaderCode;
604 case Fragment:
605 return d->m_fragmentShaderCode;
606 case Compute:
607 return d->m_computeShaderCode;
608 default:
609 Q_UNREACHABLE();
610 }
611}
612
613/*!
614 \qmlproperty string ShaderProgram::log
615
616 Holds the log of the current shader program. This is useful to diagnose a
617 compilation failure of the shader program.
618*/
619/*!
620 \property QShaderProgram::log
621
622 Holds the log of the current shader program. This is useful to diagnose a
623 compilation failure of the shader program.
624*/
625QString QShaderProgram::log() const
626{
627 Q_D(const QShaderProgram);
628 return d->m_log;
629}
630
631/*!
632 \qmlproperty enumeration ShaderProgram::status
633
634 Holds the status of the current shader program.
635*/
636/*!
637 \property QShaderProgram::status
638
639 Holds the status of the current shader program.
640*/
641/*!
642 Returns the status of the current shader program.
643*/
644QShaderProgram::Status QShaderProgram::status() const
645{
646 Q_D(const QShaderProgram);
647 return d->m_status;
648}
649
650void QShaderProgram::setFormat(QShaderProgram::Format format)
651{
652 Q_D(QShaderProgram);
653 if (format != d->m_format) {
654 d->m_format = format;
655 emit formatChanged(format);
656 }
657}
658
659/*!
660 \qmlproperty enumeration ShaderProgram::format
661 \since 5.15
662
663 Holds the format of the code provided on the ShaderProgram.
664 The default is ShaderProgram.GLSL
665*/
666/*!
667 \property QShaderProgram::format
668 \since 5.15
669
670 Holds the format of the code provided on the ShaderProgram.
671 The default is ShaderProgram.GLSL
672*/
673QShaderProgram::Format QShaderProgram::format() const
674{
675 Q_D(const QShaderProgram);
676 return d->m_format;
677}
678
679QByteArray QShaderProgramPrivate::deincludify(const QString &filePath)
680{
681 QFile f(filePath);
682 if (!f.open(flags: QIODevice::ReadOnly | QIODevice::Text)) {
683 qWarning() << "Could not read shader source file:" << f.fileName();
684 return QByteArray();
685 }
686
687 QByteArray contents = f.readAll();
688 return deincludify(contents, filePath);
689}
690
691QByteArray QShaderProgramPrivate::deincludify(const QByteArray &contents, const QString &filePath)
692{
693 QByteArrayList lines = contents.split(sep: '\n');
694 const QByteArray includeDirective = QByteArrayLiteral("#pragma include");
695 for (int i = 0; i < lines.count(); ++i) {
696 const auto line = lines[i].simplified();
697 if (line.startsWith(a: includeDirective)) {
698 const QString includePartialPath = QString::fromUtf8(str: line.mid(index: includeDirective.count() + 1));
699
700 QString includePath = QFileInfo(includePartialPath).isAbsolute() ? includePartialPath
701 : QFileInfo(filePath).absolutePath() + QLatin1Char('/') + includePartialPath;
702 if (qEnvironmentVariableIsSet(varName: "QT3D_GLSL100_WORKAROUND")) {
703 QString candidate = includePath + QLatin1String("100");
704 if (QFile::exists(fileName: candidate))
705 includePath = candidate;
706 }
707 lines.removeAt(i);
708 QByteArray includedContents = deincludify(filePath: includePath);
709 lines.insert(i, t: includedContents);
710 QString lineDirective = QString(QStringLiteral("#line %1")).arg(a: i + 2);
711 lines.insert(i: i + 1, t: lineDirective.toUtf8());
712 }
713 }
714
715 return lines.join(sep: '\n');
716}
717
718/*!
719 \qmlmethod string ShaderProgram::loadSource(url sourceUrl)
720
721 Returns the shader code loaded from \a sourceUrl.
722*/
723/*!
724 Returns the shader code loaded from \a sourceUrl.
725*/
726QByteArray QShaderProgram::loadSource(const QUrl &sourceUrl)
727{
728 // TO DO: Handle remote path
729 return QShaderProgramPrivate::deincludify(filePath: Qt3DRender::QUrlHelper::urlToLocalFileOrQrc(url: sourceUrl));
730}
731
732Qt3DCore::QNodeCreatedChangeBasePtr QShaderProgram::createNodeCreationChange() const
733{
734 auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QShaderProgramData>::create(arguments: this);
735 auto &data = creationChange->data;
736 Q_D(const QShaderProgram);
737 data.vertexShaderCode = d->m_vertexShaderCode;
738 data.tessellationControlShaderCode = d->m_tessControlShaderCode;
739 data.tessellationEvaluationShaderCode = d->m_tessEvalShaderCode;
740 data.geometryShaderCode = d->m_geometryShaderCode;
741 data.fragmentShaderCode = d->m_fragmentShaderCode;
742 data.computeShaderCode = d->m_computeShaderCode;
743 data.format = d->m_format;
744 return creationChange;
745}
746
747} // of namespace Qt3DRender
748
749QT_END_NAMESPACE
750

source code of qt3d/src/render/materialsystem/qshaderprogram.cpp