#include "first_app.hpp" #include #include namespace cve { FirstApp::FirstApp() { loadModels(); createPipelineLayout(); createPipeline(); createCommandBuffers(); } FirstApp::~FirstApp() { vkDestroyPipelineLayout(cveDevice.device(), pipelineLayout, nullptr); } void FirstApp::run() { while (!cveWindow.shouldClose()) { glfwPollEvents(); drawFrame(); } vkDeviceWaitIdle(cveDevice.device()); } void FirstApp::loadModels() { std::vector verticies { {{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}}, {{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}}, {{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}} }; cveModel = std::make_unique(cveDevice, verticies); } void FirstApp::createPipelineLayout() { VkPipelineLayoutCreateInfo pipelineLayoutInfo{}; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.setLayoutCount = 0; pipelineLayoutInfo.pSetLayouts = nullptr; pipelineLayoutInfo.pushConstantRangeCount = 0; pipelineLayoutInfo.pPushConstantRanges = nullptr; if (vkCreatePipelineLayout(cveDevice.device(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) { throw std::runtime_error("Failed to create pipeline layout"); } } void FirstApp::createPipeline() { auto pipelineConfig = CvePipeline::defaultPipelineConfigInfo(cveSwapChain.width(), cveSwapChain.height()); pipelineConfig.renderPass = cveSwapChain.getRenderPass(); pipelineConfig.pipelineLayout = pipelineLayout; cvePipeline = std::make_unique( cveDevice, "shaders/simple_shader.vert.spv", "shaders/simple_shader.frag.spv", pipelineConfig ); } void FirstApp::createCommandBuffers() { commandBuffers.resize(cveSwapChain.imageCount()); VkCommandBufferAllocateInfo allocInfo{}; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.commandPool = cveDevice.getCommandPool(); allocInfo.commandBufferCount = static_cast(commandBuffers.size()); if (vkAllocateCommandBuffers(cveDevice.device(), &allocInfo, commandBuffers.data()) != VK_SUCCESS) { throw std::runtime_error("Failed to allocate command buffers"); } for (int 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 std::runtime_error("Failed to begin command buffer recording"); } VkRenderPassBeginInfo renderPassInfo{}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassInfo.renderPass = cveSwapChain.getRenderPass(); renderPassInfo.framebuffer = cveSwapChain.getFrameBuffer(i); renderPassInfo.renderArea.offset = {0, 0}; renderPassInfo.renderArea.extent = cveSwapChain.getSwapChainExtent(); std::array clearValues{}; clearValues[0].color = {0.1f, 0.1f, 0.1f, 1.0f}; clearValues[1].depthStencil = {1.0f, 0}; renderPassInfo.clearValueCount = static_cast(clearValues.size()); renderPassInfo.pClearValues = clearValues.data(); vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); cvePipeline->bind(commandBuffers[i]); cveModel->bind(commandBuffers[i]); cveModel->draw(commandBuffers[i]); vkCmdEndRenderPass(commandBuffers[i]); if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) { throw std::runtime_error("Failed to record command buffer!"); } } } void FirstApp::drawFrame() { uint32_t imageIndex; auto result = cveSwapChain.acquireNextImage(&imageIndex); if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { throw std::runtime_error("Failed to acquire swap chain image!"); } result = cveSwapChain.submitCommandBuffers(&commandBuffers[imageIndex], &imageIndex); if (result != VK_SUCCESS) { throw std::runtime_error("Failed to present swap chain image!"); } } }