ITextureSP VKTS_APIENTRY textureCreate(const IInitialResourcesSP& initialResources, const std::string& name, const VkBool32 mipmap, const VkBool32 cubemap, const IMemoryImageSP& memoryImage, const VkSamplerCreateInfo& samplerCreateInfo, const VkImageViewCreateInfo& imageViewCreateInfo) { if (!memoryImage.get()) { return ITextureSP(); } // VkSamplerCreateInfo finalSamplerCreateInfo; memcpy(&finalSamplerCreateInfo, &samplerCreateInfo, sizeof(VkImageViewCreateInfo)); finalSamplerCreateInfo.maxLod = mipmap ? (float) memoryImage->getImageData()->getMipLevels() : 0.0f; auto sampler = samplerCreate(initialResources->getDevice()->getDevice(), finalSamplerCreateInfo.flags, finalSamplerCreateInfo.magFilter, finalSamplerCreateInfo.minFilter, finalSamplerCreateInfo.mipmapMode, samplerCreateInfo.addressModeU, samplerCreateInfo.addressModeV, finalSamplerCreateInfo.addressModeW, finalSamplerCreateInfo.mipLodBias, finalSamplerCreateInfo.anisotropyEnable, finalSamplerCreateInfo.maxAnisotropy, finalSamplerCreateInfo.compareEnable, finalSamplerCreateInfo.compareOp, finalSamplerCreateInfo.minLod, finalSamplerCreateInfo.maxLod, finalSamplerCreateInfo.borderColor, finalSamplerCreateInfo.unnormalizedCoordinates); if (!sampler.get()) { logPrint(VKTS_LOG_ERROR, "Texture: Could not create sampler."); return ITextureSP(); } // VkImageViewCreateInfo finalImageViewCreateInfo; memcpy(&finalImageViewCreateInfo, &imageViewCreateInfo, sizeof(VkImageViewCreateInfo)); finalImageViewCreateInfo.image = memoryImage->getImage()->getImage(); finalImageViewCreateInfo.viewType = cubemap ? VK_IMAGE_VIEW_TYPE_CUBE : VK_IMAGE_VIEW_TYPE_2D; finalImageViewCreateInfo.format = memoryImage->getImage()->getFormat(); finalImageViewCreateInfo.subresourceRange.levelCount = mipmap ? memoryImage->getImageData()->getMipLevels() : 1; finalImageViewCreateInfo.subresourceRange.layerCount = cubemap ? memoryImage->getImageData()->getArrayLayers() : 1; auto imageView = imageViewCreate(initialResources->getDevice()->getDevice(), finalImageViewCreateInfo.flags, finalImageViewCreateInfo.image, finalImageViewCreateInfo.viewType, finalImageViewCreateInfo.format, finalImageViewCreateInfo.components, finalImageViewCreateInfo.subresourceRange); if (!imageView.get()) { logPrint(VKTS_LOG_ERROR, "Texture: Could not create image view."); return ITextureSP(); } // auto newInstance = new Texture(initialResources, name, memoryImage, sampler, imageView); if (!newInstance) { newInstance->destroy(); return ITextureSP(); } return ITextureSP(newInstance); }
void Font::destroy() { if (texture.get()) { texture->destroy(); texture = ITextureSP(nullptr); } allCharacters.clear(); if (vertexBuffer.get()) { vertexBuffer->destroy(); vertexBuffer = IBufferObjectSP(nullptr); } }
FontCacheEntry* FreeTypeFont::getGlyph(const char32_t character, const size_t size) { if (!face) { return nullptr; } // auto results = cache.find(character); while (results != cache.cend()) { if (results->second.size == size) { return &results->second; } results++; } // if (FT_Set_Char_Size(face, VKTS_TO_CHAR_SIZE(size), VKTS_TO_CHAR_SIZE(size), 0, 0)) { return nullptr; } auto glyphIndex = FT_Get_Char_Index(face, character); if (FT_Load_Glyph(face, glyphIndex, FT_LOAD_DEFAULT)) { return nullptr; } if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL)) { return nullptr; } // IImageDataSP glyphImageData; if (face->glyph->bitmap.buffer) { glyphImageData = imageDataCreate("FontCharacterImageData", face->glyph->bitmap.width, face->glyph->bitmap.rows, 1, VK_IMAGE_TYPE_2D, VK_FORMAT_R8_UNORM); if (!glyphImageData.get()) { return nullptr; } VkSubresourceLayout subresourceLayout; subresourceLayout.offset = 0; subresourceLayout.size = face->glyph->bitmap.width * face->glyph->bitmap.rows; subresourceLayout.rowPitch = face->glyph->bitmap.width; subresourceLayout.arrayPitch = 0; subresourceLayout.depthPitch = 0; if (!glyphImageData->upload(face->glyph->bitmap.buffer, 0, subresourceLayout)) { return nullptr; } } else { // For space, no data is created. glyphImageData = imageDataCreate("FontCharacterImageData", 1, 1, 1, 0.0f, 0.0f, 0.0f, 0.0f, VK_IMAGE_TYPE_2D, VK_FORMAT_R8_UNORM); if (!glyphImageData.get()) { return nullptr; } } // FontCacheEntry fontCacheEntry; fontCacheEntry.character = character; fontCacheEntry.size = size; fontCacheEntry.width = face->glyph->bitmap.width; fontCacheEntry.height = face->glyph->bitmap.rows; fontCacheEntry.advanceX = VKTS_FROM_CHAR_SIZE(face->glyph->advance.x); fontCacheEntry.advanceY = VKTS_FROM_CHAR_SIZE(face->glyph->advance.y); fontCacheEntry.offsetX = VKTS_FROM_CHAR_SIZE(face->glyph->metrics.vertBearingX - face->glyph->metrics.width); fontCacheEntry.offsetY = VKTS_FROM_CHAR_SIZE(face->glyph->metrics.horiBearingY - face->glyph->metrics.height); fontCacheEntry.glyphImageData = glyphImageData; fontCacheEntry.texture = ITextureSP(); cache.insert(std::make_pair(character, fontCacheEntry)); // results = cache.find(character); while (results != cache.cend()) { if (results->second.size == size) { return &results->second; } results++; } return nullptr; }
ITextureSP VKTS_APIENTRY textureCreate(IImageSP& stageImage, IBufferSP& stageBuffer, IDeviceMemorySP& stageDeviceMemory, const IInitialResourcesSP& initialResources, const ICommandBuffersSP& cmdBuffer, const std::string& name, const IImageDataSP& imageData, const VkImageCreateInfo& imageCreateInfo, const VkAccessFlags dstAccessMask, const VkImageLayout newLayout, const VkImageSubresourceRange& subresourceRange, const VkMemoryPropertyFlags memoryPropertyFlags, const VkSamplerCreateInfo& samplerCreateInfo, const VkImageViewCreateInfo& imageViewCreateInfo) { if (!cmdBuffer || !imageData.get()) { return ITextureSP(); } VkResult result; // IImageSP image; IDeviceMemorySP deviceMemory; // if (!texturePrepare(image, deviceMemory, initialResources, cmdBuffer, imageCreateInfo, dstAccessMask, newLayout, subresourceRange, memoryPropertyFlags)) { return ITextureSP(); } // 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 (!textureUpload(deviceMemory, imageData, i, subresourceLayout)) { logPrint(VKTS_LOG_ERROR, "Texture: Could not upload image data."); return ITextureSP(); } } } 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; if (!texturePrepare(stageImage, stageDeviceMemory, initialResources, cmdBuffer, stageImageCreateInfo, dstAccessMask, newLayout, subresourceRange, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) { logPrint(VKTS_LOG_ERROR, "Texture: Could not prepare staging image."); return ITextureSP(); } 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 (!textureUpload(stageDeviceMemory, imageData, i, subresourceLayout)) { logPrint(VKTS_LOG_ERROR, "Texture: Could not upload image data."); return ITextureSP(); } 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->getImage(), image->getAccessMask(), image->getImageLayout(), imageCopy); } }