truck_platform/
scene.rs

1use crate::*;
2use std::sync::atomic::{AtomicUsize, Ordering};
3use winit::window::Window;
4
5static MAXID: AtomicUsize = AtomicUsize::new(0);
6
7impl RenderID {
8    /// Generate the unique `RenderID`.
9    #[inline(always)]
10    pub fn gen() -> Self { RenderID(MAXID.fetch_add(1, Ordering::SeqCst)) }
11}
12
13async fn init_default_device(
14    window: Option<Arc<Window>>,
15) -> (DeviceHandler, Option<WindowHandler>) {
16    #[cfg(not(feature = "webgl"))]
17    let backends = Backends::PRIMARY;
18    #[cfg(feature = "webgl")]
19    let backends = Backends::all();
20    let instance = Instance::new(InstanceDescriptor {
21        backends,
22        ..Default::default()
23    });
24
25    let surface = window.as_ref().map(|window| {
26        instance
27            .create_surface(Arc::clone(window))
28            .expect("Failed to create `Surface`")
29    });
30
31    let adapter = instance
32        .request_adapter(&RequestAdapterOptions {
33            #[cfg(not(feature = "webgl"))]
34            power_preference: PowerPreference::HighPerformance,
35            #[cfg(feature = "webgl")]
36            power_preference: PowerPreference::LowPower,
37            compatible_surface: surface.as_ref(),
38            force_fallback_adapter: false,
39        })
40        .await
41        .expect("Failed to find an appropriate adapter");
42
43    let (device, queue) = adapter
44        .request_device(
45            &DeviceDescriptor {
46                required_features: Default::default(),
47                memory_hints: MemoryHints::Performance,
48                #[cfg(not(feature = "webgl"))]
49                required_limits: Limits::downlevel_defaults().using_resolution(adapter.limits()),
50                #[cfg(feature = "webgl")]
51                required_limits: Limits::downlevel_webgl2_defaults(),
52                label: None,
53            },
54            None,
55        )
56        .await
57        .expect("Failed to create device");
58    let device_handler = DeviceHandler {
59        adapter: Arc::new(adapter),
60        device: Arc::new(device),
61        queue: Arc::new(queue),
62    };
63    let window_handler = window.map(|window| WindowHandler {
64        window,
65        surface: Arc::new(surface.unwrap()),
66    });
67    (device_handler, window_handler)
68}
69
70impl DeviceHandler {
71    /// constructor
72    #[inline(always)]
73    pub const fn new(
74        adapter: Arc<Adapter>,
75        device: Arc<Device>,
76        queue: Arc<Queue>,
77    ) -> DeviceHandler {
78        DeviceHandler {
79            adapter,
80            device,
81            queue,
82        }
83    }
84    /// Returns the reference of the adapter.
85    #[inline(always)]
86    pub const fn adapter(&self) -> &Arc<Adapter> { &self.adapter }
87    /// Returns the reference of the device.
88    #[inline(always)]
89    pub const fn device(&self) -> &Arc<Device> { &self.device }
90    /// Returns the reference of the queue.
91    #[inline(always)]
92    pub const fn queue(&self) -> &Arc<Queue> { &self.queue }
93
94    /// Creates default device handler.
95    pub async fn default_device() -> Self { init_default_device(None).await.0 }
96}
97
98impl Default for StudioConfig {
99    #[inline(always)]
100    fn default() -> StudioConfig {
101        StudioConfig {
102            background: Color::BLACK,
103            camera: Camera::default(),
104            lights: vec![Light::default()],
105        }
106    }
107}
108
109impl Default for BackendBufferConfig {
110    #[inline(always)]
111    fn default() -> BackendBufferConfig {
112        BackendBufferConfig {
113            depth_test: true,
114            sample_count: 1,
115        }
116    }
117}
118
119impl Default for RenderTextureConfig {
120    #[inline(always)]
121    fn default() -> RenderTextureConfig {
122        RenderTextureConfig {
123            canvas_size: (1024, 768),
124            format: TextureFormat::Rgba8Unorm,
125        }
126    }
127}
128
129impl RenderTextureConfig {
130    /// Returns compatible `SurfaceConfiguration`.
131    #[inline(always)]
132    pub fn compatible_surface_config(self) -> SurfaceConfiguration {
133        SurfaceConfiguration {
134            usage: TextureUsages::RENDER_ATTACHMENT,
135            format: self.format,
136            width: self.canvas_size.0,
137            height: self.canvas_size.1,
138            alpha_mode: CompositeAlphaMode::Auto,
139            present_mode: PresentMode::Fifo,
140            view_formats: Vec::new(),
141            desired_maximum_frame_latency: 2,
142        }
143    }
144}
145
146impl SceneDescriptor {
147    /// Creates a `UNIFORM` buffer of camera.
148    ///
149    /// The bind group provides [`Scene`] holds this uniform buffer.
150    ///
151    /// # Shader Example
152    /// ```glsl
153    /// layout(set = 0, binding = 0) uniform Camera {
154    ///     mat4 camera_matrix;     // the camera matrix
155    ///     mat4 camera_projection; // the projection into the normalized view volume
156    /// };
157    /// ```
158    #[inline(always)]
159    pub fn camera_buffer(&self, device: &Device) -> BufferHandler {
160        let (width, height) = self.render_texture.canvas_size;
161        let as_rat = width as f64 / height as f64;
162        self.studio.camera.buffer(as_rat, device)
163    }
164
165    /// Creates a `STORAGE` buffer of all lights.
166    ///
167    /// The bind group provides [`Scene`] holds this uniform buffer.
168    ///
169    /// # Shader Example
170    /// ```glsl
171    /// struct Light {
172    ///     vec4 position;      // the position of light, position.w == 1.0
173    ///     vec4 color;         // the color of light, color.w == 1.0
174    ///     uvec4 light_type;   // Point => uvec4(0, 0, 0, 0), Uniform => uvec4(1, 0, 0, 0)
175    /// };
176    ///
177    /// layout(set = 0, binding = 1) buffer Lights {
178    ///     Light lights[];
179    /// };
180    /// ```
181    #[inline(always)]
182    pub fn lights_buffer(&self, device: &Device) -> BufferHandler {
183        let mut light_vec: Vec<_> = self.studio.lights.iter().map(Light::light_info).collect();
184        light_vec.resize(LIGHT_MAX, LightInfo::zeroed());
185        BufferHandler::from_slice(&light_vec, device, BufferUsages::UNIFORM)
186    }
187
188    #[inline(always)]
189    fn sampling_buffer(
190        device: &Device,
191        render_texture: RenderTextureConfig,
192        sample_count: u32,
193    ) -> Texture {
194        device.create_texture(&TextureDescriptor {
195            size: Extent3d {
196                width: render_texture.canvas_size.0,
197                height: render_texture.canvas_size.1,
198                depth_or_array_layers: 1,
199            },
200            mip_level_count: 1,
201            sample_count,
202            dimension: TextureDimension::D2,
203            format: render_texture.format,
204            usage: TextureUsages::RENDER_ATTACHMENT,
205            view_formats: &[],
206            label: None,
207        })
208    }
209
210    #[inline(always)]
211    fn depth_texture(device: &Device, size: (u32, u32), sample_count: u32) -> Texture {
212        device.create_texture(&TextureDescriptor {
213            size: Extent3d {
214                width: size.0,
215                height: size.1,
216                depth_or_array_layers: 1,
217            },
218            mip_level_count: 1,
219            sample_count,
220            dimension: TextureDimension::D2,
221            format: TextureFormat::Depth32Float,
222            usage: TextureUsages::RENDER_ATTACHMENT,
223            view_formats: &[],
224            label: None,
225        })
226    }
227
228    fn backend_buffers(&self, device: &Device) -> (Option<Texture>, Option<Texture>) {
229        let foward_depth = if self.backend_buffer.depth_test {
230            Some(Self::depth_texture(
231                device,
232                self.render_texture.canvas_size,
233                self.backend_buffer.sample_count,
234            ))
235        } else {
236            None
237        };
238        let sampling_buffer = if self.backend_buffer.sample_count > 1 {
239            Some(Self::sampling_buffer(
240                device,
241                self.render_texture,
242                self.backend_buffer.sample_count,
243            ))
244        } else {
245            None
246        };
247        (foward_depth, sampling_buffer)
248    }
249}
250
251/// Mutable reference of `SceneDescriptor` in `Scene`.
252///
253/// When this struct is dropped, the backend buffers of scene will be updated.
254#[derive(Debug)]
255pub struct SceneDescriptorMut<'a>(&'a mut Scene);
256
257impl<'a> std::ops::Deref for SceneDescriptorMut<'a> {
258    type Target = SceneDescriptor;
259    #[inline(always)]
260    fn deref(&self) -> &SceneDescriptor { &self.0.scene_desc }
261}
262
263impl<'a> std::ops::DerefMut for SceneDescriptorMut<'a> {
264    #[inline(always)]
265    fn deref_mut(&mut self) -> &mut SceneDescriptor { &mut self.0.scene_desc }
266}
267
268impl<'a> Drop for SceneDescriptorMut<'a> {
269    fn drop(&mut self) {
270        let (forward_depth, sampling_buffer) = self.backend_buffers(self.0.device());
271        self.0.foward_depth = forward_depth;
272        self.0.sampling_buffer = sampling_buffer;
273    }
274}
275
276impl Scene {
277    #[inline(always)]
278    fn camera_bgl_entry() -> PreBindGroupLayoutEntry {
279        PreBindGroupLayoutEntry {
280            visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
281            ty: BindingType::Buffer {
282                ty: BufferBindingType::Uniform,
283                has_dynamic_offset: false,
284                min_binding_size: None,
285            },
286            count: None,
287        }
288    }
289
290    #[inline(always)]
291    fn lights_bgl_entry() -> PreBindGroupLayoutEntry {
292        PreBindGroupLayoutEntry {
293            visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
294            ty: BindingType::Buffer {
295                ty: BufferBindingType::Uniform,
296                has_dynamic_offset: false,
297                min_binding_size: None,
298            },
299            count: None,
300        }
301    }
302
303    #[inline(always)]
304    fn scene_bgl_entry() -> PreBindGroupLayoutEntry {
305        PreBindGroupLayoutEntry {
306            visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
307            ty: BindingType::Buffer {
308                ty: BufferBindingType::Uniform,
309                has_dynamic_offset: false,
310                min_binding_size: None,
311            },
312            count: None,
313        }
314    }
315
316    #[inline(always)]
317    fn init_scene_bind_group_layout(device: &Device) -> BindGroupLayout {
318        bind_group_util::create_bind_group_layout(
319            device,
320            &[
321                Self::camera_bgl_entry(),
322                Self::lights_bgl_entry(),
323                Self::scene_bgl_entry(),
324            ],
325        )
326    }
327
328    /// constructor
329    // About `scene_desc`, entity is better than reference for the performance.
330    // This is reference because only for as wgpu is.
331    #[inline(always)]
332    pub fn new(device_handler: DeviceHandler, scene_desc: &SceneDescriptor) -> Scene {
333        let device = device_handler.device();
334        let (foward_depth, sampling_buffer) = scene_desc.backend_buffers(device);
335        let bind_group_layout = Self::init_scene_bind_group_layout(device);
336        Scene {
337            objects: Default::default(),
338            bind_group_layout,
339            foward_depth,
340            sampling_buffer,
341            clock: TimeInstant::now(),
342            scene_desc: scene_desc.clone(),
343            device_handler,
344        }
345    }
346
347    /// Construct scene from default GPU device.
348    /// # Arguments
349    /// - `size`: (width, height)
350    pub async fn from_default_device(scene_desc: &SceneDescriptor) -> Scene {
351        Scene::new(DeviceHandler::default_device().await, scene_desc)
352    }
353
354    /// Creates compatible texture for render attachment.
355    ///
356    /// # Remarks
357    /// The usage of texture is `TextureUsages::RENDER_ATTACHMENT | TetureUsages::COPY_SRC`.
358    #[inline(always)]
359    pub fn compatible_texture(&self) -> Texture {
360        let config = self.scene_desc.render_texture;
361        self.device().create_texture(&TextureDescriptor {
362            label: None,
363            size: Extent3d {
364                width: config.canvas_size.0,
365                height: config.canvas_size.1,
366                depth_or_array_layers: 1,
367            },
368            mip_level_count: 1,
369            sample_count: 1,
370            dimension: TextureDimension::D2,
371            format: config.format,
372            view_formats: &[],
373            usage: TextureUsages::RENDER_ATTACHMENT | TextureUsages::COPY_SRC,
374        })
375    }
376
377    /// Returns the reference of its own `DeviceHandler`.
378    #[inline(always)]
379    pub const fn device_handler(&self) -> &DeviceHandler { &self.device_handler }
380
381    /// Returns the reference of the device.
382    #[inline(always)]
383    pub const fn device(&self) -> &Arc<Device> { &self.device_handler.device }
384
385    /// Returns the reference of the queue.
386    #[inline(always)]
387    pub const fn queue(&self) -> &Arc<Queue> { &self.device_handler.queue }
388
389    /// Returns the elapsed time since the scene was created.
390    #[inline(always)]
391    pub fn elapsed(&self) -> std::time::Duration { self.clock.elapsed() }
392
393    /// Returns the reference of the descriptor.
394    #[inline(always)]
395    pub const fn descriptor(&self) -> &SceneDescriptor { &self.scene_desc }
396
397    /// Returns the mutable reference of the descriptor.
398    ///
399    /// # Remarks
400    ///
401    /// When the return value is dropped, the depth buffer and sampling buffer are automatically updated.
402    /// Use `studio_config_mut` if you only want to update the colors of the camera, lights, and background.
403    #[inline(always)]
404    pub fn descriptor_mut(&mut self) -> SceneDescriptorMut<'_> { SceneDescriptorMut(self) }
405
406    /// Returns the reference of the studio configuration.
407    #[inline(always)]
408    pub const fn studio_config(&self) -> &StudioConfig { &self.scene_desc.studio }
409
410    /// Returns the mutable reference of the studio configuration.
411    #[inline(always)]
412    pub fn studio_config_mut(&mut self) -> &mut StudioConfig { &mut self.scene_desc.studio }
413
414    /// Returns the bind group layout in the scene.
415    #[inline(always)]
416    pub const fn bind_group_layout(&self) -> &BindGroupLayout { &self.bind_group_layout }
417
418    /// Creates a `UNIFORM` buffer of the camera.
419    ///
420    /// The bind group provides [`Scene`] holds this uniform buffer.
421    ///
422    /// # Shader Example
423    /// ```glsl
424    /// layout(set = 0, binding = 0) uniform Camera {
425    ///     mat4 camera_matrix;     // the camera matrix
426    ///     mat4 camera_projection; // the projection into the normalized view volume
427    /// };
428    /// ```
429    #[inline(always)]
430    pub fn camera_buffer(&self) -> BufferHandler { self.scene_desc.camera_buffer(self.device()) }
431
432    /// Creates a `STORAGE` buffer of all lights.
433    ///
434    /// The bind group provides [`Scene`] holds this uniform buffer.
435    ///
436    /// # Shader Example
437    /// ```glsl
438    /// struct Light {
439    ///     vec4 position;      // the position of light, position.w == 1.0
440    ///     vec4 color;         // the color of light, color.w == 1.0
441    ///     uvec4 light_type;   // Point => uvec4(0, 0, 0, 0), Uniform => uvec4(1, 0, 0, 0)
442    /// };
443    ///
444    /// layout(set = 0, binding = 1) buffer Lights {
445    ///     Light lights[]; // the number of lights must be gotten from another place
446    /// };
447    /// ```
448    #[inline(always)]
449    pub fn lights_buffer(&self) -> BufferHandler { self.scene_desc.lights_buffer(self.device()) }
450
451    /// Creates a `UNIFORM` buffer of the scene status.
452    ///
453    /// The bind group provides [`Scene`] holds this uniform buffer.
454    ///
455    /// # Shader Example
456    /// ```glsl
457    /// layout(set = 0, binding = 2) uniform Scene {
458    ///     vec4 bk_color;  // color of back ground
459    ///     float time;     // elapsed time since the scene was created.
460    ///     uint nlights;   // the number of lights
461    /// };
462    /// ```
463    #[inline(always)]
464    pub fn scene_status_buffer(&self) -> BufferHandler {
465        let bk = self.scene_desc.studio.background;
466        let size = self.scene_desc.render_texture.canvas_size;
467        let scene_info = SceneInfo {
468            background_color: [bk.r as f32, bk.g as f32, bk.b as f32, bk.a as f32],
469            resolution: [size.0, size.1],
470            time: self.elapsed().as_secs_f32(),
471            num_of_lights: self.scene_desc.studio.lights.len() as u32,
472        };
473        BufferHandler::from_slice(&[scene_info], self.device(), BufferUsages::UNIFORM)
474    }
475
476    /// Creates bind group.
477    /// # Shader Examples
478    /// Suppose binded as `set = 0`.
479    /// ```glsl
480    /// layout(set = 0, binding = 0) uniform Camera {
481    ///     mat4 camera_matrix;     // the camera matrix
482    ///     mat4 camera_projection; // the projection into the normalized view volume
483    /// };
484    ///
485    /// struct Light {
486    ///     vec4 position;      // the position of light, position.w == 1.0
487    ///     vec4 color;         // the color of light, color.w == 1.0
488    ///     uvec4 light_type;   // Point => uvec4(0, 0, 0, 0), Uniform => uvec4(1, 0, 0, 0)
489    /// };
490    ///
491    /// layout(set = 0, binding = 1) buffer Lights {
492    ///     Light lights[];
493    /// };
494    ///
495    /// layout(set = 0, binding = 2) uniform Scene {
496    ///     float time;     // elapsed time since the scene was created.
497    ///     uint nlights;   // the number of lights
498    /// };
499    /// ```
500    #[inline(always)]
501    pub fn scene_bind_group(&self) -> BindGroup {
502        bind_group_util::create_bind_group(
503            self.device(),
504            &self.bind_group_layout,
505            vec![
506                self.camera_buffer().binding_resource(),
507                self.lights_buffer().binding_resource(),
508                self.scene_status_buffer().binding_resource(),
509            ],
510        )
511    }
512
513    /// Adds a render object to the scene.
514    ///
515    /// If there already exists a render object with the same ID,
516    /// replaces the render object and returns false.
517    #[inline(always)]
518    pub fn add_object<R: Rendered>(&mut self, object: &R) -> bool {
519        let render_object = object.render_object(self);
520        self.objects
521            .insert(object.render_id(), render_object)
522            .is_none()
523    }
524    /// Sets the visibility of a render object.
525    ///
526    /// If there does not exist the render object in the scene, does nothing and returns `false`.
527    #[inline(always)]
528    pub fn set_visibility<R: Rendered>(&mut self, object: &R, visible: bool) -> bool {
529        self.objects
530            .get_mut(&object.render_id())
531            .map(|obj| obj.visible = visible)
532            .is_some()
533    }
534    /// Adds render objects to the scene.
535    ///
536    /// If there already exists a render object with the same ID,
537    /// replaces the render object and returns false.
538    #[inline(always)]
539    pub fn add_objects<'a, R, I>(&mut self, objects: I) -> bool
540    where
541        R: 'a + Rendered,
542        I: IntoIterator<Item = &'a R>, {
543        let closure = move |flag, object| flag && self.add_object(object);
544        objects.into_iter().fold(true, closure)
545    }
546    /// Removes a render object from the scene.
547    ///
548    /// If there does not exist the render object in the scene, does nothing and returns `false`.
549    #[inline(always)]
550    pub fn remove_object<R: Rendered>(&mut self, object: &R) -> bool {
551        self.objects.remove(&object.render_id()).is_some()
552    }
553    /// Removes render objects from the scene.
554    ///
555    /// If there exists a render object which does not exist in the scene, returns `false`.
556    #[inline(always)]
557    pub fn remove_objects<'a, R, I>(&mut self, objects: I) -> bool
558    where
559        R: 'a + Rendered,
560        I: IntoIterator<Item = &'a R>, {
561        let closure = move |flag, object| flag && self.remove_object(object);
562        objects.into_iter().fold(true, closure)
563    }
564
565    /// Removes all render objects from the scene.
566    #[inline(always)]
567    pub fn clear_objects(&mut self) { self.objects.clear() }
568
569    /// Returns the number of the render objects in the scene.
570    #[inline(always)]
571    pub fn number_of_objects(&self) -> usize { self.objects.len() }
572
573    /// Synchronizes the information of vertices of `object` in the CPU memory
574    /// and that in the GPU memory.
575    ///
576    /// If there does not exist the render object in the scene, does nothing and returns false.
577    #[inline(always)]
578    pub fn update_vertex_buffer<R: Rendered>(&mut self, object: &R) -> bool {
579        let (handler, objects) = (&self.device_handler, &mut self.objects);
580        match objects.get_mut(&object.render_id()) {
581            None => false,
582            Some(render_object) => {
583                let (vb, ib) = object.vertex_buffer(handler);
584                render_object.vertex_buffer = vb;
585                render_object.index_buffer = ib;
586                true
587            }
588        }
589    }
590
591    /// Synchronizes the information of vertices of `objects` in the CPU memory
592    /// and that in the GPU memory.
593    ///
594    /// If there exists a render object which does not exist in the scene, returns false.
595    #[inline(always)]
596    pub fn update_vertex_buffers<'a, R, I>(&mut self, objects: I) -> bool
597    where
598        R: 'a + Rendered,
599        I: IntoIterator<Item = &'a R>, {
600        let closure = move |flag, object: &R| flag && self.update_vertex_buffer(object);
601        objects.into_iter().fold(true, closure)
602    }
603
604    /// Synchronizes the information of bind group of `object` in the CPU memory
605    /// and that in the GPU memory.
606    ///
607    /// If there does not exist the render object in the scene, does nothing and returns false.
608    #[inline(always)]
609    pub fn update_bind_group<R: Rendered>(&mut self, object: &R) -> bool {
610        let (handler, objects) = (&self.device_handler, &mut self.objects);
611        match objects.get_mut(&object.render_id()) {
612            Some(render_object) => {
613                let bind_group = object.bind_group(handler, &render_object.bind_group_layout);
614                render_object.bind_group = bind_group;
615                true
616            }
617            _ => false,
618        }
619    }
620    /// Synchronizes the information of bind group of `object` in the CPU memory
621    /// and that in the GPU memory.
622    ///
623    /// If there exists a render object which does not exist in the scene, returns false.
624    #[inline(always)]
625    pub fn update_bind_groups<'a, R, I>(&mut self, objects: I) -> bool
626    where
627        R: 'a + Rendered,
628        I: IntoIterator<Item = &'a R>, {
629        let closure = move |flag, object: &R| flag && self.update_bind_group(object);
630        objects.into_iter().fold(true, closure)
631    }
632    /// Synchronizes the information of pipeline of `object` in the CPU memory
633    /// and that in the GPU memory.
634    ///
635    /// If there does not exist the render object in the scene, does nothing and returns false.
636    #[inline(always)]
637    pub fn update_pipeline<R: Rendered>(&mut self, object: &R) -> bool {
638        let (handler, objects) = (&self.device_handler, &mut self.objects);
639        match objects.get_mut(&object.render_id()) {
640            Some(render_object) => {
641                let device = handler.device();
642                let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
643                    bind_group_layouts: &[
644                        &self.bind_group_layout,
645                        &render_object.bind_group_layout,
646                    ],
647                    push_constant_ranges: &[],
648                    label: None,
649                });
650                render_object.pipeline =
651                    object.pipeline(handler, &pipeline_layout, &self.scene_desc);
652                true
653            }
654            _ => false,
655        }
656    }
657    /// Synchronizes the information of pipeline of `object` in the CPU memory
658    /// and that in the GPU memory.
659    ///
660    /// If there exists a render object which does not exist in the scene, returns false.
661    #[inline(always)]
662    pub fn update_pipelines<'a, R, I>(&mut self, objects: I) -> bool
663    where
664        R: 'a + Rendered,
665        I: IntoIterator<Item = &'a R>, {
666        let closure = move |flag, object: &R| flag && self.update_pipeline(object);
667        objects.into_iter().fold(true, closure)
668    }
669    #[inline(always)]
670    fn depth_stencil_attachment_descriptor(
671        depth_view: &TextureView,
672    ) -> RenderPassDepthStencilAttachment<'_> {
673        RenderPassDepthStencilAttachment {
674            view: depth_view,
675            depth_ops: Some(Operations {
676                load: LoadOp::Clear(1.0),
677                store: StoreOp::Store,
678            }),
679            stencil_ops: None,
680        }
681    }
682
683    /// Renders the scene to `view`.
684    pub fn render(&self, view: &TextureView) {
685        let bind_group = self.scene_bind_group();
686        let depth_view = self
687            .foward_depth
688            .as_ref()
689            .map(|tex| tex.create_view(&Default::default()));
690        let sampled_view = self
691            .sampling_buffer
692            .as_ref()
693            .map(|tex| tex.create_view(&Default::default()));
694        let mut encoder = self
695            .device()
696            .create_command_encoder(&CommandEncoderDescriptor { label: None });
697        {
698            let (attachment, resolve_target) = match sampled_view.as_ref() {
699                Some(sampled_view) => (sampled_view, Some(view)),
700                None => (view, None),
701            };
702            let mut rpass = encoder.begin_render_pass(&RenderPassDescriptor {
703                color_attachments: &[Some(RenderPassColorAttachment {
704                    view: attachment,
705                    resolve_target,
706                    ops: Operations {
707                        load: LoadOp::Clear(self.scene_desc.studio.background),
708                        store: StoreOp::Store,
709                    },
710                })],
711                depth_stencil_attachment: depth_view
712                    .as_ref()
713                    .map(Self::depth_stencil_attachment_descriptor),
714                ..Default::default()
715            });
716            rpass.set_bind_group(0, &bind_group, &[]);
717            for (_, object) in &self.objects {
718                if !object.visible {
719                    continue;
720                }
721                rpass.set_pipeline(&object.pipeline);
722                rpass.set_bind_group(1, &object.bind_group, &[]);
723                rpass.set_vertex_buffer(0, object.vertex_buffer.buffer.slice(..));
724                match object.index_buffer {
725                    Some(ref index_buffer) => {
726                        rpass.set_index_buffer(index_buffer.buffer.slice(..), IndexFormat::Uint32);
727                        let index_size = index_buffer.size as u32 / size_of::<u32>() as u32;
728                        rpass.draw_indexed(0..index_size, 0, 0..1);
729                    }
730                    None => rpass.draw(
731                        0..(object.vertex_buffer.size / object.vertex_buffer.stride) as u32,
732                        0..1,
733                    ),
734                }
735            }
736        }
737        self.queue().submit(vec![encoder.finish()]);
738    }
739
740    /// Render image to buffer.
741    pub async fn render_to_buffer(&self) -> Vec<u8> {
742        let texture = self.compatible_texture();
743        let view = texture.create_view(&Default::default());
744        self.render(&view);
745        let (device, queue) = (self.device(), self.queue());
746
747        let (width, height) = self.scene_desc.render_texture.canvas_size;
748        let size = (width * height * 4) as u64;
749        let buffer = device.create_buffer(&BufferDescriptor {
750            label: None,
751            mapped_at_creation: false,
752            usage: BufferUsages::COPY_DST | BufferUsages::MAP_READ,
753            size,
754        });
755        let mut encoder = device.create_command_encoder(&CommandEncoderDescriptor { label: None });
756        encoder.copy_texture_to_buffer(
757            ImageCopyTexture {
758                texture: &texture,
759                mip_level: 0,
760                origin: Origin3d::ZERO,
761                aspect: TextureAspect::All,
762            },
763            ImageCopyBuffer {
764                buffer: &buffer,
765                layout: ImageDataLayout {
766                    offset: 0,
767                    bytes_per_row: Some(width * 4),
768                    rows_per_image: Some(height),
769                },
770            },
771            Extent3d {
772                width,
773                height,
774                depth_or_array_layers: 1,
775            },
776        );
777        queue.submit(Some(encoder.finish()));
778        let buffer_slice = buffer.slice(..);
779        let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel();
780        buffer_slice.map_async(MapMode::Read, move |v| sender.send(v).unwrap());
781        device.poll(Maintain::Wait);
782        match receiver.receive().await {
783            Some(Ok(_)) => buffer_slice.get_mapped_range().iter().copied().collect(),
784            Some(Err(e)) => panic!("{}", e),
785            None => panic!("Asynchronous processing fails"),
786        }
787    }
788}
789
790impl WindowScene {
791    /// Initialize scene compatible with `window`.
792    pub async fn from_window(window: Arc<Window>, scene_desc: &WindowSceneDescriptor) -> Self {
793        let size = window.inner_size();
794        let got = init_default_device(Some(window)).await;
795        let (device_handler, window_handler) = (got.0, got.1.unwrap());
796        let (device, surface) = (&device_handler.device, &window_handler.surface);
797        let render_texture = RenderTextureConfig {
798            canvas_size: size.into(),
799            format: TextureFormat::Bgra8Unorm,
800        };
801        let config = render_texture.compatible_surface_config();
802        surface.configure(device, &config);
803
804        Self {
805            scene: Scene::new(
806                device_handler,
807                &SceneDescriptor {
808                    studio: scene_desc.studio.clone(),
809                    backend_buffer: scene_desc.backend_buffer,
810                    render_texture,
811                },
812            ),
813            window_handler,
814        }
815    }
816    /// Get the reference of initializing window.
817    #[inline(always)]
818    pub const fn window(&self) -> &Arc<Window> { &self.window_handler.window }
819    /// Get the reference of surface.
820    #[inline(always)]
821    pub const fn surface(&self) -> &Arc<Surface<'_>> { &self.window_handler.surface }
822    /// Adjusts the size of the backend buffers (depth or sampling buffer) to the size of the window.
823    pub fn size_alignment(&mut self) {
824        let size = self.window().inner_size();
825        let canvas_size = self.scene.scene_desc.render_texture.canvas_size;
826        if canvas_size != (size.width, size.height) {
827            let mut desc = self.scene.descriptor_mut();
828            desc.render_texture.canvas_size = size.into();
829            let config = desc.render_texture.compatible_surface_config();
830            drop(desc);
831            self.surface().configure(self.device(), &config);
832        }
833    }
834    /// Render scene to initializing window.
835    pub fn render_frame(&mut self) {
836        self.size_alignment();
837        let surface = self.surface();
838        let surface_texture = match surface.get_current_texture() {
839            Ok(got) => got,
840            Err(_) => {
841                let config = self
842                    .scene
843                    .scene_desc
844                    .render_texture
845                    .compatible_surface_config();
846                surface.configure(self.device(), &config);
847                surface
848                    .get_current_texture()
849                    .expect("Failed to acquire next surface texture!")
850            }
851        };
852        let view = surface_texture
853            .texture
854            .create_view(&TextureViewDescriptor::default());
855        self.render(&view);
856        surface_texture.present();
857    }
858}