summaryrefslogtreecommitdiff
path: root/model.h
diff options
context:
space:
mode:
Diffstat (limited to 'model.h')
-rw-r--r--model.h281
1 files changed, 43 insertions, 238 deletions
diff --git a/model.h b/model.h
index 083023d..c114b5e 100644
--- a/model.h
+++ b/model.h
@@ -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