From 7d598c7345b7713e5188f717df294571090f4264 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 25 Apr 2026 02:10:33 +0200 Subject: [PATCH] docs(shaders_lab): rewrite app.md to track current state across phases Documents phases 1-4e in order: core renderer, annotated uniforms, DAG mode (catalog + compiler + multi-source), multi-window layout, visual node editor (imgui-node-editor), Functions palette, UX deletes, per-node previews. Lists what comes next (persistence, more nodes, custom nodes, crossfade, Claude integration, VJ output protocols). Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/shaders_lab/app.md | 145 +++++++++++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 16 deletions(-) diff --git a/apps/shaders_lab/app.md b/apps/shaders_lab/app.md index 8641eb4b..66a0e4eb 100644 --- a/apps/shaders_lab/app.md +++ b/apps/shaders_lab/app.md @@ -2,44 +2,157 @@ name: shaders_lab lang: cpp domain: gfx -description: "Live GLSL fragment shader editor con preview en tiempo real. Layout de 3 paneles: editor de código, canvas de preview y controles." -tags: [gui, shaders, opengl, glsl, imgui] +description: "Live GLSL fragment shader playground. Editor de codigo + node-editor visual (DAG con multi-source) + Functions palette drag-and-drop, dos canvas paralelos (Code y DAG), thumbnails per-nodo, todo nativo C++17 + ImGui + OpenGL 3.3 + imgui-node-editor." +tags: [gui, shaders, opengl, glsl, imgui, node-editor, dag, vj] uses_functions: + - gl_loader_cpp_gfx - gl_shader_cpp_gfx - gl_framebuffer_cpp_gfx - fullscreen_quad_cpp_gfx - shader_canvas_cpp_gfx + - uniform_parser_cpp_gfx + - uniform_panel_cpp_gfx + - dag_catalog_cpp_gfx + - dag_compile_cpp_gfx + - dag_uniforms_cpp_gfx + - dag_palette_cpp_gfx + - dag_node_editor_cpp_gfx + - dag_node_previews_cpp_gfx - fps_overlay_cpp_core uses_types: [] -framework: "imgui + opengl3" +framework: "imgui + opengl3 + imgui-node-editor" entry_point: "cpp/build/linux/apps/shaders_lab/shaders_lab" dir_path: "cpp/apps/shaders_lab" --- -## Descripción +## Descripcion -Editor interactivo de fragment shaders GLSL con preview en tiempo real. Incluye 3 presets (Plasma, Circle, Checker) y recompila automáticamente con debounce de 250ms al editar el código. +App de live-coding y composicion de fragment shaders GLSL con dos modos coexistentes: editor de codigo libre y editor de DAG visual con catalogo de nodos arrastrables. Pensada para jugar con shaders de tipo VJ y para extraer funciones GLSL al registry global. -## Layout +## Estado actual -- **Code** (izquierda): editor de texto con botones de preset y footer de errores de compilación -- **Canvas** (centro): preview del shader renderizado a FBO y mostrado via ImGui::Image -- **Controls** (derecha): placeholder para fase 2 + FPS overlay +### Fase 1 — Core renderer + editor de codigo `[done]` +- Ventana ImGui + OpenGL 3.3 via `fn::run_app` del framework. +- Editor de texto del fragment shader con recompile auto (debounce 250 ms). +- Render a FBO + `ImGui::Image` para mostrar preview en panel propio. +- Errores de compilacion con linea, footer rojo en el panel Code. +- 3 presets seed: Plasma, Circle, Checker. +- Cross-compile a Windows con loader propio (`gl_loader`) — sin dependencias externas mas alla de GLFW/ImGui ya vendorizados. + +### Fase 2 — Annotated uniforms + auto-controls `[done]` +- Parser de comentarios `// @slider`, `// @color`, `// @toggle`, `// @xy` sobre las declaraciones de uniforms. +- Panel `Controls` con widgets ImGui auto-generados (sliders, color pickers, checkboxes). +- Sincronizacion de valores entre recompilaciones por nombre del uniform. +- Tests inline para `uniform_parser` (6/6 asserts). + +### Fase 3 — DAG mode `[done]` +- Catalogo de 11 nodos: 4 Gen (`solid`, `gradient`, `plasma`, `circle`), 3 Op (`invert`, `gamma`, `hueShift`), 3 Blend (`mix`, `multiply`, `screen`), 1 Output. +- Compilador `compile_dag_to_glsl(pipeline)` que emite un fragment shader unico con `vec4 node_(...)` por nodo y main encadenando outputs. +- Multi-source: hasta 4 inputs por nodo via `source_ids[4]`. Compilador resuelve cada slot. +- Nodo `Output` (sink, rojo, no borrable): su `source_ids[0]` decide que va a `fragColor`. +- Tests inline para `dag_compile` (6/6) y `dag_catalog` (8/8). + +### Fase 4a — Layout multi-ventana + dos canvas `[done]` +- Cada panel es ventana ImGui dockable independiente: `Code`, `DAG Pipeline`, `Canvas Code`, `Canvas DAG`, `Controls`, `Generated GLSL`, `Functions`. +- Dos `ShaderCanvas` simultaneos: el del Code y el del DAG renderizan en paralelo, cada uno con su FBO y programa propio. +- Sin focus-based recompile: cada fuente recompila solo cuando su contenido cambia. + +### Fase 4b — Visual node editor (imgui-node-editor) `[done]` +- Vendorizada `imgui-node-editor` de thedmd en `cpp/vendor/imgui-node-editor/` (parche puntual en `imgui_extra_math.inl` para evitar choque con ImGui 1.92.7). +- Layout 3 columnas por nodo: pines input a la izquierda, controles en el centro, pin output a la derecha. +- Pines como circulos de radio 9 pegados al borde del nodo (mitad fuera, mitad dentro), color uniforme neutro (data type uniforme = `vec4`). +- `ed::PinRect` cubre el circulo entero — la mitad sobresaliente sigue siendo grabbable. +- Cables 2.5px del color del pin. +- Node drag, pan, zoom — todo nativo del editor. +- Topology change disparado solo cuando se anaden/quitan/reconectan nodos. Mover sliders no recompila. + +### Fase 4c — Functions palette drag-drop `[done]` +- Ventana `Functions` con catalogo agrupado en `Generators / Operators / Blends`. +- Cada item es drag source con payload `DAG_NODE_TYPE`. +- Drop sobre el canvas del DAG anade el nodo en la posicion del mouse. +- Sin botones `+ Add Node` / `Clear` — todo flujo via drag-drop. +- Output node nunca aparece en la paleta (sink unico fijo). + +### Fase 4d — UX deletes + cycle check real `[done]` +- **Right-click sobre cable**: borra ese link. +- **Right-click sobre pin output**: limpia el fan-out completo (todos los inputs que apuntaban a este nodo). +- **Right-click sobre pin input**: limpia ese slot. +- **Doble right-click sobre nodo**: borra el nodo (Output protegido). +- Validacion de ciclo via DFS sobre `source_ids` (no por indice del vector); `topo_sort` reordena el pipeline tras cada cambio para mantener `out_` coherentes. +- Drop de nuevo nodo se inserta antes del Output, no al final. + +### Fase 4e — Per-node preview `[done]` +- Toggle `[+] preview` / `[-] preview` en cada nodo no-Output (off por defecto). +- Cada nodo abierto tiene su FBO de 96x64 keyed por `editor_uid`. +- Compilador emite `uniform int u_preview_target` y branches `if (u_preview_target == i) { fragColor = out_i; return; }`. +- `dag_previews_render` itera nodos con preview abierto, dibuja al FBO con ese index. +- Sin recompile al togglear preview ni al mover sliders — un solo programa GL. + +## Lo siguiente que pega + +- Persistencia: `shaders_lab.db` local (SQLite). Guardar/cargar pipelines con nombre. Sync con `registry.db` global por tag (push selectivo de funciones GLSL "buenas" al registry para que aparezcan en `fn search`). +- Mas nodos: warps (twirl, polar, kaleidoscope), ruidos reales (perlin, fbm, worley), SDFs (box, line, smooth_union), filtros de luma (threshold, levels, duotone). +- Nodos custom definidos por el usuario: modal con editor GLSL del body + declaracion de params, persistencia en SQLite, aparicion automatica en la paleta. +- Crossfade A↔B: tercer canvas que mezcla Canvas Code y Canvas DAG con un slider. +- Cliente Claude: chat con tool use (`search_registry`, `apply_shader`, `save_function`). +- Integracion VJ: Spout/Syphon/NDI para mandar el output a Resolume/OBS. ## Build ```bash ./fn run build_cpp_linux_bash_infra shaders_lab +./fn run build_cpp_windows_bash_infra shaders_lab ``` -Binario: `cpp/build/linux/apps/shaders_lab/shaders_lab` +- Linux: `cpp/build/linux/apps/shaders_lab/shaders_lab` +- Windows (cross-compile mingw-w64): `cpp/build/windows/apps/shaders_lab/shaders_lab.exe` — copiado a `apps/shaders_lab/shaders_lab.exe` y al Desktop tras cada build. -## Uniforms disponibles en los shaders +## Tests -- `u_resolution`: vec2 — dimensiones del canvas en pixels -- `u_time`: float — segundos desde inicio de la app (ImGui::GetTime()) -- `u_mouse`: vec2 — posición del mouse relativa al canvas, origen bottom-left +```bash +g++ -std=c++17 -Icpp/functions -DUNIFORM_PARSER_TEST cpp/functions/gfx/uniform_parser.cpp -o /tmp/uniform_parser_test && /tmp/uniform_parser_test +g++ -std=c++17 -Icpp/functions -DDAG_COMPILE_TEST cpp/functions/gfx/dag_compile.cpp cpp/functions/gfx/dag_catalog.cpp -o /tmp/dag_compile_test && /tmp/dag_compile_test +g++ -std=c++17 -Icpp/functions -DDAG_CATALOG_TEST cpp/functions/gfx/dag_catalog.cpp -o /tmp/dag_catalog_test && /tmp/dag_catalog_test +``` -## Notas +Cobertura actual: 6 + 6 + 8 = 20 asserts puros (sin GL/ImGui). La parte UI (`dag_node_editor`, `dag_palette`, `uniform_panel`, `shader_canvas`) no es testeable sin entorno grafico. -No requiere dependencias externas más allá de lo ya vendorizado (GLFW, ImGui, OpenGL). Los fragment shaders se escriben sin `#version`, sin `out vec4 fragColor` ni declaraciones de uniforms — `compile_fragment()` los prepende automáticamente. +## Uniforms del Code mode + +Auto-prependidos por `compile_fragment`: + +```glsl +uniform vec2 u_resolution; +uniform float u_time; +uniform vec2 u_mouse; +out vec4 fragColor; +``` + +El cuerpo del fragment se escribe sin `#version`, sin `out`, sin esos uniforms. Cualquier `uniform` adicional declarado por el usuario con anotacion (`// @slider`, etc.) genera un widget en `Controls`. + +## Uniforms del DAG mode + +Ademas de los anteriores, el shader generado por `compile_dag_to_glsl` declara: + +```glsl +uniform vec4 u_params[16]; // 4 floats por nodo (slot del nodo i en u_params[i]) +uniform int u_preview_target; // -1 = real Output; 0..15 = render out_ +``` + +`dag_uniforms_apply` sube `u_params[16]` cada frame antes del draw del Canvas DAG. `dag_previews_render` rebinde el FBO de cada nodo abierto y setea `u_preview_target` antes de cada draw. + +## Layout sugerido + +Al primer arranque las ventanas se apilan; arrastra por el titulo a los splits del dockspace. ImGui persiste el layout en `imgui.ini` junto al binario. + +Disposicion comoda: +- `Code` y `DAG Pipeline` ocupan la fila superior. +- `Canvas Code` y `Canvas DAG` ocupan la fila inferior, lado a lado. +- `Functions` y `Controls` van a un lateral. +- `Generated GLSL` minimizado o en pestana junto a `Controls`. + +## Notas de cross-compile + +- `gl_loader` resuelve simbolos OpenGL 2.0+ con `wglGetProcAddress` en Windows; en Linux es no-op (`GL_GLEXT_PROTOTYPES`). +- `WIN32_EXECUTABLE TRUE` en `CMakeLists.txt` evita la consola al lanzar el .exe. +- Vendor de imgui-node-editor cuesta ~1MB en el binario final (~18 MB total).