Skip to content

Commit bd0f163

Browse files
committed
Use loaded RPG tiles as textures.
1 parent c50e987 commit bd0f163

File tree

2 files changed

+31
-60
lines changed

2 files changed

+31
-60
lines changed

assets/shaders/texture_binding_array.wgsl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ fn fragment(
1111
// Select the texture to sample from using non-uniform uv coordinates
1212
let coords = clamp(vec2<u32>(uv * 4.0), vec2<u32>(0u), vec2<u32>(3u));
1313
let index = coords.y * 4u + coords.x;
14-
return textureSample(textures[index], samplers[index], uv * 3.9 + 0.05);
14+
let inner_uv = fract(uv * 4.0);
15+
return textureSample(textures[index], samplers[index], inner_uv);
1516
#else
1617
return vec4<f32>(1.0, 0.0, 1.0, 1.0);
1718
#endif

examples/shader/texture_binding_array.rs

Lines changed: 29 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bevy::{
55
render_asset::RenderAssets,
66
render_resource::{AsBindGroupError, PreparedBindGroup, *},
77
renderer::RenderDevice,
8-
texture::{FallbackImage, ImageSampler},
8+
texture::FallbackImage,
99
},
1010
};
1111
use std::num::NonZeroU32;
@@ -16,72 +16,39 @@ fn main() {
1616
App::new()
1717
.add_plugins(DefaultPlugins)
1818
.add_plugin(MaterialPlugin::<BindlessMaterial>::default())
19-
.init_resource::<ColorTextures>()
2019
.add_startup_system(setup)
2120
.run();
2221
}
2322

2423
const MAX_TEXTURE_COUNT: usize = 16;
25-
26-
#[derive(Resource, Deref)]
27-
struct ColorTextures(Vec<Handle<Image>>);
28-
29-
impl FromWorld for ColorTextures {
30-
fn from_world(world: &mut World) -> Self {
31-
let mut images = world.resource_mut::<Assets<Image>>();
32-
33-
// Create 16 textures with different color gradients
34-
let handles = (1..=MAX_TEXTURE_COUNT)
35-
.map(|id| {
36-
let mut pixel = vec![(256 / id - 1) as u8; 64];
37-
for y in 0..3 {
38-
for x in 0..3 {
39-
pixel[16 * y + 4 * x + 1] = (256 / (y + 1) - 1) as u8;
40-
pixel[16 * y + 4 * x + 2] = (256 / (x + 1) - 1) as u8;
41-
pixel[16 * y + 4 * x + 3] = 255;
42-
}
43-
}
44-
45-
let mut image = Image::new_fill(
46-
Extent3d {
47-
width: 4,
48-
height: 4,
49-
depth_or_array_layers: 1,
50-
},
51-
TextureDimension::D2,
52-
&pixel[..],
53-
TextureFormat::Rgba8Unorm,
54-
);
55-
image.sampler_descriptor = ImageSampler::Descriptor(SamplerDescriptor {
56-
address_mode_u: AddressMode::Repeat,
57-
address_mode_v: AddressMode::Repeat,
58-
address_mode_w: AddressMode::Repeat,
59-
..Default::default()
60-
});
61-
images.add(image)
62-
})
63-
.collect();
64-
65-
Self(handles)
66-
}
67-
}
24+
const TILE_ID: [usize; 16] = [
25+
19, 23, 4, 33, 12, 69, 30, 48, 10, 65, 40, 47, 57, 41, 44, 46,
26+
];
6827

6928
fn setup(
7029
mut commands: Commands,
7130
mut meshes: ResMut<Assets<Mesh>>,
7231
mut materials: ResMut<Assets<BindlessMaterial>>,
73-
color_textures: Res<ColorTextures>,
32+
asset_server: Res<AssetServer>,
7433
) {
7534
commands.spawn(Camera3dBundle {
7635
transform: Transform::from_xyz(2.0, 2.0, 2.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y),
7736
..Default::default()
7837
});
7938

39+
// load 16 textures
40+
let textures: Vec<_> = TILE_ID
41+
.iter()
42+
.map(|id| {
43+
let path = format!("textures/rpg/tiles/generic-rpg-tile{:0>2}.png", id);
44+
asset_server.load(path)
45+
})
46+
.collect();
47+
48+
// a cube with multiple textures
8049
commands.spawn(MaterialMeshBundle {
8150
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
82-
material: materials.add(BindlessMaterial {
83-
textures: color_textures.clone(),
84-
}),
51+
material: materials.add(BindlessMaterial { textures }),
8552
..Default::default()
8653
});
8754
}
@@ -99,24 +66,27 @@ impl AsBindGroup for BindlessMaterial {
9966
&self,
10067
layout: &BindGroupLayout,
10168
render_device: &RenderDevice,
102-
images: &RenderAssets<Image>,
69+
image_assets: &RenderAssets<Image>,
10370
fallback_image: &FallbackImage,
10471
) -> Result<PreparedBindGroup<Self::Data>, AsBindGroupError> {
72+
// retrieve the render resources from handles
73+
let mut images = vec![];
74+
for handle in self.textures.iter().take(MAX_TEXTURE_COUNT) {
75+
match image_assets.get(handle) {
76+
Some(image) => images.push(image),
77+
None => return Err(AsBindGroupError::RetryNextUpdate),
78+
}
79+
}
80+
10581
let textures = vec![&fallback_image.texture_view; MAX_TEXTURE_COUNT];
10682
let samplers = vec![&fallback_image.sampler; MAX_TEXTURE_COUNT];
10783

108-
// Convert bevy's resource types to wgpu's references
84+
// convert bevy's resource types to WGPU's references
10985
let mut textures: Vec<_> = textures.into_iter().map(|texture| &**texture).collect();
11086
let mut samplers: Vec<_> = samplers.into_iter().map(|sampler| &**sampler).collect();
11187

112-
// Fill in up to the first `MAX_TEXTURE_COUNT` textures and samplers to the arrays
113-
for (id, image) in self
114-
.textures
115-
.iter()
116-
.filter_map(|handle| images.get(handle))
117-
.take(MAX_TEXTURE_COUNT)
118-
.enumerate()
119-
{
88+
// fill in up to the first `MAX_TEXTURE_COUNT` textures and samplers to the arrays
89+
for (id, image) in images.into_iter().enumerate() {
12090
textures[id] = &*image.texture_view;
12191
samplers[id] = &*image.sampler;
12292
}

0 commit comments

Comments
 (0)