first release

This commit is contained in:
2019-10-14 23:02:51 +02:00
commit 542ef348ee
72 changed files with 5990 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
#pragma once
#include <stdint.h>
#include <algorithm>
namespace openVulkanoCpp
{
class EngineConfiguration
{
private:
EngineConfiguration() = default;
~EngineConfiguration() = default;
uint32_t numThreads = 1;
public:
static EngineConfiguration* GetEngineConfiguration()
{
static EngineConfiguration* config = new EngineConfiguration();
return config;
}
void SetNumThreads(uint32_t numThreads)
{
this->numThreads = numThreads;
}
uint32_t GetNumThreads() const
{
return std::max(static_cast<uint32_t>(1), numThreads);
}
};
}

View File

@@ -0,0 +1,31 @@
#pragma once
#include <string>
#include <spdlog/fmt/fmt.h> //TODO replace with external fmt
namespace openVulkanoCpp
{
#define MAKE_VERSION(major, minor, patch) (((major) << 22) | ((minor) << 12) | (patch))
const char* ENGINE_NAME = "openVulkanoCpp";
struct EngineVersion
{
int major, minor, patch;
int intVersion;
std::string stringVersion;
EngineVersion(int major, int minor, int patch, int build = 0) : major(major), minor(minor), patch(patch)
{
intVersion = ((major) << 24) | ((minor) << 16) | (patch);
std::string buildConfig = "";
#ifdef _DEBUG
buildConfig += "-MSVC_DEBUG";
#elif DEBUG
buildConfig += "-DEBUG";
#endif
stringVersion = fmt::format("v{0}.{1}.{2}.{3}{4}", major, minor, patch, build, buildConfig);
}
};
const EngineVersion ENGINE_VERSION(0, 0, 1);
}

View File

