diff --git a/src/main.rs b/src/main.rs index 4be5b23..7d52cc8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use canvas::{ Canvas, texture::Texture, sprite::TextureSprite, + utils::Position, }; use std::{ @@ -46,6 +47,7 @@ struct ExampleState { pub sub_sprite: TextureSprite, pub last_instant: Instant, pub last_offset: u32, + pub last_pos: Position, } struct ExampleApp {} @@ -60,7 +62,7 @@ impl Application for ExampleApp { //// 20 x 20 sprite of a picture let texture = canvas.create_texture_from_file("assets/camel.jpg", None, None, None) .unwrap(); - let mut tex_sprite = canvas.create_texture_sprite(Size {w: 20, h: 20}); + let mut tex_sprite = canvas.create_texture_sprite(Size {w: 200, h: 200}); tex_sprite.set_texture(texture.clone(), Some(Position {x: 0, y: 0})); let mut sub_sprite = canvas.create_texture_sprite(Size {w: 350, h: 427}); @@ -77,6 +79,7 @@ impl Application for ExampleApp { sub_sprite, last_instant, last_offset: 0, + last_pos: Position::origin(), }) } @@ -96,8 +99,10 @@ impl Application for ExampleApp { //state.sub_sprite.for_each(|pix| unsafe {pix.flat = pix.flat.wrapping_add(1);}); state.last_offset += 1; + state.last_pos.x += 1; state.sub_sprite.set_texture(state.texture.clone(), Some(Position {x: state.last_offset, y: 0})); + state.sub_sprite.set_position(state.last_pos); // inputs //if canvas.key_pressed(Key::A) { diff --git a/src/renderer.rs b/src/renderer.rs index a4ad260..4e7ceb9 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -4,9 +4,10 @@ use log::{debug, error, info, trace, warn}; use raw_window_handle::HasRawWindowHandle; use wgpu; use wgpu_hal; +use cgmath::Matrix3; use crate::{ - sprite::Sprite, + sprite::{Sprite, ModelMatrix}, texture::{GpuTexture}, utils::{Pixel, Size}, }; @@ -22,12 +23,16 @@ pub struct WgpuRenderer { device: wgpu::Device, queue: wgpu::Queue, config: wgpu::SurfaceConfiguration, - size: Size, + + surface_size: Size, + aspect_matrix: Matrix3, + output: Option, + texture_bind_group_layout: wgpu::BindGroupLayout, texture_render_pipeline: wgpu::RenderPipeline, + shape_render_pipeline: wgpu::RenderPipeline, quad_mesh: GpuMesh, //TODO temporary, to be moved to shapes.rs - output: Option, } impl WgpuRenderer { @@ -76,6 +81,11 @@ impl WgpuRenderer { }; surface.configure(&device, &config); + let surface_size = size; + let aspect_matrix = Matrix3::from_nonuniform_scale(size.h as f32 / size.w as f32, 1.0); + let output = Some(surface.get_current_texture() + .map_err(|_| "Failed to create SurfaceTexture")?); + let texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[ @@ -235,20 +245,18 @@ impl WgpuRenderer { GpuMesh::create(&device, mesh) }; - let output = Some(surface.get_current_texture() - .map_err(|_| "Failed to create SurfaceTexture")?); - Ok(Self { surface, device, queue, config, - size, + surface_size, + aspect_matrix, + output, texture_bind_group_layout, texture_render_pipeline, shape_render_pipeline, quad_mesh, - output, }) } @@ -277,7 +285,7 @@ impl WgpuRenderer { let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default()); match sprite.render_data() { - RenderData::Texture ((gpu_mesh, texture)) => { + RenderData::Texture ((matrix, gpu_mesh, texture)) => { let mut texture = texture.borrow_mut(); if texture.is_synced == false { @@ -309,13 +317,12 @@ impl WgpuRenderer { render_pass.set_index_buffer(gpu_mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint16); render_pass.set_bind_group(0, &texture.bind_group, &[]); - let matrix = { - use cgmath::SquareMatrix; - cgmath::Matrix3::::from_nonuniform_scale(720.0/1280.0, 1.0) - }; - render_pass.set_push_constants(wgpu::ShaderStages::VERTEX, - 0, - bytemuck::bytes_of(&matrix)); + debug!("mat: {:#?}", matrix.get_matrix()); + render_pass.set_push_constants( + wgpu::ShaderStages::VERTEX, + 0, + bytemuck::bytes_of(&(self.aspect_matrix * matrix.get_matrix())) + ); render_pass.draw_indexed(0..gpu_mesh.index_number, 0, 0..1); drop(render_pass); @@ -363,7 +370,9 @@ impl WgpuRenderer { if size.w == 0 || size.h == 0 { panic!("window has zero as at least one of its dimensions"); } - self.size = size; + + self.surface_size = size; + self.aspect_matrix = Matrix3::from_nonuniform_scale(size.h as f32 / size.w as f32, 1.0); self.config.width = size.w; self.config.height = size.h; self.surface.configure(&self.device, &self.config); @@ -384,7 +393,7 @@ impl WgpuRenderer { .map_err(|err| match err { wgpu::SurfaceError::Lost => { warn!("Lost surface, trying resizing"); - self.resize(self.size); + self.resize(self.surface_size); self.surface.get_current_texture() }, _ => Err(err) @@ -459,7 +468,11 @@ let index_buffer = device.create_buffer( &wgpu_types::BufferDescriptor { } pub enum RenderData<'a> { - Texture ((&'a mut GpuMesh, &'a Rc>)), + Texture (( + &'a mut ModelMatrix, + &'a mut GpuMesh, + &'a Rc>, + )), Shape (&'a GpuMesh), } diff --git a/src/shaders/texture.wgsl b/src/shaders/texture.wgsl index 04111f3..9955b9f 100644 --- a/src/shaders/texture.wgsl +++ b/src/shaders/texture.wgsl @@ -18,7 +18,7 @@ fn vs_main(model: VertexInput) -> VertexOutput { var out: VertexOutput; out.tex_coords = model.tex_coords; out.clip_position - = vec4(model_matrix * vec3(model.position, 0.0), 1.0); + = vec4(model_matrix * vec3(model.position, 1.0), 1.0); return out; } diff --git a/src/sprite.rs b/src/sprite.rs index ea21eb3..d652630 100644 --- a/src/sprite.rs +++ b/src/sprite.rs @@ -8,7 +8,12 @@ use crate::{ utils::{Pixel, Position, Size}, }; -use cgmath::Matrix4; +use cgmath::{ + Deg, + Vector2, + Matrix3, + Matrix4, +}; use std::{ rc::Rc, @@ -26,11 +31,71 @@ pub trait Sprite { fn render_data(&mut self) -> RenderData; } +//--ModelMatrix struct------------------------------------------------------------------------------ +pub struct ModelMatrix { + position: Vector2, + rotation: Deg, + scale: f32, + + matrix: Matrix3, + is_synced: bool, +} + +impl ModelMatrix { + + pub fn new(pos: Vector2, rot: f32, scale: f32) -> Self { + use cgmath::SquareMatrix; + + Self { + position: pos, + rotation: Deg (rot), + scale, + + matrix: Matrix3::identity(), + is_synced: false, + } + } + + pub fn default() -> Self { + Self::new(Vector2 {x: 0.1, y: 0.1}, 0.0, 1.0) + } + + pub fn set_position(&mut self, pos: Vector2) { + self.position = pos; + self.is_synced = false; + } + + pub fn set_rotation(&mut self, rot: f32) { + self.rotation = Deg (rot); + self.is_synced = false; + } + + pub fn set_scale(&mut self, scale: f32) { + self.scale = scale; + self.is_synced = false; + } + + pub fn get_matrix(&mut self) -> Matrix3 { + use cgmath::{Basis3, Rotation3, SquareMatrix}; + + if self.is_synced == false { + let rot_mat = Matrix3::from(Basis3::from_angle_z(self.rotation)); + debug!("rot_mat : {:#?}", rot_mat); + let scale_mat = Matrix3::from_scale(self.scale); + debug!("scale_mat : {:#?}", scale_mat); + let pos_mat = Matrix3::from_translation(self.position); + debug!("pos_mat : {:#?}", pos_mat); + self.matrix = pos_mat * rot_mat * scale_mat; + self.is_synced = true; + } + + self.matrix + } +} + //--TextureSprite struct---------------------------------------------------------------------------- pub struct TextureSprite { - position: Position, - scale: f32, - matrix: Matrix4, + matrix: ModelMatrix, gpu_mesh: GpuMesh, texture: Texture, texture_offset: Position, @@ -41,17 +106,11 @@ impl TextureSprite { pub fn create(texture: Texture, size: Size, gpu_mesh: GpuMesh) -> Self { - let position = Position::origin(); - let scale = 1.0; - let matrix = Matrix4::from_scale(scale) + Matrix4::from_translation(position.into()); - Self { - position, - scale, - matrix, + matrix: ModelMatrix::default(), gpu_mesh, texture, - texture_offset: position, + texture_offset: Position::origin(), texture_size: size, } } @@ -111,24 +170,25 @@ impl TextureSprite { impl Sprite for TextureSprite { - fn set_position(&mut self, _pos: Position) { - unimplemented!(); + fn set_position(&mut self, pos: Position) { + let normalized_pos = Vector2 { x: pos.x as f32 / 720.0, y: pos.y as f32 / 1280.0 }; + self.matrix.set_position(normalized_pos); } - fn set_rotation(&mut self, _rot: f32) { - unimplemented!(); + fn set_rotation(&mut self, rot: f32) { + self.matrix.set_rotation(rot); } fn set_alpha(&mut self, _alpha: u8) { unimplemented!(); } - fn set_scale(&mut self, _scale: f32) { - unimplemented!(); + fn set_scale(&mut self, scale: f32) { + self.matrix.set_scale(scale); } fn render_data(&mut self) -> RenderData { - RenderData::Texture ((&mut self.gpu_mesh, &self.texture.gpu_texture())) + RenderData::Texture ((&mut self.matrix, &mut self.gpu_mesh, &self.texture.gpu_texture())) } }