Move vertex input description out of VulkanShader

This commit is contained in:
2021-01-15 16:38:07 +01:00
parent eec33c30dc
commit e737a3ce95
4 changed files with 65 additions and 10 deletions

View File

@@ -52,6 +52,7 @@ public:
cam.SetMatrix(Utils::translate(Matrix4f(1), Vector3f_SIMD(0,0,-10)));
shader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/basic");
shader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/basic");
shader.AddVertexInputDescription(openVulkanoCpp::Vertex::GetVertexInputDescription());
drawablesPool.resize(GEOS);
for(int i = 0; i < GEOS; i++)
{

View File

@@ -8,6 +8,7 @@
#include "Base/ICloseable.hpp"
#include "Base/Utils.hpp"
#include "VertexInputDescription.hpp"
#include <string>
#include <stdexcept>
@@ -119,6 +120,7 @@ namespace openVulkanoCpp::Scene
struct Shader final : public virtual ICloseable
{
std::vector<ShaderProgram> shaderPrograms{};
std::vector<VertexInputDescription> vertexInputDescriptions{};
Topology topology = Topology::TRIANGLE_LIST;
ICloseable* renderShader = nullptr;
@@ -147,6 +149,25 @@ namespace openVulkanoCpp::Scene
return *this;
}
Shader& AddVertexInputDescription(const VertexInputDescription& inputDescription, int bindingId = -1)
{
if (renderShader) throw std::runtime_error("Shader already initialized!");
if (bindingId < 0) bindingId = vertexInputDescriptions.size();
if (bindingId > vertexInputDescriptions.size())
{
vertexInputDescriptions.emplace_back(0, 0);
}
if (bindingId == vertexInputDescriptions.size())
{
vertexInputDescriptions.emplace_back(bindingId, inputDescription);
}
else
{
vertexInputDescriptions[bindingId] = inputDescription;
}
return *this;
}
void Close() override
{
renderShader->Close();

View File

@@ -7,6 +7,7 @@
#pragma once
#include "Math/Math.hpp"
#include "VertexInputDescription.hpp"
#include <assimp/vector2.h>
#include <assimp/vector3.h>
#include <assimp/color4.h>
@@ -182,5 +183,17 @@ namespace openVulkanoCpp
{
this->color = { color.r, color.g, color.b, color.a };
}
static VertexInputDescription GetVertexInputDescription()
{
VertexInputDescription description(0, sizeof(Vertex));
description.AddInputParameter(DataFormat::R32G32B32_SFLOAT, offsetof(Vertex, position));
description.AddInputParameter(DataFormat::R32G32B32_SFLOAT, offsetof(Vertex, normal));
description.AddInputParameter(DataFormat::R32G32B32_SFLOAT, offsetof(Vertex, tangent));
description.AddInputParameter(DataFormat::R32G32B32_SFLOAT, offsetof(Vertex, biTangent));
description.AddInputParameter(DataFormat::R32G32B32_SFLOAT, offsetof(Vertex, textureCoordinates));
description.AddInputParameter(DataFormat::R32G32B32A32_SFLOAT, offsetof(Vertex, color));
return description;
}
};
}

View File

@@ -6,7 +6,6 @@
#include "VulkanShader.hpp"
#include "Vulkan/Context.hpp"
#include "Scene/Vertex.hpp"
#include "Scene/Shader.hpp"
#include "Vulkan/Resources/IShaderOwner.hpp"
@@ -33,18 +32,39 @@ namespace openVulkanoCpp::Vulkan
void VulkanShader::BuildPipeline()
{
vk::VertexInputBindingDescription vertexBindDesc(0, sizeof(Vertex), vk::VertexInputRate::eVertex);
std::vector<vk::VertexInputBindingDescription> vertexBindDesc;
std::vector<vk::VertexInputAttributeDescription> attributeDescriptions;
attributeDescriptions.emplace_back(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, position));
attributeDescriptions.emplace_back(1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, normal));
attributeDescriptions.emplace_back(2, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, tangent));
attributeDescriptions.emplace_back(3, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, biTangent));
attributeDescriptions.emplace_back(4, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, textureCoordinates));
attributeDescriptions.emplace_back(5, 0, vk::Format::eR32G32B32A32Sfloat, offsetof(Vertex, color));
vertexBindDesc.reserve(shader->vertexInputDescriptions.size());
for(const auto& description : shader->vertexInputDescriptions)
{
vertexBindDesc.emplace_back(description.bindingId, description.vertexSize, vk::VertexInputRate::eVertex);
if (shader->vertexInputDescriptions.size() > 1)
{
for(const auto& param : description.inputParameters)
{
attributeDescriptions.push_back(reinterpret_cast<const vk::VertexInputAttributeDescription&>(param));
}
}
}
uint32_t attributeDescriptionsSize;
vk::VertexInputAttributeDescription* attributeDescriptionsData;
if (shader->vertexInputDescriptions.size() == 1)
{ // Reuse already existing vertex attribute description
static_assert(sizeof(VertexInputParameter) == sizeof(vk::VertexInputAttributeDescription));
attributeDescriptionsSize = shader->vertexInputDescriptions[0].inputParameters.size();
attributeDescriptionsData = reinterpret_cast<vk::VertexInputAttributeDescription*>(shader->vertexInputDescriptions[0].inputParameters.data());
}
else
{
attributeDescriptionsSize = attributeDescriptions.size();
attributeDescriptionsData = attributeDescriptions.data();
}
vk::PipelineViewportStateCreateInfo viewportStateCreateInfo = { {}, 1, &context->swapChain.GetFullscreenViewport(), 1, &context->swapChain.GetFullscreenScissor() };
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = { {}, 1, &vertexBindDesc,
static_cast<uint32_t>(attributeDescriptions.size()), attributeDescriptions.data() };
vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = {
{}, static_cast<uint32_t>(vertexBindDesc.size()), vertexBindDesc.data(),
attributeDescriptionsSize, attributeDescriptionsData };
vk::PipelineInputAssemblyStateCreateInfo inputAssembly = { {}, static_cast<vk::PrimitiveTopology>(shader->topology), 0 };
vk::PipelineRasterizationStateCreateInfo rasterizer = {};
rasterizer.cullMode = vk::CullModeFlagBits::eBack;