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