QQuickShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickShaderEffectNode *rootNode) { if (!rootNode) rootNode = buildCustomNodes(); if (!rootNode) return 0; if (m_dirtyProgram) { const bool isES = QOpenGLContext::currentContext()->isOpenGLES(); QQuickShaderEffectMaterial *material = static_cast<QQuickShaderEffectMaterial *>(rootNode->material()); Q_ASSERT(material); Key s = m_common.source; QSGShaderSourceBuilder builder; if (s.sourceCode[Key::FragmentShader].isEmpty()) { builder.appendSourceFile(QStringLiteral(":/particles/shaders/customparticle.frag")); if (isES) builder.removeVersion(); s.sourceCode[Key::FragmentShader] = builder.source(); builder.clear(); } builder.appendSourceFile(QStringLiteral(":/particles/shaders/customparticletemplate.vert")); if (isES) builder.removeVersion(); if (s.sourceCode[Key::VertexShader].isEmpty()) builder.appendSourceFile(QStringLiteral(":/particles/shaders/customparticle.vert")); s.sourceCode[Key::VertexShader] = builder.source() + s.sourceCode[Key::VertexShader]; s.className = metaObject()->className(); material->setProgramSource(s); material->attributes = m_common.attributes; foreach (QQuickShaderEffectNode* node, m_nodes) node->markDirty(QSGNode::DirtyMaterial); m_dirtyProgram = false; m_dirtyUniforms = true; } m_lastTime = m_system->systemSync(this) / 1000.; if (true) //Currently this is how we update timestamp... potentially over expensive. buildData(rootNode); return rootNode; }
void QSGShaderSourceBuilder::initializeProgramFromFiles(QOpenGLShaderProgram *program, const QString &vertexShader, const QString &fragmentShader) { Q_ASSERT(program); program->removeAllShaders(); QSGShaderSourceBuilder builder; builder.appendSourceFile(vertexShader); program->addShaderFromSourceCode(QOpenGLShader::Vertex, builder.source()); builder.clear(); builder.appendSourceFile(fragmentShader); program->addShaderFromSourceCode(QOpenGLShader::Fragment, builder.source()); }