scene module + better trait/generic relationships

This commit is contained in:
mars 2022-05-11 09:30:01 -06:00
parent 31e336f4ef
commit 7e855f5a46
8 changed files with 210 additions and 173 deletions

View File

@ -3,9 +3,9 @@ use std::f32::consts::LN_2;
use std::time::Instant; use std::time::Instant;
use winit::event::{ElementState, VirtualKeyCode}; use winit::event::{ElementState, VirtualKeyCode};
pub trait Camera { pub struct Camera {
fn get_eye(&self) -> [f32; 4]; pub eye: [f32; 4],
fn get_vp(&self) -> [[f32; 4]; 4]; pub vp: [[f32; 4]; 4],
} }
#[derive(Debug)] #[derive(Debug)]
@ -209,14 +209,19 @@ impl Flycam {
fn get_orientation(&self) -> glam::Quat { fn get_orientation(&self) -> glam::Quat {
Quat::from_euler(glam::EulerRot::YXZ, self.euler_y, self.euler_x, 0.0) Quat::from_euler(glam::EulerRot::YXZ, self.euler_y, self.euler_x, 0.0)
} }
}
impl Camera for Flycam { pub fn get_camera(&self) -> Camera {
fn get_eye(&self) -> [f32; 4] { Camera {
eye: self.get_eye(),
vp: self.get_vp()
}
}
pub fn get_eye(&self) -> [f32; 4] {
self.position.extend(0.0).to_array() self.position.extend(0.0).to_array()
} }
fn get_vp(&self) -> [[f32; 4]; 4] { pub fn get_vp(&self) -> [[f32; 4]; 4] {
// view matrix is inverted camera pose (world space to camera space) // view matrix is inverted camera pose (world space to camera space)
let rotation = Mat4::from_quat(self.get_orientation().inverse()); let rotation = Mat4::from_quat(self.get_orientation().inverse());
let translation = Mat4::from_translation(-self.position); let translation = Mat4::from_translation(-self.position);

View File

@ -1,13 +1,14 @@
//! Cyborg is a high-performance, modern, experimental rendering engine written //! Cyborg is a high-performance, modern, experimental rendering engine written
//! in Rust. //! in Rust.
use parking_lot::Mutex;
use rayon::prelude::*; use rayon::prelude::*;
use std::sync::Arc; use std::sync::Arc;
use parking_lot::Mutex;
pub mod camera; pub mod camera;
pub mod pass; pub mod pass;
pub mod phase; pub mod phase;
pub mod scene;
pub mod shader; pub mod shader;
pub mod staging; pub mod staging;
pub mod storage; pub mod storage;
@ -16,7 +17,7 @@ pub mod viewport;
use camera::Camera; use camera::Camera;
use pass::*; use pass::*;
use phase::*; use phase::*;
use viewport::ViewportImage; use viewport::Viewport;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
@ -26,10 +27,10 @@ pub struct ViewportUniform {
} }
impl ViewportUniform { impl ViewportUniform {
pub fn from_camera(camera: &impl Camera) -> Self { pub fn from_camera(camera: &Camera) -> Self {
Self { Self {
eye: camera.get_eye(), eye: camera.eye,
vp: camera.get_vp(), vp: camera.vp,
} }
} }
} }
@ -160,21 +161,16 @@ impl Renderer {
&self.layouts &self.layouts
} }
pub fn add_pass<T: 'static + RenderPass>(&mut self, pass: T) { pub fn get_frames_in_flight(&self) -> usize {
let pass = Arc::new(pass); self.frames_in_flight
self.add_pass_arc(pass);
} }
pub fn add_pass_arc<T: 'static + RenderPass>(&mut self, pass: Arc<T>) { pub fn render<'a>(
let pass = RenderPassBox::new(pass, self.frames_in_flight); &mut self,
self.add_pass_box(pass); passes: &mut [&mut dyn RenderPassBoxTrait],
} target: &dyn Viewport,
camera: &Camera,
pub fn add_pass_box(&mut self, pass: Box<dyn RenderPassBoxTrait>) { ) {
self.render_passes.push(pass);
}
pub fn render<'a>(&mut self, target: &impl ViewportImage<'a>, camera: &impl Camera) {
self.frame_index += 1; self.frame_index += 1;
if self.frame_index >= self.frame_datas.len() { if self.frame_index >= self.frame_datas.len() {
self.frame_index = 0; self.frame_index = 0;
@ -193,7 +189,7 @@ impl Renderer {
let phase_passes = multimap::MultiMap::<Phase, usize>::new(); let phase_passes = multimap::MultiMap::<Phase, usize>::new();
let phase_passes = std::sync::Mutex::new(phase_passes); let phase_passes = std::sync::Mutex::new(phase_passes);
self.render_passes passes
.par_iter_mut() .par_iter_mut()
.enumerate() .enumerate()
.for_each(|(pass_index, rp)| { .for_each(|(pass_index, rp)| {
@ -219,7 +215,7 @@ impl Renderer {
if let Some(upload) = phase_passes.get_vec(&Phase::Upload) { if let Some(upload) = phase_passes.get_vec(&Phase::Upload) {
upload.iter().for_each(|pass_index| { upload.iter().for_each(|pass_index| {
let phase_data = frame_data.make_phase_data(Phase::Upload, &viewport); let phase_data = frame_data.make_phase_data(Phase::Upload, &viewport);
let pass = &self.render_passes[*pass_index]; let pass = &passes[*pass_index];
pass.record_commands(phase_data, &mut encoder); pass.record_commands(phase_data, &mut encoder);
}); });
} }
@ -231,17 +227,17 @@ impl Renderer {
skinning.iter().for_each(|pass_index| { skinning.iter().for_each(|pass_index| {
let phase_data = frame_data.make_phase_data(Phase::Skinning, &viewport); let phase_data = frame_data.make_phase_data(Phase::Skinning, &viewport);
let pass = &self.render_passes[*pass_index]; let pass = &passes[*pass_index];
pass.record_compute(phase_data, &mut cmds); pass.record_compute(phase_data, &mut cmds);
}) })
} }
let record_render = |phase| { let record_render = |phase| {
let cmds = Mutex::new(Vec::new()); let cmds = Mutex::new(Vec::new());
if let Some(passes) = phase_passes.get_vec(&phase) { if let Some(phase_passes) = phase_passes.get_vec(&phase) {
passes.par_iter().for_each(|pass_index| { phase_passes.par_iter().for_each(|pass_index| {
let phase_data = frame_data.make_phase_data(phase, &viewport); let phase_data = frame_data.make_phase_data(phase, &viewport);
let pass = &self.render_passes[*pass_index]; let pass = &passes[*pass_index];
if let Some(cmd) = pass.record_render(phase_data) { if let Some(cmd) = pass.record_render(phase_data) {
cmds.lock().push(cmd); cmds.lock().push(cmd);

View File

@ -1,4 +1,5 @@
use cyborg::shader; use cyborg::shader;
use cyborg::storage::mesh::*;
use cyborg::{pass, viewport::*, Renderer}; use cyborg::{pass, viewport::*, Renderer};
use std::sync::Arc; use std::sync::Arc;
use winit::{ use winit::{
@ -13,7 +14,7 @@ fn main() {
let mut viewport = pollster::block_on(WinitViewport::from_window(&window)); let mut viewport = pollster::block_on(WinitViewport::from_window(&window));
let mut renderer = Renderer::new(viewport.device.clone(), viewport.queue.clone()); let mut renderer = Renderer::new(viewport.device.clone(), viewport.queue.clone());
let mut camera = cyborg::camera::Flycam::new(0.002, 10.0, 0.25); let mut flycam = cyborg::camera::Flycam::new(0.002, 10.0, 0.25);
let mut is_grabbed = false; let mut is_grabbed = false;
let device = renderer.get_device(); let device = renderer.get_device();
@ -43,31 +44,85 @@ fn main() {
let debug_pass = let debug_pass =
pass::debug::DebugPass::new(device.to_owned(), layouts.to_owned(), viewport.get_info()); pass::debug::DebugPass::new(device.to_owned(), layouts.to_owned(), viewport.get_info());
renderer.add_pass(mesh_pass); let example_vertices = vec![
renderer.add_pass(debug_pass); pass::mesh::Vertex {
position: [-0.5, 0.5, 0.0],
tan_frame: 0,
},
pass::mesh::Vertex {
position: [0.5, 0.5, 0.0],
tan_frame: 0,
},
pass::mesh::Vertex {
position: [0.0, -0.5, 0.0],
tan_frame: 0,
},
];
let example_vertices = AttrBuffer {
id: mesh_pass.get_vertex_attr_id(),
count: example_vertices.len(),
data: bytemuck::cast_slice(&example_vertices).to_vec(),
};
let example_indices = vec![0u32, 1u32, 2u32];
let example_indices = AttrBuffer {
id: mesh_pass.get_index_attr_id(),
count: example_indices.len(),
data: bytemuck::cast_slice(&example_indices).to_vec(),
};
let mut example_mesh = MeshBuffer::default();
example_mesh.attributes.push(example_vertices);
example_mesh.attributes.push(example_indices);
let example_mesh = mesh_pass.get_mesh_pool().load(example_mesh).unwrap();
let meshes = mesh_pass.get_meshes().to_owned();
let r = 8;
let mut meshes_lock = meshes.write();
for x in -r..r {
for y in -r..r {
for z in -r..r {
let translation = glam::Vec3::new(x as f32, y as f32, z as f32);
let transform = glam::Mat4::from_translation(translation);
meshes_lock.transformed.push(cyborg::scene::TransformedMesh {
transform,
mesh: example_mesh.clone(),
});
}
}
}
drop(meshes_lock);
let frames_in_flight = renderer.get_frames_in_flight();
let mut mesh_pass = pass::RenderPassBox::new(Arc::new(mesh_pass), frames_in_flight);
let mut debug_pass = pass::RenderPassBox::new(Arc::new(debug_pass), frames_in_flight);
event_loop.run(move |event, _, control_flow| match event { event_loop.run(move |event, _, control_flow| match event {
Event::RedrawRequested(_) => { Event::RedrawRequested(_) => {
println!("camera: {:#?}", camera);
match viewport.acquire() { match viewport.acquire() {
Err(wgpu::SurfaceError::Lost) => viewport.resize(viewport.size), Err(wgpu::SurfaceError::Lost) => viewport.resize(viewport.size),
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
Err(e) => eprintln!("error: {:?}", e), Err(e) => eprintln!("error: {:?}", e),
Ok(target) => { Ok(_) => {
renderer.render(&target, &camera); let mut passes: Vec<&mut dyn pass::RenderPassBoxTrait> = Vec::new();
target.present(); passes.push(&mut mesh_pass);
passes.push(&mut debug_pass);
renderer.render(passes.as_mut_slice(), &viewport, &flycam.get_camera());
viewport.present();
} }
} }
} }
Event::MainEventsCleared => { Event::MainEventsCleared => {
shader_watcher.watch(); shader_watcher.watch();
camera.update(); flycam.update();
window.request_redraw(); window.request_redraw();
} }
Event::DeviceEvent { ref event, .. } => match event { Event::DeviceEvent { ref event, .. } => match event {
DeviceEvent::MouseMotion { delta } => { DeviceEvent::MouseMotion { delta } => {
if is_grabbed { if is_grabbed {
camera.process_mouse(delta.0, delta.1); flycam.process_mouse(delta.0, delta.1);
} }
} }
_ => {} _ => {}
@ -92,7 +147,7 @@ fn main() {
is_grabbed = false; is_grabbed = false;
} }
} else { } else {
camera.process_keyboard(*key, *state); flycam.process_keyboard(*key, *state);
} }
} }
WindowEvent::MouseInput { WindowEvent::MouseInput {

View File

@ -97,17 +97,23 @@ impl<T: 'static + RenderPass> RenderPassBox<T> {
/// ///
/// Calls to [RenderPassBoxTrait] functions with frame indices greater /// Calls to [RenderPassBoxTrait] functions with frame indices greater
/// than or equal to `frame_num` are out-of-bounds and will panic. /// than or equal to `frame_num` are out-of-bounds and will panic.
pub fn new(render_pass: Arc<T>, frame_num: usize) -> Box<dyn RenderPassBoxTrait> { pub fn new(render_pass: Arc<T>, frame_num: usize) -> Self {
let frame_data = { let frame_data = {
(0..frame_num) (0..frame_num)
.map(|_| render_pass.create_frame_data()) .map(|_| render_pass.create_frame_data())
.collect() .collect()
}; };
Box::new(Self { Self {
render_pass, render_pass,
frame_data, frame_data,
}) }
}
/// Same as [Self::new], but creates a boxed [RenderPassBoxTrait] in a
/// generic-friendly interface.
pub fn new_boxed(render_pass: Arc<T>, frame_num: usize) -> Box<dyn RenderPassBoxTrait> {
Box::new(Self::new(render_pass, frame_num))
} }
} }

View File

@ -2,28 +2,7 @@ use super::*;
use crate::storage::GpuVec; use crate::storage::GpuVec;
use crate::viewport::ViewportInfo; use crate::viewport::ViewportInfo;
use crate::RenderLayouts; use crate::RenderLayouts;
use crate::scene::{DebugVertex as Vertex, DebugIndex as Index};
#[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct Vertex {
pub position: [f32; 3],
pub color: [f32; 3],
}
const VERTEX_ATTRS: &[wgpu::VertexAttribute] =
&wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3];
impl Vertex {
pub fn desc() -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: VERTEX_ATTRS,
}
}
}
pub type Index = u32;
pub struct FrameData { pub struct FrameData {
vertices: GpuVec<Vertex>, vertices: GpuVec<Vertex>,

View File

@ -1,10 +1,12 @@
use super::*; use super::*;
use crate::scene;
use crate::shader::{ShaderHandle, ShaderStore}; use crate::shader::{ShaderHandle, ShaderStore};
use crate::storage::mesh::*; use crate::storage::mesh::*;
use crate::storage::GpuVec; use crate::storage::GpuVec;
use crate::viewport::ViewportInfo; use crate::viewport::ViewportInfo;
use crate::RenderLayouts; use crate::RenderLayouts;
#[derive(Clone)]
pub struct ShaderInfo { pub struct ShaderInfo {
pub store: Arc<ShaderStore>, pub store: Arc<ShaderStore>,
pub forward: ShaderHandle, pub forward: ShaderHandle,
@ -66,11 +68,6 @@ struct MeshGroupCommands {
meshes: Vec<MeshCommand>, meshes: Vec<MeshCommand>,
} }
pub struct MeshInstance {
pub transform: glam::Mat4,
pub mesh: MeshHandle,
}
pub struct FrameData { pub struct FrameData {
skinned_vertices: GpuVec<Vertex>, skinned_vertices: GpuVec<Vertex>,
skinning_uniforms: GpuVec<SkinningUniform>, skinning_uniforms: GpuVec<SkinningUniform>,
@ -86,13 +83,12 @@ pub struct MeshPass {
vertex_attr_id: AttrId, vertex_attr_id: AttrId,
index_attr_id: AttrId, index_attr_id: AttrId,
mesh_layout_id: MeshLayoutId, mesh_layout_id: MeshLayoutId,
example_mesh: MeshHandle,
skinning_bind_group_layout: wgpu::BindGroupLayout, skinning_bind_group_layout: wgpu::BindGroupLayout,
skinning_pipeline: wgpu::ComputePipeline, skinning_pipeline: wgpu::ComputePipeline,
depth_pipeline: wgpu::RenderPipeline, depth_pipeline: wgpu::RenderPipeline,
opaque_pipeline: wgpu::RenderPipeline, opaque_pipeline: wgpu::RenderPipeline,
target_info: ViewportInfo, target_info: ViewportInfo,
instances: Vec<MeshInstance>, meshes: scene::MeshesHandle,
} }
impl MeshPass { impl MeshPass {
@ -119,54 +115,6 @@ impl MeshPass {
mesh_layout.insert(index_attr_id, ()); mesh_layout.insert(index_attr_id, ());
let mesh_layout_id = mesh_pool.add_layout(mesh_layout).unwrap(); let mesh_layout_id = mesh_pool.add_layout(mesh_layout).unwrap();
let example_vertices = vec![
Vertex {
position: [-0.5, 0.5, 0.0],
tan_frame: 0,
},
Vertex {
position: [0.5, 0.5, 0.0],
tan_frame: 0,
},
Vertex {
position: [0.0, -0.5, 0.0],
tan_frame: 0,
},
];
let example_vertices = AttrBuffer {
id: vertex_attr_id,
count: example_vertices.len(),
data: bytemuck::cast_slice(&example_vertices).to_vec(),
};
let example_indices = vec![0u32, 1u32, 2u32];
let example_indices = AttrBuffer {
id: index_attr_id,
count: example_indices.len(),
data: bytemuck::cast_slice(&example_indices).to_vec(),
};
let mut example_mesh = MeshBuffer::default();
example_mesh.attributes.push(example_vertices);
example_mesh.attributes.push(example_indices);
let example_mesh = mesh_pool.load(example_mesh).unwrap();
let mut instances = Vec::new();
let r = 4;
for x in -r..r {
for y in -r..r {
for z in -r..r {
let translation = glam::Vec3::new(x as f32, y as f32, z as f32);
let transform = glam::Mat4::from_translation(translation);
instances.push(MeshInstance {
transform,
mesh: example_mesh.clone(),
});
}
}
}
let render_pipeline_layout = let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("MeshPass Pipeline Layout"), label: Some("MeshPass Pipeline Layout"),
@ -297,15 +245,30 @@ impl MeshPass {
index_attr_id, index_attr_id,
vertex_attr_id, vertex_attr_id,
mesh_layout_id, mesh_layout_id,
example_mesh,
skinning_bind_group_layout, skinning_bind_group_layout,
skinning_pipeline, skinning_pipeline,
depth_pipeline, depth_pipeline,
opaque_pipeline, opaque_pipeline,
target_info, target_info,
instances, meshes: Default::default(),
} }
} }
pub fn get_mesh_pool(&self) -> &MeshPool {
&self.mesh_pool
}
pub fn get_vertex_attr_id(&self) -> AttrId {
self.vertex_attr_id
}
pub fn get_index_attr_id(&self) -> AttrId {
self.index_attr_id
}
pub fn get_meshes(&self) -> &scene::MeshesHandle {
&self.meshes
}
} }
impl RenderPass for MeshPass { impl RenderPass for MeshPass {
@ -343,9 +306,12 @@ impl RenderPass for MeshPass {
data.groups.clear(); data.groups.clear();
data.skinning_uniforms.clear(); data.skinning_uniforms.clear();
let meshes_read = self.meshes.read();
let mesh_bindings = self let mesh_bindings = self
.mesh_pool .mesh_pool
.iter_meshes(self.mesh_layout_id, self.instances.iter(), |i| &i.mesh) .iter_meshes(self.mesh_layout_id, meshes_read.transformed.iter(), |i| {
&i.mesh
})
.unwrap(); .unwrap();
let mut skinned_cursor = 0; let mut skinned_cursor = 0;
@ -468,8 +434,6 @@ impl RenderPass for MeshPass {
} }
fn record_render(&self, data: PhaseData<&FrameData>) -> Option<wgpu::RenderBundle> { fn record_render(&self, data: PhaseData<&FrameData>) -> Option<wgpu::RenderBundle> {
println!("MeshPass::record_render(phase: {:?})", data.phase);
let pipeline = match data.phase { let pipeline = match data.phase {
Phase::Depth => &self.depth_pipeline, Phase::Depth => &self.depth_pipeline,
Phase::Opaque => &self.opaque_pipeline, Phase::Opaque => &self.opaque_pipeline,
@ -491,7 +455,7 @@ impl RenderPass for MeshPass {
}); });
// yikes // yikes
let mesh_bindings: Vec<(MeshLayoutBindings, &Vec<MeshCommand>)> = data let mesh_bindings: Vec<_> = data
.frame_data .frame_data
.groups .groups
.iter() .iter()

54
src/scene.rs Normal file
View File

@ -0,0 +1,54 @@
//! Traits for describing Cyborg's scene representation.
//!
//! TODO this will all need to be replaced in favor of a way to represent
//! querying component and resource data framework-agnostically
use crate::storage::mesh::MeshHandle;
use parking_lot::RwLock;
use std::sync::Arc;
pub struct TransformedMesh {
pub transform: glam::Mat4,
pub mesh: MeshHandle,
}
#[derive(Default)]
pub struct Meshes {
pub transformed: Vec<TransformedMesh>,
}
pub type MeshesHandle = Arc<RwLock<Meshes>>;
#[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct DebugVertex {
pub position: [f32; 3],
pub color: [f32; 3],
}
pub const DEBUG_VERTEX_ATTRS: &[wgpu::VertexAttribute] =
&wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3];
impl DebugVertex {
pub fn desc() -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: DEBUG_VERTEX_ATTRS,
}
}
}
pub type DebugIndex = u32;
pub struct DebugDraw {
pub vertices: Vec<DebugVertex>,
pub indices: Vec<DebugIndex>,
}
#[derive(Default)]
pub struct DebugDraws {
pub draws: Vec<DebugDraw>,
}
pub type DebugDrawsHandle = Arc<RwLock<DebugDraws>>;

View File

@ -14,12 +14,6 @@ pub struct ViewportViews<'a> {
pub trait Viewport { pub trait Viewport {
fn get_info(&self) -> ViewportInfo; fn get_info(&self) -> ViewportInfo;
fn get_queue(&self) -> &wgpu::Queue; fn get_queue(&self) -> &wgpu::Queue;
}
pub trait ViewportImage<'a> {
type Viewport: Viewport;
fn get_viewport(&self) -> &Self::Viewport;
fn get_views(&self) -> ViewportViews; fn get_views(&self) -> ViewportViews;
} }
@ -27,11 +21,13 @@ pub struct WinitViewport {
pub device: Arc<wgpu::Device>, pub device: Arc<wgpu::Device>,
pub queue: Arc<wgpu::Queue>, pub queue: Arc<wgpu::Queue>,
pub size: winit::dpi::PhysicalSize<u32>, pub size: winit::dpi::PhysicalSize<u32>,
pub surface: wgpu::Surface, surface: wgpu::Surface,
pub config: wgpu::SurfaceConfiguration, config: wgpu::SurfaceConfiguration,
pub info: ViewportInfo, info: ViewportInfo,
pub depth_texture: wgpu::Texture, depth_texture: wgpu::Texture,
pub depth_texture_view: wgpu::TextureView, depth_texture_view: wgpu::TextureView,
surface_texture: Option<wgpu::SurfaceTexture>,
output_view: Option<wgpu::TextureView>,
} }
impl WinitViewport { impl WinitViewport {
@ -88,22 +84,18 @@ impl WinitViewport {
info, info,
depth_texture, depth_texture,
depth_texture_view, depth_texture_view,
surface_texture: None,
output_view: None,
} }
} }
pub fn acquire(&mut self) -> Result<WinitImage, wgpu::SurfaceError> { pub fn acquire(&mut self) -> Result<(), wgpu::SurfaceError> {
let surface_texture = self.surface.get_current_texture()?; let surface_texture = self.surface.get_current_texture()?;
let output_view = surface_texture self.output_view = Some(surface_texture
.texture .texture
.create_view(&wgpu::TextureViewDescriptor::default()); .create_view(&wgpu::TextureViewDescriptor::default()));
let depth_view = &self.depth_texture_view; self.surface_texture = Some(surface_texture);
Ok(())
Ok(WinitImage {
viewport: self,
surface_texture,
output_view,
depth_view,
})
} }
pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
@ -119,6 +111,12 @@ impl WinitViewport {
} }
} }
pub fn present(&mut self) {
if let Some(surface_texture) = self.surface_texture.take() {
surface_texture.present();
}
}
fn make_depth_texture( fn make_depth_texture(
device: &wgpu::Device, device: &wgpu::Device,
config: &wgpu::SurfaceConfiguration, config: &wgpu::SurfaceConfiguration,
@ -151,32 +149,12 @@ impl Viewport for WinitViewport {
fn get_queue(&self) -> &wgpu::Queue { fn get_queue(&self) -> &wgpu::Queue {
&self.queue &self.queue
} }
}
pub struct WinitImage<'a> {
viewport: &'a WinitViewport,
surface_texture: wgpu::SurfaceTexture,
output_view: wgpu::TextureView,
depth_view: &'a wgpu::TextureView,
}
impl<'a> WinitImage<'a> {
pub fn present(self) {
self.surface_texture.present();
}
}
impl<'a> ViewportImage<'a> for WinitImage<'a> {
type Viewport = WinitViewport;
fn get_viewport(&self) -> &WinitViewport {
self.viewport
}
fn get_views(&self) -> ViewportViews { fn get_views(&self) -> ViewportViews {
ViewportViews { let output = self.output_view.as_ref().unwrap();
output: &self.output_view, ViewportViews {
depth: self.depth_view, output,
depth: &self.depth_texture_view
} }
} }
} }