diff --git a/src/main.rs b/src/main.rs index d07c805..75e3e04 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use winit::{ use crate::render::Renderer; use bytemuck::__core::ops::Range; -use cgmath::Point3; +use cgmath::{Point3, Matrix4}; use std::rc::Rc; use wgpu::Buffer; use winit::platform::unix::x11::ffi::Time; @@ -96,12 +96,23 @@ pub enum ShaderStage { pub struct Position { x: f32, y: f32, + z: f32, + mx: Matrix4, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Color { + r: f32, + g: f32, + b: f32, + a: f32, } #[derive(Clone, Copy, Debug, PartialEq)] pub struct Velocity { dx: f32, dy: f32, + rs: f32, } #[derive(Clone, Default, PartialEq, Eq, Hash, Copy, Debug)] @@ -121,6 +132,7 @@ struct DirectionalLight { struct Mesh { index_buffer: Arc, vertex_buffer: Arc, + uniform_buf: Arc, } fn main() { @@ -203,7 +215,7 @@ fn main() { // Load up the renderer (and the resources) let mut renderer = render::Renderer::init(window); - let (plane_vertex_buffer, plane_index_buffer) = renderer.load_mesh_to_buffer("./resources/untitled.obj"); + let (plane_vertex_buffer, plane_index_buffer, plane_uniform_buffer) = renderer.load_mesh_to_buffer("./resources/untitled.obj"); // This could be used for relationships between entities...??? let light_entity: Entity = world.push(( @@ -225,21 +237,29 @@ fn main() { )); let mesh_entity: Entity = world.push(( - cgmath::Point3 { + Position { x: -5.0, y: 7.0, z: 10.0, + mx: OPENGL_TO_WGPU_MATRIX }, Mesh { index_buffer: plane_index_buffer, vertex_buffer: plane_vertex_buffer, - } + uniform_buf: plane_uniform_buffer, + }, + Color { + r: 1.0, + g: 0.5, + b: 0.5, + a: 1.0, + }, )); let entities: &[Entity] = world.extend(vec![ - (Position { x: 0.0, y: 0.0 }, Velocity { dx: 0.0, dy: 0.0 }), - (Position { x: 1.0, y: 1.0 }, Velocity { dx: 0.0, dy: 0.0 }), - (Position { x: 2.0, y: 2.0 }, Velocity { dx: 0.0, dy: 0.0 }), + (Position { x: 0.0, y: 0.0, z: 0.0, mx: OPENGL_TO_WGPU_MATRIX }, Velocity { dx: 0.0, dy: 0.0, rs: 0.0 }), + (Position { x: 1.0, y: 1.0, z: 0.0, mx: OPENGL_TO_WGPU_MATRIX }, Velocity { dx: 0.0, dy: 0.0, rs: 0.0 }), + (Position { x: 2.0, y: 2.0, z: 0.0, mx: OPENGL_TO_WGPU_MATRIX }, Velocity { dx: 0.0, dy: 0.0, rs: 0.0 }), ]); // Init, this wants the references to the buffers... @@ -275,8 +295,8 @@ fn main() { { // ask for a redraw every 20 millis if last_update_inst.elapsed() > Duration::from_millis(20) { - render_schedule.execute(&mut world, &mut resources); //window.request_redraw(); + resources.get_mut::().unwrap().window.request_redraw(); last_update_inst = Instant::now(); } @@ -319,13 +339,13 @@ fn main() { }, event::Event::RedrawRequested(_) => { + render_schedule.execute(&mut world, &mut resources); //resources.get_mut::().unwrap().render(); } _ => {} } }); - //framework::run::("shadow"); } diff --git a/src/render.rs b/src/render.rs index 2d7834c..1ba1d6d 100644 --- a/src/render.rs +++ b/src/render.rs @@ -6,14 +6,16 @@ use bytemuck::{Pod, Zeroable}; use legion::*; use wgpu::util::DeviceExt; use wgpu::{Buffer, Device, SwapChain, Queue, SwapChainFrame, Surface, SwapChainDescriptor, Instance}; -use winit::dpi::{Position, PhysicalSize}; +use winit::dpi::{PhysicalSize}; use winit::platform::unix::x11::ffi::Time; use winit::window::Window; use crate::geometry::{create_plane, import_mesh, Vertex}; use crate::light::LightRaw; -use crate::{Velocity, OPENGL_TO_WGPU_MATRIX}; +use crate::{Velocity, OPENGL_TO_WGPU_MATRIX, Color, Mesh, Position}; use futures::executor::LocalPool; +use legion::world::SubWorld; +use cgmath::Point3; #[repr(C)] #[derive(Clone, Copy)] @@ -49,7 +51,7 @@ pub struct Pass { } pub struct Renderer { - window: Window, + pub window: Window, swapchain: SwapChain, swapchain_description: Arc, instance: Arc, @@ -80,7 +82,7 @@ impl Renderer { }; const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; - fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { + pub(crate) fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 20.0); let mx_view = cgmath::Matrix4::look_at( cgmath::Point3::new(3.0f32, -10.0, 6.0), @@ -92,39 +94,37 @@ impl Renderer { } } -#[system(for_each)] -pub fn render_test(pos: &mut Position, vel: &Velocity, #[resource] renderer: &mut Renderer) { +//#[system(for_each)] +#[system] +#[write_component(Position)] +#[write_component(Mesh)] +#[write_component(Color)] +pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) { let frame = renderer.get_current_frame(); - //pos.x += vel.dx * time.elapsed_seconds; - //pos.y += vel.dy * time.elapsed_seconds; - - // frame: &wgpu::SwapChainTexture, - // device: &wgpu::Device, - // queue: &wgpu::Queue, - // _spawner: &impl futures::task::LocalSpawn, - // ) - // { + + let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query(); + // update uniforms - // for entity in self.entities.iter_mut() { - // - // // Revolve the entity by the rotation speed, only if it is non-zero - // if entity.rotation_speed != 0.0 { - // let rotation = cgmath::Matrix4::from_angle_x(cgmath::Deg(entity.rotation_speed)); - // entity.mx_world = entity.mx_world * rotation; - // } - // - // let data = EntityUniforms { - // model: entity.mx_world.into(), - // color: [ - // entity.color.r as f32, - // entity.color.g as f32, - // entity.color.b as f32, - // entity.color.a as f32, - // ], - // }; - // queue.write_buffer(&entity.uniform_buf, 0, bytemuck::bytes_of(&data)); - // } + for (pos, mesh, color) in query.iter_mut(world) { + + // Revolve the entity by the rotation speed, only if it is non-zero + // if vel.rs != 0.0 { + // let rotation = cgmath::Matrix4::from_angle_x(cgmath::Deg(vel.rs)); + // pos.mx = pos.mx * rotation; + // } + + let data = EntityUniforms { + model: pos.mx.into(), + color: [ + color.r as f32, + color.g as f32, + color.b as f32, + color.a as f32, + ], + }; + renderer.queue.write_buffer(&mesh.uniform_buf, 0, bytemuck::bytes_of(&data)); + } // if self.lights_are_dirty { // self.lights_are_dirty = false; @@ -223,7 +223,6 @@ pub fn render_test(pos: &mut Position, vel: &Velocity, #[resource] renderer: &mu renderer.queue.submit(iter::once(encoder.finish())); - renderer.window.request_redraw(); } impl Renderer { @@ -285,9 +284,17 @@ impl Renderer { (vertex_buf, index_buf) } - pub fn load_mesh_to_buffer(&self, filepath: &str) -> (Arc, Arc) { + pub fn load_mesh_to_buffer(&self, filepath: &str) -> (Arc, Arc, Arc) { let (vertices, indices) = import_mesh(filepath); - Renderer::create_buffer(&self.device, indices, vertices) + let (vertex_buf, index_buf) = Renderer::create_buffer(&self.device, indices, vertices); + + let uniform_buf = Arc::new(self.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: mem::size_of::() as wgpu::BufferAddress, + usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + mapped_at_creation: false, + })); + (vertex_buf, index_buf, uniform_buf) } pub fn init(window: Window) -> Renderer {