9788dc1446c080aaf15f71a00beee5fb1b163c8d
[carveJwlIkooP6JGAAIwe30JlM.git] / model.h
1 #ifndef MODEL_H
2 #define MODEL_H
3
4 #include "vg/vg.h"
5
6 typedef struct model model;
7 typedef struct glmesh glmesh;
8 typedef struct submodel submodel;
9 typedef struct model_vert model_vert;
10 typedef struct model_marker model_marker;
11 typedef struct sdf_primative sdf_primative;
12 typedef enum esdf_type esdf_type;
13
14 #pragma pack(push,1)
15 struct model
16 {
17 u32 identifier;
18
19 u32 vertex_count,
20 indice_count,
21 layer_count,
22 marker_count;
23 };
24
25 struct sdf_primative
26 {
27 v4f origin; /* xyz, yaw */
28 /* Cone:
29 x base scale
30 y height
31 */
32 v4f info;
33 };
34
35 struct submodel
36 {
37 u32 indice_start,
38 indice_count,
39 vertex_start,
40 vertex_count;
41
42 boxf bbx;
43 v3f pivot;
44 sdf_primative sdf;
45
46 enum esdf_type
47 {
48 k_sdf_none = 0,
49 k_sdf_cone,
50 k_sdf_sphere,
51 k_sdf_box
52 }
53 sdf_type;
54
55 char name[32];
56 };
57
58 struct model_marker
59 {
60 v3f co;
61 v4f q;
62 v3f s;
63 char name[32];
64 };
65
66 struct model_vert
67 {
68 v3f co,
69 norm;
70 v4f colour;
71 v2f uv;
72 };
73 #pragma pack(pop)
74
75 struct glmesh
76 {
77 GLuint vao, vbo, ebo;
78 u32 indice_count;
79 };
80
81 #define VERTEX_STANDARD_ATTRIBUTES \
82 "layout (location=0) in vec3 a_co;" \
83 "layout (location=1) in vec3 a_norm;" \
84 "layout (location=2) in vec4 a_colour;" \
85 "layout (location=3) in vec2 a_uv;"
86
87 static void mesh_upload( glmesh *mesh,
88 model_vert *verts, u32 vert_count,
89 u32 *indices, u32 indice_count )
90 {
91 glGenVertexArrays( 1, &mesh->vao );
92 glGenBuffers( 1, &mesh->vbo );
93 glGenBuffers( 1, &mesh->ebo );
94 glBindVertexArray( mesh->vao );
95
96 glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo );
97 glBufferData( GL_ARRAY_BUFFER, vert_count*sizeof(model_vert),
98 verts, GL_STATIC_DRAW );
99
100 glBindVertexArray( mesh->vao );
101 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo );
102 glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32),
103 indices, GL_STATIC_DRAW );
104
105 glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE,
106 sizeof(model_vert), (void*)0 );
107 glEnableVertexAttribArray( 0 );
108
109 glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE,
110 sizeof(model_vert), (void *)offsetof(model_vert, norm) );
111 glEnableVertexAttribArray( 1 );
112
113 glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE,
114 sizeof(model_vert), (void *)offsetof(model_vert, colour) );
115 glEnableVertexAttribArray( 2 );
116
117 glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE,
118 sizeof(model_vert), (void *)offsetof(model_vert, uv) );
119 glEnableVertexAttribArray( 3 );
120
121 VG_CHECK_GL();
122 mesh->indice_count = indice_count;
123 }
124
125 static void mesh_bind( glmesh *mesh )
126 {
127 glBindVertexArray( mesh->vao );
128 }
129
130 static void mesh_drawn( u32 start, u32 count )
131 {
132 glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT,
133 (void *)(start*sizeof(u32)) );
134 }
135
136 static void mesh_draw( glmesh *mesh )
137 {
138 mesh_drawn( 0, mesh->indice_count );
139 }
140
141 /*
142 * Helper functions for file offsets
143 * TODO: Revise this
144 */
145 static submodel *model_get_submodel( model *mdl, int id )
146 {
147 return ((submodel*)(mdl+1)) + id;
148 }
149
150 static model_marker *model_get_marker( model *mdl, int id )
151 {
152 return ((model_marker*)model_get_submodel(mdl,mdl->layer_count)) + id;
153 }
154
155 static model_vert *model_vertex_base( model *mdl )
156 {
157 return (model_vert *)model_get_marker( mdl, mdl->marker_count );
158 }
159
160 static u32 *model_indice_base( model *mdl )
161 {
162 return (u32 *)(model_vertex_base( mdl ) + mdl->vertex_count);
163 }
164
165 static model_vert *submodel_vert_data( model *mdl, submodel *sub )
166 {
167 return model_vertex_base(mdl) + sub->vertex_start;
168 }
169
170 static u32 *submodel_indice_data( model *mdl, submodel *sub )
171 {
172 return model_indice_base(mdl) + sub->indice_start;
173 }
174
175 static submodel *submodel_get( model *mdl, const char *name )
176 {
177 for( int i=0; i<mdl->layer_count; i++ )
178 {
179 submodel *pmdl =model_get_submodel(mdl,i);
180
181 if( !strcmp( pmdl->name, name ) )
182 return pmdl;
183 }
184
185 return NULL;
186 }
187
188 static model_marker *model_marker_get( model *mdl, const char *name )
189 {
190 for( int i=0; i<mdl->marker_count; i++ )
191 {
192 model_marker *mk = model_get_marker( mdl,i );
193
194 if( !strcmp( mk->name, name ) )
195 return mk;
196 }
197
198 return NULL;
199 }
200
201 static void submodel_draw( submodel *sm )
202 {
203 mesh_drawn( sm->indice_start, sm->indice_count );
204 }
205
206 static void model_unpack( model *model, glmesh *mesh )
207 {
208 u32 offset = model_get_submodel( model, 0 )->vertex_count;
209
210 for( int i=1; i<model->layer_count; i++ )
211 {
212 submodel *sm = model_get_submodel( model, i );
213 u32 *indices = submodel_indice_data( model, sm );
214
215 for( u32 j=0; j<sm->indice_count; j++ )
216 indices[j] += offset;
217
218 offset += sm->vertex_count;
219 }
220
221 mesh_upload( mesh, model_vertex_base( model ), model->vertex_count,
222 model_indice_base( model ), model->indice_count );
223 }
224
225 static void mesh_free( glmesh *mesh )
226 {
227 glDeleteVertexArrays( 1, &mesh->vao );
228 glDeleteBuffers( 1, &mesh->ebo );
229 glDeleteBuffers( 1, &mesh->vbo );
230 }
231
232 #endif