Shape List Demo¶
These are three examples:
One with no shape lists, and no buffered drawing.
One with simple buffered drawing. About 4x faster.
The last with complex buffered drawing. More than 850x faster.
Example One - No Shape Lists¶
1"""
2This demo shows the speed of drawing a full grid of squares using no buffering.
3
4For me this takes about 1.3 seconds per frame.
5
6It is slow because we load all the points and all the colors to the card every
7time.
8
9If Python and Arcade are installed, this example can be run from the command line with:
10python -m arcade.examples.shape_list_demo_1
11"""
12
13import arcade
14import timeit
15
16SCREEN_WIDTH = 1200
17SCREEN_HEIGHT = 800
18SCREEN_TITLE = "Shape List Demo 1"
19
20SQUARE_WIDTH = 5
21SQUARE_HEIGHT = 5
22SQUARE_SPACING = 10
23
24
25class MyGame(arcade.Window):
26 """ Main application class. """
27
28 def __init__(self, width, height, title):
29 super().__init__(width, height, title)
30
31 arcade.set_background_color(arcade.color.DARK_SLATE_GRAY)
32
33 self.draw_time = 0
34
35 def on_draw(self):
36 """
37 Render the screen.
38 """
39
40 # This command has to happen before we start drawing
41 arcade.start_render()
42
43 # Start timing how long this takes
44 draw_start_time = timeit.default_timer()
45
46 # --- Draw all the rectangles
47 for x in range(0, SCREEN_WIDTH, SQUARE_SPACING):
48 for y in range(0, SCREEN_HEIGHT, SQUARE_SPACING):
49 arcade.draw_rectangle_filled(x, y, SQUARE_WIDTH, SQUARE_HEIGHT, arcade.color.DARK_BLUE)
50
51 # Print the timing
52 output = f"Drawing time: {self.draw_time:.3f} seconds per frame."
53 arcade.draw_text(output, 20, SCREEN_HEIGHT - 40, arcade.color.WHITE, 18)
54
55 self.draw_time = timeit.default_timer() - draw_start_time
56
57
58def main():
59 MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
60
61 arcade.run()
62
63
64if __name__ == "__main__":
65 main()
Example Two - Simple Shape Lists¶
1"""
2This demo shows using buffered rectangles to draw a grid of squares on the
3screen.
4
5For me this starts at 0.500 seconds and goes down to 0.220 seconds after the
6graphics card figures out some optimizations.
7
8It is faster than demo 1 because we aren't loading the vertices and color
9to the card again and again. It isn't very fast because we are still sending
10individual draw commands to the graphics card for each square.
11
12If Python and Arcade are installed, this example can be run from the command line with:
13python -m arcade.examples.shape_list_demo_2
14"""
15
16import arcade
17import timeit
18
19SCREEN_WIDTH = 1200
20SCREEN_HEIGHT = 800
21SCREEN_TITLE = "Shape List Demo 2"
22
23SQUARE_WIDTH = 5
24SQUARE_HEIGHT = 5
25SQUARE_SPACING = 10
26
27
28class MyGame(arcade.Window):
29 """ Main application class. """
30
31 def __init__(self, width, height, title):
32 super().__init__(width, height, title)
33
34 arcade.set_background_color(arcade.color.DARK_SLATE_GRAY)
35
36 self.draw_time = 0
37 self.shape_list = None
38
39 def setup(self):
40 # --- Create the vertex buffers objects for each square before we do
41 # any drawing.
42 self.shape_list = arcade.ShapeElementList()
43 for x in range(0, SCREEN_WIDTH, SQUARE_SPACING):
44 for y in range(0, SCREEN_HEIGHT, SQUARE_SPACING):
45 shape = arcade.create_rectangle_filled(x, y, SQUARE_WIDTH, SQUARE_HEIGHT, arcade.color.DARK_BLUE)
46 self.shape_list.append(shape)
47
48 def on_draw(self):
49 """
50 Render the screen.
51 """
52
53 # This command has to happen before we start drawing
54 arcade.start_render()
55
56 # Start timing how long this takes
57 draw_start_time = timeit.default_timer()
58
59 # --- Draw all the rectangles
60 self.shape_list.draw()
61
62 output = f"Drawing time: {self.draw_time:.3f} seconds per frame."
63 arcade.draw_text(output, 20, SCREEN_HEIGHT - 40, arcade.color.WHITE, 18)
64
65 self.draw_time = timeit.default_timer() - draw_start_time
66
67
68def main():
69 window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
70 window.setup()
71 arcade.run()
72
73
74if __name__ == "__main__":
75 main()
Example Three - Complex Shape Lists¶
1"""
2This demo shows drawing a grid of squares using a single buffer.
3
4We calculate the points of each rectangle and add them to a point list.
5We create a list of colors for each point.
6We then draw all the squares with one drawing command.
7
8This runs in about 0.000 seconds for me. It is much more complex in code
9than the prior two examples, but the pay-off in speed is huge.
10
11If Python and Arcade are installed, this example can be run from the command line with:
12python -m arcade.examples.shape_list_demo_3
13"""
14
15import arcade
16import timeit
17
18SCREEN_WIDTH = 1200
19SCREEN_HEIGHT = 800
20SCREEN_TITLE = "Shape List Demo 3"
21
22HALF_SQUARE_WIDTH = 2.5
23HALF_SQUARE_HEIGHT = 2.5
24SQUARE_SPACING = 10
25
26
27class MyGame(arcade.Window):
28 """ Main application class. """
29
30 def __init__(self, width, height, title):
31 super().__init__(width, height, title)
32
33 arcade.set_background_color(arcade.color.DARK_SLATE_GRAY)
34
35 self.draw_time = 0
36 self.shape_list = None
37
38 def setup(self):
39 self.shape_list = arcade.ShapeElementList()
40
41 # --- Create all the rectangles
42
43 # We need a list of all the points and colors
44 point_list = []
45 color_list = []
46
47 # Now calculate all the points
48 for x in range(0, SCREEN_WIDTH, SQUARE_SPACING):
49 for y in range(0, SCREEN_HEIGHT, SQUARE_SPACING):
50
51 # Calculate where the four points of the rectangle will be if
52 # x and y are the center
53 top_left = (x - HALF_SQUARE_WIDTH, y + HALF_SQUARE_HEIGHT)
54 top_right = (x + HALF_SQUARE_WIDTH, y + HALF_SQUARE_HEIGHT)
55 bottom_right = (x + HALF_SQUARE_WIDTH, y - HALF_SQUARE_HEIGHT)
56 bottom_left = (x - HALF_SQUARE_WIDTH, y - HALF_SQUARE_HEIGHT)
57
58 # Add the points to the points list.
59 # ORDER MATTERS!
60 # Rotate around the rectangle, don't append points caty-corner
61 point_list.append(top_left)
62 point_list.append(top_right)
63 point_list.append(bottom_right)
64 point_list.append(bottom_left)
65
66 # Add a color for each point. Can be different colors if you want
67 # gradients.
68 for i in range(4):
69 color_list.append(arcade.color.DARK_BLUE)
70
71 shape = arcade.create_rectangles_filled_with_colors(point_list, color_list)
72 self.shape_list.append(shape)
73
74 def on_draw(self):
75 """
76 Render the screen.
77 """
78
79 # This command has to happen before we start drawing
80 arcade.start_render()
81
82 # Start timing how long this takes
83 draw_start_time = timeit.default_timer()
84
85 # --- Draw all the rectangles
86 self.shape_list.draw()
87
88 output = f"Drawing time: {self.draw_time:.3f} seconds per frame."
89 arcade.draw_text(output, 20, SCREEN_HEIGHT - 40, arcade.color.WHITE, 18)
90
91 self.draw_time = timeit.default_timer() - draw_start_time
92
93
94def main():
95 window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
96 window.setup()
97 arcade.run()
98
99
100if __name__ == "__main__":
101 main()