Fix matrix transformation issues
This commit is contained in:
parent
67f802dd77
commit
b524ad07e0
@ -106,7 +106,7 @@ mod tests {
|
|||||||
message
|
message
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.level(log::LevelFilter::Trace)
|
.level(log::LevelFilter::Debug)
|
||||||
.chain(std::io::stdout())
|
.chain(std::io::stdout())
|
||||||
.chain(fern::log_file("output.log")?)
|
.chain(fern::log_file("output.log")?)
|
||||||
.apply()?;
|
.apply()?;
|
||||||
|
|||||||
74
src/main.rs
74
src/main.rs
@ -30,7 +30,7 @@ fn setup_logger() -> Result<(), fern::InitError> {
|
|||||||
message
|
message
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.level(log::LevelFilter::Info)
|
.level(log::LevelFilter::Debug)
|
||||||
.chain(std::io::stdout())
|
.chain(std::io::stdout())
|
||||||
.chain(fern::log_file("output.log")?)
|
.chain(fern::log_file("output.log")?)
|
||||||
.apply()?; Ok(())
|
.apply()?; Ok(())
|
||||||
@ -40,7 +40,8 @@ struct ExampleState {
|
|||||||
pub texture: TextureHandle,
|
pub texture: TextureHandle,
|
||||||
pub tex_sprite: TextureSprite,
|
pub tex_sprite: TextureSprite,
|
||||||
pub sub_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_instant: Instant,
|
||||||
pub last_offset: u32,
|
pub last_offset: u32,
|
||||||
pub last_pos: Position,
|
pub last_pos: Position,
|
||||||
@ -63,18 +64,21 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let mut tex_sprite = canvas.create_texture_sprite(Size {w: 1280, h: 720});
|
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_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});
|
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);
|
let mut sub_sprite2 = canvas.create_texture_sprite(Size {w: 200, h: 200});
|
||||||
for x in 0..10 {
|
sub_sprite2.set_texture(texture.clone(), Some(Position {x: 100, y: 0}), 1.0);
|
||||||
for y in 0..5 {
|
sub_sprite2.set_rotation(0.0);
|
||||||
let mut sprite = canvas.create_text_sprite("00", Size {w: 200, h: 200}, 11.0);
|
sub_sprite2.set_position(Position {x: 0, y: 0});
|
||||||
sprite.set_position(Position { x: x * 100, y: y * 100});
|
|
||||||
txt_sprites.push(sprite);
|
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.clear();
|
||||||
canvas.update();
|
canvas.update();
|
||||||
@ -85,10 +89,11 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
texture,
|
texture,
|
||||||
tex_sprite,
|
tex_sprite,
|
||||||
sub_sprite,
|
sub_sprite,
|
||||||
txt_sprites,
|
sub_sprite2,
|
||||||
|
txt_sprite,
|
||||||
last_instant,
|
last_instant,
|
||||||
last_offset: 0,
|
last_offset: 0,
|
||||||
last_pos: Position::origin(),
|
last_pos: Position {x: 0, y: 0},
|
||||||
last_rot: 0.0,
|
last_rot: 0.0,
|
||||||
frame_counter: 0,
|
frame_counter: 0,
|
||||||
})
|
})
|
||||||
@ -107,40 +112,29 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
state.frame_counter += 1;
|
state.frame_counter += 1;
|
||||||
if state.frame_counter >= 60 {
|
if state.frame_counter >= 60 {
|
||||||
state.frame_counter = 0;
|
state.frame_counter = 0;
|
||||||
|
state.txt_sprite.set_text(&format!("{}", elapsed));
|
||||||
for sprite in state.txt_sprites.iter_mut() {
|
state.txt_sprite.set_text_size(elapsed as f32);
|
||||||
sprite.set_text(&format!("{}", elapsed));
|
|
||||||
sprite.set_text_size(elapsed as f32);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
match state.frame_counter {
|
match state.frame_counter {
|
||||||
0 => {
|
0 => state.txt_sprite.set_color(Color::RED),
|
||||||
for sprite in state.txt_sprites.iter_mut() {
|
20 => state.txt_sprite.set_color(Color::BLUE),
|
||||||
sprite.set_color(Color::RED);
|
40 => state.txt_sprite.set_color(Color::GREEN),
|
||||||
}
|
|
||||||
},
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
//state.sub_sprite.for_each(|pix| unsafe {pix.flat = pix.flat.wrapping_add(1);});
|
//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_pos.y += 1;
|
||||||
state.last_rot += 1.0;
|
state.last_rot += 1.0;
|
||||||
|
debug!("{:#?}", state.last_pos);
|
||||||
state.tex_sprite.set_texture(state.texture.clone(), None, state.last_rot/100.0);
|
state.tex_sprite.set_texture(state.texture.clone(), None, state.last_rot/100.0);
|
||||||
state.sub_sprite.set_texture(state.texture.clone(),
|
// state.sub_sprite.set_texture(state.texture.clone(),
|
||||||
Some(Position {x: state.last_offset, y: 0}), 1.0);
|
// Some(Position {x: state.last_offset, y: 0}), 1.0);
|
||||||
state.sub_sprite.set_position(state.last_pos);
|
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_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);
|
//state.sub_sprite.set_scale(state.last_rot/1000.0);
|
||||||
|
|
||||||
@ -153,6 +147,7 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
// unimplemented!();
|
// unimplemented!();
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
|
//
|
||||||
//match canvas.get_key_presses() {
|
//match canvas.get_key_presses() {
|
||||||
// Key::A => unimplemented!(),
|
// Key::A => unimplemented!(),
|
||||||
// _ => (),
|
// _ => (),
|
||||||
@ -200,10 +195,9 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
|
|
||||||
|
|
||||||
canvas.draw(&mut state.tex_sprite);
|
canvas.draw(&mut state.tex_sprite);
|
||||||
// canvas.draw(&mut state.sub_sprite);
|
canvas.draw(&mut state.sub_sprite2);
|
||||||
for sprite in state.txt_sprites.iter_mut() {
|
canvas.draw(&mut state.txt_sprite);
|
||||||
canvas.draw(sprite);
|
canvas.draw(&mut state.sub_sprite);
|
||||||
}
|
|
||||||
canvas.update();
|
canvas.update();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -96,6 +96,10 @@ impl WgpuRenderer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_surface_size(&self) -> Size {
|
||||||
|
self.surface_size
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self, color: Pixel) {
|
pub fn clear(&mut self, color: Pixel) {
|
||||||
|
|
||||||
let view = self.create_texture_view();
|
let view = self.create_texture_view();
|
||||||
|
|||||||
@ -18,6 +18,7 @@ pub struct ModelMatrix {
|
|||||||
position: Position,
|
position: Position,
|
||||||
rotation: Deg<f32>,
|
rotation: Deg<f32>,
|
||||||
scale: f32,
|
scale: f32,
|
||||||
|
aspect_matrix: Matrix3<f32>,
|
||||||
|
|
||||||
uniform: Uniform<MATRIX_SIZE>,
|
uniform: Uniform<MATRIX_SIZE>,
|
||||||
is_synced: bool,
|
is_synced: bool,
|
||||||
@ -31,13 +32,19 @@ impl ModelMatrix {
|
|||||||
scale: f32)
|
scale: f32)
|
||||||
-> Self
|
-> 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 {
|
Self {
|
||||||
position: pos,
|
position: pos,
|
||||||
rotation: Deg (rot),
|
rotation: Deg (rot),
|
||||||
scale,
|
scale,
|
||||||
|
aspect_matrix,
|
||||||
|
|
||||||
uniform: Uniform::create(renderer, &renderer.matrix_layout),
|
uniform: Uniform::create(renderer, &renderer.matrix_layout),
|
||||||
is_synced: false,
|
is_synced: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,17 +73,17 @@ impl ModelMatrix {
|
|||||||
|
|
||||||
if self.is_synced == false {
|
if self.is_synced == false {
|
||||||
|
|
||||||
let pos_vec = Vector2 {
|
let translation_mat = Matrix3::from_translation(self.position.into());
|
||||||
x: self.position.x as f32,
|
|
||||||
y: self.position.y as f32,
|
|
||||||
};
|
|
||||||
let rotation_mat = Matrix3::from(Basis3::from_angle_z(self.rotation));
|
let rotation_mat = Matrix3::from(Basis3::from_angle_z(self.rotation));
|
||||||
let scale_mat = Matrix3::from_scale(self.scale);
|
//same factor 2 as for the aspect ratio and the offset, no idea why its needed either
|
||||||
let translation_mat = Matrix3::from_translation(pos_vec);
|
let scale_mat = Matrix3::from_scale(self.scale/2.0);
|
||||||
let aspect_mat = Matrix3::from_nonuniform_scale(1.0/1280.0, 1.0/720.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();
|
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];
|
let mut bytes = [0; 48];
|
||||||
for i in 0..12 {
|
for i in 0..12 {
|
||||||
bytes[i] = mat_bytes[i];
|
bytes[i] = mat_bytes[i];
|
||||||
|
|||||||
@ -14,12 +14,12 @@ struct VertexOutput {
|
|||||||
var<uniform> model_matrix: mat3x3<f32>;
|
var<uniform> model_matrix: mat3x3<f32>;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(model: VertexInput) -> VertexOutput {
|
fn vs_main(vertex: VertexInput) -> VertexOutput {
|
||||||
|
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.tex_coords = model.tex_coords;
|
out.tex_coords = vertex.tex_coords;
|
||||||
out.clip_position
|
out.clip_position
|
||||||
= vec4<f32>(model_matrix * vec3<f32>(model.position, 1.0), 1.0);
|
= vec4<f32>(model_matrix * vec3<f32>(vertex.position, 1.0), 1.0);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,8 @@ impl TextureSprite {
|
|||||||
];
|
];
|
||||||
|
|
||||||
pub fn new(texture: TextureHandle,
|
pub fn new(texture: TextureHandle,
|
||||||
size: Size, renderer: &WgpuRenderer)
|
size: Size,
|
||||||
|
renderer: &WgpuRenderer)
|
||||||
-> Self
|
-> Self
|
||||||
{
|
{
|
||||||
// initialize pipeline if needed
|
// initialize pipeline if needed
|
||||||
|
|||||||
18
src/utils.rs
18
src/utils.rs
@ -3,10 +3,10 @@ use log::{debug, error, info, trace, warn};
|
|||||||
|
|
||||||
use winit;
|
use winit;
|
||||||
|
|
||||||
use cgmath::Vector3;
|
use cgmath::{Vector3, Vector2};
|
||||||
|
|
||||||
//--Position struct---------------------------------------------------------------------------------
|
//--Position struct---------------------------------------------------------------------------------
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
pub x: u32,
|
pub x: u32,
|
||||||
pub y: 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 {
|
impl std::ops::Add for Position {
|
||||||
type Output = Self;
|
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------------------------------------------------------------------------------------
|
//--Pixel struct------------------------------------------------------------------------------------
|
||||||
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user