despero 0.1.0

Rusty game engine, using API Vulkan and implementing paradigm of ECS
Documentation
use std::sync::{Arc, Mutex};
use ash::vk;
use rapier3d::prelude::*;
use gpu_allocator::*;
use gpu_allocator::vulkan::*;

use crate::error::DesperoResult;
use crate::render::{
    backend::{
        pipeline::*,
        buffer::*,
        shader::*,
        swapchain::*,
        descriptor_pool::*,
    },
    renderer::Renderer,
};

pub const DEBUG_TOPOLOGY: vk::PrimitiveTopology = vk::PrimitiveTopology::LINE_LIST;

pub struct DebugRenderer {
    pub pipeline: Pipeline,
    pub vertexbuffer: Buffer,
    pub instancebuffer: Buffer,
}

impl DebugRenderer {
    pub fn new(
        logical_device: &ash::Device,
        swapchain: &Swapchain,
        descriptor_pool: &DescriptorPool,
        renderpass: &vk::RenderPass,
        allocator: &mut gpu_allocator::vulkan::Allocator,
    ) -> DesperoResult<Self> {
        let vertex_shader = vk::ShaderModuleCreateInfo::builder()
            .code(vk_shader_macros::include_glsl!(
                "./src/shaders/vertex_debug.glsl", 
                kind: vert,
            ));
        
        let fragment_shader = vk::ShaderModuleCreateInfo::builder()
            .code(vk_shader_macros::include_glsl!(
                "./src/shaders/fragment_debug.glsl",
                kind: frag,
            ));
            
        let vertex_attributes = vec![
            ShaderInputAttribute{
                binding: 0,
                location: 0,
                offset: 0,
                format: ShaderInputFormat::R32G32B32_SFLOAT,
            },
            ShaderInputAttribute{
                binding: 1,
                location: 1,
                offset: 0,
                format: ShaderInputFormat::R32G32B32A32_SFLOAT,
            }
        ]; 
        
        let pipeline = unsafe {Pipeline::init_internal(
            &logical_device,
            &swapchain,
            &descriptor_pool,
            *renderpass,
            &*vertex_shader,
            &*fragment_shader,
            vertex_attributes.clone(),
            12,
            16,
            DEBUG_TOPOLOGY,
        )?};
        
        let pipeline = Pipeline {
            pipeline,
            vertex_shader: *vertex_shader,
            fragment_shader: *fragment_shader,
            vertex_attributes,
            vertex_bytes: 12,
            instance_bytes: 16,
            topology: DEBUG_TOPOLOGY,
        };
        
        let vertexbuffer = Buffer::new(
            &logical_device,
            allocator,
            24,
            vk::BufferUsageFlags::VERTEX_BUFFER,
            MemoryLocation::CpuToGpu,
            "Debug renderer vertex buffer"
        )?;
        
        let instancebuffer = Buffer::new(
            &logical_device,
            allocator,
            16,
            vk::BufferUsageFlags::VERTEX_BUFFER,
            MemoryLocation::CpuToGpu,
            "Debug renderer instance buffer"
        )?;
        
        Ok(DebugRenderer {
            pipeline,
            vertexbuffer,
            instancebuffer,
        })
    }
    
    pub fn cleanup(
        &mut self,
        logical_device: &ash::Device,
        allocator: &Arc<Mutex<Allocator>>,
    ){
        let mut alloc: Option<Allocation> = None;
        std::mem::swap(&mut alloc, &mut self.vertexbuffer.allocation);
        (*allocator.lock().unwrap()).free(alloc.unwrap()).unwrap();
        
        let mut alloc: Option<Allocation> = None;
        std::mem::swap(&mut alloc, &mut self.instancebuffer.allocation);
        (*allocator.lock().unwrap()).free(alloc.unwrap()).unwrap();
        
        unsafe { logical_device.destroy_buffer(self.vertexbuffer.buffer, None) };
        unsafe { logical_device.destroy_buffer(self.instancebuffer.buffer, None) };
        
        self.pipeline.cleanup(&logical_device);
    }
}

impl DebugRenderBackend for Renderer {
    fn draw_line(
        &mut self,
        _object: DebugRenderObject<'_>,
        a: Point<f32>,
        b: Point<f32>,
        color: [f32; 4]
    ){        
        let vertexdata: [[f32; 3]; 2] = [a.into(), b.into()];
        
        self.debug_renderer.vertexbuffer.fill(
            &self.device,
            &mut *self.allocator.lock().unwrap(),
            &vertexdata,
        ).expect("Cannot fill debug renderer vertex buffer");
        
        self.debug_renderer.instancebuffer.fill(
            &self.device,
            &mut *self.allocator.lock().unwrap(),
            &color,
        ).expect("Cannot fill debug renderer instance buffer");
        
        unsafe {
            self.device.cmd_bind_pipeline(
                self.commandbuffer_pools.current_commandbuffer.unwrap(),
                vk::PipelineBindPoint::GRAPHICS,
                self.debug_renderer.pipeline.pipeline,
            );
            
            self.device.cmd_bind_vertex_buffers(
                self.commandbuffer_pools.current_commandbuffer.unwrap(),
                0,
                &[self.debug_renderer.vertexbuffer.buffer],
                &[0],
            );
            
            self.device.cmd_bind_vertex_buffers(
                self.commandbuffer_pools.current_commandbuffer.unwrap(),
                1,
                &[self.debug_renderer.instancebuffer.buffer],
                &[0],
            );
            
            self.device.cmd_draw(
                self.commandbuffer_pools.current_commandbuffer.unwrap(),
                2,
                1,
                0,
                0,
            );
        }
    }
}