Added proper texture scaling
This commit is contained in:
parent
7a46eff82c
commit
2591b60a5d
15
src/main.rs
15
src/main.rs
@ -63,11 +63,11 @@ 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: 200, h: 200});
|
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}));
|
tex_sprite.set_texture(texture.clone(), Some(Position {x: 0, y: 0}), 1.0);
|
||||||
|
|
||||||
let mut sub_sprite = canvas.create_texture_sprite(Size {w: 350, h: 427});
|
let mut sub_sprite = canvas.create_texture_sprite(Size {w: 200, h: 200});
|
||||||
sub_sprite.set_texture(texture.clone(), Some(Position {x: 350, y: 0}));
|
sub_sprite.set_texture(texture.clone(), Some(Position {x: 350, y: 0}), 1.0);
|
||||||
|
|
||||||
canvas.clear();
|
canvas.clear();
|
||||||
canvas.update();
|
canvas.update();
|
||||||
@ -103,11 +103,12 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
state.last_offset += 1;
|
state.last_offset += 1;
|
||||||
state.last_pos.x += 1;
|
state.last_pos.x += 1;
|
||||||
state.last_rot += 1.0;
|
state.last_rot += 1.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}));
|
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_sprite.set_rotation(state.last_rot);
|
state.sub_sprite.set_rotation(state.last_rot);
|
||||||
state.sub_sprite.set_scale(state.last_rot/1000.0);
|
//state.sub_sprite.set_scale(state.last_rot/1000.0);
|
||||||
|
|
||||||
// inputs
|
// inputs
|
||||||
//if canvas.key_pressed(Key::A) {
|
//if canvas.key_pressed(Key::A) {
|
||||||
|
|||||||
@ -82,7 +82,9 @@ impl WgpuRenderer {
|
|||||||
surface.configure(&device, &config);
|
surface.configure(&device, &config);
|
||||||
|
|
||||||
let surface_size = size;
|
let surface_size = size;
|
||||||
let aspect_matrix = Matrix3::from_nonuniform_scale(size.h as f32 / size.w as f32, 1.0);
|
let aspect_matrix
|
||||||
|
= Matrix3::from_nonuniform_scale(1.0 / size.w as f32, 1.0 / size.h as f32);
|
||||||
|
|
||||||
let output = Some(surface.get_current_texture()
|
let output = Some(surface.get_current_texture()
|
||||||
.map_err(|_| "Failed to create SurfaceTexture")?);
|
.map_err(|_| "Failed to create SurfaceTexture")?);
|
||||||
|
|
||||||
@ -320,10 +322,7 @@ impl WgpuRenderer {
|
|||||||
render_pass.set_push_constants(
|
render_pass.set_push_constants(
|
||||||
wgpu::ShaderStages::VERTEX,
|
wgpu::ShaderStages::VERTEX,
|
||||||
0,
|
0,
|
||||||
bytemuck::bytes_of(&(
|
bytemuck::bytes_of(&(self.aspect_matrix * matrix.get_matrix()))
|
||||||
self.aspect_matrix
|
|
||||||
* matrix.compute_matrix(self.surface_size)
|
|
||||||
))
|
|
||||||
);
|
);
|
||||||
render_pass.draw_indexed(0..gpu_mesh.index_number, 0, 0..1);
|
render_pass.draw_indexed(0..gpu_mesh.index_number, 0, 0..1);
|
||||||
|
|
||||||
@ -374,7 +373,8 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.surface_size = size;
|
self.surface_size = size;
|
||||||
self.aspect_matrix = Matrix3::from_nonuniform_scale(size.h as f32 / size.w as f32, 1.0);
|
self.aspect_matrix
|
||||||
|
= Matrix3::from_nonuniform_scale(1.0 / size.w as f32, 1.0 / size.h as f32);
|
||||||
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);
|
||||||
@ -433,7 +433,8 @@ where
|
|||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
let index_buffer = device.create_buffer( &wgpu_types::BufferDescriptor {
|
|
||||||
|
let index_buffer = device.create_buffer( &wgpu_types::BufferDescriptor {
|
||||||
label: Some("Index Buffer"),
|
label: Some("Index Buffer"),
|
||||||
size: (I_NB * size_of::<u16>()) as u64,
|
size: (I_NB * size_of::<u16>()) as u64,
|
||||||
usage: Usages::INDEX.union(Usages::COPY_DST),
|
usage: Usages::INDEX.union(Usages::COPY_DST),
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use crate::{
|
|||||||
renderer::{Mesh, GpuMesh, RenderData, TextureVertex},
|
renderer::{Mesh, GpuMesh, RenderData, TextureVertex},
|
||||||
shape::Shape,
|
shape::Shape,
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
utils::{Pixel, Position, Size},
|
utils::{Pixel, Position, Size, NormalizedSize},
|
||||||
};
|
};
|
||||||
|
|
||||||
use cgmath::{
|
use cgmath::{
|
||||||
@ -75,14 +75,14 @@ impl ModelMatrix {
|
|||||||
self.is_synced = false;
|
self.is_synced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_matrix(&mut self, size: Size) -> Matrix3<f32> {
|
pub fn get_matrix(&mut self) -> Matrix3<f32> {
|
||||||
use cgmath::{Basis3, Rotation3, SquareMatrix};
|
use cgmath::{Basis3, Rotation3, SquareMatrix};
|
||||||
|
|
||||||
if self.is_synced == false {
|
if self.is_synced == false {
|
||||||
|
|
||||||
let pos_vec = Vector2 {
|
let pos_vec = Vector2 {
|
||||||
x: self.position.x as f32 / size.w as f32,
|
x: self.position.x as f32,
|
||||||
y: self.position.y as f32 / size.h 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);
|
let scale_mat = Matrix3::from_scale(self.scale);
|
||||||
@ -100,54 +100,68 @@ impl ModelMatrix {
|
|||||||
pub struct TextureSprite {
|
pub struct TextureSprite {
|
||||||
matrix: ModelMatrix,
|
matrix: ModelMatrix,
|
||||||
gpu_mesh: GpuMesh<TextureVertex, 4, 6>,
|
gpu_mesh: GpuMesh<TextureVertex, 4, 6>,
|
||||||
|
inner_size: Size, //TODO move to f32
|
||||||
|
|
||||||
texture: Texture,
|
texture: Texture,
|
||||||
texture_offset: Position,
|
texture_offset: Position,
|
||||||
texture_size: Size,
|
texture_scale: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureSprite {
|
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 {
|
||||||
|
|
||||||
Self {
|
let mut sprite = Self {
|
||||||
matrix: ModelMatrix::default(),
|
matrix: ModelMatrix::default(),
|
||||||
gpu_mesh,
|
gpu_mesh,
|
||||||
texture,
|
inner_size: size,
|
||||||
|
|
||||||
|
texture: texture.clone(),
|
||||||
texture_offset: Position::origin(),
|
texture_offset: Position::origin(),
|
||||||
texture_size: size,
|
texture_scale: 1.0,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
//generate proper mesh
|
||||||
|
//TODO improve that
|
||||||
|
sprite.set_texture(texture, None, 1.0);
|
||||||
|
sprite
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_texture(&mut self, texture: Texture, offset: Option<Position>) {
|
pub fn set_texture(&mut self, texture: Texture, offset: Option<Position>, scale: f32) {
|
||||||
|
|
||||||
// update texture
|
// update texture
|
||||||
self.texture = texture;
|
self.texture = texture;
|
||||||
|
self.texture_scale = scale;
|
||||||
let size = self.texture.get_size();
|
let size = self.texture.get_size();
|
||||||
|
|
||||||
// compute normalized coordinates
|
// compute normalized coordinates
|
||||||
self.texture_offset = offset.unwrap_or(Position::origin());
|
self.texture_offset = offset.unwrap_or(Position::origin());
|
||||||
let x_size = self.texture_size.w as f32 / size.w as f32;
|
let x_size = self.inner_size.w as f32 / size.w as f32 * scale;
|
||||||
let y_size = self.texture_size.h as f32 / size.h as f32;
|
let y_size = self.inner_size.h as f32 / size.h as f32 * scale;
|
||||||
let x_offset = self.texture_offset.x as f32 / size.w as f32;
|
let x_offset = self.texture_offset.x as f32 / size.w as f32;
|
||||||
let y_offset = self.texture_offset.y as f32 / size.h as f32;
|
let y_offset = self.texture_offset.y as f32 / size.h as f32;
|
||||||
|
|
||||||
|
// compute mesh size
|
||||||
|
let w = self.inner_size.w as f32;
|
||||||
|
let h = self.inner_size.h as f32;
|
||||||
|
|
||||||
// generate new sprite mesh
|
// generate new sprite mesh
|
||||||
let mesh = Mesh {
|
let mesh = Mesh {
|
||||||
vertices: [
|
vertices: [
|
||||||
TextureVertex {
|
TextureVertex {
|
||||||
position: [-0.5, -0.5],
|
position: [-w, -h],
|
||||||
tex_coords: [x_offset , y_offset + y_size],
|
tex_coords: [x_offset , y_offset + y_size],
|
||||||
},
|
},
|
||||||
TextureVertex {
|
TextureVertex {
|
||||||
position: [ 0.5, -0.5],
|
position: [ w, -h],
|
||||||
tex_coords: [x_offset + x_size, y_offset + y_size],
|
tex_coords: [x_offset + x_size, y_offset + y_size],
|
||||||
},
|
},
|
||||||
TextureVertex {
|
TextureVertex {
|
||||||
position: [ 0.5, 0.5],
|
position: [ w, h],
|
||||||
tex_coords: [x_offset + x_size, y_offset ],
|
tex_coords: [x_offset + x_size, y_offset ],
|
||||||
},
|
},
|
||||||
TextureVertex {
|
TextureVertex {
|
||||||
position: [-0.5, 0.5],
|
position: [-w, h],
|
||||||
tex_coords: [x_offset , y_offset ],
|
tex_coords: [x_offset , y_offset ],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -167,7 +181,8 @@ impl TextureSprite {
|
|||||||
|
|
||||||
pub fn for_each<F: FnMut(&mut Pixel)>(&mut self, func: F) {
|
pub fn for_each<F: FnMut(&mut Pixel)>(&mut self, func: F) {
|
||||||
//TODO check pos ?
|
//TODO check pos ?
|
||||||
self.texture.for_each_in_area(func, self.texture_offset, self.texture_size);
|
//TODO take scale into account
|
||||||
|
self.texture.for_each_in_area(func, self.texture_offset, self.inner_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
18
src/utils.rs
18
src/utils.rs
@ -79,6 +79,24 @@ impl From<winit::dpi::PhysicalSize<u32>> for Size {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--NormalizedSize struct---------------------------------------------------------------------------
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct NormalizedSize {
|
||||||
|
pub w: f32,
|
||||||
|
pub h: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NormalizedSize {
|
||||||
|
|
||||||
|
pub fn from_size(size: Size, surface_size: Size) -> Self {
|
||||||
|
|
||||||
|
Self {
|
||||||
|
w: size.w as f32 / surface_size.w as f32,
|
||||||
|
h: size.h as f32 / surface_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