/* * Copyright (C) 2018 Tomasz Kramkowski * SPDX-License-Identifier: MIT */ #include #include "eprintf.h" #include "glprog.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]; #define SH_IN(_, name) \ gl_va_define(prog.attr.name, NELEM(v->name), GL_FLOAT, GL_FALSE, sizeof *v, (void *)offsetof(struct vertex, name)); \ gl_va_enable(prog.attr.name); #include "shaders/data.h" // 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]); } }