diff --git a/arcade/context.py b/arcade/context.py index f011b5833d..2cbbc33d7b 100644 --- a/arcade/context.py +++ b/arcade/context.py @@ -155,7 +155,6 @@ def __init__( self.shape_line_program: Program = self.load_program( vertex_shader=":system:shaders/shapes/line/unbuffered_vs.glsl", fragment_shader=":system:shaders/shapes/line/unbuffered_fs.glsl", - geometry_shader=":system:shaders/shapes/line/unbuffered_geo.glsl", ) self.shape_ellipse_filled_unbuffered_program: Program = self.load_program( vertex_shader=":system:shaders/shapes/ellipse/filled_unbuffered_vs.glsl", @@ -230,16 +229,34 @@ def __init__( ] ) # Shape line(s) - # Reserve space for 1000 lines (2f pos, 4f color) - # TODO: Different version for buffered and unbuffered - # TODO: Make round-robin buffers self.shape_line_buffer_pos = self.buffer(reserve=8 * 10) - # self.shape_line_buffer_color = self.buffer(reserve=4 * 10) self.shape_line_geometry = self.geometry( [ - BufferDescription(self.shape_line_buffer_pos, "2f", ["in_vert"]), - # BufferDescription(self.shape_line_buffer_color, '4f1', ['in_color']) - ] + # Instanced quad (triangle strip) + BufferDescription( + self.buffer( + data=array( + "f", + [ + 0.0, # 4 dummy vertices + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + ) + ), + "2f", + ["in_vert"], + ), + BufferDescription( + self.shape_line_buffer_pos, "4f", ["in_instance_pos"], instanced=True + ), + ], + mode=self.TRIANGLE_STRIP, ) # ellipse/circle filled self.shape_ellipse_unbuffered_buffer = self.buffer(reserve=8) diff --git a/arcade/draw/line.py b/arcade/draw/line.py index a2e232f6ea..daf5c244be 100644 --- a/arcade/draw/line.py +++ b/arcade/draw/line.py @@ -80,7 +80,7 @@ def draw_line( line_pos_buffer.write(data=array.array("f", (start_x, start_y, end_x, end_y))) ctx.enable(ctx.BLEND) - geometry.render(program, mode=gl.LINES, vertices=2) + geometry.render(program, instances=1) ctx.disable(ctx.BLEND) @@ -127,6 +127,6 @@ def draw_lines(point_list: Point2List, color: RGBOrA255, line_width: float = 1) program["color"] = color_normalized line_buffer_pos.write(data=line_pos_array) - geometry.render(program, mode=gl.LINES, vertices=num_points) + geometry.render(program, instances=num_points // 2) ctx.disable(ctx.BLEND) diff --git a/arcade/resources/system/shaders/shapes/line/unbuffered_geo.glsl b/arcade/resources/system/shaders/shapes/line/unbuffered_geo.glsl deleted file mode 100644 index 5cf17b0587..0000000000 --- a/arcade/resources/system/shaders/shapes/line/unbuffered_geo.glsl +++ /dev/null @@ -1,37 +0,0 @@ -#version 330 - -layout (lines) in; -layout (triangle_strip, max_vertices = 4) out; - -uniform WindowBlock { - mat4 projection; - mat4 view; -} window; - -uniform float line_width; - -vec2 lineNormal2D(vec2 start, vec2 end) { - vec2 n = end - start; - return normalize(vec2(-n.y, n.x)); -} - -void main() { - // Get the line segment - vec2 line_start = gl_in[0].gl_Position.xy; - vec2 line_end = gl_in[1].gl_Position.xy; - - // Calculate normal - vec2 normal = lineNormal2D(line_start, line_end) * line_width / 2.0; - - // Emit a quad using a line strip with the correct line width - gl_Position = window.projection * window.view * vec4(line_start + normal, 0.0, 1.0); - EmitVertex(); - gl_Position = window.projection * window.view * vec4(line_start - normal, 0.0, 1.0); - EmitVertex(); - gl_Position = window.projection * window.view * vec4(line_end + normal, 0.0, 1.0); - EmitVertex(); - gl_Position = window.projection * window.view * vec4(line_end - normal, 0.0, 1.0); - EmitVertex(); - - EndPrimitive(); -} diff --git a/arcade/resources/system/shaders/shapes/line/unbuffered_vs.glsl b/arcade/resources/system/shaders/shapes/line/unbuffered_vs.glsl index 02be2f2654..e886e7bfca 100644 --- a/arcade/resources/system/shaders/shapes/line/unbuffered_vs.glsl +++ b/arcade/resources/system/shaders/shapes/line/unbuffered_vs.glsl @@ -1,7 +1,31 @@ #version 330 +uniform WindowBlock { + mat4 projection; + mat4 view; +} window; + +uniform float line_width; + in vec2 in_vert; +in vec4 in_instance_pos; + +vec2 lineNormal2D(vec2 start, vec2 end) { + vec2 n = end - start; + return normalize(vec2(-n.y, n.x)); +} void main() { - gl_Position = vec4(in_vert, 0.0, 1.0); + vec2 line_start = in_instance_pos.xy; + vec2 line_end = in_instance_pos.zw; + + vec2 normal = lineNormal2D(line_start, line_end) * line_width / 2.0; + mat4 mvp = window.projection * window.view; + vec2 positions[4] = vec2[4]( + line_start + normal, + line_start - normal, + line_end + normal, + line_end - normal + ); + gl_Position = mvp * vec4(positions[gl_VertexID % 4], 0.0, 1.0); }