MXVK Vulkan Framework
0.35.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
main.py
Go to the documentation of this file.
1
#!/usr/bin/env python3
2
## @file main.py
3
## @brief MXVK Python compute-shader post-processing example.
4
## @details Loads an image sprite, attaches a compute post-processing shader,
5
## and updates shader mouse, timing, frame-rate, and audio-style uniforms.
6
## The shader is inspected before use, preventing a fragment or vertex SPIR-V
7
## module from being attached as a compute effect.
8
##
9
## @section compute_run Running the example
10
## @code{.sh}
11
## python3 python-examples/compute/main.py --filename inter.comp.spv --vsync
12
## @endcode
13
## @section compute_controls Controls
14
## - Move the mouse to update the shader mouse position.
15
## - Hold the left mouse button to set the shader pressed state.
16
## - Escape: exit.
17
## @section compute_flow Rendering flow
18
## @c SpriteWindow queues the source sprite in @c proc(), then MXVK runs the
19
## @c PostProcessingEffect compute stage and presents its output. The explicit
20
## @c close() method detaches the effect before releasing native resources.
21
22
import
argparse
23
import
time
24
from
pathlib
import
Path
25
26
import
mxvk_ext
as
mxvk
27
28
29
EXAMPLE_DIR = Path(__file__).resolve().parent
30
DATA_DIR = EXAMPLE_DIR /
"data"
31
32
33
class
SpriteWindow
(
mxvk.VK_Window
):
34
def
__init__
(self, filename: str, width: int, height: int, fullscreen: bool, enable_vsync: bool) ->
None
:
35
super().
__init__
(
"VK_Example"
, width, height, fullscreen,
False
, enable_vsync)
36
37
self.
fallback_width
= width
38
self.
fallback_height
= height
39
self.
_closed
=
False
40
self.
start_time
= time.monotonic()
41
self.
last_time
= self.
start_time
42
self.
frame_count
= 0
43
self.
mouse_x
= 0.0
44
self.
mouse_y
= 0.0
45
self.
mouse_pressed
=
False
46
self.
alpha
= 1.0
47
self.
alpha_direction
= 1.0
48
self.
amp
= 0.0
49
self.
iamp
= 0.0
50
self.
amp_peak
= 0.0
51
self.
amp_rms
= 0.0
52
self.
amp_smooth
= 0.0
53
self.
amp_low
= 0.0
54
self.
amp_mid
= 0.0
55
self.
amp_high
= 0.0
56
self.
sample_rate
= 44100.0
57
self.set_font(str(DATA_DIR /
"font.ttf"
), 24)
58
self.
sprite
= self.create_sprite(str(DATA_DIR /
"intro.png"
), str(DATA_DIR /
"sprite.vert.spv"
), str(DATA_DIR /
"fragment.frag.spv"
))
59
compute_path = DATA_DIR / filename
60
info = mxvk.inspect_spirv_file(str(compute_path))
61
62
if(info.stage != mxvk.ShaderStage.compute):
63
raise
RuntimeError(f
"{compute_path} is not a compute shader"
)
64
65
effect = mxvk.PostProcessingEffect()
66
effect.fragment_shader_path = str(compute_path)
67
effect.stage = mxvk.ShaderStage.compute
68
effect.time_enabled =
False
69
self.
effects
= [effect]
70
self.
post_sprites
= self.attach_post_processing_shaders(self.
effects
)
71
self.
compute_sprite
= self.
post_sprites
[0]
72
self.
compute_sprite
.set_custom_uniforms([1.0, 0.018, 0.35, 0.12])
73
self.set_post_processing_enabled(
True
)
74
75
def
close
(self) -> None:
76
if(self.
_closed
):
77
return
78
79
self.
_closed
=
True
80
81
try
:
82
self.detach_post_processing_shader()
83
self.
compute_sprite
=
None
84
self.
post_sprites
=
None
85
self.
effects
=
None
86
self.
sprite
=
None
87
finally
:
88
self.
release
()
89
90
def
update_uniforms
(self, width: int, height: int) ->
None
:
91
now = time.monotonic()
92
elapsed = now - self.
start_time
93
delta_time = now - self.
last_time
94
self.
last_time
= now
95
96
if(delta_time > 0.0):
97
frame_rate = 1.0 / delta_time
98
else
:
99
frame_rate = 0.0
100
101
self.
alpha
+= 0.1 * self.
alpha_direction
102
103
if(self.
alpha
>= 6.0):
104
self.
alpha
= 6.0
105
self.
alpha_direction
= -1.0
106
elif(self.
alpha
<= 1.0):
107
self.
alpha
= 1.0
108
self.
alpha_direction
= 1.0
109
110
self.
compute_sprite
.set_mouse_state(self.
mouse_x
, self.
mouse_y
, 1.0
if
self.
mouse_pressed
else
0.0, 0.0)
111
self.
compute_sprite
.set_uniform0(self.
alpha
, elapsed, float(width), float(height))
112
self.
compute_sprite
.set_uniform1(delta_time, self.
amp
, self.
iamp
, frame_rate)
113
self.
compute_sprite
.set_uniform2(float(self.
frame_count
), elapsed, self.
sample_rate
, self.
amp_peak
)
114
self.
compute_sprite
.set_uniform3(0.0, 0.0, self.
amp_rms
, self.
amp_smooth
)
115
self.
compute_sprite
.set_audio_bands(self.
amp_low
, self.
amp_mid
, self.
amp_high
, 0.0)
116
117
def
proc
(self) -> None:
118
width, height = self.
swapchain_extent
119
120
if(width <= 0
or
height <= 0):
121
width = self.
fallback_width
122
height = self.
fallback_height
123
124
self.
update_uniforms
(width, height)
125
self.
sprite
.draw_rect(0, 0, width, height)
126
self.print_text(
"MXVK Compute Shader"
, 15, 15, mxvk.Color(255, 255, 255, 255))
127
self.
frame_count
+= 1
128
129
def
event
(self, event: mxvk.Event) ->
None
:
130
if(event.type == mxvk.EVENT_KEY_DOWN):
131
if(event.key == mxvk.KEY_ESCAPE):
132
self.request_exit()
133
return
134
135
if(event.mouse_motion):
136
self.
mouse_x
= event.x
137
self.
mouse_y
= event.y
138
return
139
140
if(event.mouse_button_down):
141
if(event.button == mxvk.MOUSE_BUTTON_LEFT):
142
self.
mouse_x
= event.x
143
self.
mouse_y
= event.y
144
self.
mouse_pressed
=
True
145
return
146
147
if(event.mouse_button_up):
148
if(event.button == mxvk.MOUSE_BUTTON_LEFT):
149
self.
mouse_x
= event.x
150
self.
mouse_y
= event.y
151
self.
mouse_pressed
=
False
152
return
153
154
155
def
parse_args
() -> argparse.Namespace:
156
parser = argparse.ArgumentParser(description=
"MXVK Python compute shader example"
)
157
parser.add_argument(
"--filename"
, type=str, default=
"inter.comp.spv"
)
158
parser.add_argument(
"--width"
, type=int, default=1280)
159
parser.add_argument(
"--height"
, type=int, default=720)
160
parser.add_argument(
"--fullscreen"
, action=
"store_true"
)
161
parser.add_argument(
"--vsync"
, action=
"store_true"
)
162
return
parser.parse_args()
163
164
165
def
main
() -> int:
166
args =
parse_args
()
167
window =
None
168
169
try
:
170
window =
SpriteWindow
(args.filename, args.width, args.height, args.fullscreen, args.vsync)
171
window.loop()
172
except
mxvk.MXVKError
as
exception:
173
print(f
"mxvk: Exception: {exception}"
)
174
return
1
175
finally
:
176
if(window
is
not
None
):
177
window.close()
178
179
return
0
180
181
182
if(__name__ ==
"__main__"
):
183
raise
SystemExit(
main
())
main.SpriteWindow
Definition
main.py:33
main.SpriteWindow.amp_high
float amp_high
Definition
main.py:55
main.SpriteWindow.alpha
float alpha
Definition
main.py:46
main.SpriteWindow.last_time
last_time
Definition
main.py:41
main.SpriteWindow.alpha_direction
float alpha_direction
Definition
main.py:47
main.SpriteWindow.sprite
sprite
Definition
main.py:58
main.SpriteWindow.sample_rate
float sample_rate
Definition
main.py:56
main.SpriteWindow.close
None close(self)
Definition
main.py:75
main.SpriteWindow.amp_rms
float amp_rms
Definition
main.py:51
main.SpriteWindow.fallback_height
fallback_height
Definition
main.py:38
main.SpriteWindow.event
None event(self, mxvk.Event event)
Definition
main.py:129
main.SpriteWindow.amp_low
float amp_low
Definition
main.py:53
main.SpriteWindow._closed
bool _closed
Definition
main.py:39
main.SpriteWindow.iamp
float iamp
Definition
main.py:49
main.SpriteWindow.fallback_width
fallback_width
Definition
main.py:37
main.SpriteWindow.amp_smooth
float amp_smooth
Definition
main.py:52
main.SpriteWindow.effects
list effects
Definition
main.py:69
main.SpriteWindow.post_sprites
post_sprites
Definition
main.py:70
main.SpriteWindow.__init__
None __init__(self, str filename, int width, int height, bool fullscreen, bool enable_vsync)
Definition
main.py:34
main.SpriteWindow.start_time
start_time
Definition
main.py:40
main.SpriteWindow.amp_peak
float amp_peak
Definition
main.py:50
main.SpriteWindow.mouse_pressed
bool mouse_pressed
Definition
main.py:45
main.SpriteWindow.update_uniforms
None update_uniforms(self, int width, int height)
Definition
main.py:90
main.SpriteWindow.mouse_y
float mouse_y
Definition
main.py:44
main.SpriteWindow.compute_sprite
compute_sprite
Definition
main.py:71
main.SpriteWindow.amp_mid
float amp_mid
Definition
main.py:54
main.SpriteWindow.frame_count
int frame_count
Definition
main.py:42
main.SpriteWindow.amp
float amp
Definition
main.py:48
main.SpriteWindow.mouse_x
float mouse_x
Definition
main.py:43
mxvk::VK_Window
Main Vulkan window wrapper for MXVK.
Definition
mxvk.hpp:39
mxvk::VK_Window::swapchain_extent
VkExtent2D swapchain_extent
Definition
mxvk.hpp:616
mxvk::VK_Window::release
void release()
Release Vulkan and SDL resources.
Definition
mxvk.cpp:247
mxvk::VK_Window::proc
virtual void proc()
Execute one processing/update step.
Definition
mxvk.cpp:1278
main
Definition
main.py:1
main.main
int main()
Definition
main.py:165
main.parse_args
argparse.Namespace parse_args()
Definition
main.py:155
python-examples
compute
main.py
Generated by
1.18.0