8fff226106e7bc2a007611636226a339910ac294
1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
10 * FIXME: The line buffer sometimes overflows. Low priority
15 #define VG__RED 0xff0000ff
16 #define VG__GREEN 0xff00ff00
17 #define VG__BLUE 0xffff0000
18 #define VG__WHITE 0xffffffff
19 #define VG__BLACK 0xff000000
20 #define VG__CLEAR 0x00ffffff
21 #define VG__PINK 0xffff00ff
22 #define VG__YELOW 0xff00ffff
23 #define VG__CYAN 0xffffff00
24 #define VG__NONE 0x00000000
26 static struct vg_shader _shader_lines
= {
34 "layout (location=0) in vec3 a_co;"
35 "layout (location=1) in vec4 a_colour;"
41 " vec4 vert_pos = uPv * vec4( a_co, 1.0 );"
42 " s_colour = a_colour;"
43 " gl_Position = vert_pos;"
56 " FragColor = s_colour;"
75 #define VG_LINES_BUFFER_SIZE 50000 * sizeof( struct vg_lines_vert )
77 static void async_vg_lines_init( void *payload
, u32 payload_size
){
78 glGenVertexArrays( 1, &vg_lines
.vao
);
79 glGenBuffers( 1, &vg_lines
.vbo
);
80 glBindVertexArray( vg_lines
.vao
);
81 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
83 glBufferData( GL_ARRAY_BUFFER
, VG_LINES_BUFFER_SIZE
, NULL
, GL_DYNAMIC_DRAW
);
84 glBindVertexArray( vg_lines
.vao
);
88 glVertexAttribPointer(
93 sizeof( struct vg_lines_vert
),
96 glEnableVertexAttribArray( 0 );
98 glVertexAttribPointer(
103 sizeof( struct vg_lines_vert
),
104 (void*)(offsetof( struct vg_lines_vert
, colour
))
106 glEnableVertexAttribArray( 1 );
111 static void vg_lines_init(void){
112 vg_lines
.vertex_buffer
=
113 vg_create_linear_allocator( vg_mem
.rtmemory
,
114 VG_LINES_BUFFER_SIZE
, VG_MEMORY_REALTIME
);
116 vg_async_call( async_vg_lines_init
, NULL
, 0 );
118 vg_console_reg_var( "vg_lines", &vg_lines
.render
, k_var_dtype_i32
,
120 vg_shader_register( &_shader_lines
);
123 static void vg_lines_drawall( void ){
124 glUseProgram( _shader_lines
.id
);
126 glUniformMatrix4fv( glGetUniformLocation( _shader_lines
.id
, "uPv" ),
127 1, GL_FALSE
, (float *)vg
.pv
);
129 glBindVertexArray( vg_lines
.vao
);
130 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
132 u32 bufusage
= vg_linear_get_cur(vg_lines
.vertex_buffer
);
133 glBufferSubData( GL_ARRAY_BUFFER
, 0, bufusage
, vg_lines
.vertex_buffer
);
135 glEnable( GL_BLEND
);
136 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
137 glBlendEquation( GL_FUNC_ADD
);
139 if( vg_lines
.render
)
140 glDrawArrays( GL_LINES
, 0, bufusage
/ sizeof(struct vg_lines_vert
) );
142 glDisable( GL_BLEND
);
143 vg_linear_clear( vg_lines
.vertex_buffer
);
146 static void vg_line2( line_co from
, line_co to
, u32 fc
, u32 tc
){
147 if( !vg_lines
.enabled
) return;
149 u32 size
= 2 * sizeof(struct vg_lines_vert
);
150 struct vg_lines_vert
*v
= vg_linear_alloc( vg_lines
.vertex_buffer
, size
);
152 v3_copy( from
, v
[0].co
);
153 v3_copy( to
, v
[1].co
);
159 static void vg_line( line_co from
, line_co to
, u32 colour
){
160 if( !vg_lines
.enabled
) return;
162 vg_line2( from
, to
, colour
, colour
);
165 static void vg_line_arrow( line_co co
, line_co dir
, float size
, u32 colour
){
166 if( !vg_lines
.enabled
) return;
168 v3f p1
, tx
, ty
, p2
, p3
;
169 v3_muladds( co
, dir
, size
, p1
);
170 v3_tangent_basis( dir
, tx
, ty
);
172 v3_muladds( p1
, dir
, -size
* 0.125f
, p2
);
173 v3_muladds( p2
, ty
, size
* 0.125f
, p3
);
174 v3_muladds( p2
, ty
, -size
* 0.125f
, p2
);
176 vg_line( co
, p1
, colour
);
177 vg_line( p1
, p2
, colour
);
178 vg_line( p1
, p3
, colour
);
181 static void vg_line_box_verts( boxf box
, v3f verts
[8] ){
182 if( !vg_lines
.enabled
) return;
184 for( u32 i
=0; i
<8; i
++ ){
185 for( u32 j
=0; j
<3; j
++ ){
186 verts
[i
][j
] = i
&(0x1<<j
)? box
[1][j
]: box
[0][j
];
191 static void vg_line_mesh( v3f verts
[], u32 indices
[][2], u32 indice_count
,
193 if( !vg_lines
.enabled
) return;
195 for( u32 i
=0; i
<indice_count
; i
++ ){
196 vg_line( verts
[indices
[i
][0]], verts
[indices
[i
][1]], colour
);
200 static void vg_line_boxf( boxf box
, u32 colour
){
201 if( !vg_lines
.enabled
) return;
204 vg_line_box_verts( box
, verts
);
205 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
206 {4,5},{5,7},{7,6},{6,4},
207 {4,0},{5,1},{6,2},{7,3}};
209 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
212 static void vg_line_boxf_transformed( m4x3f m
, boxf box
, u32 colour
){
213 if( !vg_lines
.enabled
) return;
216 vg_line_box_verts( box
, verts
);
218 for( u32 i
=0; i
<8; i
++ ){
219 m4x3_mulv( m
, verts
[i
], verts
[i
] );
222 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
223 {4,5},{5,7},{7,6},{6,4},
224 {4,0},{5,1},{6,2},{7,3}};
226 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
229 static void vg_line_cross(v3f pos
,u32 colour
, float scale
){
230 if( !vg_lines
.enabled
) return;
233 v3_add( (v3f
){ scale
,0.0f
,0.0f
}, pos
, p0
);
234 v3_add( (v3f
){-scale
,0.0f
,0.0f
}, pos
, p1
);
235 vg_line( p0
, p1
, colour
);
236 v3_add( (v3f
){0.0f
, scale
,0.0f
}, pos
, p0
);
237 v3_add( (v3f
){0.0f
,-scale
,0.0f
}, pos
, p1
);
238 vg_line( p0
, p1
, colour
);
239 v3_add( (v3f
){0.0f
,0.0f
, scale
}, pos
, p0
);
240 v3_add( (v3f
){0.0f
,0.0f
,-scale
}, pos
, p1
);
241 vg_line( p0
, p1
, colour
);
244 static void vg_line_point( v3f pt
, float size
, u32 colour
){
245 if( !vg_lines
.enabled
) return;
249 { pt
[0]-size
, pt
[1]-size
, pt
[2]-size
},
250 { pt
[0]+size
, pt
[1]+size
, pt
[2]+size
}
253 vg_line_boxf( box
, colour
);
257 static void vg_line_sphere( m4x3f m
, float radius
, u32 colour
){
258 if( !vg_lines
.enabled
) return;
260 v3f ly
= { 0.0f
, 0.0f
, radius
},
261 lx
= { 0.0f
, radius
, 0.0f
},
262 lz
= { 0.0f
, 0.0f
, radius
};
264 for( int i
=0; i
<16; i
++ ){
265 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
269 v3f py
= { s
*radius
, 0.0f
, c
*radius
},
270 px
= { s
*radius
, c
*radius
, 0.0f
},
271 pz
= { 0.0f
, s
*radius
, c
*radius
};
273 v3f p0
, p1
, p2
, p3
, p4
, p5
;
274 m4x3_mulv( m
, py
, p0
);
275 m4x3_mulv( m
, ly
, p1
);
276 m4x3_mulv( m
, px
, p2
);
277 m4x3_mulv( m
, lx
, p3
);
278 m4x3_mulv( m
, pz
, p4
);
279 m4x3_mulv( m
, lz
, p5
);
281 vg_line( p0
, p1
, colour
== 0x00? 0xff00ff00: colour
);
282 vg_line( p2
, p3
, colour
== 0x00? 0xff0000ff: colour
);
283 vg_line( p4
, p5
, colour
== 0x00? 0xffff0000: colour
);
291 static void vg_line_capsule( m4x3f m
, float radius
, float h
, u32 colour
){
292 if( !vg_lines
.enabled
) return;
294 v3f ly
= { 0.0f
, 0.0f
, radius
},
295 lx
= { 0.0f
, radius
, 0.0f
},
296 lz
= { 0.0f
, 0.0f
, radius
};
298 float s0
= sinf(0.0f
)*radius
,
299 c0
= cosf(0.0f
)*radius
;
301 v3f p0
, p1
, up
, right
, forward
;
302 m3x3_mulv( m
, (v3f
){0.0f
,1.0f
,0.0f
}, up
);
303 m3x3_mulv( m
, (v3f
){1.0f
,0.0f
,0.0f
}, right
);
304 m3x3_mulv( m
, (v3f
){0.0f
,0.0f
,-1.0f
}, forward
);
305 v3_muladds( m
[3], up
, -h
*0.5f
+radius
, p0
);
306 v3_muladds( m
[3], up
, h
*0.5f
-radius
, p1
);
309 v3_muladds( p0
, right
, radius
, a0
);
310 v3_muladds( p1
, right
, radius
, a1
);
311 v3_muladds( p0
, forward
, radius
, b0
);
312 v3_muladds( p1
, forward
, radius
, b1
);
313 vg_line( a0
, a1
, colour
);
314 vg_line( b0
, b1
, colour
);
316 v3_muladds( p0
, right
, -radius
, a0
);
317 v3_muladds( p1
, right
, -radius
, a1
);
318 v3_muladds( p0
, forward
, -radius
, b0
);
319 v3_muladds( p1
, forward
, -radius
, b1
);
320 vg_line( a0
, a1
, colour
);
321 vg_line( b0
, b1
, colour
);
323 for( int i
=0; i
<16; i
++ ){
324 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
328 v3f e0
= { s0
, 0.0f
, c0
},
329 e1
= { s1
, 0.0f
, c1
},
330 e2
= { s0
, c0
, 0.0f
},
331 e3
= { s1
, c1
, 0.0f
},
332 e4
= { 0.0f
, c0
, s0
},
333 e5
= { 0.0f
, c1
, s1
};
335 m3x3_mulv( m
, e0
, e0
);
336 m3x3_mulv( m
, e1
, e1
);
337 m3x3_mulv( m
, e2
, e2
);
338 m3x3_mulv( m
, e3
, e3
);
339 m3x3_mulv( m
, e4
, e4
);
340 m3x3_mulv( m
, e5
, e5
);
342 v3_add( p0
, e0
, a0
);
343 v3_add( p0
, e1
, a1
);
344 v3_add( p1
, e0
, b0
);
345 v3_add( p1
, e1
, b1
);
347 vg_line( a0
, a1
, colour
);
348 vg_line( b0
, b1
, colour
);
351 v3_add( p0
, e2
, a0
);
352 v3_add( p0
, e3
, a1
);
353 v3_add( p0
, e4
, b0
);
354 v3_add( p0
, e5
, b1
);
357 v3_add( p1
, e2
, a0
);
358 v3_add( p1
, e3
, a1
);
359 v3_add( p1
, e4
, b0
);
360 v3_add( p1
, e5
, b1
);
363 vg_line( a0
, a1
, colour
);
364 vg_line( b0
, b1
, colour
);
371 #endif /* VG_LINES_H */