#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { template void RegisterShaderNode(ShaderGraph& graph, std::shared_ptr registry, QString category = QString()) { auto creator = [&] { return std::make_unique(graph); }; registry->registerModel(category, std::move(creator)); } } ShaderGraph::ShaderGraph() : m_flowScene(BuildRegistry()) { auto& node1 = m_flowScene.createNode(std::make_unique(*this)); node1.nodeGraphicsObject().setPos(200, 200); auto& node2 = m_flowScene.createNode(std::make_unique(*this)); node2.nodeGraphicsObject().setPos(500, 300); m_flowScene.createConnection(node2, 0, node1, 0); m_previewModel = std::make_unique(); } ShaderGraph::~ShaderGraph() { m_flowScene.clearScene(); } std::size_t ShaderGraph::AddInput(std::string name, InputType type, InputRole role, std::size_t roleIndex) { std::size_t index = m_inputs.size(); auto& inputEntry = m_inputs.emplace_back(); inputEntry.name = std::move(name); inputEntry.role = role; inputEntry.roleIndex = roleIndex; inputEntry.type = type; OnInputListUpdate(this); return index; } std::size_t ShaderGraph::AddTexture(std::string name, TextureType type) { std::size_t index = m_textures.size(); auto& textureEntry = m_textures.emplace_back(); textureEntry.name = std::move(name); textureEntry.type = type; OnTextureListUpdate(this); return index; } Nz::ShaderAst::StatementPtr ShaderGraph::ToAst() { std::vector statements; std::function HandleNode; HandleNode = [&](QtNodes::Node* node) -> Nz::ShaderAst::ExpressionPtr { ShaderNode* shaderNode = static_cast(node->nodeDataModel()); qDebug() << shaderNode->name(); std::size_t inputCount = shaderNode->nPorts(QtNodes::PortType::In); Nz::StackArray expressions = NazaraStackArray(Nz::ShaderAst::ExpressionPtr, inputCount); std::size_t i = 0; for (const auto& connectionSet : node->nodeState().getEntries(QtNodes::PortType::In)) { for (const auto& [uuid, conn] : connectionSet) { assert(i < expressions.size()); expressions[i] = HandleNode(conn->getNode(QtNodes::PortType::Out)); i++; } } return shaderNode->GetExpression(expressions.data(), expressions.size()); }; m_flowScene.iterateOverNodes([&](QtNodes::Node* node) { if (node->nodeDataModel()->nPorts(QtNodes::PortType::Out) == 0) { statements.emplace_back(Nz::ShaderBuilder::ExprStatement(HandleNode(node))); } }); return std::make_shared(std::move(statements)); } void ShaderGraph::UpdateInput(std::size_t inputIndex, std::string name, InputType type, InputRole role, std::size_t roleIndex) { assert(inputIndex < m_inputs.size()); auto& inputEntry = m_inputs[inputIndex]; inputEntry.name = std::move(name); inputEntry.role = role; inputEntry.roleIndex = roleIndex; inputEntry.type = type; OnInputUpdate(this, inputIndex); } void ShaderGraph::UpdateTexturePreview(std::size_t textureIndex, QImage preview) { assert(textureIndex < m_textures.size()); auto& textureEntry = m_textures[textureIndex]; textureEntry.preview = std::move(preview); textureEntry.preview.convertTo(QImage::Format_RGBA8888); OnTexturePreviewUpdate(this, textureIndex); } std::shared_ptr ShaderGraph::BuildRegistry() { auto registry = std::make_shared(); RegisterShaderNode(*this, registry, "Casts"); RegisterShaderNode(*this, registry, "Casts"); RegisterShaderNode(*this, registry, "Casts"); RegisterShaderNode(*this, registry, "Casts"); RegisterShaderNode(*this, registry, "Casts"); RegisterShaderNode(*this, registry, "Casts"); RegisterShaderNode(*this, registry, "Outputs"); RegisterShaderNode(*this, registry, "Inputs"); RegisterShaderNode(*this, registry, "Texture"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Vector operations"); RegisterShaderNode(*this, registry, "Constants"); RegisterShaderNode(*this, registry, "Constants"); RegisterShaderNode(*this, registry, "Constants"); return registry; }