#include "engine.h" Engine::Engine::Engine() : initialized(false), window(new Window()), instance(new Instance()), surface(nullptr), physicalDevice(nullptr), logicalDevice(nullptr), deviceExtensionNames(), deviceExtensions(), programs() { addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); } Engine::Engine::~Engine() { delete instance; delete window; } void Engine::Engine::addDeviceExtension(const std::string& extensionName) { if (initialized) throw std::runtime_error("Adding extension to an initialized engine is not supported yet"); std::pair::const_iterator, bool> pair = deviceExtensionNames.insert(extensionName); if (pair.second) deviceExtensions.push_back(pair.first->c_str()); } void Engine::Engine::enableDebug() { instance->enableDebug(); } void Engine::Engine::addProgram(const Program& program) { programs.emplace_back(program); if (logicalDevice != nullptr) logicalDevice->addProgram(program); } void Engine::Engine::initVulkan() { instance->initialize(window->getRequiredVulkanExtensions()); surface = new Surface(instance, window); pickPhysicalDevice(); logicalDevice = new LogicalDevice(physicalDevice, surface, deviceExtensions, instance->getLayers()); //logicalDevice->createGraphicsPipeline("shaders/shader.vert.spv", "shaders/shader.frag.spv"); for (const Program& program : programs) logicalDevice->addProgram(program); logicalDevice->createSwapChain(); } void Engine::Engine::cleanup() { delete logicalDevice; logicalDevice = nullptr; delete physicalDevice; physicalDevice = nullptr; delete surface; surface = nullptr; instance->deinitialize(); programs.clear(); } void Engine::Engine::pickPhysicalDevice() { std::vector devices = instance->enumeratePhysicalDevices(); if (devices.size() == 0) throw std::runtime_error("failed to find GPUs with Vulkan support!"); for (const auto& device : devices) { if (PhysicalDevice::checkDeviceExtensionSupport(device, deviceExtensionNames)) { QueueFamilyIndices indices = surface->findQueueFamilies(device); if (indices.isComplete()) { SwapChainSupportDetails scsd = surface->querySwapChainSupport(device); if (scsd.adequate()) { physicalDevice = new PhysicalDevice(device, indices, scsd); break; } } } } if (physicalDevice == nullptr) throw std::runtime_error("failed to find a suitable GPU!"); } void Engine::Engine::run() { initVulkan(); mainLoop(); cleanup(); } void Engine::Engine::mainLoop() { SDL_Event e; bool bQuit = false; //main loop while (!bQuit) { //Handle events on queue while (SDL_PollEvent(&e) != 0) { //close the window when user clicks the X button or alt-f4s switch (e.type) { case SDL_QUIT: bQuit = true; break; case SDL_WINDOWEVENT: handleWindowEvent(e.window); break; } } logicalDevice->drawFrame(); } logicalDevice->waitIdle(); } void Engine::Engine::handleWindowEvent(const SDL_WindowEvent& e) { switch (e.event) { case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_SIZE_CHANGED: logicalDevice->setResized(); break; } }