diff --git a/crates/comet_app/src/app.rs b/crates/comet_app/src/app.rs index e9745cb..3b561f7 100644 --- a/crates/comet_app/src/app.rs +++ b/crates/comet_app/src/app.rs @@ -4,7 +4,7 @@ use std::sync::atomic::AtomicBool; use std::thread; use std::time::{Duration, Instant}; use crossbeam_channel::bounded; -use comet_ecs::{Component, ComponentSet, Entity, Render, Transform2D, Transform3D, World}; +use comet_ecs::{Camera2D, Component, ComponentSet, Entity, Render, Render2D, Transform2D, Transform3D, World}; use comet_resources::{ResourceManager, Vertex}; use comet_renderer::renderer2d::Renderer2D; @@ -98,7 +98,9 @@ impl App { match preset { ApplicationType::App2D => { info!("Creating 2D app!"); - self.world.register_component::() + self.world.register_component::(); + self.world.register_component::(); + self.world.register_component::() }, ApplicationType::App3D => { info!("Creating 3D app!"); @@ -129,8 +131,8 @@ impl App { self.game_state.as_mut()?.downcast_mut::() } - pub fn input_manager(&self) -> &WinitInputHelper { - &self.input_manager + pub fn world(&self) -> &World { + &self.world } pub fn key_pressed(&self, key: Key) -> bool { diff --git a/crates/comet_ecs/src/component.rs b/crates/comet_ecs/src/component.rs index 9fb7e77..7df8d10 100644 --- a/crates/comet_ecs/src/component.rs +++ b/crates/comet_ecs/src/component.rs @@ -3,12 +3,13 @@ // Also just as a nomenclature: bundles are a component made up of multiple components, // so it's a collection of components bundled together (like Transform2D) +use comet_math::Mat4; use crate::math::{ Vec2, Vec3 }; use component_derive::Component; -use crate::Entity; +use crate::{Entity, World}; // ################################################## // # BASIC # @@ -51,13 +52,8 @@ pub struct Render2D { #[derive(Component)] pub struct Camera2D { - left: f32, - right: f32, - bottom: f32, - top: f32, - near: f32, - far: f32, - zoom: f32 + zoom: f32, + dimensions: Vec2, } // ################################################## @@ -104,7 +100,8 @@ pub trait Render { } pub trait Camera { - fn get_visible_entities(&self) -> Vec; + fn get_visible_entities(&self, camera_position: Position2D, world: World) -> Vec; + fn get_projection_matrix(&self) -> Mat4; } // ################################################## @@ -278,18 +275,29 @@ impl Transform3D { } impl Camera2D { - pub fn new(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32, zoom: f32) -> Self { + pub fn new(dimensions: Vec2, zoom: f32) -> Self { Self { - left, - right, - bottom, - top, - near, - far, + dimensions, zoom } } + pub fn zoom(&self) -> f32 { + self.zoom + } + + pub fn set_zoom(&mut self, zoom: f32) { + self.zoom = zoom; + } + + pub fn dimensions(&self) -> Vec2 { + self.dimensions + } + + pub fn set_dimensions(&mut self, dimensions: Vec2) { + self.dimensions = dimensions; + } + fn in_view_frustum(&self, camera_pos: Position2D, entity: Position2D) -> bool { let left = camera_pos.x() - self.zoom; let right = camera_pos.x() + self.zoom; @@ -301,7 +309,23 @@ impl Camera2D { } impl Camera for Camera2D { - fn get_visible_entities(&self) -> Vec { - unimplemented!() + fn get_visible_entities(&self, camera_position: Position2D, world: World) -> Vec { + let entities = world.entities(); + let mut visible_entities = Vec::new(); + for entity in entities { + if self.in_view_frustum(camera_position, *world.get_component::(*entity.clone().unwrap().id() as usize).unwrap().position()) { + visible_entities.push(entity.clone().unwrap()); + } + } + visible_entities + } + + fn get_projection_matrix(&self) -> Mat4 { + let left = -self.dimensions.x() / 2.0; + let right = self.dimensions.x() / 2.0; + let bottom = -self.dimensions.y() / 2.0; + let top = self.dimensions.y() / 2.0; + + Mat4::OPENGL * Mat4::orthographic_matrix(left, right, bottom, top, 1.0, 0.0) } } \ No newline at end of file diff --git a/crates/comet_ecs/src/world.rs b/crates/comet_ecs/src/world.rs index aa777cc..7ac7e1e 100644 --- a/crates/comet_ecs/src/world.rs +++ b/crates/comet_ecs/src/world.rs @@ -200,7 +200,10 @@ impl World { /// Returns a list of entities that have the given components. pub fn get_entities_with(&self, components: ComponentSet) -> Vec { - assert!(self.archetypes.contains_archetype(&components), "The given components {:?} are not registered in the world!", components); - self.archetypes.get_archetype(&components).unwrap().clone() + //assert!(self.archetypes.contains_archetype(&components), "The given components {:?} are not registered in the world!", components); + if self.archetypes.contains_archetype(&components) { + return self.archetypes.get_archetype(&components).unwrap().clone(); + } + Vec::new() } } diff --git a/crates/comet_math/src/matrix.rs b/crates/comet_math/src/matrix.rs index 74da5d5..73293d8 100644 --- a/crates/comet_math/src/matrix.rs +++ b/crates/comet_math/src/matrix.rs @@ -528,6 +528,13 @@ impl Mat4 { x30: 0.0, x31: 0.0, x32: 0.0, x33: 1.0 }; + pub const OPENGL: Mat4 = Mat4 { + x00: 1.0, x01: 0.0, x02: 0.0, x03: 0.0, + x10: 0.0, x11: 1.0, x12: 0.0, x13: 0.0, + x20: 0.0, x21: 0.0, x22: 0.5, x23: 0.0, + x30: 0.0, x31: 0.0, x32: 0.5, x33: 1.0 + }; + pub const fn new(x00: f32, x01: f32,x02: f32,x03: f32,x10: f32,x11: f32,x12: f32,x13: f32,x20: f32,x21: f32,x22: f32,x23: f32,x30: f32, x31: f32, x32: f32,x33: f32) -> Self { Self { x00, x01, x02, x03, diff --git a/crates/comet_renderer/src/renderer2d.rs b/crates/comet_renderer/src/renderer2d.rs index be6f0f6..1ae1ef7 100644 --- a/crates/comet_renderer/src/renderer2d.rs +++ b/crates/comet_renderer/src/renderer2d.rs @@ -8,12 +8,12 @@ use wgpu::util::DeviceExt; use winit::dpi::PhysicalSize; use winit::window::Window; use comet_colors::LinearRgba; -use comet_ecs::{Component, ComponentSet, Render, Render2D, Transform2D, World}; +use comet_ecs::{Camera, Camera2D, Component, ComponentSet, Render, Render2D, Transform2D, World}; use comet_log::{debug, info}; use comet_math::{Point3, Vec2, Vec3}; use comet_resources::{texture, graphic_resource_manager::GraphicResorceManager, Texture, Vertex}; use comet_resources::texture_atlas::TextureRegion; -use crate::camera::{Camera, CameraUniform}; +use crate::camera::{Camera as OldCam, CameraUniform}; use crate::render_pass::RenderPassInfo; use crate::renderer::Renderer; @@ -37,7 +37,7 @@ pub struct Renderer2D<'a> { diffuse_texture: texture::Texture, diffuse_bind_group: wgpu::BindGroup, graphic_resource_manager: GraphicResorceManager, - camera: Camera, + camera: OldCam, camera_uniform: CameraUniform, camera_buffer: wgpu::Buffer, camera_bind_group: wgpu::BindGroup, @@ -120,7 +120,7 @@ impl<'a> Renderer2D<'a> { let diffuse_bytes = include_bytes!(r"../../../resources/textures/comet_icon.png"); let diffuse_texture = - texture::Texture::from_bytes(&device, &queue, diffuse_bytes, "comet_icon.png", false).unwrap(); + Texture::from_bytes(&device, &queue, diffuse_bytes, "comet_icon.png", false).unwrap(); let texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { @@ -160,7 +160,7 @@ impl<'a> Renderer2D<'a> { label: Some("diffuse_bind_group"), }); - let camera = Camera::new(1.0, Vec2::new(2.0, 2.0), Vec3::new(0.0, 0.0, 0.0)); + let camera = OldCam::new(1.0, Vec2::new(2.0, 2.0), Vec3::new(0.0, 0.0, 0.0)); let mut camera_uniform = CameraUniform::new(); camera_uniform.update_view_proj(&camera); @@ -288,9 +288,9 @@ impl<'a> Renderer2D<'a> { diffuse_bind_group, graphic_resource_manager, camera, - camera_uniform, camera_buffer, - camera_bind_group, + camera_uniform, + camera_bind_group } } @@ -732,7 +732,66 @@ impl<'a> Renderer2D<'a> { /// A function to automatically render all the entities of the `World` struct. /// The entities must have the `Render2D` and `Transform2D` components to be rendered as well as set visible. pub fn render_scene_2d(&mut self, world: &World) { - let entities = world.get_entities_with(ComponentSet::from_ids(vec![Render2D::type_id()])); + let cameras = world.get_entities_with(ComponentSet::from_ids(vec![Camera2D::type_id()])); + + if cameras == vec![] { + info!("No camera found in the scene"); + return; + } + + info!("Camera found in the scene"); + + let entities = world.get_entities_with(ComponentSet::from_ids(vec![Transform2D::type_id(), Render2D::type_id()])); + + for camera in cameras { + let camera_position = world.get_component::(camera as usize).unwrap().position(); + let camera_component = world.get_component::(camera as usize); + let camera = OldCam::new(camera_component.unwrap().zoom(), camera_component.unwrap().dimensions(), Vec3::new(camera_position.as_vec().x(), camera_position.as_vec().y(), 0.0)); + let mut camera_uniform = CameraUniform::new(); + camera_uniform.update_view_proj(&camera); + + let camera_buffer = self.device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Camera Buffer"), + contents: bytemuck::cast_slice(&[camera_uniform]), + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }); + + let camera_bind_group_layout = + self.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + }], + label: Some("camera_bind_group_layout"), + }); + + let camera_bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &camera_bind_group_layout, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: camera_buffer.as_entire_binding(), + }], + label: Some("camera_bind_group"), + }); + + self.camera = camera; + self.camera_buffer = camera_buffer; + self.camera_uniform = camera_uniform; + self.camera_bind_group = camera_bind_group; + + let visible_entities = camera_component.unwrap().get_visible_entities(*camera_position, world.clone()); + println!("{:?}", visible_entities); + } + + + + /*let entities = world.get_entities_with(ComponentSet::from_ids(vec![Transform2D::type_id(), Render2D::type_id()])); let mut vertex_buffer: Vec = Vec::new(); let mut index_buffer: Vec = Vec::new(); @@ -767,7 +826,7 @@ impl<'a> Renderer2D<'a> { } } - self.set_buffers(vertex_buffer, index_buffer); + self.set_buffers(vertex_buffer, index_buffer);*/ } pub fn update(&mut self) -> f32 {