@@ -12,7 +12,7 @@ use bevy::{
1212} ;
1313use command:: { CommandBuffer , DrawCommand } ;
1414use material:: MaterialKey ;
15- use primitive:: { TessellationMode , box_mesh, empty_mesh, sphere_mesh} ;
15+ use primitive:: { StrokeConfig , TessellationMode , box_mesh, empty_mesh, sphere_mesh} ;
1616use transform:: TransformStack ;
1717
1818use crate :: {
@@ -65,6 +65,7 @@ pub struct RenderState {
6565 pub fill_color : Option < Color > ,
6666 pub stroke_color : Option < Color > ,
6767 pub stroke_weight : f32 ,
68+ pub stroke_config : StrokeConfig ,
6869 pub material_key : MaterialKey ,
6970 pub transform : TransformStack ,
7071}
@@ -75,6 +76,7 @@ impl RenderState {
7576 fill_color : Some ( Color :: WHITE ) ,
7677 stroke_color : Some ( Color :: BLACK ) ,
7778 stroke_weight : 1.0 ,
79+ stroke_config : StrokeConfig :: default ( ) ,
7880 material_key : MaterialKey :: Color {
7981 transparent : false ,
8082 background_image : None ,
@@ -87,6 +89,7 @@ impl RenderState {
8789 self . fill_color = Some ( Color :: WHITE ) ;
8890 self . stroke_color = Some ( Color :: BLACK ) ;
8991 self . stroke_weight = 1.0 ;
92+ self . stroke_config = StrokeConfig :: default ( ) ;
9093 self . material_key = MaterialKey :: Color {
9194 transparent : false ,
9295 background_image : None ,
@@ -152,6 +155,12 @@ pub fn flush_draw_commands(
152155 DrawCommand :: StrokeWeight ( weight) => {
153156 state. stroke_weight = weight;
154157 }
158+ DrawCommand :: StrokeCap ( cap) => {
159+ state. stroke_config . line_cap = cap;
160+ }
161+ DrawCommand :: StrokeJoin ( join) => {
162+ state. stroke_config . line_join = join;
163+ }
155164 DrawCommand :: Roughness ( r) => {
156165 state. material_key = match state. material_key {
157166 MaterialKey :: Pbr {
@@ -223,11 +232,24 @@ pub fn flush_draw_commands(
223232 } ;
224233 }
225234 DrawCommand :: Rect { x, y, w, h, radii } => {
235+ let stroke_config = state. stroke_config ;
226236 add_fill (
227237 & mut res,
228238 & mut batch,
229239 & state,
230- |mesh, color| rect ( mesh, x, y, w, h, radii, color, TessellationMode :: Fill ) ,
240+ |mesh, color| {
241+ rect (
242+ mesh,
243+ x,
244+ y,
245+ w,
246+ h,
247+ radii,
248+ color,
249+ TessellationMode :: Fill ,
250+ & stroke_config,
251+ )
252+ } ,
231253 & p_material_handles,
232254 ) ;
233255
@@ -245,6 +267,7 @@ pub fn flush_draw_commands(
245267 radii,
246268 color,
247269 TessellationMode :: Stroke ( weight) ,
270+ & stroke_config,
248271 )
249272 } ,
250273 & p_material_handles,
@@ -556,34 +579,68 @@ fn add_shape3d(
556579 mesh : Mesh ,
557580 material_handles : & Query < & UntypedMaterial > ,
558581) {
582+ use bevy:: pbr:: wireframe:: { Wireframe , WireframeColor , WireframeLineWidth , WireframeTopology } ;
583+
559584 flush_batch ( res, batch, material_handles) ;
560585
561586 let mesh_handle = res. meshes . add ( mesh) ;
562- let material_key = material_key_with_fill ( state) ;
563-
564- let material_handle = match & material_key {
587+ let fill_color = state. fill_color . unwrap_or ( Color :: WHITE ) ;
588+ let material_handle = match & state. material_key {
565589 MaterialKey :: Custom ( entity) => match material_handles. get ( * entity) {
566590 Ok ( handle) => handle. 0 . clone ( ) ,
567591 Err ( _) => {
568592 warn ! ( "Custom material entity {:?} not found" , entity) ;
569593 return ;
570594 }
571595 } ,
572- _ => material_key. to_material ( & mut res. materials ) ,
596+ // TODO: in 2d, we use vertex colors. `to_material` becomes complicated if we also encode
597+ // a base color in the material, so for simplicity we just create a new material here
598+ // that is unlit and uses the fill color as the base color
599+ MaterialKey :: Color { transparent, .. } => {
600+ let mat = StandardMaterial {
601+ base_color : fill_color,
602+ unlit : true ,
603+ cull_mode : None ,
604+ alpha_mode : if * transparent {
605+ AlphaMode :: Blend
606+ } else {
607+ AlphaMode :: Opaque
608+ } ,
609+ ..default ( )
610+ } ;
611+ res. materials . add ( mat) . untyped ( )
612+ }
613+ _ => {
614+ let key = material_key_with_fill ( state) ;
615+ key. to_material ( & mut res. materials )
616+ }
573617 } ;
574618
575619 let z_offset = -( batch. draw_index as f32 * 0.001 ) ;
576620 let mut transform = state. transform . to_bevy_transform ( ) ;
577621 transform. translation . z += z_offset;
578622
579- res. commands . spawn ( (
623+ let mut entity = res. commands . spawn ( (
580624 Mesh3d ( mesh_handle) ,
581625 UntypedMaterial ( material_handle) ,
582626 BelongsToGraphics ( batch. graphics_entity ) ,
583627 transform,
584628 batch. render_layers . clone ( ) ,
585629 ) ) ;
586630
631+ if let Some ( stroke_color) = state. stroke_color {
632+ entity. insert ( (
633+ Wireframe ,
634+ WireframeColor {
635+ color : stroke_color,
636+ } ,
637+ WireframeLineWidth {
638+ width : state. stroke_weight ,
639+ } ,
640+ WireframeTopology :: Quads ,
641+ ) ) ;
642+ }
643+
587644 batch. draw_index += 1 ;
588645}
589646
0 commit comments