Merge branch 'renderer-refactor'
This commit is contained in:
commit
40cdd5766d
60
src/app.rs
60
src/app.rs
|
@ -5,13 +5,12 @@ use winit::{
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::renderer;
|
use crate::{camera, render, renderer};
|
||||||
|
|
||||||
pub(crate) struct App {
|
pub(crate) struct App {
|
||||||
window: winit::window::Window,
|
window: winit::window::Window,
|
||||||
event_loop: EventLoop<()>,
|
event_loop: EventLoop<()>,
|
||||||
render_ctx: renderer::RenderContext,
|
render_ctx: render::Context,
|
||||||
renderer: renderer::Renderer,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
@ -25,18 +24,58 @@ impl App {
|
||||||
.build(&event_loop)
|
.build(&event_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let render_ctx = renderer::RenderContext::new(&window).await;
|
let render_ctx = render::Context::new(&window).await;
|
||||||
let renderer = renderer::Renderer::new(&render_ctx);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
window,
|
window,
|
||||||
event_loop,
|
event_loop,
|
||||||
render_ctx,
|
render_ctx,
|
||||||
renderer,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(mut self) {
|
pub fn run(self) {
|
||||||
|
let mut camera_controller = camera::CameraController::new(
|
||||||
|
&self.render_ctx,
|
||||||
|
camera::Camera::new(
|
||||||
|
glam::Vec3 {
|
||||||
|
x: 4.01,
|
||||||
|
y: 4.01,
|
||||||
|
z: 20.0,
|
||||||
|
},
|
||||||
|
-90.0_f32.to_radians(),
|
||||||
|
0.0_f32.to_radians(),
|
||||||
|
),
|
||||||
|
camera::Projection::new(
|
||||||
|
self.render_ctx.size.width,
|
||||||
|
self.render_ctx.size.height,
|
||||||
|
90.0_f32.to_radians(),
|
||||||
|
0.01,
|
||||||
|
100.0,
|
||||||
|
),
|
||||||
|
10.0,
|
||||||
|
0.25,
|
||||||
|
);
|
||||||
|
|
||||||
|
let camera_bind_group_layout = render::BindGroupLayoutBuilder::new()
|
||||||
|
.with_label("camera_bind_group_layout")
|
||||||
|
.with_entry(
|
||||||
|
wgpu::ShaderStages::COMPUTE,
|
||||||
|
wgpu::BindingType::Buffer {
|
||||||
|
ty: wgpu::BufferBindingType::Uniform,
|
||||||
|
has_dynamic_offset: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.build(&self.render_ctx);
|
||||||
|
let camera_bind_group = render::BindGroupBuilder::new()
|
||||||
|
.with_label("camera_bind_group")
|
||||||
|
.with_layout(&camera_bind_group_layout)
|
||||||
|
.with_entry(camera_controller.get_buffer().as_entire_binding())
|
||||||
|
.build(&self.render_ctx);
|
||||||
|
|
||||||
|
let renderer = renderer::Renderer::new(&self.render_ctx, &camera_bind_group_layout);
|
||||||
|
|
||||||
let mut last_render_time = Instant::now();
|
let mut last_render_time = Instant::now();
|
||||||
self.event_loop
|
self.event_loop
|
||||||
.run(move |event, _, control_flow| match event {
|
.run(move |event, _, control_flow| match event {
|
||||||
|
@ -46,7 +85,7 @@ impl App {
|
||||||
} if window_id == self.window.id() => match event {
|
} if window_id == self.window.id() => match event {
|
||||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||||
_ => {
|
_ => {
|
||||||
self.renderer.input(&event);
|
camera_controller.process_events(&event);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Event::MainEventsCleared => {
|
Event::MainEventsCleared => {
|
||||||
|
@ -56,8 +95,9 @@ impl App {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let dt = now - last_render_time;
|
let dt = now - last_render_time;
|
||||||
last_render_time = now;
|
last_render_time = now;
|
||||||
self.renderer.update(dt, &self.render_ctx);
|
camera_controller.update(dt);
|
||||||
self.renderer.render(&self.render_ctx);
|
camera_controller.update_buffer(&self.render_ctx);
|
||||||
|
renderer.render(&self.render_ctx, &camera_bind_group);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::time::Duration;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode, WindowEvent};
|
use winit::event::{ElementState, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||||
|
|
||||||
use crate::renderer::RenderContext;
|
use crate::render::Context;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
|
@ -103,7 +103,7 @@ pub(crate) struct CameraController {
|
||||||
|
|
||||||
impl CameraController {
|
impl CameraController {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
context: &RenderContext,
|
context: &Context,
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
projection: Projection,
|
projection: Projection,
|
||||||
move_speed: f32,
|
move_speed: f32,
|
||||||
|
@ -236,7 +236,7 @@ impl CameraController {
|
||||||
// log::info!("Camera Pitch: {:?}", self.camera.pitch);
|
// log::info!("Camera Pitch: {:?}", self.camera.pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_buffer(&mut self, context: &RenderContext) {
|
pub fn update_buffer(&mut self, context: &Context) {
|
||||||
self.uniform.update(
|
self.uniform.update(
|
||||||
self.camera.get_view_matrix(),
|
self.camera.get_view_matrix(),
|
||||||
self.projection.get_matrix(),
|
self.projection.get_matrix(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod app;
|
mod app;
|
||||||
mod camera;
|
mod camera;
|
||||||
|
mod render;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod texture;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
mod bind_group;
|
||||||
|
mod context;
|
||||||
|
mod texture;
|
||||||
|
|
||||||
|
pub use self::{
|
||||||
|
bind_group::{BindGroupBuilder, BindGroupLayoutBuilder},
|
||||||
|
context::Context,
|
||||||
|
texture::{Texture, TextureBuilder},
|
||||||
|
};
|
|
@ -0,0 +1,96 @@
|
||||||
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
|
use super::Context;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct BindGroupLayoutBuilder<'a> {
|
||||||
|
next_binding: u32,
|
||||||
|
entries: Vec<wgpu::BindGroupLayoutEntry>,
|
||||||
|
label: Option<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> BindGroupLayoutBuilder<'a> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_label(mut self, label: &'a str) -> Self {
|
||||||
|
self.label = Some(label);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_entry(
|
||||||
|
mut self,
|
||||||
|
visibility: wgpu::ShaderStages,
|
||||||
|
ty: wgpu::BindingType,
|
||||||
|
count: Option<NonZeroU32>,
|
||||||
|
) -> Self {
|
||||||
|
self.entries.push(wgpu::BindGroupLayoutEntry {
|
||||||
|
binding: self.next_binding,
|
||||||
|
visibility,
|
||||||
|
ty,
|
||||||
|
count,
|
||||||
|
});
|
||||||
|
self.next_binding += 1;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn build(self, context: &Context) -> wgpu::BindGroupLayout {
|
||||||
|
context
|
||||||
|
.device
|
||||||
|
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: self.label,
|
||||||
|
entries: &self.entries,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct BindGroupBuilder<'a> {
|
||||||
|
next_binding: u32,
|
||||||
|
label: Option<&'a str>,
|
||||||
|
entries: Vec<wgpu::BindGroupEntry<'a>>,
|
||||||
|
layout: Option<&'a wgpu::BindGroupLayout>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> BindGroupBuilder<'a> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_label(mut self, label: &'a str) -> Self {
|
||||||
|
self.label = Some(label);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_entry(mut self, resource: wgpu::BindingResource<'a>) -> Self {
|
||||||
|
self.entries.push(wgpu::BindGroupEntry {
|
||||||
|
binding: self.next_binding,
|
||||||
|
resource,
|
||||||
|
});
|
||||||
|
self.next_binding += 1;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_layout(mut self, layout: &'a wgpu::BindGroupLayout) -> Self {
|
||||||
|
self.layout = Some(layout);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn build(self, context: &Context) -> wgpu::BindGroup {
|
||||||
|
context
|
||||||
|
.device
|
||||||
|
.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: self.label,
|
||||||
|
layout: &self.layout.unwrap(),
|
||||||
|
entries: self.entries.as_slice(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
use winit::{dpi::PhysicalSize, window::Window};
|
||||||
|
|
||||||
|
pub struct Context {
|
||||||
|
pub instance: wgpu::Instance,
|
||||||
|
pub size: PhysicalSize<u32>,
|
||||||
|
pub surface: wgpu::Surface,
|
||||||
|
pub surface_config: wgpu::SurfaceConfiguration,
|
||||||
|
pub adapter: wgpu::Adapter,
|
||||||
|
pub device: wgpu::Device,
|
||||||
|
pub queue: wgpu::Queue,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
pub async fn new(window: &Window) -> Self {
|
||||||
|
log::info!("Initialising WGPU context...");
|
||||||
|
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||||
|
backends: wgpu::Backends::VULKAN,
|
||||||
|
dx12_shader_compiler: Default::default(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// To be able to start drawing we need a few things:
|
||||||
|
// - A surface
|
||||||
|
// - A GPU device to draw to the surface
|
||||||
|
// - A draw command queue
|
||||||
|
log::info!("Initialising window surface...");
|
||||||
|
let surface = unsafe { instance.create_surface(&window) }.unwrap();
|
||||||
|
|
||||||
|
log::info!("Requesting GPU adapter...");
|
||||||
|
let adapter = instance
|
||||||
|
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||||
|
power_preference: wgpu::PowerPreference::HighPerformance,
|
||||||
|
force_fallback_adapter: false,
|
||||||
|
compatible_surface: Some(&surface),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
log::info!("Checking GPU adapter meets requirements");
|
||||||
|
log::info!("Requesting GPU device...");
|
||||||
|
let (device, queue) = adapter
|
||||||
|
.request_device(
|
||||||
|
&wgpu::DeviceDescriptor {
|
||||||
|
label: None,
|
||||||
|
features: wgpu::Features::empty(),
|
||||||
|
limits: wgpu::Limits::default(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
log::info!("Configuring window surface...");
|
||||||
|
let size = window.inner_size();
|
||||||
|
let surface_config = surface
|
||||||
|
.get_default_config(&adapter, size.width, size.height)
|
||||||
|
.unwrap();
|
||||||
|
surface.configure(&device, &surface_config);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
instance,
|
||||||
|
size,
|
||||||
|
surface,
|
||||||
|
surface_config,
|
||||||
|
adapter,
|
||||||
|
device,
|
||||||
|
queue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::renderer::RenderContext;
|
|
||||||
|
|
||||||
// TODO: Support mip-mapping and multi-sampling
|
// TODO: Support mip-mapping and multi-sampling
|
||||||
|
|
||||||
|
use super::{BindGroupBuilder, BindGroupLayoutBuilder, Context};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TextureAttributes {
|
pub struct TextureAttributes {
|
||||||
pub size: wgpu::Extent3d,
|
pub size: wgpu::Extent3d,
|
||||||
|
@ -35,7 +35,7 @@ impl Default for TextureAttributes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct TextureBuilder {
|
pub struct TextureBuilder {
|
||||||
pub attributes: TextureAttributes,
|
pub attributes: TextureAttributes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,12 +97,12 @@ impl TextureBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn build(self, context: &RenderContext) -> Texture {
|
pub fn build(self, context: &Context) -> Texture {
|
||||||
Texture::new(context, self.attributes)
|
Texture::new(context, self.attributes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct Texture {
|
pub struct Texture {
|
||||||
pub attributes: TextureAttributes,
|
pub attributes: TextureAttributes,
|
||||||
pub texture: wgpu::Texture,
|
pub texture: wgpu::Texture,
|
||||||
pub view: wgpu::TextureView,
|
pub view: wgpu::TextureView,
|
||||||
|
@ -112,7 +112,7 @@ pub(crate) struct Texture {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Texture {
|
impl Texture {
|
||||||
pub fn new(context: &RenderContext, attributes: TextureAttributes) -> Self {
|
pub fn new(context: &Context, attributes: TextureAttributes) -> Self {
|
||||||
let texture = context.device.create_texture(&wgpu::TextureDescriptor {
|
let texture = context.device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: attributes.size,
|
size: attributes.size,
|
||||||
|
@ -141,46 +141,27 @@ impl Texture {
|
||||||
wgpu::TextureDimension::D3 => wgpu::TextureViewDimension::D3,
|
wgpu::TextureDimension::D3 => wgpu::TextureViewDimension::D3,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bind_group_layout =
|
let bind_group_layout = BindGroupLayoutBuilder::new()
|
||||||
context
|
.with_entry(
|
||||||
.device
|
attributes.shader_visibility,
|
||||||
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
wgpu::BindingType::Texture {
|
||||||
label: None,
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
entries: &[
|
view_dimension,
|
||||||
wgpu::BindGroupLayoutEntry {
|
multisampled: false,
|
||||||
binding: 0,
|
},
|
||||||
visibility: attributes.shader_visibility,
|
None,
|
||||||
ty: wgpu::BindingType::Texture {
|
)
|
||||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
.with_entry(
|
||||||
view_dimension: view_dimension,
|
attributes.shader_visibility,
|
||||||
multisampled: false,
|
wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||||
},
|
None,
|
||||||
count: None,
|
)
|
||||||
},
|
.build(context);
|
||||||
wgpu::BindGroupLayoutEntry {
|
let bind_group = BindGroupBuilder::new()
|
||||||
binding: 1,
|
.with_layout(&bind_group_layout)
|
||||||
visibility: attributes.shader_visibility,
|
.with_entry(wgpu::BindingResource::TextureView(&view))
|
||||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
.with_entry(wgpu::BindingResource::Sampler(&sampler))
|
||||||
count: None,
|
.build(context);
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
let bind_group = context
|
|
||||||
.device
|
|
||||||
.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
||||||
label: None,
|
|
||||||
layout: &bind_group_layout,
|
|
||||||
entries: &[
|
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: wgpu::BindingResource::TextureView(&view),
|
|
||||||
},
|
|
||||||
wgpu::BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: wgpu::BindingResource::Sampler(&sampler),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
attributes,
|
attributes,
|
||||||
|
@ -192,7 +173,7 @@ impl Texture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&self, context: &RenderContext, data: &[u8]) {
|
pub fn update(&self, context: &Context, data: &[u8]) {
|
||||||
log::info!("Updating texture contents...");
|
log::info!("Updating texture contents...");
|
||||||
let copy_texture = wgpu::ImageCopyTexture {
|
let copy_texture = wgpu::ImageCopyTexture {
|
||||||
texture: &self.texture,
|
texture: &self.texture,
|
189
src/renderer.rs
189
src/renderer.rs
|
@ -1,79 +1,4 @@
|
||||||
use std::time::Duration;
|
use crate::render::{BindGroupBuilder, BindGroupLayoutBuilder, Context, Texture, TextureBuilder};
|
||||||
|
|
||||||
use wgpu::util::DeviceExt;
|
|
||||||
use winit::event::WindowEvent;
|
|
||||||
use winit::{dpi::PhysicalSize, window::Window};
|
|
||||||
|
|
||||||
use crate::camera;
|
|
||||||
use crate::texture::{Texture, TextureBuilder};
|
|
||||||
|
|
||||||
pub(crate) struct RenderContext {
|
|
||||||
pub instance: wgpu::Instance,
|
|
||||||
pub size: PhysicalSize<u32>,
|
|
||||||
pub surface: wgpu::Surface,
|
|
||||||
pub surface_config: wgpu::SurfaceConfiguration,
|
|
||||||
pub adapter: wgpu::Adapter,
|
|
||||||
pub device: wgpu::Device,
|
|
||||||
pub queue: wgpu::Queue,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RenderContext {
|
|
||||||
pub async fn new(window: &Window) -> Self {
|
|
||||||
log::info!("Initialising WGPU context...");
|
|
||||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
|
||||||
backends: wgpu::Backends::VULKAN,
|
|
||||||
dx12_shader_compiler: Default::default(),
|
|
||||||
});
|
|
||||||
|
|
||||||
// To be able to start drawing we need a few things:
|
|
||||||
// - A surface
|
|
||||||
// - A GPU device to draw to the surface
|
|
||||||
// - A draw command queue
|
|
||||||
log::info!("Initialising window surface...");
|
|
||||||
let surface = unsafe { instance.create_surface(&window) }.unwrap();
|
|
||||||
|
|
||||||
log::info!("Requesting GPU adapter...");
|
|
||||||
let adapter = instance
|
|
||||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
|
||||||
power_preference: wgpu::PowerPreference::HighPerformance,
|
|
||||||
force_fallback_adapter: false,
|
|
||||||
compatible_surface: Some(&surface),
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
log::info!("Checking GPU adapter meets requirements");
|
|
||||||
log::info!("Requesting GPU device...");
|
|
||||||
let (device, queue) = adapter
|
|
||||||
.request_device(
|
|
||||||
&wgpu::DeviceDescriptor {
|
|
||||||
label: None,
|
|
||||||
features: wgpu::Features::empty(),
|
|
||||||
limits: wgpu::Limits::default(),
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
log::info!("Configuring window surface...");
|
|
||||||
let size = window.inner_size();
|
|
||||||
let surface_config = surface
|
|
||||||
.get_default_config(&adapter, size.width, size.height)
|
|
||||||
.unwrap();
|
|
||||||
surface.configure(&device, &surface_config);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
instance,
|
|
||||||
size,
|
|
||||||
surface,
|
|
||||||
surface_config,
|
|
||||||
adapter,
|
|
||||||
device,
|
|
||||||
queue,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct Renderer {
|
pub(crate) struct Renderer {
|
||||||
clear_color: wgpu::Color,
|
clear_color: wgpu::Color,
|
||||||
|
@ -82,12 +7,10 @@ pub(crate) struct Renderer {
|
||||||
render_pipeline: wgpu::RenderPipeline,
|
render_pipeline: wgpu::RenderPipeline,
|
||||||
render_texture: Texture,
|
render_texture: Texture,
|
||||||
voxel_texture: Texture,
|
voxel_texture: Texture,
|
||||||
camera_controller: camera::CameraController,
|
|
||||||
camera_bind_group: wgpu::BindGroup,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
pub fn new(context: &RenderContext) -> Self {
|
pub fn new(context: &Context, camera_bind_group_layout: &wgpu::BindGroupLayout) -> Self {
|
||||||
log::info!("Creating render shader...");
|
log::info!("Creating render shader...");
|
||||||
let shader_descriptor = wgpu::include_wgsl!("../assets/shaders/shader.wgsl");
|
let shader_descriptor = wgpu::include_wgsl!("../assets/shaders/shader.wgsl");
|
||||||
let shader = context.device.create_shader_module(shader_descriptor);
|
let shader = context.device.create_shader_module(shader_descriptor);
|
||||||
|
@ -140,54 +63,6 @@ impl Renderer {
|
||||||
voxel_texture.update(&context, &data);
|
voxel_texture.update(&context, &data);
|
||||||
|
|
||||||
log::info!("Creating camera...");
|
log::info!("Creating camera...");
|
||||||
let camera_controller = camera::CameraController::new(
|
|
||||||
context,
|
|
||||||
camera::Camera::new(
|
|
||||||
glam::Vec3 {
|
|
||||||
x: 4.01,
|
|
||||||
y: 4.01,
|
|
||||||
z: 20.0,
|
|
||||||
},
|
|
||||||
-90.0_f32.to_radians(),
|
|
||||||
0.0_f32.to_radians(),
|
|
||||||
),
|
|
||||||
camera::Projection::new(
|
|
||||||
context.size.width,
|
|
||||||
context.size.height,
|
|
||||||
90.0_f32.to_radians(),
|
|
||||||
0.01,
|
|
||||||
100.0,
|
|
||||||
),
|
|
||||||
10.0,
|
|
||||||
0.25,
|
|
||||||
);
|
|
||||||
|
|
||||||
let camera_bind_group_layout =
|
|
||||||
context
|
|
||||||
.device
|
|
||||||
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
|
||||||
entries: &[wgpu::BindGroupLayoutEntry {
|
|
||||||
binding: 0,
|
|
||||||
visibility: wgpu::ShaderStages::COMPUTE,
|
|
||||||
ty: wgpu::BindingType::Buffer {
|
|
||||||
ty: wgpu::BufferBindingType::Uniform,
|
|
||||||
has_dynamic_offset: false,
|
|
||||||
min_binding_size: None,
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
}],
|
|
||||||
label: Some("camera_bind_group_layout"),
|
|
||||||
});
|
|
||||||
let camera_bind_group = context
|
|
||||||
.device
|
|
||||||
.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
||||||
layout: &camera_bind_group_layout,
|
|
||||||
entries: &[wgpu::BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: camera_controller.get_buffer().as_entire_binding(),
|
|
||||||
}],
|
|
||||||
label: Some("camera_bind_group"),
|
|
||||||
});
|
|
||||||
|
|
||||||
log::info!("Creating render pipeline...");
|
log::info!("Creating render pipeline...");
|
||||||
let render_pipeline =
|
let render_pipeline =
|
||||||
|
@ -221,32 +96,21 @@ impl Renderer {
|
||||||
log::info!("Creating compute pipeline...");
|
log::info!("Creating compute pipeline...");
|
||||||
let cs_descriptor = wgpu::include_wgsl!("../assets/shaders/voxel_volume.wgsl");
|
let cs_descriptor = wgpu::include_wgsl!("../assets/shaders/voxel_volume.wgsl");
|
||||||
let cs = context.device.create_shader_module(cs_descriptor);
|
let cs = context.device.create_shader_module(cs_descriptor);
|
||||||
let compute_layout =
|
let compute_layout = BindGroupLayoutBuilder::new()
|
||||||
context
|
.with_entry(
|
||||||
.device
|
wgpu::ShaderStages::COMPUTE,
|
||||||
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
wgpu::BindingType::StorageTexture {
|
||||||
label: None,
|
access: wgpu::StorageTextureAccess::WriteOnly,
|
||||||
entries: &[wgpu::BindGroupLayoutEntry {
|
format: render_texture.attributes.format,
|
||||||
binding: 0,
|
view_dimension: wgpu::TextureViewDimension::D2,
|
||||||
visibility: wgpu::ShaderStages::COMPUTE,
|
},
|
||||||
ty: wgpu::BindingType::StorageTexture {
|
None,
|
||||||
access: wgpu::StorageTextureAccess::WriteOnly,
|
)
|
||||||
format: render_texture.attributes.format,
|
.build(context);
|
||||||
view_dimension: wgpu::TextureViewDimension::D2,
|
let compute_bind_group = BindGroupBuilder::new()
|
||||||
},
|
.with_layout(&compute_layout)
|
||||||
count: None,
|
.with_entry(wgpu::BindingResource::TextureView(&render_texture.view))
|
||||||
}],
|
.build(context);
|
||||||
});
|
|
||||||
let compute_bind_group = context
|
|
||||||
.device
|
|
||||||
.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
||||||
label: None,
|
|
||||||
layout: &compute_layout,
|
|
||||||
entries: &[wgpu::BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: wgpu::BindingResource::TextureView(&render_texture.view),
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
let compute_pipeline =
|
let compute_pipeline =
|
||||||
context
|
context
|
||||||
.device
|
.device
|
||||||
|
@ -281,12 +145,10 @@ impl Renderer {
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
render_texture,
|
render_texture,
|
||||||
voxel_texture,
|
voxel_texture,
|
||||||
camera_controller,
|
|
||||||
camera_bind_group,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self, context: &RenderContext) {
|
pub fn render(&self, context: &Context, camera_bind_group: &wgpu::BindGroup) {
|
||||||
let frame = context.surface.get_current_texture().unwrap();
|
let frame = context.surface.get_current_texture().unwrap();
|
||||||
let view = frame
|
let view = frame
|
||||||
.texture
|
.texture
|
||||||
|
@ -301,7 +163,7 @@ impl Renderer {
|
||||||
compute_pass.set_pipeline(&self.compute_pipeline);
|
compute_pass.set_pipeline(&self.compute_pipeline);
|
||||||
compute_pass.set_bind_group(0, &self.compute_bind_group, &[]);
|
compute_pass.set_bind_group(0, &self.compute_bind_group, &[]);
|
||||||
compute_pass.set_bind_group(1, &self.voxel_texture.bind_group, &[]);
|
compute_pass.set_bind_group(1, &self.voxel_texture.bind_group, &[]);
|
||||||
compute_pass.set_bind_group(2, &self.camera_bind_group, &[]);
|
compute_pass.set_bind_group(2, camera_bind_group, &[]);
|
||||||
compute_pass.dispatch_workgroups(size.width / 8, size.height / 8, 1);
|
compute_pass.dispatch_workgroups(size.width / 8, size.height / 8, 1);
|
||||||
drop(compute_pass);
|
drop(compute_pass);
|
||||||
|
|
||||||
|
@ -325,14 +187,13 @@ impl Renderer {
|
||||||
|
|
||||||
context.queue.submit(Some(encoder.finish()));
|
context.queue.submit(Some(encoder.finish()));
|
||||||
frame.present();
|
frame.present();
|
||||||
}
|
|
||||||
|
|
||||||
pub fn input(&mut self, event: &WindowEvent) -> bool {
|
// let mut command_buffers = Vec::with_capacity(encoders.len());
|
||||||
self.camera_controller.process_events(event)
|
// for encoder in encoders {
|
||||||
}
|
// command_buffers.push(encoder.finish());
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn update(&mut self, dt: Duration, render_ctx: &RenderContext) {
|
// context.queue.submit(command_buffers);
|
||||||
self.camera_controller.update(dt);
|
// frame.present();
|
||||||
self.camera_controller.update_buffer(render_ctx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue