QmlDesigner: Add more shader compiling support functionality

Functionality for adding default shaders, tags, and varying variables

Task-number: QDS-10499
Change-Id: Ib32e558510fb37c29765d2467cfc4c047a446a87
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Amr Essam
2023-09-05 16:07:38 +03:00
committed by Amr Elsayed
parent 99cabee246
commit 1474afe8db
2 changed files with 107 additions and 35 deletions

View File

@@ -4,8 +4,10 @@
#include "effectmakermodel.h" #include "effectmakermodel.h"
#include "compositionnode.h" #include "compositionnode.h"
#include "syntaxhighlighterdata.h"
#include "uniform.h" #include "uniform.h"
#include <QByteArrayView>
#include <QRegularExpression> #include <QRegularExpression>
#include <QVector2D> #include <QVector2D>
@@ -166,7 +168,6 @@ const QString EffectMakerModel::getFSUniforms()
return s; return s;
} }
// Detects common GLSL error messages and returns potential // Detects common GLSL error messages and returns potential
// additional error information related to them. // additional error information related to them.
QString EffectMakerModel::detectErrorMessage(const QString &errorMessage) QString EffectMakerModel::detectErrorMessage(const QString &errorMessage)
@@ -210,8 +211,7 @@ void EffectMakerModel::setEffectError(const QString &errorMessage, int type, int
// For shaders, get the line number from baker output. // For shaders, get the line number from baker output.
// Which is something like "ERROR: :15: message" // Which is something like "ERROR: :15: message"
int glslErrorLineNumber = -1; int glslErrorLineNumber = -1;
static QRegularExpression spaceReg("\\s+"); QStringList errorStringList = errorMessage.split(m_spaceReg, Qt::SkipEmptyParts);
QStringList errorStringList = errorMessage.split(spaceReg, Qt::SkipEmptyParts);
if (errorStringList.size() >= 2) { if (errorStringList.size() >= 2) {
QString lineString = errorStringList.at(1).trimmed(); QString lineString = errorStringList.at(1).trimmed();
if (lineString.size() >= 3) { if (lineString.size() >= 3) {
@@ -284,69 +284,137 @@ const QString EffectMakerModel::getConstVariables()
const QString EffectMakerModel::getDefineProperties() const QString EffectMakerModel::getDefineProperties()
{ {
// TODO const QList<Uniform *> uniforms = allUniforms();
return QString(); QString s;
for (Uniform *uniform : uniforms) {
// TODO: Check if uniform is already added.
if (uniform->type() == Uniform::Type::Define) {
QString defineValue = uniform->value().toString();
s += QString("#define %1 %2\n").arg(uniform->name(), defineValue);
}
}
if (!s.isEmpty())
s += '\n';
return s;
} }
int EffectMakerModel::getTagIndex(const QStringList &code, const QString &tag) int EffectMakerModel::getTagIndex(const QStringList &code, const QString &tag)
{ {
Q_UNUSED(code) int index = -1;
Q_UNUSED(tag) int line = 0;
const QString tagString = QString("@%1").arg(tag);
// TODO for (const QString &s : code) {
return 0; auto st = s.trimmed();
// Check if line or first non-space content of the line matches to tag
static auto spaceReg = QRegularExpression("\\s");
auto firstSpace = st.indexOf(spaceReg);
QString firstWord = st;
if (firstSpace > 0)
firstWord = st.sliced(0, firstSpace);
if (firstWord == tagString) {
index = line;
break;
}
line++;
}
return index;
} }
QString EffectMakerModel::processVertexRootLine(const QString &line) QString EffectMakerModel::processVertexRootLine(const QString &line)
{ {
Q_UNUSED(line) QString output;
QStringList lineList = line.split(m_spaceReg, Qt::SkipEmptyParts);
// TODO if (lineList.length() > 1 && lineList.at(0) == QStringLiteral("out")) {
return QString(); lineList.removeFirst();
QString outLine = lineList.join(' ');
m_shaderVaryingVariables << outLine;
} else {
output = line + '\n';
}
return output;
} }
QString EffectMakerModel:: processFragmentRootLine(const QString &line) QString EffectMakerModel::processFragmentRootLine(const QString &line)
{ {
Q_UNUSED(line) QString output;
QStringList lineList = line.split(m_spaceReg, Qt::SkipEmptyParts);
// TODO // Just skip all "in" variables. It is enough to have "out" variable in vertex.
if (lineList.length() > 1 && lineList.at(0) == QStringLiteral("in"))
return QString(); return QString();
output = line + '\n';
return output;
} }
QStringList EffectMakerModel::getDefaultRootVertexShader() QStringList EffectMakerModel::getDefaultRootVertexShader()
{ {
// TODO if (m_defaultRootVertexShader.isEmpty()) {
return {}; m_defaultRootVertexShader << "void main() {";
m_defaultRootVertexShader << " texCoord = qt_MultiTexCoord0;";
m_defaultRootVertexShader << " fragCoord = qt_Vertex.xy;";
m_defaultRootVertexShader << " vec2 vertCoord = qt_Vertex.xy;";
m_defaultRootVertexShader << " @nodes";
m_defaultRootVertexShader << " gl_Position = qt_Matrix * vec4(vertCoord, 0.0, 1.0);";
m_defaultRootVertexShader << "}";
}
return m_defaultRootVertexShader;
} }
QStringList EffectMakerModel::getDefaultRootFragmentShader() QStringList EffectMakerModel::getDefaultRootFragmentShader()
{ {
// TODO if (m_defaultRootFragmentShader.isEmpty()) {
return {}; m_defaultRootFragmentShader << "void main() {";
m_defaultRootFragmentShader << " fragColor = texture(iSource, texCoord);";
m_defaultRootFragmentShader << " @nodes";
m_defaultRootFragmentShader << " fragColor = fragColor * qt_Opacity;";
m_defaultRootFragmentShader << "}";
}
return m_defaultRootFragmentShader;
} }
// Remove all post-processing tags ("@tag") from the code.
// Except "@nodes" tag as that is handled later.
QStringList EffectMakerModel::removeTagsFromCode(const QStringList &codeLines) QStringList EffectMakerModel::removeTagsFromCode(const QStringList &codeLines)
{ {
Q_UNUSED(codeLines) QStringList s;
for (const QString &line : codeLines) {
// TODO const auto trimmedLine = line.trimmed();
return {}; if (!trimmedLine.startsWith('@') || trimmedLine.startsWith("@nodes")) {
s << line;
} else {
// Check if the tag is known
bool validTag = false;
const QList<QByteArrayView> tags = SyntaxHighlighterData::reservedTagNames();
QString firstWord = trimmedLine.split(m_spaceReg, Qt::SkipEmptyParts).first();
for (const QByteArrayView &tag : tags) {
if (firstWord == QString::fromUtf8(tag)) {
validTag = true;
break;
}
}
if (!validTag)
setEffectError(QString("Unknown tag: %1").arg(trimmedLine), ErrorPreprocessor);
}
}
return s;
} }
QString EffectMakerModel::removeTagsFromCode(const QString &code) QString EffectMakerModel::removeTagsFromCode(const QString &code)
{ {
Q_UNUSED(code) QStringList codeLines = removeTagsFromCode(code.split('\n'));
return codeLines.join('\n');
// TODO
return QString();
} }
QString EffectMakerModel::getCustomShaderVaryings(bool outState) QString EffectMakerModel::getCustomShaderVaryings(bool outState)
{ {
Q_UNUSED(outState) QString output;
QString direction = outState ? QStringLiteral("out") : QStringLiteral("in");
// TODO int varLocation = m_shaderFeatures.enabled(ShaderFeatures::FragCoord) ? 2 : 1;
return QString(); for (const QString &var : std::as_const(m_shaderVaryingVariables)) {
output += QString("layout(location = %1) %2 %3\n").arg(QString::number(varLocation), direction, var);
varLocation++;
}
return output;
} }
QString EffectMakerModel::generateVertexShader(bool includeUniforms) QString EffectMakerModel::generateVertexShader(bool includeUniforms)

View File

@@ -110,6 +110,10 @@ private:
QStringList m_shaderVaryingVariables; QStringList m_shaderVaryingVariables;
QString m_fragmentShader; QString m_fragmentShader;
QString m_vertexShader; QString m_vertexShader;
QStringList m_defaultRootVertexShader;
QStringList m_defaultRootFragmentShader;
const QRegularExpression m_spaceReg = QRegularExpression("\\s+");
}; };
} // namespace QmlDesigner } // namespace QmlDesigner