halfway through imgui, the context is really not ergonomic
This commit is contained in:
@@ -15,7 +15,7 @@ typed-arena = "2.0.1"
|
|||||||
serde = { version = "1", features = ["derive"], optional = true }
|
serde = { version = "1", features = ["derive"], optional = true }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
png = "0.16"
|
png = "0.16"
|
||||||
winit = { version = "0.22.1", features = ["web-sys"] }
|
winit = "0.24.0"
|
||||||
rand = { version = "0.7.2", features = ["wasm-bindgen"] }
|
rand = { version = "0.7.2", features = ["wasm-bindgen"] }
|
||||||
bytemuck = "1"
|
bytemuck = "1"
|
||||||
noise = "0.6"
|
noise = "0.6"
|
||||||
@@ -29,4 +29,7 @@ cgmath = "0.18.0"
|
|||||||
rapier3d = { version = "0.5.0", features = ["simd-nightly", "parallel"] }
|
rapier3d = { version = "0.5.0", features = ["simd-nightly", "parallel"] }
|
||||||
nalgebra = "0.24.1"
|
nalgebra = "0.24.1"
|
||||||
legion = "0.3.1"
|
legion = "0.3.1"
|
||||||
wgpu = "0.7.0"
|
wgpu = "0.7.0"
|
||||||
|
imgui = "0.7.0"
|
||||||
|
imgui-wgpu = "0.14.0"
|
||||||
|
imgui-winit-support = "0.7.0"
|
||||||
@@ -136,16 +136,14 @@ impl CameraController {
|
|||||||
|
|
||||||
pub fn update_camera(&mut self, camera: &mut Camera, dt: f32) {
|
pub fn update_camera(&mut self, camera: &mut Camera, dt: f32) {
|
||||||
// Move forward/backward and left/right
|
// Move forward/backward and left/right
|
||||||
let (yaw_sin, yaw_cos) = camera.yaw.0.sin_cos();
|
|
||||||
let forward = Vector3::new(yaw_cos, 0.0, yaw_sin).normalize();
|
|
||||||
let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize();
|
|
||||||
|
|
||||||
let view_vector = Vector3::new(
|
let view_vector = Vector3::new(
|
||||||
(1.0 * camera.pitch.0.sin() * camera.yaw.0.sin()),
|
(1.0 * camera.pitch.0.sin() * camera.yaw.0.sin()),
|
||||||
(1.0 * camera.pitch.0.cos()),
|
(1.0 * camera.pitch.0.cos()),
|
||||||
(1.0 * camera.pitch.0.sin() * camera.yaw.0.cos()),
|
(1.0 * camera.pitch.0.sin() * camera.yaw.0.cos()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Offset the yaw 90 degrees and set the pitch to level for our
|
||||||
|
// right / left hand translation vectors
|
||||||
let offset = camera.yaw.0 + PI/2.0;
|
let offset = camera.yaw.0 + PI/2.0;
|
||||||
let pitch = PI/2.0;
|
let pitch = PI/2.0;
|
||||||
let left_vector = Vector3::new(
|
let left_vector = Vector3::new(
|
||||||
@@ -156,19 +154,12 @@ impl CameraController {
|
|||||||
|
|
||||||
camera.position += view_vector * (self.amount_forward - self.amount_backward) * self.speed * dt;
|
camera.position += view_vector * (self.amount_forward - self.amount_backward) * self.speed * dt;
|
||||||
camera.position += left_vector * (self.amount_left - self.amount_right) * self.speed * dt;
|
camera.position += left_vector * (self.amount_left - self.amount_right) * self.speed * dt;
|
||||||
|
|
||||||
|
|
||||||
// Move up/down. Since we don't use roll, we can just
|
|
||||||
// modify the y coordinate directly.
|
|
||||||
camera.position.y += (self.amount_up - self.amount_down) * self.speed * dt;
|
camera.position.y += (self.amount_up - self.amount_down) * self.speed * dt;
|
||||||
|
|
||||||
// Rotate
|
// Rotate
|
||||||
camera.yaw += Rad(self.rotate_horizontal) * self.sensitivity * dt;
|
camera.yaw += Rad(self.rotate_horizontal) * self.sensitivity * dt;
|
||||||
camera.pitch += Rad(self.rotate_vertical) * self.sensitivity * dt;
|
camera.pitch += Rad(self.rotate_vertical) * self.sensitivity * dt;
|
||||||
|
|
||||||
// If process_mouse isn't called every frame, these values
|
|
||||||
// will not get set to zero, and the camera will rotate
|
|
||||||
// when moving in a non cardinal direction.
|
|
||||||
self.rotate_horizontal = 0.0;
|
self.rotate_horizontal = 0.0;
|
||||||
self.rotate_vertical = 0.0;
|
self.rotate_vertical = 0.0;
|
||||||
|
|
||||||
|
|||||||
@@ -61,17 +61,4 @@ pub fn import_mesh(mesh_path: &str) -> (Vec<Vertex>, Vec<u32>) {
|
|||||||
}
|
}
|
||||||
(vertex_data.to_vec(), index_data.to_vec())
|
(vertex_data.to_vec(), index_data.to_vec())
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_plane(size: f32) -> (Vec<Vertex>, Vec<u32>) {
|
|
||||||
let vertex_data = [
|
|
||||||
vertex([size, -size, 0.0], [0.0, 0.0, 1.0]),
|
|
||||||
vertex([size, size, 0.0], [0.0, 0.0, 1.0]),
|
|
||||||
vertex([-size, -size, 0.0], [0.0, 0.0, 1.0]),
|
|
||||||
vertex([-size, size, 0.0], [0.0, 0.0, 1.0]),
|
|
||||||
];
|
|
||||||
|
|
||||||
let index_data: &[u32] = &[0, 1, 2, 2, 1, 3];
|
|
||||||
|
|
||||||
(vertex_data.to_vec(), index_data.to_vec())
|
|
||||||
}
|
}
|
||||||
147
src/main.rs
147
src/main.rs
@@ -1,3 +1,6 @@
|
|||||||
|
extern crate imgui;
|
||||||
|
extern crate imgui_wgpu;
|
||||||
|
extern crate imgui_winit_support;
|
||||||
extern crate tobj;
|
extern crate tobj;
|
||||||
extern crate winit;
|
extern crate winit;
|
||||||
|
|
||||||
@@ -8,9 +11,17 @@ use std::sync::Arc;
|
|||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use bytemuck::__core::ops::Range;
|
use bytemuck::__core::ops::Range;
|
||||||
use cgmath::{Decomposed, Deg, Euler, InnerSpace, Quaternion, Rotation3, SquareMatrix, Point3, Rad};
|
use cgmath::{
|
||||||
|
Decomposed, Deg, Euler, InnerSpace, Point3, Quaternion, Rad, Rotation3, SquareMatrix,
|
||||||
|
};
|
||||||
|
use futures::executor::block_on;
|
||||||
use futures::task::LocalSpawn;
|
use futures::task::LocalSpawn;
|
||||||
|
use gilrs::{Gamepad, Gilrs};
|
||||||
|
use gilrs::Event as GilEvent;
|
||||||
|
use imgui::*;
|
||||||
|
use imgui_wgpu::{Renderer as ImguiRenderer, RendererConfig as ImguiRendererConfig};
|
||||||
use legion::*;
|
use legion::*;
|
||||||
|
use rapier3d::counters::Timer;
|
||||||
use rapier3d::dynamics::{
|
use rapier3d::dynamics::{
|
||||||
IntegrationParameters, JointSet, RigidBody, RigidBodyBuilder, RigidBodyHandle, RigidBodySet,
|
IntegrationParameters, JointSet, RigidBody, RigidBodyBuilder, RigidBodyHandle, RigidBodySet,
|
||||||
};
|
};
|
||||||
@@ -20,30 +31,27 @@ use rapier3d::na::{Isometry, Isometry3, Vector, Vector3};
|
|||||||
use rapier3d::pipeline::PhysicsPipeline;
|
use rapier3d::pipeline::PhysicsPipeline;
|
||||||
use wgpu::{BindGroup, Buffer, TextureView};
|
use wgpu::{BindGroup, Buffer, TextureView};
|
||||||
use wgpu_subscriber;
|
use wgpu_subscriber;
|
||||||
use winit::event::DeviceEvent::MouseMotion;
|
|
||||||
use winit::platform::unix::x11::ffi::Time;
|
|
||||||
use winit::{
|
use winit::{
|
||||||
event::{self, WindowEvent},
|
event::{self, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
};
|
};
|
||||||
|
use winit::event::DeviceEvent::MouseMotion;
|
||||||
|
use winit::platform::unix::x11::ffi::Time;
|
||||||
|
use winit::window::Window;
|
||||||
|
|
||||||
use gilrs::Event as GilEvent;
|
use crate::camera::{Camera, CameraController};
|
||||||
|
use crate::components::{Collider, Color, LoopState, Physics, Position};
|
||||||
use crate::camera::{CameraController, Camera};
|
use crate::owned_event::{OwnedEvent, OwnedEventExtension};
|
||||||
use crate::components::{Collider, Color, Physics, Position, LoopState};
|
|
||||||
use crate::physics::PhysicsState;
|
use crate::physics::PhysicsState;
|
||||||
use crate::render::Renderer;
|
use crate::render::Renderer;
|
||||||
use crate::owned_event::{OwnedEventExtension, OwnedEvent};
|
|
||||||
use gilrs::{Gamepad, Gilrs};
|
|
||||||
use rapier3d::counters::Timer;
|
|
||||||
|
|
||||||
mod camera;
|
mod camera;
|
||||||
mod components;
|
mod components;
|
||||||
mod geometry;
|
mod geometry;
|
||||||
mod light;
|
mod light;
|
||||||
|
mod owned_event;
|
||||||
mod physics;
|
mod physics;
|
||||||
mod render;
|
mod render;
|
||||||
mod owned_event;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@@ -104,38 +112,36 @@ fn main() {
|
|||||||
let mut builder = winit::window::WindowBuilder::new();
|
let mut builder = winit::window::WindowBuilder::new();
|
||||||
builder = builder.with_title("MVGE");
|
builder = builder.with_title("MVGE");
|
||||||
|
|
||||||
// I don't know what they are doing here
|
|
||||||
#[cfg(windows_OFF)] // TODO
|
|
||||||
{
|
|
||||||
use winit::platform::windows::WindowBuilderExtWindows;
|
|
||||||
builder = builder.with_no_redirection_bitmap(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
let window = builder.build(&event_loop).unwrap();
|
let window = builder.build(&event_loop).unwrap();
|
||||||
|
|
||||||
// Load up the renderer (and the resources)
|
|
||||||
let mut renderer = {
|
|
||||||
let mut renderer = render::Renderer::init(&window);
|
|
||||||
entity_loading(&mut world, &mut renderer);
|
|
||||||
renderer
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut resources = Resources::default();
|
let mut resources = Resources::default();
|
||||||
resources.insert(renderer);
|
|
||||||
|
|
||||||
let (physics_state, physics_pipeline) =
|
// Load up all the resources
|
||||||
PhysicsState::build(rapier3d::math::Vector::new(0.0, -9.81, 0.05));
|
{
|
||||||
resources.insert(physics_state);
|
|
||||||
resources.insert(physics_pipeline);
|
|
||||||
|
|
||||||
resources.insert(LoopState {
|
// The renderer
|
||||||
delta_time: Default::default(),
|
let mut renderer = render::Renderer::init(&window, &mut imgui_context);
|
||||||
start_time: Instant::now(),
|
entity_loading(&mut world, &mut renderer);
|
||||||
step_size: 0.01666, // 60hz
|
resources.insert(renderer);
|
||||||
});
|
resources.insert(window);
|
||||||
|
|
||||||
|
// Physics
|
||||||
|
let (physics_state, physics_pipeline) =
|
||||||
|
PhysicsState::build(rapier3d::math::Vector::new(0.0, -9.81, 0.05));
|
||||||
|
resources.insert(physics_state);
|
||||||
|
resources.insert(physics_pipeline);
|
||||||
|
|
||||||
resources.insert(Vec::<OwnedEvent<OwnedEventExtension>>::new());
|
// Loop data
|
||||||
|
resources.insert(LoopState {
|
||||||
|
delta_time: Default::default(),
|
||||||
|
start_time: Instant::now(),
|
||||||
|
step_size: 0.01666, // 60hz
|
||||||
|
});
|
||||||
|
|
||||||
|
// And our event stack
|
||||||
|
resources.insert(Vec::<OwnedEvent<OwnedEventExtension>>::new());
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
let event_loop_proxy = event_loop.create_proxy();
|
let event_loop_proxy = event_loop.create_proxy();
|
||||||
|
|
||||||
@@ -147,7 +153,12 @@ fn main() {
|
|||||||
if gamepad_.name() == "PS4" {
|
if gamepad_.name() == "PS4" {
|
||||||
gamepad = Some(gamepad_);
|
gamepad = Some(gamepad_);
|
||||||
}
|
}
|
||||||
println!("{} is {:?} {:?}", gamepad_.name(), gamepad_.power_info(), gamepad_.id());
|
println!(
|
||||||
|
"{} is {:?} {:?}",
|
||||||
|
gamepad_.name(),
|
||||||
|
gamepad_.power_info(),
|
||||||
|
gamepad_.id()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let mut active_gamepad = None;
|
let mut active_gamepad = None;
|
||||||
|
|
||||||
@@ -155,9 +166,11 @@ fn main() {
|
|||||||
while let Some(GilEvent { id, event, time }) = gilrs.next_event() {
|
while let Some(GilEvent { id, event, time }) = gilrs.next_event() {
|
||||||
println!("{:?} New event from {}: {:?}", time, id, event);
|
println!("{:?} New event from {}: {:?}", time, id, event);
|
||||||
active_gamepad = Some(id);
|
active_gamepad = Some(id);
|
||||||
event_loop_proxy.send_event(OwnedEventExtension::GamepadEvent {
|
event_loop_proxy
|
||||||
gil_event: GilEvent { id, event, time }
|
.send_event(OwnedEventExtension::GamepadEvent {
|
||||||
}).ok();
|
gil_event: GilEvent { id, event, time },
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// // You can also use cached gamepad state
|
// // You can also use cached gamepad state
|
||||||
@@ -171,29 +184,35 @@ fn main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut elapsed_time: f32 = { // deltatime since last frame
|
let mut elapsed_time: f32 = {
|
||||||
|
// deltatime since last frame
|
||||||
let loop_state = resources.get::<LoopState>().unwrap();
|
let loop_state = resources.get::<LoopState>().unwrap();
|
||||||
loop_state.start_time.elapsed()
|
loop_state.start_time.elapsed()
|
||||||
}.as_secs_f32();
|
}
|
||||||
|
.as_secs_f32();
|
||||||
|
|
||||||
let mut delta_time: f32 = 0.0;
|
let mut delta_time: f32 = 0.0;
|
||||||
let mut accumulator_time: f32 = 0.0;
|
let mut accumulator_time: f32 = 0.0;
|
||||||
let mut current_time: f32 = elapsed_time;
|
let mut current_time: f32 = elapsed_time;
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
|
|
||||||
*control_flow = ControlFlow::Poll;
|
*control_flow = ControlFlow::Poll;
|
||||||
match event {
|
match event {
|
||||||
event::Event::NewEvents(cause) => {
|
event::Event::NewEvents(cause) => {
|
||||||
event_schedule.execute(&mut world, &mut resources);
|
event_schedule.execute(&mut world, &mut resources);
|
||||||
resources.get_mut::<Vec<OwnedEvent<OwnedEventExtension>>>()
|
resources
|
||||||
.unwrap().clear();
|
.get_mut::<Vec<OwnedEvent<OwnedEventExtension>>>()
|
||||||
|
.unwrap()
|
||||||
|
.clear();
|
||||||
}
|
}
|
||||||
event::Event::MainEventsCleared => {
|
event::Event::MainEventsCleared => {
|
||||||
|
let (step_size, elapsed_time) = {
|
||||||
let (step_size, elapsed_time) = { // deltatime since last frame
|
// deltatime since last frame
|
||||||
let loop_state = resources.get::<LoopState>().unwrap();
|
let loop_state = resources.get::<LoopState>().unwrap();
|
||||||
(loop_state.step_size, loop_state.start_time.elapsed().as_secs_f32())
|
(
|
||||||
|
loop_state.step_size,
|
||||||
|
loop_state.start_time.elapsed().as_secs_f32(),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
delta_time = elapsed_time - current_time;
|
delta_time = elapsed_time - current_time;
|
||||||
current_time = elapsed_time;
|
current_time = elapsed_time;
|
||||||
@@ -225,9 +244,10 @@ fn main() {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.resize(width, height);
|
.resize(width, height);
|
||||||
}
|
}
|
||||||
event::Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
event::Event::WindowEvent {
|
||||||
*control_flow = ControlFlow::Exit
|
event: WindowEvent::CloseRequested,
|
||||||
}
|
..
|
||||||
|
} => *control_flow = ControlFlow::Exit,
|
||||||
event::Event::RedrawRequested(_) => {
|
event::Event::RedrawRequested(_) => {
|
||||||
// Call the render system
|
// Call the render system
|
||||||
render_schedule.execute(&mut world, &mut resources);
|
render_schedule.execute(&mut world, &mut resources);
|
||||||
@@ -235,11 +255,14 @@ fn main() {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
resources.get_mut::<Vec<OwnedEvent<OwnedEventExtension>>>()
|
resources
|
||||||
.unwrap().push(event.into());
|
.get_mut::<Vec<OwnedEvent<OwnedEventExtension>>>()
|
||||||
|
.unwrap()
|
||||||
|
.push(event.into());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn entity_loading(world: &mut World, renderer: &mut Renderer) {
|
pub fn entity_loading(world: &mut World, renderer: &mut Renderer) {
|
||||||
let monkey_mesh = renderer.load_mesh_to_buffer("./resources/monkey.obj");
|
let monkey_mesh = renderer.load_mesh_to_buffer("./resources/monkey.obj");
|
||||||
|
|
||||||
@@ -248,10 +271,10 @@ pub fn entity_loading(world: &mut World, renderer: &mut Renderer) {
|
|||||||
position: Point3 {
|
position: Point3 {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
y: 0.0,
|
y: 0.0,
|
||||||
z: 10.0
|
z: 10.0,
|
||||||
},
|
},
|
||||||
yaw: Rad(-PI),
|
yaw: Rad(-PI),
|
||||||
pitch: Rad(PI/2.0)
|
pitch: Rad(PI / 2.0),
|
||||||
},
|
},
|
||||||
Color {
|
Color {
|
||||||
r: 1.0,
|
r: 1.0,
|
||||||
@@ -272,8 +295,8 @@ pub fn entity_loading(world: &mut World, renderer: &mut Renderer) {
|
|||||||
rot: Euler {
|
rot: Euler {
|
||||||
x: Deg(0.0),
|
x: Deg(0.0),
|
||||||
y: Deg(-25.0),
|
y: Deg(-25.0),
|
||||||
z: Deg(0.0)
|
z: Deg(0.0),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
Color {
|
Color {
|
||||||
r: 1.0,
|
r: 1.0,
|
||||||
@@ -323,17 +346,11 @@ pub fn entity_loading(world: &mut World, renderer: &mut Renderer) {
|
|||||||
));
|
));
|
||||||
|
|
||||||
let mut dynamic_ball_body = RigidBodyBuilder::new_dynamic()
|
let mut dynamic_ball_body = RigidBodyBuilder::new_dynamic()
|
||||||
.position(Isometry3::new(
|
.position(Isometry3::new(Vector3::new(0.0, 0.0, 0.0), Vector::y()))
|
||||||
Vector3::new(0.0, 0.0, 0.0),
|
|
||||||
Vector::y(),
|
|
||||||
))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut static_floor_body = RigidBodyBuilder::new_static()
|
let mut static_floor_body = RigidBodyBuilder::new_static()
|
||||||
.position(Isometry3::new(
|
.position(Isometry3::new(Vector3::new(0.0, -8.0, 0.0), Vector::y()))
|
||||||
Vector3::new(0.0, -8.0, 0.0),
|
|
||||||
Vector::y(),
|
|
||||||
))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let ball_collider = ColliderBuilder::ball(1.5).build();
|
let ball_collider = ColliderBuilder::ball(1.5).build();
|
||||||
|
|||||||
@@ -96,6 +96,20 @@ pub fn update_camera(world: &mut SubWorld, #[resource] loop_state: &mut LoopStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[system]
|
||||||
|
#[write_component(Camera)]
|
||||||
|
pub fn update_imgui(
|
||||||
|
world: &mut SubWorld,
|
||||||
|
#[resource] loop_state: &mut LoopState,
|
||||||
|
#[resource] renderer: &mut Renderer,
|
||||||
|
) {
|
||||||
|
|
||||||
|
let mut query = <(&mut Camera, &mut CameraController)>::query();
|
||||||
|
for (mut camera, controller) in query.iter_mut(world) {
|
||||||
|
controller.update_camera(&mut camera, loop_state.step_size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[system]
|
#[system]
|
||||||
#[write_component(Collider)]
|
#[write_component(Collider)]
|
||||||
#[write_component(Physics)]
|
#[write_component(Physics)]
|
||||||
|
|||||||
109
src/render.rs
109
src/render.rs
@@ -23,8 +23,12 @@ use winit::window::Window;
|
|||||||
|
|
||||||
use crate::camera::{Camera, CameraController};
|
use crate::camera::{Camera, CameraController};
|
||||||
use crate::components::{Color, Mesh, Position, RangeCopy};
|
use crate::components::{Color, Mesh, Position, RangeCopy};
|
||||||
use crate::geometry::{create_plane, import_mesh, vertex, Vertex};
|
use crate::geometry::{import_mesh, vertex, Vertex};
|
||||||
use crate::light::{DirectionalLight, LightRaw};
|
use crate::light::{DirectionalLight, LightRaw};
|
||||||
|
use imgui_winit_support::WinitPlatform;
|
||||||
|
use imgui::*;
|
||||||
|
use imgui_wgpu::{Renderer as ImguiRenderer, RendererConfig as ImguiRendererConfig};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@@ -80,7 +84,12 @@ pub struct Pass {
|
|||||||
#[write_component(Mesh)]
|
#[write_component(Mesh)]
|
||||||
#[write_component(Color)]
|
#[write_component(Color)]
|
||||||
#[write_component(DirectionalLight)]
|
#[write_component(DirectionalLight)]
|
||||||
pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) {
|
pub fn render_test(
|
||||||
|
world: &mut SubWorld,
|
||||||
|
#[resource] renderer: &mut Renderer,
|
||||||
|
#[resource] winit_window: &mut Window,
|
||||||
|
) {
|
||||||
|
|
||||||
let mut encoder = renderer
|
let mut encoder = renderer
|
||||||
.device
|
.device
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||||
@@ -88,6 +97,92 @@ pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) {
|
|||||||
|
|
||||||
let frame = renderer.get_current_frame();
|
let frame = renderer.get_current_frame();
|
||||||
|
|
||||||
|
|
||||||
|
// set up imgui for rendering
|
||||||
|
|
||||||
|
// update delta time and prepare the frame
|
||||||
|
//renderer.imgui_platform.io_mut().update_delta_time(now - last_frame);
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
let mut imgui_context = imgui::Context::create();
|
||||||
|
imgui_context.set_ini_filename(None);
|
||||||
|
|
||||||
|
let font_size = 10.0 as f32;
|
||||||
|
//imgui_context.io_mut().font_global_scale = 10.0 as f32;
|
||||||
|
|
||||||
|
imgui_context.fonts().add_font(&[FontSource::DefaultFontData {
|
||||||
|
config: Some(imgui::FontConfig {
|
||||||
|
oversample_h: 1,
|
||||||
|
pixel_snap_h: true,
|
||||||
|
size_pixels: font_size,
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
}]);
|
||||||
|
|
||||||
|
// The imgui context lives as a resource for the render system to use
|
||||||
|
let mut platform = imgui_winit_support::WinitPlatform::init(imgui_context);
|
||||||
|
platform.attach_window(
|
||||||
|
imgui_context.io_mut(),
|
||||||
|
window,
|
||||||
|
imgui_winit_support::HiDpiMode::Default,
|
||||||
|
);
|
||||||
|
|
||||||
|
let clear_color = wgpu::Color {
|
||||||
|
r: 0.1,
|
||||||
|
g: 0.2,
|
||||||
|
b: 0.3,
|
||||||
|
a: 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let renderer_config = ImguiRendererConfig {
|
||||||
|
texture_format: sc_desc.format,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut renderer = ImguiRenderer::new(imgui_context, &device, &queue, renderer_config);
|
||||||
|
|
||||||
|
renderer.imgui_platform
|
||||||
|
.prepare_frame(imgui_context.io_mut(), &winit_window)
|
||||||
|
.expect("Failed to prepare frame");
|
||||||
|
|
||||||
|
// get the frame and build a ui window
|
||||||
|
let ui = imgui_context.frame();
|
||||||
|
let window = imgui::Window::new(im_str!("Hello too"));
|
||||||
|
window
|
||||||
|
.size([400.0, 200.0], Condition::FirstUseEver)
|
||||||
|
.position([400.0, 200.0], Condition::FirstUseEver)
|
||||||
|
.build(&ui, || {
|
||||||
|
ui.text(im_str!("Frametime: {:?}", 10.0));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//ui.show_demo_window(&mut demo_open);
|
||||||
|
renderer.imgui_platform.prepare_render(&ui, &winit_window);
|
||||||
|
|
||||||
|
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: None,
|
||||||
|
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||||
|
attachment: &frame.output.view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||||
|
r: 0.1,
|
||||||
|
g: 0.2,
|
||||||
|
b: 0.3,
|
||||||
|
a: 1.0,
|
||||||
|
}),
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
});
|
||||||
|
renderer.imgui_renderer
|
||||||
|
.render(ui.render(), &renderer.queue, &renderer.device, &mut rpass)
|
||||||
|
.expect("Rendering failed");
|
||||||
|
|
||||||
|
drop(rpass);
|
||||||
|
}
|
||||||
// Update the camera uniform buffers, need to make it support selection of
|
// Update the camera uniform buffers, need to make it support selection of
|
||||||
// cameras
|
// cameras
|
||||||
let mut query = <(&mut Camera)>::query();
|
let mut query = <(&mut Camera)>::query();
|
||||||
@@ -253,6 +348,10 @@ pub struct Renderer {
|
|||||||
light_uniform_buf: wgpu::Buffer,
|
light_uniform_buf: wgpu::Buffer,
|
||||||
|
|
||||||
camera_projection: Matrix4<f32>,
|
camera_projection: Matrix4<f32>,
|
||||||
|
|
||||||
|
imgui_platform: WinitPlatform,
|
||||||
|
imgui_renderer: ImguiRenderer,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
@@ -393,7 +492,8 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(window: &Window) -> Renderer {
|
pub fn init(window: &Window, imgui_context: &mut imgui::Context) -> Renderer {
|
||||||
|
|
||||||
// Grab the GPU instance, and query its features
|
// Grab the GPU instance, and query its features
|
||||||
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
|
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
|
||||||
let (size, surface) = unsafe {
|
let (size, surface) = unsafe {
|
||||||
@@ -804,6 +904,7 @@ impl Renderer {
|
|||||||
label: Some("Depth Texture"),
|
label: Some("Depth Texture"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Renderer {
|
Renderer {
|
||||||
swapchain: swap_chain,
|
swapchain: swap_chain,
|
||||||
queue: queue,
|
queue: queue,
|
||||||
@@ -821,6 +922,8 @@ impl Renderer {
|
|||||||
instance: Arc::new(instance),
|
instance: Arc::new(instance),
|
||||||
views_given: 0,
|
views_given: 0,
|
||||||
camera_projection: mx_projection,
|
camera_projection: mx_projection,
|
||||||
|
imgui_platform: platform,
|
||||||
|
imgui_renderer: renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user