---
name: graph_renderer
kind: function
lang: cpp
domain: viz
version: "1.1.0"
purity: impure
signature: "GraphRenderer* graph_renderer_create(int width, int height, const GraphRendererConfig& config)"
description: "Renderer GPU de grafos con instanced rendering a FBO, compatible con ImGui::Image para visualizacion de grafos grandes"
tags: [graph, renderer, opengl, gpu, instanced, fbo, visualization]
uses_functions: []
uses_types: ["GraphData_cpp_viz"]
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [imgui]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/viz/graph_renderer.cpp"
framework: imgui
params:
  - name: width
    desc: "Ancho del framebuffer en pixels"
  - name: height
    desc: "Alto del framebuffer en pixels"
  - name: config
    desc: "Configuracion visual: outline width, edge width, edge alpha, color de fondo, fade de aristas por distancia a camara"
output: "Handle opaco al renderer. Usar graph_renderer_draw() para obtener texture ID de OpenGL, pasable directamente a ImGui::Image()"
---

# graph_renderer

Renderer GPU de grafos basado en OpenGL 3.3 core profile con instanced rendering. Renderiza nodos y aristas de un `GraphData` a un FBO interno y retorna el texture ID para integracion directa con `ImGui::Image()`.

## Funciones del API

```cpp
// Ciclo de vida
GraphRenderer* graph_renderer_create(int width, int height, const GraphRendererConfig& config = {});
void graph_renderer_destroy(GraphRenderer* r);
void graph_renderer_resize(GraphRenderer* r, int width, int height);

// Renderizado
unsigned int graph_renderer_draw(GraphRenderer* r, const GraphData& graph,
                                  float cam_x, float cam_y, float cam_zoom);
```

## Ejemplo de uso con ImGui

```cpp
// Inicializacion (una vez)
GraphRenderer* renderer = graph_renderer_create(800, 600);

// En el render loop
ImVec2 panel_size = ImGui::GetContentRegionAvail();
graph_renderer_resize(renderer, (int)panel_size.x, (int)panel_size.y);

unsigned int tex = graph_renderer_draw(renderer, graph_data,
                                        cam_x, cam_y, cam_zoom);

ImGui::Image((ImTextureID)(uintptr_t)tex,
             panel_size,
             ImVec2(0, 1), ImVec2(1, 0)); // flip Y para OpenGL

// Destruccion
graph_renderer_destroy(renderer);
```

## Notas de implementacion

**Renderizado de nodos:** Instanced rendering con un quad unitario [-0.5, 0.5] expandido por el tamano del nodo. El fragment shader aplica un SDF circular con anti-aliasing via `smoothstep` y un anillo de outline.

**Renderizado de aristas:** `GL_LINES` con datos de posicion y color empaquetados por arista. El ancho se controla con `GraphRendererConfig::edge_width`.

**Transformacion de camara:**
```
tx = -cam_x * zoom + width/2
ty = -cam_y * zoom + height/2
ndc = (screen / viewport) * 2 - 1
```

**Paleta de comunidades:** 10 colores ABGR usados cuando `node.color == 0`, seleccionados por `node.community % 10`.

**Estado GL:** Guarda y restaura `GL_FRAMEBUFFER_BINDING` y `GL_VIEWPORT` para ser compatible con el render loop de ImGui sin efectos secundarios.

**Includes GL:** Usa `gfx/gl_loader.h` (v1.1+). En Linux es no-op (incluye headers con `GL_GLEXT_PROTOTYPES`). En Windows expone los simbolos modernos via `wglGetProcAddress` con macros `#define gl* fn_gl*`. Cualquier app que use `graph_renderer` debe linkear `gl_loader.cpp` y llamar `fn::gfx::gl_loader_init()` una vez tras crear el contexto GL.

## Notas

- **v1.1** (2026-04-25): cambia de raw `<GL/glext.h>` a `gfx/gl_loader.h` para que compile en cross-compile MinGW. Sin cambios funcionales — el binario Linux es bit-equivalente.
