-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5933fb9
commit 315473b
Showing
83 changed files
with
619 additions
and
1,835 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#pragma once | ||
|
||
#include "../include/example_app_base.hpp" | ||
|
||
#include "inexor/vulkan-renderer/rendering/imgui/imgui.hpp" | ||
#include "inexor/vulkan-renderer/rendering/octree/octree_renderer.hpp" | ||
|
||
#include <spdlog/spdlog.h> | ||
|
||
namespace inexor::example_app { | ||
|
||
/// An example application using Inexor vulkan-renderer | ||
class ExampleApp : public ExampleAppBase { | ||
private: | ||
std::unique_ptr<ImGuiRenderer> m_imgui_renderer; | ||
std::unique_ptr<OctreeRenderer> m_octree_renderer; | ||
|
||
public: | ||
ExampleApp(int argc, char **argv); | ||
~ExampleApp(); | ||
|
||
ExampleApp(const ExampleApp &) = delete; | ||
// TODO: Implement me! | ||
ExampleApp(ExampleApp &&) noexcept; | ||
|
||
ExampleApp &operator=(const ExampleApp &) = delete; | ||
// TODO: Implement me! | ||
ExampleApp &operator=(ExampleApp &&) noexcept; | ||
|
||
void initialize() override; | ||
|
||
void load_toml_configuration_file(const std::string &file_name); | ||
|
||
void setup_render_graph() override; | ||
|
||
void cursor_position_callback(GLFWwindow *window, double x_pos, double y_pos) override; | ||
|
||
void keyboard_button_callback(GLFWwindow *window, int key, int scancode, int action, int mods) override; | ||
|
||
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) override; | ||
|
||
void mouse_scroll_callback(GLFWwindow *window, double x_offset, double y_offset) override; | ||
|
||
void update_imgui() override; | ||
}; | ||
|
||
} // namespace inexor::example_app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#pragma once | ||
|
||
#include "inexor/vulkan-renderer/input/keyboard_mouse_data.hpp" | ||
#include "inexor/vulkan-renderer/rendering/render-graph/render_graph.hpp" | ||
#include "inexor/vulkan-renderer/tools/cla_parser.hpp" | ||
#include "inexor/vulkan-renderer/wrapper/device.hpp" | ||
#include "inexor/vulkan-renderer/wrapper/instance.hpp" | ||
#include "inexor/vulkan-renderer/wrapper/surface.hpp" | ||
#include "inexor/vulkan-renderer/wrapper/swapchain.hpp" | ||
#include "inexor/vulkan-renderer/wrapper/window.hpp" | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
namespace inexor::example_app { | ||
|
||
// Using declarations | ||
using inexor::vulkan_renderer::input::KeyboardMouseInputData; | ||
using inexor::vulkan_renderer::render_graph::RenderGraph; | ||
using inexor::vulkan_renderer::tools::CommandLineArgumentParser; | ||
using inexor::vulkan_renderer::wrapper::Device; | ||
using inexor::vulkan_renderer::wrapper::Instance; | ||
using inexor::vulkan_renderer::wrapper::Surface; | ||
using inexor::vulkan_renderer::wrapper::Swapchain; | ||
using inexor::vulkan_renderer::wrapper::Window; | ||
|
||
/// The command line arguments will be parsed into these options | ||
struct CommandLineOptions { | ||
bool stop_on_validation_error{false}; | ||
bool vsync_enabled{false}; | ||
}; | ||
|
||
/// A base class for example apps which use Inexor vulkan-renderer | ||
class ExampleAppBase { | ||
private: | ||
const std::string m_wnd_title = "inexor-vulkan-renderer-example"; | ||
std::uint32_t m_wnd_width{1280}; | ||
std::uint32_t m_wnd_height{720}; | ||
Window::Mode m_wnd_mode{Window::Mode::WINDOWED}; | ||
bool m_wnd_resized{false}; | ||
|
||
std::unique_ptr<Window> m_window; | ||
std::unique_ptr<Instance> m_instance; | ||
std::unique_ptr<Surface> m_surface; | ||
std::unique_ptr<Device> m_device; | ||
std::shared_ptr<Swapchain> m_swapchain; | ||
std::unique_ptr<KeyboardMouseInputData> m_input_data; | ||
|
||
void initialize_spdlog(); | ||
|
||
void recreate_swapchain(); | ||
|
||
/// Because GLFW is a C-style API, we can't use a pointer to non-static class methods as window or input callback. | ||
/// A good explanation can be found on Stack Overflow: | ||
/// https://stackoverflow.com/questions/7676971/pointing-to-a-function-that-is-a-class-member-glfw-setkeycallback | ||
/// In order to fix this, we can pass a lambda to glfwSetKeyCallback, which calls our callbacks internally. There is | ||
/// another problem: Inside of the lambda, we need to call the member function. In order to do so, we need to have | ||
/// access to the this-pointer. Unfortunately, the this-pointer can't be captured in the lambda capture like | ||
/// [this](){}, because the glfw would not accept the lambda then. To fix this problem, we store the this pointer | ||
/// using glfwSetWindowUserPointer. Inside of these lambdas, we then cast the pointer to Application* again, | ||
/// allowing us to finally use the callbacks. | ||
void setup_window_and_input_callbacks(); | ||
|
||
protected: | ||
CommandLineOptions m_options; | ||
|
||
VKAPI_ATTR VkBool32 VKAPI_CALL | ||
validation_layer_debug_messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT, | ||
VkDebugUtilsMessageTypeFlagsEXT, | ||
const VkDebugUtilsMessengerCallbackDataEXT *, | ||
void *); | ||
|
||
std::shared_ptr<RenderGraph> m_rendergraph; | ||
|
||
public: | ||
ExampleAppBase(int argc, char **argv); | ||
virtual ~ExampleAppBase(); | ||
|
||
ExampleAppBase(const ExampleAppBase &) = delete; | ||
// TODO: Implement me! | ||
ExampleAppBase(ExampleAppBase &&) noexcept; | ||
|
||
ExampleAppBase &operator=(const ExampleAppBase &) = delete; | ||
// TODO: Implement me! | ||
ExampleAppBase &operator=(ExampleAppBase &&) noexcept; | ||
|
||
virtual void evaluate_command_line_arguments(const CommandLineArgumentParser &parser) = 0; | ||
virtual void cursor_position_callback(GLFWwindow *, double, double) = 0; | ||
virtual void keyboard_button_callback(GLFWwindow *, int, int, int, int) = 0; | ||
virtual void mouse_button_callback(GLFWwindow *, int, int, int) = 0; | ||
virtual void mouse_scroll_callback(GLFWwindow *, double, double) = 0; | ||
virtual void initialize() = 0; | ||
virtual void process_mouse_input() = 0; | ||
virtual void process_keyboard_input() = 0; | ||
virtual void render_frame() = 0; | ||
virtual void setup_device() = 0; | ||
virtual void setup_render_graph() = 0; | ||
virtual void shutdown() = 0; | ||
virtual void update_imgui() = 0; | ||
}; | ||
|
||
} // namespace inexor::example_app |
20 changes: 19 additions & 1 deletion
20
example/CMakeLists.txt → example-app/src/CMakeLists.txt
100755 → 100644
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include "../include/example_app.hpp" | ||
|
||
#include <toml.hpp> | ||
|
||
#include <memory> | ||
|
||
namespace inexor::example_app { | ||
|
||
ExampleApp::ExampleApp(int argc, char **argv) : ExampleAppBase(argc, argv) {} | ||
|
||
ExampleApp::~ExampleApp() {} | ||
|
||
void ExampleApp::initialize() { | ||
// | ||
} | ||
|
||
void ExampleApp::setup_render_graph() { | ||
spdlog::trace("Setting up rendergraph"); | ||
m_octree_renderer = std::make_unique<OctreeRenderer>(m_rendergraph); | ||
m_imgui_renderer = std::make_unique<ImGuiRenderer>(m_rendergraph); | ||
} | ||
|
||
void ExampleApp::update_imgui() { | ||
ImGuiIO &io = ImGui::GetIO(); | ||
io.DeltaTime = m_time_passed + 0.00001f; | ||
auto cursor_pos = m_input_data->get_cursor_pos(); | ||
io.MousePos = ImVec2(static_cast<float>(cursor_pos[0]), static_cast<float>(cursor_pos[1])); | ||
io.MouseDown[0] = m_input_data->is_mouse_button_pressed(GLFW_MOUSE_BUTTON_LEFT); | ||
io.MouseDown[1] = m_input_data->is_mouse_button_pressed(GLFW_MOUSE_BUTTON_RIGHT); | ||
io.DisplaySize = | ||
ImVec2(static_cast<float>(m_swapchain->extent().width), static_cast<float>(m_swapchain->extent().height)); | ||
|
||
ImGui::NewFrame(); | ||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0); | ||
ImGui::SetNextWindowPos(ImVec2(10, 10)); | ||
ImGui::SetNextWindowSize(ImVec2(330, 0)); | ||
ImGui::Begin("Inexor Vulkan-renderer", nullptr, | ||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove); | ||
ImGui::Text("%s", m_device->gpu_name().c_str()); | ||
ImGui::Text("Engine version %d.%d.%d (Git sha %s)", ENGINE_VERSION[0], ENGINE_VERSION[1], ENGINE_VERSION[2], | ||
BUILD_GIT); | ||
ImGui::Text("Vulkan API %d.%d.%d", VK_API_VERSION_MAJOR(wrapper::Instance::REQUIRED_VK_API_VERSION), | ||
VK_API_VERSION_MINOR(wrapper::Instance::REQUIRED_VK_API_VERSION), | ||
VK_API_VERSION_PATCH(wrapper::Instance::REQUIRED_VK_API_VERSION)); | ||
const auto &cam_pos = m_camera->position(); | ||
ImGui::Text("Camera position (%.2f, %.2f, %.2f)", cam_pos.x, cam_pos.y, cam_pos.z); | ||
const auto &cam_rot = m_camera->rotation(); | ||
ImGui::Text("Camera rotation: (%.2f, %.2f, %.2f)", cam_rot.x, cam_rot.y, cam_rot.z); | ||
const auto &cam_front = m_camera->front(); | ||
ImGui::Text("Camera vector front: (%.2f, %.2f, %.2f)", cam_front.x, cam_front.y, cam_front.z); | ||
const auto &cam_right = m_camera->right(); | ||
ImGui::Text("Camera vector right: (%.2f, %.2f, %.2f)", cam_right.x, cam_right.y, cam_right.z); | ||
const auto &cam_up = m_camera->up(); | ||
ImGui::Text("Camera vector up (%.2f, %.2f, %.2f)", cam_up.x, cam_up.y, cam_up.z); | ||
ImGui::Text("Yaw: %.2f pitch: %.2f roll: %.2f", m_camera->yaw(), m_camera->pitch(), m_camera->roll()); | ||
const auto cam_fov = m_camera->fov(); | ||
ImGui::Text("Field of view: %d", static_cast<std::uint32_t>(cam_fov)); | ||
ImGui::PushItemWidth(150.0f); | ||
ImGui::PopItemWidth(); | ||
ImGui::PopStyleVar(); | ||
ImGui::End(); | ||
ImGui::EndFrame(); | ||
ImGui::Render(); | ||
} | ||
|
||
} // namespace inexor::example_app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
#include "../include/example_app_base.hpp" | ||
|
||
#include <spdlog/async.h> | ||
#include <spdlog/sinks/basic_file_sink.h> | ||
#include <spdlog/sinks/stdout_color_sinks.h> | ||
#include <spdlog/spdlog.h> | ||
|
||
namespace inexor::example_app { | ||
|
||
ExampleAppBase::ExampleAppBase(int argc, char **argv) { | ||
// Setup spdlog logging library | ||
initialize_spdlog(); | ||
|
||
// Parse and evaluate command line arguments | ||
CommandLineArgumentParser cla_parser; | ||
cla_parser.parse_args(argc, argv); | ||
evaluate_command_line_arguments(cla_parser); | ||
|
||
spdlog::trace("Application version: {}.{}.{}", APP_VERSION[0], APP_VERSION[1], APP_VERSION[2]); | ||
spdlog::trace("Engine version: {}.{}.{}", ENGINE_VERSION[0], ENGINE_VERSION[1], ENGINE_VERSION[2]); | ||
|
||
// NOTE: We must create the window before the VkInstance, otherwise glfwGetRequiredInstanceExtensions fails! | ||
m_window = std::make_unique<Window>(m_wnd_title, m_wnd_width, m_wnd_height, true, true, m_wnd_mode); | ||
setup_window_and_input_callbacks(); | ||
|
||
m_instance = std::make_unique<Instance>( | ||
APP_NAME, ENGINE_NAME, VK_MAKE_API_VERSION(0, APP_VERSION[0], APP_VERSION[1], APP_VERSION[2]), | ||
VK_MAKE_API_VERSION(0, ENGINE_VERSION[0], ENGINE_VERSION[1], ENGINE_VERSION[2]), | ||
validation_layer_debug_messenger_callback); | ||
|
||
m_surface = std::make_unique<Surface>(m_instance->instance(), m_window->window()); | ||
m_input_data = std::make_unique<KeyboardMouseInputData>(); | ||
|
||
m_device = std::make_unique<Device>(*m_instance, m_surface->surface(), physical_device, required_extensions, | ||
required_features, optional_extensions, optional_features); | ||
|
||
m_swapchain = std::make_shared<Swapchain>(*m_device, "Default Swapchain", m_surface->surface(), *m_window, | ||
m_options.vsync_enabled); | ||
} | ||
|
||
ExampleAppBase::~ExampleAppBase() { | ||
spdlog::trace("Shutting down vulkan-renderer-example"); | ||
} | ||
|
||
void ExampleAppBase::initialize_spdlog() { | ||
spdlog::init_thread_pool(8192, 2); | ||
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); | ||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("vulkan-renderer-example.log", true); | ||
auto logger = std::make_shared<spdlog::async_logger>("vulkan-renderer-example", | ||
spdlog::sinks_init_list{console_sink, file_sink}, | ||
spdlog::thread_pool(), spdlog::async_overflow_policy::block); | ||
logger->set_level(spdlog::level::trace); | ||
logger->set_pattern("%Y-%m-%d %T.%f %^%l%$ %5t [%-10n] %v"); | ||
logger->flush_on(spdlog::level::trace); | ||
spdlog::set_default_logger(logger); | ||
spdlog::trace("Inexor vulkan-renderer-example, BUILD " + std::string(__DATE__) + ", " + __TIME__); | ||
} | ||
|
||
void ExampleAppBase::setup_window_and_input_callbacks() { | ||
m_window->set_user_ptr(this); | ||
|
||
m_window->set_resize_callback([](GLFWwindow *window, int width, int height) { | ||
auto *app = static_cast<ExampleAppBase *>(glfwGetWindowUserPointer(window)); | ||
app->m_wnd_resized = true; | ||
}); | ||
|
||
m_window->set_keyboard_button_callback([](GLFWwindow *window, int key, int scancode, int action, int mods) { | ||
auto *app = static_cast<ExampleAppBase *>(glfwGetWindowUserPointer(window)); | ||
app->keyboard_button_callback(window, key, scancode, action, mods); | ||
}); | ||
|
||
m_window->set_cursor_position_callback([](GLFWwindow *window, double xpos, double ypos) { | ||
auto *app = static_cast<ExampleAppBase *>(glfwGetWindowUserPointer(window)); | ||
app->cursor_position_callback(window, xpos, ypos); | ||
}); | ||
|
||
m_window->set_mouse_button_callback([](GLFWwindow *window, int button, int action, int mods) { | ||
auto *app = static_cast<ExampleAppBase *>(glfwGetWindowUserPointer(window)); | ||
app->mouse_button_callback(window, button, action, mods); | ||
}); | ||
|
||
m_window->set_mouse_scroll_callback([](GLFWwindow *window, double xoffset, double yoffset) { | ||
auto *app = static_cast<ExampleAppBase *>(glfwGetWindowUserPointer(window)); | ||
app->mouse_scroll_callback(window, xoffset, yoffset); | ||
}); | ||
} | ||
|
||
void ExampleAppBase::recreate_swapchain() { | ||
// TODO: Implement! | ||
} | ||
|
||
VkBool32 VKAPI_CALL | ||
ExampleAppBase::validation_layer_debug_messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, | ||
VkDebugUtilsMessageTypeFlagsEXT type, | ||
const VkDebugUtilsMessengerCallbackDataEXT *data, | ||
void *user_data) { | ||
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { | ||
spdlog::trace("{}", data->pMessage); | ||
} else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { | ||
spdlog::info("{}", data->pMessage); | ||
} else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { | ||
spdlog::warn("{}", data->pMessage); | ||
} else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { | ||
spdlog::critical("{}", data->pMessage); | ||
} | ||
if (m_options.stop_on_validation_error) { | ||
throw std::runtime_error("[ExampleApp::validation_layer_debug_messenger_callback] Validation error, stopped."); | ||
} | ||
return false; | ||
} | ||
|
||
} // namespace inexor::example_app |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.