Got the matrix system working
Surface size is hardcoded for now
This commit is contained in:
parent
1081051084
commit
1e9fb49a49
@ -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) {
|
||||
|
||||
@ -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>),
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user