Dynamic Texture #2627
Unanswered
massimiliano-mantione
asked this question in
Q&A
Dynamic Texture
#2627
Replies: 1 comment
-
Think I can help, I've implemented something similar to what You described. let input = Arc::new(Mutex::new(camera_stream));
App::build()
.insert_resource(input.clone()) Next I have a system that grabs each new frame that it receives from the stream and The system looks like this. pub fn video_stream(
mut commands: Commands,
input: ResMut<Arc<Mutex<BufInput<VideoFrame>>>>,
mut textures: ResMut<Assets<Texture>>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut game: ResMut<GameState>,
) {
let some_frame = input.lock().unwrap().read();
if frame.is_none() {
return;
}
let frame = some_frame.unwrap();
let width = frame.width();
let height = frame.height();
// create new texture
let texture_handle = textures.add(Texture {
data: frame.data().to_vec(),
dimension: bevy::render::texture::TextureDimension::D2,
format: TextureFormat::Rgba8Unorm,
size: Extent3d {
width,
height,
depth: 1,
},
..Default::default()
});
let frame_sprite = SpriteBundle {
material: materials.add(texture_handle.into()),
transform: Transform {
translation: Vec3::new(0.0, 0.0, 1.0),
..Default::default()
},
..Default::default()
};
// despawn old frame if there is some
if let Some(current_frame) = game.current_frame {
commands.entity(current_frame).despawn_recursive();
game.current_frame = None;
}
// spawn new frame texture and track the frame entity in the game state
game.current_frame = Some(commands.spawn_bundle(frame_sprite).id());
} This approach worked for me, the FPS worked fine but I'm not sure if there is a better way |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I am trying to put CPU-generated data inside a texture.
What I ultimately need is to grab frames from a camera, process them, and show the result as images, in real time.
I wanted to show those images both in a 3D scene and inside an egui UI.
The problem is that I can update the texture, I see it changing in the UI, but it disappears from the 3D scene.
If I never change it it works in both egui and the 3D renderer.
However, as soon as I write inside the texture
data
vector, egui shows the modified texture but the 3D scene shows no texture at all (it apparently becomes transparent for the 3D renderer).The texture uses the
TextureFormat::Rgba8UnormSrgb
format, I simply write RGBA data in the texturedata
vector (which I manually created of the correct size).I have seen issues related to tracking texture modifications and reflecting them into materials (like #1161) but they seem solved now.
Is there anything specific I should do?
From here on I am explaining how my code works:
I figured out that I can create a
Texture
use it as a resource, then I could change it by usingResMut
.However, in order to use the texture (both in egui and in a
StandardMaterial
) I see I need aHandle<Texture>
.So I put the texture inside
Assets<Texture>
, get the handle, and use it everywhere.I have a
DynamicTexture
type that I can use as a resource, it just contains texture handle as some other texture-related info.My setup looks like this:
(the texture is called
axes
because of what it shows now, this is irrelevant).Then I have this system:
So... what's wrong?
Do I need to notify the 3D renderer that the texture changed?
If yes, how?
Beta Was this translation helpful? Give feedback.
All reactions