Got the matrix system working

Surface size is hardcoded for now
This commit is contained in:
Steins7 2022-08-20 16:35:32 +02:00
parent 1081051084
commit 1e9fb49a49
4 changed files with 118 additions and 40 deletions

View File

@ -6,6 +6,7 @@ use canvas::{
Canvas, Canvas,
texture::Texture, texture::Texture,
sprite::TextureSprite, sprite::TextureSprite,
utils::Position,
}; };
use std::{ use std::{
@ -46,6 +47,7 @@ struct ExampleState {
pub sub_sprite: TextureSprite, pub sub_sprite: TextureSprite,
pub last_instant: Instant, pub last_instant: Instant,
pub last_offset: u32, pub last_offset: u32,
pub last_pos: Position,
} }
struct ExampleApp {} struct ExampleApp {}
@ -60,7 +62,7 @@ impl Application<ExampleState> for ExampleApp {
//// 20 x 20 sprite of a picture //// 20 x 20 sprite of a picture
let texture = canvas.create_texture_from_file("assets/camel.jpg", None, None, None) let texture = canvas.create_texture_from_file("assets/camel.jpg", None, None, None)
.unwrap(); .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})); 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}); let mut sub_sprite = canvas.create_texture_sprite(Size {w: 350, h: 427});
@ -77,6 +79,7 @@ impl Application<ExampleState> for ExampleApp {
sub_sprite, sub_sprite,
last_instant, last_instant,
last_offset: 0, last_offset: 0,
last_pos: Position::origin(),
}) })
} }
@ -96,8 +99,10 @@ impl Application<ExampleState> for ExampleApp {
//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.sub_sprite.set_texture(state.texture.clone(), state.sub_sprite.set_texture(state.texture.clone(),
Some(Position {x: state.last_offset, y: 0})); Some(Position {x: state.last_offset, y: 0}));
state.sub_sprite.set_position(state.last_pos);
// inputs // inputs
//if canvas.key_pressed(Key::A) { //if canvas.key_pressed(Key::A) {

View File

