void SubMesh::drawIndexed(const ICommandBuffersSP& cmdBuffer, const uint32_t bufferIndex) const { if (!cmdBuffer.get()) { return; } vkCmdDrawIndexed(cmdBuffer->getCommandBuffer(bufferIndex), getNumberIndices(), 1, 0, 0, 0); }
void SubMesh::bindDrawIndexedRecursive(const std::string& nodeName, const ICommandBuffersSP& cmdBuffer, const SmartPointerVector<IGraphicsPipelineSP>& allGraphicsPipelines, const overwrite* renderOverwrite, const uint32_t bufferIndex) const { const overwrite* currentOverwrite = renderOverwrite; while (currentOverwrite) { if (!currentOverwrite->submeshBindDrawIndexedRecursive(*this, cmdBuffer, allGraphicsPipelines, bufferIndex)) { return; } currentOverwrite = currentOverwrite->getNextOverwrite(); } if (bsdfMaterial.get()) { // TODO: Add again. } else if (phongMaterial.get()) { IGraphicsPipelineSP graphicsPipeline; for (size_t i = 0; i < allGraphicsPipelines.size(); i++) { if (allGraphicsPipelines[i]->getVertexBufferType() == vertexBufferType) { graphicsPipeline = allGraphicsPipelines[i]; break; } } if (!graphicsPipeline.get()) { logPrint(VKTS_LOG_SEVERE, "SubMesh: Vertex buffer type not found %x", vertexBufferType); return; } vkCmdBindPipeline(cmdBuffer->getCommandBuffer(), VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->getPipeline()); phongMaterial->bindDrawIndexedRecursive(nodeName,cmdBuffer, graphicsPipeline, renderOverwrite, bufferIndex); } else { return; } bindIndexBuffer(cmdBuffer, bufferIndex); bindVertexBuffers(cmdBuffer, bufferIndex); drawIndexed(cmdBuffer, bufferIndex); }
void BRDFMaterial::bindDescriptorSets(const ICommandBuffersSP& cmdBuffer, const VkPipelineLayout layout, const uint32_t bufferIndex) const { if (!cmdBuffer.get()) { return; } if (!descriptorSets.get()) { return; } vkCmdBindDescriptorSets(cmdBuffer->getCommandBuffer(bufferIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1, &descriptorSets->getDescriptorSets()[0], 0, nullptr); }
void PhongMaterial::bindDescriptorSets(const std::string& nodeName, const ICommandBuffersSP& cmdBuffer, const VkPipelineLayout layout, const uint32_t bufferIndex) const { if (!cmdBuffer.get()) { return; } auto currentDescriptorSets = getDescriptorSetsByName(nodeName); if (!currentDescriptorSets.get()) { return; } vkCmdBindDescriptorSets(cmdBuffer->getCommandBuffer(bufferIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1, ¤tDescriptorSets->getDescriptorSets()[0], 0, nullptr); }
void SubMesh::bindIndexBuffer(const ICommandBuffersSP& cmdBuffer, const uint32_t bufferIndex) const { if (!indicesVertexBuffer.get()) { return; } if (!indicesVertexBuffer->getBuffer().get()) { return; } if (!cmdBuffer.get()) { return; } vkCmdBindIndexBuffer(cmdBuffer->getCommandBuffer(bufferIndex), indicesVertexBuffer->getBuffer()->getBuffer(), 0, VK_INDEX_TYPE_UINT32); }
void SubMesh::bindVertexBuffers(const ICommandBuffersSP& cmdBuffer, const uint32_t bufferIndex) const { if (!vertexBuffer.get()) { return; } if (!vertexBuffer->getBuffer().get()) { return; } if (!cmdBuffer.get()) { return; } VkDeviceSize offsets[1] = {0}; VkBuffer buffers[1] = {vertexBuffer->getBuffer()->getBuffer()}; vkCmdBindVertexBuffers(cmdBuffer->getCommandBuffer(bufferIndex), 0, 1, buffers, offsets); }
IBufferObjectSP VKTS_APIENTRY bufferObjectCreate(IBufferSP& stageBuffer, IDeviceMemorySP& stageDeviceMemory, const IInitialResourcesSP& initialResources, const ICommandBuffersSP& cmdBuffer, const IBinaryBufferSP& binaryBuffer, const VkBufferCreateInfo& bufferCreateInfo, const VkMemoryPropertyFlags memoryPropertyFlag) { if (!initialResources.get() || !cmdBuffer.get() || !binaryBuffer.get()) { return IBufferObjectSP(); } // VkResult result; // IBufferSP buffer; IDeviceMemorySP deviceMemory; if (!bufferObjectPrepare(buffer, deviceMemory, initialResources, bufferCreateInfo, memoryPropertyFlag)) { return IBufferObjectSP(); } // if (memoryPropertyFlag & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { result = deviceMemory->upload(0, deviceMemory->getAllocationSize(), 0, binaryBuffer->getData(), binaryBuffer->getSize()); if (result != VK_SUCCESS) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not upload vertex data."); return IBufferObjectSP(); } } else { if (!bufferObjectPrepare(stageBuffer, stageDeviceMemory, initialResources, bufferCreateInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not create vertex buffer."); return IBufferObjectSP(); } result = stageDeviceMemory->upload(0, stageDeviceMemory->getAllocationSize(), 0, binaryBuffer->getData(), binaryBuffer->getSize()); if (result != VK_SUCCESS) { logPrint(VKTS_LOG_ERROR, "BufferObject: Could not upload vertex data."); return IBufferObjectSP(); } VkBufferCopy bufferCopy; bufferCopy.srcOffset = 0; bufferCopy.dstOffset = 0; bufferCopy.size = binaryBuffer->getSize(); stageBuffer->copyBuffer(cmdBuffer->getCommandBuffer(), buffer->getBuffer(), buffer->getSize(), 1, &bufferCopy); } // IBufferViewSP noBufferView; auto newInstance = new BufferObject(initialResources, buffer, noBufferView, deviceMemory); if (!newInstance) { buffer->destroy(); return IBufferObjectSP(); } return IBufferObjectSP(newInstance); }
void Font::drawText(const ICommandBuffersSP& cmdBuffer, const glm::mat4& viewProjection, const glm::vec2& translate, const std::string& text, const glm::vec4& color) const { if (!cmdBuffer.get()) { return; } // const VkBuffer buffers[1] = {vertexBuffer->getBuffer()->getBuffer()}; VkDeviceSize offsets[1] = {0}; vkCmdBindVertexBuffers(cmdBuffer->getCommandBuffer(), 0, 1, buffers, offsets); // glm::vec2 cursor = translate; const Char* lastCharacter = nullptr; for (auto c : text) { // Line break. if (c == '\n') { cursor.x = translate.x; cursor.y += getLineHeight(); lastCharacter = nullptr; continue; } auto currentCharacter = allCharacters.find((int32_t)c); if (currentCharacter == allCharacters.end()) { // Character not found. lastCharacter = nullptr; continue; } // // Advance, depending on kerning of current and last character. // if (lastCharacter) { cursor.x += lastCharacter->getKerning(currentCharacter->second.getId()); } // // Get bottom left corner of the character texture. // glm::vec2 origin = cursor; origin.y += getBase(); origin.x -= currentCharacter->second.getXoffset(); // Draw Character. glm::mat4 transformVertex = viewProjection * translateMat4(origin.x, origin.y, 0.0f); vkCmdPushConstants(cmdBuffer->getCommandBuffer(), graphicsPipeline->getLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float) * 16, glm::value_ptr(transformVertex)); glm::mat3 translateTexCoord = translateMat3(currentCharacter->second.getX() / getScaleWidth(), (getScaleHeight() - currentCharacter->second.getY() - currentCharacter->second.getHeight()) / getScaleHeight()); glm::mat3 scaleTexCoord = scaleMat3(currentCharacter->second.getWidth() / getScaleWidth(), currentCharacter->second.getHeight() / getScaleHeight(), 1.0f); glm::mat3 transformTexCoord = translateTexCoord * scaleTexCoord; vkCmdPushConstants(cmdBuffer->getCommandBuffer(), graphicsPipeline->getLayout(), VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 16, sizeof(float) * 9, glm::value_ptr(transformTexCoord)); vkCmdPushConstants(cmdBuffer->getCommandBuffer(), graphicsPipeline->getLayout(), VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 16 + sizeof(float) * 12, sizeof(float) * 4, glm::value_ptr(color)); // Expecting triangle strip as primitive topology. vkCmdDraw(cmdBuffer->getCommandBuffer(), 4, 1, 0, 0); // // Advance, as character has been drawn. // cursor.x += currentCharacter->second.getXadvance(); lastCharacter = ¤tCharacter->second; } }
IMemoryImageSP VKTS_APIENTRY memoryImageCreate(IImageSP& stageImage, IBufferSP& stageBuffer, IDeviceMemorySP& stageDeviceMemory, const IInitialResourcesSP& initialResources, const ICommandBuffersSP& cmdBuffer, const std::string& name, const IImageDataSP& imageData, const VkImageCreateInfo& imageCreateInfo, const VkAccessFlags srcAccessMask, const VkAccessFlags dstAccessMask, const VkImageLayout newLayout, const VkImageSubresourceRange& subresourceRange, const VkMemoryPropertyFlags memoryPropertyFlags) { if (!cmdBuffer || !imageData.get()) { return IMemoryImageSP(); } VkResult result; // IImageSP image; IDeviceMemorySP deviceMemory; // if (!memoryImagePrepare(image, deviceMemory, initialResources, cmdBuffer, imageCreateInfo, srcAccessMask, dstAccessMask, newLayout, subresourceRange, memoryPropertyFlags)) { return IMemoryImageSP(); } // if (memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { for (uint32_t i = 0; i < imageData->getMipLevels(); i++) { VkImageSubresource imageSubresource; imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageSubresource.mipLevel = i; imageSubresource.arrayLayer = 0; VkSubresourceLayout subresourceLayout; image->getImageSubresourceLayout(subresourceLayout, imageSubresource); if (!memoryImageUpload(deviceMemory, imageData, i, subresourceLayout)) { logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not upload image data."); return IMemoryImageSP(); } } } else { if (initialResources->getPhysicalDevice()->isImageTilingAvailable(VK_IMAGE_TILING_LINEAR, imageData->getFormat(), imageData->getImageType(), 0, imageData->getExtent3D(), imageData->getMipLevels(), 1, VK_SAMPLE_COUNT_1_BIT, imageData->getSize())) { VkImageCreateInfo stageImageCreateInfo; memcpy(&stageImageCreateInfo, &imageCreateInfo, sizeof(VkImageCreateInfo)); stageImageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR; stageImageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; stageImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; if (!memoryImagePrepare(stageImage, stageDeviceMemory, initialResources, cmdBuffer, stageImageCreateInfo, VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresourceRange, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) { logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not prepare staging image."); return IMemoryImageSP(); } for (uint32_t i = 0; i < imageData->getMipLevels(); i++) { VkImageSubresource imageSubresource; imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageSubresource.mipLevel = i; imageSubresource.arrayLayer = 0; VkSubresourceLayout subresourceLayout; stageImage->getImageSubresourceLayout(subresourceLayout, imageSubresource); if (!memoryImageUpload(stageDeviceMemory, imageData, i, subresourceLayout)) { logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not upload image data."); return IMemoryImageSP(); } VkImageCopy imageCopy; imageCopy.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i, 0, 1}; imageCopy.srcOffset = {0, 0, 0}; imageCopy.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i, 0, 1}; imageCopy.dstOffset = {0, 0, 0}; imageCopy.extent = {glm::max(imageData->getWidth() >> i, 1u), glm::max(imageData->getHeight() >> i, 1u), glm::max(imageData->getDepth() >> i, 1u)}; stageImage->copyImage(cmdBuffer->getCommandBuffer(), image, imageCopy); } }