7 VulkanSpriteRenderer::VulkanSpriteRenderer(VulkanRenderer * renderer, VulkanLogicalDevice * device, VulkanDescriptorPool * descriptorPool)
9 this->renderer = renderer;
10 this->device = device;
11 this->descriptorPool = descriptorPool;
13 renderPassPipeline = eastl::unique_ptr<VulkanPipeline>(
new VulkanPipeline(device, renderer));
15 renderPassPipeline->LoadShader(VulkanPipeline::SHADER_TYPE::VERTEX_SHADER,
"Sprite.vert.spv");
16 renderPassPipeline->LoadShader(VulkanPipeline::SHADER_TYPE::FRAGMENT_SHADER,
"Sprite.frag.spv");
18 renderPassPipeline->AddVertexInputBindingDescription(0, static_cast<uint32_t>(
sizeof(VertexInfo_t)), VK_VERTEX_INPUT_RATE_VERTEX);
19 renderPassPipeline->AddVertexInputAttributeDescription(0, 0, VK_FORMAT_R32G32B32_SFLOAT, 0);
20 renderPassPipeline->AddVertexInputAttributeDescription(1, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(VertexInfo_t, texCoord));
22 renderPassPipeline->CreateDescriptorSet();
23 renderPassPipeline->CreateDescriptorSet();
25 renderPassPipeline->AddDescriptorSetBinding(0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT,
nullptr);
27 renderPassPipeline->AddDescriptorSetBinding(1, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
nullptr);
29 renderPassPipeline->AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT, 0, static_cast<uint32_t>(
sizeof(PushConstants_t)));
31 renderPassPipeline->SetRenderPassInfo(renderer->GetRenderPass(),
static_cast<int>(VulkanRenderer::RenderSubPasses::RENDER_PASS));
33 renderPassPipeline->CreateColorBlendAttachment(VK_TRUE, VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
34 VK_BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA);
36 renderPassPipeline->SetInputAssemblyState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
false);
38 renderPassPipeline->SetRasterizerSettings(0U, 0U, VK_POLYGON_MODE_FILL, 1.f, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_COUNTER_CLOCKWISE);
40 renderPassPipeline->Compile();
44 vertexBuffer = eastl::unique_ptr<VulkanBuffer>(
new VulkanBuffer(device, renderer->GetVmaAllocator(),
45 static_cast<uint32_t
>(
sizeof(VertexInfo_t))*4, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
46 true, renderer->GetGraphicsCommandPool()));
48 indexBuffer = eastl::unique_ptr<VulkanBuffer>(
new VulkanBuffer(device, renderer->GetVmaAllocator(),
49 static_cast<uint32_t
>(
sizeof(uint32_t)) * 6, VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
50 true, renderer->GetGraphicsCommandPool()));
52 uboBuffer = eastl::unique_ptr<VulkanBuffer>(
new VulkanBuffer(device, renderer->GetVmaAllocator(),
53 static_cast<uint32_t
>(
sizeof(Ubo_t)), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
54 false, renderer->GetGraphicsCommandPool()));
56 ubo.proj = glm::mat4();
57 ubo.view = glm::scale(glm::mat4(),glm::vec3(0.f,0.f,0.f));
59 eastl::vector<VertexInfo_t> vertexData = {
60 {glm::vec3(-0.5f,0.5f,0.0f),glm::vec2(0.f,1.f)},
61 {glm::vec3(-0.5f,-0.5f,0.0f),glm::vec2(0.f,0.f)},
62 {glm::vec3(0.5f,-0.5f,0.0f),glm::vec2(1.f,0.f)},
63 {glm::vec3(0.5f,0.5f,0.0f),glm::vec2(1.f,1.f)}
66 indices = { 0,1,2,2,3,0 };
68 vertexBuffer->UpdateBuffer(vertexData.data(), 0,
static_cast<uint32_t
>(
sizeof(VertexInfo_t)*vertexData.size()));
69 indexBuffer->UpdateBuffer(indices.data(), 0,
static_cast<uint32_t
>(
sizeof(uint32_t)*indices.size()));
70 uboBuffer->UpdateBuffer(&ubo, 0, static_cast<uint32_t>(
sizeof(Ubo_t)));
72 VkDescriptorSetLayout renderLayouts[] = { renderPassPipeline->GetDescriptorSetLayout(0) };
74 descriptorPool->AllocateDescriptorSet(1, renderLayouts, &renderUboDescriptorSet);
75 descriptorPool->DescriptorSetBindToBuffer(renderUboDescriptorSet, uboBuffer->GetBuffer(),
76 0,
static_cast<VkDeviceSize
>(
sizeof(Ubo_t)),
77 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1);
80 VulkanSpriteRenderer::~VulkanSpriteRenderer()
86 renderPassPipeline.reset();
89 void VulkanSpriteRenderer::StartRender(VkCommandBuffer renderPassBuffer, glm::mat4 viewMatrix, glm::mat4 projectionMatrix)
91 this->renderCommandBuffer = renderPassBuffer;
93 if (ubo.view != viewMatrix || ubo.proj != projectionMatrix) {
94 ubo.view = viewMatrix;
95 ubo.proj = projectionMatrix;
97 uboBuffer->UpdateBuffer(&ubo, 0, static_cast<uint32_t>(
sizeof(Ubo_t)));
100 VkRect2D scissor = { 0,0,renderer->GetSwapChainExtent() };
102 VkBuffer vertexBuffers[] = { (vertexBuffer->GetBuffer()) };
103 VkDeviceSize offsets[] = { 0 };
105 renderer->StartSecondaryCommandBufferRecording(renderCommandBuffer,
106 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
107 renderer->GetRenderPass(),
static_cast<int>(VulkanRenderer::RenderSubPasses::RENDER_PASS), renderer->GetFrameBuffer());
109 vkCmdSetScissor(renderCommandBuffer, 0, 1, &scissor);
111 vkCmdBindPipeline(renderCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderPassPipeline->GetPipeline());
113 vkCmdBindDescriptorSets(renderCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderPassPipeline->GetPipelineLayout(), 0, 1, &renderUboDescriptorSet, 0,
nullptr);
115 vkCmdBindVertexBuffers(renderCommandBuffer, 0, 1, vertexBuffers, offsets);
117 vkCmdBindIndexBuffer(renderCommandBuffer, indexBuffer->GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
120 void VulkanSpriteRenderer::RenderSprite(eastl::weak_ptr<VulkanTexture> texture, glm::mat4 modelMatrix)
122 PushConstants_t constants = { modelMatrix };
124 vkCmdPushConstants(renderCommandBuffer, renderPassPipeline->GetPipelineLayout(),
125 VK_SHADER_STAGE_VERTEX_BIT, 0,
static_cast<uint32_t
>(
sizeof(PushConstants_t)), &constants);
127 if (texture.lock()->GetDescriptorSet(0, renderPassPipeline->GetPipelineId(), 1) == VK_NULL_HANDLE) {
128 texture.lock()->CreateDescriptorSet(0, renderPassPipeline->GetPipelineId(), 1, renderPassPipeline->GetDescriptorSetLayout(1));
131 VkDescriptorSet sets[] = { texture.lock()->GetDescriptorSet(0, renderPassPipeline->GetPipelineId(),1) };
132 vkCmdBindDescriptorSets(renderCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
133 renderPassPipeline->GetPipelineLayout(), 1, 1, sets, 0,
nullptr);
135 vkCmdDrawIndexed(renderCommandBuffer, static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
138 void VulkanSpriteRenderer::FinishRender()
140 renderer->EndSecondaryCommandBufferRecording(renderCommandBuffer);
143 void VulkanSpriteRenderer::Clean()
const 145 renderPassPipeline->Clean();
148 void VulkanSpriteRenderer::Recreate()
150 renderPassPipeline->SetRenderPassInfo(renderer->GetRenderPass(),
static_cast<int>(VulkanRenderer::RenderSubPasses::RENDER_PASS));
151 renderPassPipeline->Recreate();
156 #endif // USING_VULKAN