/* * Copyright (C) 2018 Tomasz Kramkowski * SPDX-License-Identifier: MIT */ #include #include "eprintf.h" #include "linmath.h" #include "model.h" #include "nelem.h" #include "vertex.h" void model_load(struct model *mdl, const struct fmd *fmd) { GLuint vbo, ebo; struct vertex *v; assert(mdl != NULL); assert(fmd != NULL); gl_va_gen(1, &mdl->vao); gl_va_bind(mdl->vao); gl_buf_gen(1, &vbo); gl_buf_bind(GL_ARRAY_BUFFER, vbo); gl_buf_data(GL_ARRAY_BUFFER, fmd->nverts * sizeof *fmd->verts, fmd->verts, GL_STATIC_DRAW); gl_buf_gen(1, &ebo); gl_buf_bind(GL_ELEMENT_ARRAY_BUFFER, ebo); gl_buf_data(GL_ELEMENT_ARRAY_BUFFER, fmd->ntris * sizeof *fmd->tris, fmd->tris, GL_STATIC_DRAW); v = &fmd->verts[0]; gl_va_define(0, NELEM(v->pos), GL_FLOAT, GL_FALSE, sizeof *v, (void *)offsetof(struct vertex, pos)); gl_va_enable(0); gl_va_define(1, NELEM(v->norm), GL_FLOAT, GL_FALSE, sizeof *v, (void *)offsetof(struct vertex, norm)); gl_va_enable(1); gl_va_define(2, NELEM(v->uv), GL_FLOAT, GL_FALSE, sizeof *v, (void *)offsetof(struct vertex, uv)); gl_va_enable(2); // TODO: materials, use a shared material set mdl->nmeshes = fmd->nmeshes; mdl->meshes = emalloc(mdl->nmeshes * sizeof *mdl->meshes); for (int i = 0; i < fmd->nmeshes; i++) { struct mesh *m = &mdl->meshes[i]; struct fmd_mesh *fm = &fmd->meshes[i]; if (fm->midx >= 0) m->mtl = mtl_load(fmd->mtls[fm->midx]); else m->mtl = -1; m->elems.idx = fm->tidx * NELEM(*fmd->tris); m->elems.cnt = fm->tcnt * NELEM(*fmd->tris); } } void model_render(struct model *mdl) { gl_va_bind(mdl->vao); for (int i = 0; i < mdl->nmeshes; i++) { struct mesh *m = &mdl->meshes[i]; mtl_use(m->mtl); gl_draw_elems(GL_TRIANGLES, m->elems.cnt, GL_UNSIGNED_INT, &((GLuint *)NULL)[m->elems.idx]); } }