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
= {
23 "layout (location=0) in vec3 a_co;"
24 "layout (location=1) in vec4 a_colour;"
30 " vec4 vert_pos = uPv * vec4( a_co, 1.0 );"
31 " s_colour = a_colour;"
32 " gl_Position = vert_pos;"
45 " FragColor = s_colour;"
50 #define VG_LINES_BUFFER_SIZE 50000 * sizeof( struct vg_lines_vert )
52 static void async_vg_lines_init( void *payload
, u32 payload_size
)
54 glGenVertexArrays( 1, &vg_lines
.vao
);
55 glGenBuffers( 1, &vg_lines
.vbo
);
56 glBindVertexArray( vg_lines
.vao
);
57 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
59 glBufferData( GL_ARRAY_BUFFER
, VG_LINES_BUFFER_SIZE
, NULL
, GL_DYNAMIC_DRAW
);
60 glBindVertexArray( vg_lines
.vao
);
64 glVertexAttribPointer(
69 sizeof( struct vg_lines_vert
),
72 glEnableVertexAttribArray( 0 );
74 glVertexAttribPointer(
79 sizeof( struct vg_lines_vert
),
80 (void*)(offsetof( struct vg_lines_vert
, colour
))
82 glEnableVertexAttribArray( 1 );
87 void vg_lines_init(void)
89 vg_lines
.vertex_buffer
=
90 vg_create_linear_allocator( vg_mem
.rtmemory
,
91 VG_LINES_BUFFER_SIZE
, VG_MEMORY_REALTIME
);
93 vg_async_call( async_vg_lines_init
, NULL
, 0 );
95 vg_console_reg_var( "vg_lines", &vg_lines
.render
, k_var_dtype_i32
,
97 vg_shader_register( &_shader_lines
);
100 void vg_lines_drawall( void )
102 glUseProgram( _shader_lines
.id
);
104 glUniformMatrix4fv( glGetUniformLocation( _shader_lines
.id
, "uPv" ),
105 1, GL_FALSE
, (float *)vg
.pv
);
107 glBindVertexArray( vg_lines
.vao
);
108 glBindBuffer( GL_ARRAY_BUFFER
, vg_lines
.vbo
);
110 u32 bufusage
= vg_linear_get_cur(vg_lines
.vertex_buffer
);
111 glBufferSubData( GL_ARRAY_BUFFER
, 0, bufusage
, vg_lines
.vertex_buffer
);
113 glEnable( GL_BLEND
);
114 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
115 glBlendEquation( GL_FUNC_ADD
);
117 if( vg_lines
.render
)
118 glDrawArrays( GL_LINES
, 0, bufusage
/ sizeof(struct vg_lines_vert
) );
120 glDisable( GL_BLEND
);
121 vg_linear_clear( vg_lines
.vertex_buffer
);
124 void vg_line2( line_co from
, line_co to
, u32 fc
, u32 tc
)
126 if( !vg_lines
.enabled
) return;
128 u32 size
= 2 * sizeof(struct vg_lines_vert
);
129 struct vg_lines_vert
*v
= vg_linear_alloc( vg_lines
.vertex_buffer
, size
);
131 v3_copy( from
, v
[0].co
);
132 v3_copy( to
, v
[1].co
);
138 void vg_line( line_co from
, line_co to
, u32 colour
)
140 if( !vg_lines
.enabled
) return;
142 vg_line2( from
, to
, colour
, colour
);
145 void vg_line_arrow( line_co co
, line_co dir
, float size
, u32 colour
)
147 if( !vg_lines
.enabled
) return;
149 v3f p1
, tx
, ty
, p2
, p3
;
150 v3_muladds( co
, dir
, size
, p1
);
151 v3_tangent_basis( dir
, tx
, ty
);
153 v3_muladds( p1
, dir
, -size
* 0.125f
, p2
);
154 v3_muladds( p2
, ty
, size
* 0.125f
, p3
);
155 v3_muladds( p2
, ty
, -size
* 0.125f
, p2
);
157 vg_line( co
, p1
, colour
);
158 vg_line( p1
, p2
, colour
);
159 vg_line( p1
, p3
, colour
);
162 void vg_line_box_verts( boxf box
, v3f verts
[8] )
164 if( !vg_lines
.enabled
) return;
166 for( u32 i
=0; i
<8; i
++ ){
167 for( u32 j
=0; j
<3; j
++ ){
168 verts
[i
][j
] = i
&(0x1<<j
)? box
[1][j
]: box
[0][j
];
173 void vg_line_mesh( v3f verts
[], u32 indices
[][2], u32 indice_count
,u32 colour
){
174 if( !vg_lines
.enabled
) return;
176 for( u32 i
=0; i
<indice_count
; i
++ ){
177 vg_line( verts
[indices
[i
][0]], verts
[indices
[i
][1]], colour
);
181 void vg_line_boxf( boxf box
, u32 colour
)
183 if( !vg_lines
.enabled
) return;
186 vg_line_box_verts( box
, verts
);
187 u32 indices
[][2] = {{0,1},{1,3},{3,2},{2,0},
188 {4,5},{5,7},{7,6},{6,4},
189 {4,0},{5,1},{6,2},{7,3}};
191 vg_line_mesh( verts
, indices
, vg_list_size(indices
), colour
);
194 void vg_line_boxf_transformed( m4x3f m
, boxf box
, u32 colour
)
196 if( !vg_lines
.enabled
) return;
199 vg_line_box_verts( box
, verts
);
201 for( u32 i
=0; i
<8; i
++ ){
202 m4x3_mulv( m
, verts
[i
], verts
[i
] );
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 void vg_line_cross(v3f pos
,u32 colour
, float scale
)
214 if( !vg_lines
.enabled
) return;
217 v3_add( (v3f
){ scale
,0.0f
,0.0f
}, pos
, p0
);
218 v3_add( (v3f
){-scale
,0.0f
,0.0f
}, pos
, p1
);
219 vg_line( p0
, p1
, colour
);
220 v3_add( (v3f
){0.0f
, scale
,0.0f
}, pos
, p0
);
221 v3_add( (v3f
){0.0f
,-scale
,0.0f
}, pos
, p1
);
222 vg_line( p0
, p1
, colour
);
223 v3_add( (v3f
){0.0f
,0.0f
, scale
}, pos
, p0
);
224 v3_add( (v3f
){0.0f
,0.0f
,-scale
}, pos
, p1
);
225 vg_line( p0
, p1
, colour
);
228 void vg_line_point( v3f pt
, float size
, u32 colour
)
230 if( !vg_lines
.enabled
) return;
234 { pt
[0]-size
, pt
[1]-size
, pt
[2]-size
},
235 { pt
[0]+size
, pt
[1]+size
, pt
[2]+size
}
238 vg_line_boxf( box
, colour
);
242 void vg_line_sphere( m4x3f m
, float radius
, u32 colour
)
244 if( !vg_lines
.enabled
) return;
246 v3f ly
= { 0.0f
, 0.0f
, radius
},
247 lx
= { 0.0f
, radius
, 0.0f
},
248 lz
= { 0.0f
, 0.0f
, radius
};
250 for( int i
=0; i
<16; i
++ ){
251 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
255 v3f py
= { s
*radius
, 0.0f
, c
*radius
},
256 px
= { s
*radius
, c
*radius
, 0.0f
},
257 pz
= { 0.0f
, s
*radius
, c
*radius
};
259 v3f p0
, p1
, p2
, p3
, p4
, p5
;
260 m4x3_mulv( m
, py
, p0
);
261 m4x3_mulv( m
, ly
, p1
);
262 m4x3_mulv( m
, px
, p2
);
263 m4x3_mulv( m
, lx
, p3
);
264 m4x3_mulv( m
, pz
, p4
);
265 m4x3_mulv( m
, lz
, p5
);
267 vg_line( p0
, p1
, colour
== 0x00? 0xff00ff00: colour
);
268 vg_line( p2
, p3
, colour
== 0x00? 0xff0000ff: colour
);
269 vg_line( p4
, p5
, colour
== 0x00? 0xffff0000: colour
);
277 void vg_line_capsule( m4x3f m
, float radius
, float h
, u32 colour
)
279 if( !vg_lines
.enabled
) return;
281 v3f ly
= { 0.0f
, 0.0f
, radius
},
282 lx
= { 0.0f
, radius
, 0.0f
},
283 lz
= { 0.0f
, 0.0f
, radius
};
285 float s0
= sinf(0.0f
)*radius
,
286 c0
= cosf(0.0f
)*radius
;
288 v3f p0
, p1
, up
, right
, forward
;
289 m3x3_mulv( m
, (v3f
){0.0f
,1.0f
,0.0f
}, up
);
290 m3x3_mulv( m
, (v3f
){1.0f
,0.0f
,0.0f
}, right
);
291 m3x3_mulv( m
, (v3f
){0.0f
,0.0f
,-1.0f
}, forward
);
292 v3_muladds( m
[3], up
, -h
*0.5f
+radius
, p0
);
293 v3_muladds( m
[3], up
, h
*0.5f
-radius
, p1
);
296 v3_muladds( p0
, right
, radius
, a0
);
297 v3_muladds( p1
, right
, radius
, a1
);
298 v3_muladds( p0
, forward
, radius
, b0
);
299 v3_muladds( p1
, forward
, radius
, b1
);
300 vg_line( a0
, a1
, colour
);
301 vg_line( b0
, b1
, colour
);
303 v3_muladds( p0
, right
, -radius
, a0
);
304 v3_muladds( p1
, right
, -radius
, a1
);
305 v3_muladds( p0
, forward
, -radius
, b0
);
306 v3_muladds( p1
, forward
, -radius
, b1
);
307 vg_line( a0
, a1
, colour
);
308 vg_line( b0
, b1
, colour
);
310 for( int i
=0; i
<16; i
++ ){
311 float t
= ((float)(i
+1) * (1.0f
/16.0f
)) * VG_PIf
* 2.0f
,
315 v3f e0
= { s0
, 0.0f
, c0
},
316 e1
= { s1
, 0.0f
, c1
},
317 e2
= { s0
, c0
, 0.0f
},
318 e3
= { s1
, c1
, 0.0f
},
319 e4
= { 0.0f
, c0
, s0
},
320 e5
= { 0.0f
, c1
, s1
};
322 m3x3_mulv( m
, e0
, e0
);
323 m3x3_mulv( m
, e1
, e1
);
324 m3x3_mulv( m
, e2
, e2
);
325 m3x3_mulv( m
, e3
, e3
);
326 m3x3_mulv( m
, e4
, e4
);
327 m3x3_mulv( m
, e5
, e5
);
329 v3_add( p0
, e0
, a0
);
330 v3_add( p0
, e1
, a1
);
331 v3_add( p1
, e0
, b0
);
332 v3_add( p1
, e1
, b1
);
334 vg_line( a0
, a1
, colour
);
335 vg_line( b0
, b1
, colour
);
338 v3_add( p0
, e2
, a0
);
339 v3_add( p0
, e3
, a1
);
340 v3_add( p0
, e4
, b0
);
341 v3_add( p0
, e5
, b1
);
344 v3_add( p1
, e2
, a0
);
345 v3_add( p1
, e3
, a1
);
346 v3_add( p1
, e4
, b0
);
347 v3_add( p1
, e5
, b1
);
350 vg_line( a0
, a1
, colour
);
351 vg_line( b0
, b1
, colour
);