Skip to content

Commit

Permalink
Update to Bevy 0.8 (#111)
Browse files Browse the repository at this point in the history
* update to work with bevy main

* update to latest bevy main

* Refactor the side_panel example, fix linters

* dont run EguiNode when there is no window

* add bevy_asset feature as it is now optional

* Update to the released version

Co-authored-by: mvlabat <mvlabat@gmail.com>
  • Loading branch information
DGriffin91 and mvlabat committed Jul 30, 2022
1 parent 022ebd1 commit 66bbed3
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 78 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ manage_clipboard = ["arboard", "thread_local"]
open_url = ["webbrowser"]

[dependencies]
bevy = { version = "0.7", default-features = false, features = ["bevy_render", "bevy_core_pipeline"] }
bevy = { version = "0.8", default-features = false, features = ["bevy_render", "bevy_core_pipeline", "bevy_asset"] }
egui = { version = "0.18", features = ["bytemuck"] }
webbrowser = { version = "0.7", optional = true }

Expand All @@ -31,7 +31,7 @@ thread_local = { version = "1.1.0", optional = true }
[dev-dependencies]
once_cell = "1.9.0"
version-sync = "0.9.2"
bevy = { version = "0.7", default-features = false, features = [
bevy = { version = "0.8", default-features = false, features = [
"x11",
"png",
"bevy_pbr",
Expand Down
11 changes: 7 additions & 4 deletions examples/side_panel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::{prelude::*, window::PresentMode, winit::WinitSettings};
use bevy::{prelude::*, render::camera::Projection, window::PresentMode, winit::WinitSettings};
use bevy_egui::{egui, EguiContext, EguiPlugin};

#[derive(Default)]
Expand Down Expand Up @@ -99,7 +99,7 @@ fn setup_system(
Transform::from_translation(camera_pos).looking_at(CAMERA_TARGET, Vec3::Y);
commands.insert_resource(OriginalCameraTransform(camera_transform));

commands.spawn_bundle(PerspectiveCameraBundle {
commands.spawn_bundle(Camera3dBundle {
transform: camera_transform,
..Default::default()
});
Expand All @@ -109,9 +109,12 @@ fn update_camera_transform_system(
occupied_screen_space: Res<OccupiedScreenSpace>,
original_camera_transform: Res<OriginalCameraTransform>,
windows: Res<Windows>,
mut camera_query: Query<(&PerspectiveProjection, &mut Transform)>,
mut camera_query: Query<(&Projection, &mut Transform)>,
) {
let (camera_projection, mut transform) = camera_query.get_single_mut().unwrap();
let (camera_projection, mut transform) = match camera_query.get_single_mut() {
Ok((Projection::Perspective(projection), transform)) => (projection, transform),
_ => unreachable!(),
};

let distance_to_target = (CAMERA_TARGET - original_camera_transform.0.translation).length();
let frustum_height = 2.0 * distance_to_target * (camera_projection.fov * 0.5).tan();
Expand Down
11 changes: 2 additions & 9 deletions examples/two_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use bevy::{
prelude::*,
render::{camera::RenderTarget, render_graph::RenderGraph, RenderApp},
window::{CreateWindow, PresentMode, WindowId},
winit::WinitSettings,
};
use bevy_egui::{EguiContext, EguiPlugin};
use once_cell::sync::Lazy;
Expand All @@ -16,12 +15,6 @@ struct Images {
fn main() {
let mut app = App::new();
app.add_plugins(DefaultPlugins)
// Optimal power saving and present mode settings for desktop apps.
.insert_resource(WinitSettings::desktop_app())
.insert_resource(WindowDescriptor {
present_mode: PresentMode::Mailbox,
..Default::default()
})
.add_plugin(EguiPlugin)
.init_resource::<SharedUiState>()
.add_startup_system(load_assets)
Expand Down Expand Up @@ -52,13 +45,13 @@ fn create_new_window(mut create_window_events: EventWriter<CreateWindow>, mut co
descriptor: WindowDescriptor {
width: 800.,
height: 600.,
present_mode: PresentMode::Mailbox,
present_mode: PresentMode::AutoVsync,
title: "Second window".to_string(),
..Default::default()
},
});
// second window camera
commands.spawn_bundle(PerspectiveCameraBundle {
commands.spawn_bundle(Camera3dBundle {
camera: Camera {
target: RenderTarget::Window(*SECOND_WINDOW_ID),
..Default::default()
Expand Down
8 changes: 1 addition & 7 deletions examples/ui.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::{prelude::*, window::PresentMode, winit::WinitSettings};
use bevy::prelude::*;
use bevy_egui::{egui, EguiContext, EguiPlugin, EguiSettings};

struct Images {
Expand All @@ -24,12 +24,6 @@ fn main() {
App::new()
.insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
.insert_resource(Msaa { samples: 4 })
// Optimal power saving and present mode settings for desktop apps.
.insert_resource(WinitSettings::desktop_app())
.insert_resource(WindowDescriptor {
present_mode: PresentMode::Mailbox,
..Default::default()
})
.init_resource::<UiState>()
.add_plugins(DefaultPlugins)
.add_plugin(EguiPlugin)
Expand Down
34 changes: 17 additions & 17 deletions src/egui.wgsl
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
struct Transform {
scale: vec2<f32>;
translation: vec2<f32>;
};
scale: vec2<f32>,
translation: vec2<f32>,
}

struct VertexInput {
[[location(0)]] position: vec2<f32>;
[[location(1)]] uv: vec2<f32>;
[[location(2)]] color: vec4<f32>;
};
@location(0) position: vec2<f32>,
@location(1) uv: vec2<f32>,
@location(2) color: vec4<f32>,
}

struct VertexOutput {
[[builtin(position)]] position: vec4<f32>;
[[location(0)]] color: vec4<f32>;
[[location(1)]] uv: vec2<f32>;
};
@builtin(position) position: vec4<f32>,
@location(0) color: vec4<f32>,
@location(1) uv: vec2<f32>,
}

[[group(0), binding(0)]] var<uniform> transform: Transform;
[[group(1), binding(0)]] var image_texture: texture_2d<f32>;
[[group(1), binding(1)]] var image_sampler: sampler;
@group(0) @binding(0) var<uniform> transform: Transform;
@group(1) @binding(0) var image_texture: texture_2d<f32>;
@group(1) @binding(1) var image_sampler: sampler;

fn linear_from_srgb(srgb: vec3<f32>) -> vec3<f32> {
let cutoff = srgb < vec3<f32>(0.04045);
Expand All @@ -26,15 +26,15 @@ fn linear_from_srgb(srgb: vec3<f32>) -> vec3<f32> {
return select(higher, lower, cutoff);
}

[[stage(vertex)]]
@vertex
fn vs_main(in: VertexInput) -> VertexOutput {
let position = in.position * transform.scale + transform.translation;
let color = vec4<f32>(linear_from_srgb(in.color.rgb), in.color.a);
return VertexOutput(vec4<f32>(position, 0.0, 1.0), color, in.uv);
}

[[stage(fragment)]]
fn fs_main(in: VertexOutput) -> [[location(0)]] vec4<f32> {
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
let texture_color = textureSample(image_texture, image_sampler, in.uv);
// This assumes that texture images are not premultiplied.
let color = in.color * vec4<f32>(texture_color.rgb * texture_color.a, texture_color.a);
Expand Down
38 changes: 22 additions & 16 deletions src/egui_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use bevy::{
render::{
render_graph::{Node, NodeRunError, RenderGraphContext},
render_resource::{
std140::AsStd140, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
BindingType, BlendComponent, BlendFactor, BlendOperation, BlendState, Buffer,
BufferAddress, BufferBindingType, BufferDescriptor, BufferSize, BufferUsages,
ColorTargetState, ColorWrites, Extent3d, FrontFace, IndexFormat, LoadOp,
MultisampleState, Operations, PipelineLayoutDescriptor, PrimitiveState,
RawFragmentState, RawRenderPipelineDescriptor, RawVertexBufferLayout, RawVertexState,
BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType,
BlendComponent, BlendFactor, BlendOperation, BlendState, Buffer, BufferAddress,
BufferBindingType, BufferDescriptor, BufferUsages, ColorTargetState, ColorWrites,
Extent3d, FrontFace, IndexFormat, LoadOp, MultisampleState, Operations,
PipelineLayoutDescriptor, PrimitiveState, RawFragmentState,
RawRenderPipelineDescriptor, RawVertexBufferLayout, RawVertexState,
RenderPassColorAttachment, RenderPassDescriptor, RenderPipeline, SamplerBindingType,
ShaderModuleDescriptor, ShaderSource, ShaderStages, TextureDimension, TextureFormat,
TextureSampleType, TextureViewDimension, VertexAttribute, VertexFormat, VertexStepMode,
Expand All @@ -21,6 +21,8 @@ use bevy::{
window::WindowId,
};

use bevy::render::render_resource::ShaderType;

use crate::render_systems::{
EguiTexture, EguiTextureBindGroups, EguiTransform, EguiTransforms, ExtractedEguiContext,
ExtractedEguiSettings, ExtractedRenderOutput, ExtractedWindowSizes,
Expand All @@ -38,7 +40,7 @@ impl FromWorld for EguiPipeline {
let render_device = world.get_resource::<RenderDevice>().unwrap();

let shader_source = ShaderSource::Wgsl(include_str!("egui.wgsl").into());
let shader_module = render_device.create_shader_module(&ShaderModuleDescriptor {
let shader_module = render_device.create_shader_module(ShaderModuleDescriptor {
label: Some("egui shader"),
source: shader_source,
});
Expand All @@ -52,9 +54,7 @@ impl FromWorld for EguiPipeline {
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: true,
min_binding_size: Some(
BufferSize::new(EguiTransform::std140_size_static() as u64).unwrap(),
),
min_binding_size: Some(EguiTransform::min_size()),
},
count: None,
}],
Expand Down Expand Up @@ -119,7 +119,7 @@ impl FromWorld for EguiPipeline {
fragment: Some(RawFragmentState {
module: &shader_module,
entry_point: "fs_main",
targets: &[ColorTargetState {
targets: &[Some(ColorTargetState {
format: TextureFormat::bevy_default(),
blend: Some(BlendState {
color: BlendComponent {
Expand All @@ -134,7 +134,7 @@ impl FromWorld for EguiPipeline {
},
}),
write_mask: ColorWrites::ALL,
}],
})],
}),
primitive: PrimitiveState {
front_face: FrontFace::Cw,
Expand Down Expand Up @@ -306,6 +306,14 @@ impl Node for EguiNode {
render_context: &mut RenderContext,
world: &World,
) -> Result<(), NodeRunError> {
let extracted_windows = &world.get_resource::<ExtractedWindows>().unwrap().windows;
let extracted_window =
if let Some(extracted_window) = extracted_windows.get(&self.window_id) {
extracted_window
} else {
return Ok(()); // No window
};

let egui_shaders = world.get_resource::<EguiPipeline>().unwrap();
let render_queue = world.get_resource::<RenderQueue>().unwrap();

Expand All @@ -324,23 +332,21 @@ impl Node for EguiNode {

let egui_transforms = world.get_resource::<EguiTransforms>().unwrap();

let extracted_window =
&world.get_resource::<ExtractedWindows>().unwrap().windows[&self.window_id];
let swap_chain_texture = extracted_window.swap_chain_texture.as_ref().unwrap();

let mut render_pass =
render_context
.command_encoder
.begin_render_pass(&RenderPassDescriptor {
label: Some("egui render pass"),
color_attachments: &[RenderPassColorAttachment {
color_attachments: &[Some(RenderPassColorAttachment {
view: swap_chain_texture,
resolve_target: None,
ops: Operations {
load: LoadOp::Load,
store: true,
},
}],
})],
depth_stencil_attachment: None,
});

Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ impl Plugin for EguiPlugin {
.add_system_to_stage(RenderStage::Queue, render_systems::queue_bind_groups);

let mut render_graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap();
setup_pipeline(&mut *render_graph, RenderGraphConfig::default());
setup_pipeline(&mut render_graph, RenderGraphConfig::default());
}
}
}
Expand Down Expand Up @@ -604,7 +604,7 @@ pub fn setup_pipeline(render_graph: &mut RenderGraph, config: RenderGraphConfig)

render_graph
.add_node_edge(
bevy::core_pipeline::node::MAIN_PASS_DRIVER,
bevy::render::main_graph::node::CAMERA_DRIVER,
config.egui_pass,
)
.unwrap();
Expand Down
27 changes: 14 additions & 13 deletions src/render_systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ use bevy::{
render::{
render_asset::RenderAssets,
render_resource::{
std140::AsStd140, BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource,
BufferId, DynamicUniformVec,
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferId,
DynamicUniformBuffer, ShaderType,
},
renderer::{RenderDevice, RenderQueue},
texture::Image,
Extract,
},
utils::HashMap,
window::WindowId,
Expand Down Expand Up @@ -53,22 +54,21 @@ impl ExtractedEguiTextures {

pub(crate) fn extract_egui_render_data(
mut commands: Commands,
mut egui_render_output: ResMut<HashMap<WindowId, EguiRenderOutput>>,
window_sizes: ResMut<HashMap<WindowId, WindowSize>>,
egui_settings: Res<EguiSettings>,
egui_context: Res<EguiContext>,
egui_render_output: Extract<Res<HashMap<WindowId, EguiRenderOutput>>>,
window_sizes: Extract<Res<HashMap<WindowId, WindowSize>>>,
egui_settings: Extract<Res<EguiSettings>>,
egui_context: Extract<Res<EguiContext>>,
) {
let render_output = std::mem::take(&mut *egui_render_output);
commands.insert_resource(ExtractedRenderOutput(render_output));
commands.insert_resource(ExtractedRenderOutput(egui_render_output.clone()));
commands.insert_resource(ExtractedEguiSettings(egui_settings.clone()));
commands.insert_resource(ExtractedEguiContext(egui_context.ctx.clone()));
commands.insert_resource(ExtractedWindowSizes(window_sizes.clone()));
}

pub(crate) fn extract_egui_textures(
mut commands: Commands,
egui_context: Res<EguiContext>,
egui_managed_textures: ResMut<EguiManagedTextures>,
egui_context: Extract<Res<EguiContext>>,
egui_managed_textures: Extract<Res<EguiManagedTextures>>,
) {
commands.insert_resource(ExtractedEguiTextures {
egui_textures: egui_managed_textures
Expand All @@ -84,16 +84,17 @@ pub(crate) fn extract_egui_textures(

#[derive(Default)]
pub(crate) struct EguiTransforms {
pub buffer: DynamicUniformVec<EguiTransform>,
pub buffer: DynamicUniformBuffer<EguiTransform>,
pub offsets: HashMap<WindowId, u32>,
pub bind_group: Option<(BufferId, BindGroup)>,
}

#[derive(AsStd140)]
#[derive(ShaderType, Default)]
pub(crate) struct EguiTransform {
scale: Vec2,
translation: Vec2,
}

impl EguiTransform {
fn new(window_size: WindowSize, egui_settings: &EguiSettings) -> Self {
EguiTransform {
Expand Down Expand Up @@ -130,7 +131,7 @@ pub(crate) fn prepare_egui_transforms(
.buffer
.write_buffer(&render_device, &render_queue);

if let Some(buffer) = egui_transforms.buffer.uniform_buffer() {
if let Some(buffer) = egui_transforms.buffer.buffer() {
match egui_transforms.bind_group {
Some((id, _)) if buffer.id() == id => {}
_ => {
Expand Down
Loading

0 comments on commit 66bbed3

Please sign in to comment.