Skip to content
Merged

Midi #77

Show file tree
Hide file tree
Changes from all 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
1,741 changes: 1,085 additions & 656 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ bevy = { git = "https://github.com/bevyengine/bevy", branch = "main", features =
processing = { path = "." }
processing_pyo3 = { path = "crates/processing_pyo3" }
processing_render = { path = "crates/processing_render" }
processing_midi = { path = "crates/processing_midi" }

[dependencies]
bevy = { workspace = true }
processing_render = { workspace = true }
processing_midi = { workspace = true }

[dev-dependencies]
glfw = "0.60.0"
Expand Down Expand Up @@ -76,6 +78,10 @@ path = "examples/materials.rs"
name = "pbr"
path = "examples/pbr.rs"

[[example]]
name = "midi"
path = "examples/midi.rs"

[profile.wasm-release]
inherits = "release"
opt-level = "z"
Expand Down
12 changes: 12 additions & 0 deletions crates/processing_midi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "processing_midi"
version = "0.1.0"
edition = "2024"

[dependencies]
bevy = { workspace = true }
bevy_midi = { git = "https://github.com/BlackPhlox/bevy_midi", branch = "latest" }


[lints]
workspace = true
25 changes: 25 additions & 0 deletions crates/processing_midi/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use bevy::prelude::*;
use bevy_midi::prelude::*;

pub struct MidiPlugin;

impl Plugin for MidiPlugin {
fn build(&self, app: &mut App) {
app.insert_resource(MidiOutputSettings {
port_name: "output",
})
.add_plugins(MidiOutputPlugin);
}
}

enum MidiCommand {}

pub fn connect(port: usize) {
// we need to work with the ECS
// do we pass a MidiCommand to Bevy?
Copy link
Member

Choose a reason for hiding this comment

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

I think we need to make a few changes to bevy_midi to support things like hot-plugging. Right now it assumes that devices are available on startup.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahhh okay good to know! in this PR the midi stuff is so early because of the bevy updates. i was going to keep working on this, but i'm wondering if we could land the bevy changes just so main has them

}

pub fn disconnect() {}
pub fn refresh_ports() {}

pub fn play_notes() {}
1 change: 1 addition & 0 deletions crates/processing_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ tracing = "0.1"
tracing-subscriber = "0.3"
half = "2.7"
crossbeam-channel = "0.5"
processing_midi = { workspace = true }

[target.'cfg(target_os = "macos")'.dependencies]
objc2 = { version = "0.6", default-features = false }
Expand Down
7 changes: 4 additions & 3 deletions crates/processing_render/src/geometry/attribute.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::ops::Range;

use bevy::{
asset::AssetMut,
mesh::{Indices, MeshVertexAttribute, VertexAttributeValues},
prelude::*,
render::render_resource::VertexFormat,
Expand Down Expand Up @@ -31,7 +32,7 @@ fn get_mesh_mut<'a>(
entity: Entity,
geometries: &Query<&Geometry>,
meshes: &'a mut Assets<Mesh>,
) -> Result<&'a mut Mesh> {
) -> Result<AssetMut<'a, Mesh>> {
let geometry = geometries
.get(entity)
.map_err(|_| ProcessingError::GeometryNotFound)?;
Expand Down Expand Up @@ -89,7 +90,7 @@ macro_rules! impl_setter {
geometries: Query<&Geometry>,
mut meshes: ResMut<Assets<Mesh>>,
) -> Result<()> {
let mesh = get_mesh_mut(entity, &geometries, &mut meshes)?;
let mut mesh = get_mesh_mut(entity, &geometries, &mut meshes)?;
match mesh.attribute_mut($attr) {
Some(VertexAttributeValues::$variant(data)) => {
let idx = index as usize;
Expand Down Expand Up @@ -335,7 +336,7 @@ pub fn set_attribute(
geometries: Query<&Geometry>,
mut meshes: ResMut<Assets<Mesh>>,
) -> Result<()> {
let mesh = get_mesh_mut(entity, &geometries, &mut meshes)?;
let mut mesh = get_mesh_mut(entity, &geometries, &mut meshes)?;
let idx = index as usize;

let attr = mesh.attribute_mut(attribute_id).ok_or_else(|| {
Expand Down
4 changes: 2 additions & 2 deletions crates/processing_render/src/geometry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ pub fn vertex(
.get(geometry.layout)
.map_err(|_| ProcessingError::LayoutNotFound)?;

let mesh = meshes
let mut mesh = meshes
.get_mut(&geometry.handle)
.ok_or(ProcessingError::GeometryNotFound)?;

Expand Down Expand Up @@ -323,7 +323,7 @@ pub fn index(
.get(entity)
.map_err(|_| ProcessingError::GeometryNotFound)?;

let mesh = meshes
let mut mesh = meshes
.get_mut(&geometry.handle)
.ok_or(ProcessingError::GeometryNotFound)?;

Expand Down
19 changes: 13 additions & 6 deletions crates/processing_render/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! configured to render to a specific surface (either a window or an offscreen image).
use bevy::{
camera::{
CameraMainTextureUsages, CameraOutputMode, CameraProjection, ClearColorConfig,
CameraMainTextureUsages, CameraOutputMode, CameraProjection, ClearColorConfig, Hdr,
ImageRenderTarget, MsaaWriteback, Projection, RenderTarget, visibility::RenderLayers,
},
core_pipeline::tonemapping::Tonemapping,
Expand All @@ -20,7 +20,7 @@ use bevy::{
},
renderer::{RenderDevice, RenderQueue},
sync_world::MainEntity,
view::{Hdr, ViewTarget, prepare_view_targets},
view::{ViewTarget, prepare_view_targets},
},
window::WindowRef,
};
Expand Down Expand Up @@ -52,7 +52,7 @@ impl Plugin for GraphicsPlugin {
.add_systems(
Render,
send_view_targets
.in_set(RenderSystems::ManageViews)
.in_set(RenderSystems::PrepareViews)
.after(prepare_view_targets),
)
.insert_resource(GraphicsTargetSender(tx));
Expand Down Expand Up @@ -220,14 +220,14 @@ pub fn create(
.spawn((
Camera3d::default(),
Camera {
target,
// always load the previous frame (provides sketch like behavior)
clear_color: ClearColorConfig::None,
// TODO: toggle this conditionally based on whether we need to write back MSAA
// when doing manual pixel udpates
msaa_writeback: MsaaWriteback::Always,
..default()
},
target,
// default to floating point texture format
Hdr,
// tonemapping prevents color accurate readback, so we disable it
Expand All @@ -243,7 +243,7 @@ pub fn create(
Transform::from_xyz(0.0, 0.0, 999.9),
render_layer,
CommandBuffer::new(),
RenderState::new(),
RenderState::default(),
SurfaceSize(width, height),
Graphics {
readback_buffer,
Expand Down Expand Up @@ -294,6 +294,10 @@ pub fn mode_3d(
let near = camera_z / 10.0;
let far = camera_z * 10.0;

// TODO: Setting this as a default, but we need to think about API around
// a user defined value
let near_clip_plane = vec4(0.0, 0.0, -1.0, -near);
Comment on lines +297 to +299
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'm putting value here for now. But after this gets merged, we'll need an issue to create intentional API around near_clip_plane. We want to support portals :P


let mut projection = projections
.get_mut(entity)
.map_err(|_| ProcessingError::GraphicsNotFound)?;
Expand All @@ -303,6 +307,7 @@ pub fn mode_3d(
aspect_ratio: aspect,
near,
far,
near_clip_plane,
});

let mut transform = transforms
Expand Down Expand Up @@ -352,6 +357,7 @@ pub fn perspective(
aspect_ratio,
near,
far,
near_clip_plane,
},
)): In<(Entity, PerspectiveProjection)>,
mut projections: Query<&mut Projection>,
Expand All @@ -365,6 +371,7 @@ pub fn perspective(
aspect_ratio,
near,
far,
near_clip_plane,
});

Ok(())
Expand Down Expand Up @@ -527,7 +534,7 @@ pub fn readback(
});

render_device
.poll(PollType::Wait)
.poll(PollType::wait_indefinitely())
.expect("Failed to poll device for map async");

r.recv().expect("Failed to receive the map_async message");
Expand Down
4 changes: 2 additions & 2 deletions crates/processing_render/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,14 +255,14 @@ pub fn readback(
});

render_device
.poll(PollType::Wait)
.poll(PollType::wait_indefinitely())
.expect("Failed to poll device for map async");

r.recv().expect("Failed to receive the map_async message");

let data = buffer_slice.get_mapped_range().to_vec();

let image = images
let mut image = images
.get_mut(&p_image.handle)
.ok_or(ProcessingError::ImageNotFound)?;
image.data = Some(data.clone());
Expand Down
5 changes: 5 additions & 0 deletions crates/processing_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ use crate::{
surface::SurfacePlugin,
};

use processing_midi::MidiPlugin;

static IS_INIT: OnceLock<()> = OnceLock::new();

thread_local! {
Expand Down Expand Up @@ -267,6 +269,7 @@ fn create_app(config: Config) -> App {
geometry::GeometryPlugin,
LightPlugin,
material::MaterialPlugin,
MidiPlugin,
));
app.add_systems(First, (clear_transient_meshes, activate_cameras))
.add_systems(
Expand Down Expand Up @@ -514,6 +517,7 @@ pub fn graphics_perspective(
aspect_ratio: f32,
near: f32,
far: f32,
near_clip_plane: Vec4,
) -> error::Result<()> {
app_mut(|app| {
flush(app, graphics_entity)?;
Expand All @@ -527,6 +531,7 @@ pub fn graphics_perspective(
aspect_ratio,
near,
far,
near_clip_plane,
},
),
)
Expand Down
4 changes: 2 additions & 2 deletions crates/processing_render/src/material/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ pub fn set_property(
.clone()
.try_typed::<StandardMaterial>()
.map_err(|_| ProcessingError::MaterialNotFound)?;
let standard = standard_materials
let mut standard = standard_materials
.get_mut(&handle)
.ok_or(ProcessingError::MaterialNotFound)?;
pbr::set_property(standard, &name, &value)?;
pbr::set_property(&mut standard, &name, &value)?;
Ok(())
}

Expand Down
1 change: 0 additions & 1 deletion crates/processing_render/src/material/pbr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use bevy::prelude::*;
use bevy::render::alpha::AlphaMode;

use super::MaterialValue;
use crate::error::{ProcessingError, Result};
Expand Down
2 changes: 1 addition & 1 deletion crates/processing_render/src/render/material.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::{prelude::*, render::alpha::AlphaMode};
use bevy::prelude::*;
use std::ops::Deref;

/// A component that holds an untyped handle to a material. This allows the main render loop
Expand Down
2 changes: 1 addition & 1 deletion crates/processing_render/src/sketch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub struct Sketch {
///
/// Currently supports `.py` files, but the loader is designed to be extended
/// for other languages in the future.
#[derive(Default)]
#[derive(Default, TypePath)]
pub struct SketchLoader;

impl AssetLoader for SketchLoader {
Expand Down
50 changes: 50 additions & 0 deletions examples/midi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
mod glfw;

use glfw::GlfwContext;
use processing::prelude::*;
use processing_render::render::command::DrawCommand;

fn main() {
match sketch() {
Ok(_) => {
eprintln!("Sketch completed successfully");
exit(0).unwrap();
}
Err(e) => {
eprintln!("Sketch error: {:?}", e);
exit(1).unwrap();
}
};
}

fn sketch() -> error::Result<()> {
let mut glfw_ctx = GlfwContext::new(400, 400)?;
init(Config::default())?;

let width = 400;
let height = 400;
let scale_factor = 1.0;

let surface = glfw_ctx.create_surface(width, height, scale_factor)?;
let graphics = graphics_create(surface, width, height)?;

processing_midi::connect(0);

while glfw_ctx.poll_events() {
graphics_begin_draw(graphics)?;

graphics_record_command(
graphics,
DrawCommand::Rect {
x: 10.0,
y: 10.0,
w: 100.0,
h: 100.0,
radii: [0.0, 0.0, 0.0, 0.0],
},
)?;

graphics_end_draw(graphics)?;
}
Ok(())
}
Loading