use crate::engine_handle::{Engine, WgpuClump};
use crate::resource::{ResourceId, ResourceManager};
use crate::shader::Shader;
use crate::vectors::Vec2;
use crate::Game;
pub(crate) fn make_pipeline(
device: &wgpu::Device,
topology: wgpu::PrimitiveTopology,
bind_group_layouts: &[&wgpu::BindGroupLayout],
vertex_buffers: &[wgpu::VertexBufferLayout],
shader: &wgpu::ShaderModule,
texture_format: wgpu::TextureFormat,
label: Option<&str>,
) -> wgpu::RenderPipeline {
let layout_label = label.map(|label| format!("{}_layout", label));
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: layout_label.as_deref(), bind_group_layouts,
push_constant_ranges: &[],
});
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label,
layout: Some(&layout),
vertex: wgpu::VertexState {
module: shader,
entry_point: "vs_main", buffers: vertex_buffers, },
fragment: Some(wgpu::FragmentState {
module: shader,
entry_point: "fs_main",
targets: &[Some(wgpu::ColorTargetState {
format: texture_format,
blend: Some(wgpu::BlendState::ALPHA_BLENDING), write_mask: wgpu::ColorWrites::ALL, })],
}),
primitive: wgpu::PrimitiveState {
topology,
strip_index_format: None,
front_face: wgpu::FrontFace::Cw, cull_mode: Some(wgpu::Face::Back), polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false,
conservative: false,
},
depth_stencil: None,
multisample: wgpu::MultisampleState {
count: 1, mask: !0, alpha_to_coverage_enabled: false, },
multiview: None,
})
}
pub struct RenderInformation<'pass, 'others> {
pub(crate) size: Vec2<u32>,
pub(crate) render_pass: wgpu::RenderPass<'pass>,
pub(crate) resources: &'others ResourceManager,
pub(crate) defualt_id: ResourceId<Shader>,
pub(crate) camera_bindgroup: &'others wgpu::BindGroup,
pub(crate) wgpu: &'others WgpuClump,
}
pub(crate) fn render<T>(game: &mut T, engine: &mut Engine) -> Result<(), wgpu::SurfaceError>
where
T: Game,
{
if engine.is_loading() {
return Ok(());
}
let wgpu = engine.get_wgpu();
let output = engine.get_current_texture()?;
let view = output
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let mut encoder = wgpu
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Render Encoder"),
});
let mut render_pass = 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(engine.wgpu_colour()),
store: wgpu::StoreOp::Store,
},
})],
timestamp_writes: None,
occlusion_query_set: None,
depth_stencil_attachment: None,
});
render_pass.set_bind_group(1, engine.camera_bindgroup(), &[]);
let render_info = RenderInformation {
size: engine.get_window_size(),
render_pass,
resources: engine.get_resources(),
defualt_id: engine.defualt_pipe_id(),
camera_bindgroup: engine.camera_bindgroup(),
wgpu,
};
game.render(render_info);
wgpu.queue.submit(std::iter::once(encoder.finish()));
output.present();
Ok(())
}