Qt 6.x
The Qt SDK
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
qssgshadermaterialadapter.cpp
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5/* clang-format off */
6
7#include <QtQuick3DRuntimeRender/private/qssgshadermaterialadapter_p.h>
8#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
9
11
13
15{
16 switch (materialNode.type) {
17 case QSSGRenderGraphObject::Type::DefaultMaterial:
18 case QSSGRenderGraphObject::Type::PrincipledMaterial:
19 case QSSGRenderGraphObject::Type::SpecularGlossyMaterial:
20 return new QSSGShaderDefaultMaterialAdapter(static_cast<const QSSGRenderDefaultMaterial &>(materialNode));
21
22 case QSSGRenderGraphObject::Type::CustomMaterial:
23 return new QSSGShaderCustomMaterialAdapter(static_cast<const QSSGRenderCustomMaterial &>(materialNode));
24
25 default:
26 break;
27 }
28
29 return nullptr;
30}
31
33{
34 return false;
35}
36
38{
39 return false;
40}
41
44{
45 return QByteArray();
46}
47
49 const QByteArray &,
51{
52 return false;
53}
54
58{
59}
60
62{
63 return false;
64}
65
66
67
69 : m_material(material)
70{
71}
72
74{
75 return m_material.type == QSSGRenderGraphObject::Type::PrincipledMaterial;
76}
77
79{
80 return m_material.type == QSSGRenderGraphObject::Type::SpecularGlossyMaterial;
81}
82
84{
85 return m_material.isMetalnessEnabled();
86}
87
89{
90 return m_material.isSpecularEnabled();
91}
92
94{
95 return m_material.isVertexColorsEnabled();
96}
97
99{
100 return m_material.isClearcoatEnabled();
101}
102
104{
105 return m_material.isTransmissionEnabled();
106}
107
109{
110 return m_material.hasLighting();
111}
112
114{
115 return false;
116}
117
119{
120 return false;
121}
122
124{
125 return m_material.specularModel;
126}
127
129{
130 return m_material.alphaMode;
131}
132
134{
135 return m_material.iblProbe;
136}
137
139{
140 return m_material.emissiveColor;
141}
142
144{
145 return m_material.color;
146}
147
149{
150 return m_material.specularTint;
151}
152
154{
155 return m_material.ior;
156}
157
159{
160 return m_material.fresnelPower;
161}
162
164{
165 return m_material.metalnessAmount;
166}
167
169{
170 return m_material.specularAmount;
171}
172
174{
175 return m_material.specularRoughness;
176}
177
179{
180 return m_material.bumpAmount;
181}
182
184{
185 return m_material.translucentFalloff;
186}
187
189{
190 return m_material.diffuseLightWrap;
191}
192
194{
195 return m_material.occlusionAmount;
196}
197
199{
200 return m_material.alphaCutoff;
201}
202
204{
205 return m_material.pointSize;
206}
207
209{
210 return m_material.lineWidth;
211}
212
214{
215 return m_material.heightAmount;
216}
217
219{
220 return m_material.minHeightSamples;
221}
222
224{
225 return m_material.maxHeightSamples;
226}
227
229{
230 return m_material.clearcoatAmount;
231}
232
234{
235 return m_material.clearcoatRoughnessAmount;
236}
237
239{
240 return m_material.transmissionFactor;
241}
242
244{
245 return m_material.thicknessFactor;
246}
247
249{
250 return m_material.attenuationDistance;
251}
252
254{
255 return m_material.attenuationColor;
256}
257
259 : m_material(material)
260{
261}
262
263// Act like Principled. Lighting is always on, specular, metalness, etc. support should all be enabled.
264// Unlike Principled, the *enabled values do not depend on the metalness or specularAmount values
265// (we cannot tell what those are if they are written in the shader).
266
268{
269 return true;
270}
271
273{
274 return false;
275}
276
278{
279 return true;
280}
281
283{
284 return true;
285}
286
288{
290}
291
293{
294 // TODO: Expose Clearcoat properties to custom material
295 return false;
296}
297
299{
300 // TODO: Expose Transmission to custom material
301 return false;
302}
303
305{
306 return true;
307}
308
310{
312}
313
315{
317}
318
320{
322}
323
325{
327}
328
330{
331 return m_material.m_iblProbe;
332}
333
334// The following are the values that get set into uniforms such as
335// qt_material_properties etc. When a custom shader is present, these values
336// are not used at all. However, a CustomMaterial is also valid without a
337// vertex/fragment shader, or with no custom shaders at all. Therefore the
338// values here must match the defaults of PrincipledMaterial, in order to make
339// PrincipledMaterial { } and CustomMaterial { } identical.
340
342{
343 return QVector3D(0, 0, 0);
344}
345
347{
348 return QVector4D(1, 1, 1, 1);
349}
350
352{
353 return QVector3D(1, 1, 1);
354}
355
357{
358 return 1.45f;
359}
360
362{
363 return 0.0f;
364}
365
367{
368 return 0.0f;
369}
370
372{
373 return 0.5f;
374}
375
377{
378 return 0.0f;
379}
380
382{
383 return 0.0f;
384}
385
387{
388 return 0.0f;
389}
390
392{
393 return 0.0f;
394}
395
397{
398 return 1.0f;
399}
400
402{
403 return 0.5f;
404}
405
407{
408 return 1.0f;
409}
410
412{
413 return m_material.m_lineWidth;
414}
415
417{
418 return 0.0f;
419}
420
422{
423 return 0.0f;
424}
425
427{
428 return 0.0f;
429}
430
432{
433 return 0.0f;
434}
435
437{
438 return 0.0f;
439}
440
442{
443 return 0.0f;
444}
445
447{
448 return 0.0f;
449}
450
452{
453 return std::numeric_limits<float>::infinity();
454}
455
457{
458 return { 1.0f, 1.0f, 1.0f };
459}
460
462{
464}
465
467{
470
472}
473
475 QSSGShaderLibraryManager &shaderLibraryManager)
476{
478 return shaderLibraryManager.getShaderSource(m_material.m_shaderPathKey, type);
479
480 return QByteArray();
481}
482
484 const QByteArray &funcName,
485 QSSGShaderLibraryManager &shaderLibraryManager)
486{
487 if (hasCustomShaderSnippet(shaderType))
488 return shaderLibraryManager.getShaderMetaData(m_material.m_shaderPathKey, shaderType).customFunctions.contains(funcName);
489
490 return false;
491}
492
494 QSSGRhiShaderPipeline &shaderPipeline,
496{
497 context.customMaterialSystem()->applyRhiShaderPropertyValues(ubufData, m_material, shaderPipeline);
498}
499
501{
502 return m_material.m_usesSharedVariables;
503}
504
505namespace {
506
507// Custom material shader substitution table.
508// Must be in sync with the shader generator.
509static const QSSGCustomMaterialVariableSubstitution qssg_var_subst_tab[] = {
510 // uniform (block members)
511 { "MODELVIEWPROJECTION_MATRIX", "qt_modelViewProjection" },
512 { "VIEWPROJECTION_MATRIX", "qt_viewProjectionMatrix" },
513 { "MODEL_MATRIX", "qt_modelMatrix" },
514 { "VIEW_MATRIX", "qt_viewMatrix" },
515 { "NORMAL_MATRIX", "qt_normalMatrix"},
516 { "BONE_TRANSFORMS", "qt_getTexMatrix" },
517 { "BONE_NORMAL_TRANSFORMS", "qt_getTexMatrix" },
518 { "PROJECTION_MATRIX", "qt_projectionMatrix" },
519 { "INVERSE_PROJECTION_MATRIX", "qt_inverseProjectionMatrix" },
520 { "CAMERA_POSITION", "qt_cameraPosition" },
521 { "CAMERA_DIRECTION", "qt_cameraDirection" },
522 { "CAMERA_PROPERTIES", "qt_cameraProperties" },
523 { "FRAMEBUFFER_Y_UP", "qt_rhi_properties.x" },
524 { "NDC_Y_UP", "qt_rhi_properties.y" },
525 { "NEAR_CLIP_VALUE", "qt_rhi_properties.z" },
526 { "IBL_MAXMIPMAP", "qt_lightProbeProperties.y" },
527 { "IBL_HORIZON", "qt_lightProbeProperties.z" },
528 { "IBL_EXPOSE", "qt_lightProbeProperties.w" },
529
530 // outputs
531 { "POSITION", "gl_Position" },
532 { "FRAGCOLOR", "fragOutput" },
533 { "POINT_SIZE", "gl_PointSize" },
534
535 // fragment inputs
536 { "FRAGCOORD", "gl_FragCoord"},
537
538 // functions
539 { "DIRECTIONAL_LIGHT", "qt_directionalLightProcessor" },
540 { "POINT_LIGHT", "qt_pointLightProcessor" },
541 { "SPOT_LIGHT", "qt_spotLightProcessor" },
542 { "AMBIENT_LIGHT", "qt_ambientLightProcessor" },
543 { "SPECULAR_LIGHT", "qt_specularLightProcessor" },
544 { "MAIN", "qt_customMain" },
545 { "POST_PROCESS", "qt_customPostProcessor" },
546 { "IBL_PROBE", "qt_iblProbeProcessor" },
547
548 // textures
549 { "SCREEN_TEXTURE", "qt_screenTexture" },
550 { "SCREEN_MIP_TEXTURE", "qt_screenTexture" }, // same resource as SCREEN_TEXTURE under the hood
551 { "DEPTH_TEXTURE", "qt_depthTexture" },
552 { "AO_TEXTURE", "qt_aoTexture" },
553 { "IBL_TEXTURE", "qt_lightProbe" },
554 { "LIGHTMAP", "qt_lightmap" },
555
556 // For shaded only: vertex outputs, for convenience and perf. (only those
557 // that are always present when lighting is enabled) The custom vertex main
558 // can also calculate on its own and pass them on with VARYING but that's a
559 // bit wasteful since we calculate these anyways.
560 { "VAR_WORLD_NORMAL", "qt_varNormal" },
561 { "VAR_WORLD_TANGENT", "qt_varTangent" },
562 { "VAR_WORLD_BINORMAL", "qt_varBinormal" },
563 { "VAR_WORLD_POSITION", "qt_varWorldPos" },
564 // vertex color is always enabled for custom materials (shaded)
565 { "VAR_COLOR", "qt_varColor" },
566
567 // effects
568 { "INPUT", "qt_inputTexture" },
569 { "INPUT_UV", "qt_inputUV" },
570 { "TEXTURE_UV", "qt_textureUV" },
571 { "INPUT_SIZE", "qt_inputSize" },
572 { "OUTPUT_SIZE", "qt_outputSize" },
573 { "FRAME", "qt_frame_num" },
574
575 // instancing
576 { "INSTANCE_COLOR", "qt_instanceColor"},
577 { "INSTANCE_DATA", "qt_instanceData"},
578 { "INSTANCE_INDEX", "gl_InstanceIndex"},
579
580 // morphing
581 { "MORPH_POSITION", "qt_getTargetPositionFromTargetId"},
582 { "MORPH_NORMAL", "qt_getTargetNormalFromTargetId"},
583 { "MORPH_TANGENT", "qt_getTargetTangentFromTargetId"},
584 { "MORPH_BINORMAL", "qt_getTargetBinormalFromTargetId"},
585 { "MORPH_WEIGHTS", "qt_morphWeights"},
586
587 // custom variables
588 { "SHARED_VARS", "struct QT_SHARED_VARS"}
589};
590
591// Functions that, if present, get an argument list injected.
592static const QByteArrayView qssg_func_injectarg_tab[] = {
593 "DIRECTIONAL_LIGHT",
594 "POINT_LIGHT",
595 "SPOT_LIGHT",
596 "AMBIENT_LIGHT",
597 "SPECULAR_LIGHT",
598 "MAIN",
599 "POST_PROCESS",
600 "IBL_PROBE"
601};
602
603// This is based on the Qt Quick shader rewriter (with fixes)
604struct Tokenizer {
605 enum Token {
606 Token_Comment,
607 Token_OpenBrace,
608 Token_CloseBrace,
609 Token_OpenParen,
610 Token_CloseParen,
611 Token_SemiColon,
612 Token_Identifier,
613 Token_Macro,
614 Token_OpenBraket,
615 Token_CloseBraket,
616 Token_Unspecified,
617
618 Token_EOF
619 };
620
621 void initialize(const QByteArray &input);
622 Token next();
623
624 const char *stream;
625 const char *pos;
626 const char *identifier;
627};
628
629void Tokenizer::initialize(const QByteArray &input)
630{
631 stream = input.constData();
632 pos = input;
633 identifier = input;
634}
635
636Tokenizer::Token Tokenizer::next()
637{
638 while (*pos) {
639 char c = *pos++;
640 switch (c) {
641 case '/':
642 if (*pos == '/') {
643 // '//' comment
644 ++pos;
645 while (*pos && *pos != '\n') ++pos;
646 return Token_Comment;
647 } else if (*pos == '*') {
648 // /* */ comment
649 ++pos;
650 while (*pos && (*pos != '*' || pos[1] != '/')) ++pos;
651 if (*pos) pos += 2;
652 return Token_Comment;
653 }
654 return Token_Unspecified;
655
656 case '#': {
657 while (*pos) {
658 if (*pos == '\n') {
659 ++pos;
660 break;
661 } else if (*pos == '\\') {
662 ++pos;
663 while (*pos && (*pos == ' ' || *pos == '\t'))
664 ++pos;
665 if (*pos && (*pos == '\n' || (*pos == '\r' && pos[1] == '\n')))
666 pos += 2;
667 } else {
668 ++pos;
669 }
670 }
671 return Token_Unspecified;
672 }
673
674 case ';': return Token_SemiColon;
675 case '\0': return Token_EOF;
676 case '{': return Token_OpenBrace;
677 case '}': return Token_CloseBrace;
678 case '(': return Token_OpenParen;
679 case ')': return Token_CloseParen;
680 case '[': return Token_OpenBraket;
681 case ']': return Token_CloseBraket;
682
683 case ' ':
684 case '\n':
685 case '\r': break;
686 default:
687 // Identifier...
688 if ((c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' ) || c == '_') {
689 identifier = pos - 1;
690 while (*pos && ((*pos >= 'a' && *pos <= 'z')
691 || (*pos >= 'A' && *pos <= 'Z')
692 || *pos == '_'
693 || (*pos >= '0' && *pos <= '9'))) {
694 ++pos;
695 }
696 return Token_Identifier;
697 } else {
698 return Token_Unspecified;
699 }
700 }
701 }
702
703 return Token_EOF;
704}
705} // namespace
706
709 const QByteArray &shaderCode,
711 const StringPairList &baseUniforms,
712 const StringPairList &baseInputs,
713 const StringPairList &baseOutputs)
714{
715 QByteArrayList inputs;
716 QByteArrayList outputs;
717
718 Tokenizer tok;
719 tok.initialize(shaderCode);
720
723 result.reserve(1024);
724 // If shader debugging is not enabled we reset the line count to make error message
725 // when a shader fails more useful. When shader debugging is enabled the whole shader
726 // will be printed and not just the user written part, so in that case we do not want
727 // to adjust the line numbers.
728 //
729 // NOTE: This is not perfect, we do expend the custom material and effect shaders, so
730 // there cane still be cases where the reported line numbers are slightly off.
732 result.prepend("#line 1\n");
733 const char *lastPos = shaderCode.constData();
734
735 int funcFinderState = 0;
736 int useJointTexState = -1;
737 int useJointNormalTexState = -1;
738 QByteArray currentShadedFunc;
739 Tokenizer::Token t = tok.next();
740 while (t != Tokenizer::Token_EOF) {
741 switch (t) {
742 case Tokenizer::Token_Comment:
743 break;
744 case Tokenizer::Token_Identifier:
745 {
746 QByteArray id = QByteArray::fromRawData(lastPos, tok.pos - lastPos);
747 if (id.trimmed() == QByteArrayLiteral("VARYING")) {
748 QByteArray vtype;
749 QByteArray vname;
750 lastPos = tok.pos;
751 t = tok.next();
752 while (t != Tokenizer::Token_EOF) {
753 QByteArray data = QByteArray::fromRawData(lastPos, tok.pos - lastPos);
754 if (t == Tokenizer::Token_Identifier) {
755 if (vtype.isEmpty())
756 vtype = data.trimmed();
757 else if (vname.isEmpty())
758 vname = data.trimmed();
759 }
760 if (t == Tokenizer::Token_SemiColon)
761 break;
762 lastPos = tok.pos;
763 t = tok.next();
764 }
766 outputs.append(vtype + " " + vname);
767 else
768 inputs.append(vtype + " " + vname);
769 } else {
770 const QByteArray trimmedId = id.trimmed();
771 if (funcFinderState == 0 && trimmedId == QByteArrayLiteral("void")) {
772 funcFinderState += 1;
773 } else if (funcFinderState == 1) {
774 auto begin = qssg_func_injectarg_tab;
775 const auto end = qssg_func_injectarg_tab + (sizeof(qssg_func_injectarg_tab) / sizeof(qssg_func_injectarg_tab[0]));
776 const auto foundIt = std::find_if(begin, end, [trimmedId](const QByteArrayView &entry) { return entry == trimmedId; });
777 if (foundIt != end) {
778 currentShadedFunc = trimmedId;
779 funcFinderState += 1;
780 }
781 } else {
782 funcFinderState = 0;
783 }
784
785 if (trimmedId == QByteArrayLiteral("SCREEN_TEXTURE"))
787 else if (trimmedId == QByteArrayLiteral("SCREEN_MIP_TEXTURE"))
789 else if (trimmedId == QByteArrayLiteral("DEPTH_TEXTURE"))
791 else if (trimmedId == QByteArrayLiteral("AO_TEXTURE"))
793 else if (trimmedId == QByteArrayLiteral("POSITION"))
795 else if (trimmedId == QByteArrayLiteral("PROJECTION_MATRIX"))
797 else if (trimmedId == QByteArrayLiteral("INVERSE_PROJECTION_MATRIX"))
799 else if (trimmedId == QByteArrayLiteral("VAR_COLOR"))
801 else if (trimmedId == QByteArrayLiteral("SHARED_VARS"))
803 else if (trimmedId == QByteArrayLiteral("IBL_ORIENTATION"))
805 else if (trimmedId == QByteArrayLiteral("LIGHTMAP"))
807
808 for (const QSSGCustomMaterialVariableSubstitution &subst : qssg_var_subst_tab) {
809 if (trimmedId == subst.builtin) {
810 id.replace(subst.builtin, subst.actualName); // replace, not assignment, to keep whitespace etc.
811 if (trimmedId == QByteArrayLiteral("BONE_TRANSFORMS")) {
812 useJointTexState = 0;
814 } else if (trimmedId == QByteArrayLiteral("BONE_NORMAL_TRANSFORMS")) {
815 useJointNormalTexState = 0;
817 }
818 if (trimmedId == QByteArrayLiteral("MORPH_POSITION") ||
819 trimmedId == QByteArrayLiteral("MORPH_NORMAL") ||
820 trimmedId == QByteArrayLiteral("MORPH_TANGENT") ||
821 trimmedId == QByteArrayLiteral("MORPH_BINORMAL"))
823 break;
824 }
825 }
826 result += id;
827 }
828 }
829 break;
830 case Tokenizer::Token_OpenParen:
831 result += QByteArray::fromRawData(lastPos, tok.pos - lastPos);
832 if (funcFinderState == 2) {
833 result += QByteArrayLiteral("/*%QT_ARGS_");
834 result += currentShadedFunc;
835 result += QByteArrayLiteral("%*/");
836 for (const QSSGCustomMaterialVariableSubstitution &subst : qssg_var_subst_tab) {
837 if (currentShadedFunc == subst.builtin) {
838 currentShadedFunc = subst.actualName.toByteArray();
839 break;
840 }
841 }
842 md.customFunctions.insert(currentShadedFunc);
843 currentShadedFunc.clear();
844 }
845 funcFinderState = 0;
846 break;
847 case Tokenizer::Token_OpenBraket:
848 if (useJointTexState == 0) {
849 result += QByteArrayLiteral("(2 * (");
850 ++useJointTexState;
851 break;
852 } else if (useJointNormalTexState == 0) {
853 result += QByteArrayLiteral("(1 + 2 * (");
854 ++useJointNormalTexState;
855 break;
856 }
857
858 if (useJointTexState >= 0)
859 ++useJointTexState;
860 else if (useJointNormalTexState >= 0)
861 ++useJointNormalTexState;
863 break;
864 case Tokenizer::Token_CloseBraket:
865 // This implementation will not allow mixed usages of BONE_TRANSFORMS and
866 // BONE_NORMAL_TRANSFORMS.
867 // For example, BONE_TRANSFORM[int(BONE_NORMAL_TRANFORMS[i][0].x)]
868 // cannot be compiled successfully.
869 if (useJointTexState <= 0 && useJointNormalTexState <= 0) {
871 break;
872 }
873 if (useJointTexState > 1) {
875 --useJointTexState;
876 break;
877 } else if (useJointNormalTexState > 1) {
879 --useJointNormalTexState;
880 break;
881 }
882 result += QByteArrayLiteral("))");
883 useJointTexState = -1;
884 useJointNormalTexState = -1;
885 break;
886 default:
887 result += QByteArray::fromRawData(lastPos, tok.pos - lastPos);
888 break;
889 }
890 lastPos = tok.pos;
891 t = tok.next();
892 }
893
894 result += '\n';
895
896 StringPairList allUniforms = baseUniforms;
898 allUniforms.append({ "sampler2D", "qt_screenTexture" });
900 allUniforms.append({ "sampler2D", "qt_depthTexture" });
902 allUniforms.append({ "sampler2D", "qt_aoTexture" });
904 allUniforms.append({ "sampler2D", "qt_lightmap" });
905
906 static const char *metaStart = "#ifdef QQ3D_SHADER_META\n/*{\n \"uniforms\": [\n";
907 static const char *metaEnd = " ]\n}*/\n#endif\n";
908 dst.append(metaStart);
909 for (int i = 0, count = allUniforms.size(); i < count; ++i) {
910 const auto &typeAndName(allUniforms[i]);
911 dst.append(" { \"type\": \"" + typeAndName.first + "\", \"name\": \"" + typeAndName.second + "\" }");
912 if (i < count - 1)
913 dst.append(",");
914 dst.append("\n");
915 }
916 dst.append(metaEnd);
917
918 const char *stageStr = type == QSSGShaderCache::ShaderType::Vertex ? "vertex" : "fragment";
919 StringPairList allInputs = baseInputs;
920 for (const QByteArray &inputTypeAndName : inputs) {
921 const QByteArrayList typeAndName = inputTypeAndName.split(' ');
922 if (typeAndName.size() == 2)
923 allInputs.append({ typeAndName[0].trimmed(), typeAndName[1].trimmed() });
924 }
925 if (!allInputs.isEmpty()) {
926 static const char *metaStart = "#ifdef QQ3D_SHADER_META\n/*{\n \"inputs\": [\n";
927 static const char *metaEnd = " ]\n}*/\n#endif\n";
928 dst.append(metaStart);
929 for (int i = 0, count = allInputs.size(); i < count; ++i) {
930 dst.append(" { \"type\": \"" + allInputs[i].first
931 + "\", \"name\": \"" + allInputs[i].second
932 + "\", \"stage\": \"" + stageStr + "\" }");
933 if (i < count - 1)
934 dst.append(",");
935 dst.append("\n");
936 }
937 dst.append(metaEnd);
938 }
939
940 StringPairList allOutputs = baseOutputs;
941 for (const QByteArray &outputTypeAndName : outputs) {
942 const QByteArrayList typeAndName = outputTypeAndName.split(' ');
943 if (typeAndName.size() == 2)
944 allOutputs.append({ typeAndName[0].trimmed(), typeAndName[1].trimmed() });
945 }
946 if (!allOutputs.isEmpty()) {
947 static const char *metaStart = "#ifdef QQ3D_SHADER_META\n/*{\n \"outputs\": [\n";
948 static const char *metaEnd = " ]\n}*/\n#endif\n";
949 dst.append(metaStart);
950 for (int i = 0, count = allOutputs.size(); i < count; ++i) {
951 dst.append(" { \"type\": \"" + allOutputs[i].first
952 + "\", \"name\": \"" + allOutputs[i].second
953 + "\", \"stage\": \"" + stageStr + "\" }");
954 if (i < count - 1)
955 dst.append(",");
956 dst.append("\n");
957 }
958 dst.append(metaEnd);
959 }
960
961 return { result, md };
962}
963
965{
967 k.reserve(std::size(qssg_var_subst_tab));
968 for (const auto &v : qssg_var_subst_tab)
969 k.push_back(v.builtin);
970 return k;
971}
972
974
\inmodule QtCore
\inmodule QtCore
Definition qbytearray.h:57
QByteArray trimmed() const &
Definition qbytearray.h:198
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
void clear()
Clears the contents of the byte array and makes it null.
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:394
Definition qlist.h:74
void push_back(parameter_type t)
Definition qlist.h:672
void reserve(qsizetype size)
Definition qlist.h:746
static bool shaderDebuggingEnabled()
QSSGCustomShaderMetaData getShaderMetaData(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
QByteArray getShaderSource(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
bool contains(const T &value) const
Definition qset.h:71
iterator insert(const T &value)
Definition qset.h:155
constexpr size_type size() const noexcept
void append(const T &t)
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
The QVector4D class represents a vector or vertex in 4D space.
Definition qvectornd.h:330
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QByteArrayView trimmed(QByteArrayView s) noexcept
Q_QUICK3DRUNTIMERENDER_EXPORT QList< QByteArrayView > preprocessorVars()
static void * context
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
static bool initialize()
Definition qctf.cpp:67
EGLStreamKHR stream
GLsizei const GLfloat * v
[13]
GLuint GLuint end
GLenum GLuint id
[7]
GLenum GLenum GLsizei count
GLenum type
GLenum GLenum dst
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint first
const GLubyte * c
GLuint entry
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLenum GLenum GLenum input
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
CustomShaderPresence m_customShaderPresence
QSSGRenderDefaultMaterial::MaterialSpecularModel specularModel
QSSGRenderDefaultMaterial::MaterialAlphaMode alphaMode
bool hasCustomShaderSnippet(QSSGShaderCache::ShaderType type) override
bool hasCustomShaderFunction(QSSGShaderCache::ShaderType shaderType, const QByteArray &funcName, QSSGShaderLibraryManager &shaderLibraryManager) override
void setCustomPropertyUniforms(char *ubufData, QSSGRhiShaderPipeline &shaderPipeline, const QSSGRenderContextInterface &context) override
static ShaderCodeAndMetaData prepareCustomShader(QByteArray &dst, const QByteArray &shaderCode, QSSGShaderCache::ShaderType type, const StringPairList &baseUniforms, const StringPairList &baseInputs=StringPairList(), const StringPairList &baseOutputs=StringPairList())
QSSGShaderCustomMaterialAdapter(const QSSGRenderCustomMaterial &material)
QPair< QByteArray, QSSGCustomShaderMetaData > ShaderCodeAndMetaData
QByteArray customShaderSnippet(QSSGShaderCache::ShaderType type, QSSGShaderLibraryManager &shaderLibraryManager) override
QSSGRenderDefaultMaterial::MaterialSpecularModel specularModel() override
QSSGRenderDefaultMaterial::MaterialAlphaMode alphaMode() override
QSSGShaderDefaultMaterialAdapter(const QSSGRenderDefaultMaterial &material)
QSSGRenderDefaultMaterial::MaterialSpecularModel specularModel() override
QSSGRenderDefaultMaterial::MaterialAlphaMode alphaMode() override
virtual ~QSSGShaderMaterialAdapter()
virtual QByteArray customShaderSnippet(QSSGShaderCache::ShaderType type, QSSGShaderLibraryManager &shaderLibraryManager)
virtual bool hasCustomShaderFunction(QSSGShaderCache::ShaderType shaderType, const QByteArray &funcName, QSSGShaderLibraryManager &shaderLibraryManager)
virtual bool hasCustomShaderSnippet(QSSGShaderCache::ShaderType type)
static QSSGShaderMaterialAdapter * create(const QSSGRenderGraphObject &materialNode)
virtual void setCustomPropertyUniforms(char *ubufData, QSSGRhiShaderPipeline &shaderPipeline, const QSSGRenderContextInterface &context)
Token
Definition token.h:194