I can haz UI?

This commit is contained in:
2026-02-11 13:33:14 +01:00
parent 714ce86699
commit 311ca48092
5 changed files with 52 additions and 29 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -5,8 +5,6 @@ use bevy::app::ScheduleRunnerPlugin;
use bevy::camera::RenderTarget; use bevy::camera::RenderTarget;
use bevy::color::Color; use bevy::color::Color;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::RenderPlugin;
use bevy::winit::WinitPlugin;
use wgpu::{TextureFormat, TextureUsages}; use wgpu::{TextureFormat, TextureUsages};
mod post_process; mod post_process;
@@ -21,19 +19,21 @@ mod shared;
fn main() { fn main() {
App::new() App::new()
.add_plugins(( .add_plugins((
DefaultPlugins DefaultPlugins.set(WindowPlugin {
.set(RenderPlugin { primary_window: Some(Window {
synchronous_pipeline_compilation: true, resolution: bevy::window::WindowResolution::new(160 * 4, 43 * 4)
.with_scale_factor_override(4.0),
..default() ..default()
}) }),
.build() ..default()
.disable::<WinitPlugin>(), }),
ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1. / 30.)), ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1. / 30.)),
post_process::PostProcessPlugin, post_process::PostProcessPlugin,
ImageExportPlugin, ImageExportPlugin,
)) ))
.insert_resource(ClearColor(Color::linear_rgba(0.0, 0.0, 0.0, 1.0))) .insert_resource(ClearColor(Color::linear_rgba(0.0, 0.0, 0.0, 0.0)))
.add_systems(Startup, setup_scene_system) .add_systems(Startup, setup_scene_system)
.add_systems(PostStartup, spawn_in_ui)
.add_systems(Update, rotate_cube) .add_systems(Update, rotate_cube)
.run(); .run();
} }
@@ -66,18 +66,44 @@ fn setup_scene_system(
Camera::default(), Camera::default(),
RenderTarget::Image(image_handle.clone().into()), RenderTarget::Image(image_handle.clone().into()),
Transform::from_xyz(0.0, 1.0, 2.5).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(0.0, 1.0, 2.5).looking_at(Vec3::ZERO, Vec3::Y),
UiAntiAlias::Off,
PostProcessSettings { scale: 1.0 }, PostProcessSettings { scale: 1.0 },
)); ));
commands.spawn((ImageExport(export_sources.add(image_handle)),)); commands.spawn((ImageExport(export_sources.add(image_handle)),));
} }
fn spawn_in_ui(mut commands: Commands, assets: Res<AssetServer>, camera: Query<(Entity, &Camera)>) {
let font: Handle<Font> = assets.load("fonts/Roboto-Bold.ttf");
let text_font = TextFont::from(font.clone())
.with_font_size(12.)
.with_font_smoothing(bevy::text::FontSmoothing::None);
let Ok(main_camera) = camera.single() else {
return; // no camera... yet?
};
commands.spawn((
Node {
position_type: PositionType::Absolute,
top: Val::Px(5.0),
left: Val::Px(5.0),
..default()
},
Text::new("Hello World!"),
text_font.clone(),
TextColor(Color::WHITE),
UiTargetCamera(main_camera.0),
));
}
fn rotate_cube( fn rotate_cube(
mut cubes: Query<(&mut Transform, &Spinner)>, mut cubes: Query<(&mut Transform, &Spinner)>,
timer: Res<Time>, timer: Res<Time>,
g13: Res<G13Resource>, g13: Res<G13Resource>,
) { ) {
const DEADZONE: i32 = 30; const DEADZONE: i32 = 35;
let g13 = g13.g13.state(); let g13 = g13.g13.state();
let mut x = g13.x as f32 / 512.0; let mut x = g13.x as f32 / 512.0;

View File

@@ -59,7 +59,7 @@ impl Plugin for PostProcessPlugin {
} }
#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)] #[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)]
struct PostProcessLabel; pub struct PostProcessLabel;
#[derive(Default)] #[derive(Default)]
struct PostProcessNode; struct PostProcessNode;

View File

@@ -14,9 +14,8 @@ use bevy::{
texture::GpuImage, texture::GpuImage,
}, },
}; };
use embedded_graphics::pixelcolor::BinaryColor;
use futures::channel::oneshot; use futures::channel::oneshot;
use g13_driver::{G13, G13_LCD_BUF_SIZE}; use g13_driver::G13;
use wgpu::PollType; use wgpu::PollType;
#[derive(Resource, Clone)] #[derive(Resource, Clone)]
@@ -141,25 +140,21 @@ fn save_buffer_to_disk(
image_bytes = unpadded_bytes; image_bytes = unpadded_bytes;
} }
let mut img_buffer = [0u8; G13_LCD_BUF_SIZE as usize]; let mut img_buffer = [0u8; g13_driver::G13_LCD_BUF_SIZE as usize];
for (i, b) in image_bytes for (i, rgba) in image_bytes.chunks(4).enumerate() {
.iter()
.step_by(4)
.take(G13_LCD_BUF_SIZE as usize * 8)
.enumerate()
{
let offset = i / 8; let offset = i / 8;
let mask = 1 << (7 - (i % 8)); let mask = 1 << (7 - (i % 8));
if *b == 0xFF { if ((rgba[0] + rgba[1] + rgba[2]) / 3) > 0x08 {
img_buffer[offset] |= mask; img_buffer[offset] |= mask;
} else { } else {
img_buffer[offset] &= !mask; img_buffer[offset] &= !mask;
} }
} }
use embedded_graphics::image::ImageDrawable; use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::prelude::*;
embedded_graphics::image::ImageRaw::<BinaryColor>::new(&img_buffer, 160) embedded_graphics::image::ImageRaw::<BinaryColor>::new(&img_buffer, 160)
.draw(&mut g13.g13) .draw(&mut g13.g13)
.expect("G13 to be connected"); .expect("G13 to be connected");
@@ -194,7 +189,7 @@ impl Plugin for ImageExportPlugin {
let g13r: G13Resource = G13Resource { g13 }; let g13r: G13Resource = G13Resource { g13 };
app.configure_sets(PostUpdate, ImageExportSetup) app.configure_sets(PostUpdate, ImageExportSetup)
.insert_resource(g13r.clone()) .insert_resource(g13r.clone()) // input only
.register_type::<ImageExportSource>() .register_type::<ImageExportSource>()
.init_asset::<ImageExportSource>() .init_asset::<ImageExportSource>()
.register_asset_reflect::<ImageExportSource>() .register_asset_reflect::<ImageExportSource>()
@@ -206,7 +201,9 @@ impl Plugin for ImageExportPlugin {
let render_app = app.sub_app_mut(RenderApp); let render_app = app.sub_app_mut(RenderApp);
render_app.insert_resource(g13r).add_systems( render_app
.insert_resource(g13r) // output only
.add_systems(
Render, Render,
save_buffer_to_disk save_buffer_to_disk
.after(RenderSystems::Render) .after(RenderSystems::Render)