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