diff --git a/arcade/context.py b/arcade/context.py index 2e714fa08f..f011b5833d 100644 --- a/arcade/context.py +++ b/arcade/context.py @@ -170,8 +170,8 @@ def __init__( self.shape_rectangle_filled_unbuffered_program = self.load_program( vertex_shader=":system:shaders/shapes/rectangle/filled_unbuffered_vs.glsl", fragment_shader=":system:shaders/shapes/rectangle/filled_unbuffered_fs.glsl", - geometry_shader=":system:shaders/shapes/rectangle/filled_unbuffered_geo.glsl", ) + # Atlas shaders self.atlas_resize_program: Program = self.load_program( # NOTE: This is the geo shader version of the atlas resize program. @@ -253,9 +253,36 @@ def __init__( ) # rectangle filled self.shape_rectangle_filled_unbuffered_buffer = self.buffer(reserve=8) + # fmt: off self.shape_rectangle_filled_unbuffered_geometry: Geometry = self.geometry( - [BufferDescription(self.shape_rectangle_filled_unbuffered_buffer, "2f", ["in_vert"])] + [ + # Instanced quad (triangle strip) + BufferDescription( + self.buffer( + data=array( + "f", + [ + -0.5, +0.5, # Upper left + -0.5, -0.5, # lower left + +0.5, +0.5, # upper right + +0.5, -0.5, # lower right + ], + ) + ), + "2f", + ["in_vert"], + ), + # Per instance data + BufferDescription( + self.shape_rectangle_filled_unbuffered_buffer, + "2f", + ["in_instance_pos"], + instanced=True + ), + ], + mode=self.TRIANGLE_STRIP, ) + # fmt: on self.geometry_empty: Geometry = self.geometry() self._atlas: TextureAtlasBase | None = None diff --git a/arcade/draw/point.py b/arcade/draw/point.py index 9a4ddb6d74..9898f66527 100644 --- a/arcade/draw/point.py +++ b/arcade/draw/point.py @@ -68,7 +68,6 @@ def draw_points(point_list: Point2List, color: RGBOrA255, size: float = 1.0) -> # Resize buffer data_size = num_points * 8 - # if data_size > buffer.size: buffer.orphan(size=data_size) ctx.enable(ctx.BLEND) @@ -79,6 +78,6 @@ def draw_points(point_list: Point2List, color: RGBOrA255, size: float = 1.0) -> buffer.write(data=point_array) # Only render the # of points we have complete data for - geometry.render(program, mode=ctx.POINTS, vertices=data_size // 8) + geometry.render(program, instances=num_points) ctx.disable(ctx.BLEND) diff --git a/arcade/draw/rect.py b/arcade/draw/rect.py index 0fc3d832ee..8e9deb237a 100644 --- a/arcade/draw/rect.py +++ b/arcade/draw/rect.py @@ -395,7 +395,7 @@ def draw_rect_filled(rect: Rect, color: RGBOrA255, tilt_angle: float = 0) -> Non buffer.orphan() buffer.write(data=array.array("f", (rect.x, rect.y))) - geometry.render(program, mode=ctx.POINTS, vertices=1) + geometry.render(program, instances=1) ctx.disable(ctx.BLEND) diff --git a/arcade/resources/system/shaders/shapes/rectangle/filled_unbuffered_geo.glsl b/arcade/resources/system/shaders/shapes/rectangle/filled_unbuffered_geo.glsl deleted file mode 100644 index fc30127855..0000000000 --- a/arcade/resources/system/shaders/shapes/rectangle/filled_unbuffered_geo.glsl +++ /dev/null @@ -1,42 +0,0 @@ -#version 330 - -layout (points) in; -layout (triangle_strip, max_vertices = 4) out; - -uniform WindowBlock { - mat4 projection; - mat4 view; -} window; - -// [w, h, tilt] -uniform vec3 shape; - -void main() { - // Get center of the circle - vec2 center = gl_in[0].gl_Position.xy; - - // Calculate rotation/tilt - float angle = radians(shape.z); - mat2 rot = mat2( - cos(angle), -sin(angle), - sin(angle), cos(angle) - ); - vec2 size = shape.xy / 2.0; - - // Emit quad as triangle strip - vec2 p1 = rot * vec2(-size.x, size.y); - vec2 p2 = rot * vec2(-size.x, -size.y); - vec2 p3 = rot * vec2( size.x, size.y); - vec2 p4 = rot * vec2( size.x, -size.y); - - gl_Position = window.projection * window.view * vec4(p1 + center, 0.0, 1.0); - EmitVertex(); - gl_Position = window.projection * window.view * vec4(p2 + center, 0.0, 1.0); - EmitVertex(); - gl_Position = window.projection * window.view * vec4(p3 + center, 0.0, 1.0); - EmitVertex(); - gl_Position = window.projection * window.view * vec4(p4 + center, 0.0, 1.0); - EmitVertex(); - - EndPrimitive(); -} diff --git a/arcade/resources/system/shaders/shapes/rectangle/filled_unbuffered_vs.glsl b/arcade/resources/system/shaders/shapes/rectangle/filled_unbuffered_vs.glsl index 02be2f2654..6560d426c9 100644 --- a/arcade/resources/system/shaders/shapes/rectangle/filled_unbuffered_vs.glsl +++ b/arcade/resources/system/shaders/shapes/rectangle/filled_unbuffered_vs.glsl @@ -1,7 +1,24 @@ #version 330 +uniform WindowBlock { + mat4 projection; + mat4 view; +} window; + +// [w, h, tilt] +uniform vec3 shape; + in vec2 in_vert; +in vec2 in_instance_pos; void main() { - gl_Position = vec4(in_vert, 0.0, 1.0); + float angle = radians(shape.z); + mat2 rot = mat2( + cos(angle), -sin(angle), + sin(angle), cos(angle) + ); + // vec2 size = shape.xy / 2.0; + mat4 mvp = window.projection * window.view; + vec2 pos = in_instance_pos + (in_vert * shape.xy); + gl_Position = mvp * vec4(rot * pos, 0.0, 1.0); }