new characters and anim blending
[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 #define VERTEX_STANDARD_ATTRIBUTES \
73 "layout (location=0) in vec3 a_co;" \
74 "layout (location=1) in vec3 a_norm;" \
75 "layout (location=2) in vec4 a_colour;" \
76 "layout (location=3) in vec2 a_uv;"
77
78 static void mesh_upload( glmesh *mesh,
79 model_vert *verts, u32 vert_count,
80 u32 *indices, u32 indice_count )
81 {
82 glGenVertexArrays( 1, &mesh->vao );
83 glGenBuffers( 1, &mesh->vbo );
84 glGenBuffers( 1, &mesh->ebo );
85 glBindVertexArray( mesh->vao );
86
87 glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo );
88 glBufferData( GL_ARRAY_BUFFER, vert_count*sizeof(model_vert),
89 verts, GL_STATIC_DRAW );
90
91 glBindVertexArray( mesh->vao );
92 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo );
93 glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32),
94 indices, GL_STATIC_DRAW );
95
96 glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE,
97 sizeof(model_vert), (void*)0 );
98 glEnableVertexAttribArray( 0 );
99
100 glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE,
101 sizeof(model_vert), (void *)offsetof(model_vert, norm) );
102 glEnableVertexAttribArray( 1 );
103
104 glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE,
105 sizeof(model_vert), (void *)offsetof(model_vert, colour) );
106 glEnableVertexAttribArray( 2 );
107
108 glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE,
109 sizeof(model_vert), (void *)offsetof(model_vert, uv) );
110 glEnableVertexAttribArray( 3 );
111
112 VG_CHECK_GL();
113 mesh->indice_count = indice_count;
114 }
115
116 static void mesh_bind( glmesh *mesh )
117 {
118 glBindVertexArray( mesh->vao );
119 }
120
121 static void mesh_drawn( u32 start, u32 count )
122 {
123 glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT,
124 (void *)(start*sizeof(u32)) );
125 }
126
127 static void mesh_draw( glmesh *mesh )
128 {
129 mesh_drawn( 0, mesh->indice_count );
130 }
131
132 /*
133 * Helper functions for file offsets
134 */
135 static submodel *model_get_submodel( model *mdl, int id )
136 {
137 return ((submodel*)(mdl+1)) + id;
138 }
139
140 static model_vert *model_vertex_base( model *mdl )
141 {
142 return (model_vert *)model_get_submodel( mdl, mdl->layer_count );
143 }
144
145 static u32 *model_indice_base( model *mdl )
146 {
147 return (u32 *)(model_vertex_base( mdl ) + mdl->vertex_count);
148 }
149
150 static model_vert *submodel_vert_data( model *mdl, submodel *sub )
151 {
152 return model_vertex_base(mdl) + sub->vertex_start;
153 }
154
155 static u32 *submodel_indice_data( model *mdl, submodel *sub )
156 {
157 return model_indice_base(mdl) + sub->indice_start;
158 }
159
160 static submodel *submodel_get( model *mdl, const char *name )
161 {
162 for( int i=0; i<mdl->layer_count; i++ )
163 {
164 submodel *pmdl =model_get_submodel(mdl,i);
165
166 if( !strcmp( pmdl->name, name ) )
167 return pmdl;
168 }
169
170 return NULL;
171 }
172
173 static void submodel_draw( submodel *sm )
174 {
175 mesh_drawn( sm->indice_start, sm->indice_count );
176 }
177
178 static void model_unpack( model *model, glmesh *mesh )
179 {
180 u32 offset = model_get_submodel( model, 0 )->vertex_count;
181
182 for( int i=1; i<model->layer_count; i++ )
183 {
184 submodel *sm = model_get_submodel( model, i );
185 u32 *indices = submodel_indice_data( model, sm );
186
187 for( u32 j=0; j<sm->indice_count; j++ )
188 indices[j] += offset;
189
190 offset += sm->vertex_count;
191 }
192
193 mesh_upload( mesh, model_vertex_base( model ), model->vertex_count,
194 model_indice_base( model ), model->indice_count );
195 }
196
197 #endif