tutorial5-textures done
This commit is contained in:
parent
edb71eb9aa
commit
fad62b21e7
6 changed files with 286 additions and 28 deletions
95
Cargo.lock
generated
95
Cargo.lock
generated
|
@ -1,5 +1,20 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler32"
|
name = "adler32"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -62,6 +77,20 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide 0.4.1",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -371,6 +400,28 @@ version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
|
checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "failure"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"failure_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "failure_derive"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.21",
|
||||||
|
"quote 1.0.7",
|
||||||
|
"syn",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foreign-types"
|
name = "foreign-types"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
|
@ -658,6 +709,12 @@ dependencies = [
|
||||||
"lzw",
|
"lzw",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
|
@ -892,6 +949,15 @@ dependencies = [
|
||||||
"adler32",
|
"adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4d7559a8a40d0f97e1edea3220f698f78b1c5ab67532e49f68fde3910323b722"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.22"
|
version = "0.6.22"
|
||||||
|
@ -1096,6 +1162,12 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.4.1"
|
version = "1.4.1"
|
||||||
|
@ -1208,7 +1280,7 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"deflate",
|
"deflate",
|
||||||
"miniz_oxide",
|
"miniz_oxide 0.3.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1314,6 +1386,12 @@ version = "0.1.57"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusttype"
|
name = "rusttype"
|
||||||
version = "0.7.9"
|
version = "0.7.9"
|
||||||
|
@ -1459,6 +1537,18 @@ dependencies = [
|
||||||
"unicode-xid 0.2.1",
|
"unicode-xid 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "synstructure"
|
||||||
|
version = "0.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.21",
|
||||||
|
"quote 1.0.7",
|
||||||
|
"syn",
|
||||||
|
"unicode-xid 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
|
@ -1487,7 +1577,7 @@ checksum = "3f3b8a87c4da944c3f27e5943289171ac71a6150a79ff6bacfff06d159dfff2f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"lzw",
|
"lzw",
|
||||||
"miniz_oxide",
|
"miniz_oxide 0.3.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1744,6 +1834,7 @@ name = "wgpu-tutorial"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
|
"failure",
|
||||||
"futures",
|
"futures",
|
||||||
"image",
|
"image",
|
||||||
"shaderc",
|
"shaderc",
|
||||||
|
|
|
@ -13,3 +13,4 @@ image = "0.23.9"
|
||||||
futures = "0.3.5"
|
futures = "0.3.5"
|
||||||
shaderc = "0.6.2"
|
shaderc = "0.6.2"
|
||||||
bytemuck = "1.4.1"
|
bytemuck = "1.4.1"
|
||||||
|
failure = "0.1.8"
|
||||||
|
|
106
src/main.rs
106
src/main.rs
|
@ -5,6 +5,8 @@ use winit::{
|
||||||
window::{Window, WindowBuilder},
|
window::{Window, WindowBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod texture;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = WindowBuilder::new()
|
let window = WindowBuilder::new()
|
||||||
|
@ -60,6 +62,9 @@ struct State {
|
||||||
sc_desc: wgpu::SwapChainDescriptor,
|
sc_desc: wgpu::SwapChainDescriptor,
|
||||||
swap_chain: wgpu::SwapChain,
|
swap_chain: wgpu::SwapChain,
|
||||||
|
|
||||||
|
diffuse_texture: texture::Texture,
|
||||||
|
diffuse_bind_group: wgpu::BindGroup,
|
||||||
|
|
||||||
vertex_buffer: wgpu::Buffer,
|
vertex_buffer: wgpu::Buffer,
|
||||||
index_buffer: wgpu::Buffer,
|
index_buffer: wgpu::Buffer,
|
||||||
num_indices: u32,
|
num_indices: u32,
|
||||||
|
@ -106,6 +111,51 @@ impl State {
|
||||||
|
|
||||||
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
|
||||||
|
|
||||||
|
// Load image
|
||||||
|
let diffuse_bytes = include_bytes!("snubben.png");
|
||||||
|
let (diffuse_texture, command) =
|
||||||
|
texture::Texture::from_bytes(&device, diffuse_bytes, "diffuse_texture").unwrap();
|
||||||
|
queue.submit(Some(command));
|
||||||
|
|
||||||
|
let texture_bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: Some("texture_bind_group_layout"),
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::SampledTexture {
|
||||||
|
dimension: wgpu::TextureViewDimension::D2,
|
||||||
|
component_type: wgpu::TextureComponentType::Uint,
|
||||||
|
multisampled: false,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 1,
|
||||||
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||||
|
count: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
let diffuse_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: Some("diffuse_bind_group"),
|
||||||
|
layout: &texture_bind_group_layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&diffuse_texture.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Compile & load shaders
|
||||||
let vs_src = include_str!("shader.vert");
|
let vs_src = include_str!("shader.vert");
|
||||||
let fs_src = include_str!("shader.frag");
|
let fs_src = include_str!("shader.frag");
|
||||||
|
|
||||||
|
@ -135,28 +185,30 @@ impl State {
|
||||||
let vs_module = device.create_shader_module(vs_data);
|
let vs_module = device.create_shader_module(vs_data);
|
||||||
let fs_module = device.create_shader_module(fs_data);
|
let fs_module = device.create_shader_module(fs_data);
|
||||||
|
|
||||||
|
// Setup buffers
|
||||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Vertex buffer"),
|
label: Some("vertex_buffer"),
|
||||||
contents: bytemuck::cast_slice(&VERTICES),
|
contents: bytemuck::cast_slice(&VERTICES),
|
||||||
usage: wgpu::BufferUsage::VERTEX,
|
usage: wgpu::BufferUsage::VERTEX,
|
||||||
});
|
});
|
||||||
|
|
||||||
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Index buffer"),
|
label: Some("index_buffer"),
|
||||||
contents: bytemuck::cast_slice(&INDICES),
|
contents: bytemuck::cast_slice(&INDICES),
|
||||||
usage: wgpu::BufferUsage::INDEX,
|
usage: wgpu::BufferUsage::INDEX,
|
||||||
});
|
});
|
||||||
let num_indices = INDICES.len() as u32;
|
let num_indices = INDICES.len() as u32;
|
||||||
|
|
||||||
|
// Setup render pipeline
|
||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("Render pipeline layout"),
|
label: Some("render_pipeline_layout"),
|
||||||
bind_group_layouts: &[],
|
bind_group_layouts: &[&texture_bind_group_layout],
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
|
||||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
label: Some("Render pipeline"),
|
label: Some("render_pipeline"),
|
||||||
layout: Some(&render_pipeline_layout),
|
layout: Some(&render_pipeline_layout),
|
||||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||||
module: &vs_module,
|
module: &vs_module,
|
||||||
|
@ -184,9 +236,7 @@ impl State {
|
||||||
depth_stencil_state: None, // TODO
|
depth_stencil_state: None, // TODO
|
||||||
vertex_state: wgpu::VertexStateDescriptor {
|
vertex_state: wgpu::VertexStateDescriptor {
|
||||||
index_format: wgpu::IndexFormat::Uint16,
|
index_format: wgpu::IndexFormat::Uint16,
|
||||||
vertex_buffers: &[
|
vertex_buffers: &[Vertex::desc()],
|
||||||
Vertex::desc(),
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
sample_mask: !0,
|
sample_mask: !0,
|
||||||
|
@ -201,6 +251,8 @@ impl State {
|
||||||
queue,
|
queue,
|
||||||
sc_desc,
|
sc_desc,
|
||||||
swap_chain,
|
swap_chain,
|
||||||
|
diffuse_texture,
|
||||||
|
diffuse_bind_group,
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
index_buffer,
|
index_buffer,
|
||||||
num_indices,
|
num_indices,
|
||||||
|
@ -254,6 +306,7 @@ impl State {
|
||||||
});
|
});
|
||||||
|
|
||||||
render_pass.set_pipeline(&self.render_pipeline);
|
render_pass.set_pipeline(&self.render_pipeline);
|
||||||
|
render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]);
|
||||||
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(0..));
|
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(0..));
|
||||||
render_pass.set_index_buffer(self.index_buffer.slice(0..));
|
render_pass.set_index_buffer(self.index_buffer.slice(0..));
|
||||||
render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
|
render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
|
||||||
|
@ -268,7 +321,7 @@ impl State {
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
position: [f32; 3],
|
position: [f32; 3],
|
||||||
color: [f32; 3],
|
tex_coords: [f32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl bytemuck::Pod for Vertex {}
|
unsafe impl bytemuck::Pod for Vertex {}
|
||||||
|
@ -288,24 +341,35 @@ impl Vertex {
|
||||||
},
|
},
|
||||||
wgpu::VertexAttributeDescriptor {
|
wgpu::VertexAttributeDescriptor {
|
||||||
offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
|
offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
|
||||||
format: wgpu::VertexFormat::Float3,
|
format: wgpu::VertexFormat::Float2,
|
||||||
shader_location: 1,
|
shader_location: 1,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERTICES: &[Vertex] = &[
|
const VERTICES: &[Vertex] = &[
|
||||||
Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] },
|
Vertex {
|
||||||
Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] },
|
position: [-0.0868241, 0.49240386, 0.0],
|
||||||
Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] },
|
tex_coords: [0.4131759, 0.00759614],
|
||||||
Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] },
|
},
|
||||||
Vertex { position: [0.44147372, 0.2347359, 0.0],color: [0.5, 0.0, 0.5] },
|
Vertex {
|
||||||
|
position: [-0.49513406, 0.06958647, 0.0],
|
||||||
|
tex_coords: [0.0048659444, 0.43041354],
|
||||||
|
},
|
||||||
|
Vertex {
|
||||||
|
position: [-0.21918549, -0.44939706, 0.0],
|
||||||
|
tex_coords: [0.28081453, 0.949397057],
|
||||||
|
},
|
||||||
|
Vertex {
|
||||||
|
position: [0.35966998, -0.3473291, 0.0],
|
||||||
|
tex_coords: [0.85967, 0.84732911],
|
||||||
|
},
|
||||||
|
Vertex {
|
||||||
|
position: [0.44147372, 0.2347359, 0.0],
|
||||||
|
tex_coords: [0.9414737, 0.2652641],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const INDICES: &[u16] = &[
|
const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4];
|
||||||
0, 1, 4,
|
|
||||||
1, 2, 4,
|
|
||||||
2, 3, 4,
|
|
||||||
];
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(location=0) in vec3 v_color;
|
layout(location=0) in vec2 v_tex_coords;
|
||||||
layout(location=0) out vec4 f_color;
|
layout(location=0) out vec4 f_color;
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0) uniform texture2D t_diffuse;
|
||||||
|
layout(set = 0, binding = 1) uniform sampler s_diffuse;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
f_color = vec4(v_color, 1.0);
|
f_color = texture(sampler2D(t_diffuse, s_diffuse), v_tex_coords);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(location=0) in vec3 a_position;
|
layout(location=0) in vec3 a_position;
|
||||||
layout(location=1) in vec3 a_color;
|
layout(location=1) in vec2 a_tex_coords;
|
||||||
|
|
||||||
layout(location=0) out vec3 v_color;
|
layout(location=0) out vec2 v_tex_coords;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vec4(a_position, 1.0);
|
gl_Position = vec4(a_position, 1.0);
|
||||||
v_color = a_color;
|
v_tex_coords = a_tex_coords;
|
||||||
}
|
}
|
||||||
|
|
99
src/texture.rs
Normal file
99
src/texture.rs
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
use image::GenericImageView;
|
||||||
|
use wgpu::util::DeviceExt;
|
||||||
|
|
||||||
|
pub struct Texture {
|
||||||
|
pub texture: wgpu::Texture,
|
||||||
|
pub view: wgpu::TextureView,
|
||||||
|
pub sampler: wgpu::Sampler,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Texture {
|
||||||
|
pub fn from_bytes(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
bytes: &[u8],
|
||||||
|
label: &str,
|
||||||
|
) -> Result<(Self, wgpu::CommandBuffer), failure::Error> {
|
||||||
|
let img = image::load_from_memory(bytes)?;
|
||||||
|
Self::from_image(device, &img, Some(label))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_image(
|
||||||
|
device: &wgpu::Device,
|
||||||
|
img: &image::DynamicImage,
|
||||||
|
label: Option<&str>,
|
||||||
|
) -> Result<(Self, wgpu::CommandBuffer), failure::Error> {
|
||||||
|
let rgba = img.as_rgba8().unwrap();
|
||||||
|
|
||||||
|
let (width, height) = img.dimensions();
|
||||||
|
|
||||||
|
let size = wgpu::Extent3d {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
depth: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
|
label: Some("texture"),
|
||||||
|
size,
|
||||||
|
mip_level_count: 1,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||||
|
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||||
|
});
|
||||||
|
|
||||||
|
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("buffer"),
|
||||||
|
contents: &rgba,
|
||||||
|
usage: wgpu::BufferUsage::COPY_SRC,
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||||
|
label: Some("texture_buffer_copy_encoder"),
|
||||||
|
});
|
||||||
|
|
||||||
|
encoder.copy_buffer_to_texture(
|
||||||
|
wgpu::BufferCopyView {
|
||||||
|
buffer: &buffer,
|
||||||
|
layout: wgpu::TextureDataLayout {
|
||||||
|
offset: 0,
|
||||||
|
bytes_per_row: 4 * width,
|
||||||
|
rows_per_image: height,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wgpu::TextureCopyView {
|
||||||
|
texture: &texture,
|
||||||
|
mip_level: 0,
|
||||||
|
origin: wgpu::Origin3d::ZERO,
|
||||||
|
},
|
||||||
|
size,
|
||||||
|
);
|
||||||
|
|
||||||
|
let command = encoder.finish();
|
||||||
|
|
||||||
|
let view = texture.create_view(&Default::default());
|
||||||
|
|
||||||
|
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
||||||
|
label: Some("sampler"),
|
||||||
|
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||||
|
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||||
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
|
min_filter: wgpu::FilterMode::Nearest,
|
||||||
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
|
lod_min_clamp: -100.0,
|
||||||
|
lod_max_clamp: 100.0,
|
||||||
|
compare: None,
|
||||||
|
anisotropy_clamp: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Texture {
|
||||||
|
texture,
|
||||||
|
view,
|
||||||
|
sampler,
|
||||||
|
},
|
||||||
|
command,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue