Files
fn_registry/dev/issues/0026-cpp-gl-texture-load.md
T
egutierrez 461bb77298 docs(issues): añadir 0025-0036 — features C++ para registry y primitives_gallery
12 issues nuevos para implementacion paralela: text_editor, file_watcher,
gl_texture_load, gl_compute+pingpong+DAG Compute, ImPlot3D, mesh_viewer,
audio reactivo, animation curves, sql_workbench, http+ws inspector,
scientific viz (5 charts), map_tiles, image_canvas + webcam_texture.

Cada issue añade funciones al registry y un demo propio en
primitives_gallery/demos_<feature>.cpp para minimizar conflictos en paralelo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 20:48:18 +02:00

131 lines
5.0 KiB
Markdown

# 0026 — C++ gl_texture_load
## APP Metadata
| Campo | Valor |
|-------|-------|
| **ID** | 0026 |
| **Estado** | pendiente |
| **Prioridad** | alta |
| **Tipo** | feature — C++ gfx (cpp/functions/gfx) |
## Dependencias
Ninguna. Se compone con `gl_loader_cpp_gfx`, `gl_shader_cpp_gfx`, `shader_canvas_cpp_gfx`.
**Desbloquea:** shaders que toman imagenes externas (textura de ruido, foto, lookup tables). Base para `webcam_texture` (0036) y para nodos DAG futuros que usen sampler2D.
---
## Objetivo
Añadir una funcion impura al registry C++ que carga PNG/JPG/HDR desde disco y devuelve un `GLuint` listo para `glBindTexture` + `glUniform1i`. Vendorea **stb_image** (header-only, dominio publico) en `cpp/vendor/stb/`.
Mostrar el resultado en `primitives_gallery` como demo: un shader fullscreen que samplea una imagen cargada, con sliders para tint y zoom UV.
## Contexto
Actualmente `gl_shader_cpp_gfx` solo expone uniforms `u_resolution`, `u_time`, `u_mouse`, y `shaders_lab` puede pasar `u_params[16]` via `dag_uniforms`. No hay forma de meter una imagen al pipeline. Esto bloquea casos comunes:
- Texturas de ruido (perlin/bluenoise) precomputadas.
- Lookup tables para color grading.
- Imagenes de referencia para post-process.
## Arquitectura
```
cpp/
├── vendor/stb/
│ └── stb_image.h # NEW (~10k LOC, public domain)
├── functions/gfx/
│ ├── gl_texture_load.h # NEW
│ ├── gl_texture_load.cpp # NEW
│ └── gl_texture_load.md # NEW
└── apps/primitives_gallery/
├── demos_gl_texture.cpp # NEW
├── demos.h # MOD
├── main.cpp # MOD
└── CMakeLists.txt # MOD
cpp/CMakeLists.txt # MOD
```
### Pure core / impure shell
Funcion **impura** (`purity: impure`, `kind: function`): hace I/O de disco + crea recurso GPU.
### API propuesta
```cpp
namespace fn {
struct GlTexture {
GLuint id = 0;
int w = 0;
int h = 0;
int channels = 0;
bool ok() const { return id != 0; }
};
// Carga desde disco (PNG/JPG/BMP/TGA via stb_image, HDR como float opcional).
// flip_y por defecto true para coincidir con UV de OpenGL.
// Devuelve GlTexture con id=0 si falla; usar gl_texture_last_error() para detalle.
GlTexture gl_texture_load(const char* path, bool flip_y = true, bool srgb = false);
GlTexture gl_texture_load_from_memory(const unsigned char* data, int size, bool flip_y = true, bool srgb = false);
void gl_texture_destroy(GlTexture& tex);
const char* gl_texture_last_error();
// Helper: bind a una texture unit y subir uniform sampler.
void gl_texture_bind_uniform(GLuint program, const char* name, const GlTexture& tex, int unit);
}
```
## Tareas
### Fase 1 — Vendor stb_image
- 1.1 Descargar `stb_image.h` (commit estable) a `cpp/vendor/stb/`. Crear `cpp/vendor/stb/stb_image_impl.cpp` con `#define STB_IMAGE_IMPLEMENTATION` antes del include, para evitar emitir el cuerpo en multiples TUs.
- 1.2 Añadirlo a `cpp/CMakeLists.txt` global.
### Fase 2 — gl_texture_load
- 2.1 Implementar `gl_texture_load.h/.cpp`. Usar `glGenTextures` + `glTexImage2D`. Filtros LINEAR_MIPMAP_LINEAR + LINEAR. Generar mipmaps con `glGenerateMipmap`.
- 2.2 Soporte para `srgb=true` (`GL_SRGB8_ALPHA8` como internal format).
- 2.3 Soporte HDR: si extension es `.hdr`, usar `stbi_loadf` y `GL_RGBA16F`.
- 2.4 `gl_texture_load.md` con frontmatter (`kind: function`, `purity: impure`, `error_type`, `uses_functions: [gl_loader_cpp_gfx]`).
### Fase 3 — Gallery demo
- 3.1 `demos_gl_texture.cpp` con `demo_gl_texture_load()`: carga `assets/sample.png` (un PNG de prueba, ej. patron damero). Renderiza un fullscreen quad con un shader que samplea la textura y aplica tint via uniforms. ImGui::Image con thumbnail al lado y info (w, h, channels).
- 3.2 Añadir `assets/sample.png` (256x256, ~10KB).
- 3.3 Registrar en `demos.h`, `main.cpp`, `CMakeLists.txt`.
### Fase 4 — Tests + docs
- 4.1 Test que carga un PNG embebido (in-memory) y verifica `tex.ok() && tex.w == ...`.
- 4.2 `./fn index` y verificar via `fn show gl_texture_load_cpp_gfx`.
## Ejemplo de uso
```cpp
auto tex = fn::gl_texture_load("assets/noise.png");
if (!tex.ok()) {
std::fprintf(stderr, "error: %s\n", fn::gl_texture_last_error());
return 1;
}
glUseProgram(prog);
fn::gl_texture_bind_uniform(prog, "u_noise", tex, 0); // unit 0
glDrawArrays(GL_TRIANGLES, 0, 6);
```
## Decisiones de diseño
- **Vendoreado en `cpp/vendor/stb/`** sigue el patron actual de ImGui/ImPlot.
- **`flip_y=true` por defecto** porque la convencion en GLSL es V hacia arriba.
- **`srgb` opcional** — para texturas LDR de color, `GL_SRGB8_ALPHA8` da un gamma correcto sin tener que `pow(color, 2.2)` en el shader.
## Riesgos
- **Tamaño de imagenes**: cargar PNGs de 4K consume RAM/VRAM. Documentar limite practico (<= 8192 lado).
- **Driver no soporta sRGB**: documentar fallback a `GL_RGBA8`.
- **Codigo de stb_image lento**: aceptable para uso interactivo (no es hot path de cada frame).