8
8
//! I can focus on the shader stuff. It'll probably be a good idea to go back and tweak some of that stuff later
9
9
//! to get it to work on other platforms, but I'm not really worried about that right now.
10
10
11
- use wgpu:: {
12
- include_wgsl, BindGroupDescriptor , BindGroupEntry , BindGroupLayoutDescriptor ,
13
- BindGroupLayoutEntry , BindingResource , BindingType , BufferBindingType , BufferDescriptor ,
14
- BufferUsages , ColorTargetState , CommandEncoderDescriptor , DeviceDescriptor , Features ,
15
- FragmentState , Instance , Limits , MultisampleState , PipelineLayoutDescriptor , PowerPreference ,
16
- PrimitiveState , RenderPassColorAttachment , RenderPassDescriptor , RenderPipelineDescriptor ,
17
- RequestAdapterOptions , ShaderStages , TextureViewDescriptor , VertexState ,
18
- } ;
19
11
use winit:: {
20
12
event:: { Event , WindowEvent } ,
21
13
event_loop:: EventLoop ,
22
- window:: { Window , WindowBuilder } ,
14
+ window:: WindowBuilder ,
23
15
} ;
24
16
17
+ mod app;
18
+
25
19
#[ tokio:: main]
26
20
async fn main ( ) {
27
21
// Setup windowing
@@ -32,7 +26,7 @@ async fn main() {
32
26
. expect ( "New window" ) ;
33
27
34
28
// Setup the app
35
- let mut app = App :: new ( window) . await ;
29
+ let mut app = app :: App :: new ( window) . await ;
36
30
37
31
// Run the event loop
38
32
let _ = event_loop. run ( |event, elwt| {
@@ -77,171 +71,3 @@ struct MousePosition {
77
71
x : f32 ,
78
72
y : f32 ,
79
73
}
80
-
81
- // impl bytemuck::Pod and bytemuck::Zeroable so we can use it as a buffer
82
- // I'm not sure if this is the best way to do this, but it works.
83
- unsafe impl bytemuck:: Pod for MousePosition { }
84
- unsafe impl bytemuck:: Zeroable for MousePosition { }
85
-
86
- struct App < ' a > {
87
- // Render stuff
88
- surface : wgpu:: Surface < ' a > ,
89
- adapter : wgpu:: Adapter ,
90
- queue : wgpu:: Queue ,
91
- device : wgpu:: Device ,
92
- render_pipeline : wgpu:: RenderPipeline ,
93
-
94
- // Buffer stuff
95
- buffer : wgpu:: Buffer ,
96
- bind_group : wgpu:: BindGroup ,
97
- mouse_position : Option < MousePosition > ,
98
- }
99
- impl App < ' _ > {
100
- async fn new ( window : Window ) -> Self {
101
- // Grab the window size now, so we can use it to size our surface.
102
- // We need it here because we won't have a borrow on the window later.
103
- let size = window. inner_size ( ) ;
104
-
105
- // Setting up access to the GPU and the surface to render too.
106
- let instance = Instance :: default ( ) ;
107
- let surface = instance. create_surface ( window) . expect ( "Create surface" ) ;
108
- let adapter = instance
109
- . request_adapter ( & RequestAdapterOptions {
110
- power_preference : PowerPreference :: default ( ) ,
111
- force_fallback_adapter : false ,
112
- compatible_surface : Some ( & surface) ,
113
- } )
114
- . await
115
- . expect ( "Request adapter" ) ;
116
- let ( device, queue) = adapter
117
- . request_device (
118
- & DeviceDescriptor {
119
- label : None ,
120
- required_features : Features :: default ( ) ,
121
- required_limits : Limits :: default ( ) ,
122
- } ,
123
- None ,
124
- )
125
- . await
126
- . expect ( "Request device" ) ;
127
- let surface_config = surface
128
- . get_default_config ( & adapter, size. width , size. height )
129
- . expect ( "Get default surface config" ) ;
130
- surface. configure ( & device, & surface_config) ;
131
-
132
- // Set up a buffer to store mouse position
133
- let buffer = device. create_buffer ( & BufferDescriptor {
134
- label : None ,
135
- size : 32 * 2 , // 'vec2<f32>'
136
- usage : BufferUsages :: UNIFORM | BufferUsages :: COPY_DST ,
137
- mapped_at_creation : false ,
138
- } ) ;
139
- let bind_group_layout = device. create_bind_group_layout ( & BindGroupLayoutDescriptor {
140
- entries : & [ BindGroupLayoutEntry {
141
- binding : 0 ,
142
- visibility : ShaderStages :: FRAGMENT ,
143
- ty : BindingType :: Buffer {
144
- ty : BufferBindingType :: Uniform ,
145
- has_dynamic_offset : false ,
146
- min_binding_size : None ,
147
- } ,
148
- count : None ,
149
- } ] ,
150
- label : None ,
151
- } ) ;
152
- let bind_group = device. create_bind_group ( & BindGroupDescriptor {
153
- layout : & bind_group_layout,
154
- entries : & [ BindGroupEntry {
155
- binding : 0 ,
156
- resource : BindingResource :: Buffer ( buffer. as_entire_buffer_binding ( ) ) ,
157
- } ] ,
158
- label : None ,
159
- } ) ;
160
- let pipeline_layout = device. create_pipeline_layout ( & PipelineLayoutDescriptor {
161
- bind_group_layouts : & [ & bind_group_layout] ,
162
- ..Default :: default ( )
163
- } ) ;
164
-
165
- // Set up the render pipeline
166
- let shader = device. create_shader_module ( include_wgsl ! ( "shader.wgsl" ) ) ;
167
- let render_pipeline = device. create_render_pipeline ( & RenderPipelineDescriptor {
168
- label : None ,
169
- layout : Some ( & pipeline_layout) ,
170
- vertex : VertexState {
171
- module : & shader,
172
- entry_point : "vertex" ,
173
- buffers : & [ ] ,
174
- } ,
175
- primitive : PrimitiveState :: default ( ) ,
176
- depth_stencil : None ,
177
- multisample : MultisampleState :: default ( ) ,
178
- fragment : Some ( FragmentState {
179
- module : & shader,
180
- entry_point : "fragment" ,
181
- targets : & [ Some ( ColorTargetState {
182
- format : surface_config. format ,
183
- blend : None ,
184
- write_mask : Default :: default ( ) ,
185
- } ) ] ,
186
- } ) ,
187
- multiview : None ,
188
- } ) ;
189
-
190
- Self {
191
- surface,
192
- adapter,
193
- queue,
194
- device,
195
- render_pipeline,
196
- buffer,
197
- bind_group,
198
- mouse_position : None ,
199
- }
200
- }
201
-
202
- fn render ( & self ) {
203
- let surface_texture = self
204
- . surface
205
- . get_current_texture ( )
206
- . expect ( "Get current texture" ) ;
207
- let texture_view = surface_texture
208
- . texture
209
- . create_view ( & TextureViewDescriptor :: default ( ) ) ;
210
-
211
- let mut command_encoder = self
212
- . device
213
- . create_command_encoder ( & CommandEncoderDescriptor :: default ( ) ) ;
214
- {
215
- let mut render_pass = command_encoder. begin_render_pass ( & RenderPassDescriptor {
216
- color_attachments : & [ Some ( RenderPassColorAttachment {
217
- view : & texture_view,
218
- resolve_target : None ,
219
- ops : Default :: default ( ) ,
220
- } ) ] ,
221
- ..Default :: default ( )
222
- } ) ;
223
- render_pass. set_pipeline ( & self . render_pipeline ) ;
224
- render_pass. set_bind_group ( 0 , & self . bind_group , & [ ] ) ;
225
- render_pass. draw ( 0 ..6 , 0 ..1 ) ;
226
- }
227
-
228
- // Copy the mouse position into the buffer if we have one
229
- if let Some ( mp) = self . mouse_position {
230
- self . queue
231
- . write_buffer ( & self . buffer , 0 , bytemuck:: cast_slice ( & [ mp] ) )
232
- }
233
-
234
- self . queue . submit ( Some ( command_encoder. finish ( ) ) ) ;
235
- surface_texture. present ( ) ;
236
- }
237
-
238
- fn resize ( & mut self , size : winit:: dpi:: PhysicalSize < u32 > ) {
239
- self . surface . configure (
240
- & self . device ,
241
- & self
242
- . surface
243
- . get_default_config ( & self . adapter , size. width , size. height )
244
- . expect ( "Get default surface config" ) ,
245
- ) ;
246
- }
247
- }
0 commit comments