diff --git a/src/canvas/canvas_frame.rs b/src/canvas/canvas_frame.rs index 7d6b79e7..d216dd40 100644 --- a/src/canvas/canvas_frame.rs +++ b/src/canvas/canvas_frame.rs @@ -9,7 +9,7 @@ use std::any::Any; use crate::{VertexTypeContainer}; use winit::event::Event; use crate::util::tr_event::{TrEvent, TrUIEvent}; -use crate::drawables::sprite::{Velocity, Geometry}; +use crate::render_system::Position; enum CustomEvent { @@ -27,14 +27,6 @@ pub trait Drawable { depth: f32, ) -> Vec; - // Update simply passes the delta time. The implementor doesn't necessarily need to use delta_time - // or even add anything other than a Vec::new() to the function. - fn update(&self, delta_time: f32) -> Vec>; - - // Notify is where custom events created in other parts of the system will be ingested. It - // might be a good idea in the future to have some of pre-function-call filtering so we - // don't have as many notifies that just immediately reject. - fn notify(&self, tr_event : Vec>, ui_events: Vec>) -> Vec>; } @@ -60,18 +52,18 @@ impl CanvasFrame { } } - /// Push this drawable onto the back of the accumulator - pub fn draw(&mut self, drawable: &dyn Drawable, mv: Velocity, geom: Geometry) { - for i in drawable.render( - self.window_size, - (mv.pos_x, mv.pos_y), - geom.rotation, - (geom.size_x, geom.size_y), - geom.depth - ) { - self.map.push(i); - } - } + // /// Push this drawable onto the back of the accumulator + // pub fn draw(&mut self, drawable: &dyn Drawable, pos: Position, geom: Geometry) { + // for i in drawable.render( + // self.window_size, + // (mv.pos_x, mv.pos_y), + // geom.rotation, + // (geom.size_x, geom.size_y), + // geom.depth + // ) { + // self.map.push(i); + // } + // } } diff --git a/src/canvas/compu_frame.rs b/src/canvas/compu_frame.rs index 0dc16d89..600cdd54 100644 --- a/src/canvas/compu_frame.rs +++ b/src/canvas/compu_frame.rs @@ -4,7 +4,7 @@ use crate::canvas::managed::handles::{CompuKernelHandle}; use crate::drawables::compu_sprite::CompuSprite; use crate::canvas::canvas_frame::Drawable; use crate::util::vertex::VertexTypeContainer; -use crate::drawables::sprite::{Velocity, Geometry}; +use crate::render_system::{Images, Geometry}; #[derive(Default)] pub struct CompuFrame { @@ -57,22 +57,23 @@ impl CompuFrame { pub fn add_with_image_swap(&mut self, buffer: Arc, kernel: Arc, - sprite: &CompuSprite, - mv: Velocity, + images: &Images, geom: Geometry, ) { - let compu_sprites = sprite.render( - self.window_size, - (mv.pos_x, mv.pos_y), - geom.rotation, - (geom.size_x, geom.size_y), - geom.depth, - ); - if compu_sprites.len() == 1 { - if let VertexTypeContainer::ImageType(a, b) = compu_sprites.first().unwrap() { - self.swapped_to_image.push((buffer, b.clone(), kernel)) - }; - } + // TODO fix this + // let compu_sprites = sprite.render( + // self.window_size, + // (mv.pos_x, mv.pos_y), + // geom.rotation, + // (geom.size_x, geom.size_y), + // geom.depth, + // ); + // + // if compu_sprites.len() == 1 { + // if let VertexTypeContainer::ImageType(a, b) = compu_sprites.first().unwrap() { + // self.swapped_to_image.push((buffer, b.clone(), kernel)) + // }; + // } } } \ No newline at end of file diff --git a/src/compu_system.rs b/src/compu_system.rs new file mode 100644 index 00000000..792e741b --- /dev/null +++ b/src/compu_system.rs @@ -0,0 +1,61 @@ +use std::sync::Arc; + +use specs::{Component, Join, System, VecStorage, Write, WriteStorage}; + +use crate::canvas::canvas_frame::CanvasFrame; +use crate::canvas::compu_frame::CompuFrame; +use crate::canvas::managed::handles::{CanvasImageHandle, CanvasTextureHandle, CompuBufferHandle, CompuKernelHandle}; +use crate::PersistentState; +use crate::render_system::{Geometry, Images, Position, Textures}; +use crate::util::vertex::{ImageVertex3D, TextureVertex3D, VertexTypeContainer}; +use crate::vkprocessor::VkProcessor; + +pub struct Compu { + pub kernels: Vec>, + pub buffers: Vec>, +} + +impl Component for Compu { + type Storage = VecStorage; +} + +pub struct CompuSystem; + +impl<'a> System<'a> for CompuSystem { + type SystemData = ( + WriteStorage<'a, Compu>, + WriteStorage<'a, Geometry>, + WriteStorage<'a, Images>, + Write<'a, PersistentState>, // delta_time, window size, etc. + Write<'a, VkProcessor>, // Renderer + ); + + fn run(&mut self, ( + mut compu_list, + mut geom_list, + mut image_list, + mut state, + mut vk_processor + ): Self::SystemData) { + state.compu_frame = CompuFrame::new(state.window_size); + + // compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1); + // compu_frame.add(compute_buffer.clone(), compute_kernel.clone()); + + for (compute_item, geom, image) in (&mut compu_list, &mut geom_list, &mut image_list).join() { + state.compu_frame.add_with_image_swap( + compute_item.buffers.get(0).unwrap().clone(), + compute_item.kernels.get(0).unwrap().clone(), + image, + geom.clone(), + ); + } + + for (compute_item) in (&mut compu_list).join() { + state.compu_frame.add( + compute_item.buffers.get(0).unwrap().clone(), + compute_item.kernels.get(0).unwrap().clone(), + ); + } + } +} \ No newline at end of file diff --git a/src/drawables/compu_sprite.rs b/src/drawables/compu_sprite.rs index 7a318313..1857a645 100644 --- a/src/drawables/compu_sprite.rs +++ b/src/drawables/compu_sprite.rs @@ -64,11 +64,11 @@ impl Drawable for CompuSprite { vec![self.verts.clone()] } - fn update(&self, delta_time: f32) -> Vec> { - Vec::new() - } - - fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { - Vec::new() - } + // fn update(&self, delta_time: f32) -> Vec> { + // Vec::new() + // } + // + // fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { + // Vec::new() + // } } \ No newline at end of file diff --git a/src/drawables/polygon.rs b/src/drawables/polygon.rs index 139eeccb..6e7b1f89 100644 --- a/src/drawables/polygon.rs +++ b/src/drawables/polygon.rs @@ -72,13 +72,13 @@ impl Drawable for Polygon { vec![self.verts.clone()] } - fn update(&self, delta_time: f32) -> Vec> { - Vec::new() - } - - fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { - Vec::new() - } + // fn update(&self, delta_time: f32) -> Vec> { + // Vec::new() + // } + // + // fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { + // Vec::new() + // } } diff --git a/src/drawables/rect.rs b/src/drawables/rect.rs index 721111f8..c7f6d93b 100644 --- a/src/drawables/rect.rs +++ b/src/drawables/rect.rs @@ -88,11 +88,11 @@ impl Drawable for Rect { ] } - fn update(&self, delta_time: f32) -> Vec> { - Vec::new() - } - - fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { - Vec::new() - } + // fn update(&self, delta_time: f32) -> Vec> { + // Vec::new() + // } + // + // fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { + // Vec::new() + // } } diff --git a/src/drawables/slider.rs b/src/drawables/slider.rs index 59db95c4..35b8ddb3 100644 --- a/src/drawables/slider.rs +++ b/src/drawables/slider.rs @@ -104,28 +104,28 @@ impl Drawable for Slider { vertices } - fn update(&self, delta_time: f32) -> Vec> { - Vec::new() - } - - fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { - match tr_event { - TrEvent::WindowEvent { event: TrWindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => { - - - match button { - MouseButton::Left => { - if *state == ElementState::Pressed { - self.position.0 += 30.0; - self.value += 10; - self.update() - } - } - _ => {} - } - } - _ => {} - } - Vec::new() - } + // fn update(&self, delta_time: f32) -> Vec> { + // Vec::new() + // } + // + // fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { + // match tr_event { + // TrEvent::WindowEvent { event: TrWindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => { + // + // + // match button { + // MouseButton::Left => { + // if *state == ElementState::Pressed { + // self.position.0 += 30.0; + // self.value += 10; + // self.update() + // } + // } + // _ => {} + // } + // } + // _ => {} + // } + // Vec::new() + // } } diff --git a/src/drawables/sprite.rs b/src/drawables/sprite.rs index 927b1f81..2496cc3a 100644 --- a/src/drawables/sprite.rs +++ b/src/drawables/sprite.rs @@ -6,26 +6,12 @@ use crate::util::vertex::{VertexTypeContainer, TextureVertex3D, Vertex3D}; use winit::event::{DeviceEvent, MouseButton, ElementState, Event, WindowEvent}; use crate::util::tr_event::{TrEvent, TrWindowEvent, TrUIEvent}; -pub struct Geometry { - pos_x: f32, - pos_y: f32, - size_x: f32, - size_y: f32, - rotation: f32, - depth: f32, -} -pub struct Velocity { - vel_x: f32, - vel_y: f32, - vel_r: f32, -} /// #[derive(Debug, Clone)] pub struct Sprite { texture_handle: Arc, - geometry: Geometry, - velocity: Velocity, + } /// Container class which implements drawable. @@ -78,19 +64,7 @@ impl Sprite { pub fn new(texture_handle: Arc) -> Sprite { Sprite { texture_handle: texture_handle.clone(), - geometry: Geometry { - pos_x: 0.0, - pos_y: 0.0, - size_x: 0.0, - size_y: 0.0, - rotation: 0.0, - depth: 0.0 - }, - velocity: Velocity { - vel_x: 0.0, - vel_y: 0.0, - vel_r: 0.0 - } + } } } @@ -112,25 +86,25 @@ impl Drawable for Sprite { self.texture_handle.clone()) ] } - - fn update(&self, delta_time: f32) -> Vec> { - Vec::new() - } - - fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { - match tr_event { - TrEvent::WindowEvent { event: TrWindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => { - match button { - MouseButton::Left => { - if *state == ElementState::Pressed { - - } - } - _ => {} - } - } - _ => {} - } - Vec::new() - } + // + // fn update(&self, delta_time: f32) -> Vec> { + // Vec::new() + // } + // + // fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { + // match tr_event { + // TrEvent::WindowEvent { event: TrWindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => { + // match button { + // MouseButton::Left => { + // if *state == ElementState::Pressed { + // + // } + // } + // _ => {} + // } + // } + // _ => {} + // } + // Vec::new() + // } } diff --git a/src/drawables/text.rs b/src/drawables/text.rs index fc13d523..05c0bd4d 100644 --- a/src/drawables/text.rs +++ b/src/drawables/text.rs @@ -148,11 +148,11 @@ impl Drawable for Text { vec![self.verts.clone()] } - fn update(&self, delta_time: f32) -> Vec> { - Vec::new() - } - - fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { - Vec::new() - } + // fn update(&self, delta_time: f32) -> Vec> { + // Vec::new() + // } + // + // fn notify(&self, tr_event: Vec>, ui_events: Vec>) -> Vec> { + // Vec::new() + // } } diff --git a/src/main.rs b/src/main.rs index 229a9a3b..1aa44a6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,14 +8,17 @@ extern crate hprof; extern crate image; extern crate nalgebra as na; extern crate rand; +extern crate specs; extern crate time; use std::path::Path; use std::sync::Arc; use gilrs::{Button, Event as GilEvent, Gamepad, GamepadId, Gilrs}; +use specs::prelude::*; use vulkano::instance::debug::DebugCallback; use vulkano::instance::Instance; +use vulkano::swapchain::Surface; use vulkano::sync; use vulkano::sync::GpuFuture; use vulkano_win::VkSurfaceBuild; @@ -23,44 +26,37 @@ use winit::dpi::LogicalSize; use winit::event::{DeviceEvent, ElementState, Event, MouseButton, StartCause, VirtualKeyCode, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop, EventLoopProxy}; use winit::platform::unix::WindowBuilderExtUnix; -use winit::window::{WindowBuilder, Window}; +use winit::window::{Window, WindowBuilder}; + +use canvas::compu_frame::CompuFrame; use crate::canvas::canvas_frame::{CanvasFrame, Drawable}; use crate::canvas::canvas_state::CanvasState; use crate::canvas::managed::handles::{CanvasFontHandle, CanvasTextureHandle, Handle}; -use canvas::compu_frame::CompuFrame; use crate::canvas::managed::handles::{CompuBufferHandle, CompuKernelHandle}; use crate::drawables::compu_sprite::CompuSprite; use crate::drawables::rect::Rect; +use crate::drawables::slider::Slider; use crate::drawables::sprite::Sprite; use crate::drawables::text::Text; +use crate::render_system::{Geometry, Images, Position, Render, RenderSystem, Textures}; use crate::util::load_raw; use crate::util::timer::Timer; -use crate::util::tr_event::{TrEventExtension, TrEvent}; +use crate::util::tr_event::{TrEvent, TrEventExtension}; use crate::util::vertex::{TextureVertex3D, VertexTypeContainer}; use crate::vkprocessor::VkProcessor; -use crate::drawables::slider::Slider; +use crate::compu_system::{CompuSystem, Compu}; pub mod util; pub mod vkprocessor; pub mod drawables; pub mod canvas; +pub mod render_system; +pub mod compu_system; -extern crate specs; - -use specs::prelude::*; -use vulkano::swapchain::Surface; - -pub struct Render { - render_actor: Box, -} - -impl Component for Render { - type Storage = VecStorage; -} #[derive(Default)] -struct PersistentState { +pub struct PersistentState { surface: Option>>, window_size: (u32, u32), delta_time: f32, @@ -68,47 +64,6 @@ struct PersistentState { compu_frame: CompuFrame, } -struct RenderSystem; - -impl<'a> System<'a> for RenderSystem { - type SystemData = ( - WriteStorage<'a, Render>, // generates the vertices - Write<'a, PersistentState>, // delta_time, window size, etc. - Write<'a, VkProcessor>, // Renderer - ); - - fn run(&mut self, (mut mv, mut draw, mut state, mut vk_processor): Self::SystemData) { - state.canvas_frame = CanvasFrame::new(state.window_size); - state.compu_frame = CompuFrame::new(state.window_size); - - // compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1); - // compu_frame.add(compute_buffer.clone(), compute_kernel.clone()); - - for (mv, geom, draw) in (&mut mv, &mut draw).join() { - geom.pos_x += mv.vel_x * state.delta_time; - geom.pos_y += mv.vel_y * state.delta_time; - - let window_size = state.window_size.clone(); - state.canvas_frame.add(draw.0.get( - window_size, - (geom.pos_x, geom.pos_y), - geom.rotation, - (geom.size_x, geom.size_y), - geom.depth, - )); - } - - for draw_data in (&draw).join() { - let size = state.window_size.clone(); - } - - vk_processor.run(&state.surface.clone().unwrap(), - &state.canvas_frame, - &state.compu_frame); - } -} - - struct EventSystem; impl<'a> System<'a> for EventSystem { @@ -128,13 +83,11 @@ impl<'a> System<'a> for EventSystem { } } -struct Eventt(u32); pub fn main() { //hprof::start_frame(); //let g = hprof::enter("vulkan preload"); - let instance = { let extensions = vulkano_win::required_extensions(); Instance::new(None, &extensions, None).unwrap() @@ -174,11 +127,6 @@ pub fn main() { let image_dimensions_u: (u32, u32) = image_data.1; - let compu_sprite1: CompuSprite = - CompuSprite::new((-1.0, -1.0), (1.0, 1.0), 0, image_dimensions_f, - // Swap image to render the result to. Must match dimensions - processor.new_swap_image(image_dimensions_u)); - let compute_buffer: Arc = processor.new_compute_buffer(image_data.0.clone(), image_data.1, 4); @@ -189,6 +137,8 @@ pub fn main() { processor.get_kernel_handle(String::from("simple-edge.compute")) .expect("Can't find that kernel"); + let compu_image = processor.new_swap_image(image_dimensions_u); + // Get the handles for the assets let funky_handle: Arc = processor.get_texture_handle(String::from("funky-bird.jpg")).unwrap(); @@ -197,6 +147,11 @@ pub fn main() { let mut world = World::new(); world.register::(); + world.register::(); + world.register::(); + world.register::(); + world.register::(); + world.register::(); world.insert::(processor); world.insert::>>(Vec::new()); world.insert::(PersistentState { @@ -207,26 +162,27 @@ pub fn main() { compu_frame: CompuFrame::new((0, 0)), }); - - let thing = Box::new(Sprite::new(funky_handle.clone())); - - // An entity may or may not contain some component. - let t = world.create_entity() - .with(Render{ render_actor: thing })// just a drawable + world.create_entity() + .with(Render { vertices: vec![] })// just a drawable + .with(Position { x: 0.0, y: 0.0, z: 0 }) + .with(Geometry { size_x: 300.0, size_y: 300.0, rotation: 0.0 }) + .with(Textures { textures: vec![funky_handle] }) .build(); - let thing2 = Box::new(Slider::new((300.0, 50.0), (550.0, 100.0), 30000)); - world.create_entity() - .with(Render{ render_actor: thing2 })// just a drawable + .with(Render { vertices: vec![] })// just a drawable + .with(Position { x: 600.0, y: 500.0, z: 0 }) + .with(Geometry { size_x: 600.0, size_y: 600.0, rotation: 0.0 }) + .with(Images { images: vec![compu_image], image_resolutions: vec![image_dimensions_u] }) .build(); - // call the run method for the following systems & deps let mut dispatcher = DispatcherBuilder::new() // .with(SysA, "sys_a", &[]) .with(EventSystem, "event_s", &[]) - .with(RenderSystem, "render_s", &["event_s"]).build(); + .with(CompuSystem, "compu_s", &["event_s"]) + .with(RenderSystem, "render_s", &["event_s", "compu_s"]).build(); + let event_loop_proxy = events_loop.create_proxy(); diff --git a/src/render_system.rs b/src/render_system.rs new file mode 100644 index 00000000..5a658abf --- /dev/null +++ b/src/render_system.rs @@ -0,0 +1,232 @@ +use specs::{Component, Join, System, VecStorage, Write, WriteStorage}; + +use crate::canvas::canvas_frame::CanvasFrame; +use crate::canvas::compu_frame::CompuFrame; +use crate::canvas::managed::handles::{CanvasImageHandle, CanvasTextureHandle}; +use crate::PersistentState; +use crate::util::vertex::{TextureVertex3D, VertexTypeContainer, ImageVertex3D}; +use crate::vkprocessor::VkProcessor; +use std::sync::Arc; + +#[derive(Debug, Clone)] +pub struct Position { + pub x: f32, + pub y: f32, + pub z: u8, +} + +impl Component for Position { + type Storage = VecStorage; +} + +#[derive(Debug, Clone)] +pub struct Geometry { + pub size_x: f32, + pub size_y: f32, + pub rotation: f32, +} + +impl Component for Geometry { + type Storage = VecStorage; +} + +#[derive(Debug, Clone)] +pub struct Render { + pub vertices: Vec, +} + +impl Component for Render { + type Storage = VecStorage; +} + +#[derive(Debug, Clone)] +pub struct Textures { + pub textures: Vec>, +} + +impl Component for Textures { + type Storage = VecStorage; +} + +#[derive(Debug, Clone)] +pub struct Images { + pub images: Vec>, + pub image_resolutions: Vec<(u32, u32)>, +} + +impl Component for Images { + type Storage = VecStorage; +} + +pub struct RenderSystem; + +impl<'a> System<'a> for RenderSystem { + type SystemData = ( + WriteStorage<'a, Render>, + WriteStorage<'a, Position>, + WriteStorage<'a, Geometry>, + WriteStorage<'a, Textures>, + WriteStorage<'a, Images>, + Write<'a, PersistentState>, // delta_time, window size, etc. + Write<'a, VkProcessor>, // Renderer + ); + + fn run(&mut self, ( + mut vertices_list, + mut pos_list, + mut geom_list, + mut textures_list, + mut images_list, + mut state, + mut vk_processor + ): Self::SystemData) { + state.canvas_frame = CanvasFrame::new(state.window_size); + state.compu_frame = CompuFrame::new(state.window_size); + + // compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1); + // compu_frame.add(compute_buffer.clone(), compute_kernel.clone()); + + for (vertices, position, geometry, textures) in (&mut vertices_list, &mut pos_list, &mut geom_list, &mut textures_list).join() { + // geom.pos_x += mv.vel_x * state.delta_time; + // geom.pos_y += mv.vel_y * state.delta_time; + + let window_size = state.window_size.clone(); + let pos = (position.x, position.y); + let size = (geometry.size_x, geometry.size_y); + let normalized_depth = position.z as f32 / 255.0; + + let textured_vertices = vec![ + VertexTypeContainer::TextureType( + generate_textured_verts(window_size, pos, size, normalized_depth), + textures.textures.get(0).unwrap().clone() + ) + ]; + + state.canvas_frame.add(textured_vertices); + } + + for (vertices, position, geometry, images) in (&mut vertices_list, &mut pos_list, &mut geom_list, &mut images_list).join() { + // geom.pos_x += mv.vel_x * state.delta_time; + // geom.pos_y += mv.vel_y * state.delta_time; + + let window_size = state.window_size.clone(); + let pos = (position.x, position.y); + let size = (geometry.size_x, geometry.size_y); + let normalized_depth = position.z as f32 / 255.0; + + let textured_vertices = vec![ + VertexTypeContainer::ImageType( + generate_image_verts(window_size, pos, size, images.image_resolutions.get(0).unwrap().clone(), normalized_depth), + images.images.get(0).unwrap().clone() + ) + ]; + + state.canvas_frame.add(textured_vertices); + } + + vk_processor.run(&state.surface.clone().unwrap(), + &state.canvas_frame, + &state.compu_frame); + } +} + +fn generate_image_verts( + window_size: (u32, u32), + position: (f32, f32), + size: (f32, f32), + image_size: (u32, u32), + depth: f32, +) -> Vec { + + let image_size = (image_size.0 as f32, image_size.1 as f32); + + // screen space position + let ss_position = ( + position.0 / window_size.0 as f32 - 1.0, + position.1 / window_size.1 as f32 - 1.0 + ); + + // screen space size + let ss_size = ( + size.0 / window_size.0 as f32, + size.1 / window_size.1 as f32 + ); + +// pub fn new(position: (f32, f32), +// size: (f32, f32), +// depth: u32, +// image_size: (f32, f32), +// image_handle: Arc) -> CompuSprite { + + vec![ + ImageVertex3D { + v_position: [ss_position.0, ss_position.1, depth], // top left + ti_position: [-0.0, -0.0] + }, + ImageVertex3D { + v_position: [ss_position.0, ss_position.1 + ss_size.1, depth], // bottom left + ti_position: [-0.0, image_size.1] + }, + ImageVertex3D { + v_position: [ss_position.0 + ss_size.0, ss_position.1 + ss_size.1, depth], // bottom right + ti_position: [image_size.0, image_size.1] + }, + ImageVertex3D { + v_position: [ss_position.0, ss_position.1, depth], // top left + ti_position: [-0.0, -0.0] + }, + ImageVertex3D { + v_position: [ss_position.0 + ss_size.0, ss_position.1 + ss_size.1, depth], // bottom right + ti_position: [image_size.0, image_size.1] + }, + ImageVertex3D { + v_position: [ss_position.0 + ss_size.0, ss_position.1, depth], // top right + ti_position: [image_size.0, -0.0] + }, + ] +} + +fn generate_textured_verts( + window_size: (u32, u32), + position: (f32, f32), + size: (f32, f32), + depth: f32, +) -> Vec { + + let ss_position = ( + position.0 / window_size.0 as f32 - 1.0, + position.1 / window_size.1 as f32 - 1.0 + ); + + let ss_size = ( + size.0 / window_size.0 as f32, + size.1 / window_size.1 as f32 + ); + + vec![ + TextureVertex3D { + v_position: [ss_position.0, ss_position.1, depth], // top left + ti_position: [-0.0, -0.0], + }, + TextureVertex3D { + v_position: [ss_position.0, ss_position.1 + ss_size.1, depth], // bottom left + ti_position: [-0.0, 1.0], + }, + TextureVertex3D { + v_position: [ss_position.0 + ss_size.0, ss_position.1 + ss_size.1, depth], // bottom right + ti_position: [1.0, 1.0], + }, + TextureVertex3D { + v_position: [ss_position.0, ss_position.1, depth], // top left + ti_position: [-0.0, -0.0], + }, + TextureVertex3D { + v_position: [ss_position.0 + ss_size.0, ss_position.1 + ss_size.1, depth], // bottom right + ti_position: [1.0, 1.0], + }, + TextureVertex3D { + v_position: [ss_position.0 + ss_size.0, ss_position.1, depth], // top right + ti_position: [1.0, -0.0], + }, + ] +} \ No newline at end of file