Files
fn_registry/apps/shaders_lab/app.md
T
egutierrez 7d598c7345 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) <noreply@anthropic.com>
2026-04-25 02:10:33 +02:00

8.5 KiB

name, lang, domain, description, tags, uses_functions, uses_types, framework, entry_point, dir_path
name lang domain description tags uses_functions uses_types framework entry_point dir_path
shaders_lab cpp gfx 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.
gui
shaders
opengl
glsl
imgui
node-editor
dag
vj
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
imgui + opengl3 + imgui-node-editor cpp/build/linux/apps/shaders_lab/shaders_lab cpp/apps/shaders_lab

Descripcion

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.

Estado actual

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_<i>(...) 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_<i> 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

./fn run build_cpp_linux_bash_infra shaders_lab
./fn run build_cpp_windows_bash_infra 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.

Tests

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

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.

Uniforms del Code mode

Auto-prependidos por compile_fragment:

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:

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_<i>

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).