Fix matrix transformation issues

This commit is contained in:
Steins7 2023-01-03 22:29:27 +01:00 committed by Steins7
parent 32bfe01a1e
commit 3a630fefaf
7 changed files with 81 additions and 61 deletions

View File

@ -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()?;

View File

@ -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<TextSprite>,
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<ExampleState> 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::<TextSprite>::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<ExampleState> 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<ExampleState> 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<ExampleState> for ExampleApp {
// unimplemented!();
//}
//
//
//match canvas.get_key_presses() {
// Key::A => unimplemented!(),
// _ => (),
@ -200,10 +195,9 @@ impl Application<ExampleState> 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(())

View File

@ -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();

View File

@ -18,6 +18,7 @@ pub struct ModelMatrix {
position: Position,
rotation: Deg<f32>,
scale: f32,
aspect_matrix: Matrix3<f32>,
uniform: Uniform<MATRIX_SIZE>,
is_synced: bool,
@ -31,13 +32,19 @@ impl ModelMatrix {
scale: f32)
-> Self
{
let surface_size: Vector2<f32> = 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];

View File

@ -14,12 +14,12 @@ struct VertexOutput {
var<uniform> model_matrix: mat3x3<f32>;
@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<f32>(model_matrix * vec3<f32>(model.position, 1.0), 1.0);
out.tex_coords = vertex.tex_coords;
out.clip_position
= vec4<f32>(model_matrix * vec3<f32>(vertex.position, 1.0), 1.0);
return out;
}

View File

@ -42,7 +42,8 @@ impl TextureSprite {
];
pub fn new(texture: TextureHandle,
size: Size, renderer: &WgpuRenderer)
size: Size,
renderer: &WgpuRenderer)
-> Self
{
// initialize pipeline if needed

View File

@ -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<Position> for Vector3<f32> {
}
}
impl From<Position> for Vector2<f32> {
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<winit::dpi::PhysicalSize<u32>> for Size {
}
}
impl From<Size> for Vector2<f32> {
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)]