stories/engine/engine.cpp

119 lines
3.2 KiB
C++

#include "engine.h"
Engine::Engine::Engine() :
initialized(false),
window(new Window()),
instance(new Instance()),
surface(nullptr),
physicalDevice(nullptr),
logicalDevice(nullptr),
deviceExtensionNames(),
deviceExtensions()
{
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<std::set<std::string>::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::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");
logicalDevice->createSwapChain();
}
void Engine::Engine::cleanup() {
delete logicalDevice;
logicalDevice = nullptr;
delete physicalDevice;
physicalDevice = nullptr;
delete surface;
surface = nullptr;
instance->deinitialize();
}
void Engine::Engine::pickPhysicalDevice() {
std::vector<VkPhysicalDevice> 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;
}
}