1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
11 #define VG__RED 0xff0000ff
12 #define VG__GREEN 0xff00ff00
13 #define VG__BLUE 0xffff0000
14 #define VG__WHITE 0xffffffff
15 #define VG__BLACK 0xff000000
16 #define VG__CLEAR 0x00ffffff
17 #define VG__PINK 0xffff00ff
18 #define VG__YELOW 0xff00ffff
19 #define VG__CYAN 0xffffff00
20 #define VG__NONE 0x00000000
22 static struct vg_shader _shader_lines
= {
30 "layout (location=0) in vec3 a_co;"
31 "layout (location=1) in vec4 a_colour;"
37 " vec4 vert_pos = uPv * vec4( a_co, 1.0 );"
38 " s_colour = a_colour;"
39 " gl_Position = vert_pos;"
52 " FragColor = s_colour;"
71 VG_STATIC
void async_vg_lines_init( void *payload
, u32 payload_size
){
72 glGenVertexArrays( 1, &vg_lines
.vao
);
73 glGenBuffers( 1, &vg_lines
.vbo
);
74 glBindVertexArray( vg_lines
.vao
);
75 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
77 u32 size
= 50000 * sizeof( struct vg_lines_vert
);
79 vg_lines
.vertex_buffer
=
80 vg_create_linear_allocator(vg_mem
.rtmemory
, size
, VG_MEMORY_REALTIME
);
82 glBufferData( GL_ARRAY_BUFFER
, size
, NULL
, GL_DYNAMIC_DRAW
);
83 glBindVertexArray( vg_lines
.vao
);
87 glVertexAttribPointer(
92 sizeof( struct vg_lines_vert
),
95 glEnableVertexAttribArray( 0 );
97 glVertexAttribPointer(
102 sizeof( struct vg_lines_vert
),
103 (void*)(offsetof( struct vg_lines_vert
, colour
))
105 glEnableVertexAttribArray( 1 );
108 vg_lines
.allow_input
= 1;
111 VG_STATIC
void vg_lines_init(void){
112 vg_async_call( async_vg_lines_init
, NULL
, 0 );
114 vg_console_reg_var( "vg_lines", &vg_lines
.draw
, k_var_dtype_i32
,
116 vg_shader_register( &_shader_lines
);
120 VG_STATIC
void vg_lines_drawall( void ){
121 glUseProgram( _shader_lines
.id
);
123 glUniformMatrix4fv( glGetUniformLocation( _shader_lines
.id
, "uPv" ),
124 1, GL_FALSE
, (float *)vg
.pv
);
126 glBindVertexArray( vg_lines
.vao
);
127 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
129 u32 bufusage
= vg_linear_get_cur(vg_lines
.vertex_buffer
);
131 glBufferSubData( GL_ARRAY_BUFFER
, 0, bufusage
, vg_lines
.vertex_buffer
);
133 glEnable( GL_BLEND
);
134 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
135 glBlendEquation( GL_FUNC_ADD
);
138 glDrawArrays( GL_LINES
, 0, bufusage
/ sizeof(struct vg_lines_vert
) );
140 glDisable( GL_BLEND
);
141 vg_linear_clear( vg_lines
.vertex_buffer
);
144 VG_STATIC
void vg_line2( line_co from
, line_co to
, u32 fc
, u32 tc
){
145 if( !vg_lines
.allow_input
) return;
146 if( !vg_lines
.draw
) return;
148 u32 size
= 2 * sizeof(struct vg_lines_vert
);
149 struct vg_lines_vert
*v
= vg_linear_alloc( vg_lines
.vertex_buffer
, size
);
151 v3_copy( from
, v
[0].co
);
152 v3_copy( to
, v
[1].co
);
158 VG_STATIC
void vg_line( line_co from
, line_co to
, u32 colour
){
159 vg_line2( from
, to
, colour
, colour
);
162 VG_STATIC
void vg_line_arrow( line_co co
, line_co dir
, float size
, u32 colour
){
163 v3f p1
, tx
, ty
, p2
, p3
;
164 v3_muladds( co
, dir
, size
, p1
);
165 v3_tangent_basis( dir
, tx
, ty
);
167 v3_muladds( p1
, dir
, -size
* 0.125f
, p2
);
168 v3_muladds( p2
, ty
, size
* 0.125f
, p3
);
169 v3_muladds( p2
, ty
, -size
* 0.125f
, p2
);
171 vg_line( co
, p1
, colour
);
172 vg_line( p1
, p2
, colour
);
173 vg_line( p1
, p3
, colour
);
176 VG_STATIC
void vg_line_box_verts( boxf box
, v3f verts
[8] ){
177 for( u32 i
=0; i
<8; i
++ ){
178 for( u32 j
=0; j
<3; j
++ ){
179 verts
[i
][j
] = i
&(0x1<<j
)? box
[1][j
]: box
[0][j
];
184 VG_STATIC
void vg_line_mesh( v3f verts
[], u32 indices
[][2], u32 indice_count
,
186 for( u32 i
=0; i
<indice_count
; i
++ ){
187 vg_line( verts
[indices
[i
][0]], verts
[indices
[i
][1]], colour
);
191 VG_STATIC
void vg_line_boxf( boxf box
, u32 colour
){
193 vg_line_box_verts( box
, verts
);
194 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
195 {4,5},{5,7},{7,6},{6,4},
196 {4,0},{5,1},{6,2},{7,3}};
198 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
201 VG_STATIC
void vg_line_boxf_transformed( m4x3f m
, boxf box
, u32 colour
){
203 vg_line_box_verts( box
, verts
);
205 for( u32 i
=0; i
<8; i
++ ){
206 m4x3_mulv( m
, verts
[i
], verts
[i
] );
209 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
210 {4,5},{5,7},{7,6},{6,4},
211 {4,0},{5,1},{6,2},{7,3}};
213 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
216 VG_STATIC
void vg_line_cross(v3f pos
,u32 colour
, float scale
){
218 v3_add( (v3f
){ scale
,0.0f
,0.0f
}, pos
, p0
);
219 v3_add( (v3f
){-scale
,0.0f
,0.0f
}, pos
, p1
);
220 vg_line( p0
, p1
, colour
);
221 v3_add( (v3f
){0.0f
, scale
,0.0f
}, pos
, p0
);
222 v3_add( (v3f
){0.0f
,-scale
,0.0f
}, pos
, p1
);
223 vg_line( p0
, p1
, colour
);
224 v3_add( (v3f
){0.0f
,0.0f
, scale
}, pos
, p0
);
225 v3_add( (v3f
){0.0f
,0.0f
,-scale
}, pos
, p1
);
226 vg_line( p0
, p1
, colour
);
229 VG_STATIC
void vg_line_point( v3f pt
, float size
, u32 colour
){
232 { pt
[0]-size
, pt
[1]-size
, pt
[2]-size
},
233 { pt
[0]+size
, pt
[1]+size
, pt
[2]+size
}
236 vg_line_boxf( box
, colour
);
240 VG_STATIC
void vg_line_sphere( m4x3f m
, float radius
, u32 colour
){
241 v3f ly
= { 0.0f
, 0.0f
, radius
},
242 lx
= { 0.0f
, radius
, 0.0f
},
243 lz
= { 0.0f
, 0.0f
, radius
};
245 for( int i
=0; i
<16; i
++ ){
246 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
250 v3f py
= { s
*radius
, 0.0f
, c
*radius
},
251 px
= { s
*radius
, c
*radius
, 0.0f
},
252 pz
= { 0.0f
, s
*radius
, c
*radius
};
254 v3f p0
, p1
, p2
, p3
, p4
, p5
;
255 m4x3_mulv( m
, py
, p0
);
256 m4x3_mulv( m
, ly
, p1
);
257 m4x3_mulv( m
, px
, p2
);
258 m4x3_mulv( m
, lx
, p3
);
259 m4x3_mulv( m
, pz
, p4
);
260 m4x3_mulv( m
, lz
, p5
);
262 vg_line( p0
, p1
, colour
== 0x00? 0xff00ff00: colour
);
263 vg_line( p2
, p3
, colour
== 0x00? 0xff0000ff: colour
);
264 vg_line( p4
, p5
, colour
== 0x00? 0xffff0000: colour
);
272 VG_STATIC
void vg_line_capsule( m4x3f m
, float radius
, float h
, u32 colour
){
273 v3f ly
= { 0.0f
, 0.0f
, radius
},
274 lx
= { 0.0f
, radius
, 0.0f
},
275 lz
= { 0.0f
, 0.0f
, radius
};
277 float s0
= sinf(0.0f
)*radius
,
278 c0
= cosf(0.0f
)*radius
;
280 v3f p0
, p1
, up
, right
, forward
;
281 m3x3_mulv( m
, (v3f
){0.0f
,1.0f
,0.0f
}, up
);
282 m3x3_mulv( m
, (v3f
){1.0f
,0.0f
,0.0f
}, right
);
283 m3x3_mulv( m
, (v3f
){0.0f
,0.0f
,-1.0f
}, forward
);
284 v3_muladds( m
[3], up
, -h
*0.5f
+radius
, p0
);
285 v3_muladds( m
[3], up
, h
*0.5f
-radius
, p1
);
288 v3_muladds( p0
, right
, radius
, a0
);
289 v3_muladds( p1
, right
, radius
, a1
);
290 v3_muladds( p0
, forward
, radius
, b0
);
291 v3_muladds( p1
, forward
, radius
, b1
);
292 vg_line( a0
, a1
, colour
);
293 vg_line( b0
, b1
, colour
);
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 for( int i
=0; i
<16; i
++ ){
303 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
307 v3f e0
= { s0
, 0.0f
, c0
},
308 e1
= { s1
, 0.0f
, c1
},
309 e2
= { s0
, c0
, 0.0f
},
310 e3
= { s1
, c1
, 0.0f
},
311 e4
= { 0.0f
, c0
, s0
},
312 e5
= { 0.0f
, c1
, s1
};
314 m3x3_mulv( m
, e0
, e0
);
315 m3x3_mulv( m
, e1
, e1
);
316 m3x3_mulv( m
, e2
, e2
);
317 m3x3_mulv( m
, e3
, e3
);
318 m3x3_mulv( m
, e4
, e4
);
319 m3x3_mulv( m
, e5
, e5
);
321 v3_add( p0
, e0
, a0
);
322 v3_add( p0
, e1
, a1
);
323 v3_add( p1
, e0
, b0
);
324 v3_add( p1
, e1
, b1
);
326 vg_line( a0
, a1
, colour
);
327 vg_line( b0
, b1
, colour
);
330 v3_add( p0
, e2
, a0
);
331 v3_add( p0
, e3
, a1
);
332 v3_add( p0
, e4
, b0
);
333 v3_add( p0
, e5
, b1
);
336 v3_add( p1
, e2
, a0
);
337 v3_add( p1
, e3
, a1
);
338 v3_add( p1
, e4
, b0
);
339 v3_add( p1
, e5
, b1
);
342 vg_line( a0
, a1
, colour
);
343 vg_line( b0
, b1
, colour
);
350 #endif /* VG_LINES_H */