feat: add C++ support with ImGui/ImPlot framework and vendor submodules

Añade soporte C++ al registry: vendor submodules (glfw, imgui, implot, tracy),
sistema de build con CMake y toolchains cross-platform, runner C++ en fn CLI,
parser de tests Google Test, y funciones bash para build Linux/Windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 23:46:36 +02:00
parent 0c759c1b66
commit 4b2bb6998a
36 changed files with 1065 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
#include "core/fps_overlay.h"
#include "imgui.h"
#ifdef TRACY_ENABLE
#include "tracy/Tracy.hpp"
#endif
void fps_overlay() {
#ifdef TRACY_ENABLE
ZoneScoped;
#endif
ImGuiIO& io = ImGui::GetIO();
ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration
| ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoFocusOnAppearing
| ImGuiWindowFlags_NoNav
| ImGuiWindowFlags_NoMove;
const float pad = 10.0f;
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImVec2 pos(viewport->WorkPos.x + viewport->WorkSize.x - pad,
viewport->WorkPos.y + pad);
ImGui::SetNextWindowPos(pos, ImGuiCond_Always, ImVec2(1.0f, 0.0f));
ImGui::SetNextWindowBgAlpha(0.65f);
if (ImGui::Begin("##fps_overlay", nullptr, flags)) {
ImGui::Text("%.1f FPS", io.Framerate);
ImGui::Text("%.3f ms", 1000.0f / io.Framerate);
}
ImGui::End();
}
+5
View File
@@ -0,0 +1,5 @@
#pragma once
// Renders an FPS counter overlay in the top-right corner.
// Call within an ImGui frame.
void fps_overlay();
+30
View File
@@ -0,0 +1,30 @@
---
name: fps_overlay
kind: component
lang: cpp
domain: core
version: "1.0.0"
purity: pure
signature: "void fps_overlay()"
description: "Renderiza un overlay de FPS y frametime en la esquina superior derecha, con soporte opcional de Tracy"
tags: [imgui, fps, overlay, profiling, debug]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [imgui]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/core/fps_overlay.cpp"
framework: imgui
params: []
output: "Renderiza el overlay de FPS en el frame ImGui actual"
---
# fps_overlay
Muestra FPS y frametime (ms) en una ventana semi-transparente en la esquina superior derecha.
Si se compila con `TRACY_ENABLE`, incluye un `ZoneScoped` para profiling con Tracy.
+26
View File
@@ -0,0 +1,26 @@
#include "viz/bar_chart.h"
#include "implot.h"
#include <vector>
void bar_chart(const char* title, const char* const* labels, const float* values, int count, float bar_width) {
if (ImPlot::BeginPlot(title, ImVec2(-1, 0))) {
std::vector<double> positions(count);
for (int i = 0; i < count; i++) positions[i] = i;
ImPlot::SetupAxisTicks(ImAxis_X1, positions.data(), count, labels);
ImPlot::PlotBars("##data", values, count, bar_width);
ImPlot::EndPlot();
}
}
void bar_chart(const char* title, const char* const* labels, const double* values, int count, double bar_width) {
if (ImPlot::BeginPlot(title, ImVec2(-1, 0))) {
std::vector<double> positions(count);
for (int i = 0; i < count; i++) positions[i] = i;
ImPlot::SetupAxisTicks(ImAxis_X1, positions.data(), count, labels);
ImPlot::PlotBars("##data", values, count, bar_width);
ImPlot::EndPlot();
}
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
// Renders a vertical bar chart using ImPlot.
// Call within an ImGui frame.
void bar_chart(const char* title, const char* const* labels, const float* values, int count, float bar_width = 0.67f);
void bar_chart(const char* title, const char* const* labels, const double* values, int count, double bar_width = 0.67);
+40
View File
@@ -0,0 +1,40 @@
---
name: bar_chart
kind: component
lang: cpp
domain: viz
version: "1.0.0"
purity: pure
signature: "void bar_chart(const char* title, const char* const* labels, const float* values, int count, float bar_width)"
description: "Renderiza un grafico de barras verticales usando ImPlot dentro de un frame ImGui"
tags: [implot, chart, visualization, gpu, bar]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [implot]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/viz/bar_chart.cpp"
framework: imgui
params:
- name: title
desc: "Titulo del grafico de barras"
- name: labels
desc: "Array de etiquetas para el eje X, una por barra"
- name: values
desc: "Array de valores numericos para la altura de cada barra"
- name: count
desc: "Numero de barras (longitud de labels y values)"
- name: bar_width
desc: "Ancho de cada barra como fraccion del espacio disponible (default 0.67)"
output: "Renderiza el grafico de barras en el frame ImGui actual"
---
# bar_chart
Wrapper atomico sobre `ImPlot::PlotBars` con configuracion automatica de etiquetas en el eje X.
Debe llamarse dentro del render callback de `fn::run_app`.
+24
View File
@@ -0,0 +1,24 @@
#include "viz/heatmap.h"
#include "implot.h"
void heatmap(const char* title, const float* values, int rows, int cols,
float scale_min, float scale_max) {
if (ImPlot::BeginPlot(title, ImVec2(-1, 0), ImPlotFlags_NoLegend)) {
ImPlot::SetupAxes(nullptr, nullptr,
ImPlotAxisFlags_NoDecorations, ImPlotAxisFlags_NoDecorations);
ImPlot::PlotHeatmap("##data", values, rows, cols,
scale_min, scale_max);
ImPlot::EndPlot();
}
}
void heatmap(const char* title, const double* values, int rows, int cols,
double scale_min, double scale_max) {
if (ImPlot::BeginPlot(title, ImVec2(-1, 0), ImPlotFlags_NoLegend)) {
ImPlot::SetupAxes(nullptr, nullptr,
ImPlotAxisFlags_NoDecorations, ImPlotAxisFlags_NoDecorations);
ImPlot::PlotHeatmap("##data", values, rows, cols,
scale_min, scale_max);
ImPlot::EndPlot();
}
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
// Renders a heatmap using ImPlot.
// Data is row-major: values[row * cols + col].
// Call within an ImGui frame.
void heatmap(const char* title, const float* values, int rows, int cols,
float scale_min = 0.0f, float scale_max = 0.0f);
void heatmap(const char* title, const double* values, int rows, int cols,
double scale_min = 0.0, double scale_max = 0.0);
+42
View File
@@ -0,0 +1,42 @@
---
name: heatmap
kind: component
lang: cpp
domain: viz
version: "1.0.0"
purity: pure
signature: "void heatmap(const char* title, const float* values, int rows, int cols, float scale_min, float scale_max)"
description: "Renderiza un mapa de calor 2D usando ImPlot dentro de un frame ImGui"
tags: [implot, chart, visualization, gpu, heatmap, matrix]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [implot]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/viz/heatmap.cpp"
framework: imgui
params:
- name: title
desc: "Titulo del heatmap"
- name: values
desc: "Array de valores en orden row-major (values[row * cols + col])"
- name: rows
desc: "Numero de filas de la matriz"
- name: cols
desc: "Numero de columnas de la matriz"
- name: scale_min
desc: "Valor minimo de la escala de color (0 para autodetectar)"
- name: scale_max
desc: "Valor maximo de la escala de color (0 para autodetectar)"
output: "Renderiza el heatmap en el frame ImGui actual"
---
# heatmap
Wrapper atomico sobre `ImPlot::PlotHeatmap`. Renderiza una matriz de valores como mapa de calor con escala de color.
Los datos deben estar en formato row-major. Si `scale_min` y `scale_max` son ambos 0, ImPlot autodetecta el rango.
+16
View File
@@ -0,0 +1,16 @@
#include "viz/line_plot.h"
#include "implot.h"
void line_plot(const char* title, const float* xs, const float* ys, int count) {
if (ImPlot::BeginPlot(title, ImVec2(-1, 0))) {
ImPlot::PlotLine("##data", xs, ys, count);
ImPlot::EndPlot();
}
}
void line_plot(const char* title, const double* xs, const double* ys, int count) {
if (ImPlot::BeginPlot(title, ImVec2(-1, 0))) {
ImPlot::PlotLine("##data", xs, ys, count);
ImPlot::EndPlot();
}
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
// Renders a 2D line plot using ImPlot.
// Call within an ImGui frame (inside fn::run_app render callback).
void line_plot(const char* title, const float* xs, const float* ys, int count);
// Overload with double precision.
void line_plot(const char* title, const double* xs, const double* ys, int count);
+40
View File
@@ -0,0 +1,40 @@
---
name: line_plot
kind: component
lang: cpp
domain: viz
version: "1.0.0"
purity: pure
signature: "void line_plot(const char* title, const float* xs, const float* ys, int count)"
description: "Renderiza un grafico de lineas 2D usando ImPlot dentro de un frame ImGui"
tags: [implot, chart, visualization, gpu, line]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [implot]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/viz/line_plot.cpp"
framework: imgui
params:
- name: title
desc: "Titulo del grafico, se muestra como header del plot"
- name: xs
desc: "Array de coordenadas X"
- name: ys
desc: "Array de coordenadas Y"
- name: count
desc: "Numero de puntos en los arrays xs/ys"
output: "Renderiza el grafico de lineas en el frame ImGui actual"
---
# line_plot
Wrapper atomico sobre `ImPlot::PlotLine`. Renderiza un grafico de lineas 2D con los datos proporcionados.
Debe llamarse dentro del render callback de `fn::run_app` (o cualquier contexto con un frame ImGui activo).
Soporta `float` y `double` precision.
+16
View File
@@ -0,0 +1,16 @@
#include "viz/scatter_plot.h"
#include "implot.h"
void scatter_plot(const char* title, const float* xs, const float* ys, int count) {
if (ImPlot::BeginPlot(title, ImVec2(-1, 0))) {
ImPlot::PlotScatter("##data", xs, ys, count);
ImPlot::EndPlot();
}
}
void scatter_plot(const char* title, const double* xs, const double* ys, int count) {
if (ImPlot::BeginPlot(title, ImVec2(-1, 0))) {
ImPlot::PlotScatter("##data", xs, ys, count);
ImPlot::EndPlot();
}
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
// Renders a scatter plot using ImPlot.
// Call within an ImGui frame.
void scatter_plot(const char* title, const float* xs, const float* ys, int count);
void scatter_plot(const char* title, const double* xs, const double* ys, int count);
+38
View File
@@ -0,0 +1,38 @@
---
name: scatter_plot
kind: component
lang: cpp
domain: viz
version: "1.0.0"
purity: pure
signature: "void scatter_plot(const char* title, const float* xs, const float* ys, int count)"
description: "Renderiza un grafico de dispersion usando ImPlot dentro de un frame ImGui"
tags: [implot, chart, visualization, gpu, scatter]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [implot]
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/viz/scatter_plot.cpp"
framework: imgui
params:
- name: title
desc: "Titulo del grafico scatter"
- name: xs
desc: "Array de coordenadas X"
- name: ys
desc: "Array de coordenadas Y"
- name: count
desc: "Numero de puntos en los arrays xs/ys"
output: "Renderiza el grafico de dispersion en el frame ImGui actual"
---
# scatter_plot
Wrapper atomico sobre `ImPlot::PlotScatter`. Renderiza un grafico de dispersion 2D.
Debe llamarse dentro del render callback de `fn::run_app`.