2023-06-29 15:06:11 +03:00
|
|
|
// 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
|
|
|
|
|
|
2023-08-30 13:43:24 +03:00
|
|
|
#include "shaderfeatures.h"
|
|
|
|
|
|
2023-10-09 13:46:08 +03:00
|
|
|
#include <utils/filepath.h>
|
|
|
|
|
|
2023-10-19 16:39:21 +03:00
|
|
|
#include <QFileSystemWatcher>
|
2023-08-17 13:41:27 +03:00
|
|
|
#include <QMap>
|
2023-09-06 16:32:10 +03:00
|
|
|
#include <QRegularExpression>
|
2023-06-29 15:06:11 +03:00
|
|
|
#include <QStandardItemModel>
|
2023-09-25 10:44:31 +03:00
|
|
|
#include <QTemporaryFile>
|
2023-06-29 15:06:11 +03:00
|
|
|
|
2023-10-11 18:59:03 +03:00
|
|
|
namespace ProjectExplorer {
|
|
|
|
|
class Target;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-09 13:46:08 +03:00
|
|
|
namespace Utils {
|
|
|
|
|
class Process;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-15 15:36:15 +03:00
|
|
|
namespace EffectMaker {
|
2023-06-29 15:06:11 +03:00
|
|
|
|
2023-08-17 13:41:27 +03:00
|
|
|
class CompositionNode;
|
2023-08-30 13:43:24 +03:00
|
|
|
class Uniform;
|
2023-08-17 13:41:27 +03:00
|
|
|
|
2023-09-01 10:59:02 +03:00
|
|
|
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)
|
2023-09-01 16:43:56 +03:00
|
|
|
|
2023-09-01 10:59:02 +03:00
|
|
|
public:
|
|
|
|
|
QString m_message;
|
|
|
|
|
int m_line = -1;
|
|
|
|
|
int m_type = -1;
|
|
|
|
|
};
|
|
|
|
|
|
2023-06-29 15:06:11 +03:00
|
|
|
class EffectMakerModel : public QAbstractListModel
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
|
|
|
|
Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged)
|
2023-09-01 16:43:56 +03:00
|
|
|
Q_PROPERTY(bool shadersUpToDate READ shadersUpToDate WRITE setShadersUpToDate NOTIFY shadersUpToDateChanged)
|
2023-10-03 10:34:50 +03:00
|
|
|
Q_PROPERTY(QString qmlComponentString READ qmlComponentString)
|
2023-11-14 14:49:42 +02:00
|
|
|
Q_PROPERTY(QString currentComposition READ currentComposition WRITE setCurrentComposition NOTIFY currentCompositionChanged)
|
2023-06-29 15:06:11 +03:00
|
|
|
|
|
|
|
|
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;
|
2023-09-06 15:18:02 +03:00
|
|
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
2023-06-29 15:06:11 +03:00
|
|
|
|
|
|
|
|
bool isEmpty() const { return m_isEmpty; }
|
2023-09-08 11:07:10 +03:00
|
|
|
void setIsEmpty(bool val);
|
2023-06-29 15:06:11 +03:00
|
|
|
|
2023-08-17 13:41:27 +03:00
|
|
|
void addNode(const QString &nodeQenPath);
|
2023-06-29 15:06:11 +03:00
|
|
|
|
2023-09-04 14:17:01 +03:00
|
|
|
Q_INVOKABLE void moveNode(int fromIdx, int toIdx);
|
2023-08-29 16:24:43 +03:00
|
|
|
Q_INVOKABLE void removeNode(int idx);
|
2023-11-21 12:43:49 +02:00
|
|
|
Q_INVOKABLE void removeAllNodes();
|
2023-06-29 15:06:11 +03:00
|
|
|
|
2023-09-01 16:43:56 +03:00
|
|
|
bool shadersUpToDate() const;
|
|
|
|
|
void setShadersUpToDate(bool newShadersUpToDate);
|
|
|
|
|
|
2023-09-08 11:27:00 +03:00
|
|
|
QString fragmentShader() const;
|
|
|
|
|
void setFragmentShader(const QString &newFragmentShader);
|
2023-10-09 13:46:08 +03:00
|
|
|
|
2023-09-08 11:27:00 +03:00
|
|
|
QString vertexShader() const;
|
|
|
|
|
void setVertexShader(const QString &newVertexShader);
|
|
|
|
|
|
2023-10-03 10:34:50 +03:00
|
|
|
const QString &qmlComponentString() const;
|
|
|
|
|
|
2023-10-13 15:11:43 +03:00
|
|
|
void clear();
|
|
|
|
|
|
2023-10-03 10:34:50 +03:00
|
|
|
Q_INVOKABLE void updateQmlComponent();
|
|
|
|
|
|
2023-10-09 13:46:08 +03:00
|
|
|
Q_INVOKABLE void resetEffectError(int type);
|
|
|
|
|
Q_INVOKABLE void setEffectError(const QString &errorMessage, int type = -1, int lineNumber = -1);
|
|
|
|
|
|
2023-11-08 16:12:35 +02:00
|
|
|
Q_INVOKABLE void exportComposition(const QString &name);
|
2023-11-09 18:34:18 +02:00
|
|
|
Q_INVOKABLE void exportResources(const QString &name);
|
2023-11-08 16:12:35 +02:00
|
|
|
|
2023-11-14 14:49:42 +02:00
|
|
|
void openComposition(const QString &path);
|
|
|
|
|
|
|
|
|
|
QString currentComposition() const;
|
|
|
|
|
void setCurrentComposition(const QString &newCurrentComposition);
|
|
|
|
|
|
2023-06-29 15:06:11 +03:00
|
|
|
signals:
|
|
|
|
|
void isEmptyChanged();
|
|
|
|
|
void selectedIndexChanged(int idx);
|
2023-09-01 10:59:02 +03:00
|
|
|
void effectErrorChanged();
|
2023-09-01 16:43:56 +03:00
|
|
|
void shadersUpToDateChanged();
|
2023-09-25 10:44:31 +03:00
|
|
|
void shadersBaked();
|
2023-06-29 15:06:11 +03:00
|
|
|
|
2023-11-14 14:49:42 +02:00
|
|
|
void currentCompositionChanged();
|
|
|
|
|
|
2023-06-29 15:06:11 +03:00
|
|
|
private:
|
2023-08-17 13:41:27 +03:00
|
|
|
enum Roles {
|
|
|
|
|
NameRole = Qt::UserRole + 1,
|
2023-09-06 15:18:02 +03:00
|
|
|
EnabledRole,
|
2023-08-21 11:52:11 +03:00
|
|
|
UniformsRole
|
2023-08-17 13:41:27 +03:00
|
|
|
};
|
|
|
|
|
|
2023-09-01 16:43:56 +03:00
|
|
|
enum ErrorTypes {
|
|
|
|
|
ErrorCommon = -1,
|
|
|
|
|
ErrorQMLParsing,
|
|
|
|
|
ErrorVert,
|
|
|
|
|
ErrorFrag,
|
|
|
|
|
ErrorQMLRuntime,
|
|
|
|
|
ErrorPreprocessor
|
|
|
|
|
};
|
|
|
|
|
|
2023-06-29 15:06:11 +03:00
|
|
|
bool isValidIndex(int idx) const;
|
|
|
|
|
|
2023-08-30 13:43:24 +03:00
|
|
|
const QList<Uniform *> allUniforms();
|
|
|
|
|
|
|
|
|
|
const QString getBufUniform();
|
|
|
|
|
const QString getVSUniforms();
|
|
|
|
|
const QString getFSUniforms();
|
|
|
|
|
|
2023-09-01 10:59:02 +03:00
|
|
|
QString detectErrorMessage(const QString &errorMessage);
|
|
|
|
|
EffectError effectError() const;
|
|
|
|
|
|
2023-09-08 11:27:00 +03:00
|
|
|
QString valueAsString(const Uniform &uniform);
|
|
|
|
|
QString valueAsBinding(const Uniform &uniform);
|
2023-09-04 13:09:34 +03:00
|
|
|
QString valueAsVariable(const Uniform &uniform);
|
2023-09-08 11:27:00 +03:00
|
|
|
QString getImageElementName(const Uniform &uniform);
|
2023-09-01 16:43:56 +03:00
|
|
|
const QString getConstVariables();
|
2023-09-04 14:56:30 +03:00
|
|
|
const QString getDefineProperties();
|
2023-09-01 16:43:56 +03:00
|
|
|
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);
|
2023-10-11 18:59:03 +03:00
|
|
|
void handleQsbProcessExit(Utils::Process *qsbProcess, const QString &shader);
|
2023-10-19 16:39:21 +03:00
|
|
|
QString stripFileFromURL(const QString &urlString) const;
|
2023-11-09 18:34:18 +02:00
|
|
|
QString getQmlEffectString();
|
2023-10-09 13:46:08 +03:00
|
|
|
|
2023-09-08 11:27:00 +03:00
|
|
|
void updateCustomUniforms();
|
2023-11-01 15:25:43 +02:00
|
|
|
void createFiles();
|
2023-09-01 16:43:56 +03:00
|
|
|
void bakeShaders();
|
|
|
|
|
|
2023-10-19 16:39:21 +03:00
|
|
|
QString mipmapPropertyName(const QString &name) const;
|
2023-10-03 16:00:01 +03:00
|
|
|
QString getQmlImagesString(bool localFiles);
|
2023-10-03 10:34:50 +03:00
|
|
|
QString getQmlComponentString(bool localFiles);
|
|
|
|
|
|
2023-08-29 16:24:43 +03:00
|
|
|
QList<CompositionNode *> m_nodes;
|
2023-06-29 15:06:11 +03:00
|
|
|
|
|
|
|
|
int m_selectedIndex = -1;
|
|
|
|
|
bool m_isEmpty = true;
|
2023-09-01 16:43:56 +03:00
|
|
|
// True when shaders haven't changed since last baking
|
|
|
|
|
bool m_shadersUpToDate = true;
|
2023-10-11 18:59:03 +03:00
|
|
|
int m_remainingQsbTargets = 0;
|
2023-09-01 10:59:02 +03:00
|
|
|
QMap<int, EffectError> m_effectErrors;
|
2023-08-30 13:43:24 +03:00
|
|
|
ShaderFeatures m_shaderFeatures;
|
2023-09-01 16:43:56 +03:00
|
|
|
QStringList m_shaderVaryingVariables;
|
|
|
|
|
QString m_fragmentShader;
|
|
|
|
|
QString m_vertexShader;
|
2023-09-05 16:07:38 +03:00
|
|
|
QStringList m_defaultRootVertexShader;
|
|
|
|
|
QStringList m_defaultRootFragmentShader;
|
2023-10-10 14:02:01 +03:00
|
|
|
// Temp files to store shaders sources and binary data
|
|
|
|
|
QTemporaryFile m_fragmentSourceFile;
|
|
|
|
|
QTemporaryFile m_vertexSourceFile;
|
2023-10-11 18:59:03 +03:00
|
|
|
QString m_fragmentSourceFilename;
|
|
|
|
|
QString m_vertexSourceFilename;
|
|
|
|
|
QString m_fragmentShaderFilename;
|
|
|
|
|
QString m_vertexShaderFilename;
|
2023-09-08 11:27:00 +03:00
|
|
|
// 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;
|
2023-10-03 10:34:50 +03:00
|
|
|
QString m_qmlComponentString;
|
2023-10-19 16:39:21 +03:00
|
|
|
bool m_loadComponentImages = true;
|
2023-11-14 14:49:42 +02:00
|
|
|
QString m_currentComposition;
|
2023-09-05 16:07:38 +03:00
|
|
|
|
|
|
|
|
const QRegularExpression m_spaceReg = QRegularExpression("\\s+");
|
2023-06-29 15:06:11 +03:00
|
|
|
};
|
|
|
|
|
|
2023-09-15 15:36:15 +03:00
|
|
|
} // namespace EffectMaker
|
|
|
|
|
|