---
name: dag_catalog
kind: function
lang: cpp
domain: gfx
version: "1.0.0"
purity: pure
signature: "const std::vector<DagNodeDef>& dag_catalog(); const DagNodeDef* dag_find(const std::string& name)"
description: "Catalogo global de nodos DAG para el pipeline de shaders. dag_catalog() devuelve referencia estable a los 10 nodos hardcoded (4 gen, 3 op, 3 blend) portados desde shader-dag-blends.jsx. dag_find() busca por nombre."
tags: [dag, shader, catalog, nodes, gfx, pipeline]
uses_functions: []
uses_types:
  - dag_types_cpp_gfx
returns: []
returns_optional: false
error_type: ""
imports: [dag_types, string, vector]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/gfx/dag_catalog.cpp"
params: []
output: "dag_catalog(): referencia const estable al vector de DagNodeDef (instancia estatica, no se invalida). dag_find(name): puntero al nodo con ese nombre o nullptr si no existe."
notes: "consumido por cpp/apps/shaders_lab/main.cpp"
---

## Nodos incluidos

### Generadores (4)
- **solid**: color constante RGB
- **gradient**: gradiente direccional con tono
- **plasma**: onda trigonometrica animada
- **circle**: SDF de circulo con suavizado

### Operadores (3)
- **invert**: 1 - rgb
- **gamma**: correccion gamma pow(rgb, 1/g)
- **hueShift**: rotacion de matiz via matriz YIQ

### Blends (3)
- **blend_mix**: interpolacion mix(a, b, t)
- **blend_multiply**: a.rgb * b.rgb
- **blend_screen**: 1 - (1-a)(1-b)

## Notas

Los cuerpos GLSL omiten las declaraciones de u_time, u_resolution, u_params — las proporciona el preamble de gl_shader::compile_fragment o compile_dag_to_glsl. El indice idx que recibe body_glsl es la posicion en el pipeline (para indexar u_params[idx]).

## Cambios 2026-04-25 (Fase 5 + Fase 7 shaders_lab)

Catálogo creció de 11 a **19 nodos**. Nuevos `Gen` (8): `checker`, `stripes`, `dots`, `rings`, `polar_rays`, `noise_value`, `voronoi`, `truchet`. Bug fix: `solid` ahora muestra label en su control Color (era invisible por `ImGuiColorEditFlags_NoLabel`).

API mutable y lifecycle (declarados en `dag_catalog.h`):
- `dag_register_node(DagNodeDef def) -> bool`: añade o reemplaza un nodo user. Refuse si el nombre colisiona con un built-in. Setea `is_builtin = false` en el stored.
- `dag_unregister_node(name) -> bool`: borra un user node. Built-ins están protegidos.
- Flag `is_builtin` en `DagNodeDef` (ver `dag_types.h`). Built-ins se cargan en el constructor estático y nunca se tocan tras eso.

Layout de params:
- `param_names`/`param_defaults` pasan de `array<*,4>` a `vector<*>`. Cada nodo declara la cantidad real de floats que necesita (sin padding cosmético).
- `body_glsl` recibe `int base_vec4` (índice base en el array global), no el index del nodo. El compilador lo calcula vía `dag_param_layout`.
- `body_glsl(idx)` semantically: where `idx` was the node index, now it is the vec4 base. Bodies que originalmente hacían `vec4 p = u_params[i]; ...; p.x ... p.w` siguen funcionando porque cada nodo built-in cabe en 1 vec4. Generators custom de Code → DAG (`code_to_generator`) reciben `__BASE__` como placeholder y la lambda lo sustituye en runtime con el valor real.

`body_glsl(int base_vec4)` retorna string con cuerpo de la función `vec4 node_<i>(vec4 a?, vec4 b?, ..., vec2 uv)`. Los inputs llegan como params `a`,`b`,`c`,`d` según `num_inputs`; `uv` siempre presente.

Tests: 8/8 (19 nodos, invariantes por kind + 1 control_idx in-bounds + name uniqueness).
