Fix windows compilation

This commit is contained in:
bailwillharr 2023-02-19 13:55:08 +00:00
parent 05cceb7abe
commit 7c0b286e13
11 changed files with 120 additions and 39 deletions

View File

@ -2,6 +2,8 @@
#include "resource_manager.hpp" #include "resource_manager.hpp"
#include "gfx.hpp"
#include <memory> #include <memory>
#include <string> #include <string>
#include <filesystem> #include <filesystem>
@ -23,7 +25,7 @@ namespace engine {
class Application { class Application {
public: public:
Application(const char* appName, const char* appVersion); Application(const char* appName, const char* appVersion, gfx::GraphicsSettings graphicsSettings);
~Application(); ~Application();
Application(const Application&) = delete; Application(const Application&) = delete;
Application& operator=(const Application&) = delete; Application& operator=(const Application&) = delete;

View File

@ -3,8 +3,32 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
// Enums and structs for the graphics abstraction
namespace engine::gfx { namespace engine::gfx {
enum class MSAALevel {
MSAA_OFF,
MSAA_2X,
MSAA_4X,
MSAA_8X,
MSAA_16X,
};
struct GraphicsSettings {
GraphicsSettings()
{
// sane defaults
vsync = false;
msaaLevel = MSAALevel::MSAA_OFF;
}
bool vsync;
MSAALevel msaaLevel;
};
enum class ShaderType { enum class ShaderType {
VERTEX, VERTEX,
FRAGMENT, FRAGMENT,

View File

@ -11,7 +11,7 @@ namespace engine {
class GFXDevice { class GFXDevice {
public: public:
GFXDevice(const char* appName, const char* appVersion, SDL_Window* window, bool vsync = false); GFXDevice(const char* appName, const char* appVersion, SDL_Window* window, gfx::GraphicsSettings settings);
GFXDevice(const GFXDevice&) = delete; GFXDevice(const GFXDevice&) = delete;
GFXDevice& operator=(const GFXDevice&) = delete; GFXDevice& operator=(const GFXDevice&) = delete;

View File

@ -27,8 +27,10 @@ namespace engine {
std::vector<spdlog::sink_ptr> sinks; std::vector<spdlog::sink_ptr> sinks;
sinks.emplace_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_path.string(), true)); sinks.emplace_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_path.string(), true));
sinks.back()->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v");
sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
sinks.back()->set_pattern("[%H:%M:%S.%e] [%l] %v");
auto logger = std::make_shared<spdlog::logger>(appName, sinks.begin(), sinks.end()); auto logger = std::make_shared<spdlog::logger>(appName, sinks.begin(), sinks.end());
@ -36,6 +38,7 @@ namespace engine {
spdlog::register_logger(logger); spdlog::register_logger(logger);
spdlog::set_default_logger(logger); spdlog::set_default_logger(logger);
spdlog::flush_every(std::chrono::seconds(60));
INFO("Created log with path: {}", log_path.string()); INFO("Created log with path: {}", log_path.string());

View File

@ -23,8 +23,8 @@ namespace engine {
// only uses transform component, which is required for all entities anyway // only uses transform component, which is required for all entities anyway
uint32_t camEntity = 0; uint32_t camEntity = 0;
float verticalFovDegrees = 70.0f; float verticalFovDegrees = 70.0f;
float clipNear = 0.1f; float clipNear = 0.5f;
float clipFar = 1000.0f; float clipFar = 10000.0f;
} m_camera; } m_camera;
float m_viewportAspectRatio = 1.0f; float m_viewportAspectRatio = 1.0f;

View File

@ -26,6 +26,6 @@ void main() {
fragNorm = mat3(transpose(inverse(constants.view * constants.model))) * inNorm; fragNorm = mat3(transpose(inverse(constants.view * constants.model))) * inNorm;
fragUV = inUV; fragUV = inUV;
vec3 lightPos = vec3(-10.0, 10.0, 10.0); vec3 lightPos = vec3(2000.0, 2000.0, -2000.0);
fragLightPos = vec3(constants.view * vec4(lightPos, 1.0)); fragLightPos = vec3(constants.view * vec4(lightPos, 1.0));
} }

View File

@ -56,10 +56,10 @@ static std::filesystem::path getResourcesPath()
namespace engine { namespace engine {
Application::Application(const char* appName, const char* appVersion) Application::Application(const char* appName, const char* appVersion, gfx::GraphicsSettings graphicsSettings)
{ {
m_window = std::make_unique<Window>(appName, true, false); m_window = std::make_unique<Window>(appName, true, false);
m_gfx = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle()); m_gfx = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle(), graphicsSettings);
m_inputManager = std::make_unique<InputManager>(window()); m_inputManager = std::make_unique<InputManager>(window());
m_sceneManager = std::make_unique<SceneManager>(this); m_sceneManager = std::make_unique<SceneManager>(this);

View File

@ -173,6 +173,29 @@ namespace engine {
throw std::runtime_error("Unknown texture filter"); throw std::runtime_error("Unknown texture filter");
} }
static VkSampleCountFlags getSampleCountFlags(gfx::MSAALevel level)
{
switch (level) {
case gfx::MSAALevel::MSAA_OFF:
return VK_SAMPLE_COUNT_1_BIT;
break;
case gfx::MSAALevel::MSAA_2X:
return VK_SAMPLE_COUNT_2_BIT;
break;
case gfx::MSAALevel::MSAA_4X:
return VK_SAMPLE_COUNT_4_BIT;
break;
case gfx::MSAALevel::MSAA_8X:
return VK_SAMPLE_COUNT_8_BIT;
break;
case gfx::MSAALevel::MSAA_16X:
return VK_SAMPLE_COUNT_16_BIT;
break;
default:
throw std::runtime_error("Unknown MSAA level");
}
}
} }
// functions // functions
@ -486,13 +509,14 @@ namespace engine {
vmaDestroyImage(allocator, db.image, db.allocation); vmaDestroyImage(allocator, db.image, db.allocation);
} }
static VkSampleCountFlagBits getMaxSampleCount(VkPhysicalDevice physicalDevice) static VkSampleCountFlagBits getMaxSampleCount(VkPhysicalDevice physicalDevice, gfx::MSAALevel maxLevel)
{ {
VkSampleCountFlags max = vkinternal::getSampleCountFlags(maxLevel);
VkPhysicalDeviceProperties physicalDeviceProperties; VkPhysicalDeviceProperties physicalDeviceProperties;
vkGetPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties); vkGetPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
VkSampleCountFlags counts = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts; VkSampleCountFlags counts = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts;
counts %= VK_SAMPLE_COUNT_4_BIT; // restricts it to 2 or 1 (0b11) counts %= (max << 1); // restricts sample count to maxLevel
if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; } if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; }
if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; } if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; }
if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; } if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; }
@ -503,7 +527,7 @@ namespace engine {
} }
// This is called not just on initialisation, but also when the window is resized. // This is called not just on initialisation, but also when the window is resized.
static void createSwapchain(VkDevice device, VkPhysicalDevice physicalDevice, VmaAllocator allocator, std::vector<Queue> queues, SDL_Window* window, VkSurfaceKHR surface, bool vsync, bool useMSAA, Swapchain* swapchain) static void createSwapchain(VkDevice device, VkPhysicalDevice physicalDevice, VmaAllocator allocator, std::vector<Queue> queues, SDL_Window* window, VkSurfaceKHR surface, gfx::GraphicsSettings settings, Swapchain* swapchain)
{ {
[[maybe_unused]] VkResult res; [[maybe_unused]] VkResult res;
@ -574,7 +598,7 @@ namespace engine {
} }
swapchain->presentMode = VK_PRESENT_MODE_FIFO_KHR; // This mode is always available swapchain->presentMode = VK_PRESENT_MODE_FIFO_KHR; // This mode is always available
if (vsync == false) { if (settings.vsync == false) {
for (const auto& presMode : presentModes) { for (const auto& presMode : presentModes) {
if (presMode == VK_PRESENT_MODE_MAILBOX_KHR) { if (presMode == VK_PRESENT_MODE_MAILBOX_KHR) {
swapchain->presentMode = presMode; // this mode allows uncapped FPS while also avoiding screen tearing swapchain->presentMode = presMode; // this mode allows uncapped FPS while also avoiding screen tearing
@ -636,11 +660,13 @@ namespace engine {
assert(res == VK_SUCCESS); assert(res == VK_SUCCESS);
// Use multisample anti-aliasing // Use multisample anti-aliasing
if (useMSAA) if (settings.msaaLevel != gfx::MSAALevel::MSAA_OFF)
swapchain->msaaSamples = getMaxSampleCount(physicalDevice); swapchain->msaaSamples = getMaxSampleCount(physicalDevice, settings.msaaLevel);
else else
swapchain->msaaSamples = VK_SAMPLE_COUNT_1_BIT; swapchain->msaaSamples = VK_SAMPLE_COUNT_1_BIT;
INFO("Multisampling mode: {}", swapchain->msaaSamples == VK_SAMPLE_COUNT_1_BIT ? "OFF" : std::to_string(swapchain->msaaSamples) + "x");
// create depth buffer if old depth buffer is wrong size. // create depth buffer if old depth buffer is wrong size.
// Also do the same for the MSAA buffer. // Also do the same for the MSAA buffer.
if (swapchain->swapchain == VK_NULL_HANDLE) { if (swapchain->swapchain == VK_NULL_HANDLE) {
@ -678,10 +704,10 @@ namespace engine {
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
if (useMSAA) { if (swapchain->msaaSamples == VK_SAMPLE_COUNT_1_BIT) {
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
} else {
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
} else {
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
} }
colorAttachmentRef.attachment = 0; colorAttachmentRef.attachment = 0;
@ -718,10 +744,10 @@ namespace engine {
subpass.colorAttachmentCount = 1; subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef; subpass.pColorAttachments = &colorAttachmentRef;
subpass.pDepthStencilAttachment = &depthAttachmentRef; subpass.pDepthStencilAttachment = &depthAttachmentRef;
if (useMSAA) { if (swapchain->msaaSamples == VK_SAMPLE_COUNT_1_BIT) {
subpass.pResolveAttachments = &colorAttachmentResolveRef;
} else {
subpass.pResolveAttachments = nullptr; subpass.pResolveAttachments = nullptr;
} else {
subpass.pResolveAttachments = &colorAttachmentResolveRef;
} }
VkSubpassDependency dependency{}; VkSubpassDependency dependency{};
@ -736,10 +762,10 @@ namespace engine {
VkRenderPassCreateInfo createInfo{}; VkRenderPassCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
if (useMSAA) { if (swapchain->msaaSamples == VK_SAMPLE_COUNT_1_BIT) {
createInfo.attachmentCount = 3;
} else {
createInfo.attachmentCount = 2; createInfo.attachmentCount = 2;
} else {
createInfo.attachmentCount = 3;
} }
createInfo.pAttachments = attachments.data(); createInfo.pAttachments = attachments.data();
createInfo.subpassCount = 1; createInfo.subpassCount = 1;
@ -783,11 +809,11 @@ namespace engine {
VkFramebufferCreateInfo framebufferInfo{}; VkFramebufferCreateInfo framebufferInfo{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = swapchain->renderpass; framebufferInfo.renderPass = swapchain->renderpass;
if (useMSAA) { if (swapchain->msaaSamples == VK_SAMPLE_COUNT_1_BIT) {
framebufferInfo.attachmentCount = 3;
} else {
attachments[0] = swapchain->imageViews[i]; attachments[0] = swapchain->imageViews[i];
framebufferInfo.attachmentCount = 2; framebufferInfo.attachmentCount = 2;
} else {
framebufferInfo.attachmentCount = 3;
} }
framebufferInfo.pAttachments = attachments.data(); framebufferInfo.pAttachments = attachments.data();
framebufferInfo.width = swapchain->extent.width; framebufferInfo.width = swapchain->extent.width;
@ -1044,7 +1070,9 @@ namespace engine {
VmaAllocator allocator = nullptr; VmaAllocator allocator = nullptr;
// device settings // device settings
bool vsync = false; gfx::GraphicsSettings graphicsSettings;
// device properties/limits
float maxSamplerAnisotropy; float maxSamplerAnisotropy;
// render loop // render loop
@ -1059,7 +1087,7 @@ namespace engine {
}; };
GFXDevice::GFXDevice(const char* appName, const char* appVersion, SDL_Window* window, bool vsync) GFXDevice::GFXDevice(const char* appName, const char* appVersion, SDL_Window* window, gfx::GraphicsSettings settings)
{ {
pimpl = std::make_unique<Impl>(); pimpl = std::make_unique<Impl>();
@ -1067,7 +1095,7 @@ namespace engine {
VkResult res; VkResult res;
pimpl->window = window; pimpl->window = window;
pimpl->vsync = vsync; pimpl->graphicsSettings = settings;
// initialise vulkan // initialise vulkan
@ -1458,7 +1486,7 @@ namespace engine {
// Now make the swapchain // Now make the swapchain
createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, window, pimpl->surface, pimpl->vsync, false, &pimpl->swapchain); createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, window, pimpl->surface, pimpl->graphicsSettings, &pimpl->swapchain);
@ -1587,7 +1615,7 @@ namespace engine {
if (res == VK_ERROR_OUT_OF_DATE_KHR) { if (res == VK_ERROR_OUT_OF_DATE_KHR) {
// recreate swapchain // recreate swapchain
waitIdle(); waitIdle();
createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, pimpl->window, pimpl->surface, pimpl->vsync, false, &pimpl->swapchain); createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, pimpl->window, pimpl->surface, pimpl->graphicsSettings, &pimpl->swapchain);
return; return;
} }
else { else {
@ -1720,7 +1748,7 @@ namespace engine {
if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) { if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) {
// recreate swapchain // recreate swapchain
waitIdle(); waitIdle();
createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, pimpl->window, pimpl->surface, pimpl->vsync, false, &pimpl->swapchain); createSwapchain(pimpl->device, pimpl->physicalDevice, pimpl->allocator, pimpl->queues, pimpl->window, pimpl->surface, pimpl->graphicsSettings, &pimpl->swapchain);
} }
else { else {
assert(res == VK_SUCCESS); assert(res == VK_SUCCESS);

View File

@ -7,6 +7,8 @@
#include "log.hpp" #include "log.hpp"
#include <array>
namespace engine { namespace engine {
// static functions // static functions

View File

@ -115,7 +115,7 @@ void CameraControllerSystem::onUpdate(float ts)
t->position += hVel * dt; t->position += hVel * dt;
t->position.y += c->dy * dt; t->position.y += c->dy * dt;
constexpr float MAX_DISTANCE_FROM_ORIGIN = 1000.0f; constexpr float MAX_DISTANCE_FROM_ORIGIN = 10000.0f;
if (glm::length(t->position) > MAX_DISTANCE_FROM_ORIGIN) { if (glm::length(t->position) > MAX_DISTANCE_FROM_ORIGIN) {
t->position = { 0.0f, 5.0f, 0.0f }; t->position = { 0.0f, 5.0f, 0.0f };

View File

@ -40,7 +40,10 @@ static void configureInputs(engine::InputManager* inputManager)
void playGame(bool enableFrameLimiter) void playGame(bool enableFrameLimiter)
{ {
engine::Application app(PROJECT_NAME, PROJECT_VERSION); engine::gfx::GraphicsSettings graphicsSettings{};
graphicsSettings.vsync = false;
graphicsSettings.msaaLevel = engine::gfx::MSAALevel::MSAA_16X;
engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphicsSettings);
app.setFrameLimiter(enableFrameLimiter); app.setFrameLimiter(enableFrameLimiter);
@ -67,7 +70,8 @@ void playGame(bool enableFrameLimiter)
engine::EventSubscriberKind::ENTITY, camera, myScene->getSystem<CameraControllerSystem>() engine::EventSubscriberKind::ENTITY, camera, myScene->getSystem<CameraControllerSystem>()
); );
myScene->getSystem<engine::RenderSystem>()->setCameraEntity(camera); auto renderSystem = myScene->getSystem<engine::RenderSystem>();
renderSystem->setCameraEntity(camera);
} }
/* shared resources */ /* shared resources */
@ -113,21 +117,34 @@ void playGame(bool enableFrameLimiter)
enemyCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f } }; // A box enclosing the sphere enemyCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 10.0f, 10.0f, 10.0f } }; // A box enclosing the sphere
} }
/* sun */
{
uint32_t sun = myScene->createEntity("sun");
auto sunRenderable = myScene->addComponent<engine::RenderableComponent>(sun);
sunRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.textured"));
sunRenderable->material->m_texture = app.getResource<engine::resources::Texture>("engine.white");
sunRenderable->mesh = genSphereMesh(app.gfx(), 500.0f, 32, false, true);
auto sunTransform = myScene->getComponent<engine::TransformComponent>(sun);
sunTransform->position.x = 2000.0f;
sunTransform->position.y = 2000.0f;
sunTransform->position.z = -2000.0f;
}
/* floor */ /* floor */
{ {
uint32_t floor = myScene->createEntity("floor"); uint32_t floor = myScene->createEntity("floor");
myScene->getComponent<engine::TransformComponent>(floor)->position = glm::vec3{-50.0f, -0.1f, -50.0f}; myScene->getComponent<engine::TransformComponent>(floor)->position = glm::vec3{-5000.0f, -1.0f, -5000.0f};
auto floorRenderable = myScene->addComponent<engine::RenderableComponent>(floor); auto floorRenderable = myScene->addComponent<engine::RenderableComponent>(floor);
floorRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.textured")); floorRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("engine.textured"));
floorRenderable->material->m_texture = grassTexture; floorRenderable->material->m_texture = grassTexture;
floorRenderable->mesh = genCuboidMesh(app.gfx(), 100.0f, 0.1f, 100.0f, 128.0f); floorRenderable->mesh = genCuboidMesh(app.gfx(), 10000.0f, 1.0f, 10000.0f, 5000.0f);
auto floorCollider = myScene->addComponent<engine::ColliderComponent>(floor); auto floorCollider = myScene->addComponent<engine::ColliderComponent>(floor);
floorCollider->isStatic = true; floorCollider->isStatic = true;
floorCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 100.0f, 0.1f, 100.0f } }; floorCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 10000.0f, 1.0f, 10000.0f } };
} }
// cubes! // cubes!
if (0) { {
constexpr int SIZE = 10; constexpr int SIZE = 10;
const uint32_t cubeParent = myScene->createEntity("cubeParent"); const uint32_t cubeParent = myScene->createEntity("cubeParent");
@ -147,6 +164,11 @@ void playGame(bool enableFrameLimiter)
auto transform = myScene->getComponent<engine::TransformComponent>(cube); auto transform = myScene->getComponent<engine::TransformComponent>(cube);
auto renderable = myScene->addComponent<engine::RenderableComponent>(cube); auto renderable = myScene->addComponent<engine::RenderableComponent>(cube);
auto collider = myScene->addComponent<engine::ColliderComponent>(cube);
collider->aabb.pos1 = { 0.0f, 0.0f, 0.0f };
collider->aabb.pos2 = { 10.0f, 10.0f, 10.0f };
collider->isStatic = true;
collider->isTrigger = false;
transform->position = { (float)x, (float)y, (float)z }; transform->position = { (float)x, (float)y, (float)z };
renderable->mesh = cubeMesh; renderable->mesh = cubeMesh;