void QQuickShaderEffectCommon::updateShader(QQuickItem *item, Key::ShaderType shaderType) { disconnectPropertySignals(item, shaderType); qDeleteAll(signalMappers[shaderType]); uniformData[shaderType].clear(); signalMappers[shaderType].clear(); if (shaderType == Key::VertexShader) attributes.clear(); const QByteArray &code = source.sourceCode[shaderType]; if (code.isEmpty()) { // Optimize for default code. if (shaderType == Key::VertexShader) { attributes.append(QByteArray(qt_position_attribute_name)); attributes.append(QByteArray(qt_texcoord_attribute_name)); UniformData d; d.name = "qt_Matrix"; d.specialType = UniformData::Matrix; uniformData[Key::VertexShader].append(d); signalMappers[Key::VertexShader].append(0); } else if (shaderType == Key::FragmentShader) { UniformData d; d.name = "qt_Opacity"; d.specialType = UniformData::Opacity; uniformData[Key::FragmentShader].append(d); signalMappers[Key::FragmentShader].append(0); QSignalMapper *mapper = new QSignalMapper; mapper->setMapping(item, 1 | (Key::FragmentShader << 16)); const char *sourceName = "source"; d.name = sourceName; d.value = item->property(sourceName); d.specialType = UniformData::Sampler; uniformData[Key::FragmentShader].append(d); signalMappers[Key::FragmentShader].append(mapper); } } else { lookThroughShaderCode(item, shaderType, code); } connectPropertySignals(item, shaderType); }
void QQuickOpenGLShaderEffectCommon::updateShader(QQuickItem *item, const QMetaObject *itemMetaObject, Key::ShaderType shaderType) { disconnectPropertySignals(item, shaderType); uniformData[shaderType].clear(); clearSignalMappers(shaderType); if (shaderType == Key::VertexShader) attributes.clear(); // A qrc or file URL means the shader source is to be read from the specified file. QUrl srcUrl(QString::fromUtf8(source.sourceCode[shaderType])); if (!srcUrl.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) || srcUrl.isLocalFile()) { if (!fileSelector) { fileSelector = new QFileSelector(item); // There may not be an OpenGL context accessible here. So rely on // the window's requestedFormat(). if (item->window() && item->window()->requestedFormat().profile() == QSurfaceFormat::CoreProfile) { fileSelector->setExtraSelectors(QStringList() << QStringLiteral("glslcore")); } } const QString fn = fileSelector->select(QQmlFile::urlToLocalFileOrQrc(srcUrl)); QFile f(fn); if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { source.sourceCode[shaderType] = f.readAll(); f.close(); } else { qWarning("ShaderEffect: Failed to read %s", qPrintable(fn)); source.sourceCode[shaderType] = QByteArray(); } } const QByteArray &code = source.sourceCode[shaderType]; if (code.isEmpty()) { // Optimize for default code. if (shaderType == Key::VertexShader) { attributes.append(QByteArray(qtPositionAttributeName())); attributes.append(QByteArray(qtTexCoordAttributeName())); UniformData d; d.name = "qt_Matrix"; d.specialType = UniformData::Matrix; uniformData[Key::VertexShader].append(d); signalMappers[Key::VertexShader].append(0); } else if (shaderType == Key::FragmentShader) { UniformData d; d.name = "qt_Opacity"; d.specialType = UniformData::Opacity; uniformData[Key::FragmentShader].append(d); signalMappers[Key::FragmentShader].append(0); const int mappedId = 1 | (Key::FragmentShader << 16); auto mapper = new QtPrivate::MappedSlotObject([this, mappedId](){mappedPropertyChanged(mappedId);}); const char *sourceName = "source"; d.name = sourceName; d.setValueFromProperty(item, itemMetaObject); d.specialType = UniformData::Sampler; uniformData[Key::FragmentShader].append(d); signalMappers[Key::FragmentShader].append(mapper); } } else { lookThroughShaderCode(item, itemMetaObject, shaderType, code); } connectPropertySignals(item, itemMetaObject, shaderType); }