Skip to content

Commit b25bbb7

Browse files
authored
Image::get_color_at_3d and Image::set_color_at_3d: Support 2D images with layers (#17548)
# Objective This makes the `Image::get_color_at_3d` and `Image::set_color_at_3d` methods work with 2D images with more than one layer. ## Solution - The Z coordinate is interpreted as the layer number. ## Testing - Added a test: `get_set_pixel_2d_with_layers`.
1 parent e8cd12d commit b25bbb7

File tree

1 file changed

+41
-16
lines changed

1 file changed

+41
-16
lines changed

crates/bevy_image/src/image.rs

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ impl Image {
10051005
///
10061006
/// Returns None if the provided coordinates are out of bounds.
10071007
///
1008-
/// For 2D textures, Z is ignored. For 1D textures, Y and Z are ignored.
1008+
/// For 2D textures, Z is the layer number. For 1D textures, Y and Z are ignored.
10091009
#[inline(always)]
10101010
pub fn pixel_data_offset(&self, coords: UVec3) -> Option<usize> {
10111011
let width = self.texture_descriptor.size.width;
@@ -1014,18 +1014,12 @@ impl Image {
10141014

10151015
let pixel_size = self.texture_descriptor.format.pixel_size();
10161016
let pixel_offset = match self.texture_descriptor.dimension {
1017-
TextureDimension::D3 => {
1017+
TextureDimension::D3 | TextureDimension::D2 => {
10181018
if coords.x >= width || coords.y >= height || coords.z >= depth {
10191019
return None;
10201020
}
10211021
coords.z * height * width + coords.y * width + coords.x
10221022
}
1023-
TextureDimension::D2 => {
1024-
if coords.x >= width || coords.y >= height {
1025-
return None;
1026-
}
1027-
coords.y * width + coords.x
1028-
}
10291023
TextureDimension::D1 => {
10301024
if coords.x >= width {
10311025
return None;
@@ -1096,15 +1090,20 @@ impl Image {
10961090
self.get_color_at_internal(UVec3::new(x, y, 0))
10971091
}
10981092

1099-
/// Read the color of a specific pixel (3D texture).
1093+
/// Read the color of a specific pixel (2D texture with layers or 3D texture).
11001094
///
11011095
/// See [`get_color_at`](Self::get_color_at) for more details.
11021096
#[inline(always)]
11031097
pub fn get_color_at_3d(&self, x: u32, y: u32, z: u32) -> Result<Color, TextureAccessError> {
1104-
if self.texture_descriptor.dimension != TextureDimension::D3 {
1105-
return Err(TextureAccessError::WrongDimension);
1098+
match (
1099+
self.texture_descriptor.dimension,
1100+
self.texture_descriptor.size.depth_or_array_layers,
1101+
) {
1102+
(TextureDimension::D3, _) | (TextureDimension::D2, 2..) => {
1103+
self.get_color_at_internal(UVec3::new(x, y, z))
1104+
}
1105+
_ => Err(TextureAccessError::WrongDimension),
11061106
}
1107-
self.get_color_at_internal(UVec3::new(x, y, z))
11081107
}
11091108

11101109
/// Change the color of a specific pixel (1D texture).
@@ -1148,7 +1147,7 @@ impl Image {
11481147
self.set_color_at_internal(UVec3::new(x, y, 0), color)
11491148
}
11501149

1151-
/// Change the color of a specific pixel (3D texture).
1150+
/// Change the color of a specific pixel (2D texture with layers or 3D texture).
11521151
///
11531152
/// See [`set_color_at`](Self::set_color_at) for more details.
11541153
#[inline(always)]
@@ -1159,10 +1158,15 @@ impl Image {
11591158
z: u32,
11601159
color: Color,
11611160
) -> Result<(), TextureAccessError> {
1162-
if self.texture_descriptor.dimension != TextureDimension::D3 {
1163-
return Err(TextureAccessError::WrongDimension);
1161+
match (
1162+
self.texture_descriptor.dimension,
1163+
self.texture_descriptor.size.depth_or_array_layers,
1164+
) {
1165+
(TextureDimension::D3, _) | (TextureDimension::D2, 2..) => {
1166+
self.set_color_at_internal(UVec3::new(x, y, z), color)
1167+
}
1168+
_ => Err(TextureAccessError::WrongDimension),
11641169
}
1165-
self.set_color_at_internal(UVec3::new(x, y, z), color)
11661170
}
11671171

11681172
#[inline(always)]
@@ -1659,4 +1663,25 @@ mod test {
16591663
Err(TextureAccessError::OutOfBounds { x: 5, y: 10, z: 0 })
16601664
));
16611665
}
1666+
1667+
#[test]
1668+
fn get_set_pixel_2d_with_layers() {
1669+
let mut image = Image::new_fill(
1670+
Extent3d {
1671+
width: 5,
1672+
height: 10,
1673+
depth_or_array_layers: 3,
1674+
},
1675+
TextureDimension::D2,
1676+
&[0, 0, 0, 255],
1677+
TextureFormat::Rgba8Unorm,
1678+
RenderAssetUsages::MAIN_WORLD,
1679+
);
1680+
image.set_color_at_3d(0, 0, 0, Color::WHITE).unwrap();
1681+
assert!(matches!(image.get_color_at_3d(0, 0, 0), Ok(Color::WHITE)));
1682+
image.set_color_at_3d(2, 3, 1, Color::WHITE).unwrap();
1683+
assert!(matches!(image.get_color_at_3d(2, 3, 1), Ok(Color::WHITE)));
1684+
image.set_color_at_3d(4, 9, 2, Color::WHITE).unwrap();
1685+
assert!(matches!(image.get_color_at_3d(4, 9, 2), Ok(Color::WHITE)));
1686+
}
16621687
}

0 commit comments

Comments
 (0)