-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmesh.c
131 lines (96 loc) · 2.95 KB
/
mesh.c
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdlib.h>
#include <GL/glew.h>
#include <stdio.h>
#include "mesh.h"
#include "linmath.h"
#include "constants.h"
#include "shader.h"
#include "model.h"
static void
calculate_bounding_box(struct model *m, struct bounding_box *box)
{
int i;
int ncoords;
vec3 *coord;
coord = (vec3 *) m->coords;
ncoords = m->csize / sizeof *coord;
box->min[COORD_X] = coord[0][COORD_X];
box->min[COORD_Y] = coord[0][COORD_Y];
box->min[COORD_Z] = coord[0][COORD_Z];
box->max[COORD_X] = coord[0][COORD_X];
box->max[COORD_Y] = coord[0][COORD_Y];
box->max[COORD_Z] = coord[0][COORD_Z];
/* i += 2 to skip normals */
for (i = 0; i < ncoords; i += 2) {
if (coord[i][COORD_X] < box->min[COORD_X])
box->min[COORD_X] = coord[i][COORD_X];
if (coord[i][COORD_Y] < box->min[COORD_Y])
box->min[COORD_Y] = coord[i][COORD_Y];
if (coord[i][COORD_Z] < box->min[COORD_Z])
box->min[COORD_Z] = coord[i][COORD_Z];
if (coord[i][COORD_X] > box->max[COORD_X])
box->max[COORD_X] = coord[i][COORD_X];
if (coord[i][COORD_Y] > box->max[COORD_Y])
box->max[COORD_Y] = coord[i][COORD_Y];
if (coord[i][COORD_Z] > box->max[COORD_Z])
box->max[COORD_Z] = coord[i][COORD_Z];
}
}
struct mesh *
mesh_load(const char *path)
{
struct model *model;
struct mesh *mesh;
model = load_model(path);
mesh = mesh_new(model);
model_free(model);
return mesh;
}
struct mesh *
mesh_new(struct model *model)
{
/* create vertex store buffer */
GLuint vbo;
glGenBuffers(1, &vbo);
/* setup a vao */
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, model->csize, model->coords, GL_STATIC_DRAW);
/* - location of position vertex attrib
* - size of vertex attrib (vec3)
* - data type
* - normalized? no
* - stride
* - data offset in the buffer
*/
/* vertices */
glVertexAttribPointer(VERTEX_VAO, 3, GL_FLOAT, GL_FALSE,
8 * sizeof (GLfloat), (GLvoid *) 0);
/* place data on shader location 0 */
glEnableVertexAttribArray(VERTEX_VAO);
/* normals */
glVertexAttribPointer(NORMAL_VAO, 3, GL_FLOAT, GL_FALSE,
8 * sizeof (GLfloat), (GLvoid *) (3 * sizeof (GLfloat)));
glEnableVertexAttribArray(NORMAL_VAO);
/* textures */
glVertexAttribPointer(TEXTURE_VAO, 2, GL_FLOAT, GL_TRUE,
8 * sizeof (GLfloat), (GLvoid *) (6 * sizeof (GLfloat)));
glEnableVertexAttribArray(TEXTURE_VAO);
/* unbind vao */
glBindVertexArray(0);
struct mesh *m = malloc(sizeof *m);
m->vao = vao;
m->vbo = vbo;
m->vertex_count = model->nvertex;
calculate_bounding_box(model, &m->bounding_box);
return m;
}
void
mesh_free(struct mesh *m)
{
glDeleteVertexArrays(1, &m->vao);
glDeleteBuffers(1, &m->vbo);
free(m);
}