effect_wgpu/texture/
texture2d.rs

1use effect_core::id::TextureID;
2use image::ImageBuffer;
3use image::Rgba;
4
5#[derive(Clone, Debug)]
6pub struct WebTexture2D {
7    pub id: TextureID,
8    pub path: &'static str,
9    pub width: u32,
10    pub height: u32,
11    pub index: Option<[u32; 2]>,
12}
13
14impl WebTexture2D {
15    pub fn new(id: TextureID, path: &'static str) -> Self {
16        Self {
17            id,
18            path,
19            width: 0,
20            height: 0,
21            index: None,
22        }
23    }
24
25    pub fn file_path(&self) -> &str {
26        self.path
27    }
28
29    pub fn id(&self) -> &TextureID {
30        &self.id
31    }
32
33    pub fn index(&self) -> Option<[u32; 2]> {
34        self.index
35    }
36
37    pub fn width(&self) -> u32 {
38        self.width
39    }
40
41    pub fn height(&self) -> u32 {
42        self.height
43    }
44}
45
46pub struct WebTexture2DSystem;
47impl WebTexture2DSystem {
48    pub fn set_index(texture: &mut WebTexture2D, index: [u32; 2]) {
49        texture.index = Some(index);
50    }
51
52    pub fn set_dimensions(texture: &mut WebTexture2D, width: u32, height: u32) {
53        texture.width = width;
54        texture.height = height;
55    }
56
57    pub fn init_texture(
58        extent: wgpu::Extent3d,
59        rgba_image: ImageBuffer<Rgba<u8>, Vec<u8>>,
60        bind_group_layout: &wgpu::BindGroupLayout,
61        pixel_art: bool,
62        device: &wgpu::Device,
63        queue: &wgpu::Queue,
64    ) -> wgpu::BindGroup {
65        let texture = device.create_texture(&wgpu::TextureDescriptor {
66            label: Some("texture"),
67            size: extent,
68            dimension: wgpu::TextureDimension::D2,
69            format: wgpu::TextureFormat::Rgba8UnormSrgb,
70            usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
71            mip_level_count: 1,
72            sample_count: 1,
73            view_formats: &[],
74        });
75
76        queue.write_texture(
77            wgpu::ImageCopyTexture {
78                texture: &texture,
79                mip_level: 0,
80                origin: wgpu::Origin3d::ZERO,
81                aspect: wgpu::TextureAspect::All,
82            },
83            &rgba_image,
84            wgpu::ImageDataLayout {
85                offset: 0,
86                bytes_per_row: Some(extent.width * std::mem::size_of::<u32>() as u32),
87                rows_per_image: Some(extent.height),
88            },
89            extent,
90        );
91
92        let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
93        let mag_filter;
94        if pixel_art {
95            mag_filter = wgpu::FilterMode::Nearest;
96        } else {
97            mag_filter = wgpu::FilterMode::Linear
98        }
99        let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
100            address_mode_u: wgpu::AddressMode::ClampToEdge,
101            address_mode_v: wgpu::AddressMode::ClampToEdge,
102            address_mode_w: wgpu::AddressMode::ClampToEdge,
103            mag_filter,
104            min_filter: wgpu::FilterMode::Nearest,
105            mipmap_filter: wgpu::FilterMode::Nearest,
106            ..Default::default()
107        });
108
109        let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
110            label: Some("bind group"),
111            layout: bind_group_layout,
112            entries: &[
113                wgpu::BindGroupEntry {
114                    binding: 0,
115                    resource: wgpu::BindingResource::TextureView(&view),
116                },
117                wgpu::BindGroupEntry {
118                    binding: 1,
119                    resource: wgpu::BindingResource::Sampler(&sampler),
120                },
121            ],
122        });
123
124        bind_group
125    }
126}