Clean up frame implementation
Sprites no longer need to handle the frame creation as it is fully handled by the renderer itself. The fields order in the renderer have also been swapped to drop things in the right order
This commit is contained in:
parent
c2e884f68c
commit
2e326306d9
@ -27,9 +27,10 @@ pub trait Application<S> {
|
|||||||
|
|
||||||
//--Canvas struct-----------------------------------------------------------------------------------
|
//--Canvas struct-----------------------------------------------------------------------------------
|
||||||
pub struct Canvas {
|
pub struct Canvas {
|
||||||
renderer: WgpuRenderer,
|
|
||||||
clear_color: Pixel,
|
|
||||||
default_texture: TextureHandle,
|
default_texture: TextureHandle,
|
||||||
|
clear_color: Pixel,
|
||||||
|
|
||||||
|
renderer: WgpuRenderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Canvas {
|
impl Canvas {
|
||||||
|
|||||||
@ -30,7 +30,7 @@ fn setup_logger() -> Result<(), fern::InitError> {
|
|||||||
message
|
message
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.level(log::LevelFilter::Info)
|
.level(log::LevelFilter::Debug)
|
||||||
.chain(std::io::stdout())
|
.chain(std::io::stdout())
|
||||||
.chain(fern::log_file("output.log")?)
|
.chain(fern::log_file("output.log")?)
|
||||||
.apply()?; Ok(())
|
.apply()?; Ok(())
|
||||||
|
|||||||
140
src/renderer.rs
140
src/renderer.rs
@ -22,21 +22,22 @@ pub use matrix::ModelMatrix as ModelMatrix;
|
|||||||
|
|
||||||
//--Renderer struct---------------------------------------------------------------------------------
|
//--Renderer struct---------------------------------------------------------------------------------
|
||||||
pub struct WgpuRenderer {
|
pub struct WgpuRenderer {
|
||||||
surface: wgpu::Surface,
|
|
||||||
pub device: wgpu::Device,
|
|
||||||
pub queue: wgpu::Queue,
|
|
||||||
pub config: wgpu::SurfaceConfiguration,
|
|
||||||
|
|
||||||
surface_size: Size,
|
|
||||||
pub output: Option<wgpu::SurfaceTexture>,
|
|
||||||
|
|
||||||
pub matrix_layout: wgpu::BindGroupLayout,
|
|
||||||
pub texture_layout: wgpu::BindGroupLayout,
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
shape_render_pipeline: wgpu::RenderPipeline,
|
shape_render_pipeline: wgpu::RenderPipeline,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
quad_mesh: GpuMesh<ColorVertex, 4, 6>, //TODO temporary, to be moved to shapes.rs
|
quad_mesh: GpuMesh<ColorVertex, 4, 6>, //TODO temporary, to be moved to shapes.rs
|
||||||
|
|
||||||
|
pub texture_layout: wgpu::BindGroupLayout,
|
||||||
|
pub matrix_layout: wgpu::BindGroupLayout,
|
||||||
|
|
||||||
|
frame: Option<wgpu::SurfaceTexture>,
|
||||||
|
surface: wgpu::Surface,
|
||||||
|
surface_size: Size,
|
||||||
|
|
||||||
|
pub config: wgpu::SurfaceConfiguration,
|
||||||
|
pub queue: wgpu::Queue,
|
||||||
|
pub device: wgpu::Device,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuRenderer {
|
impl WgpuRenderer {
|
||||||
@ -92,8 +93,8 @@ impl WgpuRenderer {
|
|||||||
// Matrix3::from_nonuniform_scale(1.0, 1.0)
|
// Matrix3::from_nonuniform_scale(1.0, 1.0)
|
||||||
//};
|
//};
|
||||||
|
|
||||||
let output = Some(surface.get_current_texture()
|
let frame = Some(surface.get_current_texture()
|
||||||
.map_err(|_| "Failed to create SurfaceTexture")?);
|
.map_err(|_| "Failed to create frame")?);
|
||||||
|
|
||||||
let matrix_layout = utils::new_matrix_layout(&device);
|
let matrix_layout = utils::new_matrix_layout(&device);
|
||||||
let texture_layout = utils::new_texture_layout(&device);
|
let texture_layout = utils::new_texture_layout(&device);
|
||||||
@ -174,16 +175,19 @@ impl WgpuRenderer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
surface,
|
|
||||||
device,
|
|
||||||
queue,
|
|
||||||
config,
|
|
||||||
surface_size,
|
|
||||||
output,
|
|
||||||
matrix_layout,
|
|
||||||
texture_layout,
|
|
||||||
shape_render_pipeline,
|
shape_render_pipeline,
|
||||||
quad_mesh,
|
quad_mesh,
|
||||||
|
|
||||||
|
texture_layout,
|
||||||
|
matrix_layout,
|
||||||
|
|
||||||
|
frame,
|
||||||
|
surface,
|
||||||
|
surface_size,
|
||||||
|
|
||||||
|
config,
|
||||||
|
queue,
|
||||||
|
device,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,15 +197,7 @@ impl WgpuRenderer {
|
|||||||
|
|
||||||
pub fn clear(&mut self, color: Pixel) {
|
pub fn clear(&mut self, color: Pixel) {
|
||||||
|
|
||||||
let output = match &self.output {
|
let view = self.create_texture_view();
|
||||||
Some(out) => out,
|
|
||||||
None => {
|
|
||||||
self.create_output();
|
|
||||||
&self.output.as_ref().unwrap()
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||||
label: Some("Clear Encoder"),
|
label: Some("Clear Encoder"),
|
||||||
});
|
});
|
||||||
@ -224,37 +220,86 @@ impl WgpuRenderer {
|
|||||||
self.queue.submit(std::iter::once(encoder.finish()));
|
self.queue.submit(std::iter::once(encoder.finish()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resizes the render area to fit the given size.
|
||||||
|
///
|
||||||
|
/// The current frame is dropped, clearing any of the rendering done. The underlying surface is
|
||||||
|
/// then reconfigured to the right size before a new frame can be created.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// The function will panic is the given size has any of its values equal to 0 or if the
|
||||||
|
/// renderer fails to create a new frame
|
||||||
pub fn resize(&mut self, size: Size) {
|
pub fn resize(&mut self, size: Size) {
|
||||||
|
|
||||||
|
trace!("resizing render area...");
|
||||||
|
|
||||||
|
// check for valid size
|
||||||
if size.w == 0 || size.h == 0 {
|
if size.w == 0 || size.h == 0 {
|
||||||
panic!("window has zero as at least one of its dimensions");
|
panic!("window has zero as at least one of its dimensions");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.surface_size = size;
|
//destroy current frame
|
||||||
//self.aspect_matrix = {
|
match self.frame.take() {
|
||||||
// use cgmath::{Basis3, Rotation3, Deg};
|
Some(out) => drop(out),
|
||||||
|
None => {}//nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
// //Matrix3::from(Basis3::from_angle_x(Deg(-0.0)))
|
//reconfigure surface
|
||||||
// //* 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);
|
||||||
|
|
||||||
|
//generate new frame from new surface
|
||||||
|
let frame = self.create_frame();
|
||||||
|
let _ = self.frame.insert(frame);
|
||||||
|
|
||||||
|
debug!("render area resized !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Presents the current frame to the screen.
|
||||||
|
///
|
||||||
|
/// The current frame is presented and a new one is created for the future renders
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// The function will panic if the renderer fails to create a new frame
|
||||||
pub fn present(&mut self) {
|
pub fn present(&mut self) {
|
||||||
|
|
||||||
match self.output.take() {
|
trace!("presenting frame...");
|
||||||
|
match self.frame.take() {
|
||||||
Some(out) => out.present(),
|
Some(out) => out.present(),
|
||||||
None => {
|
None => {}//nothing to do
|
||||||
}//nothing to do
|
|
||||||
}
|
}
|
||||||
|
debug!("frame presented !");
|
||||||
|
|
||||||
|
//generate next frame
|
||||||
|
let frame = self.create_frame();
|
||||||
|
let _ = self.frame.insert(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_output(&mut self) {
|
pub fn create_texture_view(&self) -> wgpu::TextureView {
|
||||||
self.output = Some(
|
|
||||||
|
self.frame
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.texture
|
||||||
|
.create_view(&wgpu::TextureViewDescriptor::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new frame to be rendered on.
|
||||||
|
///
|
||||||
|
/// In case of a lost surface, will try to reconfigure it before creating the frame.
|
||||||
|
///
|
||||||
|
/// #Panics
|
||||||
|
///
|
||||||
|
/// The underlying backend will panic if a new frame is created while the previous one is still
|
||||||
|
/// alive. Only call this function after the previous frame was either dropped or presented.
|
||||||
|
///
|
||||||
|
/// The function will panic if the frame can't be created.
|
||||||
|
fn create_frame(&mut self) -> wgpu::SurfaceTexture {
|
||||||
|
|
||||||
|
trace!("creating new frame...");
|
||||||
|
let surface_texture = {
|
||||||
self.surface.get_current_texture()
|
self.surface.get_current_texture()
|
||||||
.map_err(|err| match err {
|
.map_err(|err| match err {
|
||||||
wgpu::SurfaceError::Lost => {
|
wgpu::SurfaceError::Lost => {
|
||||||
@ -263,8 +308,13 @@ impl WgpuRenderer {
|
|||||||
self.surface.get_current_texture()
|
self.surface.get_current_texture()
|
||||||
},
|
},
|
||||||
_ => Err(err)
|
_ => Err(err)
|
||||||
}).unwrap()
|
})
|
||||||
);
|
.map_err(|_| "Failed to acquire to SurfaceTexture, giving up")
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
debug!("frame created !");
|
||||||
|
|
||||||
|
surface_texture
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
use wgpu;
|
//--Internal imports--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
use super::Sprite;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
texture::TextureHandle,
|
texture::TextureHandle,
|
||||||
@ -12,8 +14,9 @@ use crate::{
|
|||||||
utils::{Size, Position, Pixel},
|
utils::{Size, Position, Pixel},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Sprite;
|
//--External imports--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
use wgpu;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
thread_local!(static PIPELINE : RefCell<Option<wgpu::RenderPipeline>> = RefCell::new(None));
|
thread_local!(static PIPELINE : RefCell<Option<wgpu::RenderPipeline>> = RefCell::new(None));
|
||||||
@ -118,11 +121,6 @@ impl TextureSprite {
|
|||||||
//TODO take scale into account
|
//TODO take scale into account
|
||||||
self.texture.for_each_in_area(func, self.texture_offset, self.inner_size);
|
self.texture.for_each_in_area(func, self.texture_offset, self.inner_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self)
|
|
||||||
{
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_pipeline(renderer: &WgpuRenderer) -> wgpu::RenderPipeline {
|
fn initialize_pipeline(renderer: &WgpuRenderer) -> wgpu::RenderPipeline {
|
||||||
@ -196,7 +194,7 @@ impl Sprite for TextureSprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_alpha(&mut self, _alpha: u8) {
|
fn set_alpha(&mut self, _alpha: u8) {
|
||||||
unimplemented!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_scale(&mut self, scale: f32) {
|
fn set_scale(&mut self, scale: f32) {
|
||||||
@ -205,19 +203,7 @@ impl Sprite for TextureSprite {
|
|||||||
|
|
||||||
fn render(&mut self, renderer: &mut WgpuRenderer) {
|
fn render(&mut self, renderer: &mut WgpuRenderer) {
|
||||||
|
|
||||||
let output = match &renderer.output {
|
|
||||||
Some(out) => out,
|
|
||||||
None => {
|
|
||||||
renderer.create_output();
|
|
||||||
&renderer.output.as_ref().unwrap()
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
//TODO move that to output struct ?
|
|
||||||
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
|
|
||||||
let texture = &self.texture.texture();
|
let texture = &self.texture.texture();
|
||||||
|
|
||||||
if texture.borrow().is_synced == false {
|
if texture.borrow().is_synced == false {
|
||||||
//TODO modify that
|
//TODO modify that
|
||||||
texture.borrow_mut().update(&mut renderer.queue);
|
texture.borrow_mut().update(&mut renderer.queue);
|
||||||
@ -236,6 +222,7 @@ impl Sprite for TextureSprite {
|
|||||||
let pipeline = pipeline.borrow();
|
let pipeline = pipeline.borrow();
|
||||||
let texture_bind_group = &texture.borrow().bind_group;
|
let texture_bind_group = &texture.borrow().bind_group;
|
||||||
|
|
||||||
|
let view = renderer.create_texture_view();
|
||||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
label: Some("Render Pass"),
|
label: Some("Render Pass"),
|
||||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user