VkBool32 FreeTypeFont::prepareText(const ICommandBuffersSP& cmdBuffer, const std::u32string& text, const size_t size) { if (!face || !cmdBuffer.get()) { return VK_FALSE; } size_t textIndex = 0; FontCacheEntry* fontCacheEntry; while (textIndex < text.length()) { fontCacheEntry = getGlyph(cmdBuffer, text[textIndex], size); if (fontCacheEntry == nullptr) { return VK_FALSE; } textIndex++; } return VK_TRUE; }
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 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); }
VkBool32 FreeTypeFont::renderText(const ICommandBuffersSP& cmdBuffer, const std::u32string& text, const size_t size, const glm::vec4& color) { if (!face || !cmdBuffer.get()) { return VK_FALSE; } // // TODO: Create once vertex buffer etc. like in example 3. // TODO: Create for each letter a descriptor set. // size_t textIndex = 0; FontCacheEntry* fontCacheEntry; while (textIndex < text.length()) { // Do not use the render command buffer for creation- fontCacheEntry = getGlyph(text[textIndex], size); if (fontCacheEntry == nullptr) { return VK_FALSE; } // TODO: Bind descriptor set. // TODO: Draw triangle square. textIndex++; } return VK_TRUE; }
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; } }