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