Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 44 additions & 22 deletions crates/bevy_image/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,21 +1063,20 @@ impl Image {
}
}

/// Changes the `size`, asserting that the total number of data elements (pixels) remains the
/// same.
///
/// # Panics
/// Panics if the `new_size` does not have the same volume as to old one.
pub fn reinterpret_size(&mut self, new_size: Extent3d) {
assert_eq!(
new_size.volume(),
self.texture_descriptor.size.volume(),
"Incompatible sizes: old = {:?} new = {:?}",
self.texture_descriptor.size,
new_size
);
/// Changes the `size` if the total number of data elements (pixels) remains the same.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs here should mention what errors it might return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for my understanding: This makes sense here, because it returns TextureReinterpretationError, but will only ever construct one variant. Correct?
I will add it.

pub fn reinterpret_size(
&mut self,
new_size: Extent3d,
) -> Result<(), TextureReinterpretationError> {
if new_size.volume() != self.texture_descriptor.size.volume() {
return Err(TextureReinterpretationError::IncompatibleSizes {
old: self.texture_descriptor.size,
new: new_size,
});
}

self.texture_descriptor.size = new_size;
Ok(())
}

/// Resizes the image to the new size, keeping the pixel data intact, anchored at the top-left.
Expand Down Expand Up @@ -1128,21 +1127,31 @@ impl Image {
/// Takes a 2D image containing vertically stacked images of the same size, and reinterprets
/// it as a 2D array texture, where each of the stacked images becomes one layer of the
/// array. This is primarily for use with the `texture2DArray` shader uniform type.
///
/// # Panics
/// Panics if the texture is not 2D, has more than one layers or is not evenly dividable into
/// the `layers`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be changed into docs on what errors it might return.

Copy link
Contributor Author

@KirmesBude KirmesBude Aug 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not see this with other functions. Here it could return every enum member. Should I still add something to the comment here?

pub fn reinterpret_stacked_2d_as_array(&mut self, layers: u32) {
pub fn reinterpret_stacked_2d_as_array(
&mut self,
layers: u32,
) -> Result<(), TextureReinterpretationError> {
// Must be a stacked image, and the height must be divisible by layers.
assert_eq!(self.texture_descriptor.dimension, TextureDimension::D2);
assert_eq!(self.texture_descriptor.size.depth_or_array_layers, 1);
assert_eq!(self.height() % layers, 0);
if self.texture_descriptor.dimension != TextureDimension::D2 {
return Err(TextureReinterpretationError::WrongDimension);
}
if self.texture_descriptor.size.depth_or_array_layers != 1 {
return Err(TextureReinterpretationError::InvalidLayerCount);
}
if self.height() % layers != 0 {
return Err(TextureReinterpretationError::HeightNotDivisibleByLayers {
height: self.height(),
layers,
});
}

self.reinterpret_size(Extent3d {
width: self.width(),
height: self.height() / layers,
depth_or_array_layers: layers,
});
})?;

Ok(())
}

/// Convert a texture from a format to another. Only a few formats are
Expand Down Expand Up @@ -1741,6 +1750,19 @@ pub enum TranscodeFormat {
Rgb8,
}

/// An error that occurs when reinterpreting the image.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/the/a

This should mention the functions that might return it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not familiar with what "s/the/a" means.
I was looking at the other Errors in this file and this looks the same to me. The other ones do not mention the functions either. Do you have an example from elsewhere in bevy that I can base this on?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"s/the/a" means subsitute (or search and replace) "the" by "a". It comes from sed or perl.

So it should be "a image" instead of "the image".

As a non-native speaker I would've used "an image" though, but that may be wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not familiar with what "s/the/a" means.

Sorry about that, bad habit of mine. Should've made a suggestion instead.

As a non-native speaker I would've used "an image" though, but that may be wrong.

This would be grammatically correct.

#[derive(Error, Debug)]
pub enum TextureReinterpretationError {
#[error("incompatible sizes: old = {old:?} new = {new:?}")]
IncompatibleSizes { old: Extent3d, new: Extent3d },
#[error("must be a 2d image")]
WrongDimension,
#[error("must not already be a layered image")]
InvalidLayerCount,
#[error("can not evenly divide height = {height} by layers = {layers}")]
HeightNotDivisibleByLayers { height: u32, layers: u32 },
}

/// An error that occurs when accessing specific pixels in a texture.
#[derive(Error, Debug)]
pub enum TextureAccessError {
Expand Down
2 changes: 1 addition & 1 deletion examples/2d/tilemap_chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fn update_tileset_image(
for event in events.read() {
if event.is_loaded_with_dependencies(chunk.tileset.id()) {
let image = images.get_mut(&chunk.tileset).unwrap();
image.reinterpret_stacked_2d_as_array(4);
image.reinterpret_stacked_2d_as_array(4).unwrap();
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion examples/3d/skybox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ fn asset_loaded(
// NOTE: PNGs do not have any metadata that could indicate they contain a cubemap texture,
// so they appear as one texture. The following code reconfigures the texture as necessary.
if image.texture_descriptor.array_layer_count() == 1 {
image.reinterpret_stacked_2d_as_array(image.height() / image.width());
image
.reinterpret_stacked_2d_as_array(image.height() / image.width())
.unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a user-facing example. This should, at the minimum, use expect, and in the best case handle the error/bubble it up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It behaves the same way as before. Thought about adding a comment. Good call on using expect - let me know what you think

image.texture_view_descriptor = Some(TextureViewDescriptor {
dimension: Some(TextureViewDimension::Cube),
..default()
Expand Down
2 changes: 1 addition & 1 deletion examples/shader/array_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn create_array_texture(

// Create a new array texture asset from the loaded texture.
let array_layers = 4;
image.reinterpret_stacked_2d_as_array(array_layers);
image.reinterpret_stacked_2d_as_array(array_layers).unwrap();

// Spawn some cubes using the array texture
let mesh_handle = meshes.add(Cuboid::default());
Expand Down
Loading