Implemented more of TextureSprite
+ added texture modification functions + added texture offset support
This commit is contained in:
parent
3a7799bc76
commit
330a93fac8
@ -69,8 +69,8 @@ impl Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--Create functions--
|
//--Create functions--
|
||||||
pub fn create_texture_sprite(&mut self, _size: Size) -> TextureSprite {
|
pub fn create_texture_sprite(&mut self, size: Size) -> TextureSprite {
|
||||||
TextureSprite::create(self.default_texture.clone())
|
TextureSprite::create(self.default_texture.clone(), size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_text_sprite(&mut self, _size: Size, _scale: f32) -> TextSprite {
|
pub fn create_text_sprite(&mut self, _size: Size, _scale: f32) -> TextSprite {
|
||||||
|
|||||||
@ -15,7 +15,10 @@ mod renderer;
|
|||||||
|
|
||||||
use utils::Size;
|
use utils::Size;
|
||||||
|
|
||||||
pub fn run_canvas<S: 'static + Sized, A: 'static + Application<S>>(title: &'static str, size: Size, mut app: A) -> ! {
|
pub fn run_canvas<S: 'static + Sized, A: 'static + Application<S>>(title: &'static str,
|
||||||
|
size: Size, mut app: A)
|
||||||
|
-> !
|
||||||
|
{
|
||||||
use winit::{
|
use winit::{
|
||||||
event_loop::EventLoop,
|
event_loop::EventLoop,
|
||||||
window::WindowBuilder,
|
window::WindowBuilder,
|
||||||
|
|||||||
28
src/main.rs
28
src/main.rs
@ -1,3 +1,6 @@
|
|||||||
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
use canvas::{
|
use canvas::{
|
||||||
Application,
|
Application,
|
||||||
Canvas,
|
Canvas,
|
||||||
@ -8,6 +11,7 @@ use canvas::{
|
|||||||
use std::{
|
use std::{
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn setup_logger() -> Result<(), fern::InitError> {
|
fn setup_logger() -> Result<(), fern::InitError> {
|
||||||
@ -39,6 +43,9 @@ fn setup_logger() -> Result<(), fern::InitError> {
|
|||||||
struct ExampleState {
|
struct ExampleState {
|
||||||
pub texture: Texture,
|
pub texture: Texture,
|
||||||
pub tex_sprite: TextureSprite,
|
pub tex_sprite: TextureSprite,
|
||||||
|
pub sub_sprite: TextureSprite,
|
||||||
|
pub last_instant: Instant,
|
||||||
|
pub last_offset: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExampleApp {}
|
struct ExampleApp {}
|
||||||
@ -55,13 +62,21 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let mut tex_sprite = canvas.create_texture_sprite(Size {w: 20, h: 20});
|
let mut tex_sprite = canvas.create_texture_sprite(Size {w: 20, h: 20});
|
||||||
tex_sprite.set_texture(texture.clone(), Some(Position {x: 0, y: 0}));
|
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});
|
||||||
|
sub_sprite.set_texture(texture.clone(), Some(Position {x: 350, y: 0}));
|
||||||
|
|
||||||
canvas.clear();
|
canvas.clear();
|
||||||
canvas.update();
|
canvas.update();
|
||||||
|
|
||||||
|
let last_instant = Instant::now();
|
||||||
|
|
||||||
Ok(ExampleState {
|
Ok(ExampleState {
|
||||||
texture,
|
texture,
|
||||||
tex_sprite,
|
tex_sprite,
|
||||||
|
sub_sprite,
|
||||||
|
last_instant,
|
||||||
|
last_offset: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +88,17 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
shape::{Shape, Rectangle},
|
shape::{Shape, Rectangle},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let now = Instant::now();
|
||||||
|
let elapsed = now.duration_since(state.last_instant).as_millis();
|
||||||
|
state.last_instant = now;
|
||||||
|
debug!("frame time: {}ms", elapsed);
|
||||||
|
|
||||||
|
//state.sub_sprite.for_each(|pix| unsafe {pix.flat = pix.flat.wrapping_add(1);});
|
||||||
|
|
||||||
|
state.last_offset += 1;
|
||||||
|
state.sub_sprite.set_texture(state.texture.clone(),
|
||||||
|
Some(Position {x: state.last_offset, y: 0}));
|
||||||
|
|
||||||
// inputs
|
// inputs
|
||||||
//if canvas.key_pressed(Key::A) {
|
//if canvas.key_pressed(Key::A) {
|
||||||
// unimplemented!();
|
// unimplemented!();
|
||||||
@ -126,8 +152,10 @@ impl Application<ExampleState> for ExampleApp {
|
|||||||
//txt_sprite.set_alpha(255);
|
//txt_sprite.set_alpha(255);
|
||||||
//txt_sprite.set_scale(0.5);
|
//txt_sprite.set_scale(0.5);
|
||||||
//canvas.draw(&txt_sprite);
|
//canvas.draw(&txt_sprite);
|
||||||
|
|
||||||
|
|
||||||
canvas.draw(&state.tex_sprite);
|
canvas.draw(&state.tex_sprite);
|
||||||
|
canvas.draw(&state.sub_sprite);
|
||||||
canvas.update();
|
canvas.update();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
119
src/renderer.rs
119
src/renderer.rs
@ -208,9 +208,40 @@ impl WgpuRenderer {
|
|||||||
multiview: None,
|
multiview: None,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let texture_quad = GpuMesh::create(&device, &TEXTURE_QUAD);
|
let texture_quad = {
|
||||||
let quad_mesh = GpuMesh::create(&device, &QUAD);
|
let mesh = Mesh {
|
||||||
|
vertices: vec![
|
||||||
|
TextureVertex { position: [0.0, 0.0], tex_coords: [0.0, 1.0] },
|
||||||
|
TextureVertex { position: [1.0, 0.0], tex_coords: [1.0, 1.0] },
|
||||||
|
TextureVertex { position: [1.0, 1.0], tex_coords: [1.0, 0.0] },
|
||||||
|
TextureVertex { position: [0.0, 1.0], tex_coords: [0.0, 0.0] },
|
||||||
|
],
|
||||||
|
indices: vec![
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
GpuMesh::create(&device, &mesh)
|
||||||
|
};
|
||||||
|
|
||||||
|
let quad_mesh = {
|
||||||
|
let mesh = Mesh {
|
||||||
|
vertices: vec![
|
||||||
|
ColorVertex { position: [0.0, 0.0], color: [1.0, 0.0, 0.0] },
|
||||||
|
ColorVertex { position: [1.0, 0.0], color: [0.0, 1.0, 0.0] },
|
||||||
|
ColorVertex { position: [1.0, 1.0], color: [0.0, 0.0, 1.0] },
|
||||||
|
ColorVertex { position: [0.0, 1.0], color: [0.5, 0.5, 0.5] },
|
||||||
|
],
|
||||||
|
indices: vec![
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
GpuMesh::create(&device, &mesh)
|
||||||
|
};
|
||||||
|
|
||||||
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")?);
|
||||||
@ -250,14 +281,18 @@ impl WgpuRenderer {
|
|||||||
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
|
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
|
||||||
match sprite.render_data() {
|
match sprite.render_data() {
|
||||||
RenderData::Texture (texture) => {
|
RenderData::Texture ((mesh, texture)) => {
|
||||||
let mut texture = texture.borrow_mut();
|
let mut texture = texture.borrow_mut();
|
||||||
|
|
||||||
if texture.is_synced() == false {
|
if texture.is_synced == false {
|
||||||
texture.update(&mut self.queue);
|
texture.update(&mut self.queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
//TODO avoid recreating buffers every time
|
||||||
|
let gpu_mesh = GpuMesh::create(&self.device, &mesh);
|
||||||
|
|
||||||
|
let mut encoder = self.device
|
||||||
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||||
label: Some("Render Encoder"),
|
label: Some("Render Encoder"),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -267,18 +302,16 @@ impl WgpuRenderer {
|
|||||||
view: &view,
|
view: &view,
|
||||||
resolve_target: None,
|
resolve_target: None,
|
||||||
ops: wgpu::Operations {
|
ops: wgpu::Operations {
|
||||||
load: wgpu::LoadOp::Load,
|
load: wgpu::LoadOp::Load, store: true, },
|
||||||
store: true,
|
|
||||||
},
|
|
||||||
})],
|
})],
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
render_pass.set_pipeline(&self.texture_render_pipeline);
|
render_pass.set_pipeline(&self.texture_render_pipeline);
|
||||||
render_pass.set_vertex_buffer(0, self.texture_quad.vertex_buffer.slice(..));
|
render_pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..));
|
||||||
render_pass.set_index_buffer(self.texture_quad.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, &texture.bind_group, &[]);
|
||||||
render_pass.draw_indexed(0..self.texture_quad.index_number, 0, 0..1);
|
render_pass.draw_indexed(0..self.texture_quad.index_number, 0, 0..1);
|
||||||
|
|
||||||
drop(render_pass);
|
drop(render_pass);
|
||||||
@ -372,7 +405,7 @@ impl<V: Copy + Clone + bytemuck::Pod + bytemuck::Zeroable> GpuMesh<V> {
|
|||||||
let vertex_buffer = device.create_buffer_init(
|
let vertex_buffer = device.create_buffer_init(
|
||||||
&wgpu::util::BufferInitDescriptor {
|
&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Vertex Buffer"),
|
label: Some("Vertex Buffer"),
|
||||||
contents: bytemuck::cast_slice(mesh.vertices),
|
contents: bytemuck::cast_slice(&mesh.vertices),
|
||||||
usage: wgpu::BufferUsages::VERTEX,
|
usage: wgpu::BufferUsages::VERTEX,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -380,7 +413,7 @@ impl<V: Copy + Clone + bytemuck::Pod + bytemuck::Zeroable> GpuMesh<V> {
|
|||||||
let index_buffer = device.create_buffer_init(
|
let index_buffer = device.create_buffer_init(
|
||||||
&wgpu::util::BufferInitDescriptor {
|
&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Index Buffer"),
|
label: Some("Index Buffer"),
|
||||||
contents: bytemuck::cast_slice(mesh.indices),
|
contents: bytemuck::cast_slice(&mesh.indices),
|
||||||
usage: wgpu::BufferUsages::INDEX,
|
usage: wgpu::BufferUsages::INDEX,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -395,7 +428,7 @@ impl<V: Copy + Clone + bytemuck::Pod + bytemuck::Zeroable> GpuMesh<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum RenderData<'a> {
|
pub enum RenderData<'a> {
|
||||||
Texture (&'a Rc<RefCell<GpuTexture>>),
|
Texture ((&'a Mesh<TextureVertex>, &'a Rc<RefCell<GpuTexture>>)),
|
||||||
Shape (&'a GpuMesh<ColorVertex>),
|
Shape (&'a GpuMesh<ColorVertex>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,36 +475,36 @@ impl ColorVertex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Mesh<'a, V: Copy + Clone + bytemuck::Pod + bytemuck::Zeroable> {
|
pub struct Mesh<V: Copy + Clone + bytemuck::Pod + bytemuck::Zeroable> {
|
||||||
pub vertices: &'a[V],
|
pub vertices: Vec<V>,
|
||||||
pub indices: &'a[u16],
|
pub indices: Vec<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const TEXTURE_QUAD: Mesh<'static, TextureVertex> = Mesh {
|
//pub const TEXTURE_QUAD: Mesh<TextureVertex> = Mesh {
|
||||||
vertices: &[
|
// vertices: [
|
||||||
TextureVertex { position: [0.0, 0.0], tex_coords: [0.0, 1.0] },
|
// TextureVertex { position: [0.0, 0.0], tex_coords: [0.0, 1.0] },
|
||||||
TextureVertex { position: [1.0, 0.0], tex_coords: [1.0, 1.0] },
|
// TextureVertex { position: [1.0, 0.0], tex_coords: [1.0, 1.0] },
|
||||||
TextureVertex { position: [1.0, 1.0], tex_coords: [1.0, 0.0] },
|
// TextureVertex { position: [1.0, 1.0], tex_coords: [1.0, 0.0] },
|
||||||
TextureVertex { position: [0.0, 1.0], tex_coords: [0.0, 0.0] },
|
// TextureVertex { position: [0.0, 1.0], tex_coords: [0.0, 0.0] },
|
||||||
],
|
// ],
|
||||||
indices: &[
|
// indices: [
|
||||||
0, 1, 2,
|
// 0, 1, 2,
|
||||||
0, 2, 3,
|
// 0, 2, 3,
|
||||||
],
|
// ],
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
const QUAD: Mesh<'static, ColorVertex> = Mesh {
|
//const QUAD: Mesh<ColorVertex> = Mesh {
|
||||||
vertices: &[
|
// vertices: [
|
||||||
ColorVertex { position: [0.0, 0.0], color: [1.0, 0.0, 0.0] },
|
// ColorVertex { position: [0.0, 0.0], color: [1.0, 0.0, 0.0] },
|
||||||
ColorVertex { position: [1.0, 0.0], color: [0.0, 1.0, 0.0] },
|
// ColorVertex { position: [1.0, 0.0], color: [0.0, 1.0, 0.0] },
|
||||||
ColorVertex { position: [1.0, 1.0], color: [0.0, 0.0, 1.0] },
|
// ColorVertex { position: [1.0, 1.0], color: [0.0, 0.0, 1.0] },
|
||||||
ColorVertex { position: [0.0, 1.0], color: [0.5, 0.5, 0.5] },
|
// ColorVertex { position: [0.0, 1.0], color: [0.5, 0.5, 0.5] },
|
||||||
],
|
// ],
|
||||||
indices: &[
|
// indices: [
|
||||||
0, 1, 2,
|
// 0, 1, 2,
|
||||||
0, 2, 3,
|
// 0, 2, 3,
|
||||||
],
|
// ],
|
||||||
};
|
//};
|
||||||
|
|
||||||
impl From<Pixel> for wgpu::Color {
|
impl From<Pixel> for wgpu::Color {
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
renderer::{GpuMesh, RenderData},
|
renderer::{Mesh, RenderData, TextureVertex},
|
||||||
shape::Shape,
|
shape::Shape,
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
utils::{Pixel, Position, Size},
|
utils::{Pixel, Position, Size},
|
||||||
@ -31,38 +31,91 @@ pub struct TextureSprite {
|
|||||||
position: Position,
|
position: Position,
|
||||||
scale: f32,
|
scale: f32,
|
||||||
matrix: Matrix4<f32>,
|
matrix: Matrix4<f32>,
|
||||||
|
mesh: Mesh<TextureVertex>,
|
||||||
texture: Texture,
|
texture: Texture,
|
||||||
|
texture_offset: Position,
|
||||||
|
texture_size: Size,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextureSprite {
|
impl TextureSprite {
|
||||||
|
|
||||||
pub fn create(texture: Texture) -> Self {
|
pub fn create(texture: Texture, size: Size) -> Self {
|
||||||
|
|
||||||
let position = Position::default();
|
let position = Position::origin();
|
||||||
let scale = 1.0;
|
let scale = 1.0;
|
||||||
let matrix = Matrix4::from_scale(scale) + Matrix4::from_translation(position.into());
|
let matrix = Matrix4::from_scale(scale) + Matrix4::from_translation(position.into());
|
||||||
|
let mesh = Mesh {
|
||||||
|
vertices: vec![
|
||||||
|
TextureVertex { position: [0.0, 0.0], tex_coords: [0.0, 1.0] },
|
||||||
|
TextureVertex { position: [1.0, 0.0], tex_coords: [1.0, 1.0] },
|
||||||
|
TextureVertex { position: [1.0, 1.0], tex_coords: [1.0, 0.0] },
|
||||||
|
TextureVertex { position: [0.0, 1.0], tex_coords: [0.0, 0.0] },
|
||||||
|
],
|
||||||
|
indices: vec![
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
position,
|
position,
|
||||||
scale,
|
scale,
|
||||||
matrix,
|
matrix,
|
||||||
|
mesh,
|
||||||
texture,
|
texture,
|
||||||
|
texture_offset: position,
|
||||||
|
texture_size: size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_texture(&mut self, texture: Texture, _offset: Option<Position>) {
|
pub fn set_texture(&mut self, texture: Texture, offset: Option<Position>) {
|
||||||
|
|
||||||
|
// update texture
|
||||||
self.texture = texture;
|
self.texture = texture;
|
||||||
|
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_offset = self.texture_offset.x as f32 / size.w as f32;
|
||||||
|
let y_offset = self.texture_offset.y as f32 / size.h as f32;
|
||||||
|
|
||||||
|
// generate new sprite mesh
|
||||||
|
self.mesh = Mesh {
|
||||||
|
vertices: vec![
|
||||||
|
TextureVertex {
|
||||||
|
position: [0.0, 0.0],
|
||||||
|
tex_coords: [x_offset , y_offset + y_size],
|
||||||
|
},
|
||||||
|
TextureVertex {
|
||||||
|
position: [1.0, 0.0],
|
||||||
|
tex_coords: [x_offset + x_size, y_offset + y_size],
|
||||||
|
},
|
||||||
|
TextureVertex {
|
||||||
|
position: [1.0, 1.0],
|
||||||
|
tex_coords: [x_offset + x_size, y_offset ],
|
||||||
|
},
|
||||||
|
TextureVertex {
|
||||||
|
position: [0.0, 1.0],
|
||||||
|
tex_coords: [x_offset , y_offset ],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
indices: vec![
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3,
|
||||||
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pixel(&mut self, _pos: Position, _pix: Pixel) {
|
pub fn set_pixel(&mut self, pos: Position, pix: Pixel) {
|
||||||
todo!();
|
//TODO check pos ?
|
||||||
|
self.texture.set_pixel(self.texture_offset + pos, pix);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> Iter<'_, Pixel> {
|
pub fn for_each<F: FnMut(&mut Pixel)>(&mut self, func: F) {
|
||||||
todo!();
|
//TODO check pos ?
|
||||||
}
|
self.texture.for_each_in_area(func, self.texture_offset, self.texture_size);
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> IterMut<'_, Pixel> {
|
|
||||||
todo!();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +138,7 @@ impl Sprite for TextureSprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_data(&self) -> RenderData {
|
fn render_data(&self) -> RenderData {
|
||||||
RenderData::Texture (&self.texture.gpu_texture())
|
RenderData::Texture ((&self.mesh, &self.texture.gpu_texture()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,9 +42,9 @@ impl GpuTexture {
|
|||||||
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
|
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
let sampler = device.create_sampler(
|
let sampler = device.create_sampler(
|
||||||
&wgpu::SamplerDescriptor {
|
&wgpu::SamplerDescriptor {
|
||||||
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
address_mode_u: wgpu::AddressMode::Repeat,
|
||||||
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
address_mode_v: wgpu::AddressMode::Repeat,
|
||||||
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
address_mode_w: wgpu::AddressMode::Repeat,
|
||||||
mag_filter: wgpu::FilterMode::Linear,
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
min_filter: wgpu::FilterMode::Nearest,
|
min_filter: wgpu::FilterMode::Nearest,
|
||||||
mipmap_filter: wgpu::FilterMode::Nearest,
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
@ -78,14 +78,6 @@ impl GpuTexture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_group(&self) -> &wgpu::BindGroup {
|
|
||||||
&self.bind_group
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_synced(&self) -> bool {
|
|
||||||
self.is_synced
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(&mut self, queue: &wgpu::Queue) {
|
pub fn update(&mut self, queue: &wgpu::Queue) {
|
||||||
|
|
||||||
queue.write_texture(
|
queue.write_texture(
|
||||||
@ -123,21 +115,47 @@ impl Texture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pixel(&mut self, _pos: Position, _pix: Pixel) {
|
pub fn set_pixel(&mut self, pos: Position, pix: Pixel) {
|
||||||
todo!();
|
|
||||||
|
//TODO check pos ?
|
||||||
|
let mut gpu_texture = self.gpu_texture.borrow_mut();
|
||||||
|
let width = gpu_texture.size.w;
|
||||||
|
gpu_texture.buffer[(pos.x + pos.y*width) as usize] = pix;
|
||||||
|
gpu_texture.is_synced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> Iter<'_, Pixel> {
|
pub fn for_each<F: FnMut(&mut Pixel)>(&mut self, mut func: F) {
|
||||||
todo!();
|
|
||||||
|
let mut gpu_texture = self.gpu_texture.borrow_mut();
|
||||||
|
for pix in &mut gpu_texture.buffer {
|
||||||
|
func(pix);
|
||||||
|
}
|
||||||
|
gpu_texture.is_synced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> IterMut<'_, Pixel> {
|
pub fn for_each_in_area<F: FnMut(&mut Pixel)>(&mut self,
|
||||||
todo!();
|
mut func: F,
|
||||||
|
offset: Position,
|
||||||
|
size: Size)
|
||||||
|
{
|
||||||
|
//TODO check offset and pos ?
|
||||||
|
let mut gpu_texture = self.gpu_texture.borrow_mut();
|
||||||
|
let width = gpu_texture.size.w;
|
||||||
|
for x in offset.x..(offset.x + size.w) {
|
||||||
|
for y in offset.y..(offset.y + size.h) {
|
||||||
|
func(&mut gpu_texture.buffer[(x + y*width) as usize]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gpu_texture.is_synced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gpu_texture(&self) -> &Rc<RefCell<GpuTexture>> {
|
pub fn gpu_texture(&self) -> &Rc<RefCell<GpuTexture>> {
|
||||||
//TODO improve that
|
//TODO improve that
|
||||||
&self.gpu_texture
|
&self.gpu_texture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_size(&self) -> Size {
|
||||||
|
self.gpu_texture.borrow().size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
src/utils.rs
15
src/utils.rs
@ -14,7 +14,7 @@ pub struct Position {
|
|||||||
|
|
||||||
impl Position {
|
impl Position {
|
||||||
|
|
||||||
pub fn default() -> Self {
|
pub fn origin() -> Self {
|
||||||
Position {
|
Position {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
@ -29,6 +29,17 @@ impl From<Position> for Vector3<f32> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::ops::Add for Position {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
Position {
|
||||||
|
x: self.x + rhs.x,
|
||||||
|
y: self.y + rhs.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--Size struct-------------------------------------------------------------------------------------
|
//--Size struct-------------------------------------------------------------------------------------
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Size {
|
pub struct Size {
|
||||||
@ -80,7 +91,7 @@ pub struct Rgba {
|
|||||||
|
|
||||||
#[derive(Copy, Clone, bytemuck::Zeroable)]
|
#[derive(Copy, Clone, bytemuck::Zeroable)]
|
||||||
pub union Pixel {
|
pub union Pixel {
|
||||||
flat: u32,
|
pub flat: u32,
|
||||||
rgba: Rgba,
|
rgba: Rgba,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user