Example #1
0
    void VulkanWindow::Render ( const Matrix4x4& aModelMatrix,
                                const Mesh& aMesh,
                                const Pipeline& aPipeline,
                                const Material* aMaterial,
                                const UniformBuffer* aSkeleton,
                                uint32_t aVertexStart,
                                uint32_t aVertexCount,
                                uint32_t aInstanceCount,
                                uint32_t aFirstInstance ) const
    {
        const auto& vulkan_material = reinterpret_cast<const VulkanMaterial&> ( ( aMaterial ) ? *aMaterial : aPipeline.GetDefaultMaterial() );
        const std::vector<VkDescriptorSet>& material_descriptor_sets = vulkan_material.GetDescriptorSets();
        const auto* vk_skeleton = reinterpret_cast<const VulkanUniformBuffer*> ( aSkeleton );
        assert ( material_descriptor_sets.size() < 3 );

        uint32_t descriptor_set_count = 1;
        std::array<VkDescriptorSet, 4> descriptor_sets { { mMatrices.GetDescriptorSet() }};
        if ( vk_skeleton )
        {
            descriptor_sets[descriptor_set_count++] = vk_skeleton->GetDescriptorSet();
        }

        memcpy ( &descriptor_sets[descriptor_set_count], material_descriptor_sets.data(), material_descriptor_sets.size() *sizeof ( VkDescriptorSet ) );
        descriptor_set_count += static_cast<uint32_t> ( material_descriptor_sets.size() );

        vkCmdBindPipeline ( mVulkanRenderer.GetCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, reinterpret_cast<const VulkanPipeline*> ( &aPipeline )->GetPipeline() );

        vkCmdPushConstants ( mVulkanRenderer.GetCommandBuffer(),
                             reinterpret_cast<const VulkanPipeline*> ( &aPipeline )->GetPipelineLayout(),
                             VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
                             0, sizeof ( float ) * 16, aModelMatrix.GetMatrix4x4() );

        vkCmdBindDescriptorSets ( mVulkanRenderer.GetCommandBuffer(),
                                  VK_PIPELINE_BIND_POINT_GRAPHICS,
                                  reinterpret_cast<const VulkanPipeline*> ( &aPipeline )->GetPipelineLayout(),
                                  0,
                                  descriptor_set_count,
                                  descriptor_sets.data(), 0, nullptr );

        {
            const VkDeviceSize offset = 0;
            const VulkanMesh& vulkan_mesh{reinterpret_cast<const VulkanMesh&> ( aMesh ) };
            vkCmdBindVertexBuffers ( mVulkanRenderer.GetCommandBuffer(), 0, 1, &vulkan_mesh.GetBuffer(), &offset );
            if ( aMesh.GetIndexCount() )
            {
                vkCmdBindIndexBuffer ( mVulkanRenderer.GetCommandBuffer(),
                                       vulkan_mesh.GetBuffer(), ( sizeof ( Vertex ) * aMesh.GetVertexCount() ),
                                       vulkan_mesh.GetIndexType() );
                vkCmdDrawIndexed (
                    mVulkanRenderer.GetCommandBuffer(),
                    ( aVertexCount != 0xffffffff ) ? aVertexCount : aMesh.GetIndexCount(),
                    aInstanceCount,
                    aVertexStart,
                    0,
                    aFirstInstance );
            }
            else
            {
                vkCmdDraw (
                    mVulkanRenderer.GetCommandBuffer(),
                    ( aVertexCount != 0xffffffff ) ? aVertexCount : aMesh.GetVertexCount(),
                    aInstanceCount,
                    aVertexStart,
                    aFirstInstance );
            }
        }
    }