2aaf48358517283fa72d6c40a1e0b1d6194e28a7
[carveJwlIkooP6JGAAIwe30JlM.git] / model.h
1 #include "vg/vg.h"
2
3 typedef struct model model;
4 typedef struct glmesh glmesh;
5 typedef struct submodel submodel;
6 typedef struct model_vert model_vert;
7 typedef struct scene scene;
8 typedef struct sdf_primative sdf_primative;
9 typedef enum esdf_type esdf_type;
10
11 #pragma pack(push,1)
12 struct model
13 {
14 u32 identifier;
15
16 u32 vertex_count,
17 indice_count,
18 layer_count;
19 };
20
21 struct sdf_primative
22 {
23 v4f origin; /* xyz, yaw */
24 /* Cone:
25 x base scale
26 y height
27 */
28 v4f info;
29 };
30
31 struct submodel
32 {
33 u32 indice_start,
34 indice_count,
35 vertex_start,
36 vertex_count;
37
38 boxf bbx;
39 sdf_primative sdf;
40
41 enum esdf_type
42 {
43 k_sdf_none = 0,
44 k_sdf_cone,
45 k_sdf_sphere,
46 k_sdf_box
47 }
48 sdf_type;
49
50 char name[32];
51 };
52
53 struct model_vert
54 {
55 v3f co,
56 norm;
57 v4f colour;
58 v2f uv;
59 };
60 #pragma pack(pop)
61
62 struct glmesh
63 {
64 GLuint vao, vbo, ebo;
65 u32 indice_count;
66 };
67
68 static void mesh_upload( glmesh *mesh,
69 model_vert *verts, u32 vert_count,
70 u32 *indices, u32 indice_count )
71 {
72 glGenVertexArrays( 1, &mesh->vao );
73 glGenBuffers( 1, &mesh->vbo );
74 glGenBuffers( 1, &mesh->ebo );
75 glBindVertexArray( mesh->vao );
76
77 glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo );
78 glBufferData( GL_ARRAY_BUFFER, vert_count*sizeof(model_vert),
79 verts, GL_STATIC_DRAW );
80
81 glBindVertexArray( mesh->vao );
82 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo );
83 glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32),
84 indices, GL_STATIC_DRAW );
85
86 glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE,
87 sizeof(model_vert), (void*)0 );
88 glEnableVertexAttribArray( 0 );
89
90 glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE,
91 sizeof(model_vert), (void *)offsetof(model_vert, norm) );
92 glEnableVertexAttribArray( 1 );
93
94 glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE,
95 sizeof(model_vert), (void *)offsetof(model_vert, colour) );
96 glEnableVertexAttribArray( 2 );
97
98 glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE,
99 sizeof(model_vert), (void *)offsetof(model_vert, uv) );
100 glEnableVertexAttribArray( 3 );
101
102 VG_CHECK_GL();
103 mesh->indice_count = indice_count;
104 }
105
106 static void mesh_bind( glmesh *mesh )
107 {
108 glBindVertexArray( mesh->vao );
109 }
110
111 static void mesh_drawn( u32 start, u32 count )
112 {
113 glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT,
114 (void *)(start*sizeof(u32)) );
115 }
116
117 static void mesh_draw( glmesh *mesh )
118 {
119 mesh_drawn( 0, mesh->indice_count );
120 }
121
122 /*
123 * Helper functions for file offsets
124 */
125 static submodel *model_get_submodel( model *mdl, int id )
126 {
127 return ((submodel*)(mdl+1)) + id;
128 }
129
130 static model_vert *model_vertex_base( model *mdl )
131 {
132 return (model_vert *)model_get_submodel( mdl, mdl->layer_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 void submodel_draw( submodel *sm )
164 {
165 mesh_drawn( sm->indice_start, sm->indice_count );
166 }
167
168 static void model_unpack( model *model, glmesh *mesh )
169 {
170 u32 offset = model_get_submodel( model, 0 )->vertex_count;
171
172 for( int i=1; i<model->layer_count; i++ )
173 {
174 submodel *sm = model_get_submodel( model, i );
175 u32 *indices = submodel_indice_data( model, sm );
176
177 for( u32 j=0; j<sm->indice_count; j++ )
178 indices[j] += offset;
179
180 offset += sm->vertex_count;
181 }
182
183 mesh_upload( mesh, model_vertex_base( model ), model->vertex_count,
184 model_indice_base( model ), model->indice_count );
185 }