--- name: shaders_lab lang: cpp domain: gfx description: "Live GLSL shader playground con DAG pipeline. Editor de codigo con compilacion en caliente, panel DAG con paleta de generadores/filtros/output, dos canvas (Code y DAG), parseo de uniforms anotados (// @slider, @color, @xy) que se convierten en controles, persistencia de generators en shaders_lab.db, y guardado/carga de layouts ImGui." tags: [imgui, opengl, glsl, shaders, dag, live-coding, playground, sqlite] uses_functions: # gfx - 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_panel_cpp_gfx - dag_node_editor_cpp_gfx - dag_palette_cpp_gfx - dag_node_previews_cpp_gfx - shaderlab_db_cpp_gfx - code_to_generator_cpp_gfx # core (modal Save-as-generator) - modal_dialog_cpp_core - text_input_cpp_core - button_cpp_core uses_types: - dag_types_cpp_gfx framework: "imgui" entry_point: "main.cpp" dir_path: "cpp/apps/shaders_lab" repo_url: "" --- ## Arquitectura App ImGui de live-coding GLSL con dos modos en paralelo: 1. **Code panel** — editor de fragment shader libre. Las anotaciones en uniforms (`// @slider`, `// @color`, `// @xy`, `// @toggle`) se parsean y convierten en controles del panel **Controls** que escriben en un `UniformStore` aplicado al programa cada frame. 2. **DAG panel** — pipeline node-based con catalogo de generadores (plasma, voronoi, etc.) y filtros (blur, threshold, etc.) que se compilan a un fragment shader unificado y se renderizan en **Canvas DAG**. Al guardar un Code shader como "generator" se traduce a un `DagNodeDef` y se persiste en `shaders_lab.db` (tabla via `shaderlab_db`), apareciendo en la paleta del DAG junto a los builtins. ## Capas | Archivo | Responsabilidad | |---|---| | `main.cpp` | UI shell, paneles, modal save-as, layouts, AppConfig | | `compiler.cpp` | `compile_code()`, `compile_dag()`, `mark_code_dirty()` con debounce 250ms | `main.cpp` mantiene estado global de sesion (g_source, g_pipeline, g_descs, g_store, g_layouts...) — ImGui retained-mode obliga a que persista entre frames. Toda la logica pura de compilacion vive en `compiler.cpp` y en las funciones `dag_compile`, `code_to_generator`, `uniform_parser` del registry. ## Persistencia - **`shaders_lab.db`** (junto al .exe) — tabla de generators de usuario via `shaderlab_db_*`, ademas de `imgui_layouts` (creada por `layout_storage`). - `imgui.ini` y `app_settings.ini` — gestionados por `fn::run_app` en `/local_files/`. ## Paneles | Panel | Atajo | Que muestra | |---|---|---| | Code | Ctrl+1 | Editor del fragment shader + boton "Save as generator" | | DAG Pipeline | Ctrl+2 | Node editor con la pipeline | | Canvas Code | Ctrl+3 | Render del Code shader | | Canvas DAG | Ctrl+4 | Render del shader compilado del DAG | | Controls | Ctrl+5 | Sliders/color pickers de uniforms anotados | | Functions | Ctrl+6 | Paleta del DAG (generators + filters + output) | | Generated GLSL | Ctrl+7 | GLSL final del DAG con uniforms baked como const array | ## Build ```bash # Linux cd cpp && cmake -B build/linux -S . && cmake --build build/linux --target shaders_lab # Windows (cross-compile) cd cpp && cmake -B build/windows -S . -DCMAKE_TOOLCHAIN_FILE=toolchains/mingw-w64.cmake \ && cmake --build build/windows --target shaders_lab ``` ## Decisiones - `init_gl_loader = true` (via `fn::run_app` por default cuando se enlaza con OpenGL) — `shader_canvas`, `gl_shader`, `gl_framebuffer` llaman gl*. - `viewports = true` — los Canvas se pueden arrastrar fuera del main. - DAG default: arranca con un nodo "plasma" + "output" si la paleta los encuentra; persiste el INI con `layout_storage`. - El boton "Save as generator" valida snake_case, evita colisionar con builtins, traduce con `code_to_generator`, persiste con `shaderlab_db_save_generator`, y registra el nodo nuevo en el catalogo en vivo (`dag_register_node`).