#include "Mesh.h" #include "../vendor/loaders/tinyobj.h" #include "../os.h" static void tinyobj_get_filedata(void* ctx, const char* filename, const int is_mtl, const char* obj_filename, char** data, size_t* len) { string file = os_readEntireFile((Arena *)ctx, s("./assets/models/cube.obj")); *data = file.str; *len = file.length; } DefineList(uint32, MeshIndex); DefineList(real32, MeshValue); Mesh createMesh(const char* obj_file) { Scratch temp = scratchStart(0, 0); Mesh result = {0}; tinyobj_attrib_t attrib; tinyobj_shape_t* shapes = NULL; size_t num_shapes; tinyobj_material_t* materials = NULL; size_t num_materials; int success = tinyobj_parse_obj( &attrib, &shapes, &num_shapes, &materials, &num_materials, obj_file, tinyobj_get_filedata, (void *)temp.arena, TINYOBJ_FLAG_TRIANGULATE ); if (success != TINYOBJ_SUCCESS || num_shapes <= 0) { print("Failed to load obj from '%s'! Success %i\n", obj_file, success); return result; } MeshIndexList indices = PushFullList(temp.arena, MeshIndexList, attrib.num_faces); MeshValueList vertices = PushFullList(temp.arena, MeshValueList, 3*attrib.num_faces); MeshValueList normals = PushFullList(temp.arena, MeshValueList, 3*attrib.num_faces); MeshValueList texcoords = PushFullList(temp.arena, MeshValueList, 2*attrib.num_faces); for (int i = 0; i < attrib.num_faces; i++) { tinyobj_vertex_index_t vertex_data = attrib.faces[i]; vertices.data[3*i] = attrib.vertices[3*vertex_data.v_idx]; vertices.data[3*i+1] = attrib.vertices[3*vertex_data.v_idx + 1]; vertices.data[3*i+2] = attrib.vertices[3*vertex_data.v_idx + 2]; normals.data[3*i] = attrib.normals[3*vertex_data.vn_idx]; normals.data[3*i+1] = attrib.normals[3*vertex_data.vn_idx + 1]; normals.data[3*i+2] = attrib.normals[3*vertex_data.vn_idx + 2]; texcoords.data[2*i] = attrib.texcoords[2*vertex_data.vt_idx]; texcoords.data[2*i+1] = attrib.texcoords[2*vertex_data.vt_idx + 1]; indices.data[i] = i; } result.num_indices = attrib.num_faces*3; glGenVertexArrays(1, &result.vao); glGenBuffers(3, result.vbos); glBindVertexArray(result.vao); glBindBuffer(GL_ARRAY_BUFFER, result.buffers.xyz); glBufferData(GL_ARRAY_BUFFER, vertices.length * sizeof(real32), vertices.data, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(real32), (void*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, result.buffers.uv); glBufferData(GL_ARRAY_BUFFER, texcoords.length * sizeof(real32), texcoords.data, GL_STATIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(real32), (void*)0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, result.buffers.normals); glBufferData(GL_ARRAY_BUFFER, normals.length * sizeof(real32), normals.data, GL_STATIC_DRAW); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(real32), (void*)0); glEnableVertexAttribArray(2); //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); //glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW); scratchEnd(temp); return result; } Mesh createMeshFromShape(const Shape* shape) { Mesh result = {0}; result.num_indices = shape->indices.length; glGenVertexArrays(1, &result.vao); glGenBuffers(3, result.vbos); glBindVertexArray(result.vao); glBindBuffer(GL_ARRAY_BUFFER, result.buffers.xyz); glBufferData(GL_ARRAY_BUFFER, shape->xyz.length * sizeof(float), shape->xyz.data, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, result.buffers.uv); glBufferData(GL_ARRAY_BUFFER, shape->uv.length * sizeof(real32), shape->uv.data, GL_STATIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(real32), (void*)0); glEnableVertexAttribArray(1); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.buffers.elements); glBufferData(GL_ELEMENT_ARRAY_BUFFER, shape->indices.length * sizeof(uint32), shape->indices.data, GL_STATIC_DRAW); return result; }