Stack base de compute shaders OpenGL 4.3 para cargas Monte Carlo intensivas
en GPU. Reutiliza el patron de graph_force_layout_gpu (SSBO + compute) y se
integra con el resto del registry sin nuevos simbolos en gl_loader (todo lo
que se necesita ya estaba expuesto).
- gpu_ssbo: lifecycle de Shader Storage Buffer Objects.
- gpu_compute_program: compila compute GLSL 4.3 con preamble inyectable
(mismo pattern de gl_shader::compile_fragment).
- gpu_dispatch: dispatch_1d/2d/3d con ceil(N/local) automatico + barrier
helpers (storage, uniform, image, buffer_update, all).
- gpu_rng_glsl: PCG32 GLSL (uniform/normal/below) + SplitMix64 seed walkers
para sembrar deterministicamente N walkers desde un master seed.
- gpu_histogram_1d: SSBO float[N] -> uint[nbins] via atomicAdd.
- gpu_histogram_2d: SSBO float[2N] xy-interleaved -> uint[nx*ny] +
to_density helper para alimentar heatmap_cpp_viz.
- gpu_reduce: workgroup-shared sum/min/max/mean (local 256, partials CPU).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Necesario para que las funciones GPU compute (gpu_histogram_1d/2d, gpu_reduce,
mc_*_gpu) puedan setear uniforms uint en Windows. En Linux ya estaba
disponible via GL_GLEXT_PROTOTYPES.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Layout force-directed en GPU usando 5 compute shaders 4.3 + spatial hash
grid 64x64. API simetrica con graph_force_layout (CPU) para que el consumer
pueda swappear sin cambios. atomicCompSwap loop para float-add portable.
- cpp/functions/viz/graph_force_layout_gpu.{h,cpp,md}: nuevo modulo
- cpp/functions/gfx/gl_loader: anade glDispatchCompute, glMemoryBarrier,
glBindBufferBase, glGetBufferSubData (Windows wgl)
- cpp/tests/test_graph_force_layout_gpu.cpp: smoke + pinned + CPU vs GPU.
Crea ventana GLFW oculta GL 4.3; SKIP si headless o sin compute.
- demos_graph: checkbox "GPU layout" para swappear CPU/GPU en runtime
- issue movido a dev/issues/completed/
El buffer de aristas pasa a estatico (16B/arista: source, target, color,
flags) y solo se reupload cuando cambia el grafo. Las posiciones de los
nodos viven en un Texture Buffer Object (RG32F) actualizado por frame; el
vertex shader hace texelFetch con gl_VertexID & 1 para elegir endpoint.
Draw call: glDrawArraysInstanced(GL_LINES, 0, 2, edge_count) con divisor=1.
Para 100k aristas: el upload de 4.8 MB/frame baja a 0 en regimen estable.
edge_alpha pasa a uniform; la pre-multiplicacion en CPU desaparece. GLSL
sigue en 330 core (samplerBuffer/texelFetch estan en 1.40+).
gl_loader gana glBufferSubData, glVertexAttribIPointer y glTexBuffer (en
Linux ya estaban via GL_GLEXT_PROTOTYPES; ahora estan disponibles tambien
en MinGW/Windows).
Tests: nuevo test_graph_edge_static valida el layout de 16B y el packing
RGBA8 del fallback. test_visual sigue verde — render visualmente identico.
Bump graph_renderer 1.2.0 -> 1.3.0.
Auditoria del issue 0044: anota en notes: el contexto de consumo de
huerfanos que no pueden registrarse en uses_functions porque sus
consumidores no son funciones del registry:
- consumido por cpp/framework/app_base.cpp (framework no indexado)
- consumido por cpp/apps/{shaders_lab,chart_demo,text_editor_smoke}/main.cpp
- scaffolding/demo en primitives_gallery
31 huerfanas anotadas. Las que quedan en uses_functions=[] tras esto
son hojas legitimas (no llaman a nada) o realmente sin uso (lista
DEAD reportada en el issue 0044).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auditoria del issue 0044: 14 archivos .md de cpp/functions/gfx/ con
uses_functions actualizado. Resuelve dependencias detectadas via
#include: gl_loader (consumido por casi todo el dominio gfx),
dag_catalog (consumido por la familia dag_*), fullscreen_quad,
gl_framebuffer, gl_shader, mesh_obj_load, uniform_parser y
dag_node_previews.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Compila/cachea por id un programa GLSL (vertex+fragment) con
iluminacion Lambert (luz=camara), gestiona Framebuffer cacheado por
id, dibuja MeshGpu con orbit camera, muestra via ImGui::Image y
maneja drag (mouse) + wheel (zoom). Wireframe opcional via
glPolygonMode.
gl_loader: añade glUniformMatrix4fv (proc requerido en Windows para
subir las matrices view/proj del mesh_viewer).
issue 0029
mesh_obj_parse (pure) + mesh_obj_load (impure file helper).
Soporta v / vn / f (tris y quads). Genera normales per-face si
faltan (flat shading). Quads se parten en 2 tris; n-gons (>4) se
descartan silenciosamente. Indices 1-based positivos y negativos.
issue 0029
Dos primitivas del pipeline de shaders_lab que ya estaban en uso pero sin
indexar al registry:
- code_to_generator_cpp_gfx (function, pure)
Traduce un fragment shader GLSL escrito a mano (modo Code, con void main()
+ fragColor = ...) en un body de DAG Gen + DagControl[]. Cada uniform
anotado se convierte en un control; el body usa el parametro uv y reemplaza
fragColor= por return. Empaqueta uniforms en vec4 (4 x n_uniforms).
- shaderlab_db_cpp_gfx (function, impure)
CRUD persistente para generators custom de shaders_lab via sqlite3.
Guarda el GLSL original, el body traducido para el DAG, los DagControl y
los param_defaults en una BD local (shaders_lab.db). Soporta open(:memory:)
para tests.
Ambas se indexan ahora en registry.db y son reusables fuera de shaders_lab
si en el futuro hay otra app que componga DAGs de shaders.
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>
Funcion impura del registry que carga PNG/JPG/BMP/TGA/HDR a una textura
OpenGL lista para sampler2D. Composable con gl_loader, gl_shader,
shader_canvas. Genera mipmaps, soporta sRGB y HDR (RGBA16F).
API:
GlTexture gl_texture_load(path, flip_y=true, srgb=false)
GlTexture gl_texture_load_from_memory(data, size, ...)
void gl_texture_destroy(tex)
const char* gl_texture_last_error() // thread-local
void gl_texture_bind_uniform(prog, name, tex, unit)
Errores via thread_local string accesible por gl_texture_last_error().
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Necesarios para que gl_texture_load (cpp/functions/gfx/) funcione en
Windows tras wglGetProcAddress. En Linux son simbolos directos via
GL_GLEXT_PROTOTYPES, no afecta.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- DagStep: preview_open flag (default false).
- dag_compile: emit `uniform int u_preview_target` and a series of
early-return branches at the start of fragColor selection. -1 (default)
falls through to the real Output-driven fragColor.
- dag_node_previews (new fn): per-node FBO keyed by editor_uid, lazy
created. Renders each node with preview_open=true to its FBO by
setting u_preview_target = step index. Texture exposed via
dag_preview_texture(uid) for ImGui::Image.
- dag_node_editor: small toggle button "[+] preview"/"[-] preview" in
each non-Output node; when open, ImGui::Image(96x64, V-flipped).
- dag_node_editor: double right-click on hovered node deletes it
(Output is protected).
- main.cpp: dag_previews_render after Canvas DAG; dag_previews_destroy
on shutdown.
Single GL program drives both the canvas and all thumbnails — moving
sliders never recompiles, only the topology change does.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
draw_pin_circle takes a PinSide and centers the circle exactly on the
left or right edge of the node. The reserved Dummy is half-width
(PIN_RADIUS instead of PIN_DIAMETER) so the inside layout stays
compact, and ed::PinRect is set to the full circle so the protruding
half is still grabbable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Pin radius bumped to 9px (18px diameter). Easier to grab.
- Single neutral pin/cable color across all kinds (data is uniformly
vec4 — coloring by node kind was misleading).
- ed::StyleVar_NodePadding(0,8,0,8): zero left/right padding so the pin
circles sit flush with the node's edges, separated from the title
and controls by 8px gaps.
- Right-click on a pin clears all connections on that pin:
- input pin → clear that single slot's source_id
- output pin → clear every source_id across the pipeline pointing
to this node (fan-out).
- Right-click on a link still deletes that single link (existing).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Three-column node layout: input pins on the left edge, controls in
the middle, output pin on the right edge.
- Pins rendered as 14px filled circles with darker outline. Color is
the node's kind (gen=blue, op=violet, blend=amber, output=red).
- ed::PinPivotAlignment(0,0.5)/(1,0.5) so the cable starts/ends at
the circle center.
- Empty columns (gen with no inputs, output with no output) get a
pin-sized Dummy so column widths stay consistent.
- ed::Link now passes color (= source node kind) and 2.5px thickness.
- Right-click on a link deletes it immediately via
ed::ShowLinkContextMenu (no popup).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously the cycle validator rejected any link whose source had a
vector index >= target's, which silently killed legitimate connections
between nodes added in the wrong drop order.
Switch to a DFS over source_ids: an edge from->to creates a cycle iff
`from` already (transitively) depends on `to`. topo_sort runs after
each topology change so the vector ends up in a consistent order
regardless of how nodes were inserted.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two bugs:
1. Dropped nodes were pushed to the end of the pipeline, but the Output
node already sat there from startup. The cycle validator and the
compiler only look for sources at indices strictly lower than the
target, so new nodes were invisible to the Output. Fix: insert
dropped nodes before the first Output; topo_sort also stable-moves
Output nodes to the back.
2. ColorEdit3 with default flags rendered RGB text inputs alongside the
swatch; clicking them dragged the node instead of opening the picker.
Fix: NoInputs + NoLabel leaves only the swatch (a single item), and
ed::Suspend/Resume wraps the call so the popup isn't clipped to the
node or captured by the canvas.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous InvisibleButton captured mouse events, so you could drag
from the Functions palette into the canvas, but node dragging and
slider interaction inside the canvas stopped working.
Fix: watch the global drag-drop payload without an explicit target. When
the mouse releases LMB over the DAG window with a "DAG_NODE_TYPE"
payload active, queue an add at that canvas position. No button, no
capture.
Tests (compiled standalone with preprocessor defines):
- dag_compile: 6/6 asserts (empty, single gen, op chain, multi-source
blend, Output-driven fragColor, unconnected-Output fallback).
- dag_catalog: 8/8 asserts (uniqueness, per-kind input invariants,
exactly one Output, body_glsl present & returns, control param
indices valid).
Build with:
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
g++ -std=c++17 -Icpp/functions -DDAG_CATALOG_TEST cpp/functions/gfx/dag_catalog.cpp -o /tmp/dag_catalog_test
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously SetNodePosition was called after EndNode every frame, which
reset any drag the user had done. Now the initial position is set once
per editor_uid (tracked in a static unordered_set), and the editor owns
the position afterwards. GetNodePosition at end-of-frame keeps step
state in sync for future persistence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ImGui native BeginDragDropSource/Target over each CollapsingHeader.
Drag source adjusted if ahead of target to keep final position correct.
Move Up/Down buttons kept for keyboard/touchpad fallback.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- cpp/functions/gfx/gl_loader.{h,cpp,md}: mini loader para OpenGL 2.0+
(Linux no-op via GL_GLEXT_PROTOTYPES, Windows wglGetProcAddress)
- Portar gl_shader/gl_framebuffer/fullscreen_quad/shader_canvas al loader
- CMakeLists: WIN32_EXECUTABLE para lanzar sin consola en Windows
- apps/shaders_lab/shaders_lab.exe: binario PE32+ precompilado
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>