This commit is contained in:
2021-08-15 22:34:29 +02:00
parent c619f945a3
commit 40aa7f635e
11 changed files with 273 additions and 56 deletions

View File

@@ -1,6 +1,6 @@
use std::{convert::TryInto, io::{self, ErrorKind, Read, Write}, path::PathBuf, sync::Arc};
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::shader::ShaderModule};
use vulkano::{command_buffer::AutoCommandBufferBuilder, descriptor::{descriptor::ShaderStages, descriptor_set::PersistentDescriptorSet}, pipeline::shader::{ShaderModule}};
use vulkano::command_buffer::DynamicState;
use vulkano::device::Device;
use vulkano::framebuffer::RenderPassAbstract;
@@ -9,7 +9,7 @@ use vulkano::pipeline::GraphicsPipeline;
use vulkano::pipeline::GraphicsPipelineAbstract;
use vulkano::pipeline::shader::GraphicsShaderType;
use crate::GameObject;
use crate::{GameObject, vulkan::TextVertex};
use crate::vulkan::{LinePoint, Vertex};
use crate::vulkan::GameData;
use crate::VulkanRenderer;
@@ -18,7 +18,7 @@ type RP = Arc<dyn RenderPassAbstract + Send + Sync>;
type GP = Arc<dyn GraphicsPipelineAbstract + Send + Sync>;
pub trait Drawcall {
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState);
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState);
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer);
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP);
fn get_pipeline(self: &Self) -> &GP;
@@ -136,12 +136,14 @@ impl DefaultShader {
}
impl Drawcall for DefaultShader {
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) {
for i in 0..game_data.game_objects.len() {
let game_object = &game_data.game_objects[i];
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
for i in 0..game_objects.len() {
let game_object = &game_objects[i];
let mesh = &game_data.meshes[game_object.mesh_index];
let push_constants = game_object.get_push_constants();
println!("default: {:?}", game_object.mesh_index);
builder.draw_indexed(
self.pipeline.clone(),
dynamic_state,
@@ -230,7 +232,7 @@ impl LineShader {
}
impl Drawcall for LineShader {
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, _fb_index: usize, game_data: &GameData, dynamic_state: &DynamicState) {
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, _fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
builder.draw(self.pipeline.clone(),
&dynamic_state,
vec![self.vertex_buffer.clone()],
@@ -246,6 +248,124 @@ impl Drawcall for LineShader {
self.pipeline = Self::create_pipeline(device, render_pass);
}
fn get_pipeline(self: &Self) -> &GP {
&self.pipeline
}
}
pub mod vs_text {
vulkano_shaders::shader!{
ty: "vertex",
path: "shaders/text.vert"
}
}
pub mod fs_text {
vulkano_shaders::shader!{
ty: "fragment",
path: "shaders/text.frag"
}
}
pub struct TextShader {
pipeline: GP,
}
impl TextShader {
pub fn new(device: Arc<Device>, render_pass: RP) -> Self {
TextShader {
pipeline: Self::create_pipeline(device, render_pass)
}
}
fn create_pipeline(device: Arc<Device>, render_pass: RP) -> GP {
let sub_pass = Subpass::from(render_pass.clone(), 0).unwrap();
#[cfg(debug_assertions)]
{
println!("Compiling shaders...");
compile_shaders().unwrap();
}
unsafe {
static ENTRY_NAME: [u8; 5usize] = [109u8, 97u8, 105u8, 110u8, 0];
let entry_name_c = std::ffi::CStr::from_ptr(ENTRY_NAME.as_ptr() as *const _);
let fs_module = shader_module_from_file(device.clone(), "shaders/text.frag.spv");
let fs_layout = fs::Layout(ShaderStages {
fragment: true,
..ShaderStages::none()
});
let fs_entry = fs_module.graphics_entry_point(entry_name_c, fs_text::MainInput, fs_text::MainOutput, fs_layout, GraphicsShaderType::Fragment);
let vs_module = shader_module_from_file(device.clone(), "shaders/text.vert.spv");
let vs_layout = vs::Layout(ShaderStages {
vertex: true,
..ShaderStages::none()
});
let vs_entry = vs_module.graphics_entry_point(entry_name_c, vs_text::MainInput, vs_text::MainOutput, vs_layout, GraphicsShaderType::Vertex);
let gp = Arc::new(GraphicsPipeline::start()
.vertex_input_single_buffer::<TextVertex>()
.vertex_shader(vs_entry, ())
.triangle_list()
.viewports_dynamic_scissors_irrelevant(1)
.depth_stencil_simple_depth()
.fragment_shader(fs_entry, ())
.blend_alpha_blending()
.cull_mode_back()
.render_pass(sub_pass.clone())
.build(device.clone())
.unwrap());
println!("layout: {:?}", vulkano::descriptor::PipelineLayoutAbstract::descriptor_set_layout(&gp, 0).unwrap().descriptors_count());
gp
}
}
}
impl Drawcall for TextShader {
fn draw(self: &Self, builder: &mut AutoCommandBufferBuilder, fb_index: usize, game_objects: Vec<&GameObject>, game_data: &GameData, dynamic_state: &DynamicState) {
for i in 0..game_objects.len() {
let game_object = &game_objects[i];
let mesh = &game_data.meshes[game_object.mesh_index];
let push_constants = game_object.get_push_constants();
println!("text: {:?}", game_object.mesh_index);
builder.draw_indexed(
self.pipeline.clone(),
dynamic_state,
vec![mesh.vertex_buffer.clone()],
mesh.index_buffer.clone(),
game_object.descriptor_sets[fb_index].clone(),
push_constants).unwrap();
}
}
fn create_descriptor_set(self: &Self, game_object: &mut GameObject, renderer: &VulkanRenderer) {
let descriptor_set_layout = self.get_pipeline().descriptor_set_layout(0).unwrap().clone();
game_object.descriptor_sets = renderer.uniform_buffers.iter().map(|uniform_buffer| {
let descriptor_set: Arc<(dyn vulkano::descriptor::DescriptorSet + std::marker::Send + std::marker::Sync + 'static)>;
let builder = PersistentDescriptorSet::start(descriptor_set_layout.clone());
let diffuse = &renderer.game_data.textures[game_object.texture_index];
descriptor_set = Arc::new(builder
.add_buffer(uniform_buffer.clone()).unwrap()
.add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap()
.add_sampled_image(diffuse.image.clone(), diffuse.sampler.clone()).unwrap()
.build().unwrap());
descriptor_set
}).collect();
}
fn recreate_pipeline(self: &mut Self, device: Arc<Device>, render_pass: RP) {
self.pipeline = Self::create_pipeline(device, render_pass);
}
fn get_pipeline(self: &Self) -> &GP {
&self.pipeline
}