diff options
Diffstat (limited to 'model.h')
| -rw-r--r-- | model.h | 281 |
1 files changed, 43 insertions, 238 deletions
@@ -1,246 +1,51 @@ -#define TINYOBJ_LOADER_C_IMPLEMENTATION -#include "tinyobj_loader_c.h" +#ifndef model_h +#define model_h -mat4 apply_transform(transform_t transform) -{ - mat4 result = mat4_make_scale(transform.scale); - result = mat4_rotate(result, transform.rotation); - result = mat4_transl(result, transform.position); - return result; -} +#include "prbm.h" +#include "arena.h" -void init_mesh_buffers(mesh_t *mesh) -{ - assert(mesh->vertices); - assert(mesh->nvertices > 0); +#define pos_loc 0 +#define norm_loc 1 +#define texc_loc 2 - u32 vertices_size = mesh->nvertices*sizeof(vertex_t); - u32 indices_size = mesh->nindices*sizeof(u32); +#define proj_matrix_name "proj" +#define view_matrix_name "view" +#define model_matrix_name "model" - glGenVertexArrays(1, &mesh->vao); - glBindVertexArray(mesh->vao); +struct vertex { + v3 pos; + v3 norm; + v2 texc; +}; - glGenBuffers(1, &mesh->vbo); - glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); - glBufferData(GL_ARRAY_BUFFER, vertices_size, mesh->vertices, GL_STATIC_DRAW); +struct mesh { + v3 pos; + v3 angles; + v3 scale; + i32 nvertices; + struct vertex *vertices; + i32 nindices; + u32 *indices; + struct texture *texture; + u32 vao; + u32 vbo; + u32 ebo; +}; - if (mesh->indices && (mesh->nindices > 0)) { - glGenBuffers(1, &mesh->ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_size, mesh->indices, GL_STATIC_DRAW); - } +struct model { + v3 pos; + v3 angles; + v3 scale; + i32 nmeshes; + struct mesh *meshes; +}; - glEnableVertexAttribArray(SHADER_POSITION_LOCATION); - glVertexAttribPointer(SHADER_POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, - sizeof(vertex_t), (void *)offsetof(vertex_t, position)); +mat get_model_matrix(v3 pos, v3 angles, v3 scale); +struct mesh init_mesh(v3 pos, v3 angles, v3 scale, + i32 nvertices, struct vertex *vertices, + i32 nindices, u32 *indices, struct texture *texture); +void clear_mesh(struct mesh *mesh); +struct mesh gen_quad(struct arena *arena, v3 pos, v3 angles, v3 scale, f32 width, f32 height); +struct model init_model(v3 pos, v3 angles, v3 scale, i32 nmeshes, struct mesh *meshes); - glEnableVertexAttribArray(SHADER_NORMAL_LOCATION); - glVertexAttribPointer(SHADER_NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, - sizeof(vertex_t), (void *)offsetof(vertex_t, normal)); - - glEnableVertexAttribArray(SHADER_TEXCOORDS_LOCATION); - glVertexAttribPointer(SHADER_TEXCOORDS_LOCATION, 2, GL_FLOAT, GL_FALSE, - sizeof(vertex_t), (void *)offsetof(vertex_t, texcoords)); - - glBindVertexArray(0); -} - -mesh_t init_mesh(transform_t transform, i32 nvertices, vertex_t *vertices, i32 nindices, u32 *indices) -{ - mesh_t mesh = {0}; - mesh.transform = transform; - mesh.nvertices = nvertices; - mesh.vertices = vertices; - mesh.nindices = nindices; - mesh.indices = indices; - init_mesh_buffers(&mesh); - return mesh; -} - -void clear_mesh(mesh_t *mesh) -{ - glBindVertexArray(mesh->vao); - glDisableVertexAttribArray(SHADER_POSITION_LOCATION); - glDisableVertexAttribArray(SHADER_NORMAL_LOCATION); - glDisableVertexAttribArray(SHADER_TEXCOORDS_LOCATION); - - glBindVertexArray(0); - glDeleteVertexArrays(1, &mesh->vao); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glDeleteBuffers(1, &mesh->vbo); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDeleteBuffers(1, &mesh->ebo); -} - -void add_mesh_texture(mesh_t *mesh, texture_t texture) -{ - if (!mesh) { - printf("error: can't add texture to a null mesh :|\n"); - return; - } - - if (mesh->ntextures+1 >= MAX_TEXTURE_PER_MESH) { - printf("warning: \"%s\" texture limit reached: %d\n", texture.name, MAX_TEXTURE_PER_MESH); - return; - } - - mesh->textures[mesh->ntextures++] = texture; -} - -mesh_t gen_quad_mesh(arena_t *arena, transform_t transform, f32 width, f32 height) -{ - assert(width > 0); - assert(height > 0); - - i32 nvertices = 4; - vertex_t *vertices = push_arena(arena, nvertices*sizeof(vertex_t)); - vertices[0] = (vertex_t){{-width/2.0f, -height/2.0f, 0.0f}, V3_ZERO, {0.0f, 0.0f}}; - vertices[1] = (vertex_t){{-width/2.0f, height/2.0f, 0.0f}, V3_ZERO, {0.0f, height}}; - vertices[2] = (vertex_t){{ width/2.0f, -height/2.0f, 0.0f}, V3_ZERO, {width, 0.0f}}; - vertices[3] = (vertex_t){{ width/2.0f, height/2.0f, 0.0f}, V3_ZERO, {width, height}}; - - i32 nindices = 6; - u32 *indices = push_arena(arena, nindices*sizeof(u32)); - indices[0] = 0; - indices[1] = 1; - indices[2] = 3; - indices[3] = 0; - indices[4] = 2; - indices[5] = 3; - - mesh_t mesh = init_mesh(transform, nvertices, vertices, nindices, indices); - - return mesh; -} - -mesh_t gen_circle_mesh(arena_t *arena, transform_t transform, f32 radius, i32 nvertices) -{ - if (nvertices < 3) - nvertices = 3; - - vertex_t *vertices = push_arena(arena, nvertices*sizeof(vertex_t)); - - f32 angle = 0.0f; - f32 dangle = 2.0f*F_PI/nvertices; - for (i32 i = 0; i < nvertices; ++i, angle += dangle) - vertices[i] = (vertex_t){{cosf(angle)*radius, sinf(angle)*radius, 0.0f}, V3_ZERO, V2_ZERO}; - - i32 nindices = nvertices*3; - u32 *indices = push_arena(arena, nindices*sizeof(u32)); - for (i32 i = 0, vi = 1; i < nindices; i += 3, vi++) { - indices[i] = 0; - indices[i+1] = vi; - indices[i+2] = ((vi+1 == nvertices) ? 1 : vi+1); - } - - mesh_t mesh = init_mesh(transform, nvertices, vertices, nindices, indices); - - return mesh; -} - -model_t init_model(transform_t transform, i32 nmeshes, mesh_t *meshes) -{ - model_t model = { - transform, - nmeshes, - meshes, - }; - return model; -} - -void read_file_tinyobj(void* ctx, const char* filename, const i32 is_mtl, const char* obj_filename, char** data, u64* len) -{ - if (is_mtl) - printf("info: is_mtl is set (don't use it right now)\n"); - if (obj_filename) - printf("info: obj_filename is \"%s\"\n", obj_filename); - if (!filename) { - printf("error: obj filename is zero\n"); - *data = 0; - *len = 0; - return; - } - - arena_t *arena = (arena_t *)ctx; - *len = sys_read_file(arena, data, filename); -} - -model_t load_model_obj(arena_t *arena, transform_t transform, const char *filename) -{ - tinyobj_attrib_t attrib; - u64 nshapes; - tinyobj_shape_t *shapes; - u64 nmaterials; - tinyobj_material_t *materials; - - u32 flags = TINYOBJ_FLAG_TRIANGULATE; - i32 status = tinyobj_parse_obj(&attrib, &shapes, &nshapes, &materials, &nmaterials, - filename, read_file_tinyobj, arena, flags); - - model_t model = {0}; - if (status != TINYOBJ_SUCCESS) { - printf("error: failed to parse \"%s\"\n", filename); - return model; - } - - u64 ntriangles = attrib.num_face_num_verts; - u64 face_offset = 0; - - u64 nvertices = ntriangles*3; - vertex_t *vertices = push_arena(arena, sizeof(vertex_t)*nvertices); - - u64 nindices = ntriangles*3; - u32 *indices = push_arena(arena, sizeof(u32)*nindices); - - i32 vertex_count = 0, index_count = 0, index_index = 0; - for (u32 i = 0; i < attrib.num_face_num_verts; ++i) { - assert(attrib.face_num_verts[i]%3 == 0); - assert(attrib.face_num_verts[i]/3 > 0); - assert(attrib.num_texcoords); - - tinyobj_vertex_index_t idx; - for (i32 j = 0; j < 3; ++j) { - idx = attrib.faces[face_offset+j]; - assert(idx.v_idx >= 0); - v3 position = { - attrib.vertices[3*idx.v_idx+0], - attrib.vertices[3*idx.v_idx+1], - attrib.vertices[3*idx.v_idx+2] - }; - - assert(idx.vn_idx < (i32)attrib.num_normals); - v3 normal = { - attrib.normals[3*idx.vn_idx+0], - attrib.normals[3*idx.vn_idx+1], - attrib.normals[3*idx.vn_idx+2] - }; - - assert(idx.vt_idx < (i32)attrib.num_texcoords); - v2 texcoords = { - attrib.texcoords[2*idx.vt_idx+0], - attrib.texcoords[2*idx.vt_idx+1] - }; - - vertices[vertex_count++] = (vertex_t){position, normal, texcoords}; - indices[index_index++] = index_count++; - } - - face_offset += 3; - } - - i32 nmeshes = 1; - mesh_t *meshes = push_arena(arena, sizeof(mesh_t)*nmeshes); - *meshes = init_mesh(DEFAULT_TRANSFORM, nvertices, vertices, nindices, indices); - - tinyobj_attrib_free(&attrib); - tinyobj_shapes_free(shapes, nshapes); - tinyobj_materials_free(materials, nmaterials); - - model = init_model(transform, nmeshes, meshes); - - printf("info: \"%s\" loaded successfully\n", filename); - - return model; -} +#endif |
