#include #include "gl.h" void mesh_init(Mesh *mesh, u32 vertex_count) { glGenVertexArrays(1, &mesh->vao); mesh->vbos_count = 0; mesh->vertex_count = vertex_count; glBindVertexArray(mesh->vao); } static void mesh_store(Mesh *mesh, void *data, u32 len, u32 dimensions, GLenum type) { GLuint vbo; GLint index = mesh->vbos_count; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, len, data, GL_STATIC_DRAW); glEnableVertexAttribArray(index); if (type == GL_FLOAT) glVertexAttribPointer(index, dimensions, type, GL_FALSE, 0, 0); else glVertexAttribIPointer(index, dimensions, type, 0, 0); mesh->vbos[mesh->vbos_count++] = vbo; } void mesh_store_float(Mesh *mesh, float *data, u32 count, u32 dimensions) { mesh_store(mesh, data, count * sizeof(float), dimensions, GL_FLOAT); } void mesh_store_i32(Mesh *mesh, i32 *data, u32 count, u32 dimensions) { mesh_store(mesh, data, count * sizeof(i32), dimensions, GL_INT); } void mesh_store_u8(Mesh *mesh, u8 *data, u32 count, u32 dimensions) { mesh_store(mesh, data, count * sizeof(u8), dimensions, GL_UNSIGNED_BYTE); } void mesh_store_u32(Mesh *mesh, u32 *data, u32 count, u32 dimensions) { mesh_store(mesh, data, count * sizeof(u32), dimensions, GL_UNSIGNED_INT); } void mesh_finish(void) { glBindVertexArray(0); } void mesh_bind(Mesh *mesh) { glBindVertexArray(mesh->vao); for (int i = 0; i < mesh->vbos_count; i++) glEnableVertexAttribArray(i); } void mesh_unbind(Mesh *mesh) { for (int i = 0; i < mesh->vbos_count; i++) glDisableVertexAttribArray(i); glBindVertexArray(0); } void mesh_draw(Mesh *mesh) { glDrawArrays(GL_TRIANGLES, 0, mesh->vertex_count); } void mesh_draw_instanced(Mesh *mesh, u32 count) { glDrawArraysInstanced(GL_TRIANGLES, 0, mesh->vertex_count, count); } void mesh_free(Mesh *mesh) { glDeleteBuffers(mesh->vbos_count, mesh->vbos); glDeleteVertexArrays(1, &mesh->vao); } void uniform_init(Uniform *uniform, u32 len) { uniform->len = len; glGenBuffers(1, &uniform->id); glBindBuffer(GL_UNIFORM_BUFFER, uniform->id); glBufferData(GL_UNIFORM_BUFFER, len, NULL, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } void uniform_store(Uniform *uniform, u32 offset, u32 len, void *data) { glBindBuffer(GL_UNIFORM_BUFFER, uniform->id); glBufferSubData(GL_UNIFORM_BUFFER, offset, len, data); glBindBuffer(GL_UNIFORM_BUFFER, 0); } void uniform_bind(Uniform *uniform, u32 binding) { glBindBufferBase(GL_UNIFORM_BUFFER, binding, uniform->id); } void uniform_unbind(u32 binding) { glBindBufferBase(GL_UNIFORM_BUFFER, binding, 0); } void uniform_free(Uniform *uniform) { glDeleteBuffers(1, &uniform->id); }