update to new shader system
[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 static void mesh_upload( glmesh *mesh,
82 model_vert *verts, u32 vert_count,
83 u32 *indices, u32 indice_count )
84 {
85 glGenVertexArrays( 1, &mesh->vao );
86 glGenBuffers( 1, &mesh->vbo );
87 glGenBuffers( 1, &mesh->ebo );
88 glBindVertexArray( mesh->vao );
89
90 glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo );
91 glBufferData( GL_ARRAY_BUFFER, vert_count*sizeof(model_vert),
92 verts, GL_STATIC_DRAW );
93
94 glBindVertexArray( mesh->vao );
95 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo );
96 glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32),
97 indices, GL_STATIC_DRAW );
98
99 glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE,
100 sizeof(model_vert), (void*)0 );
101 glEnableVertexAttribArray( 0 );
102
103 glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE,
104 sizeof(model_vert), (void *)offsetof(model_vert, norm) );
105 glEnableVertexAttribArray( 1 );
106
107 glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE,
108 sizeof(model_vert), (void *)offsetof(model_vert, colour) );
109 glEnableVertexAttribArray( 2 );
110
111 glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE,
112 sizeof(model_vert), (void *)offsetof(model_vert, uv) );
113 glEnableVertexAttribArray( 3 );
114
115 VG_CHECK_GL();
116 mesh->indice_count = indice_count;
117 }
118
119 static void mesh_bind( glmesh *mesh )
120 {
121 glBindVertexArray( mesh->vao );
122 }
123
124 static void mesh_drawn( u32 start, u32 count )
125 {
126 glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT,
127 (void *)(start*sizeof(u32)) );
128 }
129
130 static void mesh_draw( glmesh *mesh )
131 {
132 mesh_drawn( 0, mesh->indice_count );
133 }
134
135 /*
136 * Helper functions for file offsets
137 * TODO: Revise this
138 */
139 static submodel *model_get_submodel( model *mdl, int id )
140 {
141 return ((submodel*)(mdl+1)) + id;
142 }
143
144 static model_marker *model_get_marker( model *mdl, int id )
145 {
146 return ((model_marker*)model_get_submodel(mdl,mdl->layer_count)) + id;
147 }
148
149 static model_vert *model_vertex_base( model *mdl )
150 {
151 return (model_vert *)model_get_marker( mdl, mdl->marker_count );
152 }
153
154 static u32 *model_indice_base( model *mdl )
155 {
156 return (u32 *)(model_vertex_base( mdl ) + mdl->vertex_count);
157 }
158
159 static model_vert *submodel_vert_data( model *mdl, submodel *sub )
160 {
161 return model_vertex_base(mdl) + sub->vertex_start;
162 }
163
164 static u32 *submodel_indice_data( model *mdl, submodel *sub )
165 {
166 return model_indice_base(mdl) + sub->indice_start;
167 }
168
169 static submodel *submodel_get( model *mdl, const char *name )
170 {
171 for( int i=0; i<mdl->layer_count; i++ )
172 {
173 submodel *pmdl =model_get_submodel(mdl,i);
174
175 if( !strcmp( pmdl->name, name ) )
176 return pmdl;
177 }
178
179 return NULL;
180 }
181
182 static model_marker *model_marker_get( model *mdl, const char *name )
183 {
184 for( int i=0; i<mdl->marker_count; i++ )
185 {
186 model_marker *mk = model_get_marker( mdl,i );
187
188 if( !strcmp( mk->name, name ) )
189 return mk;
190 }
191
192 return NULL;
193 }
194
195 static void submodel_draw( submodel *sm )
196 {
197 mesh_drawn( sm->indice_start, sm->indice_count );
198 }
199
200 static void model_unpack_submodel( model *model, glmesh *mesh, submodel *sm )
201 {
202 mesh_upload( mesh,
203 model_vertex_base( model ) + sm->vertex_start, sm->vertex_count,
204 model_indice_base( model ) + sm->indice_start, sm->indice_count );
205 }
206
207 static void model_unpack( model *model, glmesh *mesh )
208 {
209 u32 offset = model_get_submodel( model, 0 )->vertex_count;
210
211 for( int i=1; i<model->layer_count; i++ )
212 {
213 submodel *sm = model_get_submodel( model, i );
214 u32 *indices = submodel_indice_data( model, sm );
215
216 for( u32 j=0; j<sm->indice_count; j++ )
217 indices[j] += offset;
218
219 offset += sm->vertex_count;
220 }
221
222 mesh_upload( mesh, model_vertex_base( model ), model->vertex_count,
223 model_indice_base( model ), model->indice_count );
224 }
225
226 static void mesh_free( glmesh *mesh )
227 {
228 glDeleteVertexArrays( 1, &mesh->vao );
229 glDeleteBuffers( 1, &mesh->ebo );
230 glDeleteBuffers( 1, &mesh->vbo );
231 }
232
233 #endif