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
|
||||
let texture = canvas.create_texture_from_file("assets/camel.jpg", None, None, None)
|
||||
.unwrap();
|
||||
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 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);
|
||||
|
||||
let mut sub_sprite = canvas.create_texture_sprite(Size {w: 350, h: 427});
|
||||
sub_sprite.set_texture(texture.clone(), Some(Position {x: 350, y: 0}));
|
||||
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}), 1.0);
|
||||
|
||||
canvas.clear();
|
||||
canvas.update();
|
||||
@ -103,11 +103,12 @@ impl Application<ExampleState> for ExampleApp {
|
||||
state.last_offset += 1;
|
||||
state.last_pos.x += 1;
|
||||
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(),
|
||||
Some(Position {x: state.last_offset, y: 0}));
|
||||
//state.sub_sprite.set_position(state.last_pos);
|
||||
Some(Position {x: state.last_offset, y: 0}), 1.0);
|
||||
state.sub_sprite.set_position(state.last_pos);
|
||||
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
|
||||
//if canvas.key_pressed(Key::A) {
|
||||
|
||||
@ -82,7 +82,9 @@ 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 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()
|
||||
.map_err(|_| "Failed to create SurfaceTexture")?);
|
||||
|
||||
@ -320,10 +322,7 @@ impl WgpuRenderer {
|
||||
render_pass.set_push_constants(
|
||||
wgpu::ShaderStages::VERTEX,
|
||||
0,
|
||||
bytemuck::bytes_of(&(
|
||||
self.aspect_matrix
|
||||
* matrix.compute_matrix(self.surface_size)
|
||||
))
|
||||
bytemuck::bytes_of(&(self.aspect_matrix * matrix.get_matrix()))
|
||||
);
|
||||
render_pass.draw_indexed(0..gpu_mesh.index_number, 0, 0..1);
|
||||
|
||||
@ -374,7 +373,8 @@ impl WgpuRenderer {
|
||||
}
|
||||
|
||||
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.height = size.h;
|
||||
self.surface.configure(&self.device, &self.config);
|
||||
@ -433,7 +433,8 @@ where
|
||||
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"),
|
||||
size: (I_NB * size_of::<u16>()) as u64,
|
||||
usage: Usages::INDEX.union(Usages::COPY_DST),
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::{
|
||||
renderer::{Mesh, GpuMesh, RenderData, TextureVertex},
|
||||
shape::Shape,
|
||||
texture::Texture,
|
||||
utils::{Pixel, Position, Size},
|
||||
utils::{Pixel, Position, Size, NormalizedSize},
|
||||
};
|
||||
|
||||
use cgmath::{
|
||||
@ -75,14 +75,14 @@ impl ModelMatrix {
|
||||
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};
|
||||
|
||||
if self.is_synced == false {
|
||||
|
||||
let pos_vec = Vector2 {
|
||||
x: self.position.x as f32 / size.w as f32,
|
||||
y: self.position.y as f32 / size.h as f32,
|
||||
x: self.position.x as f32,
|
||||
y: self.position.y as f32,
|
||||
};
|
||||
let rotation_mat = Matrix3::from(Basis3::from_angle_z(self.rotation));
|
||||
let scale_mat = Matrix3::from_scale(self.scale);
|
||||
@ -100,54 +100,68 @@ impl ModelMatrix {
|
||||
pub struct TextureSprite {
|
||||
matrix: ModelMatrix,
|
||||
gpu_mesh: GpuMesh<TextureVertex, 4, 6>,
|
||||
inner_size: Size, //TODO move to f32
|
||||
|
||||
texture: Texture,
|
||||
texture_offset: Position,
|
||||
texture_size: Size,
|
||||
texture_scale: f32,
|
||||
}
|
||||
|
||||
impl TextureSprite {
|
||||
|
||||
pub fn create(texture: Texture, size: Size, gpu_mesh: GpuMesh<TextureVertex, 4, 6>) -> Self {
|
||||
|
||||
Self {
|
||||
let mut sprite = Self {
|
||||
matrix: ModelMatrix::default(),
|
||||
gpu_mesh,
|
||||
texture,
|
||||
inner_size: size,
|
||||
|
||||
texture: texture.clone(),
|
||||
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
|
||||
self.texture = texture;
|
||||
self.texture_scale = scale;
|
||||
let size = self.texture.get_size();
|
||||
|
||||
// compute normalized coordinates
|
||||
self.texture_offset = offset.unwrap_or(Position::origin());
|
||||
let x_size = self.texture_size.w as f32 / size.w as f32;
|
||||
let y_size = self.texture_size.h as f32 / size.h as f32;
|
||||
let x_size = self.inner_size.w as f32 / size.w as f32 * scale;
|
||||
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 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
|
||||
let mesh = Mesh {
|
||||
vertices: [
|
||||
TextureVertex {
|
||||
position: [-0.5, -0.5],
|
||||
position: [-w, -h],
|
||||
tex_coords: [x_offset , y_offset + y_size],
|
||||
},
|
||||
TextureVertex {
|
||||
position: [ 0.5, -0.5],
|
||||
position: [ w, -h],
|
||||
tex_coords: [x_offset + x_size, y_offset + y_size],
|
||||
},
|
||||
TextureVertex {
|
||||
position: [ 0.5, 0.5],
|
||||
position: [ w, h],
|
||||
tex_coords: [x_offset + x_size, y_offset ],
|
||||
},
|
||||
TextureVertex {
|
||||
position: [-0.5, 0.5],
|
||||
position: [-w, h],
|
||||
tex_coords: [x_offset , y_offset ],
|
||||
},
|
||||
],
|
||||
@ -167,7 +181,8 @@ impl TextureSprite {
|
||||
|
||||
pub fn for_each<F: FnMut(&mut Pixel)>(&mut self, func: F) {
|
||||
//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------------------------------------------------------------------------------------
|
||||
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
#[repr(C)]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user