@@ -0,0 +1,12 @@
#pragma once
namespace openVulkanoCpp
{
class ICloseable
{
public:
virtual ~ICloseable() = default;
virtual void Close() = 0;
};
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include <string>
#include "IInitable.hpp"
#include "ITickable.hpp"
#include "ICloseable.hpp"
namespace openVulkanoCpp
{
class IGraphicsAppManager;
class IGraphicsApp : public IInitable, public ITickable, public ICloseable
{
private:
IGraphicsAppManager* manager = nullptr;
public:
virtual ~IGraphicsApp() = default;
IGraphicsAppManager* GetGraphicsAppManager() const { return manager; }
void SetGraphicsAppManager(IGraphicsAppManager* manager) { this->manager = manager; }
virtual std::string GetAppName() = 0;
virtual std::string GetAppVersion() = 0;
virtual int GetAppVersionAsInt() = 0;
};
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include <cstdint>
#include "PlatformEnums.hpp"
namespace openVulkanoCpp
{
class IWindow;
class IGraphicsApp;
class IRenderer;
class IGraphicsAppManager
{
public:
virtual ~IGraphicsAppManager() = default;
virtual RenderAPI::RenderApi GetRenderApi() const = 0;
virtual IGraphicsApp* GetGraphicsApp() const = 0;
virtual IRenderer* GetRenderer() const = 0;
virtual bool IsRunning() const = 0;
virtual bool IsPaused() const = 0;
virtual void Stop() = 0;
virtual void Run() = 0;
virtual void Pause() = 0;
virtual void Resume() = 0;
virtual float GetAvgFrameTime() const = 0;
virtual float GetAvgFps() const = 0;
virtual uint64_t GetFrameCount() const = 0;
};
}

View File

@@ -0,0 +1,12 @@
#pragma once
namespace openVulkanoCpp
{
class IInitable
{
public:
virtual ~IInitable() = default;
virtual void Init() = 0;
};
}

View File

@@ -0,0 +1,12 @@
#pragma once
namespace openVulkanoCpp
{
class ITickable
{
public:
virtual ~ITickable() = default;
virtual void Tick() = 0;
};
}

View File

@@ -0,0 +1,13 @@
#include "Logger.hpp"
namespace openVulkanoCpp
{
std::vector<spdlog::sink_ptr> Logger::sinks;
std::shared_ptr<spdlog::logger> Logger::WINDOW = nullptr;
std::shared_ptr<spdlog::logger> Logger::MANAGER = nullptr;
std::shared_ptr<spdlog::logger> Logger::RENDER = nullptr;
std::shared_ptr<spdlog::logger> Logger::PHYSIC = nullptr;
std::shared_ptr<spdlog::logger> Logger::AUDIO = nullptr;
std::shared_ptr<spdlog::logger> Logger::DATA = nullptr;
std::shared_ptr<spdlog::logger> Logger::SCENE = nullptr;
}

View File

@@ -0,0 +1,95 @@
#pragma once
#define SPDLOG_DEBUG_ON
#define SPDLOG_TRACE_ON
#include <iostream>
#include <filesystem>
#include <spdlog/spdlog.h>
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#ifndef NO_CONSOLE_LOG
#include <spdlog/sinks/stdout_color_sinks.h>
#endif
#ifdef _MSC_VER
#include "spdlog/sinks/msvc_sink.h"
#endif
namespace openVulkanoCpp
{
class Logger
{ //TODO add custom sink for in game/engine console
static std::vector<spdlog::sink_ptr> sinks;
public:
static std::shared_ptr<spdlog::logger> WINDOW;
static std::shared_ptr<spdlog::logger> MANAGER;
static std::shared_ptr<spdlog::logger> RENDER;
static std::shared_ptr<spdlog::logger> PHYSIC;
static std::shared_ptr<spdlog::logger> AUDIO;
static std::shared_ptr<spdlog::logger> DATA;
static std::shared_ptr<spdlog::logger> SCENE;
static void SetupLogger(std::string logFolder = "logs", std::string logFile = "openVulkano.log")
{
static bool initialized = false;
if (initialized) return;
try
{
try
{ //TODO allow log files in folders
sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logFile, 1024 * 1024 * 512, 3, true));
}
catch (const spdlog::spdlog_ex& e)
{
std::cerr << "Log create file log sink: " << e.what() << std::endl;
}
#ifndef NO_CONSOLE_LOG
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
#endif
#ifdef _MSC_VER // If it was build with msvc in debug we can use the msvc sink
sinks.push_back(std::make_shared<spdlog::sinks::msvc_sink_mt>());
#endif
// Make sure that there is always a sink for the loggers
if (sinks.empty()) sinks.push_back(std::make_shared<spdlog::sinks::null_sink_mt>());
MANAGER = CreateLogger("manager");
WINDOW = CreateLogger("window");
RENDER = CreateLogger("render");
PHYSIC = CreateLogger("physic");
AUDIO = CreateLogger("audio");
DATA = CreateLogger("data");
SCENE = CreateLogger("scene");
spdlog::flush_every(std::chrono::seconds(5));
MANAGER->info("Logger initialized");
initialized = true;
}
catch (const spdlog::spdlog_ex& e)
{
std::cerr << "Log initialization failed: " << e.what() << std::endl;
}
}
/**
* \brief Creates a new custom logger that writes to the main log file.
* \param name The name of the logger
* \param reg If set to true the logger can be accessed again with spdlog::get(name)
* \return The created logger
*/
static std::shared_ptr<spdlog::logger> CreateLogger(const std::string& name, const bool reg = true)
{
auto logger = std::make_shared<spdlog::logger>(name, sinks.begin(), sinks.end());
if (reg) spdlog::register_logger(logger);
#ifdef LOG_DATE
logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [T%t] [%^%l%$] [%n]: %v");
#else
logger->set_pattern("[%H:%M:%S.%e] [T%t] [%^%l%$] [%n]: %v");
#endif
#ifdef DEBUG
logger->set_level(spdlog::level::debug);
#endif
return logger;
}
};
}

View File

