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