Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions arcade/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,10 @@ def __init__(
self.shape_ellipse_filled_unbuffered_program: Program = self.load_program(
vertex_shader=":system:shaders/shapes/ellipse/filled_unbuffered_vs.glsl",
fragment_shader=":system:shaders/shapes/ellipse/filled_unbuffered_fs.glsl",
geometry_shader=":system:shaders/shapes/ellipse/filled_unbuffered_geo.glsl",
)
self.shape_ellipse_outline_unbuffered_program: Program = self.load_program(
vertex_shader=":system:shaders/shapes/ellipse/outline_unbuffered_vs.glsl",
fragment_shader=":system:shaders/shapes/ellipse/outline_unbuffered_fs.glsl",
geometry_shader=":system:shaders/shapes/ellipse/outline_unbuffered_geo.glsl",
)
self.shape_rectangle_filled_unbuffered_program = self.load_program(
vertex_shader=":system:shaders/shapes/rectangle/filled_unbuffered_vs.glsl",
Expand Down Expand Up @@ -258,16 +256,10 @@ def __init__(
],
mode=self.TRIANGLE_STRIP,
)
# ellipse/circle filled
self.shape_ellipse_unbuffered_buffer = self.buffer(reserve=8)
self.shape_ellipse_unbuffered_geometry: Geometry = self.geometry(
[BufferDescription(self.shape_ellipse_unbuffered_buffer, "2f", ["in_vert"])]
)
# ellipse/circle outline
self.shape_ellipse_outline_unbuffered_buffer = self.buffer(reserve=8)
self.shape_ellipse_outline_unbuffered_geometry: Geometry = self.geometry(
[BufferDescription(self.shape_ellipse_outline_unbuffered_buffer, "2f", ["in_vert"])]
)
# ellipse/circle filled. Empty geometry. We generate it on the fly in the vertex shader.
self.shape_ellipse_unbuffered_geometry: Geometry = self.geometry()
# ellipse/circle outline. Empty geometry. We generate it on the fly in the vertex shader.
self.shape_ellipse_outline_unbuffered_geometry: Geometry = self.geometry()
# rectangle filled
self.shape_rectangle_filled_unbuffered_buffer = self.buffer(reserve=8)
# fmt: off
Expand Down
42 changes: 27 additions & 15 deletions arcade/draw/circle.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import array

from arcade import gl
from arcade.types import Color, RGBOrA255
from arcade.window_commands import get_window

Expand Down Expand Up @@ -129,23 +126,31 @@ def draw_ellipse_filled(
# Fail immediately if we have no window or context
window = get_window()
ctx = window.ctx
ctx.enable(ctx.BLEND)

program = ctx.shape_ellipse_filled_unbuffered_program
geometry = ctx.shape_ellipse_unbuffered_geometry
buffer = ctx.shape_ellipse_unbuffered_buffer # type: ignore

# Normalize the color because this shader takes a float uniform
color_normalized = Color.from_iterable(color).normalized

# Auto select number of segments if not specified
if num_segments == -1:
size = max(width, height)
if size <= 12:
num_segments = 6
else:
num_segments = int(size) // 2

if num_segments < 3:
num_segments = 3

# Pass data to the shader
program["center"] = center_x, center_y
program["color"] = color_normalized
program["shape"] = width / 2, height / 2, tilt_angle
program["segments"] = num_segments
buffer.orphan()
buffer.write(data=array.array("f", (center_x, center_y)))

geometry.render(program, mode=gl.POINTS, vertices=1)
ctx.enable(ctx.BLEND)
geometry.render(program, mode=ctx.TRIANGLES, vertices=num_segments * 3)
ctx.disable(ctx.BLEND)


Expand Down Expand Up @@ -190,20 +195,27 @@ def draw_ellipse_outline(
ctx = window.ctx
program = ctx.shape_ellipse_outline_unbuffered_program
geometry = ctx.shape_ellipse_outline_unbuffered_geometry
buffer = ctx.shape_ellipse_outline_unbuffered_buffer # type: ignore

# Normalize the color because this shader takes a float uniform
color_normalized = Color.from_iterable(color).normalized

ctx.enable(ctx.BLEND)
# Auto select number of segments if not specified
if num_segments == -1:
size = max(width, height)
if size <= 12:
num_segments = 6
else:
num_segments = int(size) // 2

if num_segments < 3:
num_segments = 3

# Pass data to shader
program["center"] = center_x, center_y
program["color"] = color_normalized
program["shape"] = width / 2, height / 2, tilt_angle, border_width
program["segments"] = num_segments
buffer.orphan()
buffer.write(data=array.array("f", (center_x, center_y)))

geometry.render(program, mode=gl.POINTS, vertices=1)

ctx.enable(ctx.BLEND)
geometry.render(program, mode=ctx.TRIANGLES, vertices=num_segments * 6)
ctx.disable(ctx.BLEND)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,37 @@
#version 330

in vec2 in_vert;
uniform WindowBlock {
mat4 projection;
mat4 view;
} window;

uniform vec2 center;
uniform int segments;
// [w, h, tilt]
uniform vec3 shape;

const float PI = 3.141592;

void main() {
gl_Position = vec4(in_vert, 0.0, 1.0);
int triangle_id = gl_VertexID / 3;
int vertex_id = gl_VertexID % 3;

// Calculate rotation/tilt
float angle = radians(shape.z);
mat2 rot = mat2(
cos(angle), -sin(angle),
sin(angle), cos(angle)
);
// Calculate the positions for the full triangle in the current segment
vec2 positions[3] = vec2[3](
vec2(0.0, 0.0),
vec2(sin((float(triangle_id) + 1.0) * (PI * 2.0 / float(segments))),
cos((float(triangle_id) + 1.0) * (PI * 2.0 / float(segments)))) * shape.xy,
vec2(sin(float(triangle_id) * (PI * 2.0 / float(segments))),
cos(float(triangle_id) * (PI * 2.0 / float(segments)))) * shape.xy
);

mat4 mvp = window.projection * window.view;
vec4 pos = vec4(rot * positions[vertex_id] + center, 0.0, 1.0);
gl_Position = mvp * pos;
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,45 @@
#version 330

in vec2 in_vert;
uniform WindowBlock {
mat4 projection;
mat4 view;
} window;

uniform vec2 center;
uniform int segments;
// [w, h, tilt, thickness]
uniform vec4 shape;

const float PI = 3.141592;

void main() {
gl_Position = vec4(in_vert, 0.0, 1.0);
// Two triangles per line segment of the outline
int segment_id = gl_VertexID / 6;
int vertex_id = gl_VertexID % 6;

// Calculate rotation/tilt
float angle = radians(shape.z);
mat2 rot = mat2(
cos(angle), -sin(angle),
sin(angle), cos(angle)
);

// sin(v), cos(v) travels clockwise around the circle starting at 0, 1 (top of circle)
float st = PI * 2.0 / float(segments);

// calculate the four points of the line segment
// Inner and outer points for the start of line segment
vec2 p0 = vec2(sin(float(segment_id) * st), cos(float(segment_id) * st)) * shape.xy;
vec2 p1 = vec2(sin(float(segment_id) * st), cos(float(segment_id) * st)) * (shape.xy - vec2(shape.w));

// Inner and outer points for the end of line segment
vec2 p2 = vec2(sin((float(segment_id) + 1.0) * st), cos((float(segment_id) + 1.0) * st)) * shape.xy;
vec2 p3 = vec2(sin((float(segment_id) + 1.0) * st), cos((float(segment_id) + 1.0) * st)) * (shape.xy - vec2(shape.w));

vec2 position[6] = vec2[6](
p1, p0, p2, // first triangle
p1, p2, p3 // second triangle
);
mat4 mvp = window.projection * window.view;
gl_Position = mvp * vec4(rot * position[vertex_id] + center, 0.0, 1.0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ void main() {
);
// 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);
vec2 pos = in_instance_pos + (rot * (in_vert * shape.xy));
gl_Position = mvp * vec4(pos, 0.0, 1.0);
}
Loading