7194689899615b36a516715b655168bec5e203fc
[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 submodel
26 {
27 u32 indice_start,
28 indice_count,
29 vertex_start,
30 vertex_count;
31
32 boxf bbx;
33 v3f pivot; /* same as co? */
34 v4f q;
35 char name[32];
36 char material[32];
37 };
38
39 struct model_marker
40 {
41 v3f co;
42 v4f q;
43 v3f s;
44 char name[32];
45 };
46
47 struct model_vert
48 {
49 v3f co,
50 norm;
51 v4f colour;
52 v2f uv;
53 };
54 #pragma pack(pop)
55
56 struct glmesh
57 {
58 GLuint vao, vbo, ebo;
59 u32 indice_count;
60 };
61
62 static void mesh_upload( glmesh *mesh,
63 model_vert *verts, u32 vert_count,
64 u32 *indices, u32 indice_count )
65 {
66 glGenVertexArrays( 1, &mesh->vao );
67 glGenBuffers( 1, &mesh->vbo );
68 glGenBuffers( 1, &mesh->ebo );
69 glBindVertexArray( mesh->vao );
70
71 glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo );
72 glBufferData( GL_ARRAY_BUFFER, vert_count*sizeof(model_vert),
73 verts, GL_STATIC_DRAW );
74
75 glBindVertexArray( mesh->vao );
76 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo );
77 glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32),
78 indices, GL_STATIC_DRAW );
79
80 glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE,
81 sizeof(model_vert), (void*)0 );
82 glEnableVertexAttribArray( 0 );
83
84 glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE,
85 sizeof(model_vert), (void *)offsetof(model_vert, norm) );
86 glEnableVertexAttribArray( 1 );
87
88 glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE,
89 sizeof(model_vert), (void *)offsetof(model_vert, colour) );
90 glEnableVertexAttribArray( 2 );
91
92 glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE,
93 sizeof(model_vert), (void *)offsetof(model_vert, uv) );
94 glEnableVertexAttribArray( 3 );
95
96 VG_CHECK_GL();
97 mesh->indice_count = indice_count;
98 }
99
100 static void mesh_bind( glmesh *mesh )
101 {
102 glBindVertexArray( mesh->vao );
103 }
104
105 static void mesh_drawn( u32 start, u32 count )
106 {
107 glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT,
108 (void *)(start*sizeof(u32)) );
109 }
110
111 static void mesh_draw( glmesh *mesh )
112 {
113 mesh_drawn( 0, mesh->indice_count );
114 }
115
116 /*
117 * Helper functions for file offsets
118 * TODO: Revise this
119 */
120 static submodel *model_get_submodel( model *mdl, int id )
121 {
122 return ((submodel*)(mdl+1)) + id;
123 }
124
125 static model_marker *model_get_marker( model *mdl, int id )
126 {
127 return ((model_marker*)model_get_submodel(mdl,mdl->layer_count)) + id;
128 }
129
130 static model_vert *model_vertex_base( model *mdl )
131 {
132 return (model_vert *)model_get_marker( mdl, mdl->marker_count );
133 }
134
135 static u32 *model_indice_base( model *mdl )
136 {
137 return (u32 *)(model_vertex_base( mdl ) + mdl->vertex_count);
138 }
139
140 static model_vert *submodel_vert_data( model *mdl, submodel *sub )
141 {
142 return model_vertex_base(mdl) + sub->vertex_start;
143 }
144
145 static u32 *submodel_indice_data( model *mdl, submodel *sub )
146 {
147 return model_indice_base(mdl) + sub->indice_start;
148 }
149
150 static submodel *submodel_get( model *mdl, const char *name )
151 {
152 for( int i=0; i<mdl->layer_count; i++ )
153 {
154 submodel *pmdl =model_get_submodel(mdl,i);
155
156 if( !strcmp( pmdl->name, name ) )
157 return pmdl;
158 }
159
160 return NULL;
161 }
162
163 static model_marker *model_marker_get( model *mdl, const char *name )
164 {
165 for( int i=0; i<mdl->marker_count; i++ )
166 {
167 model_marker *mk = model_get_marker( mdl,i );
168
169 if( !strcmp( mk->name, name ) )
170 return mk;
171 }
172
173 return NULL;
174 }
175
176 static void submodel_draw( submodel *sm )
177 {
178 mesh_drawn( sm->indice_start, sm->indice_count );
179 }
180
181 static void model_unpack_submodel( model *model, glmesh *mesh, submodel *sm )
182 {
183 mesh_upload( mesh,
184 model_vertex_base( model ) + sm->vertex_start, sm->vertex_count,
185 model_indice_base( model ) + sm->indice_start, sm->indice_count );
186 }
187
188 static void model_unpack( model *model, glmesh *mesh )
189 {
190 u32 offset = model_get_submodel( model, 0 )->vertex_count;
191
192 for( int i=1; i<model->layer_count; i++ )
193 {
194 submodel *sm = model_get_submodel( model, i );
195 u32 *indices = submodel_indice_data( model, sm );
196
197 for( u32 j=0; j<sm->indice_count; j++ )
198 indices[j] += offset;
199
200 offset += sm->vertex_count;
201 }
202
203 mesh_upload( mesh, model_vertex_base( model ), model->vertex_count,
204 model_indice_base( model ), model->indice_count );
205 }
206
207 static void mesh_free( glmesh *mesh )
208 {
209 glDeleteVertexArrays( 1, &mesh->vao );
210 glDeleteBuffers( 1, &mesh->ebo );
211 glDeleteBuffers( 1, &mesh->vbo );
212 }
213
214 #endif