117 lines
4.3 KiB
C
117 lines
4.3 KiB
C
#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;
|
|
}
|
|
|