X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=blobdiff_plain;f=vg_rigidbody_view.h;fp=vg_rigidbody_view.h;h=578060ec2a846ddd22032224cb529221400850e4;hp=0000000000000000000000000000000000000000;hb=1c305409e8eca9cf8449d681df73208956ce14df;hpb=1abb54856257b10f6a20a4980a31930c59e3d37c diff --git a/vg_rigidbody_view.h b/vg_rigidbody_view.h new file mode 100644 index 0000000..578060e --- /dev/null +++ b/vg_rigidbody_view.h @@ -0,0 +1,319 @@ +#pragma once +#include "vg_rigidbody.h" + +static struct vg_shader _shader_rigidbody = { + .name = "[vg] rigidbody", + .link = NULL, + .vs = { + .orig_file = NULL, + .static_src = + + "uniform mat4 uPv;" + "uniform mat4x3 uMdl;" + "uniform mat4x3 uMdl1;" + "layout (location=0) in vec4 a_co;" + "layout (location=1) in vec3 a_norm;" + "out vec3 aNorm;" + "out vec3 aCo;" + "" + "void main()" + "{" + "vec3 world_pos0 = uMdl * vec4( a_co.xyz, 1.0 );" + "vec3 world_pos1 = uMdl1 * vec4( a_co.xyz, 1.0 );" + "vec3 co = mix( world_pos0, world_pos1, a_co.w );" + "vec4 vert_pos = uPv * vec4( co, 1.0 );" + + "gl_Position = vert_pos;" + "vec3 l = vec3(length(uMdl[0]),length(uMdl[1]),length(uMdl[2]));" + "aNorm = (mat3(uMdl) * a_norm)/l;" + "aCo = a_co.xyz*l;" + "}" + }, + .fs = { + .orig_file = NULL, + .static_src = + + "out vec4 FragColor;" + "uniform vec4 uColour;" + "" + "in vec3 aNorm;" + "in vec3 aCo;" + // The MIT License + // Copyright © 2017 Inigo Quilez + // Permission is hereby granted, free of charge, to any person obtaining a + // copy of this software and associated documentation files (the "Software"), + // to deal in the Software without restriction, including without limitation + // the rights to use, copy, modify, merge, publish, distribute, sublicense, + // and/or sell copies of the Software, and to permit persons to whom the + // Software is furnished to do so, subject to the following conditions: + // The above copyright notice and this permission notice shall be included in + // all copies or substantial portions of the Software. THE SOFTWARE IS + // PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + // DEALINGS IN THE SOFTWARE. + + // Info: https://iquilezles.org/articles/filterableprocedurals + // + // More filtered patterns: https://www.shadertoy.com/playlist/l3KXR1 + + "vec3 tri( in vec3 x ){" + "return 1.0-abs(2.0*fract(x/2.0)-1.0);" + "}" + + "float checkersTextureGrad( in vec3 p, in vec3 ddx, in vec3 ddy ){" + "vec3 w = max(abs(ddx), abs(ddy)) + 0.0001;" // filter kernel + "vec3 i = (tri(p+0.5*w)-tri(p-0.5*w))/w;" // analytical integral + // (box filter) + "return 0.5 - 0.5*i.x*i.y*i.z;" // xor pattern + "}" + "" + "void main()" + "{" + "vec3 uvw = aCo;" + "vec3 ddx_uvw = dFdx( uvw );" + "vec3 ddy_uvw = dFdy( uvw );" + "float diffuse = checkersTextureGrad( uvw, ddx_uvw, ddy_uvw )*0.5+0.4;" + "float light = dot( vec3(0.8017,0.5345,-0.2672), aNorm )*0.5 + 0.5;" + "FragColor = light * diffuse * uColour;" + "}" + } +}; + +#pragma pack(push,1) +struct rb_view_vert { + v4f co; + v3f n; +}; +#pragma pack(pop) + +typedef struct rb_view_vert rb_view_vert; + +struct { + GLuint vao, vbo, ebo; + + u32 sphere_start, sphere_count, + box_start, box_count; +} +static vg_rb_view; + +struct vg_rb_mesh_init { + u32 verts_size, tris_size; + rb_view_vert *verts; + u16 *tris; +}; + +static void async_vg_rb_view_init( void *payload, u32 payload_size ){ + struct vg_rb_mesh_init *inf = payload; + + glGenVertexArrays( 1, &vg_rb_view.vao ); + glGenBuffers( 1, &vg_rb_view.vbo ); + glGenBuffers( 1, &vg_rb_view.ebo ); + glBindVertexArray( vg_rb_view.vao ); + + + glBindBuffer( GL_ARRAY_BUFFER, vg_rb_view.vbo ); + glBufferData( GL_ARRAY_BUFFER, inf->verts_size, inf->verts, GL_STATIC_DRAW ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vg_rb_view.ebo ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, + inf->tris_size, inf->tris, GL_STATIC_DRAW ); + + /* 0: coordinates */ + size_t stride = sizeof(rb_view_vert); + glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, stride, (void*)0 ); + glEnableVertexAttribArray( 0 ); + + /* 1: normal */ + glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, + stride, (void *)offsetof(rb_view_vert, n) ); + glEnableVertexAttribArray( 1 ); + + VG_CHECK_GL_ERR(); +} + +static void vg_rb_view_init(void){ + vg_shader_register( &_shader_rigidbody ); + + u32 H = 20, + V = 16, + verts_count = 0, + tris_count = 0; + + /* box */ + verts_count += 4*6; + tris_count += 2*6; + vg_rb_view.box_count = 2*6; + vg_rb_view.box_start = 0; + + /* sphere */ + verts_count += H*(V-2) + 2; + tris_count += H*2 + (V-2)*(H*2); + vg_rb_view.sphere_count = H*2 + (V-2)*(H*2); + + u32 hdr_size = vg_align8( sizeof(struct vg_rb_mesh_init) ), + vert_size = vg_align8( verts_count * sizeof(rb_view_vert) ), + tris_size = vg_align8( tris_count * 3 * sizeof(u16) ); + + vg_async_item *call = vg_async_alloc( hdr_size + vert_size + tris_size ); + + struct vg_rb_mesh_init *inf = call->payload; + rb_view_vert *verts = ((void *)inf) + hdr_size; + u16 *tris = ((void *)inf) + hdr_size + vert_size; + + inf->verts = verts; + inf->tris = tris; + inf->verts_size = vert_size; + inf->tris_size = tris_size; + + u32 tri_index = 0, + vert_index = 0; + + /* box + * ----------------------------------------------------------- */ + for( u32 i=0; i<6; i ++ ){ + v3f n = {i%3==0,i%3==1,i%3==2}; + if( i >= 3 ) v3_negate( n, n ); + v3f v0, v1; + v3_tangent_basis( n, v0, v1 ); + + rb_view_vert *vs = &verts[vert_index]; + vert_index += 4; + + for( u32 j=0; j<4; j ++ ){ + v3_copy( n, vs[j].n ); + v3_muladds( n, v0, j&0x1?1.0f:-1.0f, vs[j].co ); + v3_muladds( vs[j].co, v1, j&0x2?1.0f:-1.0f, vs[j].co ); + vs[j].co[3] = 0.0f; + } + + tris[tri_index*3+0] = i*4+0; + tris[tri_index*3+1] = i*4+1; + tris[tri_index*3+2] = i*4+3; + tris[tri_index*3+3] = i*4+0; + tris[tri_index*3+4] = i*4+3; + tris[tri_index*3+5] = i*4+2; + tri_index += 2; + } + + /* sphere / capsule + * ----------------------------------------------------------- */ + u32 base = vert_index; + vg_rb_view.sphere_start = tri_index; + v4_copy( (v4f){0,-1,0,0}, verts[vert_index].co ); + v3_copy( (v3f){0,-1,0}, verts[vert_index ++].n ); + + for( u32 x=0; x=(V/2) }; + v4_copy( co, verts[vert_index].co ); + v4_copy( co, verts[vert_index ++].n ); + + if( y < V-2 ){ + tris[tri_index*3+0] = base+1 + ybase*H + x; + tris[tri_index*3+1] = base+1 + (ybase+1)*H + ((x+1)%H); + tris[tri_index*3+2] = base+1 + ybase*H + ((x+1)%H); + tris[tri_index*3+3] = base+1 + ybase*H + x; + tris[tri_index*3+4] = base+1 + (ybase+1)*H + x; + tris[tri_index*3+5] = base+1 + (ybase+1)*H + ((x+1)%H); + tri_index += 2; + } + } + } + + v4_copy( (v4f){0, 1,0,1}, verts[vert_index].co ); + v3_copy( (v3f){0, 1,0}, verts[vert_index ++].n ); + + for( u32 x=0; x