performance wins!
[carveJwlIkooP6JGAAIwe30JlM.git] / pointcloud.h
index b303973c6e6c46697ccdcc186b0c7a609e7fb456..89621a4613d800364049de09f3f55f1eaa343174 100644 (file)
@@ -1,4 +1,5 @@
-#ifndef POINTCLOUD_H
+#if 0
+//#ifndef POINTCLOUD_H
 #define POINTCLOUD_H
 
 #include "common.h"
@@ -11,91 +12,129 @@ struct pointcloud{
    GLuint vao, vbo;
    u32 count;
 
-   v4f control;
+   f64 anim_start;
+   f32 visibility;
+   enum pointcloud_anim{
+      k_pointcloud_anim_opening,
+      k_pointcloud_anim_hiding,
+      k_pointcloud_anim_idle_any,
+      k_pointcloud_anim_idle_open,
+      k_pointcloud_anim_idle_closed,
+   }
+   anim;
 }
-static pointcloud = { .control = {0.0f,0.0f,0.0f,1.0f} };
+static pointcloud;
 
 #pragma pack(push,1)
 struct pointcloud_vert{
-   u16 pos[4];    /* float[  0 -> 1 ] */
-   i8  norm[4];   /* float[ -1 -> 1 ] */
+   i16 pos[4];    /* float[ -1 -> 1 ] */
    u8  colour[4]; /* float[  0 -> 1 ] */
 };
 #pragma pack(pop)
 
-static void async_pointcloud_sub( void *payload, u32 size )
-{
+typedef struct pointcloud_vert pointcloud_vert;
+typedef struct pointcloud_buffer pointcloud_buffer;
+
+struct pointcloud_buffer{
+   u32 max, count;
+   boxf boundary;
+
+   enum pointcloud_op{
+      k_pointcloud_op_clear,
+      k_pointcloud_op_append
+   }
+   op;
+   pointcloud_vert buf[];
+};
 
+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;
+
+   pointcloud_buffer *buf = payload;
+
+   u32 start,end,count;
+   if( buf->op == k_pointcloud_op_append ){
+      start = pointcloud.count;
+      end = pointcloud.count + buf->count;
+   }
+   else{
+      start = 0;
+      end = buf->count;
+   }
+
+   end = VG_MIN(POINTCLOUD_POINTS,end);
+   count = end-start;
+
+   if( count ){
+      u32 size   = count * sizeof(pointcloud_vert),
+          offset = start * sizeof(pointcloud_vert);
+
+      glBufferSubData( GL_ARRAY_BUFFER, offset, size, buf->buf );
+      pointcloud.count = end;
+   }
 }
 
-static void async_pointcloud_alloc( void *payload, u32 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 );
+   size_t stride = sizeof( pointcloud_vert );
 
    glBindBuffer( GL_ARRAY_BUFFER, pointcloud.vbo );
    glBufferData( GL_ARRAY_BUFFER, stride * POINTCLOUD_POINTS, 
-                 payload, GL_DYNAMIC_DRAW );
+                 NULL, GL_DYNAMIC_DRAW );
 
    /* 0: coordinates */
-   glVertexAttribPointer( 0, 4, GL_UNSIGNED_SHORT, GL_TRUE, stride, (void*)0 );
+   glVertexAttribPointer( 0, 4, GL_SHORT, GL_TRUE, stride, (void*)0 );
    glEnableVertexAttribArray( 0 );
 
-   /* 1: normal */
-   glVertexAttribPointer( 1, 4, GL_BYTE, GL_TRUE, 
-                     stride, (void *)offsetof(struct pointcloud_vert, norm) );
+   /* 1: colour */
+   glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 
+                     stride, (void *)offsetof(pointcloud_vert, colour) );
    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;
+static void pointcloud_init(void){
+   vg_async_call( async_pointcloud_alloc, NULL, 0 );
+   shader_point_map_register();
+}
 
-      v3f norm;
-      vg_rand_dir( norm );
+static void pointcloud_animate( enum pointcloud_anim anim ){
+   pointcloud.anim = anim;
+   pointcloud.anim_start = vg.time;
+}
 
-      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;
+static int pointcloud_idle(void){
+   if( pointcloud.anim >= k_pointcloud_anim_idle_any ) return 1;
+   else return 0;
+}
 
-      test_data[i].colour[0] = 90;
-      test_data[i].colour[1] = 90;
-      test_data[i].colour[2] = 90;
-      test_data[i].colour[3] = 255;
+static void pointcloud_render( camera *cam, m4x3f model ){
+   if( pointcloud.anim < k_pointcloud_anim_idle_any ){
+      f32 const k_transition = 0.6f;
+      f32 t = (vg.time - pointcloud.anim_start) / k_transition;
+
+      if( pointcloud.anim == k_pointcloud_anim_hiding ){
+         if( t > 1.0f ){
+            pointcloud.visibility = 0.0f;
+            pointcloud.anim = k_pointcloud_anim_idle_closed;
+         }
+         else pointcloud.visibility = 1.0f-t;
+      }
+      else if( pointcloud.anim == k_pointcloud_anim_opening ){
+         if( t > 1.0f ){
+            pointcloud.visibility = 1.0f;
+            pointcloud.anim = k_pointcloud_anim_idle_open;
+         }
+         else pointcloud.visibility = t;
+      }
    }
 
-   vg_async_dispatch( call, async_pointcloud_alloc );
-   shader_point_map_register();
-}
+   if( pointcloud.visibility == 0.0f ) return;
 
-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 );
@@ -105,17 +144,29 @@ static void pointcloud_render( world_instance *world, camera *cam, m4x3f model )
    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 );
+   shader_point_map_uAnim( (v4f){ 32, 1.0f-pointcloud.visibility, 
+                                  0.0f, vg.time } );
 
    glBindVertexArray( pointcloud.vao );
    glEnable( GL_PROGRAM_POINT_SIZE );
    glDrawArrays( GL_POINTS, 0, pointcloud.count );
 }
 
+static void pointcloud_packvert( pointcloud_vert *vert, v3f pos, v4f colour ){
+   for( u32 i=0; i<3; i++ )
+      vert->pos[i] = (pos[i]-0.5f) * 32767.0f;
+
+   for( u32 i=0; i<4; i++ )
+      vert->colour[i] = colour[i] * 255.0f;
+}
+
+static void pointcloud_async_end(void *_, u32 __){
+   pointcloud_animate( k_pointcloud_anim_opening );
+}
+
+static void pointcloud_clear_async(void *_, u32 __){
+   pointcloud.count = 0;
+   pointcloud_animate( k_pointcloud_anim_opening );
+}
+
 #endif /* POINTCLOUD_H */