diff options
Diffstat (limited to 'mons_3d/src/mesh.c')
-rw-r--r-- | mons_3d/src/mesh.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/mons_3d/src/mesh.c b/mons_3d/src/mesh.c new file mode 100644 index 0000000..213a24c --- /dev/null +++ b/mons_3d/src/mesh.c @@ -0,0 +1,124 @@ +#include "mesh.h" +#include "vertex.h" +#include "mikktspace.h" + +#include <glad/gl.h> +#include <stdlib.h> + +void compute_tangents(mons_vertex *vertex_array, int vertex_count, int *index_array, int index_count); + +mons_mesh mons_create_mesh(mons_vertex *vertex_array, int vertex_count, int *index_array, int index_count) { + compute_tangents(vertex_array, vertex_count, index_array, index_count); + // VAO & VBO + unsigned int vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + unsigned int vbo; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(mons_vertex) * vertex_count, vertex_array, GL_STATIC_DRAW); + unsigned int ebo; + glGenBuffers(1, &ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * index_count, index_array, GL_STATIC_DRAW); + // Set up vertex attributes + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(mons_vertex), 0); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(mons_vertex), (void*)(sizeof(mons_vec3))); + glEnableVertexAttribArray(1); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(mons_vertex), (void*)(sizeof(mons_vec3) * 2)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(mons_vertex), (void*)(sizeof(mons_vec3) * 2 + sizeof(mons_vec4))); + glEnableVertexAttribArray(3); + return (mons_mesh) { + .vao = vao, + .element_count = index_count, + }; +} + +struct mesh_data { + mons_vertex *vertex_array; + int vertex_count; + int *index_array; + int index_count; +}; + +int get_vertex_index(const SMikkTSpaceContext *context, int i_face, int i_vert) { + struct mesh_data *mesh_data = context->m_pUserData; + int index_index = (i_face * 3) + i_vert; + int index = mesh_data->index_array[index_index]; + return index; +} + +int get_num_faces(const SMikkTSpaceContext *context) { + struct mesh_data *mesh_data = context->m_pUserData; + return mesh_data->index_count / 3; +} + +int get_num_vertices_of_face(const SMikkTSpaceContext *context, int i_face) { + return 3; +} + +void get_position(const SMikkTSpaceContext *context, float *outpos, int i_face, int i_vert) { + struct mesh_data *mesh_data = context->m_pUserData; + int index = get_vertex_index(context, i_face, i_vert); + mons_vertex vertex = mesh_data->vertex_array[index]; + + outpos[0] = vertex.position.x; + outpos[1] = vertex.position.y; + outpos[2] = vertex.position.z; +} + +void get_normal(const SMikkTSpaceContext *context, float *outnormal, int i_face, int i_vert) { + struct mesh_data *mesh_data = context->m_pUserData; + int index = get_vertex_index(context, i_face, i_vert); + mons_vertex vertex = mesh_data->vertex_array[index]; + + outnormal[0] = vertex.normal.x; + outnormal[1] = vertex.normal.y; + outnormal[2] = vertex.normal.z; +} + +void get_tex_coords(const SMikkTSpaceContext *context, float *outuv, int i_face, int i_vert) { + struct mesh_data *mesh_data = context->m_pUserData; + int index = get_vertex_index(context, i_face, i_vert); + mons_vertex vertex = mesh_data->vertex_array[index]; + + outuv[0] = vertex.texture_coords.x; + outuv[1] = vertex.texture_coords.y; +} + +void set_tspace_basic(const SMikkTSpaceContext *context, const float *tangentu, float f_sign, int i_face, int i_vert) { + struct mesh_data *mesh_data = context->m_pUserData; + int index = get_vertex_index(context, i_face, i_vert); + mons_vertex *vertex = &mesh_data->vertex_array[index]; + + vertex->tangent.x = tangentu[0]; + vertex->tangent.y = tangentu[1]; + vertex->tangent.z = tangentu[2]; + vertex->tangent.w = f_sign; +} + +void compute_tangents(mons_vertex *vertex_array, int vertex_count, int *index_array, int index_count) { + static SMikkTSpaceInterface iface = { + .m_getNumFaces = get_num_faces, + .m_getNumVerticesOfFace = get_num_vertices_of_face, + .m_getNormal = get_normal, + .m_getPosition = get_position, + .m_getTexCoord = get_tex_coords, + .m_setTSpaceBasic = set_tspace_basic, + }; + struct mesh_data mesh_data = { + vertex_array, + vertex_count, + index_array, + index_count, + }; + SMikkTSpaceContext context = { + .m_pInterface = &iface, + .m_pUserData = &mesh_data, + }; + + genTangSpaceDefault(&context); +} + |