--- name: mesh_gpu kind: function lang: cpp domain: gfx version: "1.0.0" purity: impure signature: "MeshGpu mesh_gpu_upload(const Mesh&); void mesh_gpu_destroy(MeshGpu&)" description: "Sube un Mesh CPU a OpenGL como VAO + VBO interleaved (pos.xyz, normal.xyz) + EBO uint32. Layout: location 0 = a_pos vec3, location 1 = a_normal vec3, stride 6 floats." tags: [opengl, mesh, vao, vbo, ebo, gpu, gfx] uses_functions: ["gl_loader_cpp_gfx", "mesh_obj_load_cpp_gfx"] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [GL/gl.h, GL/glext.h] tested: false tests: [] test_file_path: "" file_path: "cpp/functions/gfx/mesh_gpu.cpp" framework: opengl params: - name: mesh desc: "Mesh CPU con positions/normals (mismo length, stride 3) e indices uint32. Si esta vacio o invalido, upload devuelve MeshGpu{} (ok()==false)." - name: mesh_gpu desc: "MeshGpu (vao/vbo/ebo, index_count). destroy libera todo y pone IDs a 0." output: "mesh_gpu_upload: MeshGpu listo para draw con glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, 0). Si !ok(), no hubo upload." --- # mesh_gpu CRUD GPU minimal para `Mesh`. Asume contexto OpenGL 3.3+ activo. ## Layout de attribs ```glsl #version 330 core layout(location = 0) in vec3 a_pos; layout(location = 1) in vec3 a_normal; ``` Stride = `6 * sizeof(float)`, sin padding. ## Uso tipico ```cpp auto cpu = fn::gfx::mesh_obj_load("model.obj"); auto gpu = fn::gfx::mesh_gpu_upload(cpu); if (!gpu.ok()) { /* falla */ return; } // Draw: glUseProgram(prog); glBindVertexArray(gpu.vao); glDrawElements(GL_TRIANGLES, gpu.index_count, GL_UNSIGNED_INT, 0); glBindVertexArray(0); // Cleanup: fn::gfx::mesh_gpu_destroy(gpu); ``` ## Validacion de input `mesh_gpu_upload` exige que `mesh.normals.size() == mesh.positions.size()`. `mesh_obj_parse` siempre genera normales (per-face si faltan) → invariante natural. ## Notas - Indices son `GL_UNSIGNED_INT` (32-bit) para soportar meshes grandes sin tener que decidir formato dinamicamente. - `GL_STATIC_DRAW`: el assumption es que la malla no cambia post-upload. Si necesitas streaming, crear otro helper con `GL_DYNAMIC_DRAW`.