Begin wgpu render passes
This commit is contained in:
parent
718d609517
commit
b81dbd1569
73
src/lib.rs
73
src/lib.rs
|
@ -2,6 +2,7 @@
|
||||||
//! in Rust.
|
//! in Rust.
|
||||||
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
use std::sync::Mutex;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
|
@ -21,9 +22,9 @@ pub struct Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
pub fn new(device: wgpu::Device, queue: wgpu::Queue) -> Self {
|
pub fn new(device: Arc<wgpu::Device>, queue: wgpu::Queue) -> Self {
|
||||||
Self {
|
Self {
|
||||||
device: Arc::new(device),
|
device,
|
||||||
queue,
|
queue,
|
||||||
frames_in_flight: 2,
|
frames_in_flight: 2,
|
||||||
render_passes: Vec::new(),
|
render_passes: Vec::new(),
|
||||||
|
@ -48,7 +49,11 @@ impl Renderer {
|
||||||
self.render_passes.push(pass);
|
self.render_passes.push(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) {
|
pub fn render(
|
||||||
|
&mut self,
|
||||||
|
surface: &wgpu::Surface,
|
||||||
|
format: wgpu::TextureFormat,
|
||||||
|
) -> Result<(), wgpu::SurfaceError> {
|
||||||
let frame_index = 0;
|
let frame_index = 0;
|
||||||
|
|
||||||
let phase_passes = multimap::MultiMap::<Phase, usize>::new();
|
let phase_passes = multimap::MultiMap::<Phase, usize>::new();
|
||||||
|
@ -71,6 +76,66 @@ impl Renderer {
|
||||||
let phase_passes = phase_passes.into_inner().unwrap();
|
let phase_passes = phase_passes.into_inner().unwrap();
|
||||||
let viewport = ViewportData;
|
let viewport = ViewportData;
|
||||||
|
|
||||||
// Up next is actual rendering to a surface!
|
let output = 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"),
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut opaque_cmds = Vec::new();
|
||||||
|
if let Some(opaque) = phase_passes.get_vec(&Phase::Opaque) {
|
||||||
|
opaque.iter().for_each(|pass_index| {
|
||||||
|
let frame_data = IndexedPhaseData {
|
||||||
|
phase: Phase::Opaque,
|
||||||
|
frame_data: frame_index,
|
||||||
|
viewport: &viewport,
|
||||||
|
};
|
||||||
|
|
||||||
|
let pass = &self.render_passes[*pass_index];
|
||||||
|
let mut cmds = self.device.create_render_bundle_encoder(
|
||||||
|
&wgpu::RenderBundleEncoderDescriptor {
|
||||||
|
label: Some("Opaque Pass Render Bundle"),
|
||||||
|
color_formats: &[format],
|
||||||
|
depth_stencil: None,
|
||||||
|
sample_count: 1,
|
||||||
|
multiview: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
pass.record_render(frame_data, &mut cmds);
|
||||||
|
opaque_cmds.push(cmds.finish(&wgpu::RenderBundleDescriptor::default()));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rp = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: Some("Render Pass"),
|
||||||
|
color_attachments: &[wgpu::RenderPassColorAttachment {
|
||||||
|
view: &view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||||
|
r: 0.1,
|
||||||
|
g: 0.2,
|
||||||
|
b: 0.3,
|
||||||
|
a: 1.0,
|
||||||
|
}),
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
rp.execute_bundles(opaque_cmds.iter());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.queue.submit(std::iter::once(encoder.finish()));
|
||||||
|
output.present();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
55
src/main.rs
55
src/main.rs
|
@ -1,7 +1,30 @@
|
||||||
use cyborg::{pass, Renderer};
|
use cyborg::{pass, Renderer};
|
||||||
use winit::{event::*, event_loop::{ControlFlow, EventLoop}, window::WindowBuilder};
|
use std::sync::Arc;
|
||||||
|
use winit::{
|
||||||
|
event::*,
|
||||||
|
event_loop::{ControlFlow, EventLoop},
|
||||||
|
window::WindowBuilder,
|
||||||
|
};
|
||||||
|
|
||||||
async fn make_window_renderer(window: &winit::window::Window) -> Renderer {
|
struct SurfaceViewport {
|
||||||
|
device: Arc<wgpu::Device>,
|
||||||
|
size: winit::dpi::PhysicalSize<u32>,
|
||||||
|
surface: wgpu::Surface,
|
||||||
|
config: wgpu::SurfaceConfiguration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SurfaceViewport {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn make_window_renderer(window: &winit::window::Window) -> (Renderer, SurfaceViewport) {
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
||||||
let surface = unsafe { instance.create_surface(window) };
|
let surface = unsafe { instance.create_surface(window) };
|
||||||
|
@ -33,13 +56,21 @@ async fn make_window_renderer(window: &winit::window::Window) -> Renderer {
|
||||||
};
|
};
|
||||||
surface.configure(&device, &config);
|
surface.configure(&device, &config);
|
||||||
|
|
||||||
Renderer::new(device, queue)
|
let device = Arc::new(device);
|
||||||
|
let renderer = Renderer::new(device.clone(), queue);
|
||||||
|
let viewport = SurfaceViewport {
|
||||||
|
device,
|
||||||
|
size,
|
||||||
|
surface,
|
||||||
|
config,
|
||||||
|
};
|
||||||
|
(renderer, viewport)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||||
let mut renderer = pollster::block_on(make_window_renderer(&window));
|
let (mut renderer, mut viewport) = pollster::block_on(make_window_renderer(&window));
|
||||||
|
|
||||||
let device = renderer.get_device();
|
let device = renderer.get_device();
|
||||||
let mesh_pass = pass::mesh::MeshPass::new(device.to_owned());
|
let mesh_pass = pass::mesh::MeshPass::new(device.to_owned());
|
||||||
|
@ -47,10 +78,14 @@ fn main() {
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| match event {
|
event_loop.run(move |event, _, control_flow| match event {
|
||||||
Event::RedrawRequested(_) => {
|
Event::RedrawRequested(_) => {
|
||||||
renderer.render();
|
match renderer.render(&viewport.surface, viewport.config.format) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(wgpu::SurfaceError::Lost) => viewport.resize(viewport.size),
|
||||||
|
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
|
||||||
|
Err(e) => eprintln!("error: {:?}", e),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Event::MainEventsCleared => {
|
Event::MainEventsCleared => {
|
||||||
std::thread::sleep(std::time::Duration::from_secs_f32( 1.0 / 60.0 ));
|
|
||||||
window.request_redraw();
|
window.request_redraw();
|
||||||
}
|
}
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
|
@ -58,8 +93,14 @@ fn main() {
|
||||||
window_id,
|
window_id,
|
||||||
} if window_id == window.id() => match event {
|
} if window_id == window.id() => match event {
|
||||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
|
WindowEvent::Resized(physical_size) => {
|
||||||
|
viewport.resize(*physical_size);
|
||||||
|
}
|
||||||
|
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||||
|
viewport.resize(**new_inner_size);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue