b14df65e11765266952907e14b1cd5df5d2e5bd4
[vg.git] / vg_rigidbody_view.c
1 #pragma once
2 #include "vg_platform.h"
3 #include "vg_rigidbody.h"
4 #include "vg_shader.h"
5 #include "vg_engine.h"
6 #include "vg_async.h"
7
8 static struct vg_shader _shader_rigidbody =
9 {
10 .name = "[vg] rigidbody",
11 .link = NULL,
12 .vs = {
13 .orig_file = NULL,
14 .static_src =
15
16 "uniform mat4 uPv;"
17 "uniform mat4x3 uMdl;"
18 "uniform mat4x3 uMdl1;"
19 "layout (location=0) in vec4 a_co;"
20 "layout (location=1) in vec3 a_norm;"
21 "out vec3 aNorm;"
22 "out vec3 aCo;"
23 ""
24 "void main()"
25 "{"
26 "vec3 world_pos0 = uMdl * vec4( a_co.xyz, 1.0 );"
27 "vec3 world_pos1 = uMdl1 * vec4( a_co.xyz, 1.0 );"
28 "vec3 co = mix( world_pos0, world_pos1, a_co.w );"
29 "vec4 vert_pos = uPv * vec4( co, 1.0 );"
30
31 "gl_Position = vert_pos;"
32 "vec3 l = vec3(length(uMdl[0]),length(uMdl[1]),length(uMdl[2]));"
33 "aNorm = (mat3(uMdl) * a_norm)/l;"
34 "aCo = a_co.xyz*l;"
35 "}"
36 },
37 .fs = {
38 .orig_file = NULL,
39 .static_src =
40
41 "out vec4 FragColor;"
42 "uniform vec4 uColour;"
43 ""
44 "in vec3 aNorm;"
45 "in vec3 aCo;"
46 // The MIT License
47 // Copyright © 2017 Inigo Quilez
48 // Permission is hereby granted, free of charge, to any person obtaining a
49 // copy of this software and associated documentation files (the "Software"),
50 // to deal in the Software without restriction, including without limitation
51 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
52 // and/or sell copies of the Software, and to permit persons to whom the
53 // Software is furnished to do so, subject to the following conditions:
54 // The above copyright notice and this permission notice shall be included in
55 // all copies or substantial portions of the Software. THE SOFTWARE IS
56 // PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
57 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
58 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
59 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
60 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
61 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
62 // DEALINGS IN THE SOFTWARE.
63
64 // Info: https://iquilezles.org/articles/filterableprocedurals
65 //
66 // More filtered patterns: https://www.shadertoy.com/playlist/l3KXR1
67
68 "vec3 tri( in vec3 x ){"
69 "return 1.0-abs(2.0*fract(x/2.0)-1.0);"
70 "}"
71
72 "float checkersTextureGrad( in vec3 p, in vec3 ddx, in vec3 ddy ){"
73 "vec3 w = max(abs(ddx), abs(ddy)) + 0.0001;" // filter kernel
74 "vec3 i = (tri(p+0.5*w)-tri(p-0.5*w))/w;" // analytical integral
75 // (box filter)
76 "return 0.5 - 0.5*i.x*i.y*i.z;" // xor pattern
77 "}"
78 ""
79 "void main()"
80 "{"
81 "vec3 uvw = aCo;"
82 "vec3 ddx_uvw = dFdx( uvw );"
83 "vec3 ddy_uvw = dFdy( uvw );"
84 "float diffuse = checkersTextureGrad( uvw, ddx_uvw, ddy_uvw )*0.5+0.4;"
85 "float light = dot( vec3(0.8017,0.5345,-0.2672), aNorm )*0.5 + 0.5;"
86 "FragColor = light * diffuse * uColour;"
87 "}"
88 }
89 };
90
91 #pragma pack(push,1)
92 struct rb_view_vert {
93 v4f co;
94 v3f n;
95 };
96 #pragma pack(pop)
97
98 typedef struct rb_view_vert rb_view_vert;
99
100 struct {
101 GLuint vao, vbo, ebo;
102 u32 sphere_start, sphere_count,
103 box_start, box_count;
104 }
105 static vg_rb_view;
106
107 struct vg_rb_mesh_init {
108 u32 verts_size, tris_size;
109 rb_view_vert *verts;
110 u16 *tris;
111 };
112
113 static void async_vg_rb_view_init( void *payload, u32 payload_size )
114 {
115 struct vg_rb_mesh_init *inf = payload;
116
117 glGenVertexArrays( 1, &vg_rb_view.vao );
118 glGenBuffers( 1, &vg_rb_view.vbo );
119 glGenBuffers( 1, &vg_rb_view.ebo );
120 glBindVertexArray( vg_rb_view.vao );
121
122
123 glBindBuffer( GL_ARRAY_BUFFER, vg_rb_view.vbo );
124 glBufferData( GL_ARRAY_BUFFER, inf->verts_size, inf->verts, GL_STATIC_DRAW );
125 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_rb_view.ebo );
126 glBufferData( GL_ELEMENT_ARRAY_BUFFER,
127 inf->tris_size, inf->tris, GL_STATIC_DRAW );
128
129 /* 0: coordinates */
130 size_t stride = sizeof(rb_view_vert);
131 glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, stride, (void*)0 );
132 glEnableVertexAttribArray( 0 );
133
134 /* 1: normal */
135 glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE,
136 stride, (void *)offsetof(rb_view_vert, n) );
137 glEnableVertexAttribArray( 1 );
138
139 VG_CHECK_GL_ERR();
140 }
141
142 void vg_rb_view_init(void)
143 {
144 vg_shader_register( &_shader_rigidbody );
145
146 u32 H = 20,
147 V = 16,
148 verts_count = 0,
149 tris_count = 0;
150
151 /* box */
152 verts_count += 4*6;
153 tris_count += 2*6;
154 vg_rb_view.box_count = 2*6;
155 vg_rb_view.box_start = 0;
156
157 /* sphere */
158 verts_count += H*(V-2) + 2;
159 tris_count += H*2 + (V-2)*(H*2);
160 vg_rb_view.sphere_count = H*2 + (V-2)*(H*2);
161
162 u32 hdr_size = vg_align8( sizeof(struct vg_rb_mesh_init) ),
163 vert_size = vg_align8( verts_count * sizeof(rb_view_vert) ),
164 tris_size = vg_align8( tris_count * 3 * sizeof(u16) );
165
166 vg_async_item *call = vg_async_alloc( hdr_size + vert_size + tris_size );
167
168 struct vg_rb_mesh_init *inf = call->payload;
169 rb_view_vert *verts = ((void *)inf) + hdr_size;
170 u16 *tris = ((void *)inf) + hdr_size + vert_size;
171
172 inf->verts = verts;
173 inf->tris = tris;
174 inf->verts_size = vert_size;
175 inf->tris_size = tris_size;
176
177 u32 tri_index = 0,
178 vert_index = 0;
179
180 /* box
181 * ----------------------------------------------------------- */
182 for( u32 i=0; i<6; i ++ ){
183 v3f n = {i%3==0,i%3==1,i%3==2};
184 if( i >= 3 ) v3_negate( n, n );
185 v3f v0, v1;
186 v3_tangent_basis( n, v0, v1 );
187
188 rb_view_vert *vs = &verts[vert_index];
189 vert_index += 4;
190
191 for( u32 j=0; j<4; j ++ ){
192 v3_copy( n, vs[j].n );
193 v3_muladds( n, v0, j&0x1?1.0f:-1.0f, vs[j].co );
194 v3_muladds( vs[j].co, v1, j&0x2?1.0f:-1.0f, vs[j].co );
195 vs[j].co[3] = 0.0f;
196 }
197
198 tris[tri_index*3+0] = i*4+0;
199 tris[tri_index*3+1] = i*4+1;
200 tris[tri_index*3+2] = i*4+3;
201 tris[tri_index*3+3] = i*4+0;
202 tris[tri_index*3+4] = i*4+3;
203 tris[tri_index*3+5] = i*4+2;
204 tri_index += 2;
205 }
206
207 /* sphere / capsule
208 * ----------------------------------------------------------- */
209 u32 base = vert_index;
210 vg_rb_view.sphere_start = tri_index;
211 v4_copy( (v4f){0,-1,0,0}, verts[vert_index].co );
212 v3_copy( (v3f){0,-1,0}, verts[vert_index ++].n );
213
214 for( u32 x=0; x<H; x ++ ){
215 tris[tri_index*3+0] = base+0;
216 tris[tri_index*3+1] = base+1+x;
217 tris[tri_index*3+2] = base+1+((x+1)%H);
218 tri_index += 1;
219 }
220
221 for( u32 y=1; y<V-1; y ++ ){
222 f32 ty = ((f32)y/(f32)(V-1)) * VG_PIf;
223 u32 ybase = y-1;
224 for( u32 x=0; x<H; x ++ ){
225 f32 tx = ((f32)x/(f32)H) * VG_TAUf;
226
227 v4f co = { cosf(tx)*sinf(ty), -cosf(ty), sinf(tx)*sinf(ty), y>=(V/2) };
228 v4_copy( co, verts[vert_index].co );
229 v4_copy( co, verts[vert_index ++].n );
230
231 if( y < V-2 ){
232 tris[tri_index*3+0] = base+1 + ybase*H + x;
233 tris[tri_index*3+1] = base+1 + (ybase+1)*H + ((x+1)%H);
234 tris[tri_index*3+2] = base+1 + ybase*H + ((x+1)%H);
235 tris[tri_index*3+3] = base+1 + ybase*H + x;
236 tris[tri_index*3+4] = base+1 + (ybase+1)*H + x;
237 tris[tri_index*3+5] = base+1 + (ybase+1)*H + ((x+1)%H);
238 tri_index += 2;
239 }
240 }
241 }
242
243 v4_copy( (v4f){0, 1,0,1}, verts[vert_index].co );
244 v3_copy( (v3f){0, 1,0}, verts[vert_index ++].n );
245
246 for( u32 x=0; x<H; x ++ ){
247 tris[tri_index*3+0] = base + (H*(V-2) + 2)-1;
248 tris[tri_index*3+1] = base+1 + (V-3)*H+((x+1)%H);
249 tris[tri_index*3+2] = base+1 + (V-3)*H+x;
250 tri_index += 1;
251 }
252
253 vg_async_dispatch( call, async_vg_rb_view_init );
254 }
255
256 void vg_rb_view_bind(void)
257 {
258 glEnable( GL_CULL_FACE );
259 glEnable( GL_DEPTH_TEST );
260
261 glUseProgram( _shader_rigidbody.id );
262 glUniformMatrix4fv( glGetUniformLocation( _shader_rigidbody.id, "uPv" ),
263 1, GL_FALSE, (float *)vg.pv );
264
265 glBindVertexArray( vg_rb_view.vao );
266 }
267
268 void vg_rb_view_box( m4x3f mdl, boxf bbx, v4f colour )
269 {
270 v3f e;
271 v3_sub( bbx[1], bbx[0], e );
272 v3_muls( e, 0.5f, e );
273
274 m4x3f mmdl;
275 m4x3_identity( mmdl );
276 m3x3_scale( mmdl, e );
277 v3_add( bbx[0], e, mmdl[3] );
278 m4x3_mul( mdl, mmdl, mmdl );
279
280 glUniformMatrix4x3fv( glGetUniformLocation( _shader_rigidbody.id, "uMdl" ),
281 1,GL_FALSE,(float*)mmdl);
282 glUniformMatrix4x3fv( glGetUniformLocation( _shader_rigidbody.id, "uMdl1" ),
283 1,GL_FALSE,(float*)mmdl);
284 glUniform4fv( glGetUniformLocation( _shader_rigidbody.id, "uColour" ), 1,
285 colour );
286 glDrawElements( GL_TRIANGLES,
287 vg_rb_view.box_count*3, GL_UNSIGNED_SHORT,
288 (void *)(vg_rb_view.box_start*3*sizeof(u16)) );
289 }
290
291 void vg_rb_view_sphere( m4x3f mdl, f32 r, v4f colour )
292 {
293 m4x3f mmdl;
294 m4x3_copy( mdl, mmdl );
295 m3x3_scalef( mmdl, r );
296 glUniformMatrix4x3fv( glGetUniformLocation( _shader_rigidbody.id, "uMdl" ),
297 1,GL_FALSE,(float*)mmdl);
298 glUniformMatrix4x3fv( glGetUniformLocation( _shader_rigidbody.id, "uMdl1" ),
299 1,GL_FALSE,(float*)mmdl);
300 glUniform4fv( glGetUniformLocation( _shader_rigidbody.id, "uColour" ), 1,
301 colour );
302 glDrawElements( GL_TRIANGLES,
303 vg_rb_view.sphere_count*3, GL_UNSIGNED_SHORT,
304 (void *)(vg_rb_view.sphere_start*3*sizeof(u16)) );
305 }
306
307 void vg_rb_view_capsule( m4x3f mdl, f32 r, f32 h, v4f colour )
308 {
309 m4x3f mmdl0, mmdl1;
310 m4x3_identity( mmdl0 );
311 m4x3_identity( mmdl1 );
312 m3x3_scalef( mmdl0, r );
313 m3x3_scalef( mmdl1, r );
314 mmdl0[3][1] = -h*0.5f+r;
315 mmdl1[3][1] = h*0.5f-r;
316 m4x3_mul( mdl, mmdl0, mmdl0 );
317 m4x3_mul( mdl, mmdl1, mmdl1 );
318
319 glUniformMatrix4x3fv( glGetUniformLocation( _shader_rigidbody.id, "uMdl" ),
320 1,GL_FALSE,(float*)mmdl0);
321 glUniformMatrix4x3fv( glGetUniformLocation( _shader_rigidbody.id, "uMdl1" ),
322 1,GL_FALSE,(float*)mmdl1);
323 glUniform4fv( glGetUniformLocation( _shader_rigidbody.id, "uColour" ), 1,
324 colour );
325 glDrawElements( GL_TRIANGLES,
326 vg_rb_view.sphere_count*3, GL_UNSIGNED_SHORT,
327 (void *)(vg_rb_view.sphere_start*3*sizeof(u16)) );
328 }