1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "shaderfeatures.h"
#include <QMap>
#include <QRegularExpression>
#include <QStandardItemModel>
#include <QTemporaryFile>
#include <QtShaderTools/private/qshaderbaker_p.h>
namespace EffectMaker {
class CompositionNode;
class Uniform;
struct EffectError {
Q_GADGET
Q_PROPERTY(QString message MEMBER m_message)
Q_PROPERTY(int line MEMBER m_line)
Q_PROPERTY(int type MEMBER m_type)
public:
QString m_message;
int m_line = -1;
int m_type = -1;
};
class EffectMakerModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged)
Q_PROPERTY(bool shadersUpToDate READ shadersUpToDate WRITE setShadersUpToDate NOTIFY shadersUpToDateChanged)
Q_PROPERTY(QString qmlComponentString READ qmlComponentString)
public:
EffectMakerModel(QObject *parent = nullptr);
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
bool isEmpty() const { return m_isEmpty; }
void setIsEmpty(bool val);
void addNode(const QString &nodeQenPath);
Q_INVOKABLE void moveNode(int fromIdx, int toIdx);
Q_INVOKABLE void removeNode(int idx);
bool shadersUpToDate() const;
void setShadersUpToDate(bool newShadersUpToDate);
QString fragmentShader() const;
void setFragmentShader(const QString &newFragmentShader);
QString vertexShader() const;
void setVertexShader(const QString &newVertexShader);
const QString &qmlComponentString() const;
void setQmlComponentString(const QString &string);
Q_INVOKABLE void updateQmlComponent();
signals:
void isEmptyChanged();
void selectedIndexChanged(int idx);
void effectErrorChanged();
void shadersUpToDateChanged();
void shadersBaked();
private:
enum Roles {
NameRole = Qt::UserRole + 1,
EnabledRole,
UniformsRole
};
enum ErrorTypes {
ErrorCommon = -1,
ErrorQMLParsing,
ErrorVert,
ErrorFrag,
ErrorQMLRuntime,
ErrorPreprocessor
};
bool isValidIndex(int idx) const;
const QList<Uniform *> allUniforms();
const QString getBufUniform();
const QString getVSUniforms();
const QString getFSUniforms();
void updateBakedShaderVersions();
QString detectErrorMessage(const QString &errorMessage);
EffectError effectError() const;
void setEffectError(const QString &errorMessage, int type = -1, int lineNumber = -1);
void resetEffectError(int type);
QString valueAsString(const Uniform &uniform);
QString valueAsBinding(const Uniform &uniform);
QString valueAsVariable(const Uniform &uniform);
QString getImageElementName(const Uniform &uniform);
const QString getConstVariables();
const QString getDefineProperties();
int getTagIndex(const QStringList &code, const QString &tag);
QString processVertexRootLine(const QString &line);
QString processFragmentRootLine(const QString &line);
QStringList getDefaultRootVertexShader();
QStringList getDefaultRootFragmentShader();
QStringList removeTagsFromCode(const QStringList &codeLines);
QString removeTagsFromCode(const QString &code);
QString getCustomShaderVaryings(bool outState);
QString generateVertexShader(bool includeUniforms = true);
QString generateFragmentShader(bool includeUniforms = true);
void updateCustomUniforms();
void bakeShaders();
QString getQmlImagesString(bool localFiles);
QString getQmlComponentString(bool localFiles);
QList<CompositionNode *> m_nodes;
int m_selectedIndex = -1;
bool m_isEmpty = true;
// True when shaders haven't changed since last baking
bool m_shadersUpToDate = true;
QMap<int, EffectError> m_effectErrors;
ShaderFeatures m_shaderFeatures;
QStringList m_shaderVaryingVariables;
QString m_fragmentShader;
QString m_vertexShader;
QStringList m_defaultRootVertexShader;
QStringList m_defaultRootFragmentShader;
QShaderBaker m_baker;
QTemporaryFile m_fragmentShaderFile;
QTemporaryFile m_vertexShaderFile;
// Used in exported QML, at root of the file
QString m_exportedRootPropertiesString;
// Used in exported QML, at ShaderEffect component of the file
QString m_exportedEffectPropertiesString;
// Used in preview QML, at ShaderEffect component of the file
QString m_previewEffectPropertiesString;
QString m_qmlComponentString;
const QRegularExpression m_spaceReg = QRegularExpression("\\s+");
};
} // namespace EffectMaker
|