handplants
[carveJwlIkooP6JGAAIwe30JlM.git] / pointcloud.h
1 #if 0
2 //#ifndef POINTCLOUD_H
3 #define POINTCLOUD_H
4
5 #include "common.h"
6 #include "world.h"
7 #include "shaders/point_map.h"
8
9 #define POINTCLOUD_POINTS 250000
10
11 struct pointcloud{
12 GLuint vao, vbo;
13 u32 count;
14
15 f64 anim_start;
16 f32 visibility;
17 enum pointcloud_anim{
18 k_pointcloud_anim_opening,
19 k_pointcloud_anim_hiding,
20 k_pointcloud_anim_idle_any,
21 k_pointcloud_anim_idle_open,
22 k_pointcloud_anim_idle_closed,
23 }
24 anim;
25 }
26 static pointcloud;
27
28 #pragma pack(push,1)
29 struct pointcloud_vert{
30 i16 pos[4]; /* float[ -1 -> 1 ] */
31 u8 colour[4]; /* float[ 0 -> 1 ] */
32 };
33 #pragma pack(pop)
34
35 typedef struct pointcloud_vert pointcloud_vert;
36 typedef struct pointcloud_buffer pointcloud_buffer;
37
38 struct pointcloud_buffer{
39 u32 max, count;
40 boxf boundary;
41
42 enum pointcloud_op{
43 k_pointcloud_op_clear,
44 k_pointcloud_op_append
45 }
46 op;
47 pointcloud_vert buf[];
48 };
49
50 static void async_pointcloud_sub( void *payload, u32 size ){
51 glBindVertexArray( pointcloud.vao );
52 glBindBuffer( GL_ARRAY_BUFFER, pointcloud.vbo );
53
54 pointcloud_buffer *buf = payload;
55
56 u32 start,end,count;
57 if( buf->op == k_pointcloud_op_append ){
58 start = pointcloud.count;
59 end = pointcloud.count + buf->count;
60 }
61 else{
62 start = 0;
63 end = buf->count;
64 }
65
66 end = VG_MIN(POINTCLOUD_POINTS,end);
67 count = end-start;
68
69 if( count ){
70 u32 size = count * sizeof(pointcloud_vert),
71 offset = start * sizeof(pointcloud_vert);
72
73 glBufferSubData( GL_ARRAY_BUFFER, offset, size, buf->buf );
74 pointcloud.count = end;
75 }
76 }
77
78 static void async_pointcloud_alloc( void *payload, u32 size ){
79 glGenVertexArrays( 1, &pointcloud.vao );
80 glGenBuffers( 1, &pointcloud.vbo );
81 glBindVertexArray( pointcloud.vao );
82
83 size_t stride = sizeof( pointcloud_vert );
84
85 glBindBuffer( GL_ARRAY_BUFFER, pointcloud.vbo );
86 glBufferData( GL_ARRAY_BUFFER, stride * POINTCLOUD_POINTS,
87 NULL, GL_DYNAMIC_DRAW );
88
89 /* 0: coordinates */
90 glVertexAttribPointer( 0, 4, GL_SHORT, GL_TRUE, stride, (void*)0 );
91 glEnableVertexAttribArray( 0 );
92
93 /* 1: colour */
94 glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE, GL_TRUE,
95 stride, (void *)offsetof(pointcloud_vert, colour) );
96 glEnableVertexAttribArray( 1 );
97 VG_CHECK_GL_ERR();
98 }
99
100 static void pointcloud_init(void){
101 vg_async_call( async_pointcloud_alloc, NULL, 0 );
102 shader_point_map_register();
103 }
104
105 static void pointcloud_animate( enum pointcloud_anim anim ){
106 pointcloud.anim = anim;
107 pointcloud.anim_start = vg.time;
108 }
109
110 static int pointcloud_idle(void){
111 if( pointcloud.anim >= k_pointcloud_anim_idle_any ) return 1;
112 else return 0;
113 }
114
115 static void pointcloud_render( camera *cam, m4x3f model ){
116 if( pointcloud.anim < k_pointcloud_anim_idle_any ){
117 f32 const k_transition = 0.6f;
118 f32 t = (vg.time - pointcloud.anim_start) / k_transition;
119
120 if( pointcloud.anim == k_pointcloud_anim_hiding ){
121 if( t > 1.0f ){
122 pointcloud.visibility = 0.0f;
123 pointcloud.anim = k_pointcloud_anim_idle_closed;
124 }
125 else pointcloud.visibility = 1.0f-t;
126 }
127 else if( pointcloud.anim == k_pointcloud_anim_opening ){
128 if( t > 1.0f ){
129 pointcloud.visibility = 1.0f;
130 pointcloud.anim = k_pointcloud_anim_idle_open;
131 }
132 else pointcloud.visibility = t;
133 }
134 }
135
136 if( pointcloud.visibility == 0.0f ) return;
137
138 m4x4f upvmprev;
139 m4x3_expand( model, upvmprev );
140 m4x4_mul( cam->mtx_prev.pv, upvmprev, upvmprev );
141
142 shader_point_map_use();
143 shader_point_map_uPv( cam->mtx.pv );
144 shader_point_map_uPvmPrev( upvmprev );
145 shader_point_map_uMdl( model );
146 shader_point_map_uCamera( cam->pos );
147 shader_point_map_uAnim( (v4f){ 32, 1.0f-pointcloud.visibility,
148 0.0f, vg.time } );
149
150 glBindVertexArray( pointcloud.vao );
151 glEnable( GL_PROGRAM_POINT_SIZE );
152 glDrawArrays( GL_POINTS, 0, pointcloud.count );
153 }
154
155 static void pointcloud_packvert( pointcloud_vert *vert, v3f pos, v4f colour ){
156 for( u32 i=0; i<3; i++ )
157 vert->pos[i] = (pos[i]-0.5f) * 32767.0f;
158
159 for( u32 i=0; i<4; i++ )
160 vert->colour[i] = colour[i] * 255.0f;
161 }
162
163 static void pointcloud_async_end(void *_, u32 __){
164 pointcloud_animate( k_pointcloud_anim_opening );
165 }
166
167 static void pointcloud_clear_async(void *_, u32 __){
168 pointcloud.count = 0;
169 pointcloud_animate( k_pointcloud_anim_opening );
170 }
171
172 #endif /* POINTCLOUD_H */