cuneus/
texture.rs

1pub struct TextureManager {
2    pub texture: wgpu::Texture,
3    pub view: wgpu::TextureView,
4    pub sampler: wgpu::Sampler,
5    pub bind_group: wgpu::BindGroup,
6}
7impl TextureManager {
8    pub fn new(
9        device: &wgpu::Device,
10        queue: &wgpu::Queue,
11        image: &image::RgbaImage,
12        layout: &wgpu::BindGroupLayout,
13    ) -> Self {
14        let dimensions = image.dimensions();
15        
16        let texture = device.create_texture(&wgpu::TextureDescriptor {
17            label: Some("Shader Texture"),
18            size: wgpu::Extent3d {
19                width: dimensions.0,
20                height: dimensions.1,
21                depth_or_array_layers: 1,
22            },
23            mip_level_count: 1,
24            sample_count: 1,
25            dimension: wgpu::TextureDimension::D2,
26            format: wgpu::TextureFormat::Rgba8UnormSrgb,
27            usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
28            view_formats: &[],
29        });
30
31        let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
32        
33        let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
34            address_mode_u: wgpu::AddressMode::ClampToEdge,
35            address_mode_v: wgpu::AddressMode::ClampToEdge,
36            address_mode_w: wgpu::AddressMode::ClampToEdge,
37            mag_filter: wgpu::FilterMode::Linear,
38            min_filter: wgpu::FilterMode::Linear,
39            mipmap_filter: wgpu::FilterMode::Linear,
40            ..Default::default()
41        });
42
43        let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
44            layout,
45            entries: &[
46                wgpu::BindGroupEntry {
47                    binding: 0,
48                    resource: wgpu::BindingResource::TextureView(&view),
49                },
50                wgpu::BindGroupEntry {
51                    binding: 1,
52                    resource: wgpu::BindingResource::Sampler(&sampler),
53                },
54            ],
55            label: Some("Texture Bind Group"),
56        });
57        queue.write_texture(
58            wgpu::TexelCopyTextureInfo {
59                texture: &texture,
60                mip_level: 0,
61                origin: wgpu::Origin3d::ZERO,
62                aspect: wgpu::TextureAspect::All,
63            },
64            image,
65            wgpu::TexelCopyBufferLayout {
66                offset: 0,
67                bytes_per_row: Some(4 * dimensions.0),
68                rows_per_image: Some(dimensions.1),
69            },
70            wgpu::Extent3d {
71                width: dimensions.0,
72                height: dimensions.1,
73                depth_or_array_layers: 1,
74            },
75        );
76
77        Self {
78            texture,
79            view,
80            sampler,
81            bind_group,
82        }
83    }
84    pub fn update(&self, queue: &wgpu::Queue, image: &image::RgbaImage) {
85        let dimensions = image.dimensions();
86        queue.write_texture(
87            wgpu::TexelCopyTextureInfo {
88                texture: &self.texture,
89                mip_level: 0,
90                origin: wgpu::Origin3d::ZERO,
91                aspect: wgpu::TextureAspect::All,
92            },
93            image,
94            wgpu::TexelCopyBufferLayout {
95                offset: 0,
96                bytes_per_row: Some(4 * dimensions.0),
97                rows_per_image: Some(dimensions.1),
98            },
99            wgpu::Extent3d {
100                width: dimensions.0,
101                height: dimensions.1,
102                depth_or_array_layers: 1,
103            },
104        );
105    }
106}