steam friend/block info on remote players structures
[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,
18 k_pointcloud_anim_hiding,
19 k_pointcloud_anim_idle_any,
20 k_pointcloud_anim_idle_open,
21 k_pointcloud_anim_idle_closed,
22 }
23 anim;
24 }
25 static pointcloud;
26
27 #pragma pack(push,1)
28 struct pointcloud_vert{
29 i16 pos[4]; /* float[ -1 -> 1 ] */
30 u8 colour[4]; /* float[ 0 -> 1 ] */
31 };
32 #pragma pack(pop)
33
34 typedef struct pointcloud_vert pointcloud_vert;
35 typedef struct pointcloud_buffer pointcloud_buffer;
36
37 struct pointcloud_buffer{
38 u32 max, count;
39 boxf boundary;
40
41 enum pointcloud_op{
42 k_pointcloud_op_clear,
43 k_pointcloud_op_append
44 }
45 op;
46 pointcloud_vert buf[];
47 };
48
49 static void async_pointcloud_sub( void *payload, u32 size ){
50 glBindVertexArray( pointcloud.vao );
51 glBindBuffer( GL_ARRAY_BUFFER, pointcloud.vbo );
52
53 pointcloud_buffer *buf = payload;
54
55 u32 start,end,count;
56 if( buf->op == k_pointcloud_op_append ){
57 start = pointcloud.count;
58 end = pointcloud.count + buf->count;
59 }
60 else{
61 start = 0;
62 end = buf->count;
63 }
64
65 end = VG_MIN(POINTCLOUD_POINTS,end);
66 count = end-start;
67
68 if( count ){
69 u32 size = count * sizeof(pointcloud_vert),
70 offset = start * sizeof(pointcloud_vert);
71
72 glBufferSubData( GL_ARRAY_BUFFER, offset, size, buf->buf );
73 pointcloud.count = end;
74 }
75 }
76
77 static void async_pointcloud_alloc( void *payload, u32 size ){
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 vg_async_call( async_pointcloud_alloc, NULL, 0 );
101 shader_point_map_register();
102 }
103
104 static void pointcloud_animate( enum pointcloud_anim anim ){
105 pointcloud.anim = anim;
106 pointcloud.anim_start = vg.time;
107 }
108
109 static int pointcloud_idle(void){
110 if( pointcloud.anim >= k_pointcloud_anim_idle_any ) return 1;
111 else return 0;
112 }
113
114 static
115 void pointcloud_render( world_instance *world, 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 #endif /* POINTCLOUD_H */