diff --git a/src/main.rs b/src/main.rs index 4692394..5ffab97 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,11 +63,11 @@ 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: 200, h: 200}); - tex_sprite.set_texture(texture.clone(), Some(Position {x: 0, y: 0})); + let mut tex_sprite = canvas.create_texture_sprite(Size {w: 1280, h: 720}); + tex_sprite.set_texture(texture.clone(), Some(Position {x: 0, y: 0}), 1.0); - let mut sub_sprite = canvas.create_texture_sprite(Size {w: 350, h: 427}); - sub_sprite.set_texture(texture.clone(), Some(Position {x: 350, y: 0})); + let mut sub_sprite = canvas.create_texture_sprite(Size {w: 200, h: 200}); + sub_sprite.set_texture(texture.clone(), Some(Position {x: 350, y: 0}), 1.0); canvas.clear(); canvas.update(); @@ -103,11 +103,12 @@ impl Application for ExampleApp { state.last_offset += 1; state.last_pos.x += 1; state.last_rot += 1.0; + state.tex_sprite.set_texture(state.texture.clone(), None, state.last_rot/100.0); state.sub_sprite.set_texture(state.texture.clone(), - Some(Position {x: state.last_offset, y: 0})); - //state.sub_sprite.set_position(state.last_pos); + Some(Position {x: state.last_offset, y: 0}), 1.0); + state.sub_sprite.set_position(state.last_pos); state.sub_sprite.set_rotation(state.last_rot); - state.sub_sprite.set_scale(state.last_rot/1000.0); + //state.sub_sprite.set_scale(state.last_rot/1000.0); // inputs //if canvas.key_pressed(Key::A) { diff --git a/src/renderer.rs b/src/renderer.rs index 601eb9f..4817e30 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -82,7 +82,9 @@ 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 aspect_matrix + = Matrix3::from_nonuniform_scale(1.0 / size.w as f32, 1.0 / size.h as f32); + let output = Some(surface.get_current_texture() .map_err(|_| "Failed to create SurfaceTexture")?); @@ -320,10 +322,7 @@ impl WgpuRenderer { render_pass.set_push_constants( wgpu::ShaderStages::VERTEX, 0, - bytemuck::bytes_of(&( - self.aspect_matrix - * matrix.compute_matrix(self.surface_size) - )) + bytemuck::bytes_of(&(self.aspect_matrix * matrix.get_matrix())) ); render_pass.draw_indexed(0..gpu_mesh.index_number, 0, 0..1); @@ -374,7 +373,8 @@ impl WgpuRenderer { } self.surface_size = size; - self.aspect_matrix = Matrix3::from_nonuniform_scale(size.h as f32 / size.w as f32, 1.0); + self.aspect_matrix + = Matrix3::from_nonuniform_scale(1.0 / size.w as f32, 1.0 / size.h as f32); self.config.width = size.w; self.config.height = size.h; self.surface.configure(&self.device, &self.config); @@ -433,7 +433,8 @@ where mapped_at_creation: false, } ); -let index_buffer = device.create_buffer( &wgpu_types::BufferDescriptor { + + let index_buffer = device.create_buffer( &wgpu_types::BufferDescriptor { label: Some("Index Buffer"), size: (I_NB * size_of::()) as u64, usage: Usages::INDEX.union(Usages::COPY_DST), diff --git a/src/sprite.rs b/src/sprite.rs index 358fc5d..a96b40b 100644 --- a/src/sprite.rs +++ b/src/sprite.rs @@ -5,7 +5,7 @@ use crate::{ renderer::{Mesh, GpuMesh, RenderData, TextureVertex}, shape::Shape, texture::Texture, - utils::{Pixel, Position, Size}, + utils::{Pixel, Position, Size, NormalizedSize}, }; use cgmath::{ @@ -75,14 +75,14 @@ impl ModelMatrix { self.is_synced = false; } - pub fn compute_matrix(&mut self, size: Size) -> Matrix3 { + pub fn get_matrix(&mut self) -> Matrix3 { use cgmath::{Basis3, Rotation3, SquareMatrix}; if self.is_synced == false { let pos_vec = Vector2 { - x: self.position.x as f32 / size.w as f32, - y: self.position.y as f32 / size.h as f32, + x: self.position.x as f32, + y: self.position.y as f32, }; let rotation_mat = Matrix3::from(Basis3::from_angle_z(self.rotation)); let scale_mat = Matrix3::from_scale(self.scale); @@ -100,54 +100,68 @@ impl ModelMatrix { pub struct TextureSprite { matrix: ModelMatrix, gpu_mesh: GpuMesh, + inner_size: Size, //TODO move to f32 + texture: Texture, texture_offset: Position, - texture_size: Size, + texture_scale: f32, } impl TextureSprite { pub fn create(texture: Texture, size: Size, gpu_mesh: GpuMesh) -> Self { - Self { + let mut sprite = Self { matrix: ModelMatrix::default(), gpu_mesh, - texture, + inner_size: size, + + texture: texture.clone(), texture_offset: Position::origin(), - texture_size: size, - } + texture_scale: 1.0, + }; + + //generate proper mesh + //TODO improve that + sprite.set_texture(texture, None, 1.0); + sprite } - pub fn set_texture(&mut self, texture: Texture, offset: Option) { + pub fn set_texture(&mut self, texture: Texture, offset: Option, scale: f32) { // update texture self.texture = texture; + self.texture_scale = scale; let size = self.texture.get_size(); // compute normalized coordinates self.texture_offset = offset.unwrap_or(Position::origin()); - let x_size = self.texture_size.w as f32 / size.w as f32; - let y_size = self.texture_size.h as f32 / size.h as f32; + let x_size = self.inner_size.w as f32 / size.w as f32 * scale; + let y_size = self.inner_size.h as f32 / size.h as f32 * scale; let x_offset = self.texture_offset.x as f32 / size.w as f32; let y_offset = self.texture_offset.y as f32 / size.h as f32; + // compute mesh size + let w = self.inner_size.w as f32; + let h = self.inner_size.h as f32; + // generate new sprite mesh let mesh = Mesh { vertices: [ TextureVertex { - position: [-0.5, -0.5], + position: [-w, -h], tex_coords: [x_offset , y_offset + y_size], }, TextureVertex { - position: [ 0.5, -0.5], + position: [ w, -h], tex_coords: [x_offset + x_size, y_offset + y_size], }, TextureVertex { - position: [ 0.5, 0.5], + position: [ w, h], tex_coords: [x_offset + x_size, y_offset ], }, TextureVertex { - position: [-0.5, 0.5], + position: [-w, h], tex_coords: [x_offset , y_offset ], }, ], @@ -167,7 +181,8 @@ impl TextureSprite { pub fn for_each(&mut self, func: F) { //TODO check pos ? - self.texture.for_each_in_area(func, self.texture_offset, self.texture_size); + //TODO take scale into account + self.texture.for_each_in_area(func, self.texture_offset, self.inner_size); } } diff --git a/src/utils.rs b/src/utils.rs index 4e5959e..ecda784 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -79,6 +79,24 @@ impl From> for Size { } } +//--NormalizedSize struct--------------------------------------------------------------------------- +#[derive(Copy, Clone)] +pub struct NormalizedSize { + pub w: f32, + pub h: f32, +} + +impl NormalizedSize { + + pub fn from_size(size: Size, surface_size: Size) -> Self { + + Self { + w: size.w as f32 / surface_size.w as f32, + h: size.h as f32 / surface_size.h as f32, + } + } +} + //--Pixel struct------------------------------------------------------------------------------------ #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[repr(C)]