@ -4,9 +4,10 @@ use log::{debug, error, info, trace, warn};
use raw_window_handle::HasRawWindowHandle; use raw_window_handle::HasRawWindowHandle;
use wgpu; use wgpu;
use wgpu_hal; use wgpu_hal;
use cgmath::Matrix3;
use crate::{ use crate::{
sprite::Sprite, sprite::{Sprite, ModelMatrix},
texture::{GpuTexture}, texture::{GpuTexture},
utils::{Pixel, Size}, utils::{Pixel, Size},
}; };
@ -22,12 +23,16 @@ pub struct WgpuRenderer {
device: wgpu::Device, device: wgpu::Device,
queue: wgpu::Queue, queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration, config: wgpu::SurfaceConfiguration,
size: Size,
surface_size: Size,
aspect_matrix: Matrix3<f32>,
output: Option<wgpu::SurfaceTexture>,
texture_bind_group_layout: wgpu::BindGroupLayout, texture_bind_group_layout: wgpu::BindGroupLayout,
texture_render_pipeline: wgpu::RenderPipeline, texture_render_pipeline: wgpu::RenderPipeline,
shape_render_pipeline: wgpu::RenderPipeline, shape_render_pipeline: wgpu::RenderPipeline,
quad_mesh: GpuMesh<ColorVertex, 4, 6>, //TODO temporary, to be moved to shapes.rs quad_mesh: GpuMesh<ColorVertex, 4, 6>, //TODO temporary, to be moved to shapes.rs
output: Option<wgpu::SurfaceTexture>,
} }
impl WgpuRenderer { impl WgpuRenderer {
@ -76,6 +81,11 @@ impl WgpuRenderer {
}; };
surface.configure(&device, &config); 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 = let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[ entries: &[
@ -235,20 +245,18 @@ impl WgpuRenderer {
GpuMesh::create(&device, mesh) GpuMesh::create(&device, mesh)
}; };
let output = Some(surface.get_current_texture()
.map_err(|_| "Failed to create SurfaceTexture")?);
Ok(Self { Ok(Self {
surface, surface,
device, device,
queue, queue,
config, config,
size, surface_size,
aspect_matrix,
output,
texture_bind_group_layout, texture_bind_group_layout,
texture_render_pipeline, texture_render_pipeline,
shape_render_pipeline, shape_render_pipeline,
quad_mesh, quad_mesh,
output,
}) })
} }
@ -277,7 +285,7 @@ impl WgpuRenderer {
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default()); let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
match sprite.render_data() { match sprite.render_data() {
RenderData::Texture ((gpu_mesh, texture)) => { RenderData::Texture ((matrix, gpu_mesh, texture)) => {
let mut texture = texture.borrow_mut(); let mut texture = texture.borrow_mut();
if texture.is_synced == false { if texture.is_synced == false {
@ -309,13 +317,12 @@ impl WgpuRenderer {
render_pass.set_index_buffer(gpu_mesh.index_buffer.slice(..), render_pass.set_index_buffer(gpu_mesh.index_buffer.slice(..),
wgpu::IndexFormat::Uint16); wgpu::IndexFormat::Uint16);
render_pass.set_bind_group(0, &texture.bind_group, &[]); render_pass.set_bind_group(0, &texture.bind_group, &[]);
let matrix = { debug!("mat: {:#?}", matrix.get_matrix());
use cgmath::SquareMatrix; render_pass.set_push_constants(
cgmath::Matrix3::<f32>::from_nonuniform_scale(720.0/1280.0, 1.0) wgpu::ShaderStages::VERTEX,
};
render_pass.set_push_constants(wgpu::ShaderStages::VERTEX,
0, 0,
bytemuck::bytes_of(&matrix)); bytemuck::bytes_of(&(self.aspect_matrix * matrix.get_matrix()))
);
render_pass.draw_indexed(0..gpu_mesh.index_number, 0, 0..1); render_pass.draw_indexed(0..gpu_mesh.index_number, 0, 0..1);
drop(render_pass); drop(render_pass);
@ -363,7 +370,9 @@ impl WgpuRenderer {
if size.w == 0 || size.h == 0 { if size.w == 0 || size.h == 0 {
panic!("window has zero as at least one of its dimensions"); 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.width = size.w;
self.config.height = size.h; self.config.height = size.h;
self.surface.configure(&self.device, &self.config); self.surface.configure(&self.device, &self.config);
@ -384,7 +393,7 @@ impl WgpuRenderer {
.map_err(|err| match err { .map_err(|err| match err {
wgpu::SurfaceError::Lost => { wgpu::SurfaceError::Lost => {
warn!("Lost surface, trying resizing"); warn!("Lost surface, trying resizing");
self.resize(self.size); self.resize(self.surface_size);
self.surface.get_current_texture() self.surface.get_current_texture()
}, },
_ => Err(err) _ => Err(err)
@ -459,7 +468,11 @@ let index_buffer = device.create_buffer( &wgpu_types::BufferDescriptor {
} }
pub enum RenderData<'a> { pub enum RenderData<'a> {
Texture ((&'a mut GpuMesh<TextureVertex, 4, 6>, &'a Rc<RefCell<GpuTexture>>)), Texture ((
&'a mut ModelMatrix,
&'a mut GpuMesh<TextureVertex, 4, 6>,
&'a Rc<RefCell<GpuTexture>>,
)),
Shape (&'a GpuMesh<ColorVertex, 4, 6>), Shape (&'a GpuMesh<ColorVertex, 4, 6>),
} }

View File

@ -18,7 +18,7 @@ fn vs_main(model: VertexInput) -> VertexOutput {
var out: VertexOutput; var out: VertexOutput;
out.tex_coords = model.tex_coords; out.tex_coords = model.tex_coords;
out.clip_position out.clip_position
= vec4<f32>(model_matrix * vec3<f32>(model.position, 0.0), 1.0); = vec4<f32>(model_matrix * vec3<f32>(model.position, 1.0), 1.0);
return out; return out;
} }

View File

@ -8,7 +8,12 @@ use crate::{
utils::{Pixel, Position, Size}, utils::{Pixel, Position, Size},
}; };
use cgmath::Matrix4; use cgmath::{
Deg,
Vector2,
Matrix3,
Matrix4,
};
use std::{ use std::{
rc::Rc, rc::Rc,
@ -26,11 +31,71 @@ pub trait Sprite {
fn render_data(&mut self) -> RenderData; fn render_data(&mut self) -> RenderData;
} }
//--ModelMatrix struct------------------------------------------------------------------------------
pub struct ModelMatrix {
position: Vector2<f32>,
rotation: Deg<f32>,
scale: f32,
matrix: Matrix3<f32>,
is_synced: bool,
}
impl ModelMatrix {
pub fn new(pos: Vector2<f32>, 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<f32>) {
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<f32> {
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---------------------------------------------------------------------------- //--TextureSprite struct----------------------------------------------------------------------------
pub struct TextureSprite { pub struct TextureSprite {
position: Position, matrix: ModelMatrix,
scale: f32,
matrix: Matrix4<f32>,
gpu_mesh: GpuMesh<TextureVertex, 4, 6>, gpu_mesh: GpuMesh<TextureVertex, 4, 6>,
texture: Texture, texture: Texture,
texture_offset: Position, texture_offset: Position,
@ -41,17 +106,11 @@ impl TextureSprite {
pub fn create(texture: Texture, size: Size, gpu_mesh: GpuMesh<TextureVertex, 4, 6>) -> Self { pub fn create(texture: Texture, size: Size, gpu_mesh: GpuMesh<TextureVertex, 4, 6>) -> Self {
let position = Position::origin();
let scale = 1.0;
let matrix = Matrix4::from_scale(scale) + Matrix4::from_translation(position.into());
Self { Self {
position, matrix: ModelMatrix::default(),
scale,
matrix,
gpu_mesh, gpu_mesh,
texture, texture,
texture_offset: position, texture_offset: Position::origin(),
texture_size: size, texture_size: size,
} }
} }
@ -111,24 +170,25 @@ impl TextureSprite {
impl Sprite for TextureSprite { impl Sprite for TextureSprite {
fn set_position(&mut self, _pos: Position) { fn set_position(&mut self, pos: Position) {
unimplemented!(); 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) { fn set_rotation(&mut self, rot: f32) {
unimplemented!(); self.matrix.set_rotation(rot);
} }
fn set_alpha(&mut self, _alpha: u8) { fn set_alpha(&mut self, _alpha: u8) {
unimplemented!(); unimplemented!();
} }
fn set_scale(&mut self, _scale: f32) { fn set_scale(&mut self, scale: f32) {
unimplemented!(); self.matrix.set_scale(scale);
} }
fn render_data(&mut self) -> RenderData { 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()))
} }
} }