2020-06-22 19:14:40 +00:00
|
|
|
use crate::ColorMaterial;
|
2020-05-13 23:42:27 +00:00
|
|
|
use bevy_asset::{Assets, Handle};
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
use bevy_core::Bytes;
|
2021-03-24 21:29:53 +00:00
|
|
|
use bevy_ecs::{
|
|
|
|
query::Without,
|
|
|
|
system::{Query, Res},
|
|
|
|
};
|
2020-07-17 00:23:50 +00:00
|
|
|
use bevy_math::Vec2;
|
2020-11-28 00:39:59 +00:00
|
|
|
use bevy_reflect::{Reflect, ReflectDeserialize, TypeUuid};
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
use bevy_render::{
|
2021-03-24 21:29:53 +00:00
|
|
|
draw::OutsideFrustum,
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
renderer::{RenderResource, RenderResourceType, RenderResources},
|
|
|
|
texture::Texture,
|
|
|
|
};
|
2020-11-28 00:39:59 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2020-06-22 19:14:40 +00:00
|
|
|
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
#[derive(Debug, Default, Clone, TypeUuid, Reflect, RenderResources)]
|
|
|
|
#[render_resources(from_self)]
|
2020-10-18 20:48:15 +00:00
|
|
|
#[uuid = "7233c597-ccfa-411f-bd59-9af349432ada"]
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
#[repr(C)]
|
2020-05-04 08:22:25 +00:00
|
|
|
pub struct Sprite {
|
2020-06-27 04:40:09 +00:00
|
|
|
pub size: Vec2,
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
pub flip_x: bool,
|
|
|
|
pub flip_y: bool,
|
2020-09-08 19:04:22 +00:00
|
|
|
pub resize_mode: SpriteResizeMode,
|
2020-05-04 08:22:25 +00:00
|
|
|
}
|
|
|
|
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
impl RenderResource for Sprite {
|
|
|
|
fn resource_type(&self) -> Option<RenderResourceType> {
|
|
|
|
Some(RenderResourceType::Buffer)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn buffer_byte_len(&self) -> Option<usize> {
|
|
|
|
Some(12)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_buffer_bytes(&self, buffer: &mut [u8]) {
|
|
|
|
// Write the size buffer
|
|
|
|
let (size_buf, flip_buf) = buffer.split_at_mut(8);
|
|
|
|
self.size.write_bytes(size_buf);
|
|
|
|
|
|
|
|
// First bit means flip x, second bit means flip y
|
|
|
|
flip_buf[0] = if self.flip_x { 0b01 } else { 0 } | if self.flip_y { 0b10 } else { 0 };
|
|
|
|
flip_buf[1] = 0;
|
|
|
|
flip_buf[2] = 0;
|
|
|
|
flip_buf[3] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn texture(&self) -> Option<&Handle<Texture>> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-08 19:04:22 +00:00
|
|
|
/// Determines how `Sprite` resize should be handled
|
2020-11-28 00:39:59 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
|
|
|
|
#[reflect_value(PartialEq, Serialize, Deserialize)]
|
2020-09-08 19:04:22 +00:00
|
|
|
pub enum SpriteResizeMode {
|
|
|
|
Manual,
|
|
|
|
Automatic,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for SpriteResizeMode {
|
|
|
|
fn default() -> Self {
|
|
|
|
SpriteResizeMode::Automatic
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Sprite {
|
|
|
|
/// Creates new `Sprite` with `SpriteResizeMode::Manual` value for `resize_mode`
|
|
|
|
pub fn new(size: Vec2) -> Self {
|
|
|
|
Self {
|
|
|
|
size,
|
|
|
|
resize_mode: SpriteResizeMode::Manual,
|
Add Sprite Flipping (#1407)
OK, here's my attempt at sprite flipping. There are a couple of points that I need review/help on, but I think the UX is about ideal:
```rust
.spawn(SpriteBundle {
material: materials.add(texture_handle.into()),
sprite: Sprite {
// Flip the sprite along the x axis
flip: SpriteFlip { x: true, y: false },
..Default::default()
},
..Default::default()
});
```
Now for the issues. The big issue is that for some reason, when flipping the UVs on the sprite, there is a light "bleeding" or whatever you call it where the UV tries to sample past the texture boundry and ends up clipping. This is only noticed when resizing the window, though. You can see a screenshot below.
![image](https://user-images.githubusercontent.com/25393315/107098172-397aaa00-67d4-11eb-8e02-c90c820cd70e.png)
I am quite baffled why the texture sampling is overrunning like it is and could use some guidance if anybody knows what might be wrong.
The other issue, which I just worked around, is that I had to remove the `#[render_resources(from_self)]` annotation from the Spritesheet because the `SpriteFlip` render resource wasn't being picked up properly in the shader when using it. I'm not sure what the cause of that was, but by removing the annotation and re-organizing the shader inputs accordingly the problem was fixed.
I'm not sure if this is the most efficient way to do this or if there is a better way, but I wanted to try it out if only for the learning experience. Let me know what you think!
2021-03-03 19:26:45 +00:00
|
|
|
flip_x: false,
|
|
|
|
flip_y: false,
|
2020-09-08 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-05-04 08:22:25 +00:00
|
|
|
|
2020-07-10 04:18:35 +00:00
|
|
|
pub fn sprite_system(
|
|
|
|
materials: Res<Assets<ColorMaterial>>,
|
|
|
|
textures: Res<Assets<Texture>>,
|
2021-03-24 21:29:53 +00:00
|
|
|
mut query: Query<(&mut Sprite, &Handle<ColorMaterial>), Without<OutsideFrustum>>,
|
2020-07-10 04:18:35 +00:00
|
|
|
) {
|
2020-10-30 06:39:55 +00:00
|
|
|
for (mut sprite, handle) in query.iter_mut() {
|
2020-09-08 19:04:22 +00:00
|
|
|
match sprite.resize_mode {
|
|
|
|
SpriteResizeMode::Manual => continue,
|
|
|
|
SpriteResizeMode::Automatic => {
|
2020-10-18 20:48:15 +00:00
|
|
|
let material = materials.get(handle).unwrap();
|
|
|
|
if let Some(ref texture_handle) = material.texture {
|
|
|
|
if let Some(texture) = textures.get(texture_handle) {
|
2020-12-01 21:17:48 +00:00
|
|
|
let texture_size = texture.size.as_vec3().truncate();
|
2021-03-11 00:27:30 +00:00
|
|
|
// only set sprite size if it has changed (this check prevents change
|
|
|
|
// detection from triggering)
|
2020-12-01 21:17:48 +00:00
|
|
|
if sprite.size != texture_size {
|
|
|
|
sprite.size = texture_size;
|
|
|
|
}
|
2020-09-08 19:04:22 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-04 08:22:25 +00:00
|
|
|
}
|
2020-07-10 04:18:35 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-04 08:22:25 +00:00
|
|
|
}
|