#include "mesh.h" #include "vertex.h" #include "mikktspace.h" #include #include 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); }