aboutsummaryrefslogtreecommitdiffstats
path: root/model.c
blob: 63f3f333a01fd8507760762e58b4f38d0c1fded6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * Copyright (C) 2018 Tomasz Kramkowski <tk@the-tk.com>
 * SPDX-License-Identifier: MIT
 */
#include <assert.h>

#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]);
	}
}