X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=blobdiff_plain;f=vg_lines.c;fp=vg_lines.c;h=27694fccacc30444536752811f1f33baf314aafa;hp=0000000000000000000000000000000000000000;hb=3b14f3dcd5bf9dd3c85144f2123d667bfa4bb63f;hpb=fce86711735b15bff37de0f70716808410fcf269 diff --git a/vg_lines.c b/vg_lines.c new file mode 100644 index 0000000..27694fc --- /dev/null +++ b/vg_lines.c @@ -0,0 +1,356 @@ +/* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved */ + +#pragma once +#include "vg_lines.h" +#include "vg_shader.h" +#include "vg_engine.h" +#include "vg_async.h" + +struct vg_lines vg_lines; + +/* + * FIXME: The line buffer sometimes overflows. Low priority + */ + +static struct vg_shader _shader_lines = { + .name = "[vg] lines", + .link = NULL, + .vs = { + .orig_file = NULL, + .static_src = + + "uniform mat4 uPv;" + "layout (location=0) in vec3 a_co;" + "layout (location=1) in vec4 a_colour;" + "" + "out vec4 s_colour;" + "" + "void main()" + "{" + " vec4 vert_pos = uPv * vec4( a_co, 1.0 );" + " s_colour = a_colour;" + " gl_Position = vert_pos;" + "}" + }, + .fs = { + .orig_file = NULL, + .static_src = + + "out vec4 FragColor;" + "" + "in vec4 s_colour;" + "" + "void main()" + "{" + " FragColor = s_colour;" + "}" + } +}; + +#define VG_LINES_BUFFER_SIZE 50000 * sizeof( struct vg_lines_vert ) + +static void async_vg_lines_init( void *payload, u32 payload_size ) +{ + glGenVertexArrays( 1, &vg_lines.vao ); + glGenBuffers( 1, &vg_lines.vbo ); + glBindVertexArray( vg_lines.vao ); + glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo ); + + glBufferData( GL_ARRAY_BUFFER, VG_LINES_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW ); + glBindVertexArray( vg_lines.vao ); + VG_CHECK_GL_ERR(); + + /* Pointers */ + glVertexAttribPointer( + 0, + 3, + GL_FLOAT, + GL_FALSE, + sizeof( struct vg_lines_vert ), + (void *)0 + ); + glEnableVertexAttribArray( 0 ); + + glVertexAttribPointer( + 1, + 4, + GL_UNSIGNED_BYTE, + GL_TRUE, + sizeof( struct vg_lines_vert ), + (void*)(offsetof( struct vg_lines_vert, colour )) + ); + glEnableVertexAttribArray( 1 ); + + VG_CHECK_GL_ERR(); +} + +void vg_lines_init(void) +{ + vg_lines.vertex_buffer = + vg_create_linear_allocator( vg_mem.rtmemory, + VG_LINES_BUFFER_SIZE, VG_MEMORY_REALTIME); + + vg_async_call( async_vg_lines_init, NULL, 0 ); + + vg_console_reg_var( "vg_lines", &vg_lines.render, k_var_dtype_i32, + VG_VAR_CHEAT ); + vg_shader_register( &_shader_lines ); +} + +void vg_lines_drawall( void ) +{ + glUseProgram( _shader_lines.id ); + + glUniformMatrix4fv( glGetUniformLocation( _shader_lines.id, "uPv" ), + 1, GL_FALSE, (float *)vg.pv ); + + glBindVertexArray( vg_lines.vao ); + glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo ); + + u32 bufusage = vg_linear_get_cur(vg_lines.vertex_buffer); + glBufferSubData( GL_ARRAY_BUFFER, 0, bufusage, vg_lines.vertex_buffer ); + + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glBlendEquation( GL_FUNC_ADD ); + + if( vg_lines.render ) + glDrawArrays( GL_LINES, 0, bufusage / sizeof(struct vg_lines_vert) ); + + glDisable( GL_BLEND ); + vg_linear_clear( vg_lines.vertex_buffer ); +} + +void vg_line2( line_co from, line_co to, u32 fc, u32 tc ) +{ + if( !vg_lines.enabled ) return; + + u32 size = 2 * sizeof(struct vg_lines_vert); + struct vg_lines_vert *v = vg_linear_alloc( vg_lines.vertex_buffer, size ); + + v3_copy( from, v[0].co ); + v3_copy( to, v[1].co ); + + v[0].colour = fc; + v[1].colour = tc; +} + +void vg_line( line_co from, line_co to, u32 colour ) +{ + if( !vg_lines.enabled ) return; + + vg_line2( from, to, colour, colour ); +} + +void vg_line_arrow( line_co co, line_co dir, float size, u32 colour ) +{ + if( !vg_lines.enabled ) return; + + v3f p1, tx, ty, p2, p3; + v3_muladds( co, dir, size, p1 ); + v3_tangent_basis( dir, tx, ty ); + + v3_muladds( p1, dir, -size * 0.125f, p2 ); + v3_muladds( p2, ty, size * 0.125f, p3 ); + v3_muladds( p2, ty, -size * 0.125f, p2 ); + + vg_line( co, p1, colour ); + vg_line( p1, p2, colour ); + vg_line( p1, p3, colour ); +} + +void vg_line_box_verts( boxf box, v3f verts[8] ) +{ + if( !vg_lines.enabled ) return; + + for( u32 i=0; i<8; i++ ){ + for( u32 j=0; j<3; j++ ){ + verts[i][j] = i&(0x1<