@@ -0,0 +1,45 @@
#pragma once
namespace openVulkanoCpp
{
namespace RenderAPI
{
enum RenderApi
{
VULKAN = 0,
//OpenGL,
//DirectX11,
//DirectX12,
MAX_VALUE
};
inline std::string ToString(RenderApi api)
{
switch (api)
{
case VULKAN: return "Vulkan";
}
return "Invalid";
}
}
namespace Platform
{
enum Platform
{
Windows = 0, MacOS, Linux, Android, MAX_VALUE
};
inline std::string ToString(Platform os)
{
switch (os)
{
case Windows: return "Windows";
case MacOS: return "Windows";
case Linux: return "Windows";
case Android: return "Windows";
}
return "Invalid";
}
}
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include <string>
#include "../ITickable.hpp"
#include "../ICloseable.hpp"
#include "../../Scene/Scene.hpp"
namespace openVulkanoCpp
{
class IWindow;
class IGraphicsAppManager;
class IRenderer : virtual public ITickable, virtual public ICloseable
{
public:
virtual ~IRenderer() = default;
virtual void Init(IGraphicsAppManager* graphicsAppManager, IWindow* window) = 0;
virtual std::string GetMainRenderDeviceName() = 0;
virtual void Resize(uint32_t newWidth, uint32_t newHeight) = 0;
virtual void SetScene(Scene::Scene* scene) = 0;
virtual Scene::Scene* GetScene() = 0;
};
}

View File

@@ -0,0 +1,98 @@
#pragma once
#include <chrono>
#include <cstdint>
namespace openVulkanoCpp
{
/**
* \brief High-res timer
*/
class Timer
{ //TODO maybe add a Windows option that uses QPC https://docs.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps
std::chrono::high_resolution_clock::time_point tPrev, tStop;
int64_t tickNanoseconds, tickMilliseconds;
uint64_t totalNanoseconds;
double tickSeconds, totalSeconds;
bool stopped;
public:
Timer()
{
Reset();
}
~Timer() = default;
void Reset()
{
tickNanoseconds = 0;
tickMilliseconds = 0;
tickSeconds = 0;
totalNanoseconds = 0;
totalSeconds = 0;
tPrev = std::chrono::high_resolution_clock::now();
stopped = false;
}
void Start()
{
if (stopped)
{
tPrev += std::chrono::high_resolution_clock::now() - tStop;
stopped = false;
}
}
void Stop()
{
tStop = std::chrono::high_resolution_clock::now();
stopped = true;
}
/**
* \brief Will update the timer
*/
void Tick()
{
if (stopped)
{
tickNanoseconds = 0;
}
else
{
const auto now = std::chrono::high_resolution_clock::now();
tickNanoseconds = std::chrono::duration<int64_t, std::nano>(now - tPrev).count();
tPrev = now;
if (tickNanoseconds < 0) tickNanoseconds = 0;
}
totalNanoseconds += tickNanoseconds;
tickMilliseconds = tickNanoseconds / 1000000;
tickSeconds = tickNanoseconds / 1000000000.0;
totalSeconds += tickSeconds;
}
int64_t GetTickNanoseconds() const { return tickNanoseconds; }
int64_t GetTickMilliseconds() const { return tickMilliseconds; }
double GetTickSeconds() const { return tickSeconds; }
uint64_t GetTotalNanoseconds() const { return totalNanoseconds; }
/**
* \brief Gets the total amount of seconds past since the timer has been started. This will drift over time!
* \return The summed total runtime of the timer.
*/
double GetTotalSeconds() const { return totalSeconds; }
/**
* \brief Will recalculate the past time from the total nanoseconds and return it. This is more precise but also slower.
* \return The calculated total runtime of the timer.
*/
double GetTotalSecondsPrecise()
{
totalSeconds = totalNanoseconds / 1000000000.0;
return totalSeconds;
}
};
}

View File

@@ -0,0 +1,99 @@
#pragma once
#include "IWindow.hpp"
namespace openVulkanoCpp
{
class BaseWindow : virtual public IWindow
{
const int windowId;
public:
BaseWindow() : windowId(CreateWindowId()) {}
virtual ~BaseWindow() = default;
void GetSize(int* width, int* height) override = 0;
void GetSize(uint32_t* width, uint32_t* height) override
{
int w, h;
GetSize(&w, &h);
*width = w;
*height = h;
}
uint32_t GetWidth() override
{
uint32_t width, height;
GetSize(&width, &height);
return width;
}
uint32_t GetHeight() override
{
uint32_t width, height;
GetSize(&width, &height);
return height;
}
glm::ivec2 GetSize() override
{
glm::ivec2 size;
this->GetSize(&size.x, &size.y);
return size;
}
void SetSize(uint32_t width, uint32_t height) override = 0;
void SetSize(glm::ivec2 size) override
{
SetSize(size.x, size.y);
}
void GetPosition(int* x, int* y) override = 0;
int GetPositionX() override
{
int x, y;
GetPosition(&x, &y);
return x;
}
int GetPositionY() override
{
int x, y;
GetPosition(&x, &y);
return y;
}
glm::ivec2 GetPosition() override
{
glm::ivec2 position;
GetPosition(&position.x, &position.y);
return position;
}
void SetPosition(int posX, int posY) override = 0;
void SetPosition(glm::ivec2 pos) override { SetPosition(pos.x, pos.y); }
void Show() override = 0;
void Hide() override = 0;
void Show(const bool show) override { if (show) Show(); else Hide(); }
IVulkanWindow* GetVulkanWindow() override
{
return nullptr;
}
IOpenGlWindow* GetOpenGlWindow() override
{
return nullptr;
}
int GetWindowId() const override
{
return windowId;
}
};
}

View File

@@ -0,0 +1,113 @@
#pragma once
#include <string>
#include <stdexcept>
#include <glm/glm.hpp>
#include <vulkan/vulkan.hpp>
#include "../PlatformEnums.hpp"
#include "../ITickable.hpp"
#include "../ICloseable.hpp"
namespace openVulkanoCpp
{
enum WindowMode
{
WINDOWED, BORDERLESS, FULLSCREEN, BORDERLESS_FULLSCREEN
};
class IWindowHandler;
class IVulkanWindow;
class IOpenGlWindow;
class IWindow : public ITickable, public ICloseable
{
public:
virtual ~IWindow() = default;
virtual void Init(RenderAPI::RenderApi renderApi) = 0;
virtual const std::string& GetTitle() = 0;
virtual void SetTitle(const std::string& title) = 0;
virtual WindowMode GetWindowMode() = 0;
virtual void SetWindowMode(WindowMode) = 0;
virtual void SetFullscreen() { SetWindowMode(FULLSCREEN); }
virtual void SetWindowed() { SetWindowMode(WINDOWED); }
virtual uint32_t GetWidth() = 0;
virtual uint32_t GetHeight() = 0;
virtual void GetSize(int* width, int* height) = 0;
virtual void GetSize(uint32_t* width, uint32_t* height) = 0;
virtual glm::ivec2 GetSize() = 0;
virtual void SetSize(uint32_t width, uint32_t height) = 0;
virtual void SetSize(glm::ivec2 size) { SetSize(size.x, size.y); }
virtual void SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) = 0;
virtual int GetPositionX() = 0;
virtual int GetPositionY() = 0;
virtual void GetPosition(int* x, int* y) = 0;
virtual glm::ivec2 GetPosition() = 0;
virtual void SetPosition(int posX, int posY) = 0;
virtual void SetPosition(glm::ivec2 pos) = 0;
virtual void Show() = 0;
virtual void Hide() = 0;
virtual void Show(bool show) = 0;
virtual IWindowHandler* GetWindowHandler() = 0;
virtual void SetWindowHandler(IWindowHandler* handler) = 0;
/**
* \brief Gets the vulkan window implementation of the window.
* \return The IVulkanWindow reference of the window. nullptr if the current Window dose not implement IVulkanWindow
*/
virtual IVulkanWindow* GetVulkanWindow() = 0;
virtual IOpenGlWindow* GetOpenGlWindow() = 0;
virtual int GetWindowId() const = 0;
protected:
static int CreateWindowId()
{
static int id = 0;
return id++;
}
};
class IVulkanWindow : virtual public IWindow
{
public:
virtual ~IVulkanWindow() = default;
virtual vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator = nullptr) = 0;
virtual std::vector<std::string> GetRequiredInstanceExtensions() = 0;
};
class IOpenGlWindow : virtual public IWindow
{
public:
virtual ~IOpenGlWindow() = default;
virtual void MakeCurrentThread() = 0;
virtual void Present() const = 0;
};
class IWindowHandler
{
public:
virtual ~IWindowHandler() = default;
virtual void OnWindowMinimize(IWindow* window) = 0;
virtual void OnWindowRestore(IWindow* window) = 0;
virtual void OnWindowFocusLost(IWindow* window) = 0;
virtual void OnWindowFocusGained(IWindow* window) = 0;
virtual void OnWindowMove(IWindow* window, int posX, int posY) = 0;
virtual void OnWindowResize(IWindow* window, uint32_t newWidth, uint32_t newHeight) = 0;
virtual void OnWindowClose(IWindow* window) = 0;
};
class WindowInitFailedException : public std::runtime_error
{
public:
WindowInitFailedException(char const* const message) : runtime_error(message) {}
};
}

View File

@@ -0,0 +1,56 @@
#pragma once
#include <vector>
#include <string>
#include <set>
#include <algorithm>
namespace openVulkanoCpp
{
class Utils
{
public:
static std::vector<const char*> toCString(const std::vector<std::string>& values)
{
std::vector<const char*> result;
result.reserve(values.size());
for (const auto& string : values) {
result.push_back(string.c_str());
}
return result;
}
static std::vector<const char*> toCString(const std::set<std::string>& values)
{
std::vector<const char*> result;
result.reserve(values.size());
for (const auto& string : values) {
result.push_back(string.c_str());
}
return result;
}
template <typename T>
static bool Contains(std::vector<T>& vec, const T& element)
{
return (std::find(vec.begin(), vec.end(), element) != vec.end());
}
template <typename T>
static void Remove(std::vector<T>& vec, const T& element)
{
vec.erase(std::remove(vec.begin(), vec.end(), element), vec.end());
}
template <typename Enumeration>
static auto EnumAsInt(Enumeration const value)
-> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
static bool MatchesAnyElementWise(const glm::vec3& a, const glm::vec3& b)
{
return a.x == b.x || a.y == b.y || a.z == b.z;
}
};
}