Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Vulkan] question

    1 mai 2024 à 14:53:13

    Salut j'ai créer plusieurs classes pour le dessin j'ai essayé de faire comme le fait la SFML c'est à dire une classe RenderWindow pour dessiner sur la fenêtre principale :

            ////////////////////////////////////////////////////////////
            RenderWindow::RenderWindow(VideoMode mode, const String& title, window::VkSettup& vkSettup, Uint32 style,  const window::ContextSettings& settings) : RenderTarget(vkSettup), vkSettup(vkSettup)
            {
                // Don't call the base class constructor because it contains virtual function calls
                create(mode, title, style, settings);
            }
             ////////////////////////////////////////////////////////////
            RenderWindow::RenderWindow(WindowHandle handle,  window::VkSettup& vkSettup, const window::ContextSettings& settings) : vkSettup(vkSettup), RenderTarget(vkSettup)
            {
                // Don't call the base class constructor because it contains virtual function calls
                create(handle, settings);
            }
            void RenderWindow::cleanup() {
                cleanupSwapchain();
                for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
                    vkDestroySemaphore(vkSettup.getDevice(), renderFinishedSemaphores[i], nullptr);
                    vkDestroySemaphore(vkSettup.getDevice(), imageAvailableSemaphores[i], nullptr);
                    vkDestroyFence(vkSettup.getDevice(), inFlightFences[i], nullptr);
                }
                vkDestroySurfaceKHR(vkSettup.getInstance(), surface, nullptr);
            }
            void RenderWindow::createSurface(GLFWwindow* window) {
                 if (glfwCreateWindowSurface(vkSettup.getInstance(), getWindow(), nullptr, &surface) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to create window surface!", 1);
                 }
            }
            void RenderWindow::createSwapChain() {
                window::VkSettup::SwapChainSupportDetails swapChainSupport = vkSettup.querySwapChainSupport(vkSettup.getPhysicalDevice(), surface);
    
                VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
                VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes);
                VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities);
                uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
                if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) {
                    imageCount = swapChainSupport.capabilities.maxImageCount;
                }
    
                VkSwapchainCreateInfoKHR createInfo{};
                createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
                createInfo.surface = surface;
    
                createInfo.minImageCount = imageCount;
                createInfo.imageFormat = surfaceFormat.format;
                createInfo.imageColorSpace = surfaceFormat.colorSpace;
                createInfo.imageExtent = extent;
                createInfo.imageArrayLayers = 1;
                createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    
                window::VkSettup::QueueFamilyIndices indices = vkSettup.findQueueFamilies(vkSettup.getPhysicalDevice(), surface);
                uint32_t queueFamilyIndices[] = { indices.graphicsFamily.value(), indices.presentFamily.value() };
    
                if (indices.graphicsFamily != indices.presentFamily) {
                    createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
                    createInfo.queueFamilyIndexCount = 2;
                    createInfo.pQueueFamilyIndices = queueFamilyIndices;
                }
                else {
                    createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
                }
    
                createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
                createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
                createInfo.presentMode = presentMode;
                createInfo.clipped = VK_TRUE;
    
                if (vkCreateSwapchainKHR(vkSettup.getDevice(), &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to create swap chain!", 1);
                }
                vkGetSwapchainImagesKHR(vkSettup.getDevice(), swapChain, &imageCount, nullptr);
                swapChainImages.resize(imageCount);
                vkGetSwapchainImagesKHR(vkSettup.getDevice(), swapChain, &imageCount, swapChainImages.data());
    
                swapChainImageFormat = surfaceFormat.format;
                swapChainExtent = extent;
            }
            VkSurfaceFormatKHR RenderWindow::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats) {
                for (const auto& availableFormat : availableFormats) {
                    if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
                        return availableFormat;
                    }
                }
    
                return availableFormats[0];
            }
            VkPresentModeKHR RenderWindow::chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes) {
                for (const auto& availablePresentMode : availablePresentModes) {
                    if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
                        return availablePresentMode;
                    }
                }
    
                return VK_PRESENT_MODE_FIFO_KHR;
            }
            VkExtent2D RenderWindow::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
                if (capabilities.currentExtent.width != UINT32_MAX) {
                    return capabilities.currentExtent;
                } else {
                    int width, height;
                    glfwGetFramebufferSize(getWindow(), &width, &height);
    
                    VkExtent2D actualExtent = {
                        static_cast<uint32_t>(width),
                        static_cast<uint32_t>(height)
                    };
    
                    actualExtent.width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actualExtent.width));
                    actualExtent.height = std::max(capabilities.minImageExtent.height, std::min(capabilities.maxImageExtent.height, actualExtent.height));
    
                    return actualExtent;
                }
            }
            VkImageView RenderWindow::createImageView(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels) {
                VkImageViewCreateInfo viewInfo{};
                viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
                viewInfo.image = image;
                viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
                viewInfo.format = format;
                viewInfo.subresourceRange.aspectMask = aspectFlags;
                viewInfo.subresourceRange.baseMipLevel = 0;
                viewInfo.subresourceRange.levelCount = mipLevels;
                viewInfo.subresourceRange.baseArrayLayer = 0;
                viewInfo.subresourceRange.layerCount = 1;
    
                VkImageView imageView;
                if (vkCreateImageView(vkSettup.getDevice(), &viewInfo, nullptr, &imageView) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to create texture image view!", 1);
                }
    
                return imageView;
            }
            void RenderWindow::createImageViews() {
                swapChainImageViews.resize(swapChainImages.size());
    
                for (uint32_t i = 0; i < swapChainImages.size(); i++) {
                    swapChainImageViews[i] = createImageView(swapChainImages[i], swapChainImageFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1);
                }
            }
            void RenderWindow::createSyncObjects() {
                imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
                renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
                inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
                imagesInFlight.resize(swapChainImages.size(), VK_NULL_HANDLE);
    
                VkSemaphoreCreateInfo semaphoreInfo{};
                semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
    
                VkFenceCreateInfo fenceInfo{};
                fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
                fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
    
                for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
                    if (vkCreateSemaphore(vkSettup.getDevice(), &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS ||
                        vkCreateSemaphore(vkSettup.getDevice(), &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) != VK_SUCCESS ||
                        vkCreateFence(vkSettup.getDevice(), &fenceInfo, nullptr, &inFlightFences[i]) != VK_SUCCESS) {
    
                        throw core::Erreur(0, "échec de la création des objets de synchronisation pour une frame!", 1);
                    }
                }
            }
            size_t RenderWindow::getCurrentFrame() {
                return currentFrame;
            }
            VkFormat RenderWindow::getSwapchainImageFormat() {
                return swapChainImageFormat;
            }
            std::vector<VkImage> RenderWindow::getSwapchainImages() {
                return swapChainImages;
            }
            std::vector<VkImageView> RenderWindow::getSwapChainImageViews() {
                return swapChainImageViews;
            }
            VkExtent2D RenderWindow::getSwapchainExtents() {
                return swapChainExtent;
            }
            VkSurfaceKHR RenderWindow::getSurface() {
                return surface;
            }
            const int RenderWindow::getMaxFramesInFlight() {
                return MAX_FRAMES_IN_FLIGHT;
            }
            void RenderWindow::drawVulkanFrame() {
                if (getCommandBuffers().size() > 0) {
                    vkWaitForFences(vkSettup.getDevice(), 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
                    uint32_t imageIndex;
                    vkAcquireNextImageKHR(vkSettup.getDevice(), swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
                    // Vérifier si une frame précédente est en train d'utiliser cette image (il y a une fence à attendre)
                    if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
                        vkWaitForFences(vkSettup.getDevice(), 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
                    }
                     // Marque l'image comme étant à nouveau utilisée par cette frame
                    imagesInFlight[imageIndex] = inFlightFences[currentFrame];
    
                    VkSubmitInfo submitInfo{};
                    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    
                    VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame]};
                    VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
                    submitInfo.waitSemaphoreCount = 1;
                    submitInfo.pWaitSemaphores = waitSemaphores;
                    submitInfo.pWaitDstStageMask = waitStages;
                    submitInfo.commandBufferCount = 1;
                    submitInfo.pCommandBuffers = &getCommandBuffers()[imageIndex];
                    VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
                    submitInfo.signalSemaphoreCount = 1;
                    submitInfo.pSignalSemaphores = signalSemaphores;
                    vkResetFences(vkSettup.getDevice(), 1, &inFlightFences[currentFrame]);
                    if (vkQueueSubmit(vkSettup.getGraphicQueue(), 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
                        throw core::Erreur(0, "échec de l'envoi d'un command buffer!", 1);
                    }
                    VkPresentInfoKHR presentInfo{};
                    presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
    
                    presentInfo.waitSemaphoreCount = 1;
                    presentInfo.pWaitSemaphores = signalSemaphores;
                    VkSwapchainKHR swapChains[] = {swapChain};
                    presentInfo.swapchainCount = 1;
                    presentInfo.pSwapchains = swapChains;
                    presentInfo.pImageIndices = &imageIndex;
                    presentInfo.pResults = nullptr; // Optionnel
                    vkQueuePresentKHR(vkSettup.getPresentQueue(), &presentInfo);
                    currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
                    vkDeviceWaitIdle(vkSettup.getDevice());
                }
            }
            void RenderWindow::cleanupSwapchain() {
                for (size_t i = 0; i < swapChainFramebuffers.size(); i++) {
                    vkDestroyFramebuffer(vkSettup.getDevice(), swapChainFramebuffers[i], nullptr);
                }
                for (size_t i = 0; i < swapChainImageViews.size(); i++) {
                    vkDestroyImageView(vkSettup.getDevice(), swapChainImageViews[i], nullptr);
                }
    
                vkDestroySwapchainKHR(vkSettup.getDevice(), swapChain, nullptr);
            }
            void RenderWindow::recreateSwapchain() {
                vkDeviceWaitIdle(vkSettup.getDevice());
    
                cleanupSwapchain();
    
                createSwapChain();
                createImageViews();
                createFramebuffers();
            }
            ////////////////////////////////////////////////////////////
            RenderWindow::~RenderWindow()
            {
                RenderTarget::cleanup();
                cleanup();
            }
            ////////////////////////////////////////////////////////////
            Vector2u RenderWindow::getSize() const
            {
                return Window::getSize();
            }
            ////////////////////////////////////////////////////////////
            void RenderWindow::onCreate()
            {
                // Just initialize the render target part
    
                vkSettup.createInstance();
                vkSettup.setupDebugMessenger();
                createSurface(getWindow());
                vkSettup.pickupPhysicalDevice(surface);
                vkSettup.createLogicalDevice(surface);
                createSwapChain();
                createImageViews();
                RenderTarget::initialize();
                createRenderPass();
                createFramebuffers();
                createSyncObjects();
                currentFrame = 0;
            }
    
    
            ////////////////////////////////////////////////////////////
            void RenderWindow::onResize()
            {
                // Update the current view (recompute the viewport, which is stored in relative coordinates)
    
                setView(getView());
                recreateSwapchain();
                vkDestroyRenderPass(vkSettup.getDevice(), renderPass, nullptr);
                createRenderPass();
            }
            void RenderWindow::createFramebuffers() {
                swapChainFramebuffers.resize(swapChainImageViews.size());
    
                for (size_t i = 0; i < swapChainImageViews.size(); i++) {
                    VkImageView attachments[] = {
                        swapChainImageViews[i]
                    };
    
                    VkFramebufferCreateInfo framebufferInfo{};
                    framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
                    framebufferInfo.renderPass = renderPass;
                    framebufferInfo.attachmentCount = 1;
                    framebufferInfo.pAttachments = attachments;
                    framebufferInfo.width = swapChainExtent.width;
                    framebufferInfo.height = swapChainExtent.height;
                    framebufferInfo.layers = 1;
    
                    if (vkCreateFramebuffer(vkSettup.getDevice(), &framebufferInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS) {
                        throw core::Erreur(0, "failed to create framebuffer!", 1);
                    }
                }
            }
            void RenderWindow::createRenderPass() {
                VkAttachmentDescription colorAttachment{};
                colorAttachment.format =    getSwapchainImageFormat();
                colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
                colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
                colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
                colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
                colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
                colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
                colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
    
                VkAttachmentReference colorAttachmentRef{};
                colorAttachmentRef.attachment = 0;
                colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    
                VkSubpassDescription subpass{};
                subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
                subpass.colorAttachmentCount = 1;
                subpass.pColorAttachments = &colorAttachmentRef;
    
                VkRenderPassCreateInfo renderPassInfo{};
                renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
                renderPassInfo.attachmentCount = 1;
                renderPassInfo.pAttachments = &colorAttachment;
                renderPassInfo.subpassCount = 1;
                renderPassInfo.pSubpasses = &subpass;
                VkSubpassDependency dependency{};
                dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
                dependency.dstSubpass = 0;
                dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
                dependency.srcAccessMask = 0;
                dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
                dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
                renderPassInfo.dependencyCount = 1;
                renderPassInfo.pDependencies = &dependency;
                if (vkCreateRenderPass(vkSettup.getDevice(), &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to create render pass!", 1);
                }
    
            }
            size_t RenderWindow::getcurrentFrame() {
                return currentFrame;
            }

    Une classe RederTarget qui se charge juste de dessiner soit sur une fenêtre ou une texture :

    RenderTarget::RenderTarget(window::VkSettup& vkSettup) : vkSettup(vkSettup), vertexBuffer(vkSettup), defaultShader(vkSettup), defaultShader2(vkSettup),
            m_defaultView(), m_view() {
    
            }
            RenderTarget::~RenderTarget() {
                cleanup();
            }
            void RenderTarget::initialize() {
    
    
                m_defaultView = View (static_cast<float>(getSize().x), static_cast<float>(getSize().y), -static_cast<float>(getSize().y) - 200, static_cast<float>(getSize().y)+200);
                m_defaultView.reset(physic::BoundingBox(0, 0, -static_cast<float>(getSize().y) - 200,static_cast<float>(getSize().x), static_cast<float>(getSize().y),static_cast<float>(getSize().y)+200));
                m_view = m_defaultView;
                const std::string defaultVertexShader = R"(#version 450
                                                            layout(binding = 0) uniform UniformBufferObject {
                                                                mat4 model;
                                                                mat4 view;
                                                                mat4 proj;
                                                            } ubo;
                                                            layout(location = 0) in vec3 inPosition;
                                                            layout(location = 1) in vec4 inColor;
                                                            layout(location = 2) in vec2 inTexCoord;
    
                                                            layout(location = 0) out vec4 fragColor;
                                                            layout(location = 1) out vec2 fragTexCoord;
    
                                                            out gl_PerVertex {
                                                                vec4 gl_Position;
                                                            };
    
                                                            void main() {
                                                                gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0);
                                                                fragColor = inColor;
                                                                fragTexCoord = inTexCoord;
                                                            }
                                                            )";
                const std::string defaultFragmentShader = R"(#version 450
                                                              #extension GL_ARB_separate_shader_objects : enable
                                                              layout(binding = 1) uniform sampler2D texSampler;
                                                              layout(location = 0) in vec4 fragColor;
                                                              layout(location = 1) in vec2 fragTexCoord;
                                                              layout(location = 0) out vec4 outColor;
                                                              void main() {
                                                                 outColor = texture(texSampler, fragTexCoord) * fragColor;
                                                              })";
                 const std::string defaultFragmentShader2 = R"(#version 450
                                                              #extension GL_ARB_separate_shader_objects : enable
                                                              layout(location = 0) in vec4 fragColor;
                                                              layout(location = 1) in vec2 fragTexCoord;
                                                              layout(location = 0) out vec4 outColor;
                                                              void main() {
                                                                 outColor = fragColor;
                                                              })";
                 if (!defaultShader.loadFromMemory(defaultVertexShader, defaultFragmentShader)) {
                      throw core::Erreur (0, "Failed to load default shader", 1);
                 }
                 if (!defaultShader2.loadFromMemory(defaultVertexShader, defaultFragmentShader2)) {
                      throw core::Erreur (0, "Failed to load default shader 2", 1);
                 }
                 createCommandPool();
                 createUniformBuffers();
            }
            void RenderTarget::clear(const sf::Color& color) {
                cleanup();
                clearColor = color;
            }
            void RenderTarget::clearDepth() {
            }
            void RenderTarget::setView(View view)
            {
                m_view = view;
            }
            View& RenderTarget::getView() {
                return m_view;
            }
            View& RenderTarget::getDefaultView() {
                return m_defaultView;
            }
             math::Vec3f RenderTarget::mapPixelToCoords(const math::Vec3f& point)
            {
                return mapPixelToCoords(point, getView());
            }
    
    
            math::Vec3f RenderTarget::mapPixelToCoords(const math::Vec3f& point, View& view)
            {
                ViewportMatrix vpm;
                vpm.setViewport(math::Vec3f(view.getViewport().getPosition().x, view.getViewport().getPosition().y, 0)
                                            ,math::Vec3f(view.getViewport().getWidth(), view.getViewport().getHeight(), 1));
                math::Vec3f coords = vpm.toNormalizedCoordinates(point);
                coords = view.getProjMatrix().unProject(coords);
                coords = coords.normalizeToVec3();
                coords = view.getViewMatrix().inverseTransform(coords);
                return coords;
            }
    
            math::Vec3f RenderTarget::mapCoordsToPixel(const math::Vec3f& point)
            {
                return mapCoordsToPixel(point, getView());
            }
    
    
            math::Vec3f RenderTarget::mapCoordsToPixel(const math::Vec3f& point, View& view) {
                ViewportMatrix vpm;
                vpm.setViewport(math::Vec3f(view.getViewport().getPosition().x, view.getViewport().getPosition().y, 0),
                math::Vec3f(view.getViewport().getWidth(), view.getViewport().getHeight(), 1));
                math::Vec3f coords = view.getViewMatrix().transform(point);
                coords = view.getProjMatrix().project(coords);
                coords = coords.normalizeToVec3();
                coords = vpm.toViewportCoordinates(coords);
                return coords;
            }
            void RenderTarget::draw(Drawable& drawable, RenderStates states)
            {
                drawable.draw(*this, states);
            }
            void RenderTarget::draw(const Vertex* vertices, unsigned int vertexCount, sf::PrimitiveType type,
                          RenderStates states) {
    
                 vertexBuffer.clear();
                 for (unsigned int i = 0; i < vertexCount; i++) {
                    vertexBuffer.append(vertices[i]);
                 }
                 UniformBufferObject ubo;
                 ubo.proj = m_view.getProjMatrix().getMatrix().transpose();
                 ubo.proj.m22 *= -1;
                 ubo.view = m_view.getViewMatrix().getMatrix().transpose();
                 ubo.model = states.transform.getMatrix().transpose();
    
                 updateUniformBuffer(getCurrentFrame(), ubo);
                 createDescriptorSetLayout(states.texture);
                 createGraphicPipeline(vertices, vertexCount, type, states);
                 createDescriptorPool(states.texture);
                 createDescriptorSets(states.texture);
                 createCommandBuffers();
                 vertexBuffer.clearIndexes();
    
            }
            VertexBuffer& RenderTarget::getVertexBuffer () {
                return vertexBuffer;
            }
    
            void RenderTarget::createDescriptorSetLayout(const Texture* texture) {
                if (texture != nullptr) {
                    VkDescriptorSetLayoutBinding uboLayoutBinding{};
                    uboLayoutBinding.binding = 0;
                    uboLayoutBinding.descriptorCount = 1;
                    uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
                    uboLayoutBinding.pImmutableSamplers = nullptr;
                    uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
    
                    VkDescriptorSetLayoutBinding samplerLayoutBinding{};
                    samplerLayoutBinding.binding = 1;
                    samplerLayoutBinding.descriptorCount = 1;
                    samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
                    samplerLayoutBinding.pImmutableSamplers = nullptr;
                    samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
    
                    std::array<VkDescriptorSetLayoutBinding, 2> bindings = {uboLayoutBinding, samplerLayoutBinding};
    
                    VkDescriptorSetLayoutCreateInfo layoutInfo{};
                    layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
                    layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());;
                    layoutInfo.pBindings = bindings.data();
    
                    if (vkCreateDescriptorSetLayout(vkSettup.getDevice(), &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
                        throw std::runtime_error("failed to create descriptor set layout!");
                    }
                } else {
                    VkDescriptorSetLayoutBinding uboLayoutBinding{};
                    uboLayoutBinding.binding = 0;
                    uboLayoutBinding.descriptorCount = 1;
                    uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
                    uboLayoutBinding.pImmutableSamplers = nullptr;
                    uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
    
    
                    std::array<VkDescriptorSetLayoutBinding, 1> bindings = {uboLayoutBinding};
    
                    VkDescriptorSetLayoutCreateInfo layoutInfo{};
                    layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
                    layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());;
                    layoutInfo.pBindings = bindings.data();
    
                    if (vkCreateDescriptorSetLayout(vkSettup.getDevice(), &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
                        throw std::runtime_error("failed to create descriptor set layout!");
                    }
                }
            }
            void RenderTarget::createDescriptorPool(const Texture* texture) {
                if (texture != nullptr) {
                    std::array<VkDescriptorPoolSize, 2> poolSizes{};
                    poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
                    poolSizes[0].descriptorCount = static_cast<uint32_t>(getMaxFramesInFlight());
                    poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
                    poolSizes[1].descriptorCount = static_cast<uint32_t>(getMaxFramesInFlight());
    
                    VkDescriptorPoolCreateInfo poolInfo{};
                    poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
                    poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
                    poolInfo.pPoolSizes = poolSizes.data();
                    poolInfo.maxSets = static_cast<uint32_t>(getMaxFramesInFlight());
                    if (vkCreateDescriptorPool(vkSettup.getDevice(), &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
                        throw std::runtime_error("echec de la creation de la pool de descripteurs!");
                    }
                } else {
                    std::array<VkDescriptorPoolSize, 1> poolSizes{};
                    poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
                    poolSizes[0].descriptorCount = static_cast<uint32_t>(getMaxFramesInFlight());
    
                    VkDescriptorPoolCreateInfo poolInfo{};
                    poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
                    poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
                    poolInfo.pPoolSizes = poolSizes.data();
                    poolInfo.maxSets = static_cast<uint32_t>(getMaxFramesInFlight());
                    if (vkCreateDescriptorPool(vkSettup.getDevice(), &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
                        throw std::runtime_error("echec de la creation de la pool de descripteurs!");
                    }
                }
            }
            void RenderTarget::createDescriptorSets(const Texture* texture) {
                std::vector<VkDescriptorSetLayout> layouts(getMaxFramesInFlight(), descriptorSetLayout);
                VkDescriptorSetAllocateInfo allocInfo{};
                allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
                allocInfo.descriptorPool = descriptorPool;
                allocInfo.descriptorSetCount = static_cast<uint32_t>(getMaxFramesInFlight());
                allocInfo.pSetLayouts = layouts.data();
                descriptorSets.resize(getMaxFramesInFlight());
                if (vkAllocateDescriptorSets(vkSettup.getDevice(), &allocInfo, descriptorSets.data()) != VK_SUCCESS) {
                    throw std::runtime_error("echec de l'allocation d'un set de descripteurs!");
                }
                for (size_t i = 0; i < getMaxFramesInFlight(); i++) {
                    VkDescriptorBufferInfo bufferInfo{};
                    bufferInfo.buffer = uniformBuffers[i];
                    bufferInfo.offset = 0;
                    bufferInfo.range = sizeof(UniformBufferObject);
                    if (texture != nullptr) {
                        VkDescriptorImageInfo imageInfo{};
                        imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
                        imageInfo.imageView = texture->getImageView();
                        imageInfo.sampler = texture->getSampler();
                        std::array<VkWriteDescriptorSet, 2> descriptorWrites{};
    
                        descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
                        descriptorWrites[0].dstSet = descriptorSets[i];
                        descriptorWrites[0].dstBinding = 0;
                        descriptorWrites[0].dstArrayElement = 0;
                        descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
                        descriptorWrites[0].descriptorCount = 1;
                        descriptorWrites[0].pBufferInfo = &bufferInfo;
    
    
    
                        descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
                        descriptorWrites[1].dstSet = descriptorSets[i];
                        descriptorWrites[1].dstBinding = 1;
                        descriptorWrites[1].dstArrayElement = 0;
                        descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
                        descriptorWrites[1].descriptorCount = 1;
                        descriptorWrites[1].pImageInfo = &imageInfo;
    
                        vkUpdateDescriptorSets(vkSettup.getDevice(), static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
                    }  else {
                        std::array<VkWriteDescriptorSet, 1> descriptorWrites{};
    
                        descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
                        descriptorWrites[0].dstSet = descriptorSets[i];
                        descriptorWrites[0].dstBinding = 0;
                        descriptorWrites[0].dstArrayElement = 0;
                        descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
                        descriptorWrites[0].descriptorCount = 1;
                        descriptorWrites[0].pBufferInfo = &bufferInfo;
    
                        vkUpdateDescriptorSets(vkSettup.getDevice(), static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
                    }
                }
            }
            void RenderTarget::createGraphicPipeline(const Vertex* vertices, unsigned int vertexCount, sf::PrimitiveType type,
                          RenderStates states = RenderStates::Default) {
                VkShaderModule vertShaderModule;
                VkShaderModule fragShaderModule;
                if (states.texture != nullptr) {
                    defaultShader.createShaderModules();
                    vertShaderModule = defaultShader.getVertexShaderModule();
                    fragShaderModule = defaultShader.getFragmentShaderModule();
                } else {
                    defaultShader2.createShaderModules();
                    vertShaderModule = defaultShader2.getVertexShaderModule();
                    fragShaderModule = defaultShader2.getFragmentShaderModule();
                }
                VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
                vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
                vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
                vertShaderStageInfo.module = vertShaderModule;
                vertShaderStageInfo.pName = "main";
    
                VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
                fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
                fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
                fragShaderStageInfo.module = fragShaderModule;
                fragShaderStageInfo.pName = "main";
    
                VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
    
                VkPipelineVertexInputStateCreateInfo vertexInputInfo{};
                auto bindingDescription = Vertex::getBindingDescription();
                auto attributeDescriptions = Vertex::getAttributeDescriptions();
                vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
                vertexInputInfo.vertexBindingDescriptionCount = 1;
                vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
                vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
                vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
    
    
                VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
                inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
                inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
                inputAssembly.primitiveRestartEnable = VK_FALSE;
    
                VkViewport viewport{};
                viewport.x = 0.0f;
                viewport.y = 0.0f;
                viewport.width = getSwapchainExtents().width;
                viewport.height = getSwapchainExtents().height;
                viewport.minDepth = 0.0f;
                viewport.maxDepth = 1.0f;
    
                VkRect2D scissor{};
                scissor.offset = {0, 0};
                scissor.extent = getSwapchainExtents();
    
                VkPipelineViewportStateCreateInfo viewportState{};
                viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
                viewportState.viewportCount = 1;
                viewportState.pViewports = &viewport;
                viewportState.scissorCount = 1;
                viewportState.pScissors = &scissor;
    
                VkPipelineRasterizationStateCreateInfo rasterizer{};
                rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
                rasterizer.depthClampEnable = VK_FALSE;
                rasterizer.rasterizerDiscardEnable = VK_FALSE;
                rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
                rasterizer.lineWidth = 1.0f;
                rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
                rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
                rasterizer.depthBiasEnable = VK_FALSE;
    
                VkPipelineMultisampleStateCreateInfo multisampling{};
                multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
                multisampling.sampleShadingEnable = VK_FALSE;
                multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
    
                VkPipelineColorBlendAttachmentState colorBlendAttachment{};
                colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
                colorBlendAttachment.blendEnable = VK_FALSE;
    
                VkPipelineColorBlendStateCreateInfo colorBlending{};
                colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
                colorBlending.logicOpEnable = VK_FALSE;
                colorBlending.logicOp = VK_LOGIC_OP_COPY;
                colorBlending.attachmentCount = 1;
                colorBlending.pAttachments = &colorBlendAttachment;
                colorBlending.blendConstants[0] = 0.0f;
                colorBlending.blendConstants[1] = 0.0f;
                colorBlending.blendConstants[2] = 0.0f;
                colorBlending.blendConstants[3] = 0.0f;
    
                VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
                pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
                pipelineLayoutInfo.setLayoutCount = 1;
                pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
    
                if (vkCreatePipelineLayout(vkSettup.getDevice(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to create pipeline layout!", 1);
                }
                VkGraphicsPipelineCreateInfo pipelineInfo{};
                pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
                pipelineInfo.stageCount = 2;
                pipelineInfo.pStages = shaderStages;
                pipelineInfo.pVertexInputState = &vertexInputInfo;
                pipelineInfo.pInputAssemblyState = &inputAssembly;
                pipelineInfo.pViewportState = &viewportState;
                pipelineInfo.pRasterizationState = &rasterizer;
                pipelineInfo.pMultisampleState = &multisampling;
                pipelineInfo.pColorBlendState = &colorBlending;
                pipelineInfo.layout = pipelineLayout;
                pipelineInfo.renderPass = renderPass;
                pipelineInfo.subpass = 0;
                pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
    
                if (vkCreateGraphicsPipelines(vkSettup.getDevice(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to create graphics pipeline!", 1);
                }
                if (states.texture != nullptr)
                    defaultShader.cleanupShaderModules();
                else
                    defaultShader2.cleanupShaderModules();
            }
            void RenderTarget::createCommandPool() {
                window::VkSettup::QueueFamilyIndices queueFamilyIndices = vkSettup.findQueueFamilies(vkSettup.getPhysicalDevice(), getSurface());
    
                VkCommandPoolCreateInfo poolInfo{};
                poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
                poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
                poolInfo.flags = 0; // Optionel
                if (vkCreateCommandPool(vkSettup.getDevice(), &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
                    throw core::Erreur(0, "échec de la création d'une command pool!", 1);
                }
                vkSettup.setCommandPool(commandPool);
            }
            void RenderTarget::createUniformBuffers() {
                VkDeviceSize bufferSize = sizeof(UniformBufferObject);
    
                uniformBuffers.resize(getMaxFramesInFlight());
                uniformBuffersMemory.resize(getMaxFramesInFlight());
    
                for (size_t i = 0; i < getMaxFramesInFlight(); i++) {
                    createBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffers[i], uniformBuffersMemory[i]);
                }
    
            }
            void RenderTarget::updateUniformBuffer(uint32_t currentImage, UniformBufferObject ubo) {
                void* data;
                vkMapMemory(vkSettup.getDevice(), uniformBuffersMemory[currentImage], 0, sizeof(ubo), 0, &data);
                    memcpy(data, &ubo, sizeof(ubo));
                vkUnmapMemory(vkSettup.getDevice(), uniformBuffersMemory[currentImage]);
    
            }
            void RenderTarget::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) {
                VkBufferCreateInfo bufferInfo{};
                bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
                bufferInfo.size = size;
                bufferInfo.usage = usage;
                bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    
                if (vkCreateBuffer(vkSettup.getDevice(), &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
                    throw std::runtime_error("failed to create buffer!");
                }
    
                VkMemoryRequirements memRequirements;
                vkGetBufferMemoryRequirements(vkSettup.getDevice(), buffer, &memRequirements);
    
                VkMemoryAllocateInfo allocInfo{};
                allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
                allocInfo.allocationSize = memRequirements.size;
                allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
    
                if (vkAllocateMemory(vkSettup.getDevice(), &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
                    throw std::runtime_error("failed to allocate buffer memory!");
                }
    
                vkBindBufferMemory(vkSettup.getDevice(), buffer, bufferMemory, 0);
            }
            uint32_t RenderTarget::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
                VkPhysicalDeviceMemoryProperties memProperties;
                vkGetPhysicalDeviceMemoryProperties(vkSettup.getPhysicalDevice(), &memProperties);
                for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
                    if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
                        return i;
                    }
                }
                throw std::runtime_error("aucun type de memoire ne satisfait le buffer!");
            }
            void RenderTarget::createCommandBuffers() {
                commandBuffers.resize(swapChainFramebuffers.size());
    
                VkCommandBufferAllocateInfo allocInfo{};
                allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
                allocInfo.commandPool = commandPool;
                allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
                allocInfo.commandBufferCount = (uint32_t) commandBuffers.size();
    
                if (vkAllocateCommandBuffers(vkSettup.getDevice(), &allocInfo, commandBuffers.data()) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to allocate command buffers!", 1);
                }
    
                for (size_t i = 0; i < commandBuffers.size(); i++) {
                    VkCommandBufferBeginInfo beginInfo{};
                    beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    
                    if (vkBeginCommandBuffer(commandBuffers[i], &beginInfo) != VK_SUCCESS) {
                        throw core::Erreur(0, "failed to begin recording command buffer!", 1);
                    }
                    VkRenderPassBeginInfo renderPassInfo{};
                    renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
                    renderPassInfo.renderPass = renderPass;
                    renderPassInfo.framebuffer = swapChainFramebuffers[i];
                    renderPassInfo.renderArea.offset = {0, 0};
                    renderPassInfo.renderArea.extent = getSwapchainExtents();
    
                    VkClearValue clrColor = {clearColor.r / 255.f,clearColor.g / 255.f, clearColor.b / 255.f, clearColor.a / 255.f};
                    renderPassInfo.clearValueCount = 1;
                    renderPassInfo.pClearValues = &clrColor;
    
                    vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
                    vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
                    VkBuffer vertexBuffers[] = {vertexBuffer.getVertexBuffer()};
                    VkDeviceSize offsets[] = {0};
                    vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offsets);
                    vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[getCurrentFrame()], 0, nullptr);
    
                    if(vertexBuffer.getIndicesSize() > 0) {
                        vkCmdBindIndexBuffer(commandBuffers[i], vertexBuffer.getIndexBuffer(), 0, VK_INDEX_TYPE_UINT16);
                    }
                    if(vertexBuffer.getIndicesSize() > 0) {
                        vkCmdDrawIndexed(commandBuffers[i], static_cast<uint32_t>(vertexBuffer.getIndicesSize()), 1, 0, 0, 0);
                    } else {
                        vkCmdDraw(commandBuffers[i], static_cast<uint32_t>(vertexBuffer.getSize()), 1, 0, 0);
                    }
    
                    vkCmdEndRenderPass(commandBuffers[i]);
    
                    if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) {
                        throw core::Erreur(0, "failed to record command buffer!", 1);
                    }
    
                }
            }
            void RenderTarget::cleanup() {
                vkDestroyCommandPool(vkSettup.getDevice(), commandPool, nullptr);
                vkDestroyPipeline(vkSettup.getDevice(), graphicsPipeline, nullptr);
                vkDestroyPipelineLayout(vkSettup.getDevice(), pipelineLayout, nullptr);
                vkDestroyRenderPass(vkSettup.getDevice(), renderPass, nullptr);
                vkDestroyDescriptorSetLayout(vkSettup.getDevice(), descriptorSetLayout, nullptr);
                for (size_t i = 0; i < getSwapchainImages().size(); i++) {
                    vkDestroyBuffer(vkSettup.getDevice(), uniformBuffers[i], nullptr);
                    vkFreeMemory(vkSettup.getDevice(), uniformBuffersMemory[i], nullptr);
                }
                 vkDestroyDescriptorPool(vkSettup.getDevice(), descriptorPool, nullptr);
                 vkDestroyDescriptorSetLayout(vkSettup.getDevice(), descriptorSetLayout, nullptr);
                 vkDestroyRenderPass(vkSettup.getDevice(), renderPass, nullptr);
            }
            std::vector<VkCommandBuffer>& RenderTarget::getCommandBuffers() {
                return commandBuffers;
            }

    jusque là ça va le problème c'est la classe RenderTexture je sais pas comment faire pour le faire dessiner sur la texture j'ai fait comme ceci :

    RenderTexture::RenderTexture(window::VkSettup& vkSettup) : vkSettup(vkSettup), m_texture(vkSettup) {
            }
            bool RenderTexture::create(unsigned int width, unsigned int height) {
                m_texture.create(width, height);
                createFramebuffers();
                createRenderPass();
            }
            VkSurfaceKHR RenderTexture::getSurface() {
                return nullptr;
            }
            VkExtent2D RenderTexture::getSwapchainExtents() {
                VkExtent2D actualExtent = {
                    static_cast<uint32_t>(m_texture.getSize().x),
                    static_cast<uint32_t>(m_texture.getSize().y)
                };
                return actualExtent;
            }
            VkFormat RenderTexture::getSwapchainImageFormat() {
                return m_texture.getFormat();
            }
            std::vector<VkImage> RenderTexture::getSwapchainImages() {
                std::vector<VkImage> images;
                images.push_back(m_texture.getImage());
                return images;
            }
            size_t RenderTexture::getCurrentFrame() {
                return 0;
            }
            const int RenderTexture::getMaxFramesInFlight() {
                return 1;
            }
            const Texture& RenderTexture::getTexture() const {
                return m_texture;
            }
            void RenderTexture::createFramebuffers() {
                swapChainFramebuffers.resize(getSwapchainImages().size());
    
                for (size_t i = 0; i < getSwapchainImages().size(); i++) {
                    VkImageView attachments[] = {
                        m_texture.getImageView()
                    };
    
                    VkFramebufferCreateInfo framebufferInfo{};
                    framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
                    framebufferInfo.renderPass = renderPass;
                    framebufferInfo.attachmentCount = 1;
                    framebufferInfo.pAttachments = attachments;
                    framebufferInfo.width = getSwapchainExtents().width;
                    framebufferInfo.height = getSwapchainExtents().height;
                    framebufferInfo.layers = 1;
    
                    if (vkCreateFramebuffer(vkSettup.getDevice(), &framebufferInfo, nullptr, &swapChainFramebuffers[i]) != VK_SUCCESS) {
                        throw core::Erreur(0, "failed to create framebuffer!", 1);
                    }
                }
            }
            void RenderTexture::createRenderPass() {
                VkAttachmentDescription colorAttachment{};
                colorAttachment.format =    getSwapchainImageFormat();
                colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
                colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
                colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
                colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
                colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
                colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
                colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
    
                VkAttachmentReference colorAttachmentRef{};
                colorAttachmentRef.attachment = 0;
                colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    
                VkSubpassDescription subpass{};
                subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
                subpass.colorAttachmentCount = 1;
                subpass.pColorAttachments = &colorAttachmentRef;
    
                VkRenderPassCreateInfo renderPassInfo{};
                renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
                renderPassInfo.attachmentCount = 1;
                renderPassInfo.pAttachments = &colorAttachment;
                renderPassInfo.subpassCount = 1;
                renderPassInfo.pSubpasses = &subpass;
                VkSubpassDependency dependency{};
                dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
                dependency.dstSubpass = 0;
                dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
                dependency.srcAccessMask = 0;
                dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
                dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
                renderPassInfo.dependencyCount = 1;
                renderPassInfo.pDependencies = &dependency;
                if (vkCreateRenderPass(vkSettup.getDevice(), &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to create render pass!", 1);
                }
    
            }

    Mais je sais pas quoi mettre pour faire comme dans la méthode drawVulkanFrame de la classe RenderWindow pour dessiner sur la texture.

    Merci. :)



    • Partager sur Facebook
    • Partager sur Twitter
      2 mai 2024 à 13:48:03

      Salut !

      J'ai la flemme de lire ton mur de code, dont je suis certain que 90% n'ont aucun lien avec ta question, ni aucun lien avec une réponse possible.
      De plus, tu parles d'une méthode drawVulkanFrame de la classe RenderWindow, hors malgré tout ce que tu as mis, elle n'y est pas...

      Donc tu vas exprimer, avec des mots (et pas du code), ce que cette fonction fait dans RenderWindow, et ta problématique...

      • Partager sur Facebook
      • Partager sur Twitter

      Si vous ne trouvez plus rien, cherchez autre chose.

        2 mai 2024 à 19:49:29

        Salut!

        je parlais de cette fonction-ci :

        void RenderWindow::drawVulkanFrame() {
            if (getCommandBuffers().size() > 0) {
                vkWaitForFences(vkSettup.getDevice(), 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
                uint32_t imageIndex;
                vkAcquireNextImageKHR(vkSettup.getDevice(), swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
                // Vérifier si une frame précédente est en train d'utiliser cette image (il y a une fence à attendre)
                if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
                    vkWaitForFences(vkSettup.getDevice(), 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
                }
                 // Marque l'image comme étant à nouveau utilisée par cette frame
                imagesInFlight[imageIndex] = inFlightFences[currentFrame];
         
                VkSubmitInfo submitInfo{};
                submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
         
                VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame]};
                VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
                submitInfo.waitSemaphoreCount = 1;
                submitInfo.pWaitSemaphores = waitSemaphores;
                submitInfo.pWaitDstStageMask = waitStages;
                submitInfo.commandBufferCount = 1;
                submitInfo.pCommandBuffers = &getCommandBuffers()[imageIndex];
                VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
                submitInfo.signalSemaphoreCount = 1;
                submitInfo.pSignalSemaphores = signalSemaphores;
                vkResetFences(vkSettup.getDevice(), 1, &inFlightFences[currentFrame]);
                if (vkQueueSubmit(vkSettup.getGraphicQueue(), 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
                    throw core::Erreur(0, "échec de l'envoi d'un command buffer!", 1);
                }
                VkPresentInfoKHR presentInfo{};
                presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
         
                presentInfo.waitSemaphoreCount = 1;
                presentInfo.pWaitSemaphores = signalSemaphores;
                VkSwapchainKHR swapChains[] = {swapChain};
                presentInfo.swapchainCount = 1;
                presentInfo.pSwapchains = swapChains;
                presentInfo.pImageIndices = &imageIndex;
                presentInfo.pResults = nullptr; // Optionnel
                vkQueuePresentKHR(vkSettup.getPresentQueue(), &presentInfo);
                currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
                vkDeviceWaitIdle(vkSettup.getDevice());
            }
        }

        je dois mettre quoi dans la classe RenderTexture pour dessiner la frame sachant qu'il n'y a pas de swapchain je dois dessiner sur une image.

        -
        Edité par OmbreNoire 2 mai 2024 à 19:51:51

        • Partager sur Facebook
        • Partager sur Twitter
          3 mai 2024 à 8:03:36

          Ben tu fais le submit mais pas le present
          • Partager sur Facebook
          • Partager sur Twitter

          Si vous ne trouvez plus rien, cherchez autre chose.

          [Vulkan] question

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          • Editeur
          • Markdown