6#include <ssg/qssgrendercontextcore.h>
7#include <QtQuick3DRuntimeRender/private/qssgrendereffect_p.h>
8#include <QtQuick3DRuntimeRender/private/qssgshadermaterialadapter_p.h>
9#include <QtQuick3DUtils/private/qssgutils_p.h>
10#include <QtQuick/qquickwindow.h>
11#include <QtQuick3D/private/qquick3dobject_p.h>
12#include <QtQuick3D/private/qquick3dscenemanager_p.h>
13#include <QtCore/qfile.h>
14#include <QtCore/qurl.h>
579 return QQmlListProperty<QQuick3DShaderUtilsRenderPass>(
this,
599 "#if QSHADER_VIEW_COUNT >= 2\n"
600 " FRAGCOLOR = texture(INPUT, vec3(INPUT_UV, VIEW_INDEX));\n"
602 " FRAGCOLOR = texture(INPUT, INPUT_UV);\n"
608 static const char *argKey =
"/*%QT_ARGS_MAIN%*/";
609 const int argKeyLen = int(strlen(argKey));
610 const int argKeyPos = snippet.indexOf(argKey);
612 snippet = snippet.left(argKeyPos) +
QByteArrayLiteral(
"inout vec3 VERTEX") + snippet.mid(argKeyPos + argKeyLen);
620 if (!renderContext) {
621 qWarning(
"QQuick3DEffect: No render context interface?");
626 bool newBackendNode =
false;
629 newBackendNode =
true;
632 bool shadersMayChange =
false;
633 if (m_dirtyAttributes & Dirty::EffectChainDirty)
634 shadersMayChange =
true;
636 const bool fullUpdate = newBackendNode || effectNode->
incompleteBuildTimeObject || (m_dirtyAttributes & Dirty::TextureDirty);
638 if (fullUpdate || shadersMayChange) {
642 effectNode->properties.clear();
643 effectNode->textureProperties.clear();
646 const int idx =
metaObject()->indexOfSlot(
"onPropertyDirty()");
648 propertyDirtyMethod =
metaObject()->method(idx);
653 int propOffset =
metaObject()->propertyOffset();
657 while (superClass &&
qstrcmp(superClass->
className(),
"QQuick3DEffect") != 0) {
662 using TextureInputProperty = QPair<QQuick3DShaderUtilsTextureInput *, const char *>;
664 QVector<TextureInputProperty> textureProperties;
671 QMetaType propType =
property.metaType();
672 QVariant propValue =
property.read(
this);
674 propType = propValue.metaType();
677 if (propType.
id() == qMetaTypeId<QQuick3DShaderUtilsTextureInput *>()) {
681 }
else if (propType ==
QMetaType(QMetaType::QObjectStar)) {
685 const auto type = uniformType(propType);
687 uniforms.
append({ uniformTypeName(propType),
name });
688 effectNode->properties.push_back({
name, uniformTypeName(propType),
689 propValue, uniformType(propType),
i});
692 if (
property.hasNotifySignal() && propertyDirtyMethod.isValid())
742 effectNode->textureProperties.push_back(texProp);
746 for (
const auto &
property : std::as_const(textureProperties))
749 if (effectNode->incompleteBuildTimeObject) {
753 QMetaType propType = propValue.metaType();
755 propType = propValue.metaType();
758 if (propType.
id() == qMetaTypeId<QQuick3DShaderUtilsTextureInput *>()) {
762 }
else if (propType.
id() == QMetaType::QObjectStar) {
766 const auto type = uniformType(propType);
768 uniforms.append({ uniformTypeName(propType),
name });
769 effectNode->properties.push_back({
name, uniformTypeName(propType),
770 propValue, uniformType(propType), -1 });
775 qWarning(
"No known uniform conversion found for effect property %s. Skipping",
name.constData());
780 for (
const auto &
property : std::as_const(textureProperties))
785 uniforms.append({
"mat4",
"qt_modelViewProjection" });
786 uniforms.append({
"vec2",
"qt_inputSize" });
787 uniforms.append({
"vec2",
"qt_outputSize" });
788 uniforms.append({
"float",
"qt_frame_num" });
789 uniforms.append({
"float",
"qt_fps" });
790 uniforms.append({
"vec2",
"qt_cameraProperties" });
791 uniforms.append({
"float",
"qt_normalAdjustViewportFactor" });
792 uniforms.append({
"float",
"qt_nearClipValue" });
798 builtinVertexInputs.
append({
"vec3",
"attr_pos" });
799 builtinVertexInputs.append({
"vec2",
"attr_uv" });
802 builtinVertexOutputs.
append({
"vec2",
"qt_inputUV" });
803 builtinVertexOutputs.append({
"vec2",
"qt_textureUV" });
804 builtinVertexOutputs.append({
"flat uint",
"qt_viewIndex" });
808 if (!m_passes.isEmpty()) {
810 effectNode->resetCommands();
818 QByteArray shaderPathKey(
"effect pipeline--");
823 if (
s->stage == stage) {
857 if (!shaderPathKey.isEmpty())
858 shaderPathKey.append(
'>');
859 shaderPathKey +=
"DEFAULT";
871 uniforms, builtinVertexInputs, builtinVertexOutputs,
false);
876 uniforms, builtinVertexInputs, builtinVertexOutputs,
true);
882 uniforms, builtinVertexOutputs, {},
false);
887 uniforms, builtinVertexOutputs, {},
true);
892 effectNode->requiresDepthTexture =
true;
907 effectNode->commands.push_back({
nullptr,
true });
912 effectNode->shaderPrepData.passes.
append(passData);
913 effectNode->shaderPrepData.valid =
true;
921 if (outBufferName.isEmpty()) {
924 effectNode->commands.push_back({
new QSSGBindTarget(outputFormat),
true });
925 effectNode->outputFormat = outputFormat;
928 effectNode->commands.push_back({ outputBuffer->
getCommand(),
false });
930 effectNode->commands.push_back({
new QSSGBindBuffer(outBufferName),
true });
939 const auto &extraCommands = pass->m_commands;
940 for (
const auto &command : extraCommands) {
941 const int bufferCount = command->bufferCount();
942 for (
int i = 0;
i != bufferCount; ++
i)
943 effectNode->commands.push_back({ command->bufferAt(
i)->getCommand(),
false });
944 effectNode->commands.push_back({ command->getCommand(),
false });
947 effectNode->commands.push_back({
new QSSGRender,
true });
952 if (m_dirtyAttributes & Dirty::PropertyDirty) {
953 for (
const auto &prop :
std::as_const(effectNode->
properties)) {
956 prop.value =
p.read(
this);
960 m_dirtyAttributes = 0;
967void QQuick3DEffect::onPropertyDirty()
969 markDirty(Dirty::PropertyDirty);
972void QQuick3DEffect::onTextureDirty()
974 markDirty(Dirty::TextureDirty);
977void QQuick3DEffect::onPassDirty()
979 markDirty(Dirty::EffectChainDirty);
984 markDirty(Dirty::EffectChainDirty);
987void QQuick3DEffect::markDirty(QQuick3DEffect::Dirty
type)
998 for (
const auto &
it :
std::as_const(m_dynamicTextureMaps)) {
999 if (
auto tex =
it->texture())
1003 for (
const auto &
it :
std::as_const(m_dynamicTextureMaps)) {
1004 if (
auto tex =
it->texture())
1012 if (change == QQuick3DObject::ItemSceneChange)
1013 updateSceneManager(
value.sceneManager);
1022 that->m_passes.push_back(pass);
1025 that->effectChainDirty();
1031 return that->m_passes.at(
index);
1037 return that->m_passes.size();
1045 pass->disconnect(that);
1047 that->m_passes.clear();
1048 that->effectChainDirty();
1055 auto it = m_dynamicTextureMaps.
constFind(textureMap);
1060 auto it = m_dynamicTextureMaps.
constFind(textureMap);
1062 m_dynamicTextureMaps.
erase(
it);
1064 m_dynamicTextureMaps.
insert(textureMap);
void push_back(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray first(qsizetype n) const &
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
QList< QByteArray > dynamicPropertyNames() const
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
The QQmlContext class defines a context within a QML engine.
QQmlListProperty< QQuick3DShaderUtilsRenderPass > passes
static void qmlPassClear(QQmlListProperty< QQuick3DShaderUtilsRenderPass > *list)
static qsizetype qmlPassCount(QQmlListProperty< QQuick3DShaderUtilsRenderPass > *list)
QQuick3DEffect(QQuick3DObject *parent=nullptr)
\qmlproperty list Effect::passes Contains a list of render \l {Pass}{passes} implemented by the effec...
void itemChange(QQuick3DObject::ItemChange, const QQuick3DObject::ItemChangeData &) override
static void qmlAppendPass(QQmlListProperty< QQuick3DShaderUtilsRenderPass > *list, QQuick3DShaderUtilsRenderPass *pass)
QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node) override
static QQuick3DShaderUtilsRenderPass * qmlPassAt(QQmlListProperty< QQuick3DShaderUtilsRenderPass > *list, qsizetype index)
void refSceneManager(QQuick3DSceneManager &)
static QQuick3DObjectPrivate * get(QQuick3DObject *item)
\qmltype Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DObject \inherits QtObject
virtual void markAllDirty()
static QSSGRenderTextureFormat::Format mapTextureFormat(QQuick3DShaderUtilsBuffer::TextureFormat fmt)
QSSGCommand * getCommand()
int depth() const
Returns the depth of the texture data in pixels.
QQuick3DTextureData * textureData
QSSGRenderImage * getRenderImage()
TilingMode verticalTiling() const
\qmlproperty enumeration QtQuick3D::Texture::tilingModeVertical
TilingMode horizontalTiling() const
\qmlproperty enumeration QtQuick3D::Texture::tilingModeHorizontal
const_iterator constEnd() const noexcept
iterator erase(const_iterator i)
const_iterator constFind(const T &value) const
iterator insert(const T &value)
QSet< QString >::iterator it
void ensureDebugObjectName(T *node, QObject *src)
\qmltype Shader \inherits Object \inqmlmodule QtQuick3D
QByteArray resolveShader(const QUrl &fileUrl, const QQmlContext *context, QByteArray &shaderPathKey)
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
static const QCssKnownValue properties[NumProperties - 1]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint GLsizei propCount
QQmlContext * qmlContext(const QObject *obj)
static const char * default_effect_fragment_shader
static void insertVertexMainArgs(QByteArray &snippet)
static const char * default_effect_vertex_shader
obj metaObject() -> className()
@ MultiViewShaderPathKeyIndex
@ RegularShaderPathKeyIndex
QByteArray shaderPathKeyPrefix
QSSGCustomShaderMetaData vertexMetaData[2]
QByteArray vertexShaderCode[2]
QSSGCustomShaderMetaData fragmentMetaData[2]
QByteArray fragmentShaderCode[2]
bool incompleteBuildTimeObject
static ShaderCodeAndMetaData prepareCustomShader(QByteArray &dst, const QByteArray &shaderCode, QSSGShaderCache::ShaderType type, const StringPairList &baseUniforms, const StringPairList &baseInputs=StringPairList(), const StringPairList &baseOutputs=StringPairList(), bool multiViewCompatible=false)
QPair< QByteArray, QSSGCustomShaderMetaData > ShaderCodeAndMetaData