Skip to content

Commit 1b051d3

Browse files
authored
Add SamplerDescriptor to Texture (#399) (#747)
GLTF loader now grabs (some) sampler information from the respective GLTF sampler struct.
1 parent fb2b19d commit 1b051d3

File tree

3 files changed

+56
-24
lines changed

3 files changed

+56
-24
lines changed

crates/bevy_gltf/src/loader.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@ use bevy_render::{
77
mesh::{Indices, Mesh, VertexAttribute},
88
pipeline::PrimitiveTopology,
99
prelude::{Color, Texture},
10-
texture::TextureFormat,
10+
texture::{AddressMode, FilterMode, SamplerDescriptor, TextureFormat},
1111
};
1212
use bevy_scene::Scene;
1313
use bevy_transform::{
1414
hierarchy::{BuildWorldChildren, WorldChildBuilder},
1515
prelude::{GlobalTransform, Transform},
1616
};
17-
use gltf::{mesh::Mode, Primitive};
17+
use gltf::{
18+
mesh::Mode,
19+
texture::{MagFilter, MinFilter, WrappingMode},
20+
Primitive,
21+
};
1822
use image::{GenericImageView, ImageFormat};
1923
use std::path::Path;
2024
use thiserror::Error;
@@ -24,6 +28,8 @@ use thiserror::Error;
2428
pub enum GltfError {
2529
#[error("Unsupported primitive mode.")]
2630
UnsupportedPrimitive { mode: Mode },
31+
#[error("Unsupported min filter.")]
32+
UnsupportedMinFilter { filter: MinFilter },
2733
#[error("Invalid GLTF file.")]
2834
Gltf(#[from] gltf::Error),
2935
#[error("Binary blob is missing.")]
@@ -133,6 +139,7 @@ async fn load_gltf<'a, 'b>(
133139
data: image.clone().into_vec(),
134140
size: bevy_math::f32::vec2(size.0 as f32, size.1 as f32),
135141
format: TextureFormat::Rgba8Unorm,
142+
sampler: texture_sampler(&texture)?,
136143
}),
137144
);
138145
}
@@ -263,6 +270,43 @@ fn texture_label(texture: &gltf::Texture) -> String {
263270
format!("Texture{}", texture.index())
264271
}
265272

273+
fn texture_sampler(texture: &gltf::Texture) -> Result<SamplerDescriptor, GltfError> {
274+
let gltf_sampler = texture.sampler();
275+
276+
Ok(SamplerDescriptor {
277+
address_mode_u: texture_address_mode(&gltf_sampler.wrap_s()),
278+
address_mode_v: texture_address_mode(&gltf_sampler.wrap_t()),
279+
280+
mag_filter: gltf_sampler
281+
.mag_filter()
282+
.map(|mf| match mf {
283+
MagFilter::Nearest => FilterMode::Nearest,
284+
MagFilter::Linear => FilterMode::Linear,
285+
})
286+
.unwrap_or(SamplerDescriptor::default().mag_filter),
287+
288+
min_filter: gltf_sampler
289+
.min_filter()
290+
.map(|mf| match mf {
291+
MinFilter::Nearest => Ok(FilterMode::Nearest),
292+
MinFilter::Linear => Ok(FilterMode::Linear),
293+
filter => Err(GltfError::UnsupportedMinFilter { filter }),
294+
})
295+
.transpose()?
296+
.unwrap_or(SamplerDescriptor::default().min_filter),
297+
298+
..Default::default()
299+
})
300+
}
301+
302+
fn texture_address_mode(gltf_address_mode: &gltf::texture::WrappingMode) -> AddressMode {
303+
match gltf_address_mode {
304+
WrappingMode::ClampToEdge => AddressMode::ClampToEdge,
305+
WrappingMode::Repeat => AddressMode::Repeat,
306+
WrappingMode::MirroredRepeat => AddressMode::MirrorRepeat,
307+
}
308+
}
309+
266310
fn get_primitive_topology(mode: Mode) -> Result<PrimitiveTopology, GltfError> {
267311
match mode {
268312
Mode::Points => Ok(PrimitiveTopology::PointList),

crates/bevy_render/src/texture/sampler_descriptor.rs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use super::Texture;
21
use crate::pipeline::CompareFunction;
32
use std::num::NonZeroU8;
43

54
/// Describes a sampler
6-
#[derive(Copy, Clone)]
5+
#[derive(Debug, Copy, Clone)]
76
pub struct SamplerDescriptor {
87
pub address_mode_u: AddressMode,
98
pub address_mode_v: AddressMode,
@@ -34,23 +33,6 @@ impl Default for SamplerDescriptor {
3433
}
3534
}
3635

37-
impl From<&Texture> for SamplerDescriptor {
38-
fn from(_texture: &Texture) -> Self {
39-
SamplerDescriptor {
40-
address_mode_u: AddressMode::ClampToEdge,
41-
address_mode_v: AddressMode::ClampToEdge,
42-
address_mode_w: AddressMode::ClampToEdge,
43-
mag_filter: FilterMode::Nearest,
44-
min_filter: FilterMode::Linear,
45-
mipmap_filter: FilterMode::Nearest,
46-
lod_min_clamp: 0.0,
47-
lod_max_clamp: std::f32::MAX,
48-
compare_function: None,
49-
anisotropy_clamp: None,
50-
}
51-
}
52-
}
53-
5436
/// How edges should be handled in texture addressing.
5537
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
5638
pub enum AddressMode {

crates/bevy_render/src/texture/texture.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub struct Texture {
1818
pub data: Vec<u8>,
1919
pub size: Vec2,
2020
pub format: TextureFormat,
21+
pub sampler: SamplerDescriptor,
2122
}
2223

2324
impl Default for Texture {
@@ -26,6 +27,7 @@ impl Default for Texture {
2627
data: Default::default(),
2728
size: Default::default(),
2829
format: TextureFormat::Rgba8UnormSrgb,
30+
sampler: Default::default(),
2931
}
3032
}
3133
}
@@ -37,7 +39,12 @@ impl Texture {
3739
data.len(),
3840
"Pixel data, size and format have to match",
3941
);
40-
Self { data, size, format }
42+
Self {
43+
data,
44+
size,
45+
format,
46+
..Default::default()
47+
}
4148
}
4249

4350
pub fn new_fill(size: Vec2, pixel: &[u8], format: TextureFormat) -> Self {
@@ -104,8 +111,7 @@ impl Texture {
104111
let texture_descriptor: TextureDescriptor = texture.into();
105112
let texture_resource = render_resource_context.create_texture(texture_descriptor);
106113

107-
let sampler_descriptor: SamplerDescriptor = texture.into();
108-
let sampler_resource = render_resource_context.create_sampler(&sampler_descriptor);
114+
let sampler_resource = render_resource_context.create_sampler(&texture.sampler);
109115

110116
render_resource_context.set_asset_resource(
111117
texture_handle,

0 commit comments

Comments
 (0)