Skip to content

Commit

Permalink
Add custom material example.
Browse files Browse the repository at this point in the history
  • Loading branch information
tychedelia committed Jun 10, 2024
1 parent 267b655 commit 521b3a5
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 27 deletions.
24 changes: 15 additions & 9 deletions bevy_nannou_draw/src/draw/drawing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use lyon::tessellation::{FillOptions, LineCap, LineJoin, StrokeOptions};
use uuid::Uuid;

use crate::draw::primitive::Primitive;
use crate::draw::properties::material::SetMaterial;
use crate::draw::properties::{
SetColor, SetDimensions, SetFill, SetOrientation, SetPosition, SetStroke,
};
Expand Down Expand Up @@ -183,7 +182,7 @@ where

// Map the the parent's material to a new material type, taking ownership over the
// draw instance clone.
fn map_material<F>(mut self, map: F) -> Drawing<'a, T, M>
pub fn map_material<F>(mut self, map: F) -> Drawing<'a, T, M>
where
F: FnOnce(M) -> M,
{
Expand All @@ -198,6 +197,7 @@ where
.downcast_ref::<M>()
.unwrap()
.clone();

let new_id = UntypedAssetId::Uuid {
type_id: TypeId::of::<M>(),
uuid: Uuid::new_v4(),
Expand Down Expand Up @@ -837,7 +837,7 @@ where

impl<'a, T, M> Drawing<'a, T, M>
where
T: SetMaterial<M> + Into<Primitive> + Clone,
T: Into<Primitive> + Clone,
M: Material + Default,
Primitive: Into<Option<T>>,
{
Expand All @@ -849,13 +849,17 @@ where
M: MaterialExtension + Default,
{
pub fn roughness(mut self, roughness: f32) -> Self {
// self.draw.material.base.perceptual_roughness = roughness;
self
self.map_material(|mut material| {
material.base.perceptual_roughness = roughness;
material
})
}

pub fn metallic(mut self, metallic: f32) -> Self {
// self.draw.material.base.metallic = metallic;
self
self.map_material(|mut material| {
material.base.metallic = metallic;
material
})
}

pub fn base_color(mut self, color: Color) -> Self {
Expand All @@ -866,7 +870,9 @@ where
}

pub fn emissive(mut self, color: Color) -> Self {
// self.draw.material.base.emissive = color;
self
self.map_material(|mut material| {
material.base.emissive = color.linear();
material
})
}
}
8 changes: 1 addition & 7 deletions bevy_nannou_draw/src/draw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ where
type_id: TypeId::of::<M2>(),
uuid: Uuid::new_v4(),
};

state
.write()
.unwrap()
Expand Down Expand Up @@ -644,13 +645,6 @@ where
/// Drain any remaining `drawing`s and convert them to draw commands.
pub fn finish_remaining_drawings(&self) {
let mut state = self.state.write().unwrap();
let id = &self.material;
if state.last_material.as_ref() != Some(id) {
state
.draw_commands
.push(Some(DrawCommand::Material(id.clone())));
state.last_material = Some(id.clone());
}
state.finish_remaining_drawings()
}
}
Expand Down
8 changes: 0 additions & 8 deletions bevy_nannou_draw/src/draw/properties/material.rs

This file was deleted.

1 change: 0 additions & 1 deletion bevy_nannou_draw/src/draw/properties/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ pub use self::stroke::SetStroke;

pub mod color;
pub mod fill;
pub mod material;
pub mod spatial;
pub mod stroke;
4 changes: 4 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ path = "draw/draw_blend.rs"
name = "draw_capture"
path = "draw/draw_capture.rs"
[[example]]
name = "draw_custom_material"
path = "draw/draw_custom_material.rs"
required-features = ["nannou/hot_reload"]
[[example]]
name = "draw_fragment_shader"
path = "draw/draw_fragment_shader.rs"
required-features = ["nannou/nightly", "nannou/hot_reload"]
Expand Down
14 changes: 14 additions & 0 deletions examples/assets/draw_custom_material.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#import bevy_pbr::forward_io::VertexOutput

struct CustomMaterial {
color: vec4<f32>,
};

@group(2) @binding(0) var<uniform> material: CustomMaterial;

@fragment
fn fragment(
mesh: VertexOutput,
) -> @location(0) vec4<f32> {
return material.color;
}
50 changes: 50 additions & 0 deletions examples/draw/draw_custom_material.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use nannou::prelude::*;
use nannou::prelude::primitive::Primitive;

fn main() {
nannou::app(model)
.simple_window(view)
// Register our custom material to make it available for use in our drawing
.init_custom_material::<CustomMaterial>()
.run()
}

struct Model {}

// This struct defines the data that will be passed to your shader
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone, Default)]
struct CustomMaterial {
#[uniform(0)]
color: LinearRgba,
}

impl Material for CustomMaterial {
fn fragment_shader() -> ShaderRef {
"draw_custom_material.wgsl".into()
}
}


fn model(app: &App) -> Model {
Model {}
}

fn view(app: &App, model: &Model, window: Entity) {
// Begin drawing
let draw = app.draw()
// Initialize our draw instance with our custom material
.material(CustomMaterial {
color: RED.into(),
});

draw.ellipse()
.x(-200.0);

// We can also map the material manually
draw.ellipse()
.map_material(|mut mat| {
mat.color = BLUE.into();
mat
})
.x(200.0);
}
4 changes: 2 additions & 2 deletions examples/draw/draw_fragment_shader.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use nannou::prelude::*;

struct Model {}

fn main() {
nannou::app(model)
.simple_window(view)
Expand All @@ -11,6 +9,8 @@ fn main() {
.run()
}

struct Model {}

fn model(app: &App) -> Model {
Model {}
}
Expand Down
10 changes: 10 additions & 0 deletions nannou/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! - [**LoopMode**](./enum.LoopMode.html) - describes the behaviour of the application event loop.
use std::any::Any;
use std::cell::RefCell;
use std::hash::Hash;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::atomic::{AtomicUsize, Ordering};
Expand Down Expand Up @@ -283,6 +284,15 @@ where
self
}

pub fn init_custom_material<T>(mut self) -> Self
where
T: Material + Default,
T::Data: PartialEq + Eq + Hash + Clone,
{
self.app.add_plugins(NannouMaterialPlugin::<T>::default());
self
}

/// Load a fragment shader asset from the given path for use with the nannou `Draw` API.
#[cfg(feature = "nightly")]
pub fn init_fragment_shader<const SHADER: &'static str>(mut self) -> Self {
Expand Down
2 changes: 2 additions & 0 deletions nannou/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub use crate::io::{load_from_json, load_from_toml, safe_file_save, save_to_json
pub use crate::time::DurationF64;
pub use bevy::ecs as bevy_ecs;
pub use bevy::reflect as bevy_reflect;
pub use bevy::render as bevy_render;
pub use bevy::asset as bevy_asset;
pub use bevy_nannou::prelude::*;
pub use nannou_core::prelude::*;
#[cfg(feature = "egui")]
Expand Down

0 comments on commit 521b3a5

Please sign in to comment.