Added a rectangle, and started reworking logs
This commit is contained in:
parent
2603d12394
commit
9236ada59a
@ -128,7 +128,7 @@ function ( addBinary BINARY_NAME )
|
|||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_tables.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/imgui_tables.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_widgets.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/imgui_widgets.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_demo.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/imgui_demo.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_memory_editor.h
|
#${CMAKE_SOURCE_DIR}/src/imgui/imgui_memory_editor.h
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_glfw.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_glfw.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_vulkan.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_vulkan.cpp
|
||||||
|
|||||||
36
shaders/colored_triangle_mesh.vert
Normal file
36
shaders/colored_triangle_mesh.vert
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_EXT_buffer_reference : require
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 outColor;
|
||||||
|
layout(location = 1) out vec2 outUV;
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
vec3 position;
|
||||||
|
float uv_x;
|
||||||
|
vec3 normal;
|
||||||
|
float uv_y;
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(buffer_reference, std430) readonly buffer VertexBuffer {
|
||||||
|
Vertex vertices[];
|
||||||
|
};
|
||||||
|
|
||||||
|
//push constants block
|
||||||
|
layout(push_constant) uniform constants
|
||||||
|
{
|
||||||
|
mat4 render_matrix;
|
||||||
|
VertexBuffer vertexBuffer;
|
||||||
|
} PushConstants;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
//load vertex data from device adress
|
||||||
|
Vertex v = PushConstants.vertexBuffer.vertices[gl_VertexIndex];
|
||||||
|
|
||||||
|
//output data
|
||||||
|
gl_Position = PushConstants.render_matrix * vec4(v.position, 1.0f);
|
||||||
|
outColor = v.color.xyz;
|
||||||
|
outUV.x = v.uv_x;
|
||||||
|
outUV.y = v.uv_y;
|
||||||
|
}
|
||||||
@ -3,6 +3,24 @@
|
|||||||
|
|
||||||
// Custom includes
|
// Custom includes
|
||||||
|
|
||||||
|
|
||||||
|
// Enums
|
||||||
|
enum class LogModule {
|
||||||
|
ENGINE,
|
||||||
|
RENDERER,
|
||||||
|
GLFW,
|
||||||
|
CLEANUP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class LogLevel {
|
||||||
|
EDEBUG,
|
||||||
|
EINIT, // Initialization related
|
||||||
|
EINFO, // General infos
|
||||||
|
EWARN,
|
||||||
|
EERROR,
|
||||||
|
EFATAL
|
||||||
|
};
|
||||||
|
|
||||||
class NetLogger {
|
class NetLogger {
|
||||||
public:
|
public:
|
||||||
struct Server{
|
struct Server{
|
||||||
@ -17,7 +35,65 @@ class NetLogger {
|
|||||||
void logNetAsync(); // Todo
|
void logNetAsync(); // Todo
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
public:
|
||||||
|
// Members
|
||||||
|
std::string logBuffer; // Log is empty by default
|
||||||
|
std::vector<std::string_view> lines;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
template<typename... Args>
|
||||||
|
void logDisk(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to a file on disk
|
||||||
|
// Overload
|
||||||
|
void logDisk(std::string_view message);
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logRAM(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to ram (ImGUI)
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logConsole(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to the console (crashes, etc...)
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logAll(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs using all of the above, RAM then console and finally disk, maybe multithread (?)
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logError(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to console and file, in cases of crashes or errors
|
||||||
|
|
||||||
|
void merge(std::string_view source); // Merges a source dumped logs into this
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Helper functions
|
||||||
|
static std::string_view moduleToString(LogModule m);
|
||||||
|
static std::string_view levelToString(LogLevel l);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // End of header
|
#endif // End of header
|
||||||
@ -29,12 +105,229 @@ class NetLogger {
|
|||||||
// Implementation
|
// Implementation
|
||||||
|
|
||||||
// Includes
|
// Includes
|
||||||
#include <httplib.h> // Todo : add it in the flake
|
//#include <httplib.h> // Todo : add it in the flake
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
/*
|
||||||
void NetLogger::initNetLogger(Server server) {
|
void NetLogger::initNetLogger(Server server) {
|
||||||
httplib::Client cli(server.url)
|
httplib::Client cli(server.url)
|
||||||
// Todo : add error handling
|
// Todo : add error handling
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logRAM(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto timestamp = std::format("{:%Y-%m-%d %H:%M}", now);
|
||||||
|
auto start = logBuffer.size();
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(logBuffer),
|
||||||
|
"[{}] ",
|
||||||
|
timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(logBuffer),
|
||||||
|
"[{}:{}] ",
|
||||||
|
moduleToString(module),
|
||||||
|
levelToString(level)
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(logBuffer),
|
||||||
|
fmt::runtime(message),
|
||||||
|
std::forward<Args>(args)...
|
||||||
|
);
|
||||||
|
|
||||||
|
logBuffer.push_back('\n');
|
||||||
|
auto end = logBuffer.size();
|
||||||
|
lines.emplace_back(logBuffer.data() + start, end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logConsole(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
std::string tempBuffer;
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto timestamp = std::format("{:%Y-%m-%d %H:%M}", now);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
"[{}] ",
|
||||||
|
timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
"[{}:{}] ",
|
||||||
|
moduleToString(module),
|
||||||
|
levelToString(level)
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
fmt::runtime(message),
|
||||||
|
std::forward<Args>(args)...
|
||||||
|
);
|
||||||
|
|
||||||
|
std::cout.write(tempBuffer.data(), tempBuffer.size());
|
||||||
|
std::cout.put('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logDisk(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
// Open the logfile
|
||||||
|
std::ofstream logFile ("log.txt", std::ios::out | std::ios::app);
|
||||||
|
|
||||||
|
if (!logFile.good()) {
|
||||||
|
throw std::runtime_error("Failed to open logfile !");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a temporary buffer
|
||||||
|
std::string tempBuffer;
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto timestamp = std::format("{:%Y-%m-%d %H:%M}", now);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
"[{}] ",
|
||||||
|
timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
"[{}:{}] ",
|
||||||
|
moduleToString(module),
|
||||||
|
levelToString(level)
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
fmt::runtime(message),
|
||||||
|
std::forward<Args>(args)...
|
||||||
|
);
|
||||||
|
|
||||||
|
logFile << tempBuffer << '\n';
|
||||||
|
logFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload to inject a message
|
||||||
|
void Logger::logDisk(std::string_view message) {
|
||||||
|
std::ofstream logFile ("log.txt", std::ios::out | std::ios::app);
|
||||||
|
|
||||||
|
if (!logFile.good()) {
|
||||||
|
throw std::runtime_error("Failed to open logfile !");
|
||||||
|
}
|
||||||
|
|
||||||
|
logFile << message << '\n';
|
||||||
|
logFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logAll(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
// Logs to all targets !
|
||||||
|
logRAM(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
|
||||||
|
logConsole(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
|
||||||
|
logDisk(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logError(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
logDisk(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
|
||||||
|
logConsole(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Logger::merge(std::string_view source) {
|
||||||
|
/*
|
||||||
|
This merges a dumped logger into this one
|
||||||
|
Assumes the other logger is already formated.
|
||||||
|
This allows to add arbitrary strings into the logs
|
||||||
|
*/
|
||||||
|
logBuffer += source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::clear() {
|
||||||
|
logBuffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view Logger::moduleToString(LogModule m) {
|
||||||
|
using enum LogModule;
|
||||||
|
switch (m) {
|
||||||
|
case ENGINE: return "Engine";
|
||||||
|
case RENDERER: return "Renderer";
|
||||||
|
case GLFW: return "GLFW";
|
||||||
|
case CLEANUP: return "CLEANUP";
|
||||||
|
default: return "Unkown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view Logger::levelToString(LogLevel l) {
|
||||||
|
using enum LogLevel;
|
||||||
|
switch (l) {
|
||||||
|
case EDEBUG: return "Debug";
|
||||||
|
case EINFO: return "Info";
|
||||||
|
case EINIT: return "Init";
|
||||||
|
case EWARN: return "Warn";
|
||||||
|
case EERROR: return "Error";
|
||||||
|
case EFATAL: return "Fatal";
|
||||||
|
default: return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -74,6 +74,35 @@ struct AllocatedImage {
|
|||||||
VkFormat imageFormat;
|
VkFormat imageFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AllocatedBuffer {
|
||||||
|
VkBuffer buffer;
|
||||||
|
VmaAllocation allocation;
|
||||||
|
VmaAllocationInfo info;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
alignas(16) glm::vec3 position;
|
||||||
|
float uv_x;
|
||||||
|
alignas(16) glm::vec3 normal;
|
||||||
|
float uv_y;
|
||||||
|
glm::vec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Holds the ressouces required for a mesh
|
||||||
|
struct GPUMeshBuffers {
|
||||||
|
AllocatedBuffer indexBuffer;
|
||||||
|
AllocatedBuffer vertexBuffer;
|
||||||
|
VkDeviceAddress vertexBufferAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GPUDrawPushConstants {
|
||||||
|
glm::mat4 worldMatrix;
|
||||||
|
VkDeviceAddress vertexBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
// "Global" ? (I hope so) logger
|
||||||
|
Logger logger;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class Callback {
|
|||||||
|
|
||||||
void Callback::keyboardCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
void Callback::keyboardCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Info] Key pressed, key {}", key);
|
logger.logRAM(LogModule::GLFW, LogLevel::EINFO, "Key pressed, key {}", key);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ class Engine {
|
|||||||
//========== Class Members ==========
|
//========== Class Members ==========
|
||||||
bool _isInitialized { false };
|
bool _isInitialized { false };
|
||||||
int _frameNumber { 0 };
|
int _frameNumber { 0 };
|
||||||
VkExtent2D _windowExtent { 1920, 1080 };
|
VkExtent2D _windowExtent;
|
||||||
|
|
||||||
GLFWwindow *window { nullptr };
|
GLFWwindow *window { nullptr };
|
||||||
|
|
||||||
@ -99,6 +99,7 @@ class Engine {
|
|||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
bool _requestResize;
|
bool _requestResize;
|
||||||
|
bool _requestRez; // Resolution
|
||||||
|
|
||||||
// Push constants
|
// Push constants
|
||||||
std::vector<ComputeEffect> backgroundEffects;
|
std::vector<ComputeEffect> backgroundEffects;
|
||||||
@ -115,6 +116,18 @@ class Engine {
|
|||||||
// ImGUI memory editor
|
// ImGUI memory editor
|
||||||
MemoryEditor _memEdit;
|
MemoryEditor _memEdit;
|
||||||
|
|
||||||
|
// Logger
|
||||||
|
Logger _logger;
|
||||||
|
|
||||||
|
// Sum things
|
||||||
|
int prevID = 0;
|
||||||
|
|
||||||
|
// Mesh
|
||||||
|
VkPipelineLayout _meshPipelineLayout;
|
||||||
|
VkPipeline _meshPipeline;
|
||||||
|
GPUMeshBuffers rectangle;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
@ -129,6 +142,8 @@ class Engine {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using enum LogModule;
|
||||||
|
using enum LogLevel;
|
||||||
// Init functions
|
// Init functions
|
||||||
void initRender();
|
void initRender();
|
||||||
void initVulkan();
|
void initVulkan();
|
||||||
@ -137,10 +152,31 @@ class Engine {
|
|||||||
void initSyncStructures();
|
void initSyncStructures();
|
||||||
void initDescriptors();
|
void initDescriptors();
|
||||||
void initPipelines();
|
void initPipelines();
|
||||||
void initTrianglePipeline();
|
|
||||||
void initBackgroundPipelines();
|
void initBackgroundPipelines();
|
||||||
|
void initTrianglePipeline();
|
||||||
|
void initMeshPipeline();
|
||||||
void initImgui();
|
void initImgui();
|
||||||
|
|
||||||
|
// Default data
|
||||||
|
void initDefaultData();
|
||||||
|
|
||||||
|
// Allocations
|
||||||
|
AllocatedBuffer createBuffer(
|
||||||
|
size_t allocSize,
|
||||||
|
VkBufferUsageFlags usage,
|
||||||
|
VmaMemoryUsage memoryUsage
|
||||||
|
);
|
||||||
|
|
||||||
|
void destroyBuffer(
|
||||||
|
const AllocatedBuffer& buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
// Meshes
|
||||||
|
GPUMeshBuffers uploadMesh(
|
||||||
|
std::span<uint32_t> indices,
|
||||||
|
std::span<Vertex> vertices
|
||||||
|
);
|
||||||
|
|
||||||
// Random functions
|
// Random functions
|
||||||
void createSwapchain(
|
void createSwapchain(
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
@ -163,8 +199,6 @@ class Engine {
|
|||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height
|
uint32_t height
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -181,6 +215,7 @@ class Engine {
|
|||||||
#define PIPELINES_IMPL
|
#define PIPELINES_IMPL
|
||||||
#define CALLBACK_IMPL
|
#define CALLBACK_IMPL
|
||||||
#define TIMER_IMPL
|
#define TIMER_IMPL
|
||||||
|
#define LOGGER_IMPL
|
||||||
#define TYPES_IMPL
|
#define TYPES_IMPL
|
||||||
#define VMA_IMPLEMENTATION
|
#define VMA_IMPLEMENTATION
|
||||||
|
|
||||||
@ -192,6 +227,7 @@ class Engine {
|
|||||||
#include "pipelines.h"
|
#include "pipelines.h"
|
||||||
#include "Common/Types.h"
|
#include "Common/Types.h"
|
||||||
#include "Common/Timer.h"
|
#include "Common/Timer.h"
|
||||||
|
#include "Common/Logger.h"
|
||||||
|
|
||||||
// Imgui
|
// Imgui
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
@ -203,11 +239,14 @@ class Engine {
|
|||||||
#include "VkBootstrap.h"
|
#include "VkBootstrap.h"
|
||||||
#include "vk_mem_alloc.h"
|
#include "vk_mem_alloc.h"
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#ifndef DEBUG
|
|
||||||
constexpr bool bUseValidationLayers = false;
|
#ifdef DEBUG
|
||||||
#else
|
|
||||||
constexpr bool bUseValidationLayers = true;
|
constexpr bool bUseValidationLayers = true;
|
||||||
|
#else
|
||||||
|
constexpr bool bUseValidationLayers = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Abort when there is an error
|
// Abort when there is an error
|
||||||
@ -230,17 +269,30 @@ constexpr bool bUseValidationLayers = true;
|
|||||||
void Engine::init() {
|
void Engine::init() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::ifstream infile("LICENSE");
|
std::ifstream infile("LICENSE");
|
||||||
fmt::println("[Engine:Init] Initializing the engine...");
|
_logger.logAll(ENGINE, EINIT, "Initializing the engine...");
|
||||||
fmt::println("[Engine:Info] Current engine version {}", BUILD_ID);
|
_logger.logAll(ENGINE, EINFO, "Current engine version {}", BUILD_ID);
|
||||||
fmt::println("[Engine:Info] Compiled on {} at {}", __DATE__ ,__TIME__);
|
_logger.logAll(ENGINE, EINFO, "Compiled on {} at {}", __DATE__ ,__TIME__);
|
||||||
if (infile.good()) {
|
if (infile.good()) {
|
||||||
std::string sLine;
|
std::string sLine;
|
||||||
std::getline(infile, sLine);
|
std::getline(infile, sLine);
|
||||||
fmt::println("[Engine:Info] Current Licence : {}", sLine);
|
_logger.logAll(ENGINE, EINFO, "Current Licence : {}", sLine);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
glfwInit();
|
if(!glfwInit()) {
|
||||||
|
throw std::runtime_error("Failed to init GLFW !");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get primary monitor
|
||||||
|
GLFWmonitor* monitor { glfwGetPrimaryMonitor() };
|
||||||
|
|
||||||
|
// Get video mode (resolution)
|
||||||
|
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||||
|
|
||||||
|
if(mode) {
|
||||||
|
_windowExtent.width = mode->width;
|
||||||
|
_windowExtent.height = mode->height;
|
||||||
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||||
@ -257,16 +309,18 @@ void Engine::init() {
|
|||||||
|
|
||||||
initRender();
|
initRender();
|
||||||
|
|
||||||
|
initDefaultData();
|
||||||
|
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Engine Initialized !");
|
_logger.logRAM(ENGINE, EINIT, "Engine Initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::cleanup() {
|
void Engine::cleanup() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Cleanup] Cleaning up...");
|
_logger.logConsole(CLEANUP, EINFO, "Cleaning up...");
|
||||||
#endif
|
#endif
|
||||||
if (_isInitialized) {
|
if (_isInitialized) {
|
||||||
// Wait for the GPU to stop working
|
// Wait for the GPU to stop working
|
||||||
@ -298,8 +352,10 @@ void Engine::cleanup() {
|
|||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.logDisk("=========================================================================");
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Cleanup] Engine cleaned up !");
|
_logger.logConsole(CLEANUP, EINFO, "Engine cleaned up !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +377,7 @@ void Engine::draw() {
|
|||||||
_requestResize = true;
|
_requestResize = true;
|
||||||
return;
|
return;
|
||||||
} else if (aquireResult != VK_SUCCESS) {
|
} else if (aquireResult != VK_SUCCESS) {
|
||||||
throw std::runtime_error("[Engine:Error] Failed to aquire swapchain image");
|
throw std::runtime_error("Failed to aquire swapchain image");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset fences to redo sync
|
// Reset fences to redo sync
|
||||||
@ -436,16 +492,15 @@ void Engine::draw() {
|
|||||||
|
|
||||||
VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, getCurrentFrame()._renderFence));
|
VK_CHECK(vkQueueSubmit2(_graphicsQueue, 1, &submit, getCurrentFrame()._renderFence));
|
||||||
|
|
||||||
VkPresentInfoKHR presentInfo = {};
|
VkPresentInfoKHR presentInfo {
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||||
presentInfo.pNext = nullptr;
|
.pNext = nullptr,
|
||||||
presentInfo.pSwapchains = &_swapchain;
|
.waitSemaphoreCount = 1,
|
||||||
presentInfo.swapchainCount = 1;
|
.pWaitSemaphores = &renderSemaphore,
|
||||||
|
.swapchainCount = 1,
|
||||||
presentInfo.pWaitSemaphores = &renderSemaphore;
|
.pSwapchains = &_swapchain,
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
.pImageIndices = &swapchainImageIndex
|
||||||
|
};
|
||||||
presentInfo.pImageIndices = &swapchainImageIndex;
|
|
||||||
|
|
||||||
VkResult presentResult {vkQueuePresentKHR(_graphicsQueue, &presentInfo)};
|
VkResult presentResult {vkQueuePresentKHR(_graphicsQueue, &presentInfo)};
|
||||||
|
|
||||||
@ -454,7 +509,7 @@ void Engine::draw() {
|
|||||||
_requestResize = true;
|
_requestResize = true;
|
||||||
return;
|
return;
|
||||||
} else if (presentResult != VK_SUCCESS) {
|
} else if (presentResult != VK_SUCCESS) {
|
||||||
throw std::runtime_error("[Engine:Error] Failed to present swapchain image");
|
throw std::runtime_error("Failed to present swapchain image");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -463,7 +518,7 @@ void Engine::draw() {
|
|||||||
|
|
||||||
void Engine::run() {
|
void Engine::run() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Info] Running...");
|
_logger.logAll(ENGINE, EINFO,"Running...");
|
||||||
RunTimer timer;
|
RunTimer timer;
|
||||||
timer.startTimer();
|
timer.startTimer();
|
||||||
#endif
|
#endif
|
||||||
@ -471,6 +526,12 @@ void Engine::run() {
|
|||||||
|
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
// Pipeline change monitor
|
||||||
|
int currentID = currentBackgroundEffect;
|
||||||
|
if (prevID != currentID) {
|
||||||
|
_logger.logRAM(ENGINE, EINFO, "Background shader changed");
|
||||||
|
}
|
||||||
|
prevID = currentID;
|
||||||
|
|
||||||
int w, h;
|
int w, h;
|
||||||
glfwGetFramebufferSize(window, &w, &h);
|
glfwGetFramebufferSize(window, &w, &h);
|
||||||
@ -493,9 +554,13 @@ void Engine::run() {
|
|||||||
|
|
||||||
buildImgui();
|
buildImgui();
|
||||||
draw();
|
draw();
|
||||||
|
// Merge glfw logger with main logger
|
||||||
|
_logger.merge(logger.logBuffer);
|
||||||
|
logger.clear();
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Info] Engine has finished running after {} seconds!", timer.endTimer());
|
// Not an error but logs to required targets
|
||||||
|
_logger.logError(ENGINE, EINFO, "Engine has finished running after {} seconds!", timer.endTimer());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,11 +580,11 @@ void Engine::initRender() {
|
|||||||
|
|
||||||
void Engine::initVulkan() {
|
void Engine::initVulkan() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Initializing Vulkan...");
|
_logger.logRAM(ENGINE, EINIT, "Initializing Vulkan...");
|
||||||
#endif
|
#endif
|
||||||
vkb::InstanceBuilder builder;
|
vkb::InstanceBuilder builder;
|
||||||
|
|
||||||
// Create a basic VK instance, with debuging features
|
// Create a basic VK instance, with debuging features if compiled in debug mode
|
||||||
auto instRet = builder.set_app_name("Engine")
|
auto instRet = builder.set_app_name("Engine")
|
||||||
.request_validation_layers(bUseValidationLayers)
|
.request_validation_layers(bUseValidationLayers)
|
||||||
.use_default_debug_messenger()
|
.use_default_debug_messenger()
|
||||||
@ -562,9 +627,9 @@ void Engine::initVulkan() {
|
|||||||
.value();
|
.value();
|
||||||
|
|
||||||
vkb::DeviceBuilder deviceBuilder { physicalDevice };
|
vkb::DeviceBuilder deviceBuilder { physicalDevice };
|
||||||
#ifdef DEBUG
|
|
||||||
fmt::println("[Engine:Info] Device {}", physicalDevice.name);
|
_logger.logAll(ENGINE, EINFO, "Device {}", physicalDevice.name);
|
||||||
#endif
|
|
||||||
vkb::Device vkbDevice { deviceBuilder.build().value() };
|
vkb::Device vkbDevice { deviceBuilder.build().value() };
|
||||||
|
|
||||||
_device = { vkbDevice.device };
|
_device = { vkbDevice.device };
|
||||||
@ -581,20 +646,29 @@ void Engine::initVulkan() {
|
|||||||
|
|
||||||
vmaCreateAllocator(&allocatorInfo, &_allocator);
|
vmaCreateAllocator(&allocatorInfo, &_allocator);
|
||||||
|
|
||||||
_mainDeletionQueue.pushFunction([&]() {
|
_mainDeletionQueue.pushFunction([this]() {
|
||||||
|
#ifdef DEBUG
|
||||||
|
logger.logConsole(CLEANUP, EINFO, "Allocator");
|
||||||
|
#endif
|
||||||
vmaDestroyAllocator(_allocator);
|
vmaDestroyAllocator(_allocator);
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Vulkan initialized !");
|
_logger.logRAM(ENGINE, EINIT, "Vulkan initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initSwapchain() {
|
void Engine::initSwapchain() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Initializing the swapchain...");
|
_logger.logRAM(ENGINE, EINIT, "Initializing the swapchain...");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
glfwGetFramebufferSize(
|
||||||
|
window,
|
||||||
|
(int*)&_windowExtent.width,
|
||||||
|
(int*)&_windowExtent.height
|
||||||
|
);
|
||||||
|
|
||||||
createSwapchain(_windowExtent.width, _windowExtent.height);
|
createSwapchain(_windowExtent.width, _windowExtent.height);
|
||||||
|
|
||||||
VkExtent3D drawImageExtent = {
|
VkExtent3D drawImageExtent = {
|
||||||
@ -671,13 +745,13 @@ void Engine::initSwapchain() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Swapchain initialized !");
|
_logger.logRAM(ENGINE, EINIT, "Swapchain initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initCommands() {
|
void Engine::initCommands() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Initializing Vulkan commands..");
|
_logger.logRAM(ENGINE, EINIT, "Initializing Vulkan commands..");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VkCommandPoolCreateInfo commandPoolInfo = {
|
VkCommandPoolCreateInfo commandPoolInfo = {
|
||||||
@ -707,8 +781,8 @@ void Engine::initCommands() {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Immediate commands
|
|
||||||
|
|
||||||
|
// Immediate commands
|
||||||
VK_CHECK(
|
VK_CHECK(
|
||||||
vkCreateCommandPool(
|
vkCreateCommandPool(
|
||||||
_device,
|
_device,
|
||||||
@ -737,13 +811,13 @@ void Engine::initCommands() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Vulkan commands initialized !");
|
_logger.logRAM(ENGINE, EINIT, "Vulkan commands initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initSyncStructures() {
|
void Engine::initSyncStructures() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Creating sync structures...");
|
_logger.logRAM(ENGINE, EINIT, "Creating sync structures...");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Render semaphores, depends on swapchain
|
// Render semaphores, depends on swapchain
|
||||||
@ -865,19 +939,24 @@ void Engine::initDescriptors(){
|
|||||||
|
|
||||||
void Engine::initPipelines() {
|
void Engine::initPipelines() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Initializing pipelines...");
|
_logger.logRAM(ENGINE, EINIT, "Initializing pipelines...");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// COMPUTE PIPELINES
|
||||||
initBackgroundPipelines();
|
initBackgroundPipelines();
|
||||||
|
|
||||||
|
// GRAPHICS PIPELINES
|
||||||
initTrianglePipeline();
|
initTrianglePipeline();
|
||||||
|
initMeshPipeline();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Pipelines initialized !");
|
_logger.logRAM(ENGINE, EINIT, "Pipelines initialized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initBackgroundPipelines() {
|
void Engine::initBackgroundPipelines() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Initializing compute pipelines...");
|
_logger.logRAM(ENGINE, EINIT, "Initializing compute pipelines...");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -1025,13 +1104,13 @@ void Engine::initBackgroundPipelines() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Compute pipelines initalized !");
|
_logger.logRAM(ENGINE, EINIT, "Compute pipelines initalized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::initTrianglePipeline() {
|
void Engine::initTrianglePipeline() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Initializing triangle pipeline...");
|
_logger.logRAM(ENGINE, EINIT, "Initializing triangle pipeline...");
|
||||||
#endif
|
#endif
|
||||||
// Create the shader
|
// Create the shader
|
||||||
VkShaderModule triangleFragShader;
|
VkShaderModule triangleFragShader;
|
||||||
@ -1106,7 +1185,81 @@ void Engine::initTrianglePipeline() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Init] Triangle pipeline initalized !");
|
_logger.logRAM(ENGINE, EINIT, "Triangle pipeline initalized !");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::initMeshPipeline() {
|
||||||
|
#ifdef DEBUG
|
||||||
|
_logger.logRAM(ENGINE, EINIT, "Initializing mesh pipeline...");
|
||||||
|
#endif
|
||||||
|
VkShaderModule triangleFragShader;
|
||||||
|
if (!vkutil::loadShaderModule("shaders/colored_triangle_fragment.spv", _device, &triangleFragShader)) {
|
||||||
|
fmt::println("[Engine:Error] Error when building the triangle fragment shader module");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_logger.logRAM(ENGINE, EINFO, "Triangle fragment shader succesfully loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
VkShaderModule triangleVertexShader;
|
||||||
|
if (!vkutil::loadShaderModule("shaders/colored_triangle_mesh.spv", _device, &triangleVertexShader)) {
|
||||||
|
fmt::println("[Engine:Error] Error when building the triangle vertex shader module");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_logger.logRAM(ENGINE, EINFO, "Triangle vertex shader succesfully loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPushConstantRange bufferRange{};
|
||||||
|
bufferRange.offset = 0;
|
||||||
|
bufferRange.size = offsetof(GPUDrawPushConstants, vertexBuffer) + sizeof(VkDeviceAddress);
|
||||||
|
bufferRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo = vkinit::pipelineLayoutCreateInfo();
|
||||||
|
pipelineLayoutInfo.pPushConstantRanges = &bufferRange;
|
||||||
|
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
||||||
|
|
||||||
|
VK_CHECK(vkCreatePipelineLayout(_device, &pipelineLayoutInfo, nullptr, &_meshPipelineLayout));
|
||||||
|
|
||||||
|
PipelineBuilder pipelineBuilder;
|
||||||
|
|
||||||
|
// Use the triangle layout we created
|
||||||
|
pipelineBuilder._pipelineLayout = _meshPipelineLayout;
|
||||||
|
// Connecting the vertex and pixel shaders to the pipeline
|
||||||
|
pipelineBuilder.setShaders(triangleVertexShader, triangleFragShader);
|
||||||
|
// It will draw triangles
|
||||||
|
pipelineBuilder.setInputTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||||
|
// Filled triangles
|
||||||
|
pipelineBuilder.setPolygonMode(VK_POLYGON_MODE_FILL);
|
||||||
|
// No backface culling
|
||||||
|
pipelineBuilder.setCullMode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE);
|
||||||
|
// No multisampling
|
||||||
|
pipelineBuilder.setMultisamplingNone();
|
||||||
|
// No blending
|
||||||
|
pipelineBuilder.disableBlending();
|
||||||
|
|
||||||
|
pipelineBuilder.disableDepthtest();
|
||||||
|
|
||||||
|
// Connect the image format we will draw into, from draw image
|
||||||
|
pipelineBuilder.setColorAttachmentFormat(_drawImage.imageFormat);
|
||||||
|
pipelineBuilder.setDepthFormat(VK_FORMAT_UNDEFINED);
|
||||||
|
|
||||||
|
// Finally build the pipeline
|
||||||
|
_meshPipeline = pipelineBuilder.buildPipeline(_device);
|
||||||
|
|
||||||
|
// Clean structures
|
||||||
|
vkDestroyShaderModule(_device, triangleFragShader, nullptr);
|
||||||
|
vkDestroyShaderModule(_device, triangleVertexShader, nullptr);
|
||||||
|
|
||||||
|
_mainDeletionQueue.pushFunction([this]() {
|
||||||
|
vkDestroyPipelineLayout(_device, _meshPipelineLayout, nullptr);
|
||||||
|
vkDestroyPipeline(_device, _meshPipeline, nullptr);
|
||||||
|
});
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
_logger.logRAM(ENGINE, EINIT, "Mesh pipeline initialized !");
|
||||||
|
std::cout << "sizeof(GPUDrawPushConstants) = " << sizeof(GPUDrawPushConstants) << std::endl;
|
||||||
|
std::cout << "offsetof(GPUDrawPushConstants, worldMatrix) = " << offsetof(GPUDrawPushConstants, worldMatrix) << std::endl;
|
||||||
|
std::cout << "offsetof(GPUDrawPushConstants, vertexBuffer) = " << offsetof(GPUDrawPushConstants, vertexBuffer) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1227,6 +1380,203 @@ void Engine::initImgui() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//====================================
|
||||||
|
//=== Allocation-related Functions ===
|
||||||
|
//====================================
|
||||||
|
|
||||||
|
AllocatedBuffer Engine::createBuffer(
|
||||||
|
size_t allocSize,
|
||||||
|
VkBufferUsageFlags usage,
|
||||||
|
VmaMemoryUsage memoryUsage
|
||||||
|
) {
|
||||||
|
// Allocate the buffer
|
||||||
|
VkBufferCreateInfo bufferInfo {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.size = allocSize,
|
||||||
|
.usage = usage
|
||||||
|
};
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo vmaAllocInfo {
|
||||||
|
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
.usage = memoryUsage
|
||||||
|
};
|
||||||
|
|
||||||
|
AllocatedBuffer newBuffer;
|
||||||
|
|
||||||
|
// Allocate the buffer
|
||||||
|
VK_CHECK(
|
||||||
|
vmaCreateBuffer(
|
||||||
|
_allocator,
|
||||||
|
&bufferInfo,
|
||||||
|
&vmaAllocInfo,
|
||||||
|
&newBuffer.buffer,
|
||||||
|
&newBuffer.allocation,
|
||||||
|
&newBuffer.info
|
||||||
|
);
|
||||||
|
);
|
||||||
|
|
||||||
|
return newBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::destroyBuffer(
|
||||||
|
const AllocatedBuffer& buffer
|
||||||
|
) {
|
||||||
|
vmaDestroyBuffer(
|
||||||
|
_allocator,
|
||||||
|
buffer.buffer,
|
||||||
|
buffer.allocation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================
|
||||||
|
//=== Mesh-related functions ===
|
||||||
|
//==============================
|
||||||
|
|
||||||
|
GPUMeshBuffers Engine::uploadMesh(
|
||||||
|
std::span<uint32_t> indices,
|
||||||
|
std::span<Vertex> vertices
|
||||||
|
) {
|
||||||
|
const size_t vertexBufferSize = vertices.size() * sizeof(Vertex);
|
||||||
|
const size_t indexBufferSize = indices.size() * sizeof(uint32_t);
|
||||||
|
|
||||||
|
GPUMeshBuffers newSurface;
|
||||||
|
|
||||||
|
// Create a vertex buffer
|
||||||
|
newSurface.vertexBuffer = createBuffer(
|
||||||
|
vertexBufferSize,
|
||||||
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||||
|
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
|
||||||
|
VMA_MEMORY_USAGE_GPU_ONLY
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get the address of the vertex buffer
|
||||||
|
VkBufferDeviceAddressInfo deviceAddressInfo {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
|
||||||
|
.buffer = newSurface.vertexBuffer.buffer
|
||||||
|
};
|
||||||
|
newSurface.vertexBufferAddress = vkGetBufferDeviceAddress(_device, &deviceAddressInfo);
|
||||||
|
|
||||||
|
// Create a index buffer
|
||||||
|
newSurface.indexBuffer = createBuffer(
|
||||||
|
indexBufferSize,
|
||||||
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||||
|
VMA_MEMORY_USAGE_GPU_ONLY
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create a staging buffer
|
||||||
|
AllocatedBuffer staging = createBuffer(
|
||||||
|
vertexBufferSize + indexBufferSize,
|
||||||
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||||
|
VMA_MEMORY_USAGE_CPU_ONLY
|
||||||
|
);
|
||||||
|
|
||||||
|
void* data = staging.allocation->GetMappedData();
|
||||||
|
|
||||||
|
// Copy vertex buffer
|
||||||
|
memcpy(
|
||||||
|
data,
|
||||||
|
vertices.data(),
|
||||||
|
vertexBufferSize
|
||||||
|
);
|
||||||
|
// Same, but for index buffer
|
||||||
|
memcpy(
|
||||||
|
(char*)data + vertexBufferSize,
|
||||||
|
indices.data(),
|
||||||
|
indexBufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
immediateSubmit(
|
||||||
|
[&](VkCommandBuffer cmd) {
|
||||||
|
VkBufferCopy vertexCopy{ 0 };
|
||||||
|
vertexCopy.dstOffset = 0;
|
||||||
|
vertexCopy.srcOffset = 0;
|
||||||
|
vertexCopy.size = vertexBufferSize;
|
||||||
|
|
||||||
|
vkCmdCopyBuffer(
|
||||||
|
cmd,
|
||||||
|
staging.buffer,
|
||||||
|
newSurface.vertexBuffer.buffer,
|
||||||
|
1,
|
||||||
|
&vertexCopy
|
||||||
|
);
|
||||||
|
|
||||||
|
VkBufferCopy indexCopy{ 0 };
|
||||||
|
indexCopy.dstOffset = 0;
|
||||||
|
indexCopy.srcOffset = vertexBufferSize;
|
||||||
|
indexCopy.size = indexBufferSize;
|
||||||
|
|
||||||
|
vkCmdCopyBuffer(
|
||||||
|
cmd,
|
||||||
|
staging.buffer,
|
||||||
|
newSurface.indexBuffer.buffer,
|
||||||
|
1,
|
||||||
|
&indexCopy
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
destroyBuffer(staging);
|
||||||
|
|
||||||
|
return newSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==============================
|
||||||
|
//=== Default data functions ===
|
||||||
|
//==============================
|
||||||
|
|
||||||
|
void Engine::initDefaultData() {
|
||||||
|
#ifdef DEBUG
|
||||||
|
_logger.logRAM(ENGINE, EINIT, "Creating default data...");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::array<Vertex, 4> rectVertices;
|
||||||
|
|
||||||
|
rectVertices[0].position = {0.5, -0.5, 0};
|
||||||
|
rectVertices[1].position = {0.5, 0.5, 0};
|
||||||
|
rectVertices[2].position = {-0.5, -0.5, 0};
|
||||||
|
rectVertices[3].position = {-0.5, 0.5, 0};
|
||||||
|
|
||||||
|
rectVertices[0].color = {0, 0, 0, 1};
|
||||||
|
rectVertices[1].color = {0.5, 0.5, 0.5, 1};
|
||||||
|
rectVertices[2].color = {1, 0, 0, 1};
|
||||||
|
rectVertices[3].color = {0, 1, 0, 1};
|
||||||
|
|
||||||
|
std::array<uint32_t, 6> rectIndices;
|
||||||
|
|
||||||
|
rectIndices[0] = 0;
|
||||||
|
rectIndices[1] = 1;
|
||||||
|
rectIndices[2] = 2;
|
||||||
|
|
||||||
|
rectIndices[3] = 2;
|
||||||
|
rectIndices[4] = 1;
|
||||||
|
rectIndices[5] = 3;
|
||||||
|
|
||||||
|
rectangle = uploadMesh(
|
||||||
|
rectIndices,
|
||||||
|
rectVertices
|
||||||
|
);
|
||||||
|
|
||||||
|
// Delete the rectangle data on engine shutdown
|
||||||
|
_mainDeletionQueue.pushFunction([this](){
|
||||||
|
destroyBuffer(rectangle.indexBuffer);
|
||||||
|
destroyBuffer(rectangle.vertexBuffer);
|
||||||
|
});
|
||||||
|
#ifdef DEBUG
|
||||||
|
_logger.logRAM(ENGINE, EINIT, "Default data created !");
|
||||||
|
for (size_t i = 0; i < rectIndices.size(); i++) {
|
||||||
|
fmt::println(
|
||||||
|
"index[{}] = {} ({:#x})",
|
||||||
|
i,
|
||||||
|
rectIndices[i],
|
||||||
|
rectIndices[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//================================
|
//================================
|
||||||
//=== Render-related Functions ===
|
//=== Render-related Functions ===
|
||||||
@ -1280,6 +1630,7 @@ void Engine::buildImgui() {
|
|||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
// Docking
|
// Docking
|
||||||
ImGui::DockSpaceOverViewport(); // Fullscreen dockspace
|
ImGui::DockSpaceOverViewport(); // Fullscreen dockspace
|
||||||
|
//_logger.logRAM(ENGINE, EINFO, "Framecount {}", ImGui::GetFrameCount());
|
||||||
|
|
||||||
// Main ImGui things
|
// Main ImGui things
|
||||||
ImGui::ShowDemoWindow();
|
ImGui::ShowDemoWindow();
|
||||||
@ -1292,12 +1643,12 @@ void Engine::buildImgui() {
|
|||||||
)) {
|
)) {
|
||||||
ImVec2 size = ImGui::GetWindowSize();
|
ImVec2 size = ImGui::GetWindowSize();
|
||||||
if (size.x > 0 && size.y > 0) {
|
if (size.x > 0 && size.y > 0) {
|
||||||
// Redimensionner l'image de rendu si la taille du dock a changé
|
// Resize viewport render image if dock size changed
|
||||||
if ((uint32_t)size.x != _drawImage.imageExtent.width ||
|
if ((uint32_t)size.x != _drawImage.imageExtent.width ||
|
||||||
(uint32_t)size.y != _drawImage.imageExtent.height) {
|
(uint32_t)size.y != _drawImage.imageExtent.height) {
|
||||||
resizeRenderImage((uint32_t)size.x, (uint32_t)size.y);
|
resizeRenderImage((uint32_t)size.x, (uint32_t)size.y);
|
||||||
}
|
}
|
||||||
// Afficher la texture en remplissant la zone
|
// Display the texture filling the zone
|
||||||
ImGui::Image(_viewportTextureID, size);
|
ImGui::Image(_viewportTextureID, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1336,6 +1687,17 @@ void Engine::buildImgui() {
|
|||||||
(float*)& selected.data.data4
|
(float*)& selected.data.data4
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
// Logs
|
||||||
|
if(ImGui::Begin("Logs")) {
|
||||||
|
ImGui::TextWrapped("%s", _logger.logBuffer.c_str());
|
||||||
|
float scrollY = ImGui::GetScrollY();
|
||||||
|
float maxScrollY = ImGui::GetScrollMaxY();
|
||||||
|
if (scrollY >= maxScrollY - 1.0f) {
|
||||||
|
ImGui::SetScrollHereY(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
// Memory editor
|
// Memory editor
|
||||||
@ -1463,6 +1825,34 @@ void Engine::drawGeometry(
|
|||||||
//launch a draw command to draw 3 vertices
|
//launch a draw command to draw 3 vertices
|
||||||
vkCmdDraw(cmd, 3, 1, 0, 0);
|
vkCmdDraw(cmd, 3, 1, 0, 0);
|
||||||
|
|
||||||
|
vkCmdBindPipeline(
|
||||||
|
cmd,
|
||||||
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
_meshPipeline
|
||||||
|
);
|
||||||
|
|
||||||
|
GPUDrawPushConstants pushConstants;
|
||||||
|
pushConstants.worldMatrix = glm::mat4{ 1.0f };
|
||||||
|
pushConstants.vertexBuffer = rectangle.vertexBufferAddress;
|
||||||
|
|
||||||
|
vkCmdPushConstants(
|
||||||
|
cmd,
|
||||||
|
_meshPipelineLayout,
|
||||||
|
VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
0,
|
||||||
|
offsetof(GPUDrawPushConstants, vertexBuffer) + sizeof(VkDeviceAddress),
|
||||||
|
&pushConstants
|
||||||
|
);
|
||||||
|
|
||||||
|
vkCmdBindIndexBuffer(
|
||||||
|
cmd,
|
||||||
|
rectangle.indexBuffer.buffer,
|
||||||
|
0,
|
||||||
|
VK_INDEX_TYPE_UINT32
|
||||||
|
);
|
||||||
|
|
||||||
|
vkCmdDrawIndexed(cmd, 6, 1, 0, 0, 0);
|
||||||
|
|
||||||
vkCmdEndRendering(cmd);
|
vkCmdEndRendering(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1564,12 +1954,11 @@ void Engine::immediateSubmit(
|
|||||||
//INT64_MAX
|
//INT64_MAX
|
||||||
);
|
);
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::resizeSwapchain() {
|
void Engine::resizeSwapchain() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Utils] Resizing swapchain...");
|
_logger.logRAM(ENGINE, EINFO, "Resizing swapchain...");
|
||||||
#endif
|
#endif
|
||||||
vkDeviceWaitIdle(_device);
|
vkDeviceWaitIdle(_device);
|
||||||
|
|
||||||
@ -1590,13 +1979,13 @@ void Engine::resizeSwapchain() {
|
|||||||
_requestResize = false;
|
_requestResize = false;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Utils] Swapchain resized !");
|
_logger.logRAM(ENGINE, EINFO, "Swapchain resized !");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::resizeRenderImage(uint32_t width, uint32_t height) {
|
void Engine::resizeRenderImage(uint32_t width, uint32_t height) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Utils] Resizing render image to {}x{}", width, height);
|
_logger.logRAM(ENGINE,EINFO, "Resizing render image to {}x{}", width, height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vkDeviceWaitIdle(_device);
|
vkDeviceWaitIdle(_device);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user