From 3a630fefaf92d2bb4e39d959805ba8ec0f75dca2 Mon Sep 17 00:00:00 2001 From: Steins7 Date: Tue, 3 Jan 2023 22:29:27 +0100 Subject: [PATCH] Fix matrix transformation issues --- src/lib.rs | 2 +- src/main.rs | 74 +++++++++++++++------------------ src/renderer.rs | 4 ++ src/renderer/matrix.rs | 33 +++++++++------ src/sprite/shaders/texture.wgsl | 8 ++-- src/sprite/texture_sprite.rs | 3 +- src/utils.rs | 18 +++++++- 7 files changed, 81 insertions(+), 61 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 65ba04c..9902dc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -106,7 +106,7 @@ mod tests { message )) }) - .level(log::LevelFilter::Trace) + .level(log::LevelFilter::Debug) .chain(std::io::stdout()) .chain(fern::log_file("output.log")?) .apply()?; diff --git a/src/main.rs b/src/main.rs index 83209d6..81bb219 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,7 +30,7 @@ fn setup_logger() -> Result<(), fern::InitError> { message )) }) - .level(log::LevelFilter::Info) + .level(log::LevelFilter::Debug) .chain(std::io::stdout()) .chain(fern::log_file("output.log")?) .apply()?; Ok(()) @@ -40,7 +40,8 @@ struct ExampleState { pub texture: TextureHandle, pub tex_sprite: TextureSprite, pub sub_sprite: TextureSprite, - pub txt_sprites: Vec, + pub sub_sprite2: TextureSprite, + pub txt_sprite: TextSprite, pub last_instant: Instant, pub last_offset: u32, pub last_pos: Position, @@ -63,18 +64,21 @@ impl Application for ExampleApp { .unwrap(); 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); + tex_sprite.set_position(Position {x: 1280/2, y: 720/2}); let mut sub_sprite = canvas.create_texture_sprite(Size {w: 100, h: 100}); - sub_sprite.set_texture(texture.clone(), Some(Position {x: 350, y: 0}), 1.0); + sub_sprite.set_texture(texture.clone(), Some(Position {x: 0, y: 0}), 1.0); + sub_sprite.set_position(Position {x: 0, y: 0}); + sub_sprite.set_scale(2.0); - let mut txt_sprites = Vec::::with_capacity(10); - for x in 0..10 { - for y in 0..5 { - let mut sprite = canvas.create_text_sprite("00", Size {w: 200, h: 200}, 11.0); - sprite.set_position(Position { x: x * 100, y: y * 100}); - txt_sprites.push(sprite); - } - } + let mut sub_sprite2 = canvas.create_texture_sprite(Size {w: 200, h: 200}); + sub_sprite2.set_texture(texture.clone(), Some(Position {x: 100, y: 0}), 1.0); + sub_sprite2.set_rotation(0.0); + sub_sprite2.set_position(Position {x: 0, y: 0}); + + let mut txt_sprite = canvas.create_text_sprite("00", Size {w: 100, h: 100}, 22.0); + txt_sprite.set_position(Position {x:50, y: 720-50}); + txt_sprite.set_scale(1.0); canvas.clear(); canvas.update(); @@ -85,10 +89,11 @@ impl Application for ExampleApp { texture, tex_sprite, sub_sprite, - txt_sprites, + sub_sprite2, + txt_sprite, last_instant, last_offset: 0, - last_pos: Position::origin(), + last_pos: Position {x: 0, y: 0}, last_rot: 0.0, frame_counter: 0, }) @@ -107,40 +112,29 @@ impl Application for ExampleApp { state.frame_counter += 1; if state.frame_counter >= 60 { state.frame_counter = 0; - - for sprite in state.txt_sprites.iter_mut() { - sprite.set_text(&format!("{}", elapsed)); - sprite.set_text_size(elapsed as f32); - } + state.txt_sprite.set_text(&format!("{}", elapsed)); + state.txt_sprite.set_text_size(elapsed as f32); } match state.frame_counter { - 0 => { - for sprite in state.txt_sprites.iter_mut() { - sprite.set_color(Color::RED); - } - }, - 20 => { - for sprite in state.txt_sprites.iter_mut() { - sprite.set_color(Color::BLUE); - } - }, - 40 => { - for sprite in state.txt_sprites.iter_mut() { - sprite.set_color(Color::GREEN); - } - }, + 0 => state.txt_sprite.set_color(Color::RED), + 20 => state.txt_sprite.set_color(Color::BLUE), + 40 => state.txt_sprite.set_color(Color::GREEN), _ => (), } //state.sub_sprite.for_each(|pix| unsafe {pix.flat = pix.flat.wrapping_add(1);}); - state.last_offset += 1; + // state.last_offset += 1; + state.last_pos.x += 1; state.last_pos.y += 1; state.last_rot += 1.0; + debug!("{:#?}", state.last_pos); 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}), 1.0); + // state.sub_sprite.set_texture(state.texture.clone(), + // Some(Position {x: state.last_offset, y: 0}), 1.0); state.sub_sprite.set_position(state.last_pos); + state.sub_sprite2.set_position(state.last_pos); state.sub_sprite.set_rotation(state.last_rot); + state.sub_sprite2.set_rotation(state.last_rot + 45.0); //state.sub_sprite.set_scale(state.last_rot/1000.0); @@ -153,6 +147,7 @@ impl Application for ExampleApp { // unimplemented!(); //} // + // //match canvas.get_key_presses() { // Key::A => unimplemented!(), // _ => (), @@ -200,10 +195,9 @@ impl Application for ExampleApp { canvas.draw(&mut state.tex_sprite); - // canvas.draw(&mut state.sub_sprite); - for sprite in state.txt_sprites.iter_mut() { - canvas.draw(sprite); - } + canvas.draw(&mut state.sub_sprite2); + canvas.draw(&mut state.txt_sprite); + canvas.draw(&mut state.sub_sprite); canvas.update(); Ok(()) diff --git a/src/renderer.rs b/src/renderer.rs index c29662a..30a17d7 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -96,6 +96,10 @@ impl WgpuRenderer { }) } + pub fn get_surface_size(&self) -> Size { + self.surface_size + } + pub fn clear(&mut self, color: Pixel) { let view = self.create_texture_view(); diff --git a/src/renderer/matrix.rs b/src/renderer/matrix.rs index ef825fb..fad06c9 100644 --- a/src/renderer/matrix.rs +++ b/src/renderer/matrix.rs @@ -18,6 +18,7 @@ pub struct ModelMatrix { position: Position, rotation: Deg, scale: f32, + aspect_matrix: Matrix3, uniform: Uniform, is_synced: bool, @@ -31,13 +32,19 @@ impl ModelMatrix { scale: f32) -> Self { + let surface_size: Vector2 = renderer.get_surface_size().into(); + //A factor 2 is used so scales and offsets can be in sync with the translations wich are + //smaller by a factor 2, and I have no idea why. + let aspect_matrix = Matrix3::from_nonuniform_scale(2.0/surface_size.x, 2.0/surface_size.y) + * Matrix3::from_translation(-surface_size/2.0); - Self { - position: pos, - rotation: Deg (rot), - scale, + Self { + position: pos, + rotation: Deg (rot), + scale, + aspect_matrix, - uniform: Uniform::create(renderer, &renderer.matrix_layout), + uniform: Uniform::create(renderer, &renderer.matrix_layout), is_synced: false, } } @@ -66,17 +73,17 @@ impl ModelMatrix { if self.is_synced == false { - let pos_vec = Vector2 { - x: self.position.x as f32, - y: self.position.y as f32, - }; + let translation_mat = Matrix3::from_translation(self.position.into()); let rotation_mat = Matrix3::from(Basis3::from_angle_z(self.rotation)); - let scale_mat = Matrix3::from_scale(self.scale); - let translation_mat = Matrix3::from_translation(pos_vec); - let aspect_mat = Matrix3::from_nonuniform_scale(1.0/1280.0, 1.0/720.0); + //same factor 2 as for the aspect ratio and the offset, no idea why its needed either + let scale_mat = Matrix3::from_scale(self.scale/2.0); + + let matrix = self.aspect_matrix * translation_mat * scale_mat * rotation_mat; - let matrix = aspect_mat * translation_mat * rotation_mat * scale_mat; let mat_bytes: [u8; 36] = bytemuck::bytes_of(&matrix).try_into().unwrap(); + + //wgsl uses 16 bytes-aligned matrixes, but ours is 12 bytes-aligned. Fix that by adding + //4 paddings bytes after each 12 bytes let mut bytes = [0; 48]; for i in 0..12 { bytes[i] = mat_bytes[i]; diff --git a/src/sprite/shaders/texture.wgsl b/src/sprite/shaders/texture.wgsl index db20088..fb87586 100644 --- a/src/sprite/shaders/texture.wgsl +++ b/src/sprite/shaders/texture.wgsl @@ -14,12 +14,12 @@ struct VertexOutput { var model_matrix: mat3x3; @vertex -fn vs_main(model: VertexInput) -> VertexOutput { +fn vs_main(vertex: VertexInput) -> VertexOutput { var out: VertexOutput; - out.tex_coords = model.tex_coords; - out.clip_position - = vec4(model_matrix * vec3(model.position, 1.0), 1.0); + out.tex_coords = vertex.tex_coords; + out.clip_position + = vec4(model_matrix * vec3(vertex.position, 1.0), 1.0); return out; } diff --git a/src/sprite/texture_sprite.rs b/src/sprite/texture_sprite.rs index 854d0f0..0f433b7 100644 --- a/src/sprite/texture_sprite.rs +++ b/src/sprite/texture_sprite.rs @@ -42,7 +42,8 @@ impl TextureSprite { ]; pub fn new(texture: TextureHandle, - size: Size, renderer: &WgpuRenderer) + size: Size, + renderer: &WgpuRenderer) -> Self { // initialize pipeline if needed diff --git a/src/utils.rs b/src/utils.rs index 2639f5a..14a8393 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -3,10 +3,10 @@ use log::{debug, error, info, trace, warn}; use winit; -use cgmath::Vector3; +use cgmath::{Vector3, Vector2}; //--Position struct--------------------------------------------------------------------------------- -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub struct Position { pub x: u32, pub y: u32, @@ -29,6 +29,13 @@ impl From for Vector3 { } } +impl From for Vector2 { + + fn from(pos: Position) -> Self { + Self::new(pos.x as f32, pos.y as f32) + } +} + impl std::ops::Add for Position { type Output = Self; @@ -79,6 +86,13 @@ impl From> for Size { } } +impl From for Vector2 { + + fn from(size: Size) -> Self { + Self::new(size.w as f32, size.h as f32) + } +} + //--Pixel struct------------------------------------------------------------------------------------ #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[repr(C)]