1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! Showcases wireframe rendering for 2d meshes.
//!
//! Wireframes currently do not work when using webgl or webgpu.
//! Supported platforms:
//! - DX12
//! - Vulkan
//! - Metal
//!
//! This is a native only feature.

use bevy::{
    color::palettes::basic::{GREEN, RED, WHITE},
    prelude::*,
    render::{
        render_resource::WgpuFeatures,
        settings::{RenderCreation, WgpuSettings},
        RenderPlugin,
    },
    sprite::{
        MaterialMesh2dBundle, NoWireframe2d, Wireframe2d, Wireframe2dColor, Wireframe2dConfig,
        Wireframe2dPlugin,
    },
};

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins.set(RenderPlugin {
                render_creation: RenderCreation::Automatic(WgpuSettings {
                    // WARN this is a native only feature. It will not work with webgl or webgpu
                    features: WgpuFeatures::POLYGON_MODE_LINE,
                    ..default()
                }),
                ..default()
            }),
            // You need to add this plugin to enable wireframe rendering
            Wireframe2dPlugin,
        ))
        // Wireframes can be configured with this resource. This can be changed at runtime.
        .insert_resource(Wireframe2dConfig {
            // The global wireframe config enables drawing of wireframes on every mesh,
            // except those with `NoWireframe2d`. Meshes with `Wireframe2d` will always have a wireframe,
            // regardless of the global configuration.
            global: true,
            // Controls the default color of all wireframes. Used as the default color for global wireframes.
            // Can be changed per mesh using the `Wireframe2dColor` component.
            default_color: WHITE,
        })
        .add_systems(Startup, setup)
        .add_systems(Update, update_colors)
        .run();
}

/// Set up a simple 3D scene
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    // Triangle: Never renders a wireframe
    commands.spawn((
        MaterialMesh2dBundle {
            mesh: meshes
                .add(Triangle2d::new(
                    Vec2::new(0.0, 50.0),
                    Vec2::new(-50.0, -50.0),
                    Vec2::new(50.0, -50.0),
                ))
                .into(),
            material: materials.add(Color::BLACK),
            transform: Transform::from_xyz(-150.0, 0.0, 0.0),
            ..default()
        },
        NoWireframe2d,
    ));
    // Rectangle: Follows global wireframe setting
    commands.spawn(MaterialMesh2dBundle {
        mesh: meshes.add(Rectangle::new(100.0, 100.0)).into(),
        material: materials.add(Color::BLACK),
        transform: Transform::from_xyz(0.0, 0.0, 0.0),
        ..default()
    });
    // Circle: Always renders a wireframe
    commands.spawn((
        MaterialMesh2dBundle {
            mesh: meshes.add(Circle::new(50.0)).into(),
            material: materials.add(Color::BLACK),
            transform: Transform::from_xyz(150.0, 0.0, 0.0),
            ..default()
        },
        Wireframe2d,
        // This lets you configure the wireframe color of this entity.
        // If not set, this will use the color in `WireframeConfig`
        Wireframe2dColor { color: GREEN },
    ));

    // Camera
    commands.spawn(Camera2dBundle::default());

    // Text used to show controls
    commands.spawn(
        TextBundle::from_section("", TextStyle::default()).with_style(Style {
            position_type: PositionType::Absolute,
            top: Val::Px(10.0),
            left: Val::Px(10.0),
            ..default()
        }),
    );
}

/// This system lets you toggle various wireframe settings
fn update_colors(
    keyboard_input: Res<ButtonInput<KeyCode>>,
    mut config: ResMut<Wireframe2dConfig>,
    mut wireframe_colors: Query<&mut Wireframe2dColor>,
    mut text: Query<&mut Text>,
) {
    text.single_mut().sections[0].value = format!(
        "
Controls
---------------
Z - Toggle global
X - Change global color
C - Change color of the circle wireframe

Wireframe2dConfig
-------------
Global: {}
Color: {:?}
",
        config.global, config.default_color,
    );

    // Toggle showing a wireframe on all meshes
    if keyboard_input.just_pressed(KeyCode::KeyZ) {
        config.global = !config.global;
    }

    // Toggle the global wireframe color
    if keyboard_input.just_pressed(KeyCode::KeyX) {
        config.default_color = if config.default_color == WHITE {
            RED
        } else {
            WHITE
        };
    }

    // Toggle the color of a wireframe using `Wireframe2dColor` and not the global color
    if keyboard_input.just_pressed(KeyCode::KeyC) {
        for mut color in &mut wireframe_colors {
            color.color = if color.color == GREEN { RED } else { GREEN };
        }
    }
}