7 #include "shaders/point_map.h"
9 #define POINTCLOUD_POINTS 250000
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
,
29 struct pointcloud_vert
{
30 i16 pos
[4]; /* float[ -1 -> 1 ] */
31 u8 colour
[4]; /* float[ 0 -> 1 ] */
35 typedef struct pointcloud_vert pointcloud_vert
;
36 typedef struct pointcloud_buffer pointcloud_buffer
;
38 struct pointcloud_buffer
{
43 k_pointcloud_op_clear
,
44 k_pointcloud_op_append
47 pointcloud_vert buf
[];
50 static void async_pointcloud_sub( void *payload
, u32 size
){
51 glBindVertexArray( pointcloud
.vao
);
52 glBindBuffer( GL_ARRAY_BUFFER
, pointcloud
.vbo
);
54 pointcloud_buffer
*buf
= payload
;
57 if( buf
->op
== k_pointcloud_op_append
){
58 start
= pointcloud
.count
;
59 end
= pointcloud
.count
+ buf
->count
;
66 end
= VG_MIN(POINTCLOUD_POINTS
,end
);
70 u32 size
= count
* sizeof(pointcloud_vert
),
71 offset
= start
* sizeof(pointcloud_vert
);
73 glBufferSubData( GL_ARRAY_BUFFER
, offset
, size
, buf
->buf
);
74 pointcloud
.count
= end
;
78 static void async_pointcloud_alloc( void *payload
, u32 size
){
79 glGenVertexArrays( 1, &pointcloud
.vao
);
80 glGenBuffers( 1, &pointcloud
.vbo
);
81 glBindVertexArray( pointcloud
.vao
);
83 size_t stride
= sizeof( pointcloud_vert
);
85 glBindBuffer( GL_ARRAY_BUFFER
, pointcloud
.vbo
);
86 glBufferData( GL_ARRAY_BUFFER
, stride
* POINTCLOUD_POINTS
,
87 NULL
, GL_DYNAMIC_DRAW
);
90 glVertexAttribPointer( 0, 4, GL_SHORT
, GL_TRUE
, stride
, (void*)0 );
91 glEnableVertexAttribArray( 0 );
94 glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE
, GL_TRUE
,
95 stride
, (void *)offsetof(pointcloud_vert
, colour
) );
96 glEnableVertexAttribArray( 1 );
100 static void pointcloud_init(void){
101 vg_async_call( async_pointcloud_alloc
, NULL
, 0 );
102 shader_point_map_register();
105 static void pointcloud_animate( enum pointcloud_anim anim
){
106 pointcloud
.anim
= anim
;
107 pointcloud
.anim_start
= vg
.time
;
110 static int pointcloud_idle(void){
111 if( pointcloud
.anim
>= k_pointcloud_anim_idle_any
) return 1;
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
;
120 if( pointcloud
.anim
== k_pointcloud_anim_hiding
){
122 pointcloud
.visibility
= 0.0f
;
123 pointcloud
.anim
= k_pointcloud_anim_idle_closed
;
125 else pointcloud
.visibility
= 1.0f
-t
;
127 else if( pointcloud
.anim
== k_pointcloud_anim_opening
){
129 pointcloud
.visibility
= 1.0f
;
130 pointcloud
.anim
= k_pointcloud_anim_idle_open
;
132 else pointcloud
.visibility
= t
;
136 if( pointcloud
.visibility
== 0.0f
) return;
139 m4x3_expand( model
, upvmprev
);
140 m4x4_mul( cam
->mtx_prev
.pv
, upvmprev
, upvmprev
);
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
,
150 glBindVertexArray( pointcloud
.vao
);
151 glEnable( GL_PROGRAM_POINT_SIZE
);
152 glDrawArrays( GL_POINTS
, 0, pointcloud
.count
);
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
;
159 for( u32 i
=0; i
<4; i
++ )
160 vert
->colour
[i
] = colour
[i
] * 255.0f
;
163 static void pointcloud_async_end(void *_
, u32 __
){
164 pointcloud_animate( k_pointcloud_anim_opening
);
167 static void pointcloud_clear_async(void *_
, u32 __
){
168 pointcloud
.count
= 0;
169 pointcloud_animate( k_pointcloud_anim_opening
);
172 #endif /* POINTCLOUD_H */