Vertex init_vert(V3 pos, V2 texc) { Vertex v = { .pos = pos, .texc = texc, }; return v; } void init_mesh_buffers(Mesh *mesh) { ASSERT(mesh->verts); ASSERT(mesh->nverts > 0); U32 sverts, sindices; sverts = mesh->nverts*sizeof(Vertex); sindices = mesh->nindices*sizeof(U32); glGenVertexArrays(1, &mesh->vao); glBindVertexArray(mesh->vao); glGenBuffers(1, &mesh->vbo); glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); glBufferData(GL_ARRAY_BUFFER, sverts, mesh->verts, GL_STATIC_DRAW); if (mesh->indices && (mesh->nindices > 0)) { glGenBuffers(1, &mesh->ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sindices, mesh->indices, GL_STATIC_DRAW); } glEnableVertexAttribArray(PRGE_SHADER_POS_LOC); glVertexAttribPointer(PRGE_SHADER_POS_LOC, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)OFFSETOF(Vertex, pos)); glEnableVertexAttribArray(PRGE_SHADER_TEXC_LOC); glVertexAttribPointer(PRGE_SHADER_TEXC_LOC, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)OFFSETOF(Vertex, texc)); glBindVertexArray(0); } Mesh init_mesh(V3 origin, V3 rotate, S32 nverts, Vertex *verts, S32 nindices, U32 *indices) { Mesh mesh; MEM0STRUCT(&mesh); mesh.origin = origin; mesh.rotate = rotate; mesh.verts = verts; mesh.nverts = nverts; mesh.indices = indices; mesh.nindices = nindices; init_mesh_buffers(&mesh); return mesh; } void clear_mesh(Mesh *mesh) { glBindVertexArray(mesh->vao); glDisableVertexAttribArray(PRGE_SHADER_POS_LOC); 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 *mesh, Texture texture) { if (mesh->ntextures+1 >= PRGE_MAX_TEXTURES) { sys_printf("[WARNING] : Texture : \"%s\" : limit\n", texture.name); return; } mesh->textures[mesh->ntextures++] = texture; } Mesh gen_quad(Arena *arena, V3 origin, V3 rotate, F32 w, F32 h) { Mesh mesh; S32 nverts; Vertex *verts; S32 nindices; U32 *indices; ASSERT(w > 0); ASSERT(h > 0); nverts = 4; verts = push_arena(arena, nverts*sizeof(Vertex)); verts[0] = init_vert(v3(-w/2.0f, -h/2.0f, 0.0f), v2(0.0f, 0.0f)); verts[1] = init_vert(v3(-w/2.0f, h/2.0f, 0.0f), v2(0.0f, h)); verts[2] = init_vert(v3(w/2.0f, -h/2.0f, 0.0f), v2(w, 0.0f)); verts[3] = init_vert(v3(w/2.0f, h/2.0f, 0.0f), v2(w, h)); nindices = 6; 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 = init_mesh(origin, rotate, nverts, verts, nindices, indices); return mesh; } Mesh gen_circle(Arena *arena, V3 origin, V3 rotate, F32 r, S32 nverts) { Mesh mesh; Vertex *verts; S32 nindices; U32 *indices; F32 angle, dangle; S32 i, vi; if (nverts < 3) nverts = 3; verts = push_arena(arena, nverts*sizeof(Vertex)); dangle = 2*F32PI/(F32)nverts; for (i = 0, angle = 0.0f; i < nverts; i++, angle += dangle) verts[i] = init_vert(v3(f32cos(angle)*r, f32sin(angle)*r, 0.0f), V2_ZERO); nindices = nverts*3; indices = push_arena(arena, nindices*sizeof(U32)); for (i = 0, vi = 1; i < nindices; i += 3, vi++) { indices[i] = 0; indices[i+1] = vi; indices[i+2] = (((vi+1) == (nverts)) ? 1 : (vi+1)); } mesh = init_mesh(origin, rotate, nverts, verts, nindices, indices); return mesh; } Model init_model(V3 origin, V3 rotate, S32 nmeshes, Mesh *meshes) { Model model = { .origin = origin, .rotate = rotate, .nmeshes = nmeshes, .meshes = meshes, }; return model; } Model load_model(V3 origin, V3 rotate, const char *fname) { Model model; MEM0STRUCT(&model); model.origin = origin; model.rotate = rotate; sys_printf("[INFO] : PRGE : Trying to load %s\n", fname); /* TODO(pryazha): Load models with assimp? */ return model; }