使用FrameBuffer对象#
从一个简单的窗口开始:
起始模板#
1import arcade
2
3SCREEN_WIDTH = 800
4SCREEN_HEIGHT = 600
5SCREEN_TITLE = "Frame Buffer Object Demo"
6
7
8class MyGame(arcade.Window):
9
10 def __init__(self, width, height, title):
11 super().__init__(width, height, title)
12
13 self.background_color = arcade.color.ALMOND
14
15 def setup(self):
16 pass
17
18 def on_draw(self):
19 self.clear()
20
21
22def main():
23 """ Main function """
24 window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
25 window.setup()
26 arcade.run()
27
28
29if __name__ == "__main__":
30 main()
然后创建一个简单的带有帧缓冲区的程序:
直通帧缓冲区#
1import arcade
2from arcade.experimental.texture_render_target import RenderTargetTexture
3
4SCREEN_WIDTH = 800
5SCREEN_HEIGHT = 600
6SCREEN_TITLE = "Starting Template Simple"
7
8
9class RandomFilter(RenderTargetTexture):
10 def __init__(self, width, height):
11 super().__init__(width, height)
12 self.program = self.ctx.program(
13 vertex_shader="""
14 #version 330
15
16 in vec2 in_vert;
17 in vec2 in_uv;
18 out vec2 uv;
19
20 void main() {
21 gl_Position = vec4(in_vert, 0.0, 1.0);
22 uv = in_uv;
23 }
24 """,
25 fragment_shader="""
26 #version 330
27
28 uniform sampler2D texture0;
29
30 in vec2 uv;
31 out vec4 fragColor;
32
33 void main() {
34 vec4 color = texture(texture0, uv);
35 fragColor = color;
36 }
37 """,
38 )
39
40 def use(self):
41 self._fbo.use()
42
43 def draw(self):
44 self.texture.use(0)
45 self._quad_fs.render(self.program)
46
47
48class MyGame(arcade.Window):
49
50 def __init__(self, width, height, title):
51 super().__init__(width, height, title)
52 self.filter = RandomFilter(width, height)
53
54 def on_draw(self):
55 self.clear()
56 self.filter.clear()
57 self.filter.use()
58 arcade.draw_circle_filled(self.width / 2, self.height / 2, 100, arcade.color.RED)
59 arcade.draw_circle_filled(400, 300, 100, arcade.color.GREEN)
60
61 self.use()
62 self.filter.draw()
63
64
65def main():
66 """ Main function """
67 MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
68 arcade.run()
69
70
71if __name__ == "__main__":
72 main()
73
现在,将Alpha不为零的所有内容涂成绿色:
直通帧缓冲区#
1import arcade
2from arcade.experimental.texture_render_target import RenderTargetTexture
3
4SCREEN_WIDTH = 800
5SCREEN_HEIGHT = 600
6SCREEN_TITLE = "Starting Template Simple"
7
8
9class RandomFilter(RenderTargetTexture):
10 def __init__(self, width, height):
11 super().__init__(width, height)
12 self.program = self.ctx.program(
13 vertex_shader="""
14 #version 330
15
16 in vec2 in_vert;
17 in vec2 in_uv;
18 out vec2 uv;
19
20 void main() {
21 gl_Position = vec4(in_vert, 0.0, 1.0);
22 uv = in_uv;
23 }
24 """,
25 fragment_shader="""
26 #version 330
27
28 uniform sampler2D texture0;
29
30 in vec2 uv;
31 out vec4 fragColor;
32
33 void main() {
34 vec4 color = texture(texture0, uv);
35
36 if (color.a > 0)
37 fragColor = vec4(0, 1, 0, 1.0);
38 else
39 fragColor = vec4(0, 0, 0, 0);
40 }
41 """,
42 )
43
44 def use(self):
45 self._fbo.use()
46
47 def draw(self):
48 self.texture.use(0)
49 self._quad_fs.render(self.program)
50
51
52class MyGame(arcade.Window):
53
54 def __init__(self, width, height, title):
55 super().__init__(width, height, title)
56 self.filter = RandomFilter(width, height)
57
58 def on_draw(self):
59 self.clear()
60 self.filter.clear()
61 self.filter.use()
62 arcade.draw_circle_filled(self.width / 2, self.height / 2, 100, arcade.color.RED)
63
64 self.use()
65 self.filter.draw()
66
67
68def main():
69 """ Main function """
70 MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
71 arcade.run()
72
73
74if __name__ == "__main__":
75 main()
有关将统一数据传递到着色器的信息:
直通帧缓冲区#
1import arcade
2from arcade.experimental.texture_render_target import RenderTargetTexture
3
4SCREEN_WIDTH = 800
5SCREEN_HEIGHT = 600
6SCREEN_TITLE = "Starting Template Simple"
7
8
9class RandomFilter(RenderTargetTexture):
10 def __init__(self, width, height):
11 super().__init__(width, height)
12 self.program = self.ctx.program(
13 vertex_shader="""
14 #version 330
15
16 in vec2 in_vert;
17 in vec2 in_uv;
18 out vec2 uv;
19
20 void main() {
21 gl_Position = vec4(in_vert, 0.0, 1.0);
22 uv = in_uv;
23 }
24 """,
25 fragment_shader="""
26 #version 330
27
28 uniform sampler2D texture0;
29
30 in vec2 uv;
31 uniform vec4 my_color;
32 out vec4 fragColor;
33
34 void main() {
35 vec4 color = texture(texture0, uv);
36
37 if (color.a > 0)
38 fragColor = my_color;
39 else
40 fragColor = vec4(0, 0, 0, 0);
41 }
42 """,
43 )
44 self.program["my_color"] = 1, 0, 1, 1
45
46 def use(self):
47 self._fbo.use()
48
49 def draw(self):
50 self.texture.use(0)
51 self._quad_fs.render(self.program)
52
53
54class MyGame(arcade.Window):
55
56 def __init__(self, width, height, title):
57 super().__init__(width, height, title)
58 self.filter = RandomFilter(width, height)
59
60 def on_draw(self):
61 self.clear()
62 self.filter.clear()
63 self.filter.use()
64 arcade.draw_circle_filled(self.width / 2, self.height / 2, 100, arcade.color.RED)
65
66 self.use()
67 self.filter.draw()
68
69
70def main():
71 """ Main function """
72 MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
73 arcade.run()
74
75
76if __name__ == "__main__":
77 main()