forked from qt-creator/qt-creator
QmlDesigner: Prepare the process to compile shaders externally
Also added customValue for Uniform Task-number: QDS-10811 Change-Id: Ie47ad41d0c80da149bdab9cae542297d59abcee6 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -20,6 +20,31 @@ Column {
|
|||||||
// The delay in ms to wait until updating the effect
|
// The delay in ms to wait until updating the effect
|
||||||
readonly property int updateDelay: 200
|
readonly property int updateDelay: 200
|
||||||
|
|
||||||
|
// Create a dummy parent to host the effect qml object
|
||||||
|
function createNewComponent() {
|
||||||
|
var oldComponent = componentParent.children[0];
|
||||||
|
if (oldComponent)
|
||||||
|
oldComponent.destroy();
|
||||||
|
try {
|
||||||
|
const newObject = Qt.createQmlObject(
|
||||||
|
effectMakerModel.qmlComponentString,
|
||||||
|
componentParent,
|
||||||
|
""
|
||||||
|
);
|
||||||
|
effectMakerModel.resetEffectError(0);
|
||||||
|
} catch (error) {
|
||||||
|
let errorString = "QML: ERROR: ";
|
||||||
|
let errorLine = -1;
|
||||||
|
if (error.qmlErrors.length > 0) {
|
||||||
|
// Show the first QML error
|
||||||
|
let e = error.qmlErrors[0];
|
||||||
|
errorString += e.lineNumber + ": " + e.message;
|
||||||
|
errorLine = e.lineNumber;
|
||||||
|
}
|
||||||
|
effectMakerModel.setEffectError(errorString, 0, errorLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle { // toolbar
|
Rectangle { // toolbar
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: StudioTheme.Values.toolbarHeight
|
height: StudioTheme.Values.toolbarHeight
|
||||||
@@ -154,32 +179,6 @@ Column {
|
|||||||
layer.smooth: true
|
layer.smooth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a dummy parent to host the effect qml object
|
|
||||||
function createNewComponent() {
|
|
||||||
var oldComponent = componentParent.children[0];
|
|
||||||
if (oldComponent)
|
|
||||||
oldComponent.destroy();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const newObject = Qt.createQmlObject(
|
|
||||||
effectMakerModel.qmlComponentString,
|
|
||||||
componentParent,
|
|
||||||
""
|
|
||||||
);
|
|
||||||
effectMakerModel.resetEffectError(0);
|
|
||||||
} catch (error) {
|
|
||||||
let errorString = "QML: ERROR: ";
|
|
||||||
let errorLine = -1;
|
|
||||||
if (error.qmlErrors.length > 0) {
|
|
||||||
// Show the first QML error
|
|
||||||
let e = error.qmlErrors[0];
|
|
||||||
errorString += e.lineNumber + ": " + e.message;
|
|
||||||
errorLine = e.lineNumber;
|
|
||||||
}
|
|
||||||
effectMakerModel.setEffectError(errorString, 0, errorLine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: effectMakerModel
|
target: effectMakerModel
|
||||||
function onShadersBaked() {
|
function onShadersBaked() {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ find_package(Qt6 OPTIONAL_COMPONENTS Gui Quick ShaderTools)
|
|||||||
add_qtc_plugin(EffectMakerNew
|
add_qtc_plugin(EffectMakerNew
|
||||||
CONDITION TARGET QmlDesigner AND TARGET Qt::ShaderTools
|
CONDITION TARGET QmlDesigner AND TARGET Qt::ShaderTools
|
||||||
PLUGIN_DEPENDS
|
PLUGIN_DEPENDS
|
||||||
QtCreator::Core QtCreator::QmlDesigner
|
QtCreator::Core QtCreator::QmlDesigner QtCreator::ProjectExplorer
|
||||||
DEPENDS
|
DEPENDS
|
||||||
Qt::Core
|
Qt::Core
|
||||||
QtCreator::Utils Qt::CorePrivate Qt::Widgets Qt::Qml Qt::QmlPrivate Qt::Quick Qt::ShaderTools Qt::ShaderToolsPrivate
|
QtCreator::Utils Qt::CorePrivate Qt::Widgets Qt::Qml Qt::QmlPrivate Qt::Quick Qt::ShaderTools Qt::ShaderToolsPrivate
|
||||||
|
|||||||
@@ -10,6 +10,12 @@
|
|||||||
#include <QByteArrayView>
|
#include <QByteArrayView>
|
||||||
#include <QVector2D>
|
#include <QVector2D>
|
||||||
|
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/projecttree.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
namespace EffectMaker {
|
namespace EffectMaker {
|
||||||
@@ -758,7 +764,7 @@ void EffectMakerModel::updateCustomUniforms()
|
|||||||
// Custom values are not readonly, others inside the effect can be
|
// Custom values are not readonly, others inside the effect can be
|
||||||
QString readOnly = uniform->useCustomValue() ? QString() : QStringLiteral("readonly ");
|
QString readOnly = uniform->useCustomValue() ? QString() : QStringLiteral("readonly ");
|
||||||
previewEffectPropertiesString += " " + readOnly + "property " + type + " "
|
previewEffectPropertiesString += " " + readOnly + "property " + type + " "
|
||||||
+ propertyName + bindedValueString + '\n';
|
+ propertyName + valueString + '\n';
|
||||||
// Define type properties are not added into exports
|
// Define type properties are not added into exports
|
||||||
if (!isDefine) {
|
if (!isDefine) {
|
||||||
if (uniform->useCustomValue()) {
|
if (uniform->useCustomValue()) {
|
||||||
@@ -783,7 +789,9 @@ void EffectMakerModel::updateCustomUniforms()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See if any of the properties changed
|
// See if any of the properties changed
|
||||||
// TODO
|
m_exportedRootPropertiesString = exportedRootPropertiesString;
|
||||||
|
m_previewEffectPropertiesString = previewEffectPropertiesString;
|
||||||
|
m_exportedEffectPropertiesString = exportedEffectPropertiesString;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectMakerModel::bakeShaders()
|
void EffectMakerModel::bakeShaders()
|
||||||
@@ -807,6 +815,7 @@ void EffectMakerModel::bakeShaders()
|
|||||||
QString vs = m_vertexShader;
|
QString vs = m_vertexShader;
|
||||||
m_baker.setSourceString(vs.toUtf8(), QShader::VertexStage);
|
m_baker.setSourceString(vs.toUtf8(), QShader::VertexStage);
|
||||||
QShader vertShader = m_baker.bake();
|
QShader vertShader = m_baker.bake();
|
||||||
|
|
||||||
if (!vertShader.isValid()) {
|
if (!vertShader.isValid()) {
|
||||||
qWarning() << "Shader baking failed:" << qPrintable(m_baker.errorMessage());
|
qWarning() << "Shader baking failed:" << qPrintable(m_baker.errorMessage());
|
||||||
setEffectError(m_baker.errorMessage().split('\n').first(), ErrorVert);
|
setEffectError(m_baker.errorMessage().split('\n').first(), ErrorVert);
|
||||||
@@ -821,6 +830,7 @@ void EffectMakerModel::bakeShaders()
|
|||||||
m_baker.setSourceString(fs.toUtf8(), QShader::FragmentStage);
|
m_baker.setSourceString(fs.toUtf8(), QShader::FragmentStage);
|
||||||
|
|
||||||
QShader fragShader = m_baker.bake();
|
QShader fragShader = m_baker.bake();
|
||||||
|
|
||||||
if (!fragShader.isValid()) {
|
if (!fragShader.isValid()) {
|
||||||
qWarning() << "Shader baking failed:" << qPrintable(m_baker.errorMessage());
|
qWarning() << "Shader baking failed:" << qPrintable(m_baker.errorMessage());
|
||||||
setEffectError(m_baker.errorMessage().split('\n').first(), ErrorFrag);
|
setEffectError(m_baker.errorMessage().split('\n').first(), ErrorFrag);
|
||||||
@@ -908,6 +918,7 @@ QString EffectMakerModel::getQmlComponentString(bool localFiles)
|
|||||||
// When used in preview component, we need property with value
|
// When used in preview component, we need property with value
|
||||||
// and when in exported component, property with binding to root value.
|
// and when in exported component, property with binding to root value.
|
||||||
s += localFiles ? m_exportedEffectPropertiesString : m_previewEffectPropertiesString;
|
s += localFiles ? m_exportedEffectPropertiesString : m_previewEffectPropertiesString;
|
||||||
|
|
||||||
if (!customImagesString.isEmpty())
|
if (!customImagesString.isEmpty())
|
||||||
s += '\n' + customImagesString;
|
s += '\n' + customImagesString;
|
||||||
|
|
||||||
@@ -925,6 +936,21 @@ QString EffectMakerModel::getQmlComponentString(bool localFiles)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Utils::FilePath EffectMakerModel::qsbPath() const
|
||||||
|
{
|
||||||
|
const ProjectExplorer::Target *target = ProjectExplorer::ProjectTree::currentTarget();
|
||||||
|
if (target) {
|
||||||
|
if (QtSupport::QtVersion *qtVer = QtSupport::QtKitAspect::qtVersion(target->kit())) {
|
||||||
|
Utils::FilePath path = qtVer->binPath().pathAppended("qsb").withExecutableSuffix();
|
||||||
|
if (path.exists())
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qWarning() << "Shader baking failed, QSB not found.";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void EffectMakerModel::updateQmlComponent()
|
void EffectMakerModel::updateQmlComponent()
|
||||||
{
|
{
|
||||||
// Clear possible QML runtime errors
|
// Clear possible QML runtime errors
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "shaderfeatures.h"
|
#include "shaderfeatures.h"
|
||||||
|
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
@@ -12,6 +14,10 @@
|
|||||||
|
|
||||||
#include <QtShaderTools/private/qshaderbaker_p.h>
|
#include <QtShaderTools/private/qshaderbaker_p.h>
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
class Process;
|
||||||
|
}
|
||||||
|
|
||||||
namespace EffectMaker {
|
namespace EffectMaker {
|
||||||
|
|
||||||
class CompositionNode;
|
class CompositionNode;
|
||||||
@@ -60,14 +66,17 @@ public:
|
|||||||
|
|
||||||
QString fragmentShader() const;
|
QString fragmentShader() const;
|
||||||
void setFragmentShader(const QString &newFragmentShader);
|
void setFragmentShader(const QString &newFragmentShader);
|
||||||
|
|
||||||
QString vertexShader() const;
|
QString vertexShader() const;
|
||||||
void setVertexShader(const QString &newVertexShader);
|
void setVertexShader(const QString &newVertexShader);
|
||||||
|
|
||||||
const QString &qmlComponentString() const;
|
const QString &qmlComponentString() const;
|
||||||
void setQmlComponentString(const QString &string);
|
|
||||||
|
|
||||||
Q_INVOKABLE void updateQmlComponent();
|
Q_INVOKABLE void updateQmlComponent();
|
||||||
|
|
||||||
|
Q_INVOKABLE void resetEffectError(int type);
|
||||||
|
Q_INVOKABLE void setEffectError(const QString &errorMessage, int type = -1, int lineNumber = -1);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void isEmptyChanged();
|
void isEmptyChanged();
|
||||||
void selectedIndexChanged(int idx);
|
void selectedIndexChanged(int idx);
|
||||||
@@ -102,8 +111,6 @@ private:
|
|||||||
void updateBakedShaderVersions();
|
void updateBakedShaderVersions();
|
||||||
QString detectErrorMessage(const QString &errorMessage);
|
QString detectErrorMessage(const QString &errorMessage);
|
||||||
EffectError effectError() const;
|
EffectError effectError() const;
|
||||||
void setEffectError(const QString &errorMessage, int type = -1, int lineNumber = -1);
|
|
||||||
void resetEffectError(int type);
|
|
||||||
|
|
||||||
QString valueAsString(const Uniform &uniform);
|
QString valueAsString(const Uniform &uniform);
|
||||||
QString valueAsBinding(const Uniform &uniform);
|
QString valueAsBinding(const Uniform &uniform);
|
||||||
@@ -121,6 +128,9 @@ private:
|
|||||||
QString getCustomShaderVaryings(bool outState);
|
QString getCustomShaderVaryings(bool outState);
|
||||||
QString generateVertexShader(bool includeUniforms = true);
|
QString generateVertexShader(bool includeUniforms = true);
|
||||||
QString generateFragmentShader(bool includeUniforms = true);
|
QString generateFragmentShader(bool includeUniforms = true);
|
||||||
|
|
||||||
|
Utils::FilePath qsbPath() const;
|
||||||
|
|
||||||
void updateCustomUniforms();
|
void updateCustomUniforms();
|
||||||
void bakeShaders();
|
void bakeShaders();
|
||||||
|
|
||||||
@@ -140,7 +150,7 @@ private:
|
|||||||
QString m_vertexShader;
|
QString m_vertexShader;
|
||||||
QStringList m_defaultRootVertexShader;
|
QStringList m_defaultRootVertexShader;
|
||||||
QStringList m_defaultRootFragmentShader;
|
QStringList m_defaultRootFragmentShader;
|
||||||
QShaderBaker m_baker;
|
QShaderBaker m_baker; // TODO: Remove
|
||||||
QTemporaryFile m_fragmentShaderFile;
|
QTemporaryFile m_fragmentShaderFile;
|
||||||
QTemporaryFile m_vertexShaderFile;
|
QTemporaryFile m_vertexShaderFile;
|
||||||
// Used in exported QML, at root of the file
|
// Used in exported QML, at root of the file
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include "effectmakermodel.h"
|
#include "effectmakermodel.h"
|
||||||
#include "effectmakernodesmodel.h"
|
#include "effectmakernodesmodel.h"
|
||||||
#include "effectmakerview.h"
|
#include "effectmakerview.h"
|
||||||
|
|
||||||
|
#include "nodeinstanceview.h"
|
||||||
#include "qmldesignerconstants.h"
|
#include "qmldesignerconstants.h"
|
||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
#include "qqmlcontext.h"
|
#include "qqmlcontext.h"
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ Uniform::Uniform(const QJsonObject &propObj)
|
|||||||
// QEN files don't store the current value, so with those use default value
|
// QEN files don't store the current value, so with those use default value
|
||||||
value = defaultValue;
|
value = defaultValue;
|
||||||
}
|
}
|
||||||
|
m_customValue = propObj.value("customValue").toString();
|
||||||
|
m_useCustomValue = getBoolValue(propObj.value("useCustomValue"), false);
|
||||||
|
|
||||||
minValue = propObj.value("minValue").toString();
|
minValue = propObj.value("minValue").toString();
|
||||||
maxValue = propObj.value("maxValue").toString();
|
maxValue = propObj.value("maxValue").toString();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user