Create RenderContext and Renderer structs
This commit is contained in:
parent
1b0e1f4bce
commit
6a9335089b
|
@ -0,0 +1,150 @@
|
||||||
|
use winit::{dpi::PhysicalSize, window::Window};
|
||||||
|
|
||||||
|
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 {
|
||||||
|
clear_color: wgpu::Color,
|
||||||
|
render_pipeline: wgpu::RenderPipeline,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Renderer {
|
||||||
|
pub fn new(context: &RenderContext) -> Self {
|
||||||
|
log::info!("Creating render shader...");
|
||||||
|
let shader_descriptor = wgpu::include_wgsl!("../assets/shaders/shader.wgsl");
|
||||||
|
let shader = context.device.create_shader_module(shader_descriptor);
|
||||||
|
|
||||||
|
log::info!("Creating render pipeline...");
|
||||||
|
let render_pipeline =
|
||||||
|
context
|
||||||
|
.device
|
||||||
|
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: Some(&context.device.create_pipeline_layout(
|
||||||
|
&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("draw"),
|
||||||
|
bind_group_layouts: &[],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: "vertex",
|
||||||
|
buffers: &[],
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: "fragment",
|
||||||
|
targets: &[Some(context.surface_config.format.into())],
|
||||||
|
}),
|
||||||
|
primitive: wgpu::PrimitiveState::default(),
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: wgpu::MultisampleState::default(),
|
||||||
|
multiview: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let clear_color = wgpu::Color {
|
||||||
|
r: 255.0 / 255.0,
|
||||||
|
g: 216.0 / 255.0,
|
||||||
|
b: 102.0 / 255.0,
|
||||||
|
a: 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
clear_color,
|
||||||
|
render_pipeline,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render(&mut self, context: &RenderContext) {
|
||||||
|
let frame = context.surface.get_current_texture().unwrap();
|
||||||
|
let view = frame
|
||||||
|
.texture
|
||||||
|
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
|
||||||
|
let mut encoder = context
|
||||||
|
.device
|
||||||
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor::default());
|
||||||
|
|
||||||
|
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: Some("Render Pass"),
|
||||||
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
|
view: &view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(self.clear_color),
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
context.queue.submit(Some(encoder.finish()));
|
||||||
|
frame.present();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue