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