Created
March 25, 2019 15:32
-
-
Save StarArawn/8c08830877a3afd5d3a39f1fa6d5430a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
impl<B> SimpleGraphicsPipelineDesc<B, Game<B>> for SpriteBatchPassDesc | |
where B: gfx_hal::Backend, | |
{ | |
type Pipeline = SpriteBatchPass<B>; | |
fn depth_stencil(&self) -> Option<gfx_hal::pso::DepthStencilDesc> { | |
None | |
} | |
fn vertices(&self) -> Vec<( | |
Vec<gfx_hal::pso::Element<gfx_hal::format::Format>>, | |
gfx_hal::pso::ElemStride, | |
gfx_hal::pso::InstanceRate, | |
)> { | |
vec![SpriteVertex::VERTEX.gfx_vertex_input_desc(0)] | |
} | |
fn load_shader_set<'a>( | |
&self, | |
storage: &'a mut Vec<B::ShaderModule>, | |
factory: &mut Factory<B>, | |
aux: &Game<B>, | |
) -> gfx_hal::pso::GraphicsShaderSet<'a, B> { | |
let sprite_shader = aux.asset_manager.get_shader(&String::from("sprite.shader")); | |
storage.clear(); | |
storage.push(sprite_shader.vertex.module(factory).unwrap()); | |
storage.push(sprite_shader.fragment.module(factory).unwrap()); | |
gfx_hal::pso::GraphicsShaderSet { | |
vertex: gfx_hal::pso::EntryPoint { | |
entry: "main", | |
module: &storage[0], | |
specialization: gfx_hal::pso::Specialization::default(), | |
}, | |
fragment: Some(gfx_hal::pso::EntryPoint { | |
entry: "main", | |
module: &storage[1], | |
specialization: gfx_hal::pso::Specialization::default(), | |
}), | |
hull: None, | |
domain: None, | |
geometry: None, | |
} | |
} | |
fn layout(&self) -> Layout { | |
Layout { | |
sets: vec![SetLayout { | |
bindings: vec![ | |
gfx_hal::pso::DescriptorSetLayoutBinding { | |
binding: 0, | |
ty: gfx_hal::pso::DescriptorType::SampledImage, | |
count: 128, | |
stage_flags: gfx_hal::pso::ShaderStageFlags::FRAGMENT, | |
immutable_samplers: false, | |
}, | |
gfx_hal::pso::DescriptorSetLayoutBinding { | |
binding: 1, | |
ty: gfx_hal::pso::DescriptorType::Sampler, | |
count: 1, | |
stage_flags: gfx_hal::pso::ShaderStageFlags::FRAGMENT, | |
immutable_samplers: false, | |
}, | |
gfx_hal::pso::DescriptorSetLayoutBinding { | |
binding: 2, | |
ty: gfx_hal::pso::DescriptorType::UniformBuffer, | |
count: 1, | |
stage_flags: gfx_hal::pso::ShaderStageFlags::VERTEX, | |
immutable_samplers: false, | |
} | |
] | |
}], | |
push_constants: Vec::new(), | |
} | |
} | |
fn build<'a>( | |
self, | |
_rendy_graph: &mut rendy::graph::GraphContext<B>, | |
factory: &mut Factory<B>, | |
_queue: QueueId, | |
_game: &Game<B>, | |
buffers: Vec<NodeBuffer>, | |
images: Vec<NodeImage>, | |
set_layouts: &[rendy::resource::set::DescriptorSetLayout<B>] | |
) -> Result<SpriteBatchPass<B>, failure::Error> { | |
assert!(buffers.is_empty()); | |
assert!(images.is_empty()); | |
assert!(!set_layouts.is_empty()); | |
let vertex = factory.create_buffer(512, SpriteVertex::VERTEX.stride as u64 * MAX_VERTICES, (gfx_hal::buffer::Usage::VERTEX, MemoryUsageValue::Dynamic)) | |
.unwrap(); | |
Ok(SpriteBatchPass { | |
vertex, | |
sets: vec![None, None, None, None, None] | |
}) | |
} | |
} | |
impl<B> SimpleGraphicsPipeline<B, Game<B>> for SpriteBatchPass<B> | |
where | |
B: gfx_hal::Backend | |
{ | |
type Desc = SpriteBatchPassDesc; | |
fn prepare( | |
&mut self, | |
factory: &Factory<B>, | |
_queue: QueueId, | |
sets: &[rendy::resource::set::DescriptorSetLayout<B>], | |
index: usize, | |
game: &Game<B> | |
) -> PrepareResult { | |
let sprite_batch = &game.graphics.as_ref().unwrap().sprite_batch; | |
if sprite_batch.vertices.is_empty() { | |
return PrepareResult::DrawReuse; | |
} | |
let mut uniform_buffer = factory.create_buffer(0, std::mem::size_of::<UniformBuffer>() as u64, (gfx_hal::buffer::Usage::INDIRECT, MemoryUsageValue::Dynamic)) | |
.unwrap(); | |
unsafe { | |
let uniform = UniformBuffer { | |
proj: (game.current_scene.camera.view * game.current_scene.camera.projection).into() | |
}; | |
factory.upload_visible_buffer(&mut uniform_buffer, 0, &[uniform]).unwrap(); | |
} | |
unsafe { | |
factory.upload_visible_buffer(&mut self.vertex, 0, &sprite_batch.vertices).unwrap(); | |
} | |
let sprite_batch: &SpriteBatch = &game.graphics.as_ref().unwrap().sprite_batch; | |
let texture: &crate::texture::Texture2D<B> = game.asset_manager.get_texture(&sprite_batch.textures.first().unwrap()); | |
let textures = sprite_batch.textures.iter().map(|texture_name| { | |
let texture = game.asset_manager.get_texture(&texture_name); | |
gfx_hal::pso::Descriptor::Image(texture.internal.image_view.raw(), gfx_hal::image::Layout::ShaderReadOnlyOptimal) | |
}).collect(); | |
if self.sets[index].is_none() { | |
let descriptor_set = factory.create_descriptor_set(&sets[0]).unwrap(); | |
self.sets[index] = Some(descriptor_set); | |
println!("Addding new frame: {}", index); | |
} | |
let current_set = self.sets[index].as_ref().unwrap(); | |
unsafe { | |
gfx_hal::Device::write_descriptor_sets( | |
factory.device(), | |
vec![ | |
gfx_hal::pso::DescriptorSetWrite { | |
set: current_set.raw(), | |
binding: 0, | |
array_offset: 0, | |
descriptors: textures, | |
}, | |
gfx_hal::pso::DescriptorSetWrite { | |
set: current_set.raw(), | |
binding: 1, | |
array_offset: 0, | |
descriptors: vec!(gfx_hal::pso::Descriptor::Sampler(texture.internal.sampler.raw())), | |
}, | |
gfx_hal::pso::DescriptorSetWrite { | |
set: current_set.raw(), | |
binding: 2, | |
array_offset: 0, | |
descriptors: vec!(gfx_hal::pso::Descriptor::Buffer(uniform_buffer.raw(), None..None)), | |
} | |
], | |
); | |
} | |
PrepareResult::DrawRecord | |
} | |
fn draw( | |
&mut self, | |
layout: &B::PipelineLayout, | |
mut encoder: RenderPassEncoder<'_, B>, | |
index: usize, | |
game: &Game<B>, | |
) { | |
let current_set = self.sets[index].as_ref().unwrap(); | |
let sprite_batch = &game.graphics.as_ref().unwrap().sprite_batch; | |
if sprite_batch.vertices.is_empty() { | |
return; | |
} | |
encoder.bind_graphics_descriptor_sets( | |
layout, | |
0, | |
std::iter::once(current_set.raw()), | |
std::iter::empty::<u32>(), | |
); | |
encoder.bind_vertex_buffers(0, Some((self.vertex.raw(), 0))); | |
encoder.draw(0..sprite_batch.vertices.len() as u32, 0..1); | |
} | |
fn dispose(self, _factory: &mut Factory<B>, _aux: &Game<B>) { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment