Wave 1 de parallel-fix-issues integrada a master: - 0025: text_editor_cpp_core + file_watcher_cpp_core - 0026: gl_texture_load_cpp_gfx (vendor: stb_image v2.30) Ademas se commitea WIP previo de master que estaba sin commitear (cambios en shaders_lab, dag_*, framework, tokens, kpi_card, gl_loader.md, etc.) para dejar HEAD buildable. Notas: - Algunos deps del gallery (button.cpp, toolbar.cpp, modal_dialog.cpp...) siguen UNTRACKED — gating con FN_BUILD_GALLERY=ON (default OFF) para que master build (sin flag) no los necesite. - Build OK con y sin flag. fn index registra 904 functions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
23 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. |
|
|
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_appdel framework. - Editor de texto del fragment shader con recompile auto (debounce 250 ms).
- Render a FBO +
ImGui::Imagepara 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,// @xysobre las declaraciones de uniforms. - Panel
Controlscon 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 convec4 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): susource_ids[0]decide que va afragColor. - Tests inline para
dag_compile(6/6) ydag_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
ShaderCanvassimultaneos: 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-editorde thedmd encpp/vendor/imgui-node-editor/(parche puntual enimgui_extra_math.inlpara 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::PinRectcubre 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
Functionscon catalogo agrupado enGenerators / 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_sortreordena el pipeline tras cada cambio para mantenerout_<i>coherentes. - Drop de nuevo nodo se inserta antes del Output, no al final.
Fase 4e — Per-node preview [done]
- Toggle
[+] preview/[-] previewen 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_targety branchesif (u_preview_target == i) { fragColor = out_i; return; }. dag_previews_renderitera nodos con preview abierto, dibuja al FBO con ese index.- Sin recompile al togglear preview ni al mover sliders — un solo programa GL.
Fase 5 — SQLite + custom generators desde el Code [done]
u_paramsa tamaño dinámico: array globalvec4 u_params[64](256 floats), cada nodo ocupaceil(param_count/4)vec4s consecutivos.dag_param_layout(pipeline)calcula el indice base por nodo; compilador ydag_uniforms_applylo comparten.DagStep::paramsyDagNodeDef::param_*pasan avector<>.- Nuevos Gen nodes (8):
checker,stripes,dots,rings,polar_rays,noise_value,voronoi,truchet. Catalogo total: 19 nodos (4 originales + 8 nuevos Gen + 4 Op + 3 Blend + Output). - Bug fix
solid: el control Color conImGuiColorEditFlags_NoLabelno mostraba el nombre. Ahoradag_node_editorimprimeTextUnformatted(label) + SameLineantes del swatch. - Persistencia
shaders_lab.db(SQLite local enapps/shaders_lab/shaders_lab.db): tablageneratorsconid, label, description, source_glsl, body_glsl, param_count, param_defaults, param_names, controls, tags, timestamps. Funcionshaderlab_db(CRUD) testeada (7/7) y reutilizable. - Catalogo mutable:
dag_register_node()/dag_unregister_node(). Built-ins protegidos via flagis_builtin. - Code → Generator: funcion pura
code_to_generator(source)traduce el GLSL del Code en un body de Gen + DagControl[] (testeada 7/7). Cada uniform anotado se convierte en su control (slider/xy/color); cada uniform reclama 1 vec4 entero. El body se transforma asi: lineasvec2 uv = ...eliminadas,fragColor = X;->return X;, locales<type> <name> = u_params[__BASE__+i].swizzle;prependidas. La lambdabody_glslsubstituye__BASE__con el indice runtime. - UI: boton
Save as generator...en el panelCodecon modal (name snake_case + label + description + tags). Tras guardar, el nodo aparece en la paletaFunctions. Al arrancar,load_user_generators_into_catalog()re-traduce y registra los persistidos. - Quitados: botones de presets
Plasma / Circle / Checkery el archivoseed_shaders.h. Default del Code = un placeholder con uniforms anotados como ejemplo.
Fase 6 — Menubar reusable (View + Layouts) [done]
App estrena una BeginMainMenuBar con dos menus, cableada via app_menubar_cpp_core:
-
View (
panel_menu_cpp_core): MenuItem checkable por cada uno de los 7 paneles (Code,DAG Pipeline,Canvas Code,Canvas DAG,Controls,Functions,Generated GLSL). Cada boolg_show_*se comparte con elbool*deImGui::Begin(name, &g_show_X), asi que la X de cada ventana sincroniza con el menu. CadaBegin/Endenvuelto en guard para no llamarEndsi el panel esta oculto. -
Layouts (
layouts_menu_cpp_core): captura del layout actual de ImGui (SaveIniSettingsToMemory) bajo un nombre, persistido en la tablaui_layouts(name, blob, created_at, updated_at)deshaders_lab.db. Items:- Lista de layouts guardados (click → apply, marker
*en el activo). Save current as...(popup con InputText).Delete(submenu listando los layouts).Reset to default(abre todos los paneles, limpia marker activo).
- Lista de layouts guardados (click → apply, marker
Detalles tecnicos:
LoadIniSettingsFromMemoryse difiere al inicio del frame siguiente viag_pending_layout_blob(no se puede llamar mid-frame entreNewFrameyRender).shaders_lab.dbse reutiliza paraui_layoutsvia nuevo gettershaderlab_db_handle()— una sola conexion SQLite para generators y layouts.- Las callbacks (
list/on_apply/on_save/on_delete/on_reset) se cablean enmain()con lambdas que envuelven las primitivas CRUD delayout_storage_sqlite_cpp_core.
Como usarlo en otras apps
Patron reusable de tres pasos:
#include "core/app_menubar.h"
#include "core/layout_storage_sqlite.h"
// 1. Declarar bools de visibilidad por panel
static bool g_show_foo = true;
static bool g_show_bar = true;
// 2. Declarar callbacks y blob diferido
static fn_ui::LayoutCallbacks g_layout_cb;
static std::string g_pending_blob;
static std::string g_pending_name;
// 3. En main(), cablear callbacks contra tu sqlite3*
fn_ui::layout_storage_init(db);
g_layout_cb.list = [db]{ return fn_ui::layout_storage_list(db); };
g_layout_cb.on_apply = [db](const std::string& n) {
g_pending_blob = fn_ui::layout_storage_load_blob(db, n);
g_pending_name = n;
};
g_layout_cb.on_save = [db](const std::string& n) {
size_t sz = 0;
const char* b = ImGui::SaveIniSettingsToMemory(&sz);
if (b && sz) fn_ui::layout_storage_save(db, n, std::string(b, sz));
g_layout_cb.active_name = n;
};
g_layout_cb.on_delete = [db](const std::string& n) {
fn_ui::layout_storage_delete(db, n);
if (g_layout_cb.active_name == n) g_layout_cb.active_name.clear();
};
g_layout_cb.on_reset = []{ /* abrir todos los paneles, limpiar active_name */ };
// 4. En render(), aplicar pendientes y llamar app_menubar
void render() {
if (!g_pending_blob.empty()) {
ImGui::LoadIniSettingsFromMemory(g_pending_blob.c_str(), g_pending_blob.size());
g_layout_cb.active_name = g_pending_name;
g_pending_blob.clear(); g_pending_name.clear();
}
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport());
fn_ui::PanelToggle toggles[] = {
{"Foo", "Ctrl+1", &g_show_foo},
{"Bar", "Ctrl+2", &g_show_bar},
};
fn_ui::app_menubar(toggles, std::size(toggles), &g_layout_cb);
if (g_show_foo) {
if (ImGui::Begin("Foo", &g_show_foo)) { /* ... */ }
ImGui::End();
}
// ...
}
Fase 7 — UX node editor + DAG correctness [done] (2026-04-25)
Pulido de la edición visual del DAG y corrección de fugas en el render. Sin cambio de schema ni de catalog público (más allá del dag_register_node ya añadido en Fase 5).
- Nodos más grandes para conectar más rápido (
dag_node_editor.cpp):PIN_RADIUS9 → 14 px (área de grab ~2.5×).PIN_DIAMETER,CABLE_THICK2.5 → 3.5, borde de pin 1.5 → 2.0.CONTROL_WIDTHconstante 150 → 220 px,COL_GAP8 → 14 px,NodePaddingvertical 8 → 12.- Espaciado inicial entre nodos auto-colocados 220 → 320 px.
- Bug fix
solidsin label: el controlColorusabaImGuiColorEditFlags_NoLabel, así que el swatch era el único contenido del nodo y parecía "sin nombre ni parámetro". Fix endag_node_editor.cpp: imprimirImGui::TextUnformatted(ctrl.label) + SameLineantes del swatch. Aplica a todo control de tipoColor, no solo asolid. - Strict output (
dag_compile.cpp): eliminado el fallbacklast_valid_outque filtraba el output del último nodo evaluado cuandoOutputno tenía source o no existía. Ahora la regla es: solo se emite lo conectado al nodoOutput; en cualquier otro casoseed()(gris oscurovec4(0.04, 0.04, 0.06, 1.0)). Elresolve()de inputs internos también dejó de caer alast_valid_outy ahora emitevec4(0,0,0,1)para slots sin conectar. Tests:dag_compile6/6 → 7/7 (test 4b verifica que el seed final aparece después de las branches de preview, no antes). - Generated GLSL autocontenido (
compile_dag_to_glsl_baked, nuevo endag_compile.{h,cpp}):- Sustituye
uniform vec4 u_params[64]porconst vec4 u_params[N] = vec4[N](vec4(...), ...)con los valores actuales del pipeline empaquetados (mismo layout quedag_uniforms_apply). - Sustituye
uniform int u_preview_targetporconst int u_preview_target = -1(las branches de preview quedan muertas y el GLSL compiler las elimina). - Resultado: el shader del panel
Generated GLSLno depende de ningún uniform externo. Pegarlo en el editorCodereproduce exactamente el render del DAG en el momento del copy. Después editar el DAG no afecta al Code. - Test 7 nuevo:
dag_compile_bakedno contieneuniform vec4 u_paramsniuniform int u_preview_target, sí contieneconst vec4 u_params[y los valores empaquetados. - Importante: el
Canvas Codeya NO recibedag_uniforms_apply. Es totalmente independiente. (Versión anterior intentaba sincronizarlos; rompía el aislamiento entre paneles.)
- Sustituye
dag_uniforms_applytambién reseteau_preview_target = -1al final, para que la rama de preview quede desactivada en el render principal del Canvas DAG. La rutinadag_previews_renderla activa de forma transitoria por nodo y la deja restaurada.- Drop-replace del mismo kind:
- Soltar un nodo de la paleta sobre un nodo existente del mismo
DagKind(Gen sobre Gen, Op sobre Op, Blend sobre Blend, nunca sobre Output) sustituyename+params+controlsconservandoid,editor_uid,editor_pos_x/y,source_ids[]ypreview_open. - Slots de input que sobran (si el nuevo def tiene menos
num_inputsque el anterior) se limpian. - Hit-test contra cajas de nodos vía
ed::GetNodePosition+ed::GetNodeSize(canvas-space). No se usaed::GetHoveredNode()porque no es fiable durante un drag-drop activo.
- Soltar un nodo de la paleta sobre un nodo existente del mismo
- Drop-on-cable splice (intercalar nodo):
- Soltar un nodo de la paleta o arrastrar un nodo Op/Blend ya existente sobre un cable: el nodo se inserta entre
srcydst.new.source_ids[0] = src.id,dst.source_ids[slot] = new.id. Para Blend (2 inputs), slot 0 queda cableado y slot 1 vacío. - Para nodos existentes movidos: además de las dos rewires anteriores, se limpian todas las refs hacia el nodo movido en otros
source_ids[]antes (lo desengancha de cualquier consumidor previo, queda exclusivamente en la nueva posición). Tracking del nodo arrastrado vías_drag_existing_uid(set enIsMouseClicked(0)cuando hay un nodo hovered y no hay pin hovered, def es Gen/Op/Blend, no Output). - Hit-test del cable: distancia punto-segmento (
dist_point_to_segment) entre el cursor y la línea aproximada(src.right_mid → dst.left_at_slot_k). Threshold 18 px canvas-space. - Prioridad: cable-hit > node-hit > add-vacío.
- Soltar un nodo de la paleta o arrastrar un nodo Op/Blend ya existente sobre un cable: el nodo se inserta entre
- Splice highlight (preview visual):
- Mientras hay un drag activo de paleta o de nodo del canvas, el cable candidato se redibuja en
SPLICE_COLOR = (1.00, 0.82, 0.18, 1)(dorado) más grueso (CABLE_THICK + 2). - Garantía visual: además de cambiar el color en
ed::Link(), se dibuja un bezier dorado encima en elImGui::GetForegroundDrawList()(canvas → screen viaed::CanvasToScreen). Esto evita problemas de compositing interno del editor que podían enterrar el cambio de color. - Detección sin gates: la versión anterior gateaba con
IsMouseDown+window_hovered, lo que silenciaba el highlight. Ahora basta con la presencia del payload de drag-drop (paleta) o dels_drag_existing_uid(nodo del canvas).
- Mientras hay un drag activo de paleta o de nodo del canvas, el cable candidato se redibuja en
- Catalog
dag_catalog.cppya soportais_builtin(Fase 5) y permitedag_register_node/dag_unregister_nodepara generators custom; el splice/replace funciona sobre todos por igual (Built-ins, Gen custom guardados desde Code).
Comandos:
# Build linux
./fn run build_cpp_linux_bash_infra shaders_lab
# Build windows (cross-compile)
./fn run build_cpp_windows_bash_infra shaders_lab
# Tests del dominio gfx (puros, sin GL)
g++ -std=c++17 -Icpp/functions -DDAG_CATALOG_TEST cpp/functions/gfx/dag_catalog.cpp -o /tmp/dag_catalog_test && /tmp/dag_catalog_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 -DCODE_TO_GENERATOR_TEST cpp/functions/gfx/code_to_generator.cpp cpp/functions/gfx/uniform_parser.cpp -o /tmp/code_to_generator_test && /tmp/code_to_generator_test
g++ -std=c++17 -Icpp/functions -DUNIFORM_PARSER_TEST cpp/functions/gfx/uniform_parser.cpp -o /tmp/uniform_parser_test && /tmp/uniform_parser_test
gcc -c -O2 -DSQLITE_THREADSAFE=1 cpp/vendor/sqlite3/sqlite3.c -o /tmp/sqlite3.o && \
g++ -std=c++17 -Icpp/functions -Icpp/vendor/sqlite3 -DSHADERLAB_DB_TEST cpp/functions/gfx/shaderlab_db.cpp /tmp/sqlite3.o -lpthread -ldl -o /tmp/shaderlab_db_test && /tmp/shaderlab_db_test
Cobertura de tests inline tras esta fase: 8 + 7 + 7 + 6 + 7 = 35 asserts sobre dag_catalog (19 nodos), dag_compile (strict + baked), code_to_generator, uniform_parser, shaderlab_db.
Sync de binarios Windows (regla establecida en esta sesión):
cpp/build/windows/apps/shaders_lab/shaders_lab.exe(origen)apps/shaders_lab/shaders_lab.exe(in-repo)/mnt/c/Users/lucas/Desktop/shaders_lab.exe(Windows Desktop)- NUNCA copiar a
/mnt/c/Users/AdminLocal/. Memoria persistente:feedback_no_adminlocal.md.
Lo siguiente que pega
- Push selectivo al registry global: boton
Push to registryque extrae el generator acpp/functions/gfx/<name>.{cpp,md}con tagshaders_laby disparafn index. - Listado / borrado de generators custom desde la UI (hoy solo via DB directa).
- Persistencia de pipelines con nombre.
- Mas nodos: warps (twirl, polar, kaleidoscope), perlin/fbm reales, SDFs, filtros de luma.
- Save as Op (1 input
a) y Save as Blend (2 inputs). - 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.
Documentacion de exploraciones aparcadas (no en backlog inmediato):
NEXT_STEPS_DATA_TYPES.md— extensiones del DAG: pins tipados, texturas, SDF/raymarch, multi-pass, geometria 3D.NEXT_STEPS_BORDERLESS_WINDOW.md— quitar la titlebar del SO y mover min/max/close alMainMenuBarImGui.
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 aapps/shaders_lab/shaders_lab.exey 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.
Layouts
ImGui persiste el layout actual en imgui.ini junto al binario (autosave). Ademas, el menu Layouts permite tener varios layouts guardados con nombre:
- Mueve los paneles donde quieras.
Layouts > Save current as...y dale un nombre (ej. "Coding", "DAG mode", "Showcase").- Cambia el layout, guarda otro.
Layouts > <nombre>para saltar; el activo se marca con*.Layouts > Delete > <nombre>para borrar.Layouts > Reset to defaultreabre todos los paneles y limpia el marker.
Los layouts guardados viven en la tabla ui_layouts de shaders_lab.db.
Disposicion comoda al primer arranque:
CodeyDAG Pipelineocupan la fila superior.Canvas CodeyCanvas DAGocupan la fila inferior, lado a lado.FunctionsyControlsvan a un lateral.Generated GLSLminimizado o en pestana junto aControls.
El menu View togglea cada panel individualmente (mismo bool* que la X de la ventana).
Notas de cross-compile
gl_loaderresuelve simbolos OpenGL 2.0+ conwglGetProcAddressen Windows; en Linux es no-op (GL_GLEXT_PROTOTYPES).WIN32_EXECUTABLE TRUEenCMakeLists.txtevita la consola al lanzar el .exe.- Vendor de imgui-node-editor cuesta ~1MB en el binario final (~18 MB total).
Notas — Settings + iconos (sesion 2026-04-25)
app_menubarahora añade automaticamente un tercer itemSettings...junto aViewyLayouts. Click abre la ventana flotante deapp_settings(Display: toggle FPS overlay; Typography: combo de fuente Karla/Roboto/DroidSans/Cousine + slider de tamaño 10..32 px). Persiste enapp_settings.inijunto ashaders_lab.exe.- Defaults: DroidSans 15 px, FPS overlay off (antes hardcoded ON dentro del panel
Controls). - Removida la llamada explicita
fps_overlay()del panelControls— ahora se respeta el toggle de Settings. - Removidos los
.cppdefps_overlay,panel_menu,layouts_menu,app_menubardelCMakeLists.txt— viven enfn_frameworkpara evitar multiple-definition. Sololayout_storage_sqlite.cppsigue listado explicitamente. - 5 TTFs (Karla / Roboto / DroidSans / Cousine / Tabler) copiadas junto al exe via
add_imgui_apppost-build.
Para añadir secciones propias de settings:
// En main.cpp antes de fn::run_app:
fn_ui::settings_window_add_section("shader_compiler", "Shader compiler", []{
ImGui::Checkbox("Auto-compile on save", &g_auto_compile);
ImGui::SliderInt("Debounce (ms)", &g_debounce_ms, 50, 2000);
});
// Aparece debajo de Display/Typography. Persistencia propia (puede ir en
// shaders_lab.db, tabla ui_settings).
Lo siguiente que pega
- Ejemplo concreto de seccion extra de settings:
auto-compile on save+debounce_msregistrados desdemain.cppy persistidos en una tablaui_settingsenshaders_lab.db. - Auditar hex UTF-8 (
"\x..\x..") o emojis Unicode hardcoded en uniform_panel, dag_panel, dag_node_editor → migrar aTI_*decore/icons_tabler.h. - Rebuild Windows + sync:
cmake --build cpp/build/windows --target shaders_lab && cp cpp/build/windows/apps/shaders_lab/{shaders_lab.exe,*.ttf} /mnt/c/Users/lucas/Desktop/apps/shaders_lab/.