1
0
Fork 0

[RENDERER] Begin refactor

This commit is contained in:
Florian RICHER 2022-07-25 14:00:36 +02:00
parent df92b1b884
commit dc063f74a1
9 changed files with 65 additions and 54 deletions

View file

@ -1,6 +1,7 @@
use std::{ops::Deref, sync::Arc};
use cgmath::prelude::*;
use ::render::graphics_renderer::GraphicsRenderer;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
@ -9,7 +10,7 @@ use winit::{
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
use crate::render::{DefaultState, Renderer};
use crate::render::{DefaultState, State};
mod camera;
mod model;
@ -156,22 +157,21 @@ pub async fn run() {
.expect("Couldn't append canvas to document body.");
}
let mut renderer = Arc::from(Renderer::new(&window).await);
let default_state = Box::from(DefaultState::new(renderer.deref()).await);
Arc::get_mut(&mut renderer)
.unwrap()
.set_state(Some(default_state));
let mut renderer = Arc::from(GraphicsRenderer::initialize(&window).await);
let mut default_state = Arc::from(DefaultState::new(renderer.deref()).await);
let mut last_render_time = instant::Instant::now();
event_loop.run(move |base_event, _, control_flow| {
*control_flow = ControlFlow::Poll;
let renderer = Arc::get_mut(&mut renderer).unwrap();
let state = Arc::get_mut(&mut default_state).unwrap();
match base_event {
Event::MainEventsCleared => window.request_redraw(),
Event::WindowEvent {
ref event,
window_id,
} if window_id == window.id() && !renderer.input(&base_event) => match event {
} if window_id == window.id() && !state.input(&base_event) => match event {
#[cfg(not(target_arch = "wasm32"))]
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
@ -190,15 +190,20 @@ pub async fn run() {
renderer.resize(**new_inner_size);
}
_ => {
renderer.input(&base_event);
state.input(&base_event);
}
},
Event::RedrawRequested(window_id) if window_id == window.id() => {
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
renderer.update(dt);
match renderer.render() {
state.update(&renderer.queue, dt);
match renderer.render_frame(|view, command| {
let mut renderable = Arc::clone(&default_state);
let state = Arc::get_mut(&mut renderable).unwrap();
state.render(view, command)
}) {
Ok(_) => {}
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
renderer.resize(renderer.size)
@ -208,7 +213,7 @@ pub async fn run() {
}
}
_ => {
renderer.input(&base_event);
state.input(&base_event);
}
}
});

View file

@ -4,4 +4,4 @@ pub use pipelines::utils::create_render_pipeline;
pub use pipelines::{GlobalBindLayout, Pipelines};
mod renderer;
pub use renderer::{DefaultState, Renderer, State};
pub use renderer::{DefaultState, State};

View file

@ -2,6 +2,7 @@ use cgmath::prelude::*;
#[cfg(not(target_arch="wasm32"))]
use rayon::prelude::*;
use ::render::graphics_renderer::GraphicsRenderer;
use wgpu::{util::DeviceExt, Queue};
use winit::event::{DeviceEvent, ElementState, Event, KeyboardInput, MouseButton, WindowEvent};
@ -11,8 +12,6 @@ use crate::{
render, resources, texture, CameraUniform, Instance, LightUniform, NUM_INSTANCES_PER_ROW,
};
use super::Renderer;
pub struct DefaultState {
obj_model: model::Model,
camera: camera::Camera,
@ -35,7 +34,7 @@ pub struct DefaultState {
}
impl DefaultState {
pub async fn new(renderer: &Renderer) -> Self
pub async fn new(renderer: &GraphicsRenderer) -> Self
{
let global_bind_layout = render::GlobalBindLayout::new(&renderer.device);
let pipelines =

View file

@ -1,7 +1,3 @@
mod renderer;
pub use renderer::Renderer;
mod default_state;
pub use default_state::DefaultState;

View file

@ -1,120 +0,0 @@
use std::iter;
use winit::{event::Event, window::Window};
use super::State;
pub struct Renderer {
pub surface: wgpu::Surface,
pub device: wgpu::Device,
pub queue: wgpu::Queue,
pub size: winit::dpi::PhysicalSize<u32>,
pub config: wgpu::SurfaceConfiguration,
state: Option<Box<dyn State>>,
}
impl Renderer {
pub async fn new(window: &Window) -> Self {
let size = window.inner_size();
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::Backends::all());
let surface = unsafe { instance.create_surface(window) };
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::default(),
compatible_surface: Some(&surface),
force_fallback_adapter: false,
})
.await
.unwrap();
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
},
},
None, // Trace path
)
.await
.unwrap();
let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: surface.get_supported_formats(&adapter)[0],
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Fifo,
};
surface.configure(&device, &config);
Self {
surface,
device,
queue,
config,
size,
state: None,
}
}
pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
if new_size.width > 0 && new_size.height > 0 {
self.size = new_size;
self.config.width = new_size.width;
self.config.height = new_size.height;
self.surface.configure(&self.device, &self.config);
if let Some(state) = self.state.as_mut() {
state.resize(&self.device, &self.config, new_size);
}
}
}
pub fn input(&mut self, event: &Event<()>) -> bool {
if let Some(state) = self.state.as_mut() {
return state.input(event);
}
false
}
pub fn update(&mut self, dt: instant::Duration) {
if let Some(state) = self.state.as_mut() {
state.update(&self.queue, dt);
}
}
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
let output = self.surface.get_current_texture()?;
let view = output
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let mut encoder = self
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
});
if let Some(state) = self.state.as_mut() {
state.render(&view, &mut encoder)?;
self.queue.submit(iter::once(encoder.finish()));
output.present();
}
Ok(())
}
pub fn set_state(&mut self, state: Option<Box<dyn State>>) {
self.state = state;
}
}