Skip to content

Commit d28354e

Browse files
committed
Finished textures and bind groups, now onto the challenge
1 parent 91cdaa3 commit d28354e

File tree

5 files changed

+99
-56
lines changed

5 files changed

+99
-56
lines changed

Cargo.lock

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ log = "0.4"
1515
wgpu = "0.9"
1616
pollster = "0.2"
1717
bytemuck = { version = "1.4", features = [ "derive" ] }
18+
anyhow = "1.0"

readme.md

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ I am following [sotrh's learn-wgpu tutorial](https://sotrh.github.io/learn-wgpu/
44
## Status
55
I am just about to start: [The results](https://sotrh.github.io/learn-wgpu/beginner/tutorial5-textures/#the-results).
66

7+
## Dependencies
8+
Dependency | Use
9+
--- | ---
10+
anyhow | Simplifies error handling.
11+
712
## Glossary
813
Word | Definition
914
--- | ---

src/main.rs

+7-56
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use winit::{
33
event_loop::{ControlFlow, EventLoop},
44
window::{Window, WindowBuilder},
55
};
6-
76
use wgpu::util::DeviceExt;
7+
mod texture;
8+
89

910
fn main() {
1011
env_logger::init();
@@ -115,6 +116,7 @@ struct State {
115116
index_buffer: wgpu::Buffer,
116117
num_indices: u32,
117118
diffuse_bind_group: wgpu::BindGroup,
119+
diffuse_texture: texture::Texture,
118120
}
119121

120122
impl State {
@@ -153,60 +155,8 @@ impl State {
153155
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
154156

155157
let diffuse_bytes = include_bytes!("happy-tree.png");
156-
let diffuse_image = image::load_from_memory(diffuse_bytes).unwrap();
157-
let diffuse_rgba = diffuse_image.as_rgba8().unwrap();
158-
159-
use image::GenericImageView;
160-
let dimensions = diffuse_image.dimensions();
161-
162-
let texture_size = wgpu::Extent3d {
163-
width: dimensions.0,
164-
height: dimensions.1,
165-
depth_or_array_layers: 1,
166-
};
167-
168-
let diffuse_texture = device.create_texture(
169-
&wgpu::TextureDescriptor {
170-
size: texture_size,
171-
mip_level_count: 1,
172-
sample_count: 1,
173-
dimension: wgpu::TextureDimension::D2,
174-
format: wgpu::TextureFormat::Rgba8UnormSrgb,
175-
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
176-
label: Some("diffuse_texture"),
177-
}
178-
);
179158

180-
queue.write_texture(
181-
wgpu::ImageCopyTexture {
182-
texture: &diffuse_texture,
183-
mip_level: 0,
184-
origin: wgpu::Origin3d::ZERO,
185-
},
186-
&diffuse_rgba,
187-
wgpu::ImageDataLayout {
188-
offset: 0,
189-
bytes_per_row: std::num::NonZeroU32::new(4 * dimensions.0),
190-
rows_per_image: std::num::NonZeroU32::new(dimensions.1),
191-
},
192-
texture_size,
193-
);
194-
195-
let diffuse_texture_view = diffuse_texture.create_view(
196-
&wgpu::TextureViewDescriptor::default()
197-
);
198-
199-
let diffuse_sampler = device.create_sampler(
200-
&wgpu::SamplerDescriptor {
201-
address_mode_u: wgpu::AddressMode::ClampToEdge,
202-
address_mode_v: wgpu::AddressMode::ClampToEdge,
203-
address_mode_w: wgpu::AddressMode::ClampToEdge,
204-
mag_filter: wgpu::FilterMode::Linear,
205-
min_filter: wgpu::FilterMode::Nearest,
206-
mipmap_filter: wgpu::FilterMode::Nearest,
207-
..Default::default()
208-
}
209-
);
159+
let diffuse_texture = texture::Texture::from_bytes(&device, &queue, diffuse_bytes, "happy-tree.png").unwrap();
210160

211161
let texture_bind_group_layout = device.create_bind_group_layout(
212162
&wgpu::BindGroupLayoutDescriptor {
@@ -245,11 +195,11 @@ impl State {
245195
entries: &[
246196
wgpu::BindGroupEntry {
247197
binding: 0,
248-
resource: wgpu::BindingResource::TextureView(&diffuse_texture_view),
198+
resource: wgpu::BindingResource::TextureView(&diffuse_texture.view),
249199
},
250200
wgpu::BindGroupEntry {
251201
binding: 1,
252-
resource: wgpu::BindingResource::Sampler(&diffuse_sampler),
202+
resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler),
253203
}
254204
],
255205
label: Some("diffuse_bind_group"),
@@ -337,6 +287,7 @@ impl State {
337287
index_buffer,
338288
num_indices,
339289
diffuse_bind_group,
290+
diffuse_texture,
340291
}
341292
}
342293

src/texture.rs

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use image::GenericImageView;
2+
use anyhow::*;
3+
4+
pub struct Texture {
5+
pub texture: wgpu::Texture,
6+
pub view: wgpu::TextureView,
7+
pub sampler: wgpu::Sampler,
8+
}
9+
10+
impl Texture {
11+
pub fn from_bytes (
12+
device: &wgpu::Device,
13+
queue: &wgpu::Queue,
14+
bytes: &[u8],
15+
label: &str
16+
) -> Result<Self> {
17+
let img = image::load_from_memory(bytes)?;
18+
Self::from_image(device, queue, &img, Some(label))
19+
}
20+
21+
pub fn from_image(
22+
device: &wgpu::Device,
23+
queue: &wgpu::Queue,
24+
img: &image::DynamicImage,
25+
label: Option<&str>,
26+
) -> Result<Self> {
27+
let rgba = img.as_rgba8().unwrap();
28+
let dimensions = img.dimensions();
29+
30+
let size = wgpu::Extent3d {
31+
width: dimensions.0,
32+
height: dimensions.1,
33+
depth_or_array_layers: 1,
34+
};
35+
36+
let texture = device.create_texture(
37+
&wgpu::TextureDescriptor {
38+
label,
39+
size,
40+
mip_level_count: 1,
41+
sample_count: 1,
42+
dimension: wgpu::TextureDimension::D2,
43+
format: wgpu::TextureFormat::Rgba8UnormSrgb,
44+
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
45+
}
46+
);
47+
48+
queue.write_texture(
49+
wgpu::ImageCopyTexture {
50+
texture: &texture,
51+
mip_level: 0,
52+
origin: wgpu::Origin3d::ZERO
53+
},
54+
rgba,
55+
wgpu::ImageDataLayout {
56+
offset: 0,
57+
bytes_per_row: std::num::NonZeroU32::new(4 * dimensions.0),
58+
rows_per_image: std::num::NonZeroU32::new(dimensions.1),
59+
},
60+
size,
61+
);
62+
63+
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
64+
65+
let sampler = device.create_sampler(
66+
&wgpu::SamplerDescriptor {
67+
address_mode_u: wgpu::AddressMode::ClampToEdge,
68+
address_mode_v: wgpu::AddressMode::ClampToEdge,
69+
address_mode_w: wgpu::AddressMode::ClampToEdge,
70+
mag_filter: wgpu::FilterMode::Linear,
71+
min_filter: wgpu::FilterMode::Nearest,
72+
mipmap_filter: wgpu::FilterMode::Nearest,
73+
..Default::default()
74+
}
75+
);
76+
77+
Ok(Self { texture, view, sampler })
78+
}
79+
}

0 commit comments

Comments
 (0)