Files
fn_registry/cpp/functions/gfx/mesh_gpu.cpp
T
egutierrez c5dc63699a feat(gfx): mesh_gpu — VAO/VBO/EBO upload para Mesh
mesh_gpu_upload sube positions+normals interleaved (stride 6 floats,
location 0=a_pos, location 1=a_normal) + EBO uint32. mesh_gpu_destroy
libera todo. GL_STATIC_DRAW (mesh inmutable post-upload).

issue 0029
2026-04-25 21:51:10 +02:00

70 lines
2.2 KiB
C++

#include "gfx/mesh_gpu.h"
#include <vector>
namespace fn::gfx {
MeshGpu mesh_gpu_upload(const Mesh& mesh) {
MeshGpu g{};
if (mesh.positions.empty() || mesh.indices.empty()) return g;
if (mesh.normals.size() != mesh.positions.size()) return g;
const size_t nverts = mesh.positions.size() / 3;
// Interleave pos.xyz + normal.xyz, stride 6 floats.
std::vector<float> interleaved;
interleaved.resize(nverts * 6);
for (size_t i = 0; i < nverts; ++i) {
interleaved[i*6 + 0] = mesh.positions[i*3 + 0];
interleaved[i*6 + 1] = mesh.positions[i*3 + 1];
interleaved[i*6 + 2] = mesh.positions[i*3 + 2];
interleaved[i*6 + 3] = mesh.normals[i*3 + 0];
interleaved[i*6 + 4] = mesh.normals[i*3 + 1];
interleaved[i*6 + 5] = mesh.normals[i*3 + 2];
}
glGenVertexArrays(1, &g.vao);
glGenBuffers(1, &g.vbo);
glGenBuffers(1, &g.ebo);
glBindVertexArray(g.vao);
glBindBuffer(GL_ARRAY_BUFFER, g.vbo);
glBufferData(GL_ARRAY_BUFFER,
(GLsizeiptr)(interleaved.size() * sizeof(float)),
interleaved.data(),
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g.ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
(GLsizeiptr)(mesh.indices.size() * sizeof(uint32_t)),
mesh.indices.data(),
GL_STATIC_DRAW);
// location 0 = a_pos (vec3)
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
(GLsizei)(6 * sizeof(float)),
(const void*)0);
// location 1 = a_normal (vec3)
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
(GLsizei)(6 * sizeof(float)),
(const void*)(3 * sizeof(float)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
g.index_count = (int)mesh.indices.size();
return g;
}
void mesh_gpu_destroy(MeshGpu& g) {
if (g.ebo) { glDeleteBuffers(1, &g.ebo); g.ebo = 0; }
if (g.vbo) { glDeleteBuffers(1, &g.vbo); g.vbo = 0; }
if (g.vao) { glDeleteVertexArrays(1, &g.vao); g.vao = 0; }
g.index_count = 0;
}
} // namespace fn::gfx