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.
|
||||
|
||||
use rayon::prelude::*;
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
|
@ -21,9 +22,9 @@ pub struct 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 {
|
||||
device: Arc::new(device),
|
||||
device,
|
||||
queue,
|
||||
frames_in_flight: 2,
|
||||
render_passes: Vec::new(),
|
||||
|
@ -48,7 +49,11 @@ impl Renderer {
|
|||
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 phase_passes = multimap::MultiMap::<Phase, usize>::new();
|
||||
|
@ -71,6 +76,66 @@ impl Renderer {
|
|||
let phase_passes = phase_passes.into_inner().unwrap();
|
||||
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 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 instance = wgpu::Instance::new(wgpu::Backends::all());
|
||||
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);
|
||||
|
||||
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() {
|
||||
let event_loop = EventLoop::new();
|
||||
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 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::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 => {
|
||||
std::thread::sleep(std::time::Duration::from_secs_f32( 1.0 / 60.0 ));
|
||||
window.request_redraw();
|
||||
}
|
||||
Event::WindowEvent {
|
||||
|
@ -58,8 +93,14 @@ fn main() {
|
|||
window_id,
|
||||
} if window_id == window.id() => match event {
|
||||
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