fce88032ca
- .mcp.json - bash/functions/infra/write_mcp_jupyter_config.md - bash/functions/infra/write_mcp_jupyter_config.sh - cpp/CMakeLists.txt - cpp/apps/chart_demo - cpp/apps/shaders_lab - cpp/functions/gfx/gl_framebuffer.cpp - cpp/functions/gfx/gl_framebuffer.h - cpp/functions/gfx/gl_framebuffer.md - cpp/functions/gfx/mesh_gpu.md - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.6 KiB
4.6 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, tested, tests, test_file_path, file_path, framework, params, output, notes
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | tested | tests | test_file_path | file_path | framework | params | output | notes | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| gltf_load_mesh | function | cpp | gfx | 1.0.0 | impure | Mesh gltf_load_mesh_from_file(const char* path); Mesh gltf_load_mesh_from_memory(const unsigned char* data, size_t size); const char* gltf_load_last_error() | Parser GLB 2.0 (glTF binario): carga el primer mesh/primitive a CPU como fn::gfx::Mesh. Soporta POSITION+NORMAL (vec3 float), indices ubyte/ushort/uint, node transform TRS/matrix. Genera normales smooth area-weighted si faltan. Sin dependencias externas — BIN chunk + nlohmann JSON vendored. |
|
false | error_go_core |
|
true |
|
cpp/tests/test_gltf_load_mesh.cpp | cpp/functions/gfx/gltf_load_mesh.cpp | opengl |
|
fn::gfx::Mesh con positions/normals (stride 3, mismo length) y indices uint32 (tri-list). Mesh vacio (positions.empty()==true) si parse falla. gltf_load_last_error() devuelve descripcion del error. | Usa fn::gfx::Mesh de mesh_obj_load.h — mismo struct que consume mesh_gpu_upload(). nlohmann vendored en cpp/vendor/nlohmann/json.hpp. El parser no aloca heap mas alla del Mesh de salida + JSON temporal. gltf_load_last_error() usa thread_local — seguro en multihilo siempre que cada hilo llame sus propias funciones. |
gltf_load_mesh
Loader GLB 2.0 minimal para el registry. Parsea el contenedor GLB binario a mano (header 12 bytes + chunks JSON + BIN) usando nlohmann para el JSON. KISS: sin tinygltf ni dependencias extra.
Ejemplo
// Cargar .glb generado por TripoSR/trimesh y subir a GPU:
#include "gfx/gltf_load_mesh.h"
#include "gfx/mesh_gpu.h"
auto cpu = fn::gfx::gltf_load_mesh_from_file("model.glb");
if (cpu.positions.empty()) {
fprintf(stderr, "gltf load failed: %s\n", fn::gfx::gltf_load_last_error());
return;
}
// Subir a GPU (requiere contexto GL activo):
auto gpu = fn::gfx::mesh_gpu_upload(cpu);
if (!gpu.ok()) { /* fallo de upload GL */ return; }
glUseProgram(prog);
glBindVertexArray(gpu.vao);
glDrawElements(GL_TRIANGLES, gpu.index_count, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
fn::gfx::mesh_gpu_destroy(gpu);
// Desde memoria (ej. respuesta HTTP o embedding):
std::vector<unsigned char> glb_buf = download_glb(...);
auto cpu = fn::gfx::gltf_load_mesh_from_memory(glb_buf.data(), glb_buf.size());
Cuando usarla
Cuando recibes un .glb (binario glTF 2.0) de un backend Python (TripoSR,
trimesh, open3d) y necesitas renderizarlo en una app ImGui via mesh_gpu_upload.
Tambien util para inspeccionar geometria en CPU sin subir a GPU.
Limitaciones
- Solo GLB binario.
.gltf + .binseparado: no soportado. Data URIs base64: no soportados. - Primer mesh, primera primitive. Archivos con multiples meshes o materiales: solo se carga el primero.
- Sin texturas ni materiales. El Mesh solo contiene geometria (posicion + normal). El shader del viewer usa color uniforme.
- Buffer unico embebido (chunk BIN). Referencias a buffers externos: no soportadas.
- Modo solo triangulos (
"mode": 4, default). Puntos, lineas, triangle-strip: no soportados.
Gotchas
gltf_load_last_error()esthread_local. Si usas multihilo, cada hilo tiene su propio error buffer — no compartas el puntero entre hilos.- El puntero que devuelve
gltf_load_last_error()se sobreescribe en la siguiente llamada agltf_load_mesh_from_*. Copia el string si lo necesitas despues. - Un
Meshretornado conpositions.empty() == truees la senal de fallo — no lanzamos excepciones. - Para archivos grandes (>50 MB) la lectura es un
std::vector<uint8_t>completo en memoria. Para streaming, usagltf_load_mesh_from_memorycon tu propio buffer. - El parser no valida que
indicessean menores quenven cada vertice — indices fuera de rango se saltan silenciosamente durante la generacion de normales pero pueden producir geometria incorrecta.