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,
texture::Texture,
sprite::TextureSprite,
utils::Position,
};
use std::{
@ -46,6 +47,7 @@ struct ExampleState {
pub sub_sprite: TextureSprite,
pub last_instant: Instant,
pub last_offset: u32,
pub last_pos: Position,
}
struct ExampleApp {}
@ -60,7 +62,7 @@ impl Application<ExampleState> 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: 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}));
let mut sub_sprite = canvas.create_texture_sprite(Size {w: 350, h: 427});
@ -77,6 +79,7 @@ impl Application<ExampleState> for ExampleApp {
sub_sprite,
last_instant,
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.last_offset += 1;
state.last_pos.x += 1;
state.sub_sprite.set_texture(state.texture.clone(),
Some(Position {x: state.last_offset, y: 0}));
state.sub_sprite.set_position(state.last_pos);
// inputs
//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 wgpu;
use wgpu_hal;
use cgmath::Matrix3;
use crate::{
sprite::Sprite,
sprite::{Sprite, ModelMatrix},
texture::{GpuTexture},
utils::{Pixel, Size},
};
@ -22,12 +23,16 @@ pub struct WgpuRenderer {
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
size: Size,
surface_size: Size,
aspect_matrix: Matrix3<f32>,
output: Option<wgpu::SurfaceTexture>,
texture_bind_group_layout: wgpu::BindGroupLayout,
texture_render_pipeline: wgpu::RenderPipeline,
shape_render_pipeline: wgpu::RenderPipeline,
quad_mesh: GpuMesh<ColorVertex, 4, 6>, //TODO temporary, to be moved to shapes.rs
output: Option<wgpu::SurfaceTexture>,
}
impl WgpuRenderer {
@ -76,6 +81,11 @@ 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 output = Some(surface.get_current_texture()
.map_err(|_| "Failed to create SurfaceTexture")?);
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
@ -235,20 +245,18 @@ impl WgpuRenderer {
GpuMesh::create(&device, mesh)
};
let output = Some(surface.get_current_texture()
.map_err(|_| "Failed to create SurfaceTexture")?);
Ok(Self {
surface,
device,
queue,
config,
size,
surface_size,
aspect_matrix,
output,
texture_bind_group_layout,
texture_render_pipeline,
shape_render_pipeline,
quad_mesh,
output,
})
}
@ -277,7 +285,7 @@ impl WgpuRenderer {
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
match sprite.render_data() {
RenderData::Texture ((gpu_mesh, texture)) => {
RenderData::Texture ((matrix, gpu_mesh, texture)) => {
let mut texture = texture.borrow_mut();
if texture.is_synced == false {
@ -309,13 +317,12 @@ impl WgpuRenderer {
render_pass.set_index_buffer(gpu_mesh.index_buffer.slice(..),
wgpu::IndexFormat::Uint16);
render_pass.set_bind_group(0, &texture.bind_group, &[]);
let matrix = {
use cgmath::SquareMatrix;
cgmath::Matrix3::<f32>::from_nonuniform_scale(720.0/1280.0, 1.0)
};
render_pass.set_push_constants(wgpu::ShaderStages::VERTEX,
0,
bytemuck::bytes_of(&matrix));
debug!("mat: {:#?}", matrix.get_matrix());
render_pass.set_push_constants(
wgpu::ShaderStages::VERTEX,
0,
bytemuck::bytes_of(&(self.aspect_matrix * matrix.get_matrix()))
);
render_pass.draw_indexed(0..gpu_mesh.index_number, 0, 0..1);
drop(render_pass);
@ -363,7 +370,9 @@ impl WgpuRenderer {
if size.w == 0 || size.h == 0 {
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.height = size.h;
self.surface.configure(&self.device, &self.config);
@ -384,7 +393,7 @@ impl WgpuRenderer {
.map_err(|err| match err {
wgpu::SurfaceError::Lost => {
warn!("Lost surface, trying resizing");
self.resize(self.size);
self.resize(self.surface_size);
self.surface.get_current_texture()
},
_ => Err(err)
@ -459,7 +468,11 @@ let index_buffer = device.create_buffer( &wgpu_types::BufferDescriptor {
}
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>),
}

View File

@ -18,7 +18,7 @@ fn vs_main(model: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.tex_coords = model.tex_coords;
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;
}

View File

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