Skip to main content

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