Refactor modules architecture
This commit is contained in:
parent
945cf4b1cc
commit
67b2b64d2f
@ -14,4 +14,4 @@ add_subdirectory(sdk/materials)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory (p7lib)
|
||||
add_subdirectory (ECSAPI)
|
||||
add_subdirectory (frontend)
|
||||
add_subdirectory (engine)
|
||||
@ -8,7 +8,7 @@ endif()
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
project (EEfrontend)
|
||||
project (engine)
|
||||
|
||||
|
||||
# List sources
|
||||
@ -25,9 +25,6 @@ file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
|
||||
find_package(Boost REQUIRED COMPONENTS lockfree)
|
||||
find_package(xxHash CONFIG REQUIRED)
|
||||
find_package(glfw3 CONFIG REQUIRED)
|
||||
find_package(glm CONFIG REQUIRED)
|
||||
find_package(Vulkan REQUIRED)
|
||||
find_package(RmlUi CONFIG REQUIRED)
|
||||
|
||||
# Link library
|
||||
|
||||
@ -39,9 +36,6 @@ target_link_libraries(${PROJECT_NAME} PRIVATE Boost::lockfree)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE p7)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE glfw)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Vulkan::Vulkan)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE RmlUi::RmlUi)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC include/)
|
||||
|
||||
@ -63,10 +57,6 @@ if (APP_VERSION)
|
||||
)
|
||||
endif()
|
||||
|
||||
if (VALIDATION_LAYER)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE VALIDATION_LAYER_ON)
|
||||
endif()
|
||||
|
||||
# Set a symbolic link so executable can find the /assets folder
|
||||
set(link_src "${CMAKE_SOURCE_DIR}/assets")
|
||||
set(link_dst "${CMAKE_CURRENT_BINARY_DIR}/assets")
|
||||
@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
#include "AssetManager.hpp"
|
||||
#include "Renderer.hpp"
|
||||
#include "RenderInterface.hpp"
|
||||
|
||||
class Engine
|
||||
{
|
||||
public:
|
||||
static AssetManager *assetManager;
|
||||
static Renderer *renderer;
|
||||
static IRenderer *renderer;
|
||||
|
||||
private:
|
||||
Engine();
|
||||
53
engine/include/RenderInterface.hpp
Normal file
53
engine/include/RenderInterface.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <Boost/lockfree/spsc_queue.hpp>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
struct RenderCommand
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
NONE,
|
||||
|
||||
RESIZE_WINDOW,
|
||||
SHUTDOWN
|
||||
} type = NONE;
|
||||
};
|
||||
|
||||
class IRenderer
|
||||
{
|
||||
public:
|
||||
IRenderer(GLFWwindow *window);
|
||||
~IRenderer();
|
||||
|
||||
void Start();
|
||||
void Shutdown();
|
||||
|
||||
bool GetThreadStatus();
|
||||
bool GetDrawStatus();
|
||||
|
||||
void ResizeWindow(int width, int height);
|
||||
|
||||
private:
|
||||
std::atomic<bool> isRunning;
|
||||
std::atomic<bool> isDrawing;
|
||||
std::atomic<int> screenWidth, screenHeight;
|
||||
|
||||
std::stop_token *stoken;
|
||||
std::jthread renderThread;
|
||||
boost::lockfree::spsc_queue<RenderCommand, boost::lockfree::capacity<512>> commands;
|
||||
|
||||
GLFWwindow *window;
|
||||
|
||||
virtual void Draw() = 0;
|
||||
|
||||
void Threading();
|
||||
void Request(const RenderCommand &command);
|
||||
void Request(const RenderCommand::Type &type);
|
||||
virtual void Init() = 0;
|
||||
virtual void Dispose() = 0;
|
||||
void Loop();
|
||||
void ProcessCommand(const RenderCommand &command);
|
||||
void Release();
|
||||
};
|
||||
@ -1,4 +1,4 @@
|
||||
#include "Engine.hpp"
|
||||
|
||||
AssetManager* Engine::assetManager;
|
||||
Renderer* Engine::renderer;
|
||||
IRenderer* Engine::renderer;
|
||||
119
engine/src/RenderInterface.cpp
Normal file
119
engine/src/RenderInterface.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include "RenderInterface.hpp"
|
||||
#include "Logger.h"
|
||||
#include <allocator.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
IRenderer::IRenderer(GLFWwindow *window) :
|
||||
isRunning(false),
|
||||
isDrawing(false)
|
||||
{
|
||||
this->window = window;
|
||||
int width = -1, height = -1;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
screenWidth.store(width);
|
||||
screenHeight.store(height);
|
||||
}
|
||||
|
||||
IRenderer::~IRenderer()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void IRenderer::Start()
|
||||
{
|
||||
if (isRunning)
|
||||
{
|
||||
LOG(CRITICAL, "Renderer can be started only once");
|
||||
throw std::logic_error("Renderer can be started only once");
|
||||
}
|
||||
|
||||
isRunning.store(true);
|
||||
isDrawing.store(true);
|
||||
renderThread = std::jthread([this](std::stop_token stop) {
|
||||
this->stoken = &stop;
|
||||
Threading();
|
||||
});
|
||||
}
|
||||
|
||||
void IRenderer::Threading()
|
||||
{
|
||||
Logger::trace->Register_Thread(L"Renderer", 0);
|
||||
LOG(INFO, "Renderer thread started");
|
||||
|
||||
Init();
|
||||
Loop();
|
||||
Release();
|
||||
}
|
||||
|
||||
|
||||
void IRenderer::Loop()
|
||||
{
|
||||
RenderCommand commandBuffer;
|
||||
while (!stoken->stop_requested())
|
||||
{
|
||||
while (commands.pop(commandBuffer))
|
||||
{
|
||||
ProcessCommand(commandBuffer);
|
||||
}
|
||||
|
||||
Draw();
|
||||
}
|
||||
}
|
||||
|
||||
void IRenderer::ProcessCommand(const RenderCommand &command)
|
||||
{
|
||||
switch(command.type)
|
||||
{
|
||||
case RenderCommand::SHUTDOWN:
|
||||
{
|
||||
LOG(INFO, "SHUTDOWN command");
|
||||
Shutdown();
|
||||
break;
|
||||
}
|
||||
|
||||
case RenderCommand::RESIZE_WINDOW:
|
||||
{
|
||||
LOG(INFO, "RESIZE_WINDOW command");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
LOG(WARNING, "Unhandled command. Type id: %d", command.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IRenderer::Shutdown()
|
||||
{
|
||||
renderThread.request_stop();
|
||||
}
|
||||
|
||||
void IRenderer::Request(const RenderCommand &command)
|
||||
{
|
||||
commands.push(command);
|
||||
}
|
||||
|
||||
void IRenderer::Request(const RenderCommand::Type &type)
|
||||
{
|
||||
commands.push(RenderCommand {.type = type});
|
||||
}
|
||||
|
||||
void IRenderer::ResizeWindow(int width, int height)
|
||||
{
|
||||
screenWidth.store(width);
|
||||
screenHeight.store(height);
|
||||
Request(RenderCommand::RESIZE_WINDOW);
|
||||
}
|
||||
|
||||
void IRenderer::Release()
|
||||
{
|
||||
Dispose();
|
||||
LOG(INFO, "Renderer is released");
|
||||
isRunning.store(false);
|
||||
}
|
||||
|
||||
bool IRenderer::GetThreadStatus() { return isRunning.load(); }
|
||||
bool IRenderer::GetDrawStatus() { return isDrawing.load(); }
|
||||
74
engine/src/main.cpp
Normal file
74
engine/src/main.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include "Logger.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "compile_config.hpp"
|
||||
#include "Engine.hpp"
|
||||
|
||||
IP7_Trace* Logger::trace;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Setup P7 logger
|
||||
IP7_Client *p7client = P7_Create_Client(P7_SINK);
|
||||
P7_Set_Crash_Handler();
|
||||
Logger::trace = P7_Create_Trace(p7client, L"TC 1");
|
||||
Logger::trace->Register_Thread(L"Main", 0);
|
||||
|
||||
LOG(INFO, "Etredia Empires, v%d.%d.%d", MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION);
|
||||
|
||||
// Setup GLFW
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
|
||||
GLFWwindow *window = glfwCreateWindow(800, 600, "Etredia Empires", nullptr, nullptr);
|
||||
|
||||
if (!window)
|
||||
LOG(CRITICAL, "GLFW Window failed");
|
||||
else LOG(INFO, "GLFW Window created");
|
||||
|
||||
// Setup assets
|
||||
AssetManager assetManager;
|
||||
assetManager.Start();
|
||||
assetManager.LoadShaders();
|
||||
|
||||
// Setup Renderer
|
||||
// assetManager.LoadAsync(AssetInfo::MATERIAL, "assets/materials/helloworld.mat");
|
||||
// AssetHandle baseMaterialHandle = assetManager.Find("assets/materials/helloworld.mat");
|
||||
// AssetMaterial baseMaterial = assetManager.Get<AssetMaterial>(baseMaterialHandle);
|
||||
// IRenderer renderer(window);
|
||||
// renderer.Start();
|
||||
|
||||
//Setup Engine
|
||||
Engine::assetManager = &assetManager;
|
||||
//Engine::renderer = &renderer;
|
||||
|
||||
glfwSetFramebufferSizeCallback(window, [](GLFWwindow *window, int width, int height) {
|
||||
Engine::renderer->ResizeWindow(width, height);
|
||||
});
|
||||
|
||||
// Process GLFW events
|
||||
while(!glfwWindowShouldClose(window))
|
||||
{
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// Free memory
|
||||
LOG(INFO, "Exit...");
|
||||
if (Engine::renderer != nullptr)
|
||||
{ // Wait for renderer to clean and shutdown
|
||||
Engine::renderer->Shutdown();
|
||||
while(Engine::renderer->GetThreadStatus());
|
||||
}
|
||||
if (Engine::assetManager != nullptr)
|
||||
{ // Wait for asset manager to clean and shutdown
|
||||
Engine::assetManager->Shutdown();
|
||||
while(Engine::assetManager->isRunning.load());
|
||||
}
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
Logger::trace->Unregister_Thread(0);
|
||||
Logger::trace->Release();
|
||||
p7client->Release();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
#define ATTRIBUTE_FORMAT_VEC2 VK_FORMAT_R32G32_SFLOAT
|
||||
#define ATTRIBUTE_FORMAT_VEC3 VK_FORMAT_R32G32B32_SFLOAT
|
||||
#define ATTRIBUTE_FORMAT_VEC4 VK_FORMAT_R32G32B32A32_SFLOAT
|
||||
|
||||
struct GPU_Transform
|
||||
{
|
||||
glm::vec3 pos = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
};
|
||||
|
||||
struct GPU_Vertex
|
||||
{
|
||||
glm::vec2 pos;
|
||||
glm::vec3 color;
|
||||
|
||||
static std::array<VkVertexInputAttributeDescription, 2> GetAttributes();
|
||||
};
|
||||
|
||||
struct GPU_BufferSlot
|
||||
{
|
||||
size_t position;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
template<typename T> struct GPU_Buffer
|
||||
{
|
||||
T *data;
|
||||
size_t size;
|
||||
const size_t ELEMENT_SIZE;
|
||||
std::vector<GPU_BufferSlot> freeSlots;
|
||||
|
||||
GPU_Buffer();
|
||||
GPU_BufferSlot* FindFreeSlot(size_t size);
|
||||
size_t Write(const T *elements, size_t elementsCount);
|
||||
// void Clear(GPU_BufferSlot range);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// Template definitions
|
||||
|
||||
template<typename T> GPU_Buffer<T>::GPU_Buffer() : ELEMENT_SIZE(sizeof(T))
|
||||
{
|
||||
freeSlots.push_back({.position = 0, .size = size});
|
||||
}
|
||||
|
||||
template<typename T> GPU_BufferSlot* GPU_Buffer<T>::FindFreeSlot(size_t size)
|
||||
{
|
||||
for (auto i = freeSlots.rbegin(); i != freeSlots.rend(); i++)
|
||||
{
|
||||
if (i->size >= size)
|
||||
return &(*i);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T> size_t GPU_Buffer<T>::Write(const T *elements, size_t elementsCount)
|
||||
{
|
||||
GPU_BufferSlot *slot = FindFreeSlot(elementsCount);
|
||||
if (slot == nullptr) return 0;
|
||||
|
||||
memcpy(data + slot->position, elements, elementsCount * ELEMENT_SIZE);
|
||||
|
||||
slot->size -= elementsCount;
|
||||
slot->position += elementsCount;
|
||||
if (slot->size == 0)
|
||||
freeSlots.pop_back();
|
||||
|
||||
return slot->position - elementsCount;
|
||||
}
|
||||
|
||||
// template<typename T> void GPU_Buffer<T>::Clear(GPU_BufferSlot range)
|
||||
// {
|
||||
// freeSlots.push_back(range);
|
||||
// //TODO: insert sorted by pos and combine intersections
|
||||
// }
|
||||
@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "GPU_BaseTypes.hpp"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct GPU_GlobalUBO
|
||||
{
|
||||
glm::mat4 view;
|
||||
glm::mat4 proj;
|
||||
float time;
|
||||
};
|
||||
|
||||
struct GPU_TranformUBO
|
||||
{
|
||||
glm::mat4 model;
|
||||
|
||||
void Update(const GPU_Transform &tranform);
|
||||
};
|
||||
@ -1,81 +0,0 @@
|
||||
#pragma once
|
||||
#include "AssetData.hpp"
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#define PIPELINE_CREATE_NEW 0
|
||||
#define PIPELINE_CREATE_DERIVED (1 << 0)
|
||||
|
||||
struct PipelineBinding
|
||||
{
|
||||
const AssetMaterial *baseMaterial;
|
||||
|
||||
const VkRenderPass *baseRenderPass;
|
||||
const VkDevice *device;
|
||||
const VkExtent2D *surfaceExtent;
|
||||
|
||||
const VkVertexInputBindingDescription *vertexBindingConfig;
|
||||
uint32_t vertexAttributesCount;
|
||||
const VkVertexInputAttributeDescription *vertexAttributesConfig;
|
||||
};
|
||||
|
||||
struct PipelineConfig
|
||||
{
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputConfig;
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssemblyConfig;
|
||||
VkPipelineViewportStateCreateInfo viewportStateConfig;
|
||||
VkPipelineRasterizationStateCreateInfo rasterizerConfig;
|
||||
VkPipelineMultisampleStateCreateInfo multisamplingConfig;
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilConfig;
|
||||
|
||||
// SRC - new color, DST - old color
|
||||
std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentConfigs;
|
||||
VkPipelineColorBlendStateCreateInfo colorBlendConfig;
|
||||
VkPipelineDynamicStateCreateInfo dynamicStateConfig;
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutConfig;
|
||||
|
||||
VkViewport defaultViewport;
|
||||
VkRect2D defaultScissors;
|
||||
std::vector<VkDynamicState> dynamicStates;
|
||||
|
||||
std::vector<VkDescriptorSetLayoutBinding> uniforms;
|
||||
int vertexBindingsCount, fragmentBindingsCount;
|
||||
VkDescriptorSetLayoutCreateInfo uniformsConfig;
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipelineConfig;
|
||||
|
||||
PipelineConfig Copy() const;
|
||||
};
|
||||
|
||||
struct Pipeline
|
||||
{
|
||||
VkPipeline instance;
|
||||
VkPipelineLayout layout;
|
||||
VkDescriptorSetLayout uniformsLayout;
|
||||
VkViewport viewport;
|
||||
VkRect2D scissors;
|
||||
};
|
||||
|
||||
class PipelineFactory
|
||||
{
|
||||
public:
|
||||
PipelineFactory(const PipelineBinding &binding);
|
||||
~PipelineFactory();
|
||||
|
||||
Pipeline& Get(const AssetMaterial &material);
|
||||
void Create(const AssetMaterial &material, const VkRenderPass &renderPass, const uint32_t &flags);
|
||||
|
||||
private:
|
||||
PipelineBinding binding;
|
||||
PipelineConfig basePipelineConfig;
|
||||
|
||||
Pipeline basePipeline;
|
||||
std::unordered_map<const AssetMaterial*, Pipeline> pipelines;
|
||||
|
||||
const VkDevice &device;
|
||||
const VkExtent2D &surfaceExtent;
|
||||
|
||||
const VkVertexInputBindingDescription &vertexBindingConfig;
|
||||
|
||||
};
|
||||
@ -1,256 +0,0 @@
|
||||
#pragma once
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <Boost/lockfree/spsc_queue.hpp>
|
||||
|
||||
#define GLFW_INCLUDE_VULKAN
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "GPU_Types/GPU_BaseTypes.hpp"
|
||||
|
||||
#include "PipelineFactory.hpp"
|
||||
|
||||
#ifdef VALIDATION_LAYER_ON
|
||||
#define VALIDATION_LAYER "VK_LAYER_KHRONOS_validation"
|
||||
#else
|
||||
#define VALIDATION_LAYER
|
||||
#endif
|
||||
|
||||
// GPU properties priority for selection
|
||||
#define GPU_DISCRETE_PRIORITY 1000
|
||||
#define GPU_GRAPHICS_WITH_PRESENT_PRIORITY 500
|
||||
#define GPU_B8G8R8_SRGB_PRIORITY 10
|
||||
|
||||
#define QUEUE_FAMILY_NO_VALUE UINT32_MAX
|
||||
|
||||
#define RENDER_PASS_BASE 438461662
|
||||
#define RENDER_PASS_GUI
|
||||
|
||||
#define INDICES_SIZE uint16_t
|
||||
#define INDICES_SIZE_VK VK_INDEX_TYPE_UINT16
|
||||
|
||||
struct Mesh
|
||||
{
|
||||
size_t verticesBufferPosition = 0;
|
||||
size_t indicesBufferPosition = 0;
|
||||
std::vector<GPU_Vertex> vertices;
|
||||
std::vector<INDICES_SIZE> indices;
|
||||
};
|
||||
|
||||
struct MaterialParams
|
||||
{
|
||||
VkDescriptorSet descriptors;
|
||||
//TODO: push-constants
|
||||
|
||||
void Set(const char** param, const char** property = nullptr);
|
||||
};
|
||||
|
||||
struct RenderObject
|
||||
{
|
||||
uint32_t engineId = UINT32_MAX;
|
||||
|
||||
// Multiple transforms for batching
|
||||
std::vector<GPU_Transform> transforms;
|
||||
uint8_t depth = 0;
|
||||
Mesh mesh;
|
||||
bool isUI = false;
|
||||
//TODO: texture
|
||||
|
||||
AssetMaterial &material;
|
||||
MaterialParams materialParams;
|
||||
};
|
||||
bool operator < (const RenderObject& lhs, const RenderObject& rhs);
|
||||
|
||||
struct RenderCommand
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
NONE,
|
||||
|
||||
REGISTER_OBJECTS,
|
||||
RESIZE_WINDOW,
|
||||
SHUTDOWN
|
||||
} type = NONE;
|
||||
|
||||
RenderObject *objects;
|
||||
size_t objectsSize;
|
||||
};
|
||||
|
||||
struct QueueFamiliesBundle
|
||||
{
|
||||
uint32_t transfer = QUEUE_FAMILY_NO_VALUE;
|
||||
uint32_t graphics = QUEUE_FAMILY_NO_VALUE;
|
||||
uint32_t present = QUEUE_FAMILY_NO_VALUE;
|
||||
};
|
||||
|
||||
struct QueuesBundle
|
||||
{
|
||||
VkQueue transfer;
|
||||
VkQueue graphics;
|
||||
VkQueue present;
|
||||
};
|
||||
|
||||
struct DrawConfig
|
||||
{
|
||||
VkCommandBufferBeginInfo commandBeginConfig {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.pInheritanceInfo = nullptr
|
||||
};
|
||||
|
||||
VkClearValue clearColor {{{1.0f, 1.0f, 1.0f, 1.0f}}};
|
||||
|
||||
VkRenderPassBeginInfo renderPassBeginConfig {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.pNext = nullptr,
|
||||
.clearValueCount = 1,
|
||||
.pClearValues = &clearColor
|
||||
};
|
||||
|
||||
VkPipelineStageFlags waitImageStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
|
||||
VkSubmitInfo submitConfig {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.pNext = nullptr,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitDstStageMask = &waitImageStage,
|
||||
.commandBufferCount = 1,
|
||||
.signalSemaphoreCount = 1
|
||||
};
|
||||
|
||||
VkPresentInfoKHR presentConfig {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.waitSemaphoreCount = 1,
|
||||
.swapchainCount = 1,
|
||||
.pResults = nullptr
|
||||
};
|
||||
|
||||
VkVertexInputBindingDescription vertexBindingConfig {
|
||||
.binding = 0,
|
||||
.stride = sizeof(GPU_Vertex),
|
||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
||||
};
|
||||
};
|
||||
|
||||
struct SurfaceInfo
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
std::vector<VkSurfaceFormatKHR> availableFormats;
|
||||
std::vector<VkPresentModeKHR> availablePresentModes;
|
||||
|
||||
VkSurfaceFormatKHR format;
|
||||
VkPresentModeKHR presentMode;
|
||||
VkExtent2D extent;
|
||||
};
|
||||
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
Renderer(GLFWwindow *window, const AssetMaterial& baseMaterial, const size_t &vertexBufferSize, const size_t &indexBufferSize);
|
||||
~Renderer();
|
||||
|
||||
void Start();
|
||||
void Shutdown();
|
||||
|
||||
bool GetThreadStatus();
|
||||
bool GetDrawStatus();
|
||||
|
||||
void RegisterObjects(RenderObject* objects, size_t size);
|
||||
void ResizeWindow(int width, int height);
|
||||
|
||||
private:
|
||||
std::atomic<bool> isRunning;
|
||||
std::atomic<bool> isDrawing;
|
||||
std::atomic<int> screenWidth, screenHeight;
|
||||
|
||||
std::stop_token *stoken;
|
||||
std::jthread renderThread;
|
||||
boost::lockfree::spsc_queue<RenderCommand, boost::lockfree::capacity<512>> commands;
|
||||
|
||||
GLFWwindow *window;
|
||||
|
||||
VkInstance vulkan;
|
||||
VkSurfaceKHR surface;
|
||||
VkPhysicalDevice gpu;
|
||||
VkDevice device;
|
||||
VkSwapchainKHR swapchain;
|
||||
VkRenderPass baseRenderPass;
|
||||
VkCommandPool graphicsCommandPool = nullptr;
|
||||
VkCommandPool transferCommandPool = nullptr;
|
||||
VkDeviceMemory worldVerticesMemory;
|
||||
VkDeviceMemory worldIndicesMemory;
|
||||
VkDeviceMemory stagingWorldVerticesMemory;
|
||||
VkDeviceMemory stagingWorldIndicesMemory;
|
||||
VkDeviceMemory uiVerticesMemory;
|
||||
VkDeviceMemory uiIndicesMemory;
|
||||
VkBuffer worldVertices;
|
||||
VkBuffer worldIndices;
|
||||
VkBuffer stagingWorldVertices;
|
||||
VkBuffer stagingWorldIndices;
|
||||
VkBuffer uiVertices;
|
||||
VkBuffer uiIndices;
|
||||
std::vector<VkDeviceMemory> worldUniformsMemory;
|
||||
std::vector<VkBuffer> worldUniforms;
|
||||
std::vector<VkDeviceMemory> uiUniformsMemory;
|
||||
std::vector<VkBuffer> uiUniforms;
|
||||
std::vector<VkCommandBuffer> graphicsCommandBuffers;
|
||||
std::vector<VkCommandBuffer> transferCommandBuffers;
|
||||
std::vector<VkImage> frames;
|
||||
std::vector<VkImageView> frameViews;
|
||||
std::vector<VkFramebuffer> baseFrameBuffers;
|
||||
std::vector<VkSemaphore> imageAvailable;
|
||||
std::vector<VkSemaphore> renderFinished;
|
||||
std::vector<VkFence> inFlightFences;
|
||||
std::vector<VkFence> imagesInFlight;
|
||||
|
||||
SurfaceInfo surfaceInfo;
|
||||
QueueFamiliesBundle queueFamilies;
|
||||
QueuesBundle queues;
|
||||
DrawConfig drawConfig;
|
||||
PipelineFactory *pipelineFactory;
|
||||
PipelineBinding pipelineBinding;
|
||||
size_t currentFrame = 0;
|
||||
|
||||
GPU_Buffer<GPU_Vertex> worldVerticesBinded;
|
||||
GPU_Buffer<INDICES_SIZE> worldIndicesBinded;
|
||||
GPU_Buffer<GPU_Vertex> uiVerticesBinded;
|
||||
GPU_Buffer<INDICES_SIZE> uiIndicesBinded;
|
||||
|
||||
const float DEFAULT_QUEUE_PRIORITY = 1.0f;
|
||||
const AssetMaterial &baseMaterial;
|
||||
const size_t MAX_FRAMES_IN_FLIGHT = 2;
|
||||
const size_t VERTEX_BUFFER_SIZE;
|
||||
const size_t INDEX_BUFFER_SIZE;
|
||||
|
||||
std::set<RenderObject> objects;
|
||||
|
||||
//Rml::Context *uiContext;
|
||||
|
||||
void InitVulkan();
|
||||
void SetupDevice();
|
||||
void SetupSwapchain();
|
||||
void RecreateSwapchain();
|
||||
void ReleaseSwapchain();
|
||||
void SetupRenderPasses();
|
||||
void SetupPipelines();
|
||||
void SetupObjectsBuffers();
|
||||
void SetupRenderBuffers();
|
||||
void SetupSync();
|
||||
|
||||
void Draw();
|
||||
void CopyBuffer(VkBuffer src, size_t offset, VkBuffer dst, VkDeviceSize size);
|
||||
|
||||
void Threading();
|
||||
void Request(const RenderCommand &command);
|
||||
void Request(const RenderCommand::Type &type);
|
||||
void Init();
|
||||
void Loop();
|
||||
void ProcessCommand(const RenderCommand &command);
|
||||
void Release();
|
||||
|
||||
};
|
||||
@ -1,29 +0,0 @@
|
||||
#include "GPU_Types/GPU_BaseTypes.hpp"
|
||||
#include "GPU_Types/GPU_RenderUBO.hpp"
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
std::array<VkVertexInputAttributeDescription, 2> GPU_Vertex::GetAttributes()
|
||||
{
|
||||
VkVertexInputAttributeDescription posAttribute = {
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = ATTRIBUTE_FORMAT_VEC2,
|
||||
.offset = offsetof(GPU_Vertex, pos)
|
||||
};
|
||||
VkVertexInputAttributeDescription colorAttribute = {
|
||||
.location = 1,
|
||||
.binding = 0,
|
||||
.format = ATTRIBUTE_FORMAT_VEC3,
|
||||
.offset = offsetof(GPU_Vertex, color)
|
||||
};
|
||||
|
||||
return {posAttribute, colorAttribute};
|
||||
}
|
||||
|
||||
void GPU_TranformUBO::Update(const GPU_Transform &transform)
|
||||
{
|
||||
model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, transform.pos);
|
||||
model = glm::scale(model, transform.scale);
|
||||
}
|
||||
@ -1,314 +0,0 @@
|
||||
#include "PipelineFactory.hpp"
|
||||
#include "Engine.hpp"
|
||||
#include "Logger.h"
|
||||
|
||||
PipelineConfig PipelineConfig::Copy() const
|
||||
{
|
||||
PipelineConfig copy = *this;
|
||||
|
||||
copy.viewportStateConfig.pViewports = ©.defaultViewport;
|
||||
copy.viewportStateConfig.pScissors = ©.defaultScissors;
|
||||
copy.dynamicStateConfig.pDynamicStates = copy.dynamicStates.data();
|
||||
copy.colorBlendConfig.pAttachments = copy.colorBlendAttachmentConfigs.data();
|
||||
copy.uniformsConfig.pBindings = copy.uniforms.data();
|
||||
copy.pipelineConfig.pVertexInputState = ©.vertexInputConfig;
|
||||
copy.pipelineConfig.pInputAssemblyState = ©.inputAssemblyConfig;
|
||||
copy.pipelineConfig.pViewportState = ©.viewportStateConfig;
|
||||
copy.pipelineConfig.pRasterizationState = ©.rasterizerConfig;
|
||||
copy.pipelineConfig.pMultisampleState = ©.multisamplingConfig;
|
||||
copy.pipelineConfig.pDepthStencilState = nullptr;
|
||||
copy.pipelineConfig.pColorBlendState = ©.colorBlendConfig;
|
||||
copy.pipelineConfig.pDynamicState = ©.dynamicStateConfig;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
PipelineFactory::PipelineFactory(const PipelineBinding &binding) :
|
||||
device(*binding.device),
|
||||
surfaceExtent(*binding.surfaceExtent),
|
||||
vertexBindingConfig(*binding.vertexBindingConfig)
|
||||
{
|
||||
this->binding = binding;
|
||||
|
||||
basePipelineConfig.dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
|
||||
basePipelineConfig.dynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR);
|
||||
|
||||
basePipelineConfig.colorBlendAttachmentConfigs.push_back({
|
||||
.blendEnable = VK_TRUE,
|
||||
.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
|
||||
.colorBlendOp = VK_BLEND_OP_ADD,
|
||||
.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
|
||||
.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
|
||||
.alphaBlendOp = VK_BLEND_OP_ADD,
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
|
||||
});
|
||||
|
||||
basePipelineConfig.uniforms.push_back({
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.pImmutableSamplers = nullptr
|
||||
}); // GPU_GlobalUBO
|
||||
|
||||
basePipelineConfig.uniforms.push_back({
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.pImmutableSamplers = nullptr
|
||||
}); // GPU_TransformUBO
|
||||
|
||||
basePipelineConfig.vertexInputConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.vertexBindingDescriptionCount = 1,
|
||||
.pVertexBindingDescriptions = &vertexBindingConfig,
|
||||
.vertexAttributeDescriptionCount = binding.vertexAttributesCount,
|
||||
.pVertexAttributeDescriptions = binding.vertexAttributesConfig
|
||||
};
|
||||
|
||||
basePipelineConfig.inputAssemblyConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
||||
.primitiveRestartEnable = VK_FALSE
|
||||
};
|
||||
|
||||
basePipelineConfig.rasterizerConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.depthClampEnable = VK_FALSE,
|
||||
.rasterizerDiscardEnable = VK_FALSE,
|
||||
.polygonMode = VK_POLYGON_MODE_FILL,
|
||||
.cullMode = VK_CULL_MODE_NONE,
|
||||
.depthBiasEnable = VK_FALSE,
|
||||
.lineWidth = 1.0f,
|
||||
};
|
||||
|
||||
basePipelineConfig.multisamplingConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.sampleShadingEnable = VK_FALSE,
|
||||
};
|
||||
|
||||
basePipelineConfig.depthStencilConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
};
|
||||
|
||||
basePipelineConfig.dynamicStateConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.dynamicStateCount = static_cast<uint32_t>(basePipelineConfig.dynamicStates.size()),
|
||||
.pDynamicStates = basePipelineConfig.dynamicStates.data()
|
||||
};
|
||||
|
||||
basePipelineConfig.uniformsConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = static_cast<uint32_t>(basePipelineConfig.uniforms.size()),
|
||||
.pBindings = basePipelineConfig.uniforms.data()
|
||||
};
|
||||
|
||||
basePipelineConfig.pipelineLayoutConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.setLayoutCount = 1,
|
||||
.pushConstantRangeCount = 0,
|
||||
.pPushConstantRanges = nullptr
|
||||
};
|
||||
|
||||
basePipelineConfig.defaultViewport = {
|
||||
.x = 0.0f,
|
||||
.y = 0.0f,
|
||||
.width = static_cast<float>(surfaceExtent.width),
|
||||
.height = static_cast<float>(surfaceExtent.height),
|
||||
.minDepth = 0.0f,
|
||||
.maxDepth = 1.0f
|
||||
};
|
||||
|
||||
basePipelineConfig.defaultScissors = {
|
||||
.offset = {.x = 0, .y = 0},
|
||||
.extent = surfaceExtent
|
||||
};
|
||||
|
||||
basePipelineConfig.viewportStateConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.viewportCount = 1,
|
||||
.pViewports = &basePipelineConfig.defaultViewport,
|
||||
.scissorCount = 1,
|
||||
.pScissors = &basePipelineConfig.defaultScissors
|
||||
};
|
||||
|
||||
basePipelineConfig.colorBlendConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.logicOpEnable = VK_FALSE,
|
||||
.attachmentCount = static_cast<uint32_t>(basePipelineConfig.colorBlendAttachmentConfigs.size()),
|
||||
.pAttachments = basePipelineConfig.colorBlendAttachmentConfigs.data(),
|
||||
};
|
||||
|
||||
basePipelineConfig.pipelineConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.pVertexInputState = &basePipelineConfig.vertexInputConfig,
|
||||
.pInputAssemblyState = &basePipelineConfig.inputAssemblyConfig,
|
||||
.pViewportState = &basePipelineConfig.viewportStateConfig,
|
||||
.pRasterizationState = &basePipelineConfig.rasterizerConfig,
|
||||
.pMultisampleState = &basePipelineConfig.multisamplingConfig,
|
||||
.pDepthStencilState = nullptr,
|
||||
.pColorBlendState = &basePipelineConfig.colorBlendConfig,
|
||||
.pDynamicState = &basePipelineConfig.dynamicStateConfig,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = -1
|
||||
};
|
||||
|
||||
LOG(INFO, "Creating base material pipeline...");
|
||||
Create(*binding.baseMaterial, *binding.baseRenderPass, PIPELINE_CREATE_NEW);
|
||||
LOG(INFO, "Base material pipeline created");
|
||||
}
|
||||
|
||||
Pipeline& PipelineFactory::Get(const AssetMaterial &material)
|
||||
{
|
||||
if (pipelines.contains(&material))
|
||||
return pipelines[&material];
|
||||
else return basePipeline;
|
||||
}
|
||||
|
||||
void PipelineFactory::Create(const AssetMaterial &material, const VkRenderPass &renderPass, const uint32_t &flags)
|
||||
{
|
||||
VkResult vkResult;
|
||||
|
||||
Pipeline newPipeline {};
|
||||
Pipeline *result = &basePipeline;
|
||||
|
||||
PipelineConfig newConfig;
|
||||
PipelineConfig *config = &basePipelineConfig;
|
||||
|
||||
if (flags & PIPELINE_CREATE_DERIVED)
|
||||
{
|
||||
newConfig = basePipelineConfig.Copy();
|
||||
config = &newConfig;
|
||||
|
||||
result = &newPipeline;
|
||||
config->pipelineConfig.basePipelineHandle = basePipeline.instance;
|
||||
}
|
||||
|
||||
// Configure shaders
|
||||
AssetHandle shaderHandle;
|
||||
AssetShader *shader;
|
||||
VkShaderModuleCreateInfo shaderModuleCreateConfig;
|
||||
std::vector<VkPipelineShaderStageCreateInfo> stagesConfigs;
|
||||
|
||||
stagesConfigs.reserve(3);
|
||||
|
||||
// Vertex
|
||||
VkShaderModule vertexModule;
|
||||
shaderHandle = Engine::assetManager->Find(material.vertexShaderAssetID);
|
||||
shader = &Engine::assetManager->Get<AssetShader>(shaderHandle);
|
||||
shaderModuleCreateConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.codeSize = shader->size,
|
||||
.pCode = shader->content
|
||||
};
|
||||
vkResult = vkCreateShaderModule(device, &shaderModuleCreateConfig, nullptr, &vertexModule);
|
||||
if (vkResult != VK_SUCCESS)
|
||||
LOG(ERROR, "Failed to create vertex shader module [Asset ID: %d]. Code: %d", shaderHandle.id, vkResult);
|
||||
stagesConfigs.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.module = vertexModule,
|
||||
.pName = "main",
|
||||
.pSpecializationInfo = nullptr
|
||||
});
|
||||
|
||||
VkDescriptorSetLayoutBinding baseBinding {
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.pImmutableSamplers = nullptr
|
||||
};
|
||||
baseBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
|
||||
// Fragment
|
||||
VkShaderModule fragmentModule;
|
||||
shaderHandle = Engine::assetManager->Find(material.fragmentShaderAssetID);
|
||||
shader = &Engine::assetManager->Get<AssetShader>(shaderHandle);
|
||||
shaderModuleCreateConfig = {
|
||||
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.codeSize = shader->size,
|
||||
.pCode = shader->content
|
||||
};
|
||||
vkResult = vkCreateShaderModule(device, &shaderModuleCreateConfig, nullptr, &fragmentModule);
|
||||
if (vkResult != VK_SUCCESS)
|
||||
LOG(ERROR, "Failed to create fragment shader module [Asset ID: %d]. Code: %d", shaderHandle.id, vkResult);
|
||||
stagesConfigs.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.module = fragmentModule,
|
||||
.pName = "main",
|
||||
.pSpecializationInfo = nullptr
|
||||
});
|
||||
|
||||
baseBinding.binding = 0;
|
||||
baseBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
|
||||
//
|
||||
|
||||
vkResult = vkCreateDescriptorSetLayout(device, &config->uniformsConfig, nullptr, &result->uniformsLayout);
|
||||
if (vkResult != VK_SUCCESS)
|
||||
LOG(CRITICAL, "Failed to create uniforms layout");
|
||||
config->pipelineLayoutConfig.pSetLayouts = &result->uniformsLayout;
|
||||
|
||||
vkResult = vkCreatePipelineLayout(
|
||||
device,
|
||||
&config->pipelineLayoutConfig,
|
||||
nullptr,
|
||||
&result->layout
|
||||
);
|
||||
if (vkResult != VK_SUCCESS)
|
||||
LOG(CRITICAL, "Failed to create pipeline layout");
|
||||
config->pipelineConfig.layout = result->layout;
|
||||
|
||||
config->pipelineConfig.stageCount = static_cast<uint32_t>(stagesConfigs.size());
|
||||
config->pipelineConfig.pStages = stagesConfigs.data();
|
||||
config->pipelineConfig.renderPass = renderPass;
|
||||
config->pipelineConfig.subpass = material.renderStage;
|
||||
|
||||
vkResult = vkCreateGraphicsPipelines(
|
||||
device,
|
||||
VK_NULL_HANDLE,
|
||||
1,
|
||||
&config->pipelineConfig,
|
||||
nullptr,
|
||||
&result->instance
|
||||
);
|
||||
if (vkResult != VK_SUCCESS)
|
||||
LOG(CRITICAL, "Failed to create pipeline");
|
||||
|
||||
if (flags & PIPELINE_CREATE_DERIVED)
|
||||
pipelines[&material] = newPipeline;
|
||||
|
||||
result->viewport = config->defaultViewport;
|
||||
result->scissors = config->defaultScissors;
|
||||
|
||||
vkDestroyShaderModule(device, vertexModule, nullptr);
|
||||
vkDestroyShaderModule(device, fragmentModule, nullptr);
|
||||
}
|
||||
|
||||
PipelineFactory::~PipelineFactory()
|
||||
{
|
||||
vkDestroyPipeline(device, basePipeline.instance, nullptr);
|
||||
vkDestroyPipelineLayout(device, basePipeline.layout, nullptr);
|
||||
vkDestroyDescriptorSetLayout(device, basePipeline.uniformsLayout, nullptr);
|
||||
for (auto &item : pipelines)
|
||||
{
|
||||
vkDestroyPipeline(device, item.second.instance, nullptr);
|
||||
vkDestroyPipelineLayout(device, item.second.layout, nullptr);
|
||||
vkDestroyDescriptorSetLayout(device, item.second.uniformsLayout, nullptr);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,97 +0,0 @@
|
||||
#include "Logger.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "compile_config.hpp"
|
||||
#include "Engine.hpp"
|
||||
|
||||
IP7_Trace* Logger::trace;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Setup P7 logger
|
||||
IP7_Client *p7client = P7_Create_Client(P7_SINK);
|
||||
P7_Set_Crash_Handler();
|
||||
Logger::trace = P7_Create_Trace(p7client, L"TC 1");
|
||||
Logger::trace->Register_Thread(L"Main", 0);
|
||||
|
||||
LOG(INFO, "Etredia Empires, v%d.%d.%d", MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION);
|
||||
|
||||
// Setup GLFW
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
|
||||
GLFWwindow *window = glfwCreateWindow(800, 600, "Etredia Empires", nullptr, nullptr);
|
||||
|
||||
if (!window)
|
||||
LOG(CRITICAL, "GLFW Window failed");
|
||||
else LOG(INFO, "GLFW Window created");
|
||||
|
||||
// Setup assets
|
||||
AssetManager assetManager;
|
||||
assetManager.Start();
|
||||
assetManager.LoadShaders();
|
||||
|
||||
// Setup Renderer
|
||||
assetManager.LoadAsync(AssetInfo::MATERIAL, "assets/materials/helloworld.mat");
|
||||
AssetHandle baseMaterialHandle = assetManager.Find("assets/materials/helloworld.mat");
|
||||
AssetMaterial baseMaterial = assetManager.Get<AssetMaterial>(baseMaterialHandle);
|
||||
Renderer renderer(window, baseMaterial, 1000000, 1000000); //TODO: buffer sizes
|
||||
renderer.Start();
|
||||
|
||||
//Setup Engine
|
||||
Engine::assetManager = &assetManager;
|
||||
Engine::renderer = &renderer;
|
||||
|
||||
glfwSetFramebufferSizeCallback(window, [](GLFWwindow *window, int width, int height) {
|
||||
Engine::renderer->ResizeWindow(width, height);
|
||||
});
|
||||
|
||||
// Test render obj
|
||||
RenderObject triangle {
|
||||
.transforms = {{.pos = {0.0f, 0.0f, 0.0f}}},
|
||||
.mesh = {
|
||||
.vertices = {
|
||||
{.pos = {-0.5f, -0.5f}, .color = {0.0f, 0.0f, 0.0f}},
|
||||
{.pos = {0.0f, 0.5f}, .color = {0.0f, 0.0f, 0.0f}},
|
||||
{.pos = {-1.0f, 0.5f}, .color = {0.0f, 0.0f, 0.0f}}
|
||||
},
|
||||
.indices = {0, 1, 2}
|
||||
},
|
||||
|
||||
.material = baseMaterial,
|
||||
};
|
||||
RenderObject rect {
|
||||
.transforms = {{.pos = {0.0f, 0.0f, 0.0f}}},
|
||||
.mesh = {
|
||||
.vertices = {
|
||||
{.pos = {-0.5f, -0.5f}, .color = {1.0f, 0.0f, 0.0f}},
|
||||
{.pos = {0.5f, -0.5f}, .color = {0.0f, 1.0f, 0.0f}},
|
||||
{.pos = {0.5f, 0.5f}, .color = {0.0f, 0.0f, 1.0f}},
|
||||
{.pos = {-0.5f, 0.5f}, .color = {0.0f, 0.0f, 0.0f}}
|
||||
},
|
||||
.indices = { 0, 1, 2, 2, 3, 0}
|
||||
},
|
||||
|
||||
.material = baseMaterial,
|
||||
};
|
||||
RenderObject objs[] = {triangle, rect};
|
||||
renderer.RegisterObjects(objs, 2);
|
||||
|
||||
// Process GLFW events
|
||||
while(!glfwWindowShouldClose(window))
|
||||
{
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// Free memory
|
||||
LOG(INFO, "Exit...");
|
||||
renderer.Shutdown(); while(renderer.GetThreadStatus());
|
||||
assetManager.Shutdown(); while(assetManager.isRunning.load());
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
Logger::trace->Unregister_Thread(0);
|
||||
Logger::trace->Release();
|
||||
p7client->Release();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -16,7 +16,7 @@ find_package(xxHash CONFIG REQUIRED)
|
||||
add_executable(${PROJECT_NAME} compile_materials.cpp)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/frontend/include/)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/engine/include/)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user