Skip to content

Commit 90a203c

Browse files
committed
unbuffered ellipse shader: remove geometry shader
1 parent ae87741 commit 90a203c

4 files changed

Lines changed: 49 additions & 81 deletions

File tree

arcade/context.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ def __init__(
159159
self.shape_ellipse_filled_unbuffered_program: Program = self.load_program(
160160
vertex_shader=":system:shaders/shapes/ellipse/filled_unbuffered_vs.glsl",
161161
fragment_shader=":system:shaders/shapes/ellipse/filled_unbuffered_fs.glsl",
162-
geometry_shader=":system:shaders/shapes/ellipse/filled_unbuffered_geo.glsl",
163162
)
164163
self.shape_ellipse_outline_unbuffered_program: Program = self.load_program(
165164
vertex_shader=":system:shaders/shapes/ellipse/outline_unbuffered_vs.glsl",
@@ -258,11 +257,8 @@ def __init__(
258257
],
259258
mode=self.TRIANGLE_STRIP,
260259
)
261-
# ellipse/circle filled
262-
self.shape_ellipse_unbuffered_buffer = self.buffer(reserve=8)
263-
self.shape_ellipse_unbuffered_geometry: Geometry = self.geometry(
264-
[BufferDescription(self.shape_ellipse_unbuffered_buffer, "2f", ["in_vert"])]
265-
)
260+
# ellipse/circle filled. Empty geometry. We generate it on the fly in the vertex shader.
261+
self.shape_ellipse_unbuffered_geometry: Geometry = self.geometry()
266262
# ellipse/circle outline
267263
self.shape_ellipse_outline_unbuffered_buffer = self.buffer(reserve=8)
268264
self.shape_ellipse_outline_unbuffered_geometry: Geometry = self.geometry(

arcade/draw/circle.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,23 +129,31 @@ def draw_ellipse_filled(
129129
# Fail immediately if we have no window or context
130130
window = get_window()
131131
ctx = window.ctx
132-
ctx.enable(ctx.BLEND)
133132

134133
program = ctx.shape_ellipse_filled_unbuffered_program
135134
geometry = ctx.shape_ellipse_unbuffered_geometry
136-
buffer = ctx.shape_ellipse_unbuffered_buffer # type: ignore
137135

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

139+
# Auto select number of segments if not specified
140+
if num_segments == -1:
141+
size = max(width, height)
142+
if size <= 12:
143+
num_segments = 6
144+
else:
145+
num_segments = int(size) // 2
146+
147+
if num_segments < 3:
148+
num_segments = 3
149+
141150
# Pass data to the shader
151+
program["center"] = center_x, center_y
142152
program["color"] = color_normalized
143153
program["shape"] = width / 2, height / 2, tilt_angle
144154
program["segments"] = num_segments
145-
buffer.orphan()
146-
buffer.write(data=array.array("f", (center_x, center_y)))
147-
148-
geometry.render(program, mode=gl.POINTS, vertices=1)
155+
ctx.enable(ctx.BLEND)
156+
geometry.render(program, mode=ctx.TRIANGLES, vertices=num_segments * 3)
149157
ctx.disable(ctx.BLEND)
150158

151159

arcade/resources/system/shaders/shapes/ellipse/filled_unbuffered_geo.glsl

Lines changed: 0 additions & 68 deletions
This file was deleted.
Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,39 @@
11
#version 330
22

3+
uniform WindowBlock {
4+
mat4 projection;
5+
mat4 view;
6+
} window;
7+
8+
uniform vec2 center;
9+
uniform int segments;
10+
// [w, h, tilt]
11+
uniform vec3 shape;
12+
313
in vec2 in_vert;
414

15+
const float PI = 3.141592;
16+
517
void main() {
6-
gl_Position = vec4(in_vert, 0.0, 1.0);
18+
int triangle_id = gl_VertexID / 3;
19+
int vertex_id = gl_VertexID % 3;
20+
21+
// Calculate rotation/tilt
22+
float angle = radians(shape.z);
23+
mat2 rot = mat2(
24+
cos(angle), -sin(angle),
25+
sin(angle), cos(angle)
26+
);
27+
// Calculate the positions for the full triangle in the current segment
28+
vec2 positions[3] = vec2[3](
29+
vec2(0.0, 0.0),
30+
vec2(sin((float(triangle_id) + 1.0) * (PI * 2.0 / float(segments))),
31+
cos((float(triangle_id) + 1.0) * (PI * 2.0 / float(segments)))) * shape.xy,
32+
vec2(sin(float(triangle_id) * (PI * 2.0 / float(segments))),
33+
cos(float(triangle_id) * (PI * 2.0 / float(segments)))) * shape.xy
34+
);
35+
36+
mat4 mvp = window.projection * window.view;
37+
vec4 pos = vec4(rot * positions[vertex_id] + center, 0.0, 1.0);
38+
gl_Position = mvp * pos;
739
}

0 commit comments

Comments
 (0)