6 #include "shaders/point_map.h"
8 #define POINTCLOUD_POINTS 250000
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
,
28 struct pointcloud_vert
{
29 i16 pos
[4]; /* float[ -1 -> 1 ] */
30 u8 colour
[4]; /* float[ 0 -> 1 ] */
34 typedef struct pointcloud_vert pointcloud_vert
;
35 typedef struct pointcloud_buffer pointcloud_buffer
;
37 struct pointcloud_buffer
{
42 k_pointcloud_op_clear
,
43 k_pointcloud_op_append
46 pointcloud_vert buf
[];
49 static void async_pointcloud_sub( void *payload
, u32 size
){
50 glBindVertexArray( pointcloud
.vao
);
51 glBindBuffer( GL_ARRAY_BUFFER
, pointcloud
.vbo
);
53 pointcloud_buffer
*buf
= payload
;
56 if( buf
->op
== k_pointcloud_op_append
){
57 start
= pointcloud
.count
;
58 end
= pointcloud
.count
+ buf
->count
;
65 end
= VG_MIN(POINTCLOUD_POINTS
,end
);
69 u32 size
= count
* sizeof(pointcloud_vert
),
70 offset
= start
* sizeof(pointcloud_vert
);
72 glBufferSubData( GL_ARRAY_BUFFER
, offset
, size
, buf
->buf
);
73 pointcloud
.count
= end
;
77 static void async_pointcloud_alloc( void *payload
, u32 size
){
78 glGenVertexArrays( 1, &pointcloud
.vao
);
79 glGenBuffers( 1, &pointcloud
.vbo
);
80 glBindVertexArray( pointcloud
.vao
);
82 size_t stride
= sizeof( pointcloud_vert
);
84 glBindBuffer( GL_ARRAY_BUFFER
, pointcloud
.vbo
);
85 glBufferData( GL_ARRAY_BUFFER
, stride
* POINTCLOUD_POINTS
,
86 NULL
, GL_DYNAMIC_DRAW
);
89 glVertexAttribPointer( 0, 4, GL_SHORT
, GL_TRUE
, stride
, (void*)0 );
90 glEnableVertexAttribArray( 0 );
93 glVertexAttribPointer( 1, 4, GL_UNSIGNED_BYTE
, GL_TRUE
,
94 stride
, (void *)offsetof(pointcloud_vert
, colour
) );
95 glEnableVertexAttribArray( 1 );
99 static void pointcloud_init(void){
100 vg_async_call( async_pointcloud_alloc
, NULL
, 0 );
101 shader_point_map_register();
104 static void pointcloud_animate( enum pointcloud_anim anim
){
105 pointcloud
.anim
= anim
;
106 pointcloud
.anim_start
= vg
.time
;
109 static int pointcloud_idle(void){
110 if( pointcloud
.anim
>= k_pointcloud_anim_idle_any
) return 1;
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
;
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 #endif /* POINTCLOUD_H */