feat(shaders_lab): Output node + Functions palette with drag-drop

- DagKind::Output (new enum): terminal sink; compiler wires fragColor to its source_ids[0]
- dag_catalog: "output" node (1 input, red)
- dag_compile: skips Output in node_<i> emission; final fragColor resolves from Output's connection
- dag_node_editor: no more Add button; drops "DAG_NODE_TYPE" payloads at mouse canvas position; Output cannot be deleted; Output has no output pin
- dag_palette (new fn): Functions window with grouped, draggable node cards
- main.cpp: "Functions" window added; ensure_dag_default seeds plasma + connected Output
This commit is contained in:
2026-04-24 22:16:47 +02:00
parent e91e80bfcf
commit 0be4b29a4b
10 changed files with 253 additions and 106 deletions
+32 -7
View File
@@ -10,6 +10,7 @@
#include "gfx/dag_uniforms.h"
#include "gfx/dag_panel.h"
#include "gfx/dag_node_editor.h"
#include "gfx/dag_palette.h"
#include "core/fps_overlay.h"
#include "seed_shaders.h"
@@ -73,14 +74,32 @@ static void load_preset(const char* src) {
}
static void ensure_dag_default() {
// Seed with a Plasma connected to an Output node.
if (g_pipeline.empty()) {
const fn::gfx::DagNodeDef* def = fn::gfx::dag_find("plasma");
if (def) {
fn::gfx::DagStep step;
step.id = "n_default";
step.name = def->name;
step.params = def->param_defaults;
g_pipeline.push_back(step);
const fn::gfx::DagNodeDef* plasma = fn::gfx::dag_find("plasma");
if (plasma) {
fn::gfx::DagStep s;
s.id = "n_plasma";
s.name = plasma->name;
s.params = plasma->param_defaults;
g_pipeline.push_back(s);
}
}
// Ensure there is always an Output node at the end.
bool has_output = false;
for (const auto& s : g_pipeline) {
const fn::gfx::DagNodeDef* d = fn::gfx::dag_find(s.name);
if (d && d->kind == fn::gfx::DagKind::Output) { has_output = true; break; }
}
if (!has_output) {
const fn::gfx::DagNodeDef* out = fn::gfx::dag_find("output");
if (out) {
fn::gfx::DagStep s;
s.id = "n_output";
s.name = out->name;
s.editor_pos_x = 500.0f;
if (!g_pipeline.empty()) s.source_ids[0] = g_pipeline.front().id;
g_pipeline.push_back(s);
}
}
}
@@ -181,6 +200,12 @@ static void render() {
}
ImGui::End();
// --- Functions palette (drag into DAG Pipeline) ---
if (ImGui::Begin("Functions")) {
fn::gfx::dag_palette();
}
ImGui::End();
// --- Generated GLSL window (DAG compiled output, read-only) ---
if (ImGui::Begin("Generated GLSL")) {
if (g_dag_glsl.empty()) {