From 7329e399708865168f2040c3b02e378a0d841d3c Mon Sep 17 00:00:00 2001 From: marceline-cramer Date: Tue, 15 Feb 2022 16:55:00 -0700 Subject: [PATCH] Load glTF base color texture --- src/camera.rs | 2 +- src/model.rs | 63 +++++++++++++++++++++++++++++++++------------------ src/pool.rs | 6 ++--- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/camera.rs b/src/camera.rs index 6c6809a..1057e2c 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -49,7 +49,7 @@ impl Flycam { turn_speed, aspect: 1.0, // TODO compute from size fovy: std::f32::consts::FRAC_PI_2, - znear: 0.1, + znear: 0.01, zfar: 100.0, } } diff --git a/src/model.rs b/src/model.rs index 0b90c27..aae82d8 100644 --- a/src/model.rs +++ b/src/model.rs @@ -195,27 +195,9 @@ impl<'a> GltfLoader<'a> { pub fn load_primitive_material(&mut self, primitive: gltf::Primitive) -> MaterialHandle { let pbr = primitive.material().pbr_metallic_roughness(); - let base_texture = pbr.base_color_texture().unwrap(); - let base_texture = base_texture.texture().source().source(); - let base_view = if let gltf::image::Source::View { view, .. } = base_texture { - view - } else { - panic!("texture must be embedded"); - }; - - // TODO put real data in albedo texture - - let albedo_data = TextureData { - width: 256, - height: 256, - data: vec![0xffu8; 256 * 256 * 4], - }; - - let albedo = - self.ren - .texture_pool - .allocate(&self.ren.device, &self.ren.queue, &albedo_data); + let base_color = pbr.base_color_texture().unwrap().texture(); + let albedo = self.load_texture(base_color); let material_data = MaterialData { albedo }; @@ -224,6 +206,45 @@ impl<'a> GltfLoader<'a> { .allocate(&self.ren.device, &self.ren.texture_pool, &material_data) } + pub fn load_texture(&mut self, texture: gltf::Texture) -> TextureHandle { + let source = texture.source().source(); + let view = if let gltf::image::Source::View { view, .. } = source { + view + } else { + panic!("texture must be embedded"); + }; + + let start = view.offset() as usize; + let end = (view.offset() + view.length()) as usize; + let src = &self.buffers[view.buffer().index()][start..end]; + + use image::GenericImageView; + let image = image::load_from_memory(src).unwrap(); + let dimensions = image.dimensions(); + + let rgba: Vec = if let Some(rgba) = image.as_rgba8() { + rgba.to_vec() + } else { + let rgb = image.as_rgb8().unwrap().to_vec(); + let mut rgba = Vec::::new(); + for rgb in rgb.chunks(3) { + rgba.extend_from_slice(rgb); + rgba.push(0xff); + } + rgba + }; + + let data = TextureData { + width: dimensions.0, + height: dimensions.1, + data: rgba, + }; + + self.ren + .texture_pool + .allocate(&self.ren.device, &self.ren.queue, &data) + } + pub fn load_primitive_mesh(&mut self, primitive: gltf::Primitive) -> MeshHandle { use gltf::mesh::util::{ReadIndices, ReadTexCoords}; @@ -231,8 +252,6 @@ impl<'a> GltfLoader<'a> { panic!("glTF primitive must be triangle list"); } - println!("primitive: {:#?}", primitive); - let reader = primitive.reader(|buffer| Some(&self.buffers[buffer.index()])); let positions = reader.read_positions().unwrap(); let mut normals = reader.read_normals().unwrap(); diff --git a/src/pool.rs b/src/pool.rs index 4d99c61..eb05ef6 100644 --- a/src/pool.rs +++ b/src/pool.rs @@ -119,9 +119,9 @@ impl TexturePool { pub fn new(device: &wgpu::Device) -> Self { let textures = Default::default(); let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, + address_mode_u: wgpu::AddressMode::Repeat, + address_mode_v: wgpu::AddressMode::Repeat, + address_mode_w: wgpu::AddressMode::Repeat, mag_filter: wgpu::FilterMode::Linear, min_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest,