Moved from push constants to uniforms
This move also fixed display issues on Vulkan since the matrix's data alignement was not properly handled
This commit is contained in:
parent
2591b60a5d
commit
d3bc7ecc7f
@ -74,6 +74,7 @@ impl Canvas {
|
|||||||
self.default_texture.clone(),
|
self.default_texture.clone(),
|
||||||
size,
|
size,
|
||||||
self.renderer.create_texture_mesh(),
|
self.renderer.create_texture_mesh(),
|
||||||
|
self.renderer.create_matrix_uniform(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -58,6 +58,7 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
fn init(canvas: &mut Canvas) -> Result<ExampleState, &'static str> {
|
fn init(canvas: &mut Canvas) -> Result<ExampleState, &'static str> {
|
||||||
use canvas::{
|
use canvas::{
|
||||||
utils::{Position, Size},
|
utils::{Position, Size},
|
||||||
|
sprite::Sprite,
|
||||||
};
|
};
|
||||||
|
|
||||||
//// 20 x 20 sprite of a picture
|
//// 20 x 20 sprite of a picture
|
||||||
@ -101,7 +102,7 @@ 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.last_pos.y += 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.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(),
|
||||||
|
|||||||
163
src/renderer.rs
163
src/renderer.rs
@ -7,7 +7,7 @@ use wgpu_hal;
|
|||||||
use cgmath::Matrix3;
|
use cgmath::Matrix3;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
sprite::{Sprite, ModelMatrix},
|
sprite::{Sprite, ModelMatrix, MATRIX_SIZE},
|
||||||
texture::{GpuTexture},
|
texture::{GpuTexture},
|
||||||
utils::{Pixel, Size},
|
utils::{Pixel, Size},
|
||||||
};
|
};
|
||||||
@ -25,9 +25,10 @@ pub struct WgpuRenderer {
|
|||||||
config: wgpu::SurfaceConfiguration,
|
config: wgpu::SurfaceConfiguration,
|
||||||
|
|
||||||
surface_size: Size,
|
surface_size: Size,
|
||||||
aspect_matrix: Matrix3<f32>,
|
|
||||||
output: Option<wgpu::SurfaceTexture>,
|
output: Option<wgpu::SurfaceTexture>,
|
||||||
|
|
||||||
|
matrix_bind_group_layout: wgpu::BindGroupLayout,
|
||||||
|
|
||||||
texture_bind_group_layout: wgpu::BindGroupLayout,
|
texture_bind_group_layout: wgpu::BindGroupLayout,
|
||||||
texture_render_pipeline: wgpu::RenderPipeline,
|
texture_render_pipeline: wgpu::RenderPipeline,
|
||||||
|
|
||||||
@ -57,14 +58,11 @@ impl WgpuRenderer {
|
|||||||
},
|
},
|
||||||
).await.unwrap();
|
).await.unwrap();
|
||||||
|
|
||||||
let mut limits = wgpu::Limits::downlevel_defaults();
|
|
||||||
limits.max_push_constant_size = 36;
|
|
||||||
|
|
||||||
let (device, queue) = adapter.request_device(
|
let (device, queue) = adapter.request_device(
|
||||||
&wgpu::DeviceDescriptor {
|
&wgpu::DeviceDescriptor {
|
||||||
//using minimum requirements possible since 2D isn't very demanding anyway
|
//using minimum requirements possible since 2D isn't very demanding anyway
|
||||||
features: wgpu::Features::PUSH_CONSTANTS,
|
features: wgpu::Features::PUSH_CONSTANTS,
|
||||||
limits,
|
limits: wgpu::Limits::downlevel_webgl2_defaults(),
|
||||||
label: None,
|
label: None,
|
||||||
},
|
},
|
||||||
None, // Trace path
|
None, // Trace path
|
||||||
@ -82,12 +80,35 @@ impl WgpuRenderer {
|
|||||||
surface.configure(&device, &config);
|
surface.configure(&device, &config);
|
||||||
|
|
||||||
let surface_size = size;
|
let surface_size = size;
|
||||||
let aspect_matrix
|
//let aspect_matrix = {
|
||||||
= Matrix3::from_nonuniform_scale(1.0 / size.w as f32, 1.0 / size.h as f32);
|
// use cgmath::{Basis3, Rotation3, Deg};
|
||||||
|
|
||||||
|
// //Matrix3::from(Basis3::from_angle_x(Deg(-0.0)))
|
||||||
|
// //* Matrix3::identity()
|
||||||
|
// //* Matrix3::from_nonuniform_scale(1.0 / size.w as f32, 1.0 / size.h as f32)
|
||||||
|
// Matrix3::from_nonuniform_scale(1.0, 1.0)
|
||||||
|
//};
|
||||||
|
|
||||||
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")?);
|
||||||
|
|
||||||
|
let matrix_bind_group_layout =
|
||||||
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: wgpu::ShaderStages::VERTEX,
|
||||||
|
ty: wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
label: Some("matrix_bind_group_layout"),
|
||||||
|
});
|
||||||
|
|
||||||
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: &[
|
||||||
@ -113,11 +134,6 @@ impl WgpuRenderer {
|
|||||||
label: Some("texture_bind_group_layout"),
|
label: Some("texture_bind_group_layout"),
|
||||||
});
|
});
|
||||||
|
|
||||||
let mvp_push_constant = wgpu::PushConstantRange {
|
|
||||||
stages: wgpu::ShaderStages::VERTEX,
|
|
||||||
range: 0..36,
|
|
||||||
};
|
|
||||||
|
|
||||||
let texture_render_pipeline = {
|
let texture_render_pipeline = {
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("texture shader"),
|
label: Some("texture shader"),
|
||||||
@ -127,8 +143,11 @@ impl WgpuRenderer {
|
|||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("texture render pipeline layout"),
|
label: Some("texture render pipeline layout"),
|
||||||
bind_group_layouts: &[&texture_bind_group_layout],
|
bind_group_layouts: &[
|
||||||
push_constant_ranges: &[mvp_push_constant],
|
&matrix_bind_group_layout,
|
||||||
|
&texture_bind_group_layout,
|
||||||
|
],
|
||||||
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
|
||||||
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
@ -154,7 +173,7 @@ impl WgpuRenderer {
|
|||||||
topology: wgpu::PrimitiveTopology::TriangleList,
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
strip_index_format: None,
|
strip_index_format: None,
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: Some(wgpu::Face::Back),
|
cull_mode: None,//Some(wgpu::Face::Back),
|
||||||
// Setting this to anything other than Fill requires
|
// Setting this to anything other than Fill requires
|
||||||
// Features::NON_FILL_POLYGON_MODE
|
// Features::NON_FILL_POLYGON_MODE
|
||||||
polygon_mode: wgpu::PolygonMode::Fill,
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
@ -183,7 +202,9 @@ impl WgpuRenderer {
|
|||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("shape render pipeline layout"),
|
label: Some("shape render pipeline layout"),
|
||||||
bind_group_layouts: &[],
|
bind_group_layouts: &[
|
||||||
|
&matrix_bind_group_layout,
|
||||||
|
],
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -253,8 +274,8 @@ impl WgpuRenderer {
|
|||||||
queue,
|
queue,
|
||||||
config,
|
config,
|
||||||
surface_size,
|
surface_size,
|
||||||
aspect_matrix,
|
|
||||||
output,
|
output,
|
||||||
|
matrix_bind_group_layout,
|
||||||
texture_bind_group_layout,
|
texture_bind_group_layout,
|
||||||
texture_render_pipeline,
|
texture_render_pipeline,
|
||||||
shape_render_pipeline,
|
shape_render_pipeline,
|
||||||
@ -262,15 +283,16 @@ impl WgpuRenderer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_gpu_texture(&mut self, buf: &[u8], size: Size)
|
pub fn create_gpu_texture(&mut self, buf: &[u8], size: Size) -> GpuTexture {
|
||||||
-> GpuTexture
|
GpuTexture::create(&self.device, &self.texture_bind_group_layout, buf, size)
|
||||||
{
|
|
||||||
GpuTexture::create(&self.device, &self.texture_bind_group_layout, buf, size)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_texture_mesh(&self) -> GpuMesh<TextureVertex, 4, 6>
|
pub fn create_texture_mesh(&self) -> GpuMesh<TextureVertex, 4, 6> {
|
||||||
{
|
GpuMesh::create(&self.device, TEXTURE_QUAD)
|
||||||
GpuMesh::create(&self.device, TEXTURE_QUAD)
|
}
|
||||||
|
|
||||||
|
pub fn create_matrix_uniform(&self) -> GpuUniform<MATRIX_SIZE> {
|
||||||
|
GpuUniform::create(&self.device, &self.matrix_bind_group_layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<S: Sprite>(&mut self, sprite: &mut S) {
|
pub fn render<S: Sprite>(&mut self, sprite: &mut S) {
|
||||||
@ -290,6 +312,8 @@ impl WgpuRenderer {
|
|||||||
RenderData::Texture ((matrix, gpu_mesh, texture)) => {
|
RenderData::Texture ((matrix, gpu_mesh, texture)) => {
|
||||||
let mut texture = texture.borrow_mut();
|
let mut texture = texture.borrow_mut();
|
||||||
|
|
||||||
|
let matrix_bind_group = matrix.get_bind_group(&mut self.queue);
|
||||||
|
|
||||||
if texture.is_synced == false {
|
if texture.is_synced == false {
|
||||||
texture.update(&mut self.queue);
|
texture.update(&mut self.queue);
|
||||||
}
|
}
|
||||||
@ -318,12 +342,13 @@ impl WgpuRenderer {
|
|||||||
render_pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..));
|
render_pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..));
|
||||||
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, matrix_bind_group, &[]);
|
||||||
render_pass.set_push_constants(
|
render_pass.set_bind_group(1, &texture.bind_group, &[]);
|
||||||
wgpu::ShaderStages::VERTEX,
|
//render_pass.set_push_constants(
|
||||||
0,
|
// wgpu::ShaderStages::VERTEX,
|
||||||
bytemuck::bytes_of(&(self.aspect_matrix * matrix.get_matrix()))
|
// 0,
|
||||||
);
|
// 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);
|
||||||
@ -373,8 +398,15 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.surface_size = size;
|
self.surface_size = size;
|
||||||
self.aspect_matrix
|
//self.aspect_matrix = {
|
||||||
= Matrix3::from_nonuniform_scale(1.0 / size.w as f32, 1.0 / size.h as f32);
|
// use cgmath::{Basis3, Rotation3, Deg};
|
||||||
|
|
||||||
|
// //Matrix3::from(Basis3::from_angle_x(Deg(-0.0)))
|
||||||
|
// //* Matrix3::identity()
|
||||||
|
// // * Matrix3::from_nonuniform_scale(1.0 / size.w as f32, 1.0 / size.h as f32)
|
||||||
|
// Matrix3::from_nonuniform_scale(1.0, 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);
|
||||||
@ -404,6 +436,7 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--GpuMesh struct----------------------------------------------------------------------------------
|
||||||
pub struct GpuMesh<V, const V_NB: usize, const I_NB: usize>
|
pub struct GpuMesh<V, const V_NB: usize, const I_NB: usize>
|
||||||
where
|
where
|
||||||
V: Copy + Clone + bytemuck::Pod + bytemuck::Zeroable,
|
V: Copy + Clone + bytemuck::Pod + bytemuck::Zeroable,
|
||||||
@ -429,7 +462,7 @@ where
|
|||||||
&wgpu_types::BufferDescriptor {
|
&wgpu_types::BufferDescriptor {
|
||||||
label: Some("Vertex Buffer"),
|
label: Some("Vertex Buffer"),
|
||||||
size: (V_NB * size_of::<V>()) as u64,
|
size: (V_NB * size_of::<V>()) as u64,
|
||||||
usage: Usages::VERTEX.union(Usages::COPY_DST),
|
usage: Usages::VERTEX | Usages::COPY_DST,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -437,7 +470,7 @@ where
|
|||||||
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 | Usages::COPY_DST,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -470,9 +503,67 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--GpuUniform struct-------------------------------------------------------------------------------
|
||||||
|
pub struct GpuUniform<const S: usize> {
|
||||||
|
uniform: wgpu::Buffer,
|
||||||
|
bind_group: wgpu::BindGroup,
|
||||||
|
data: [u8; S],
|
||||||
|
is_synced: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const S: usize> GpuUniform<S> {
|
||||||
|
|
||||||
|
pub fn create(device: &wgpu::Device, layout: &wgpu::BindGroupLayout) -> Self {
|
||||||
|
|
||||||
|
let uniform = device.create_buffer(
|
||||||
|
&wgpu_types::BufferDescriptor {
|
||||||
|
label: Some("Uniform Buffer"),
|
||||||
|
size: S as u64,
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: uniform.as_entire_binding(),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
label: Some("uniform_bind_group"),
|
||||||
|
});
|
||||||
|
|
||||||
|
Self {
|
||||||
|
uniform,
|
||||||
|
bind_group,
|
||||||
|
data: [0; S],
|
||||||
|
is_synced: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, data: [u8; S]) {
|
||||||
|
|
||||||
|
self.data = data;
|
||||||
|
self.is_synced = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bind_group(&mut self, queue: &wgpu::Queue) -> &wgpu::BindGroup {
|
||||||
|
|
||||||
|
if self.is_synced == false {
|
||||||
|
queue.write_buffer(&self.uniform, 0, &self.data);
|
||||||
|
self.is_synced = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
&self.bind_group
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub enum RenderData<'a> {
|
pub enum RenderData<'a> {
|
||||||
Texture ((
|
Texture ((
|
||||||
&'a mut ModelMatrix,
|
&'a mut GpuUniform<MATRIX_SIZE>,
|
||||||
&'a mut GpuMesh<TextureVertex, 4, 6>,
|
&'a mut GpuMesh<TextureVertex, 4, 6>,
|
||||||
&'a Rc<RefCell<GpuTexture>>,
|
&'a Rc<RefCell<GpuTexture>>,
|
||||||
)),
|
)),
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
// Vertex shader
|
// Vertex shader
|
||||||
|
|
||||||
var<push_constant> model_matrix: mat3x3<f32>;
|
|
||||||
|
|
||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
@location(0) position: vec2<f32>,
|
@location(0) position: vec2<f32>,
|
||||||
@location(1) tex_coords: vec2<f32>,
|
@location(1) tex_coords: vec2<f32>,
|
||||||
@ -12,6 +10,9 @@ struct VertexOutput {
|
|||||||
@location(0) tex_coords: vec2<f32>,
|
@location(0) tex_coords: vec2<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@group(0)@binding(0)
|
||||||
|
var<uniform> model_matrix: mat3x3<f32>;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(model: VertexInput) -> VertexOutput {
|
fn vs_main(model: VertexInput) -> VertexOutput {
|
||||||
|
|
||||||
@ -24,9 +25,9 @@ fn vs_main(model: VertexInput) -> VertexOutput {
|
|||||||
|
|
||||||
// Fragment shader
|
// Fragment shader
|
||||||
|
|
||||||
@group(0) @binding(0)
|
@group(1)@binding(0)
|
||||||
var t_diffuse: texture_2d<f32>;
|
var t_diffuse: texture_2d<f32>;
|
||||||
@group(0)@binding(1)
|
@group(1)@binding(1)
|
||||||
var s_diffuse: sampler;
|
var s_diffuse: sampler;
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
renderer::{Mesh, GpuMesh, RenderData, TextureVertex},
|
renderer::{Mesh, GpuMesh, RenderData, TextureVertex, GpuUniform},
|
||||||
shape::Shape,
|
shape::Shape,
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
utils::{Pixel, Position, Size, NormalizedSize},
|
utils::{Pixel, Position, Size, NormalizedSize},
|
||||||
@ -37,13 +37,18 @@ pub struct ModelMatrix {
|
|||||||
rotation: Deg<f32>,
|
rotation: Deg<f32>,
|
||||||
scale: f32,
|
scale: f32,
|
||||||
|
|
||||||
matrix: Matrix3<f32>,
|
uniform: GpuUniform<MATRIX_SIZE>,
|
||||||
is_synced: bool,
|
is_synced: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModelMatrix {
|
impl ModelMatrix {
|
||||||
|
|
||||||
pub fn new(pos: Position, rot: f32, scale: f32) -> Self {
|
pub fn new(pos: Position,
|
||||||
|
rot: f32,
|
||||||
|
scale: f32,
|
||||||
|
uniform: GpuUniform<MATRIX_SIZE>)
|
||||||
|
-> Self
|
||||||
|
{
|
||||||
use cgmath::SquareMatrix;
|
use cgmath::SquareMatrix;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -51,13 +56,13 @@ impl ModelMatrix {
|
|||||||
rotation: Deg (rot),
|
rotation: Deg (rot),
|
||||||
scale,
|
scale,
|
||||||
|
|
||||||
matrix: Matrix3::identity(),
|
uniform,
|
||||||
is_synced: false,
|
is_synced: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default() -> Self {
|
pub fn default(uniform: GpuUniform<MATRIX_SIZE>) -> Self {
|
||||||
Self::new(Position::origin(), 0.0, 1.0)
|
Self::new(Position::origin(), 0.0, 1.0, uniform)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_position(&mut self, pos: Position) {
|
pub fn set_position(&mut self, pos: Position) {
|
||||||
@ -75,7 +80,7 @@ impl ModelMatrix {
|
|||||||
self.is_synced = false;
|
self.is_synced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_matrix(&mut self) -> Matrix3<f32> {
|
pub fn get_uniform(&mut self) -> &mut GpuUniform<MATRIX_SIZE> {
|
||||||
use cgmath::{Basis3, Rotation3, SquareMatrix};
|
use cgmath::{Basis3, Rotation3, SquareMatrix};
|
||||||
|
|
||||||
if self.is_synced == false {
|
if self.is_synced == false {
|
||||||
@ -87,15 +92,30 @@ impl ModelMatrix {
|
|||||||
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);
|
||||||
let translation_mat = Matrix3::from_translation(pos_vec);
|
let translation_mat = Matrix3::from_translation(pos_vec);
|
||||||
|
let aspect_mat = Matrix3::from_nonuniform_scale(1.0/1280.0, 1.0/720.0);
|
||||||
|
|
||||||
self.matrix = translation_mat * rotation_mat * scale_mat;
|
let matrix = aspect_mat * translation_mat * rotation_mat * scale_mat;
|
||||||
|
let mat_bytes: [u8; 36] = bytemuck::bytes_of(&matrix).try_into().unwrap();
|
||||||
|
let mut bytes = [0; 48];
|
||||||
|
for i in 0..12 {
|
||||||
|
bytes[i] = mat_bytes[i];
|
||||||
|
}
|
||||||
|
for i in 0..12 {
|
||||||
|
bytes[i+16] = mat_bytes[i+12];
|
||||||
|
}
|
||||||
|
for i in 0..12 {
|
||||||
|
bytes[i+32] = mat_bytes[i+24];
|
||||||
|
}
|
||||||
|
self.uniform.update(bytes);
|
||||||
self.is_synced = true;
|
self.is_synced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.matrix
|
&mut self.uniform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const MATRIX_SIZE: usize = 48;//std::mem::size_of::<Matrix3<f32>>();
|
||||||
|
|
||||||
//--TextureSprite struct----------------------------------------------------------------------------
|
//--TextureSprite struct----------------------------------------------------------------------------
|
||||||
pub struct TextureSprite {
|
pub struct TextureSprite {
|
||||||
matrix: ModelMatrix,
|
matrix: ModelMatrix,
|
||||||
@ -109,10 +129,14 @@ pub struct TextureSprite {
|
|||||||
|
|
||||||
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>,
|
||||||
|
matrix_uniform: GpuUniform<MATRIX_SIZE>)
|
||||||
|
-> Self
|
||||||
|
{
|
||||||
let mut sprite = Self {
|
let mut sprite = Self {
|
||||||
matrix: ModelMatrix::default(),
|
matrix: ModelMatrix::default(matrix_uniform),
|
||||||
gpu_mesh,
|
gpu_mesh,
|
||||||
inner_size: size,
|
inner_size: size,
|
||||||
|
|
||||||
@ -205,7 +229,11 @@ impl Sprite for TextureSprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_data(&mut self) -> RenderData {
|
fn render_data(&mut self) -> RenderData {
|
||||||
RenderData::Texture ((&mut self.matrix, &mut self.gpu_mesh, &self.texture.gpu_texture()))
|
RenderData::Texture ((
|
||||||
|
self.matrix.get_uniform(),
|
||||||
|
&mut self.gpu_mesh,
|
||||||
|
&self.texture.gpu_texture(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user