1 /* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved */
9 struct vg_lines vg_lines
;
12 * FIXME: The line buffer sometimes overflows. Low priority
15 static struct vg_shader _shader_lines
= {
22 "layout (location=0) in vec3 a_co;"
23 "layout (location=1) in vec4 a_colour;"
29 " vec4 vert_pos = uPv * vec4( a_co, 1.0 );"
30 " s_colour = a_colour;"
31 " gl_Position = vert_pos;"
44 " FragColor = s_colour;"
49 #define VG_LINES_BUFFER_SIZE 50000 * sizeof( struct vg_lines_vert )
51 static void async_vg_lines_init( void *payload
, u32 payload_size
)
53 glGenVertexArrays( 1, &vg_lines
.vao
);
54 glGenBuffers( 1, &vg_lines
.vbo
);
55 glBindVertexArray( vg_lines
.vao
);
56 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
58 glBufferData( GL_ARRAY_BUFFER
, VG_LINES_BUFFER_SIZE
, NULL
, GL_DYNAMIC_DRAW
);
59 glBindVertexArray( vg_lines
.vao
);
63 glVertexAttribPointer(
68 sizeof( struct vg_lines_vert
),
71 glEnableVertexAttribArray( 0 );
73 glVertexAttribPointer(
78 sizeof( struct vg_lines_vert
),
79 (void*)(offsetof( struct vg_lines_vert
, colour
))
81 glEnableVertexAttribArray( 1 );
86 void vg_lines_init(void)
88 vg_lines
.vertex_buffer
=
89 vg_create_linear_allocator( vg_mem
.rtmemory
,
90 VG_LINES_BUFFER_SIZE
, VG_MEMORY_REALTIME
);
92 vg_async_call( async_vg_lines_init
, NULL
, 0 );
94 vg_console_reg_var( "vg_lines", &vg_lines
.render
, k_var_dtype_i32
,
96 vg_shader_register( &_shader_lines
);
99 void vg_lines_drawall( void )
101 glUseProgram( _shader_lines
.id
);
103 glUniformMatrix4fv( glGetUniformLocation( _shader_lines
.id
, "uPv" ),
104 1, GL_FALSE
, (float *)vg
.pv
);
106 glBindVertexArray( vg_lines
.vao
);
107 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
109 u32 bufusage
= vg_linear_get_cur(vg_lines
.vertex_buffer
);
110 glBufferSubData( GL_ARRAY_BUFFER
, 0, bufusage
, vg_lines
.vertex_buffer
);
112 glEnable( GL_BLEND
);
113 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
114 glBlendEquation( GL_FUNC_ADD
);
116 if( vg_lines
.render
)
117 glDrawArrays( GL_LINES
, 0, bufusage
/ sizeof(struct vg_lines_vert
) );
119 glDisable( GL_BLEND
);
120 vg_linear_clear( vg_lines
.vertex_buffer
);
123 void vg_line2( line_co from
, line_co to
, u32 fc
, u32 tc
)
125 if( !vg_lines
.enabled
) return;
127 u32 size
= 2 * sizeof(struct vg_lines_vert
);
128 struct vg_lines_vert
*v
= vg_linear_alloc( vg_lines
.vertex_buffer
, size
);
130 v3_copy( from
, v
[0].co
);
131 v3_copy( to
, v
[1].co
);
137 void vg_line( line_co from
, line_co to
, u32 colour
)
139 if( !vg_lines
.enabled
) return;
141 vg_line2( from
, to
, colour
, colour
);
144 void vg_line_arrow( line_co co
, line_co dir
, float size
, u32 colour
)
146 if( !vg_lines
.enabled
) return;
148 v3f p1
, tx
, ty
, p2
, p3
;
149 v3_muladds( co
, dir
, size
, p1
);
150 v3_tangent_basis( dir
, tx
, ty
);
152 v3_muladds( p1
, dir
, -size
* 0.125f
, p2
);
153 v3_muladds( p2
, ty
, size
* 0.125f
, p3
);
154 v3_muladds( p2
, ty
, -size
* 0.125f
, p2
);
156 vg_line( co
, p1
, colour
);
157 vg_line( p1
, p2
, colour
);
158 vg_line( p1
, p3
, colour
);
161 void vg_line_box_verts( boxf box
, v3f verts
[8] )
163 if( !vg_lines
.enabled
) return;
165 for( u32 i
=0; i
<8; i
++ ){
166 for( u32 j
=0; j
<3; j
++ ){
167 verts
[i
][j
] = i
&(0x1<<j
)? box
[1][j
]: box
[0][j
];
172 void vg_line_mesh( v3f verts
[], u32 indices
[][2], u32 indice_count
,u32 colour
){
173 if( !vg_lines
.enabled
) return;
175 for( u32 i
=0; i
<indice_count
; i
++ ){
176 vg_line( verts
[indices
[i
][0]], verts
[indices
[i
][1]], colour
);
180 void vg_line_boxf( boxf box
, u32 colour
)
182 if( !vg_lines
.enabled
) return;
185 vg_line_box_verts( box
, verts
);
186 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
187 {4,5},{5,7},{7,6},{6,4},
188 {4,0},{5,1},{6,2},{7,3}};
190 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
193 void vg_line_boxf_transformed( m4x3f m
, boxf box
, u32 colour
)
195 if( !vg_lines
.enabled
) return;
198 vg_line_box_verts( box
, verts
);
200 for( u32 i
=0; i
<8; i
++ ){
201 m4x3_mulv( m
, verts
[i
], verts
[i
] );
204 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
205 {4,5},{5,7},{7,6},{6,4},
206 {4,0},{5,1},{6,2},{7,3}};
208 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
211 void vg_line_cross(v3f pos
,u32 colour
, float scale
)
213 if( !vg_lines
.enabled
) return;
216 v3_add( (v3f
){ scale
,0.0f
,0.0f
}, pos
, p0
);
217 v3_add( (v3f
){-scale
,0.0f
,0.0f
}, pos
, p1
);
218 vg_line( p0
, p1
, colour
);
219 v3_add( (v3f
){0.0f
, scale
,0.0f
}, pos
, p0
);
220 v3_add( (v3f
){0.0f
,-scale
,0.0f
}, pos
, p1
);
221 vg_line( p0
, p1
, colour
);
222 v3_add( (v3f
){0.0f
,0.0f
, scale
}, pos
, p0
);
223 v3_add( (v3f
){0.0f
,0.0f
,-scale
}, pos
, p1
);
224 vg_line( p0
, p1
, colour
);
227 void vg_line_point( v3f pt
, float size
, u32 colour
)
229 if( !vg_lines
.enabled
) return;
233 { pt
[0]-size
, pt
[1]-size
, pt
[2]-size
},
234 { pt
[0]+size
, pt
[1]+size
, pt
[2]+size
}
237 vg_line_boxf( box
, colour
);
241 void vg_line_sphere( m4x3f m
, float radius
, u32 colour
)
243 if( !vg_lines
.enabled
) return;
245 v3f ly
= { 0.0f
, 0.0f
, radius
},
246 lx
= { 0.0f
, radius
, 0.0f
},
247 lz
= { 0.0f
, 0.0f
, radius
};
249 for( int i
=0; i
<16; i
++ ){
250 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
254 v3f py
= { s
*radius
, 0.0f
, c
*radius
},
255 px
= { s
*radius
, c
*radius
, 0.0f
},
256 pz
= { 0.0f
, s
*radius
, c
*radius
};
258 v3f p0
, p1
, p2
, p3
, p4
, p5
;
259 m4x3_mulv( m
, py
, p0
);
260 m4x3_mulv( m
, ly
, p1
);
261 m4x3_mulv( m
, px
, p2
);
262 m4x3_mulv( m
, lx
, p3
);
263 m4x3_mulv( m
, pz
, p4
);
264 m4x3_mulv( m
, lz
, p5
);
266 vg_line( p0
, p1
, colour
== 0x00? 0xff00ff00: colour
);
267 vg_line( p2
, p3
, colour
== 0x00? 0xff0000ff: colour
);
268 vg_line( p4
, p5
, colour
== 0x00? 0xffff0000: colour
);
276 void vg_line_capsule( m4x3f m
, float radius
, float h
, u32 colour
)
278 if( !vg_lines
.enabled
) return;
280 v3f ly
= { 0.0f
, 0.0f
, radius
},
281 lx
= { 0.0f
, radius
, 0.0f
},
282 lz
= { 0.0f
, 0.0f
, radius
};
284 float s0
= sinf(0.0f
)*radius
,
285 c0
= cosf(0.0f
)*radius
;
287 v3f p0
, p1
, up
, right
, forward
;
288 m3x3_mulv( m
, (v3f
){0.0f
,1.0f
,0.0f
}, up
);
289 m3x3_mulv( m
, (v3f
){1.0f
,0.0f
,0.0f
}, right
);
290 m3x3_mulv( m
, (v3f
){0.0f
,0.0f
,-1.0f
}, forward
);
291 v3_muladds( m
[3], up
, -h
*0.5f
+radius
, p0
);
292 v3_muladds( m
[3], up
, h
*0.5f
-radius
, p1
);
295 v3_muladds( p0
, right
, radius
, a0
);
296 v3_muladds( p1
, right
, radius
, a1
);
297 v3_muladds( p0
, forward
, radius
, b0
);
298 v3_muladds( p1
, forward
, radius
, b1
);
299 vg_line( a0
, a1
, colour
);
300 vg_line( b0
, b1
, colour
);
302 v3_muladds( p0
, right
, -radius
, a0
);
303 v3_muladds( p1
, right
, -radius
, a1
);
304 v3_muladds( p0
, forward
, -radius
, b0
);
305 v3_muladds( p1
, forward
, -radius
, b1
);
306 vg_line( a0
, a1
, colour
);
307 vg_line( b0
, b1
, colour
);
309 for( int i
=0; i
<16; i
++ ){
310 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
314 v3f e0
= { s0
, 0.0f
, c0
},
315 e1
= { s1
, 0.0f
, c1
},
316 e2
= { s0
, c0
, 0.0f
},
317 e3
= { s1
, c1
, 0.0f
},
318 e4
= { 0.0f
, c0
, s0
},
319 e5
= { 0.0f
, c1
, s1
};
321 m3x3_mulv( m
, e0
, e0
);
322 m3x3_mulv( m
, e1
, e1
);
323 m3x3_mulv( m
, e2
, e2
);
324 m3x3_mulv( m
, e3
, e3
);
325 m3x3_mulv( m
, e4
, e4
);
326 m3x3_mulv( m
, e5
, e5
);
328 v3_add( p0
, e0
, a0
);
329 v3_add( p0
, e1
, a1
);
330 v3_add( p1
, e0
, b0
);
331 v3_add( p1
, e1
, b1
);
333 vg_line( a0
, a1
, colour
);
334 vg_line( b0
, b1
, colour
);
337 v3_add( p0
, e2
, a0
);
338 v3_add( p0
, e3
, a1
);
339 v3_add( p0
, e4
, b0
);
340 v3_add( p0
, e5
, b1
);
343 v3_add( p1
, e2
, a0
);
344 v3_add( p1
, e3
, a1
);
345 v3_add( p1
, e4
, b0
);
346 v3_add( p1
, e5
, b1
);
349 vg_line( a0
, a1
, colour
);
350 vg_line( b0
, b1
, colour
);