wireframe_2d/
wireframe_2d.rs

1//! Showcases wireframe rendering for 2d meshes.
2//!
3//! Wireframes currently do not work when using webgl or webgpu.
4//! Supported platforms:
5//! - DX12
6//! - Vulkan
7//! - Metal
8//!
9//! This is a native only feature.
10
11use bevy::{
12    color::palettes::basic::{GREEN, RED, WHITE},
13    prelude::*,
14    render::{
15        render_resource::WgpuFeatures,
16        settings::{RenderCreation, WgpuSettings},
17        RenderPlugin,
18    },
19    sprite_render::{
20        NoWireframe2d, Wireframe2d, Wireframe2dColor, Wireframe2dConfig, Wireframe2dPlugin,
21    },
22};
23
24fn main() {
25    App::new()
26        .add_plugins((
27            DefaultPlugins.set(RenderPlugin {
28                render_creation: RenderCreation::Automatic(WgpuSettings {
29                    // WARN this is a native only feature. It will not work with webgl or webgpu
30                    features: WgpuFeatures::POLYGON_MODE_LINE,
31                    ..default()
32                }),
33                ..default()
34            }),
35            // You need to add this plugin to enable wireframe rendering
36            Wireframe2dPlugin::default(),
37        ))
38        // Wireframes can be configured with this resource. This can be changed at runtime.
39        .insert_resource(Wireframe2dConfig {
40            // The global wireframe config enables drawing of wireframes on every mesh,
41            // except those with `NoWireframe2d`. Meshes with `Wireframe2d` will always have a wireframe,
42            // regardless of the global configuration.
43            global: true,
44            // Controls the default color of all wireframes. Used as the default color for global wireframes.
45            // Can be changed per mesh using the `Wireframe2dColor` component.
46            default_color: WHITE.into(),
47        })
48        .add_systems(Startup, setup)
49        .add_systems(Update, update_colors)
50        .run();
51}
52
53/// Set up a simple 3D scene
54fn setup(
55    mut commands: Commands,
56    mut meshes: ResMut<Assets<Mesh>>,
57    mut materials: ResMut<Assets<ColorMaterial>>,
58) {
59    // Triangle: Never renders a wireframe
60    commands.spawn((
61        Mesh2d(meshes.add(Triangle2d::new(
62            Vec2::new(0.0, 50.0),
63            Vec2::new(-50.0, -50.0),
64            Vec2::new(50.0, -50.0),
65        ))),
66        MeshMaterial2d(materials.add(Color::BLACK)),
67        Transform::from_xyz(-150.0, 0.0, 0.0),
68        NoWireframe2d,
69    ));
70    // Rectangle: Follows global wireframe setting
71    commands.spawn((
72        Mesh2d(meshes.add(Rectangle::new(100.0, 100.0))),
73        MeshMaterial2d(materials.add(Color::BLACK)),
74        Transform::from_xyz(0.0, 0.0, 0.0),
75    ));
76    // Circle: Always renders a wireframe
77    commands.spawn((
78        Mesh2d(meshes.add(Circle::new(50.0))),
79        MeshMaterial2d(materials.add(Color::BLACK)),
80        Transform::from_xyz(150.0, 0.0, 0.0),
81        Wireframe2d,
82        // This lets you configure the wireframe color of this entity.
83        // If not set, this will use the color in `WireframeConfig`
84        Wireframe2dColor {
85            color: GREEN.into(),
86        },
87    ));
88
89    commands.spawn(Camera2d);
90
91    // Text used to show controls
92    commands.spawn((
93        Text::default(),
94        Node {
95            position_type: PositionType::Absolute,
96            top: px(12),
97            left: px(12),
98            ..default()
99        },
100    ));
101}
102
103/// This system lets you toggle various wireframe settings
104fn update_colors(
105    keyboard_input: Res<ButtonInput<KeyCode>>,
106    mut config: ResMut<Wireframe2dConfig>,
107    mut wireframe_colors: Query<&mut Wireframe2dColor>,
108    mut text: Single<&mut Text>,
109) {
110    text.0 = format!(
111        "Controls
112---------------
113Z - Toggle global
114X - Change global color
115C - Change color of the circle wireframe
116
117Wireframe2dConfig
118-------------
119Global: {}
120Color: {:?}",
121        config.global,
122        config.default_color.to_srgba(),
123    );
124
125    // Toggle showing a wireframe on all meshes
126    if keyboard_input.just_pressed(KeyCode::KeyZ) {
127        config.global = !config.global;
128    }
129
130    // Toggle the global wireframe color
131    if keyboard_input.just_pressed(KeyCode::KeyX) {
132        config.default_color = if config.default_color == WHITE.into() {
133            RED.into()
134        } else {
135            WHITE.into()
136        };
137    }
138
139    // Toggle the color of a wireframe using `Wireframe2dColor` and not the global color
140    if keyboard_input.just_pressed(KeyCode::KeyC) {
141        for mut color in &mut wireframe_colors {
142            color.color = if color.color == GREEN.into() {
143                RED.into()
144            } else {
145                GREEN.into()
146            };
147        }
148    }
149}