use crate::*;
impl PolygonInstance {
#[inline(always)]
pub fn clone_instance(&self) -> PolygonInstance {
PolygonInstance {
polygon: self.polygon.clone(),
state: self.state.clone(),
shaders: self.shaders.clone(),
id: RenderId::generate(),
}
}
#[inline(always)]
pub const fn instance_state(&self) -> &PolygonState { &self.state }
#[inline(always)]
pub fn instance_state_mut(&mut self) -> &mut PolygonState { &mut self.state }
#[inline(always)]
pub fn swap_vertex(&mut self, other: &mut PolygonInstance) {
std::mem::swap(&mut self.polygon, &mut other.polygon);
}
#[inline(always)]
fn non_textured_bdl(&self, device: &Device) -> BindGroupLayout {
let entries = [
PolygonState::matrix_bgl_entry(),
PolygonState::material_bgl_entry(),
];
bind_group_util::create_bind_group_layout(device, &entries)
}
#[inline(always)]
fn textured_bdl(&self, device: &Device) -> BindGroupLayout {
bind_group_util::create_bind_group_layout(
device,
&[
PolygonState::matrix_bgl_entry(),
PolygonState::material_bgl_entry(),
PolygonState::textureview_bgl_entry(),
PolygonState::sampler_bgl_entry(),
],
)
}
#[inline(always)]
fn non_textured_bg(&self, device: &Device, layout: &BindGroupLayout) -> BindGroup {
bind_group_util::create_bind_group(
device,
layout,
vec![
self.state.matrix_buffer(device).binding_resource(),
self.state.material.buffer(device).binding_resource(),
],
)
}
#[inline(always)]
fn textured_bg(&self, device: &Device, layout: &BindGroupLayout) -> BindGroup {
let (view, sampler) = self.state.textureview_and_sampler(device);
bind_group_util::create_bind_group(
device,
layout,
vec![
self.state.matrix_buffer(device).binding_resource(),
self.state.material.buffer(device).binding_resource(),
BindingResource::TextureView(&view),
BindingResource::Sampler(&sampler),
],
)
}
}
impl Rendered for PolygonInstance {
impl_render_id!(id);
#[inline(always)]
fn vertex_buffer(&self, _: &DeviceHandler) -> (Arc<BufferHandler>, Option<Arc<BufferHandler>>) {
let polygon = self.polygon.clone();
(polygon.0, Some(polygon.1))
}
#[inline(always)]
fn bind_group_layout(&self, device_handler: &DeviceHandler) -> Arc<BindGroupLayout> {
Arc::new(match self.state.texture.is_some() {
true => self.textured_bdl(device_handler.device()),
false => self.non_textured_bdl(device_handler.device()),
})
}
#[inline(always)]
fn bind_group(
&self,
device_handler: &DeviceHandler,
layout: &BindGroupLayout,
) -> Arc<BindGroup> {
Arc::new(match self.state.texture.is_some() {
true => self.textured_bg(device_handler.device(), layout),
false => self.non_textured_bg(device_handler.device(), layout),
})
}
#[inline(always)]
fn pipeline(
&self,
device_handler: &DeviceHandler,
layout: &PipelineLayout,
scene_desc: &SceneDescriptor,
) -> Arc<RenderPipeline> {
let device = device_handler.device();
let (fragment_module, fragment_entry) = match self.state.texture.is_some() {
true => (
&self.shaders.tex_fragment_module,
self.shaders.tex_fragment_entry,
),
false => (&self.shaders.fragment_module, self.shaders.fragment_entry),
};
let cull_mode = match self.state.backface_culling {
true => Some(Face::Back),
false => None,
};
let blend = match self.state.material.alpha_blend {
true => Some(BlendState::ALPHA_BLENDING),
false => Some(BlendState::REPLACE),
};
let depth_stencil = match scene_desc.backend_buffer.depth_test {
true => Some(DepthStencilState {
format: TextureFormat::Depth32Float,
depth_write_enabled: Some(true),
depth_compare: Some(CompareFunction::Less),
stencil: Default::default(),
bias: Default::default(),
}),
false => None,
};
let sample_count = scene_desc.backend_buffer.sample_count;
let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
layout: Some(layout),
vertex: VertexState {
module: &self.shaders.vertex_module,
entry_point: Some(self.shaders.vertex_entry),
buffers: &[VertexBufferLayout {
array_stride: size_of::<AttrVertex>() as BufferAddress,
step_mode: VertexStepMode::Vertex,
attributes: &[
VertexAttribute {
format: VertexFormat::Float32x3,
offset: 0,
shader_location: 0,
},
VertexAttribute {
format: VertexFormat::Float32x2,
offset: 3 * 4,
shader_location: 1,
},
VertexAttribute {
format: VertexFormat::Float32x3,
offset: 2 * 4 + 3 * 4,
shader_location: 2,
},
],
}],
compilation_options: Default::default(),
},
fragment: Some(FragmentState {
module: fragment_module,
entry_point: Some(fragment_entry),
targets: &[Some(ColorTargetState {
format: scene_desc.render_texture.format,
blend,
write_mask: ColorWrites::ALL,
})],
compilation_options: Default::default(),
}),
primitive: PrimitiveState {
topology: PrimitiveTopology::TriangleList,
front_face: FrontFace::Ccw,
cull_mode,
polygon_mode: PolygonMode::Fill,
..Default::default()
},
depth_stencil,
multisample: MultisampleState {
count: sample_count,
mask: !0,
alpha_to_coverage_enabled: sample_count > 1,
},
label: None,
multiview_mask: None,
cache: None,
});
Arc::new(pipeline)
}
}