1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
use crate::wgpuctx::WgpuCtx;
pub struct RenderPipelineBuilder<'a>
{
bind_groups: Vec<&'a wgpu::BindGroupLayout>,
shader: &'a wgpu::ShaderModule,
vertex_entry_point: Option<&'static str>,
fragment_entry_point: Option<&'static str>,
vertex_comp_options: Option<wgpu::PipelineCompilationOptions<'a>>,
fragment_comp_options: Option<wgpu::PipelineCompilationOptions<'a>>,
vertex_buffer_layouts: Vec<wgpu::VertexBufferLayout<'a>>
}
impl<'a> RenderPipelineBuilder<'a>
{
pub fn new(
shader: &'a wgpu::ShaderModule)
-> Self {
Self {
bind_groups: Vec::new(),
shader: shader,
vertex_entry_point: Some("vs_main"),
fragment_entry_point: Some("fs_main"),
vertex_comp_options: None,
fragment_comp_options: None,
vertex_buffer_layouts: Vec::new()
}
}
pub fn add_bindgroup(
mut self,
bindgroup: &'a wgpu::BindGroupLayout)
-> Self {
self.bind_groups.push(bindgroup);
self
}
pub fn add_vertex_layout(
mut self,
layout: wgpu::VertexBufferLayout<'a>)
-> Self {
self.vertex_buffer_layouts.push(layout);
self
}
pub fn build(
self,
label: Option<&'static str>,
wgpuctx: &WgpuCtx)
-> wgpu::RenderPipeline
{
let layout_descr = wgpu::PipelineLayoutDescriptor {
label: label,
bind_group_layouts: self.bind_groups.as_slice(),
push_constant_ranges: &[]
};
let layout = wgpuctx.create_pipeline_layout(&layout_descr);
wgpuctx.create_render_pipeline(
&wgpu::RenderPipelineDescriptor {
label: label,
layout: Some(&layout),
vertex: wgpu::VertexState {
module: self.shader,
entry_point: self.vertex_entry_point,
compilation_options: match self.vertex_comp_options {
Some(option) => option,
None => wgpu::PipelineCompilationOptions::default()
},
buffers: self.vertex_buffer_layouts.as_slice()
},
fragment: Some(wgpu::FragmentState {
module: self.shader,
entry_point: self.fragment_entry_point,
compilation_options: match self.fragment_comp_options {
Some(option) => option,
None => wgpu::PipelineCompilationOptions::default()
},
targets: &[Some(wgpu::ColorTargetState {
format: wgpuctx.surface_config().format,
blend: Some(wgpu::BlendState{
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::SrcAlpha,
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
operation: wgpu::BlendOperation::Add
},
alpha: wgpu::BlendComponent::OVER
}),
write_mask: wgpu::ColorWrites::ALL
})],
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
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,
cache: None
}
)
}
}
|