1641 if (!renderContext) {
1642 qWarning(
"QQuick3DCustomMaterial: No render context interface?");
1648 bool newBackendNode =
false;
1649 bool shadersMayChange =
false;
1650 if (!customMaterial) {
1652 newBackendNode =
true;
1654 shadersMayChange =
true;
1657 if (newBackendNode || shadersMayChange) {
1660 customMaterial->m_properties.clear();
1661 customMaterial->m_textureProperties.clear();
1666 const int idx =
metaObject()->indexOfSlot(
"onPropertyDirty()");
1668 propertyDirtyMethod =
metaObject()->method(idx);
1671 int propOffset =
metaObject()->propertyOffset();
1675 while (superClass &&
qstrcmp(superClass->
className(),
"QQuick3DCustomMaterial") != 0) {
1680 using TextureInputProperty = QPair<QQuick3DShaderUtilsTextureInput *, const char *>;
1681 QVector<TextureInputProperty> textureProperties;
1689 QMetaType propType =
property.metaType();
1690 QVariant propValue =
property.read(
this);
1692 propType = propValue.metaType();
1695 if (propType.
id() == qMetaTypeId<QQuick3DShaderUtilsTextureInput *>()) {
1699 }
else if (propType ==
QMetaType(QMetaType::QObjectStar)) {
1703 const auto type = uniformType(propType);
1705 uniforms.
append({ uniformTypeName(propType),
name });
1706 customMaterial->m_properties.push_back({
name, propValue, uniformType(propType),
i});
1707 if (newBackendNode) {
1709 if (
property.hasNotifySignal() && propertyDirtyMethod.isValid())
1728 if (newBackendNode) {
1741 customMaterial->m_textureProperties.push_back(textureData);
1744 for (
const auto &textureProperty : std::as_const(textureProperties))
1745 processTextureProperty(*textureProperty.first, textureProperty.second);
1751 QMetaType propType = propValue.metaType();
1753 propType = propValue.metaType();
1756 if (propType.
id() == qMetaTypeId<QQuick3DShaderUtilsTextureInput *>()) {
1760 }
else if (propType.
id() == QMetaType::QObjectStar) {
1764 const auto type = uniformType(propType);
1766 uniforms.
append({ uniformTypeName(propType),
name });
1767 customMaterial->m_properties.push_back({
name, propValue,
1768 uniformType(propType), -1 });
1773 qWarning(
"No known uniform conversion found for custom material property %s. Skipping",
name.constData());
1778 for (
const auto &
property : std::as_const(textureProperties))
1789 QByteArray shaderPathKey(
"custom material --");
1791 customMaterial->m_renderFlags = {};
1793 if (!m_vertexShader.
isEmpty())
1796 if (!m_fragmentShader.
isEmpty())
1819 customMaterial->m_customShaderPresence = {};
1821 if (vertexProcessed[
i].isEmpty() && fragmentProcessed[
i].isEmpty())
1826 customMaterial->m_shaderPathKey[
i] =
key;
1827 if (!vertexProcessed[
i].isEmpty()) {
1831 if (!fragmentProcessed[
i].isEmpty()) {
1838 customMaterial->setAlwaysDirty(m_alwaysDirty);
1839 if (m_srcBlend != BlendMode::NoBlend && m_dstBlend != BlendMode::NoBlend) {
1844 if (m_srcAlphaBlend != BlendMode::NoBlend && m_dstAlphaBlend != BlendMode::NoBlend) {
1848 customMaterial->m_srcAlphaBlend = customMaterial->m_srcBlend;
1849 customMaterial->m_dstAlphaBlend = customMaterial->m_dstBlend;
1854 customMaterial->m_lineWidth = m_lineWidth;
1858 if (m_dirtyAttributes & Dirty::PropertyDirty) {
1859 for (
auto &prop : customMaterial->m_properties) {
1862 prop.value =
p.read(
this);
1866 if (m_dirtyAttributes & Dirty::TextureDirty) {
1870 if (prop.texInput->enabled)
1873 prop.texImage =
nullptr;
1891 prop.texImage =
nullptr;
1894 if (tex != prop.lastConnectedTexture) {
1895 prop.lastConnectedTexture = tex;
1899 disconnect(prop.horizontalTilingChangedConn);
1908 prop.depthTilingChangedConn =
connect(tex, &QQuick3DTexture::depthTilingChanged,
this, &QQuick3DCustomMaterial::onTextureDirty);
1914 m_dirtyAttributes = 0;
1916 return customMaterial;
The QQmlContext class defines a context within a QML engine.
int depth() const
Returns the depth of the texture data in pixels.
TilingMode verticalTiling() const
\qmlproperty enumeration QtQuick3D::Texture::tilingModeVertical
TilingMode horizontalTiling() const
\qmlproperty enumeration QtQuick3D::Texture::tilingModeHorizontal