point maps (wip)
[carveJwlIkooP6JGAAIwe30JlM.git] / pointcloud.h
diff --git a/pointcloud.h b/pointcloud.h
new file mode 100644 (file)
index 0000000..b303973
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef POINTCLOUD_H
+#define POINTCLOUD_H
+
+#include "common.h"
+#include "world.h"
+#include "shaders/point_map.h"
+
+#define POINTCLOUD_POINTS 250000
+
+struct pointcloud{
+   GLuint vao, vbo;
+   u32 count;
+
+   v4f control;
+}
+static pointcloud = { .control = {0.0f,0.0f,0.0f,1.0f} };
+
+#pragma pack(push,1)
+struct pointcloud_vert{
+   u16 pos[4];    /* float[  0 -> 1 ] */
+   i8  norm[4];   /* float[ -1 -> 1 ] */
+   u8  colour[4]; /* float[  0 -> 1 ] */
+};
+#pragma pack(pop)
+
+static void async_pointcloud_sub( void *payload, u32 size )
+{
+
+   glBindVertexArray( pointcloud.vao );
+   glBindBuffer( GL_ARRAY_BUFFER, pointcloud.vbo );
+   glBufferSubData( GL_ARRAY_BUFFER, 0, 
+                    sizeof(struct pointcloud_vert)*size, payload );
+   pointcloud.count = size;
+}
+
+static void async_pointcloud_alloc( void *payload, u32 size )
+{
+   glGenVertexArrays( 1, &pointcloud.vao );
+   glGenBuffers( 1, &pointcloud.vbo );
+   glBindVertexArray( pointcloud.vao );
+
+   size_t stride = sizeof( struct pointcloud_vert );
+
+   glBindBuffer( GL_ARRAY_BUFFER, pointcloud.vbo );
+   glBufferData( GL_ARRAY_BUFFER, stride * POINTCLOUD_POINTS, 
+                 payload, GL_DYNAMIC_DRAW );
+
+   /* 0: coordinates */
+   glVertexAttribPointer( 0, 4, GL_UNSIGNED_SHORT, GL_TRUE, stride, (void*)0 );
+   glEnableVertexAttribArray( 0 );
+
+   /* 1: normal */
+   glVertexAttribPointer( 1, 4, GL_BYTE, GL_TRUE, 
+                     stride, (void *)offsetof(struct pointcloud_vert, norm) );
+   glEnableVertexAttribArray( 1 );
+
+   /* 2: colour */
+   glVertexAttribPointer( 2, 4, GL_UNSIGNED_BYTE, GL_TRUE, 
+                     stride, (void *)offsetof(struct pointcloud_vert, colour) );
+   glEnableVertexAttribArray( 2 );
+   VG_CHECK_GL_ERR();
+   pointcloud.count = size;
+}
+
+static void pointcloud_init(void)
+{
+   vg_info( "Generating random test point cloud\n" );
+
+   vg_rand_seed( 2000 );
+   vg_async_item *call = 
+      vg_async_alloc( sizeof(struct pointcloud_vert)*POINTCLOUD_POINTS );
+   struct pointcloud_vert *test_data = call->payload;
+   call->size = POINTCLOUD_POINTS;
+
+   for( u32 i=0; i<POINTCLOUD_POINTS; i++ ){
+      test_data[i].pos[0] = vg_randf64() * 65535.0f;
+      test_data[i].pos[1] = vg_randf64() * 65535.0f;
+      test_data[i].pos[2] = vg_randf64() * 65535.0f;
+
+      v3f norm;
+      vg_rand_dir( norm );
+
+      test_data[i].norm[0] = norm[0] * 127.0f;
+      test_data[i].norm[1] = norm[1] * 127.0f;
+      test_data[i].norm[2] = norm[2] * 127.0f;
+
+      test_data[i].colour[0] = 90;
+      test_data[i].colour[1] = 90;
+      test_data[i].colour[2] = 90;
+      test_data[i].colour[3] = 255;
+   }
+
+   vg_async_dispatch( call, async_pointcloud_alloc );
+   shader_point_map_register();
+}
+
+static void pointcloud_render( world_instance *world, camera *cam, m4x3f model )
+{
+   m4x4f upvmprev;
+   m4x3_expand( model, upvmprev );
+   m4x4_mul( cam->mtx_prev.pv, upvmprev, upvmprev );
+
+   shader_point_map_use();
+   shader_point_map_uPv( cam->mtx.pv );
+   shader_point_map_uPvmPrev( upvmprev );
+   shader_point_map_uMdl( model );
+   shader_point_map_uCamera( cam->pos );
+   shader_point_map_uTime( (v2f){ vg.time, sinf(vg.time) } );
+   shader_point_map_uTransform( pointcloud.control );
+
+   m3x3f mnorm;
+   m3x3_inv( model, mnorm );
+   m3x3_transpose( mnorm, mnorm );
+   shader_point_map_uNormMtx( mnorm );
+
+   glBindVertexArray( pointcloud.vao );
+   glEnable( GL_PROGRAM_POINT_SIZE );
+   glDrawArrays( GL_POINTS, 0, pointcloud.count );
+}
+
+#endif /* POINTCLOUD_H */