b6f52bd385a685358b7ab3e429de9da1e460c058
[fishladder.git] / vg / vg_lines.h
1 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
2
3 SHADER_DEFINE( vg_line_shader,
4
5 // VERTEX
6 "layout (location=0) in vec2 a_co;"
7 "layout (location=1) in vec4 a_colour;"
8 "uniform mat3 uPv;"
9 ""
10 "out vec4 s_colour;"
11 ""
12 "void main()"
13 "{"
14 " vec4 vert_pos = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
15 " s_colour = a_colour;"
16 " gl_Position = vert_pos;"
17 "}",
18
19 // FRAGMENT
20 "out vec4 FragColor;"
21 ""
22 "in vec4 s_colour;"
23 ""
24 "void main()"
25 "{"
26 " FragColor = s_colour;"
27 "}"
28 ,
29 UNIFORMS({ "uPv" })
30 )
31
32 struct
33 {
34 struct vg_lines_vert
35 {
36 v2f co;
37 u32 colour;
38 }
39 *buffer;
40
41 GLuint vao, vbo;
42 u32 draw_idx, cap, buffer_size;
43 }
44 vg_lines;
45
46 static void vg_lines_init(void)
47 {
48 SHADER_INIT( vg_line_shader );
49
50 glGenVertexArrays( 1, &vg_lines.vao );
51 glGenBuffers( 1, &vg_lines.vbo );
52 glBindVertexArray( vg_lines.vao );
53
54 glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo );
55
56 vg_lines.cap = 10000;
57 vg_lines.buffer_size = vg_lines.cap * sizeof( struct vg_lines_vert );
58
59 glBufferData( GL_ARRAY_BUFFER, vg_lines.buffer_size, NULL, GL_DYNAMIC_DRAW );
60 glBindVertexArray( vg_lines.vao );
61
62 glVertexAttribPointer(
63 0,
64 sizeof( vg_lines.buffer[0].co ) / sizeof(float),
65 GL_FLOAT,
66 GL_FALSE,
67 sizeof( struct vg_lines_vert ),
68 (void *)0
69 );
70 glEnableVertexAttribArray( 0 );
71
72 glVertexAttribPointer(
73 1,
74 4,
75 GL_UNSIGNED_BYTE,
76 GL_TRUE,
77 sizeof( struct vg_lines_vert ),
78 (void*)(offsetof( struct vg_lines_vert, colour ))
79 );
80 glEnableVertexAttribArray( 1 );
81 vg_lines.buffer = malloc( vg_lines.buffer_size );
82 }
83
84 static void vg_lines_free(void)
85 {
86 glDeleteVertexArrays( 1, &vg_lines.vao );
87 glDeleteBuffers( 1, &vg_lines.vbo );
88
89 free( vg_lines.buffer );
90 }
91
92 static void vg_lines_drawall(float* projection)
93 {
94 SHADER_USE( vg_line_shader );
95 glUniformMatrix3fv( SHADER_UNIFORM( vg_line_shader, "uPv" ), 1, GL_FALSE, projection );
96
97 glBindVertexArray( vg_lines.vao );
98 glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo );
99
100 glBufferSubData( GL_ARRAY_BUFFER, 0, vg_lines.draw_idx * sizeof(struct vg_lines_vert), vg_lines.buffer );
101 glEnable( GL_BLEND );
102 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
103 glBlendEquation( GL_FUNC_ADD );
104
105 glDrawArrays( GL_LINES, 0, vg_lines.draw_idx );
106
107 glDisable( GL_BLEND );
108 vg_lines.draw_idx = 0;
109 }
110
111 static void vg_line2( v2f from, v2f to, u32 fc, u32 tc )
112 {
113 struct vg_lines_vert *v = vg_lines.buffer + vg_lines.draw_idx;
114 v2_copy( from, v[0].co );
115 v2_copy( to, v[1].co );
116 v[0].colour = fc;
117 v[1].colour = tc;
118
119 vg_lines.draw_idx += 2;
120 }
121
122 static void vg_line( v2f from, v2f to, u32 colour )
123 {
124 vg_line2( from, to, colour, colour );
125 }
126
127 static void vg_line_box( v2f min, v2f max, u32 colour )
128 {
129 vg_line( min, (v2f){min[0],max[1]}, colour );
130 vg_line( (v2f){min[0],max[1]}, max, colour );
131 vg_line( max, (v2f){max[0],min[1]}, colour );
132 vg_line( (v2f){max[0],min[1]}, min, colour );
133 }