StudioCherno / Walnut

Walnut is a simple application framework for Vulkan and Dear ImGui apps
MIT License
2.11k stars 391 forks source link

Drawing nearest pixel #77

Open Synismusist opened 5 months ago

Synismusist commented 5 months ago

By default Walnut::Image is set to use linear filter and not nearest filter. I changed the magFilter, minFilter and mipmapMode in the VkSamplerCreateInfo to nearest, but i still get interpolation between pixels. Does anyone know if there is something else i must change?

`

void Image::AllocateMemory(uint64_t size)
{
    VkDevice device = Walnut::Application::GetDevice();

    VkResult err;

    VkFormat vulkanFormat = Utils::WalnutFormatToVulkanFormat(m_Format);

    // Create the Image
    {
        uint32_t queueFamilyIndices[2] = { Walnut::Application::GetGraphicsQueueFamily(), Walnut::Application::GetComputeQueueFamily() };
        VkImageCreateInfo info = {};
        info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
        info.imageType = VK_IMAGE_TYPE_2D;
        info.format = vulkanFormat;
        info.extent.width = m_Width;
        info.extent.height = m_Height;
        info.extent.depth = 1;
        info.mipLevels = 1;
        info.arrayLayers = 1;
        info.samples = VK_SAMPLE_COUNT_1_BIT;
        info.tiling = VK_IMAGE_TILING_OPTIMAL;
        info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
        info.sharingMode = VK_SHARING_MODE_CONCURRENT;
        info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
        info.pQueueFamilyIndices = queueFamilyIndices;
        info.queueFamilyIndexCount = 2;
        err = vkCreateImage(device, &info, nullptr, &m_Image);
        check_vk_result(err);
        VkMemoryRequirements req;
        vkGetImageMemoryRequirements(device, m_Image, &req);
        VkMemoryAllocateInfo alloc_info = {};
        alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
        alloc_info.allocationSize = req.size;
        alloc_info.memoryTypeIndex = Utils::GetVulkanMemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits);
        err = vkAllocateMemory(device, &alloc_info, nullptr, &m_Memory);
        check_vk_result(err);
        err = vkBindImageMemory(device, m_Image, m_Memory, 0);
        check_vk_result(err);
    }

    // Create the Image View:
    {
        VkImageViewCreateInfo info = {};
        info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
        info.image = m_Image;
        info.viewType = VK_IMAGE_VIEW_TYPE_2D;
        info.format = vulkanFormat;
        info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
        info.subresourceRange.levelCount = 1;
        info.subresourceRange.layerCount = 1;
        err = vkCreateImageView(device, &info, nullptr, &m_ImageView);
        check_vk_result(err);
    }

    // Create sampler:
    {
        VkSamplerCreateInfo info = {};
        info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
        info.magFilter = VK_FILTER_NEAREST;
        info.minFilter = VK_FILTER_NEAREST;
        info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
        info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
        info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
        info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
        info.mipLodBias = 0.f;
        info.minLod = 0.f;
        info.maxLod = 0.f;
        info.anisotropyEnable = VK_FALSE;
        info.maxAnisotropy = 0.f;
        info.unnormalizedCoordinates = VK_FALSE;
        VkResult err = vkCreateSampler(device, &info, nullptr, &m_Sampler);
        check_vk_result(err);
    }

    // Create the Descriptor Set:
    m_DescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(m_Sampler, m_ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}

`