d7f277ad70347703de64f1804b1597ebb74ae61d
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 static void async_vg_lines_init( void *payload
, u32 payload_size
){
76 glGenVertexArrays( 1, &vg_lines
.vao
);
77 glGenBuffers( 1, &vg_lines
.vbo
);
78 glBindVertexArray( vg_lines
.vao
);
79 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
81 u32 size
= 50000 * sizeof( struct vg_lines_vert
);
83 vg_lines
.vertex_buffer
=
84 vg_create_linear_allocator(vg_mem
.rtmemory
, size
, VG_MEMORY_REALTIME
);
86 glBufferData( GL_ARRAY_BUFFER
, size
, NULL
, GL_DYNAMIC_DRAW
);
87 glBindVertexArray( vg_lines
.vao
);
91 glVertexAttribPointer(
96 sizeof( struct vg_lines_vert
),
99 glEnableVertexAttribArray( 0 );
101 glVertexAttribPointer(
106 sizeof( struct vg_lines_vert
),
107 (void*)(offsetof( struct vg_lines_vert
, colour
))
109 glEnableVertexAttribArray( 1 );
112 vg_lines
.allow_input
= 1;
115 static void vg_lines_init(void){
116 vg_async_call( async_vg_lines_init
, NULL
, 0 );
118 vg_console_reg_var( "vg_lines", &vg_lines
.draw
, k_var_dtype_i32
,
120 vg_shader_register( &_shader_lines
);
124 static void vg_lines_drawall( void ){
125 glUseProgram( _shader_lines
.id
);
127 glUniformMatrix4fv( glGetUniformLocation( _shader_lines
.id
, "uPv" ),
128 1, GL_FALSE
, (float *)vg
.pv
);
130 glBindVertexArray( vg_lines
.vao
);
131 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
133 u32 bufusage
= vg_linear_get_cur(vg_lines
.vertex_buffer
);
135 glBufferSubData( GL_ARRAY_BUFFER
, 0, bufusage
, vg_lines
.vertex_buffer
);
137 glEnable( GL_BLEND
);
138 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
139 glBlendEquation( GL_FUNC_ADD
);
142 glDrawArrays( GL_LINES
, 0, bufusage
/ sizeof(struct vg_lines_vert
) );
144 glDisable( GL_BLEND
);
145 vg_linear_clear( vg_lines
.vertex_buffer
);
148 static void vg_line2( line_co from
, line_co to
, u32 fc
, u32 tc
){
149 if( !vg_lines
.allow_input
) return;
150 if( !vg_lines
.draw
) return;
152 u32 size
= 2 * sizeof(struct vg_lines_vert
);
153 struct vg_lines_vert
*v
= vg_linear_alloc( vg_lines
.vertex_buffer
, size
);
155 v3_copy( from
, v
[0].co
);
156 v3_copy( to
, v
[1].co
);
162 static void vg_line( line_co from
, line_co to
, u32 colour
){
163 vg_line2( from
, to
, colour
, colour
);
166 static void vg_line_arrow( line_co co
, line_co dir
, float size
, u32 colour
){
167 v3f p1
, tx
, ty
, p2
, p3
;
168 v3_muladds( co
, dir
, size
, p1
);
169 v3_tangent_basis( dir
, tx
, ty
);
171 v3_muladds( p1
, dir
, -size
* 0.125f
, p2
);
172 v3_muladds( p2
, ty
, size
* 0.125f
, p3
);
173 v3_muladds( p2
, ty
, -size
* 0.125f
, p2
);
175 vg_line( co
, p1
, colour
);
176 vg_line( p1
, p2
, colour
);
177 vg_line( p1
, p3
, colour
);
180 static void vg_line_box_verts( boxf box
, v3f verts
[8] ){
181 for( u32 i
=0; i
<8; i
++ ){
182 for( u32 j
=0; j
<3; j
++ ){
183 verts
[i
][j
] = i
&(0x1<<j
)? box
[1][j
]: box
[0][j
];
188 static void vg_line_mesh( v3f verts
[], u32 indices
[][2], u32 indice_count
,
190 for( u32 i
=0; i
<indice_count
; i
++ ){
191 vg_line( verts
[indices
[i
][0]], verts
[indices
[i
][1]], colour
);
195 static void vg_line_boxf( boxf box
, u32 colour
){
197 vg_line_box_verts( box
, verts
);
198 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
199 {4,5},{5,7},{7,6},{6,4},
200 {4,0},{5,1},{6,2},{7,3}};
202 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
205 static void vg_line_boxf_transformed( m4x3f m
, boxf box
, u32 colour
){
207 vg_line_box_verts( box
, verts
);
209 for( u32 i
=0; i
<8; i
++ ){
210 m4x3_mulv( m
, verts
[i
], verts
[i
] );
213 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
214 {4,5},{5,7},{7,6},{6,4},
215 {4,0},{5,1},{6,2},{7,3}};
217 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
220 static void vg_line_cross(v3f pos
,u32 colour
, float scale
){
222 v3_add( (v3f
){ scale
,0.0f
,0.0f
}, pos
, p0
);
223 v3_add( (v3f
){-scale
,0.0f
,0.0f
}, pos
, p1
);
224 vg_line( p0
, p1
, colour
);
225 v3_add( (v3f
){0.0f
, scale
,0.0f
}, pos
, p0
);
226 v3_add( (v3f
){0.0f
,-scale
,0.0f
}, pos
, p1
);
227 vg_line( p0
, p1
, colour
);
228 v3_add( (v3f
){0.0f
,0.0f
, scale
}, pos
, p0
);
229 v3_add( (v3f
){0.0f
,0.0f
,-scale
}, pos
, p1
);
230 vg_line( p0
, p1
, colour
);
233 static void vg_line_point( v3f pt
, float size
, u32 colour
){
236 { pt
[0]-size
, pt
[1]-size
, pt
[2]-size
},
237 { pt
[0]+size
, pt
[1]+size
, pt
[2]+size
}
240 vg_line_boxf( box
, colour
);
244 static void vg_line_sphere( m4x3f m
, float radius
, u32 colour
){
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 static void vg_line_capsule( m4x3f m
, float radius
, float h
, u32 colour
){
277 v3f ly
= { 0.0f
, 0.0f
, radius
},
278 lx
= { 0.0f
, radius
, 0.0f
},
279 lz
= { 0.0f
, 0.0f
, radius
};
281 float s0
= sinf(0.0f
)*radius
,
282 c0
= cosf(0.0f
)*radius
;
284 v3f p0
, p1
, up
, right
, forward
;
285 m3x3_mulv( m
, (v3f
){0.0f
,1.0f
,0.0f
}, up
);
286 m3x3_mulv( m
, (v3f
){1.0f
,0.0f
,0.0f
}, right
);
287 m3x3_mulv( m
, (v3f
){0.0f
,0.0f
,-1.0f
}, forward
);
288 v3_muladds( m
[3], up
, -h
*0.5f
+radius
, p0
);
289 v3_muladds( m
[3], up
, h
*0.5f
-radius
, p1
);
292 v3_muladds( p0
, right
, radius
, a0
);
293 v3_muladds( p1
, right
, radius
, a1
);
294 v3_muladds( p0
, forward
, radius
, b0
);
295 v3_muladds( p1
, forward
, radius
, b1
);
296 vg_line( a0
, a1
, colour
);
297 vg_line( b0
, b1
, colour
);
299 v3_muladds( p0
, right
, -radius
, a0
);
300 v3_muladds( p1
, right
, -radius
, a1
);
301 v3_muladds( p0
, forward
, -radius
, b0
);
302 v3_muladds( p1
, forward
, -radius
, b1
);
303 vg_line( a0
, a1
, colour
);
304 vg_line( b0
, b1
, colour
);
306 for( int i
=0; i
<16; i
++ ){
307 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
311 v3f e0
= { s0
, 0.0f
, c0
},
312 e1
= { s1
, 0.0f
, c1
},
313 e2
= { s0
, c0
, 0.0f
},
314 e3
= { s1
, c1
, 0.0f
},
315 e4
= { 0.0f
, c0
, s0
},
316 e5
= { 0.0f
, c1
, s1
};
318 m3x3_mulv( m
, e0
, e0
);
319 m3x3_mulv( m
, e1
, e1
);
320 m3x3_mulv( m
, e2
, e2
);
321 m3x3_mulv( m
, e3
, e3
);
322 m3x3_mulv( m
, e4
, e4
);
323 m3x3_mulv( m
, e5
, e5
);
325 v3_add( p0
, e0
, a0
);
326 v3_add( p0
, e1
, a1
);
327 v3_add( p1
, e0
, b0
);
328 v3_add( p1
, e1
, b1
);
330 vg_line( a0
, a1
, colour
);
331 vg_line( b0
, b1
, colour
);
334 v3_add( p0
, e2
, a0
);
335 v3_add( p0
, e3
, a1
);
336 v3_add( p0
, e4
, b0
);
337 v3_add( p0
, e5
, b1
);
340 v3_add( p1
, e2
, a0
);
341 v3_add( p1
, e3
, a1
);
342 v3_add( p1
, e4
, b0
);
343 v3_add( p1
, e5
, b1
);
346 vg_line( a0
, a1
, colour
);
347 vg_line( b0
, b1
, colour
);
354 #endif /* VG_LINES_H */