704d9bde796b28ae16da8005e6d95d20fb376ddc
[vg.git] / src / vg / vg_lines.h
1 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
2
3 static int debug_lines_enable = 1;
4
5 #ifdef VG_3D
6 typedef v3f line_co;
7 #else
8 typedef v2f line_co;
9 #endif
10
11 SHADER_DEFINE( vg_line_shader,
12 #ifdef VG_3D
13 "uniform mat4 uPv;"
14 "layout (location=0) in vec3 a_co;"
15 #else
16 "uniform mat3 uPv;"
17 "layout (location=0) in vec2 a_co;"
18 #endif
19 "layout (location=1) in vec4 a_colour;"
20 ""
21 "out vec4 s_colour;"
22 ""
23 "void main()"
24 "{"
25 #ifdef VG_3D
26 " vec4 vert_pos = uPv * vec4( a_co, 1.0 );"
27 #else
28 " vec4 vert_pos = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
29 #endif
30 " s_colour = a_colour;"
31 " gl_Position = vert_pos;"
32 "}",
33
34 // FRAGMENT
35 "out vec4 FragColor;"
36 ""
37 "in vec4 s_colour;"
38 ""
39 "void main()"
40 "{"
41 " FragColor = s_colour;"
42 "}"
43 ,
44 UNIFORMS({ "uPv" })
45 )
46
47 struct
48 {
49 struct vg_lines_vert
50 {
51 #ifdef VG_3D
52 v3f co;
53 #else
54 v2f co;
55 #endif
56
57 u32 colour;
58 }
59 *buffer;
60
61 GLuint vao, vbo;
62 u32 draw_idx, cap, buffer_size;
63 }
64 vg_lines;
65
66 static void vg_lines_init(void)
67 {
68 vg_convar_push( (struct vg_convar){
69 .name = "debug_lines",
70 .data = &debug_lines_enable,
71 .data_type = k_convar_dtype_i32,
72 .opt_i32 = { .min=0, .max=1, .clamp=1 },
73 .persistent = 1
74 });
75
76 SHADER_INIT( vg_line_shader );
77
78 glGenVertexArrays( 1, &vg_lines.vao );
79 glGenBuffers( 1, &vg_lines.vbo );
80 glBindVertexArray( vg_lines.vao );
81
82 glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo );
83
84 vg_lines.cap = 50000;
85 vg_lines.buffer_size = vg_lines.cap * sizeof( struct vg_lines_vert );
86
87 glBufferData( GL_ARRAY_BUFFER, vg_lines.buffer_size, NULL, GL_DYNAMIC_DRAW );
88 glBindVertexArray( vg_lines.vao );
89
90 glVertexAttribPointer(
91 0,
92 sizeof( vg_lines.buffer[0].co ) / sizeof(float),
93 GL_FLOAT,
94 GL_FALSE,
95 sizeof( struct vg_lines_vert ),
96 (void *)0
97 );
98 glEnableVertexAttribArray( 0 );
99
100 glVertexAttribPointer(
101 1,
102 4,
103 GL_UNSIGNED_BYTE,
104 GL_TRUE,
105 sizeof( struct vg_lines_vert ),
106 (void*)(offsetof( struct vg_lines_vert, colour ))
107 );
108 glEnableVertexAttribArray( 1 );
109 vg_lines.buffer = malloc( vg_lines.buffer_size );
110 }
111
112 static void vg_lines_free(void)
113 {
114 glDeleteVertexArrays( 1, &vg_lines.vao );
115 glDeleteBuffers( 1, &vg_lines.vbo );
116
117 free( vg_lines.buffer );
118 }
119
120 static void vg_lines_drawall( float* projection )
121 {
122 SHADER_USE( vg_line_shader );
123
124 #ifdef VG_3D
125 glUniformMatrix4fv
126 #else
127 glUniformMatrix3fv
128 #endif
129 ( SHADER_UNIFORM( vg_line_shader, "uPv" ), 1, GL_FALSE, projection );
130
131 glBindVertexArray( vg_lines.vao );
132 glBindBuffer( GL_ARRAY_BUFFER, vg_lines.vbo );
133
134 glBufferSubData( GL_ARRAY_BUFFER, 0, vg_lines.draw_idx *
135 sizeof(struct vg_lines_vert), vg_lines.buffer );
136
137 glEnable( GL_BLEND );
138 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
139 glBlendEquation( GL_FUNC_ADD );
140
141 if( debug_lines_enable )
142 glDrawArrays( GL_LINES, 0, vg_lines.draw_idx );
143
144 glDisable( GL_BLEND );
145 vg_lines.draw_idx = 0;
146 }
147
148 static void vg_line2( line_co from, line_co to, u32 fc, u32 tc )
149 {
150 struct vg_lines_vert *v = &vg_lines.buffer[vg_lines.draw_idx];
151
152 #ifdef VG_3D
153 v3_copy( from, v[0].co );
154 v3_copy( to, v[1].co );
155 #else
156 v2_copy( from, v[0].co );
157 v2_copy( to, v[1].co );
158 #endif
159
160 v[0].colour = fc;
161 v[1].colour = tc;
162
163 vg_lines.draw_idx += 2;
164 }
165
166 static void vg_line( line_co from, line_co to, u32 colour )
167 {
168 vg_line2( from, to, colour, colour );
169 }
170
171 static void vg_line_box( line_co min, line_co max, u32 colour )
172 {
173 #ifdef VG_3D
174 /* TODO... */
175 #else
176 vg_line( min, (v2f){min[0],max[1]}, colour );
177 vg_line( (v2f){min[0],max[1]}, max, colour );
178 vg_line( max, (v2f){max[0],min[1]}, colour );
179 vg_line( (v2f){max[0],min[1]}, min, colour );
180 #endif
181 }
182
183 static void vg_line_boxf( boxf box, u32 colour )
184 {
185 v3f p000, p001, p010, p011, p100, p101, p110, p111;
186
187 p000[0]=box[0][0];p000[1]=box[0][1];p000[2]=box[0][2];
188 p001[0]=box[0][0];p001[1]=box[0][1];p001[2]=box[1][2];
189 p010[0]=box[0][0];p010[1]=box[1][1];p010[2]=box[0][2];
190 p011[0]=box[0][0];p011[1]=box[1][1];p011[2]=box[1][2];
191
192 p100[0]=box[1][0];p100[1]=box[0][1];p100[2]=box[0][2];
193 p101[0]=box[1][0];p101[1]=box[0][1];p101[2]=box[1][2];
194 p110[0]=box[1][0];p110[1]=box[1][1];p110[2]=box[0][2];
195 p111[0]=box[1][0];p111[1]=box[1][1];p111[2]=box[1][2];
196
197 vg_line( p000, p001, colour );
198 vg_line( p001, p011, colour );
199 vg_line( p011, p010, colour );
200 vg_line( p010, p000, colour );
201
202 vg_line( p100, p101, colour );
203 vg_line( p101, p111, colour );
204 vg_line( p111, p110, colour );
205 vg_line( p110, p100, colour );
206
207 vg_line( p100, p000, colour );
208 vg_line( p101, p001, colour );
209 vg_line( p110, p010, colour );
210 vg_line( p111, p011, colour );
211 }
212
213 static void vg_line_pt3( v3f pt, float size, u32 colour )
214 {
215 boxf box =
216 {
217 { pt[0]-size, pt[1]-size, pt[2]-size },
218 { pt[0]+size, pt[1]+size, pt[2]+size }
219 };
220
221 vg_line_boxf( box, colour );
222 }