mirror of
https://github.com/slendidev/lunar.git
synced 2025-12-16 12:09:52 +02:00
Compare commits
5 Commits
a1061c873a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 59999f211d | |||
| 608dc583be | |||
| c7283c8faf | |||
| 054a196b13 | |||
| c856e0414c |
@@ -34,6 +34,7 @@
|
|||||||
wayland
|
wayland
|
||||||
zlib
|
zlib
|
||||||
sdl3
|
sdl3
|
||||||
|
libinput
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|||||||
14
meson.build
14
meson.build
@@ -23,6 +23,8 @@ vulkan_dep = dependency('vulkan')
|
|||||||
openxr_dep = dependency('openxr')
|
openxr_dep = dependency('openxr')
|
||||||
zlib_dep = dependency('zlib')
|
zlib_dep = dependency('zlib')
|
||||||
sdl3_dep = dependency('sdl3')
|
sdl3_dep = dependency('sdl3')
|
||||||
|
libinput_dep = dependency('libinput')
|
||||||
|
libudev_dep = dependency('libudev')
|
||||||
imgui_src = files(
|
imgui_src = files(
|
||||||
'thirdparty/imgui/imgui.cpp',
|
'thirdparty/imgui/imgui.cpp',
|
||||||
'thirdparty/imgui/imgui_draw.cpp',
|
'thirdparty/imgui/imgui_draw.cpp',
|
||||||
@@ -71,6 +73,15 @@ add_project_arguments(
|
|||||||
'-Wno-switch-enum',
|
'-Wno-switch-enum',
|
||||||
'-Wno-sign-conversion',
|
'-Wno-sign-conversion',
|
||||||
'-Wno-documentation',
|
'-Wno-documentation',
|
||||||
|
'-Wno-float-equal',
|
||||||
|
'-Wno-cast-function-type-strict',
|
||||||
|
'-Wno-exit-time-destructors',
|
||||||
|
'-Wno-zero-as-null-pointer-constant',
|
||||||
|
'-Wno-unused-macros',
|
||||||
|
'-Wno-suggest-override',
|
||||||
|
'-Wno-macro-redefined',
|
||||||
|
'-DVULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE',
|
||||||
|
'-DVULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1',
|
||||||
],
|
],
|
||||||
language : 'cpp'
|
language : 'cpp'
|
||||||
)
|
)
|
||||||
@@ -111,6 +122,7 @@ exe = executable('vr-compositor',
|
|||||||
'src/DescriptorAllocator.cpp',
|
'src/DescriptorAllocator.cpp',
|
||||||
'src/GraphicsPipelineBuilder.cpp',
|
'src/GraphicsPipelineBuilder.cpp',
|
||||||
'src/DescriptorAllocatorGrowable.cpp',
|
'src/DescriptorAllocatorGrowable.cpp',
|
||||||
|
'src/Pipeline.cpp',
|
||||||
'src/Loader.cpp',
|
'src/Loader.cpp',
|
||||||
'src/DescriptorWriter.cpp',
|
'src/DescriptorWriter.cpp',
|
||||||
'src/VulkanRenderer.cpp',
|
'src/VulkanRenderer.cpp',
|
||||||
@@ -130,6 +142,8 @@ exe = executable('vr-compositor',
|
|||||||
zlib_dep,
|
zlib_dep,
|
||||||
sdl3_dep,
|
sdl3_dep,
|
||||||
fastgltf_dep,
|
fastgltf_dep,
|
||||||
|
libinput_dep,
|
||||||
|
libudev_dep,
|
||||||
],
|
],
|
||||||
cpp_args: [
|
cpp_args: [
|
||||||
'--embed-dir=' + join_paths(meson.project_build_root(), 'shaders')
|
'--embed-dir=' + join_paths(meson.project_build_root(), 'shaders')
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ shader_sources = files(
|
|||||||
'triangle.vert',
|
'triangle.vert',
|
||||||
'triangle_mesh.frag',
|
'triangle_mesh.frag',
|
||||||
'triangle_mesh.vert',
|
'triangle_mesh.vert',
|
||||||
|
'tex_image.frag',
|
||||||
)
|
)
|
||||||
|
|
||||||
spirv_shaders = []
|
spirv_shaders = []
|
||||||
|
|||||||
13
shaders/tex_image.frag
Normal file
13
shaders/tex_image.frag
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 in_color;
|
||||||
|
layout (location = 1) in vec2 in_uv;
|
||||||
|
|
||||||
|
layout (location = 0) out vec4 out_frag_color;
|
||||||
|
|
||||||
|
layout (set = 0, binding = 0) uniform sampler2D tex;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
out_frag_color = texture(tex, in_uv) * vec4(in_color, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#extension GL_EXT_buffer_reference : require
|
#extension GL_EXT_buffer_reference : require
|
||||||
|
|
||||||
layout (location = 0) out vec3 out_color;
|
layout (location = 0) out vec3 out_color;
|
||||||
layout (location = 1) out vec3 out_uv;
|
layout (location = 1) out vec2 out_uv;
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
vec3 position;
|
vec3 position;
|
||||||
|
|||||||
@@ -1,20 +1,206 @@
|
|||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <optional>
|
||||||
#include <print>
|
#include <print>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
#include <SDL3/SDL_init.h>
|
#include <SDL3/SDL_init.h>
|
||||||
|
#include <SDL3/SDL_mouse.h>
|
||||||
#include <SDL3/SDL_timer.h>
|
#include <SDL3/SDL_timer.h>
|
||||||
#include <SDL3/SDL_video.h>
|
#include <SDL3/SDL_video.h>
|
||||||
|
|
||||||
#include <imgui_impl_sdl3.h>
|
#include <imgui_impl_sdl3.h>
|
||||||
#include <imgui_impl_vulkan.h>
|
#include <imgui_impl_vulkan.h>
|
||||||
|
|
||||||
|
#include <libinput.h>
|
||||||
|
#include <libudev.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
|
|
||||||
|
#include <smath.hpp>
|
||||||
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "VulkanRenderer.h"
|
#include "VulkanRenderer.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
int open_restricted(char const *path, int flags, void * /*user_data*/)
|
||||||
|
{
|
||||||
|
int fd { open(path, flags | O_CLOEXEC) };
|
||||||
|
return fd < 0 ? -errno : fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_restricted(int fd, void * /*user_data*/) { close(fd); }
|
||||||
|
|
||||||
|
libinput_interface const g_libinput_interface {
|
||||||
|
.open_restricted = open_restricted,
|
||||||
|
.close_restricted = close_restricted,
|
||||||
|
};
|
||||||
|
|
||||||
|
auto linux_key_to_imgui(uint32_t keycode) -> std::optional<ImGuiKey>
|
||||||
|
{
|
||||||
|
switch (keycode) {
|
||||||
|
case KEY_ESC:
|
||||||
|
return ImGuiKey_Escape;
|
||||||
|
case KEY_TAB:
|
||||||
|
return ImGuiKey_Tab;
|
||||||
|
case KEY_ENTER:
|
||||||
|
return ImGuiKey_Enter;
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
return ImGuiKey_Backspace;
|
||||||
|
case KEY_SPACE:
|
||||||
|
return ImGuiKey_Space;
|
||||||
|
case KEY_LEFTSHIFT:
|
||||||
|
return ImGuiKey_LeftShift;
|
||||||
|
case KEY_RIGHTSHIFT:
|
||||||
|
return ImGuiKey_RightShift;
|
||||||
|
case KEY_LEFTCTRL:
|
||||||
|
return ImGuiKey_LeftCtrl;
|
||||||
|
case KEY_RIGHTCTRL:
|
||||||
|
return ImGuiKey_RightCtrl;
|
||||||
|
case KEY_LEFTALT:
|
||||||
|
return ImGuiKey_LeftAlt;
|
||||||
|
case KEY_RIGHTALT:
|
||||||
|
return ImGuiKey_RightAlt;
|
||||||
|
case KEY_LEFTMETA:
|
||||||
|
return ImGuiKey_LeftSuper;
|
||||||
|
case KEY_RIGHTMETA:
|
||||||
|
return ImGuiKey_RightSuper;
|
||||||
|
case KEY_CAPSLOCK:
|
||||||
|
return ImGuiKey_CapsLock;
|
||||||
|
case KEY_NUMLOCK:
|
||||||
|
return ImGuiKey_NumLock;
|
||||||
|
case KEY_SCROLLLOCK:
|
||||||
|
return ImGuiKey_ScrollLock;
|
||||||
|
case KEY_UP:
|
||||||
|
return ImGuiKey_UpArrow;
|
||||||
|
case KEY_DOWN:
|
||||||
|
return ImGuiKey_DownArrow;
|
||||||
|
case KEY_LEFT:
|
||||||
|
return ImGuiKey_LeftArrow;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
return ImGuiKey_RightArrow;
|
||||||
|
case KEY_HOME:
|
||||||
|
return ImGuiKey_Home;
|
||||||
|
case KEY_END:
|
||||||
|
return ImGuiKey_End;
|
||||||
|
case KEY_PAGEUP:
|
||||||
|
return ImGuiKey_PageUp;
|
||||||
|
case KEY_PAGEDOWN:
|
||||||
|
return ImGuiKey_PageDown;
|
||||||
|
case KEY_INSERT:
|
||||||
|
return ImGuiKey_Insert;
|
||||||
|
case KEY_DELETE:
|
||||||
|
return ImGuiKey_Delete;
|
||||||
|
case KEY_F1:
|
||||||
|
return ImGuiKey_F1;
|
||||||
|
case KEY_F2:
|
||||||
|
return ImGuiKey_F2;
|
||||||
|
case KEY_F3:
|
||||||
|
return ImGuiKey_F3;
|
||||||
|
case KEY_F4:
|
||||||
|
return ImGuiKey_F4;
|
||||||
|
case KEY_F5:
|
||||||
|
return ImGuiKey_F5;
|
||||||
|
case KEY_F6:
|
||||||
|
return ImGuiKey_F6;
|
||||||
|
case KEY_F7:
|
||||||
|
return ImGuiKey_F7;
|
||||||
|
case KEY_F8:
|
||||||
|
return ImGuiKey_F8;
|
||||||
|
case KEY_F9:
|
||||||
|
return ImGuiKey_F9;
|
||||||
|
case KEY_F10:
|
||||||
|
return ImGuiKey_F10;
|
||||||
|
case KEY_F11:
|
||||||
|
return ImGuiKey_F11;
|
||||||
|
case KEY_F12:
|
||||||
|
return ImGuiKey_F12;
|
||||||
|
case KEY_0:
|
||||||
|
return ImGuiKey_0;
|
||||||
|
case KEY_1:
|
||||||
|
return ImGuiKey_1;
|
||||||
|
case KEY_2:
|
||||||
|
return ImGuiKey_2;
|
||||||
|
case KEY_3:
|
||||||
|
return ImGuiKey_3;
|
||||||
|
case KEY_4:
|
||||||
|
return ImGuiKey_4;
|
||||||
|
case KEY_5:
|
||||||
|
return ImGuiKey_5;
|
||||||
|
case KEY_6:
|
||||||
|
return ImGuiKey_6;
|
||||||
|
case KEY_7:
|
||||||
|
return ImGuiKey_7;
|
||||||
|
case KEY_8:
|
||||||
|
return ImGuiKey_8;
|
||||||
|
case KEY_9:
|
||||||
|
return ImGuiKey_9;
|
||||||
|
case KEY_A:
|
||||||
|
return ImGuiKey_A;
|
||||||
|
case KEY_B:
|
||||||
|
return ImGuiKey_B;
|
||||||
|
case KEY_C:
|
||||||
|
return ImGuiKey_C;
|
||||||
|
case KEY_D:
|
||||||
|
return ImGuiKey_D;
|
||||||
|
case KEY_E:
|
||||||
|
return ImGuiKey_E;
|
||||||
|
case KEY_F:
|
||||||
|
return ImGuiKey_F;
|
||||||
|
case KEY_G:
|
||||||
|
return ImGuiKey_G;
|
||||||
|
case KEY_H:
|
||||||
|
return ImGuiKey_H;
|
||||||
|
case KEY_I:
|
||||||
|
return ImGuiKey_I;
|
||||||
|
case KEY_J:
|
||||||
|
return ImGuiKey_J;
|
||||||
|
case KEY_K:
|
||||||
|
return ImGuiKey_K;
|
||||||
|
case KEY_L:
|
||||||
|
return ImGuiKey_L;
|
||||||
|
case KEY_M:
|
||||||
|
return ImGuiKey_M;
|
||||||
|
case KEY_N:
|
||||||
|
return ImGuiKey_N;
|
||||||
|
case KEY_O:
|
||||||
|
return ImGuiKey_O;
|
||||||
|
case KEY_P:
|
||||||
|
return ImGuiKey_P;
|
||||||
|
case KEY_Q:
|
||||||
|
return ImGuiKey_Q;
|
||||||
|
case KEY_R:
|
||||||
|
return ImGuiKey_R;
|
||||||
|
case KEY_S:
|
||||||
|
return ImGuiKey_S;
|
||||||
|
case KEY_T:
|
||||||
|
return ImGuiKey_T;
|
||||||
|
case KEY_U:
|
||||||
|
return ImGuiKey_U;
|
||||||
|
case KEY_V:
|
||||||
|
return ImGuiKey_V;
|
||||||
|
case KEY_W:
|
||||||
|
return ImGuiKey_W;
|
||||||
|
case KEY_X:
|
||||||
|
return ImGuiKey_X;
|
||||||
|
case KEY_Y:
|
||||||
|
return ImGuiKey_Y;
|
||||||
|
case KEY_Z:
|
||||||
|
return ImGuiKey_Z;
|
||||||
|
default:
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace Lunar {
|
namespace Lunar {
|
||||||
|
|
||||||
Application::Application()
|
Application::Application()
|
||||||
@@ -33,6 +219,8 @@ Application::Application()
|
|||||||
|
|
||||||
m_renderer = std::make_unique<VulkanRenderer>(m_window, m_logger);
|
m_renderer = std::make_unique<VulkanRenderer>(m_window, m_logger);
|
||||||
|
|
||||||
|
init_input();
|
||||||
|
|
||||||
mouse_captured(true);
|
mouse_captured(true);
|
||||||
|
|
||||||
m_logger.info("App init done!");
|
m_logger.info("App init done!");
|
||||||
@@ -42,6 +230,8 @@ Application::~Application()
|
|||||||
{
|
{
|
||||||
m_renderer.reset();
|
m_renderer.reset();
|
||||||
|
|
||||||
|
shutdown_input();
|
||||||
|
|
||||||
SDL_DestroyWindow(m_window);
|
SDL_DestroyWindow(m_window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
@@ -65,7 +255,10 @@ auto Application::run() -> void
|
|||||||
if (dt > 0)
|
if (dt > 0)
|
||||||
fps = 1000.0f / (float)dt;
|
fps = 1000.0f / (float)dt;
|
||||||
|
|
||||||
|
process_libinput_events();
|
||||||
|
|
||||||
while (SDL_PollEvent(&e)) {
|
while (SDL_PollEvent(&e)) {
|
||||||
|
bool forward_to_imgui { false };
|
||||||
if (e.type == SDL_EVENT_QUIT) {
|
if (e.type == SDL_EVENT_QUIT) {
|
||||||
m_running = false;
|
m_running = false;
|
||||||
} else if (e.type == SDL_EVENT_WINDOW_RESIZED) {
|
} else if (e.type == SDL_EVENT_WINDOW_RESIZED) {
|
||||||
@@ -73,13 +266,24 @@ auto Application::run() -> void
|
|||||||
SDL_GetWindowSize(m_window, &width, &height);
|
SDL_GetWindowSize(m_window, &width, &height);
|
||||||
m_renderer->resize(static_cast<uint32_t>(width),
|
m_renderer->resize(static_cast<uint32_t>(width),
|
||||||
static_cast<uint32_t>(height));
|
static_cast<uint32_t>(height));
|
||||||
} else if (e.type == SDL_EVENT_KEY_DOWN && e.key.repeat == false) {
|
clamp_mouse_to_window(width, height);
|
||||||
if (e.key.key == SDLK_F11 && e.key.mod & SDL_KMOD_LCTRL) {
|
forward_to_imgui = true;
|
||||||
mouse_captured(!mouse_captured());
|
} else if (e.type == SDL_EVENT_MOUSE_MOTION) {
|
||||||
m_show_imgui = !mouse_captured();
|
m_mouse_x = e.motion.x;
|
||||||
}
|
m_mouse_y = e.motion.y;
|
||||||
|
forward_to_imgui = true;
|
||||||
|
} else if (e.type == SDL_EVENT_MOUSE_BUTTON_DOWN
|
||||||
|
|| e.type == SDL_EVENT_MOUSE_BUTTON_UP) {
|
||||||
|
m_mouse_x = e.button.x;
|
||||||
|
m_mouse_y = e.button.y;
|
||||||
|
forward_to_imgui = true;
|
||||||
|
} else if (e.type == SDL_EVENT_MOUSE_WHEEL) {
|
||||||
|
m_mouse_x = e.wheel.mouse_x;
|
||||||
|
m_mouse_y = e.wheel.mouse_y;
|
||||||
|
forward_to_imgui = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (forward_to_imgui)
|
||||||
ImGui_ImplSDL3_ProcessEvent(&e);
|
ImGui_ImplSDL3_ProcessEvent(&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +293,7 @@ auto Application::run() -> void
|
|||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
if (m_show_imgui) {
|
if (m_show_imgui) {
|
||||||
|
ImGui::SetNextWindowCollapsed(true, ImGuiCond_Once);
|
||||||
ImGui::ShowDemoWindow();
|
ImGui::ShowDemoWindow();
|
||||||
|
|
||||||
ImGui::SetNextWindowSize({ 100, 50 });
|
ImGui::SetNextWindowSize({ 100, 50 });
|
||||||
@@ -105,8 +310,166 @@ auto Application::run() -> void
|
|||||||
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
m_renderer->render();
|
m_renderer->render([&](VulkanRenderer::GL &gl) {
|
||||||
|
auto view { smath::matrix_look_at(smath::Vec3 { 0.0f, 0.0f, 3.0f },
|
||||||
|
smath::Vec3 { 0.0f, 0.0f, 0.0f },
|
||||||
|
smath::Vec3 { 0.0f, 1.0f, 0.0f }, false) };
|
||||||
|
auto const draw_extent = m_renderer->draw_extent();
|
||||||
|
auto const aspect = draw_extent.height == 0
|
||||||
|
? 1.0f
|
||||||
|
: static_cast<float>(draw_extent.width)
|
||||||
|
/ static_cast<float>(draw_extent.height);
|
||||||
|
auto projection { smath::matrix_perspective(
|
||||||
|
smath::deg(70.0f), aspect, 0.1f, 10000.0f) };
|
||||||
|
projection[1][1] *= -1;
|
||||||
|
auto view_projection { projection * view };
|
||||||
|
|
||||||
|
auto rect_model { smath::scale(
|
||||||
|
smath::translate(smath::Vec3 { 0.0f, 0.0f, -5.0f }),
|
||||||
|
smath::Vec3 { 5.0f, 5.0f, 1.0f }) };
|
||||||
|
|
||||||
|
gl.set_transform(view_projection * rect_model);
|
||||||
|
|
||||||
|
gl.set_texture();
|
||||||
|
auto const &meshes { m_renderer->test_meshes() };
|
||||||
|
if (meshes.size() > 2 && !meshes[2]->surfaces.empty()) {
|
||||||
|
auto const &surface = meshes[2]->surfaces[0];
|
||||||
|
gl.draw_mesh(meshes[2]->mesh_buffers, view_projection,
|
||||||
|
surface.count, surface.start_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl.set_texture(&m_renderer->white_texture());
|
||||||
|
|
||||||
|
gl.begin(VulkanRenderer::GL::GeometryKind::Quads);
|
||||||
|
|
||||||
|
gl.color(smath::Vec3 { 0.0f, 0.0f, 0.0f });
|
||||||
|
gl.uv(smath::Vec2 { 1.0f, 1.0f });
|
||||||
|
gl.vert(smath::Vec3 { 0.5f, -0.5f, 0.0f });
|
||||||
|
|
||||||
|
gl.color(smath::Vec3 { 0.5f, 0.5f, 0.5f });
|
||||||
|
gl.uv(smath::Vec2 { 1.0f, 0.0f });
|
||||||
|
gl.vert(smath::Vec3 { 0.5f, 0.5f, 0.0f });
|
||||||
|
|
||||||
|
gl.color(smath::Vec3 { 1.0f, 0.0f, 0.0f });
|
||||||
|
gl.uv(smath::Vec2 { 0.0f, 1.0f });
|
||||||
|
gl.vert(smath::Vec3 { -0.5f, -0.5f, 0.0f });
|
||||||
|
|
||||||
|
gl.color(smath::Vec3 { 0.0f, 1.0f, 0.0f });
|
||||||
|
gl.uv(smath::Vec2 { 0.0f, 0.0f });
|
||||||
|
gl.vert(smath::Vec3 { -0.5f, 0.5f, 0.0f });
|
||||||
|
|
||||||
|
gl.end();
|
||||||
|
|
||||||
|
gl.draw_rectangle({ -0.5f, 0.5f }, { 0.5f, 0.5f });
|
||||||
|
gl.draw_rectangle(
|
||||||
|
{ 0, 0.5f }, { 0.5f, 0.5f }, { Colors::TEAL, 1.0f });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Application::init_input() -> void
|
||||||
|
{
|
||||||
|
m_udev = udev_new();
|
||||||
|
if (!m_udev) {
|
||||||
|
m_logger.err("Failed to create udev context");
|
||||||
|
throw std::runtime_error("App init fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_libinput
|
||||||
|
= libinput_udev_create_context(&g_libinput_interface, this, m_udev);
|
||||||
|
if (!m_libinput) {
|
||||||
|
m_logger.err("Failed to create libinput context");
|
||||||
|
shutdown_input();
|
||||||
|
throw std::runtime_error("App init fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (libinput_udev_assign_seat(m_libinput, "seat0") != 0) {
|
||||||
|
m_logger.err("Failed to assign libinput seat");
|
||||||
|
shutdown_input();
|
||||||
|
throw std::runtime_error("App init fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
int width {}, height {};
|
||||||
|
SDL_GetWindowSize(m_window, &width, &height);
|
||||||
|
float mouse_x {}, mouse_y {};
|
||||||
|
SDL_GetMouseState(&mouse_x, &mouse_y);
|
||||||
|
m_mouse_x = mouse_x;
|
||||||
|
m_mouse_y = mouse_y;
|
||||||
|
ImGui::GetIO().AddMousePosEvent(
|
||||||
|
static_cast<float>(m_mouse_x), static_cast<float>(m_mouse_y));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Application::shutdown_input() -> void
|
||||||
|
{
|
||||||
|
if (m_libinput) {
|
||||||
|
libinput_unref(m_libinput);
|
||||||
|
m_libinput = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_udev) {
|
||||||
|
udev_unref(m_udev);
|
||||||
|
m_udev = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Application::process_libinput_events() -> void
|
||||||
|
{
|
||||||
|
if (!m_libinput)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (int const rc { libinput_dispatch(m_libinput) }; rc != 0) {
|
||||||
|
m_logger.err("libinput_dispatch failed ({})", rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (libinput_event *event { libinput_get_event(m_libinput) };
|
||||||
|
event != nullptr; event = libinput_get_event(m_libinput)) {
|
||||||
|
switch (libinput_event_get_type(event)) {
|
||||||
|
case LIBINPUT_EVENT_KEYBOARD_KEY:
|
||||||
|
handle_keyboard_event(libinput_event_get_keyboard_event(event));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
libinput_event_destroy(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Application::handle_keyboard_event(libinput_event_keyboard *event) -> void
|
||||||
|
{
|
||||||
|
uint32_t const key { libinput_event_keyboard_get_key(event) };
|
||||||
|
auto const state { libinput_event_keyboard_get_key_state(event) };
|
||||||
|
bool const pressed { state == LIBINPUT_KEY_STATE_PRESSED };
|
||||||
|
|
||||||
|
if (key == KEY_LEFTCTRL || key == KEY_RIGHTCTRL) {
|
||||||
|
if (pressed) {
|
||||||
|
++m_ctrl_pressed_count;
|
||||||
|
} else if (m_ctrl_pressed_count > 0) {
|
||||||
|
--m_ctrl_pressed_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressed && key == KEY_F11 && m_ctrl_pressed_count > 0) {
|
||||||
|
mouse_captured(!mouse_captured());
|
||||||
|
m_show_imgui = !mouse_captured();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto imgui_key { linux_key_to_imgui(key) }) {
|
||||||
|
ImGui::GetIO().AddKeyEvent(*imgui_key, pressed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Application::clamp_mouse_to_window(int width, int height) -> void
|
||||||
|
{
|
||||||
|
double const max_x { std::max(0.0, static_cast<double>(width - 1)) };
|
||||||
|
double const max_y { std::max(0.0, static_cast<double>(height - 1)) };
|
||||||
|
|
||||||
|
m_mouse_x = std::clamp(m_mouse_x, 0.0, max_x);
|
||||||
|
m_mouse_y = std::clamp(m_mouse_y, 0.0, max_y);
|
||||||
|
|
||||||
|
ImGui::GetIO().AddMousePosEvent(
|
||||||
|
static_cast<float>(m_mouse_x), static_cast<float>(m_mouse_y));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Application::mouse_captured(bool new_state) -> void
|
auto Application::mouse_captured(bool new_state) -> void
|
||||||
|
|||||||
@@ -8,6 +8,11 @@
|
|||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
|
struct libinput;
|
||||||
|
struct libinput_event_keyboard;
|
||||||
|
struct libinput_event_pointer;
|
||||||
|
struct udev;
|
||||||
|
|
||||||
namespace Lunar {
|
namespace Lunar {
|
||||||
|
|
||||||
struct VulkanRenderer;
|
struct VulkanRenderer;
|
||||||
@@ -23,13 +28,26 @@ struct Application {
|
|||||||
auto toggle_mouse_captured() -> void { mouse_captured(!m_mouse_captured); }
|
auto toggle_mouse_captured() -> void { mouse_captured(!m_mouse_captured); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
auto init_input() -> void;
|
||||||
|
auto shutdown_input() -> void;
|
||||||
|
auto process_libinput_events() -> void;
|
||||||
|
auto handle_keyboard_event(libinput_event_keyboard *event) -> void;
|
||||||
|
auto clamp_mouse_to_window(int width, int height) -> void;
|
||||||
|
|
||||||
SDL_Window *m_window { nullptr };
|
SDL_Window *m_window { nullptr };
|
||||||
Logger m_logger { "Lunar" };
|
Logger m_logger { "Lunar" };
|
||||||
std::unique_ptr<VulkanRenderer> m_renderer;
|
std::unique_ptr<VulkanRenderer> m_renderer;
|
||||||
|
|
||||||
|
udev *m_udev { nullptr };
|
||||||
|
libinput *m_libinput { nullptr };
|
||||||
|
|
||||||
bool m_running { true };
|
bool m_running { true };
|
||||||
bool m_mouse_captured { false };
|
bool m_mouse_captured { false };
|
||||||
bool m_show_imgui { false };
|
bool m_show_imgui { false };
|
||||||
|
int m_ctrl_pressed_count { 0 };
|
||||||
|
|
||||||
|
double m_mouse_x { 0.0 };
|
||||||
|
double m_mouse_y { 0.0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Lunar
|
} // namespace Lunar
|
||||||
|
|||||||
177
src/Colors.h
Normal file
177
src/Colors.h
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <smath.hpp>
|
||||||
|
|
||||||
|
namespace Lunar::Colors {
|
||||||
|
|
||||||
|
constexpr auto hex_to_vec3(uint32_t hex) -> smath::Vec3
|
||||||
|
{
|
||||||
|
return smath::Vec3 { static_cast<float>((hex >> 16) & 0xFF) / 255.0f,
|
||||||
|
static_cast<float>((hex >> 8) & 0xFF) / 255.0f,
|
||||||
|
static_cast<float>(hex & 0xFF) / 255.0f };
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr smath::Vec3 WHITE { hex_to_vec3(0xFFFFFF) };
|
||||||
|
inline constexpr smath::Vec3 SILVER { hex_to_vec3(0xC0C0C0) };
|
||||||
|
inline constexpr smath::Vec3 GRAY { hex_to_vec3(0x808080) };
|
||||||
|
inline constexpr smath::Vec3 BLACK { hex_to_vec3(0x000000) };
|
||||||
|
inline constexpr smath::Vec3 RED { hex_to_vec3(0xFF0000) };
|
||||||
|
inline constexpr smath::Vec3 MAROON { hex_to_vec3(0x800000) };
|
||||||
|
inline constexpr smath::Vec3 YELLOW { hex_to_vec3(0xFFFF00) };
|
||||||
|
inline constexpr smath::Vec3 OLIVE { hex_to_vec3(0x808000) };
|
||||||
|
inline constexpr smath::Vec3 LIME { hex_to_vec3(0x00FF00) };
|
||||||
|
inline constexpr smath::Vec3 GREEN { hex_to_vec3(0x008000) };
|
||||||
|
inline constexpr smath::Vec3 AQUA { hex_to_vec3(0x00FFFF) };
|
||||||
|
inline constexpr smath::Vec3 TEAL { hex_to_vec3(0x008080) };
|
||||||
|
inline constexpr smath::Vec3 BLUE { hex_to_vec3(0x0000FF) };
|
||||||
|
inline constexpr smath::Vec3 NAVY { hex_to_vec3(0x000080) };
|
||||||
|
inline constexpr smath::Vec3 FUCHSIA { hex_to_vec3(0xFF00FF) };
|
||||||
|
inline constexpr smath::Vec3 PURPLE { hex_to_vec3(0x800080) };
|
||||||
|
|
||||||
|
// Pink colors
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_VIOLET_RED { hex_to_vec3(0xC71585) };
|
||||||
|
inline constexpr smath::Vec3 DEEP_PINK { hex_to_vec3(0xFF1493) };
|
||||||
|
inline constexpr smath::Vec3 PALE_VIOLET_RED { hex_to_vec3(0xDB7093) };
|
||||||
|
inline constexpr smath::Vec3 HOT_PINK { hex_to_vec3(0xFF69B4) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_PINK { hex_to_vec3(0xFFB6C1) };
|
||||||
|
inline constexpr smath::Vec3 PINK { hex_to_vec3(0xFFC0CB) };
|
||||||
|
|
||||||
|
// Red colors
|
||||||
|
inline constexpr smath::Vec3 DARK_RED { hex_to_vec3(0x8B0000) };
|
||||||
|
inline constexpr smath::Vec3 FIREBRICK { hex_to_vec3(0xB22222) };
|
||||||
|
inline constexpr smath::Vec3 CRIMSON { hex_to_vec3(0xDC143C) };
|
||||||
|
inline constexpr smath::Vec3 INDIAN_RED { hex_to_vec3(0xCD5C5C) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_CORAL { hex_to_vec3(0xF08080) };
|
||||||
|
inline constexpr smath::Vec3 SALMON { hex_to_vec3(0xFA8072) };
|
||||||
|
inline constexpr smath::Vec3 DARK_SALMON { hex_to_vec3(0xE9967A) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_SALMON { hex_to_vec3(0xFFA07A) };
|
||||||
|
|
||||||
|
// Orange colors
|
||||||
|
inline constexpr smath::Vec3 ORANGE_RED { hex_to_vec3(0xFF4500) };
|
||||||
|
inline constexpr smath::Vec3 TOMATO { hex_to_vec3(0xFF6347) };
|
||||||
|
inline constexpr smath::Vec3 DARK_ORANGE { hex_to_vec3(0xFF8C00) };
|
||||||
|
inline constexpr smath::Vec3 CORAL { hex_to_vec3(0xFF7F50) };
|
||||||
|
inline constexpr smath::Vec3 ORANGE { hex_to_vec3(0xFFA500) };
|
||||||
|
|
||||||
|
// Yellow colors
|
||||||
|
inline constexpr smath::Vec3 DARK_KHAKI { hex_to_vec3(0xBDB76B) };
|
||||||
|
inline constexpr smath::Vec3 GOLD { hex_to_vec3(0xFFD700) };
|
||||||
|
inline constexpr smath::Vec3 KHAKI { hex_to_vec3(0xF0E68C) };
|
||||||
|
inline constexpr smath::Vec3 PEACH_PUFF { hex_to_vec3(0xFFDAB9) };
|
||||||
|
inline constexpr smath::Vec3 PALE_GOLDENROD { hex_to_vec3(0xEEE8AA) };
|
||||||
|
inline constexpr smath::Vec3 MOCCASIN { hex_to_vec3(0xFFE4B5) };
|
||||||
|
inline constexpr smath::Vec3 PAPAYA_WHIP { hex_to_vec3(0xFFEFD5) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_GOLDENROD_YELLOW { hex_to_vec3(0xFAFAD2) };
|
||||||
|
inline constexpr smath::Vec3 LEMON_CHIFFON { hex_to_vec3(0xFFFACD) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_YELLOW { hex_to_vec3(0xFFFFE0) };
|
||||||
|
|
||||||
|
// Brown colors
|
||||||
|
inline constexpr smath::Vec3 BROWN { hex_to_vec3(0xA52A2A) };
|
||||||
|
inline constexpr smath::Vec3 SADDLE_BROWN { hex_to_vec3(0x8B4513) };
|
||||||
|
inline constexpr smath::Vec3 SIENNA { hex_to_vec3(0xA0522D) };
|
||||||
|
inline constexpr smath::Vec3 CHOCOLATE { hex_to_vec3(0xD2691E) };
|
||||||
|
inline constexpr smath::Vec3 DARK_GOLDENROD { hex_to_vec3(0xB8860B) };
|
||||||
|
inline constexpr smath::Vec3 PERU { hex_to_vec3(0xCD853F) };
|
||||||
|
inline constexpr smath::Vec3 ROSY_BROWN { hex_to_vec3(0xBC8F8F) };
|
||||||
|
inline constexpr smath::Vec3 GOLDENROD { hex_to_vec3(0xDAA520) };
|
||||||
|
inline constexpr smath::Vec3 SANDY_BROWN { hex_to_vec3(0xF4A460) };
|
||||||
|
inline constexpr smath::Vec3 TAN { hex_to_vec3(0xD2B48C) };
|
||||||
|
inline constexpr smath::Vec3 BURLYWOOD { hex_to_vec3(0xDEB887) };
|
||||||
|
inline constexpr smath::Vec3 WHEAT { hex_to_vec3(0xF5DEB3) };
|
||||||
|
inline constexpr smath::Vec3 NAVAJO_WHITE { hex_to_vec3(0xFFDEAD) };
|
||||||
|
inline constexpr smath::Vec3 BISQUE { hex_to_vec3(0xFFE4C4) };
|
||||||
|
inline constexpr smath::Vec3 BLANCHED_ALMOND { hex_to_vec3(0xFFEBCD) };
|
||||||
|
inline constexpr smath::Vec3 CORNSILK { hex_to_vec3(0xFFF8DC) };
|
||||||
|
|
||||||
|
// Purple, violet, magenta colors
|
||||||
|
inline constexpr smath::Vec3 INDIGO { hex_to_vec3(0x4B0082) };
|
||||||
|
inline constexpr smath::Vec3 DARK_MAGENTA { hex_to_vec3(0x8B008B) };
|
||||||
|
inline constexpr smath::Vec3 DARK_VIOLET { hex_to_vec3(0x9400D3) };
|
||||||
|
inline constexpr smath::Vec3 DARK_SLATE_BLUE { hex_to_vec3(0x483D8B) };
|
||||||
|
inline constexpr smath::Vec3 BLUE_VIOLET { hex_to_vec3(0x8A2BE2) };
|
||||||
|
inline constexpr smath::Vec3 DARK_ORCHID { hex_to_vec3(0x9932CC) };
|
||||||
|
inline constexpr smath::Vec3 MAGENTA { hex_to_vec3(0xFF00FF) };
|
||||||
|
inline constexpr smath::Vec3 SLATE_BLUE { hex_to_vec3(0x6A5ACD) };
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_SLATE_BLUE { hex_to_vec3(0x7B68EE) };
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_ORCHID { hex_to_vec3(0xBA55D3) };
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_PURPLE { hex_to_vec3(0x9370DB) };
|
||||||
|
inline constexpr smath::Vec3 ORCHID { hex_to_vec3(0xDA70D6) };
|
||||||
|
inline constexpr smath::Vec3 VIOLET { hex_to_vec3(0xEE82EE) };
|
||||||
|
inline constexpr smath::Vec3 PLUM { hex_to_vec3(0xDDA0DD) };
|
||||||
|
inline constexpr smath::Vec3 THISTLE { hex_to_vec3(0xD8BFD8) };
|
||||||
|
inline constexpr smath::Vec3 LAVENDER { hex_to_vec3(0xE6E6FA) };
|
||||||
|
|
||||||
|
// Blue colors
|
||||||
|
inline constexpr smath::Vec3 MIDNIGHT_BLUE { hex_to_vec3(0x191970) };
|
||||||
|
inline constexpr smath::Vec3 DARK_BLUE { hex_to_vec3(0x00008B) };
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_BLUE { hex_to_vec3(0x0000CD) };
|
||||||
|
inline constexpr smath::Vec3 ROYAL_BLUE { hex_to_vec3(0x4169E1) };
|
||||||
|
inline constexpr smath::Vec3 STEEL_BLUE { hex_to_vec3(0x4682B4) };
|
||||||
|
inline constexpr smath::Vec3 DODGER_BLUE { hex_to_vec3(0x1E90FF) };
|
||||||
|
inline constexpr smath::Vec3 DEEP_SKY_BLUE { hex_to_vec3(0x00BFFF) };
|
||||||
|
inline constexpr smath::Vec3 CORNFLOWER_BLUE { hex_to_vec3(0x6495ED) };
|
||||||
|
inline constexpr smath::Vec3 SKY_BLUE { hex_to_vec3(0x87CEEB) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_SKY_BLUE { hex_to_vec3(0x87CEFA) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_STEEL_BLUE { hex_to_vec3(0xB0C4DE) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_BLUE { hex_to_vec3(0xADD8E6) };
|
||||||
|
inline constexpr smath::Vec3 POWDER_BLUE { hex_to_vec3(0xB0E0E6) };
|
||||||
|
|
||||||
|
// Cyan colors
|
||||||
|
inline constexpr smath::Vec3 DARK_CYAN { hex_to_vec3(0x008B8B) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_SEA_GREEN { hex_to_vec3(0x20B2AA) };
|
||||||
|
inline constexpr smath::Vec3 CADET_BLUE { hex_to_vec3(0x5F9EA0) };
|
||||||
|
inline constexpr smath::Vec3 DARK_TURQUOISE { hex_to_vec3(0x00CED1) };
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_TURQUOISE { hex_to_vec3(0x48D1CC) };
|
||||||
|
inline constexpr smath::Vec3 TURQUOISE { hex_to_vec3(0x40E0D0) };
|
||||||
|
inline constexpr smath::Vec3 CYAN { hex_to_vec3(0x00FFFF) };
|
||||||
|
inline constexpr smath::Vec3 AQUAMARINE { hex_to_vec3(0x7FFFD4) };
|
||||||
|
inline constexpr smath::Vec3 PALE_TURQUOISE { hex_to_vec3(0xAFEEEE) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_CYAN { hex_to_vec3(0xE0FFFF) };
|
||||||
|
|
||||||
|
// Green colors
|
||||||
|
inline constexpr smath::Vec3 DARK_GREEN { hex_to_vec3(0x006400) };
|
||||||
|
inline constexpr smath::Vec3 DARK_OLIVE_GREEN { hex_to_vec3(0x556B2F) };
|
||||||
|
inline constexpr smath::Vec3 FOREST_GREEN { hex_to_vec3(0x228B22) };
|
||||||
|
inline constexpr smath::Vec3 SEA_GREEN { hex_to_vec3(0x2E8B57) };
|
||||||
|
inline constexpr smath::Vec3 OLIVE_DRAB { hex_to_vec3(0x6B8E23) };
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_SEA_GREEN { hex_to_vec3(0x3CB371) };
|
||||||
|
inline constexpr smath::Vec3 LIME_GREEN { hex_to_vec3(0x32CD32) };
|
||||||
|
inline constexpr smath::Vec3 SPRING_GREEN { hex_to_vec3(0x00FF7F) };
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_SPRING_GREEN { hex_to_vec3(0x00FA9A) };
|
||||||
|
inline constexpr smath::Vec3 DARK_SEA_GREEN { hex_to_vec3(0x8FBC8F) };
|
||||||
|
inline constexpr smath::Vec3 MEDIUM_AQUAMARINE { hex_to_vec3(0x66CDAA) };
|
||||||
|
inline constexpr smath::Vec3 YELLOW_GREEN { hex_to_vec3(0x9ACD32) };
|
||||||
|
inline constexpr smath::Vec3 LAWN_GREEN { hex_to_vec3(0x7CFC00) };
|
||||||
|
inline constexpr smath::Vec3 CHARTREUSE { hex_to_vec3(0x7FFF00) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_GREEN { hex_to_vec3(0x90EE90) };
|
||||||
|
inline constexpr smath::Vec3 GREEN_YELLOW { hex_to_vec3(0xADFF2F) };
|
||||||
|
inline constexpr smath::Vec3 PALE_GREEN { hex_to_vec3(0x98FB98) };
|
||||||
|
|
||||||
|
// White colors
|
||||||
|
inline constexpr smath::Vec3 MISTY_ROSE { hex_to_vec3(0xFFE4E1) };
|
||||||
|
inline constexpr smath::Vec3 ANTIQUE_WHITE { hex_to_vec3(0xFAEBD7) };
|
||||||
|
inline constexpr smath::Vec3 LINEN { hex_to_vec3(0xFAF0E6) };
|
||||||
|
inline constexpr smath::Vec3 BEIGE { hex_to_vec3(0xF5F5DC) };
|
||||||
|
inline constexpr smath::Vec3 WHITE_SMOKE { hex_to_vec3(0xF5F5F5) };
|
||||||
|
inline constexpr smath::Vec3 LAVENDER_BLUSH { hex_to_vec3(0xFFF0F5) };
|
||||||
|
inline constexpr smath::Vec3 OLD_LACE { hex_to_vec3(0xFDF5E6) };
|
||||||
|
inline constexpr smath::Vec3 ALICE_BLUE { hex_to_vec3(0xF0F8FF) };
|
||||||
|
inline constexpr smath::Vec3 SEASHELL { hex_to_vec3(0xFFF5EE) };
|
||||||
|
inline constexpr smath::Vec3 GHOST_WHITE { hex_to_vec3(0xF8F8FF) };
|
||||||
|
inline constexpr smath::Vec3 HONEYDEW { hex_to_vec3(0xF0FFF0) };
|
||||||
|
inline constexpr smath::Vec3 FLORAL_WHITE { hex_to_vec3(0xFFFAF0) };
|
||||||
|
inline constexpr smath::Vec3 AZURE { hex_to_vec3(0xF0FFFF) };
|
||||||
|
inline constexpr smath::Vec3 MINT_CREAM { hex_to_vec3(0xF5FFFA) };
|
||||||
|
inline constexpr smath::Vec3 SNOW { hex_to_vec3(0xFFFAFA) };
|
||||||
|
inline constexpr smath::Vec3 IVORY { hex_to_vec3(0xFFFFF0) };
|
||||||
|
|
||||||
|
// Gray and black colors
|
||||||
|
inline constexpr smath::Vec3 DARK_SLATE_GRAY { hex_to_vec3(0x2F4F4F) };
|
||||||
|
inline constexpr smath::Vec3 DIM_GRAY { hex_to_vec3(0x696969) };
|
||||||
|
inline constexpr smath::Vec3 SLATE_GRAY { hex_to_vec3(0x708090) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_SLATE_GRAY { hex_to_vec3(0x778899) };
|
||||||
|
inline constexpr smath::Vec3 DARK_GRAY { hex_to_vec3(0xA9A9A9) };
|
||||||
|
inline constexpr smath::Vec3 LIGHT_GRAY { hex_to_vec3(0xD3D3D3) };
|
||||||
|
inline constexpr smath::Vec3 GAINSBORO { hex_to_vec3(0xDCDCDC) };
|
||||||
|
|
||||||
|
} // namespace Lunar::Colors
|
||||||
@@ -41,10 +41,11 @@ auto GraphicsPipelineBuilder::set_shaders(VkShaderModule vs, VkShaderModule fs)
|
|||||||
{
|
{
|
||||||
m_shader_stages.clear();
|
m_shader_stages.clear();
|
||||||
|
|
||||||
m_shader_stages.emplace_back(
|
m_shader_stages.emplace_back(vkinit::pipeline_shader_stage(
|
||||||
vkinit::pipeline_shader_stage(VK_SHADER_STAGE_VERTEX_BIT, vs));
|
static_cast<vk::ShaderStageFlagBits>(VK_SHADER_STAGE_VERTEX_BIT), vs));
|
||||||
m_shader_stages.emplace_back(
|
m_shader_stages.emplace_back(vkinit::pipeline_shader_stage(
|
||||||
vkinit::pipeline_shader_stage(VK_SHADER_STAGE_FRAGMENT_BIT, fs));
|
static_cast<vk::ShaderStageFlagBits>(VK_SHADER_STAGE_FRAGMENT_BIT),
|
||||||
|
fs));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ auto Mesh::load_gltf_meshes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool OVERRIDE_COLORS = true;
|
constexpr bool OVERRIDE_COLORS = false;
|
||||||
if (OVERRIDE_COLORS) {
|
if (OVERRIDE_COLORS) {
|
||||||
for (auto &vtx : vertices) {
|
for (auto &vtx : vertices) {
|
||||||
vtx.color = smath::Vec4(vtx.normal, 1.f);
|
vtx.color = smath::Vec4(vtx.normal, 1.f);
|
||||||
|
|||||||
79
src/Pipeline.cpp
Normal file
79
src/Pipeline.cpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#include "Pipeline.h"
|
||||||
|
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
namespace Lunar {
|
||||||
|
|
||||||
|
Pipeline::Builder::Builder(vk::Device device, Logger &logger)
|
||||||
|
: m_device(device)
|
||||||
|
, m_logger(logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Pipeline::Builder::set_descriptor_set_layouts(
|
||||||
|
std::span<vk::DescriptorSetLayout const> layouts) -> Builder &
|
||||||
|
{
|
||||||
|
m_set_layouts.assign(layouts.begin(), layouts.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Pipeline::Builder::set_push_constant_ranges(
|
||||||
|
std::span<vk::PushConstantRange const> ranges) -> Builder &
|
||||||
|
{
|
||||||
|
m_push_constant_ranges.assign(ranges.begin(), ranges.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Pipeline::Builder::build_compute(
|
||||||
|
vk::PipelineShaderStageCreateInfo const &stage) -> Pipeline
|
||||||
|
{
|
||||||
|
auto pipeline_layout = build_layout();
|
||||||
|
|
||||||
|
vk::ComputePipelineCreateInfo pipeline_ci {};
|
||||||
|
pipeline_ci.layout = pipeline_layout.get();
|
||||||
|
pipeline_ci.stage = stage;
|
||||||
|
|
||||||
|
auto pipeline_ret = m_device.createComputePipelineUnique({}, pipeline_ci);
|
||||||
|
VK_CHECK(m_logger, pipeline_ret.result);
|
||||||
|
|
||||||
|
return Pipeline {
|
||||||
|
.pipeline = std::move(pipeline_ret.value),
|
||||||
|
.layout = std::move(pipeline_layout),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Pipeline::Builder::build_graphics(
|
||||||
|
std::function<GraphicsPipelineBuilder &(GraphicsPipelineBuilder &)> const
|
||||||
|
&configure) -> Pipeline
|
||||||
|
{
|
||||||
|
auto pipeline_layout = build_layout();
|
||||||
|
|
||||||
|
auto builder = GraphicsPipelineBuilder { m_logger };
|
||||||
|
builder.set_pipeline_layout(
|
||||||
|
static_cast<VkPipelineLayout>(pipeline_layout.get()));
|
||||||
|
configure(builder);
|
||||||
|
|
||||||
|
auto pipeline_handle = builder.build(static_cast<VkDevice>(m_device));
|
||||||
|
vk::UniquePipeline pipeline_unique(pipeline_handle,
|
||||||
|
vk::detail::ObjectDestroy<vk::Device,
|
||||||
|
VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>(m_device));
|
||||||
|
|
||||||
|
return Pipeline {
|
||||||
|
.pipeline = std::move(pipeline_unique),
|
||||||
|
.layout = std::move(pipeline_layout),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Pipeline::Builder::build_layout() -> vk::UniquePipelineLayout
|
||||||
|
{
|
||||||
|
vk::PipelineLayoutCreateInfo layout_ci {};
|
||||||
|
layout_ci.setLayoutCount = static_cast<uint32_t>(m_set_layouts.size());
|
||||||
|
layout_ci.pSetLayouts = m_set_layouts.data();
|
||||||
|
layout_ci.pushConstantRangeCount
|
||||||
|
= static_cast<uint32_t>(m_push_constant_ranges.size());
|
||||||
|
layout_ci.pPushConstantRanges = m_push_constant_ranges.data();
|
||||||
|
|
||||||
|
return m_device.createPipelineLayoutUnique(layout_ci);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Lunar
|
||||||
49
src/Pipeline.h
Normal file
49
src/Pipeline.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <span>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
#include "GraphicsPipelineBuilder.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
namespace Lunar {
|
||||||
|
|
||||||
|
struct Pipeline {
|
||||||
|
vk::UniquePipeline pipeline {};
|
||||||
|
vk::UniquePipelineLayout layout {};
|
||||||
|
|
||||||
|
auto get() const -> vk::Pipeline { return pipeline.get(); }
|
||||||
|
auto get_layout() const -> vk::PipelineLayout { return layout.get(); }
|
||||||
|
auto reset() -> void
|
||||||
|
{
|
||||||
|
pipeline.reset();
|
||||||
|
layout.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Builder {
|
||||||
|
Builder(vk::Device device, Logger &logger);
|
||||||
|
|
||||||
|
auto set_descriptor_set_layouts(
|
||||||
|
std::span<vk::DescriptorSetLayout const> layouts) -> Builder &;
|
||||||
|
auto set_push_constant_ranges(
|
||||||
|
std::span<vk::PushConstantRange const> ranges) -> Builder &;
|
||||||
|
|
||||||
|
auto build_compute(vk::PipelineShaderStageCreateInfo const &stage)
|
||||||
|
-> Pipeline;
|
||||||
|
auto build_graphics(std::function<GraphicsPipelineBuilder &(
|
||||||
|
GraphicsPipelineBuilder &)> const &configure) -> Pipeline;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto build_layout() -> vk::UniquePipelineLayout;
|
||||||
|
|
||||||
|
vk::Device m_device {};
|
||||||
|
Logger &m_logger;
|
||||||
|
std::vector<vk::DescriptorSetLayout> m_set_layouts {};
|
||||||
|
std::vector<vk::PushConstantRange> m_push_constant_ranges {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Lunar
|
||||||
22
src/Types.h
22
src/Types.h
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <smath.hpp>
|
#include <smath.hpp>
|
||||||
#include <vk_mem_alloc.h>
|
#include <vk_mem_alloc.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
#include "DeletionQueue.h"
|
#include "DeletionQueue.h"
|
||||||
#include "DescriptorAllocatorGrowable.h"
|
#include "DescriptorAllocatorGrowable.h"
|
||||||
@@ -10,24 +10,24 @@
|
|||||||
namespace Lunar {
|
namespace Lunar {
|
||||||
|
|
||||||
struct AllocatedImage {
|
struct AllocatedImage {
|
||||||
VkImage image;
|
vk::Image image;
|
||||||
VkImageView image_view;
|
vk::ImageView image_view;
|
||||||
VmaAllocation allocation;
|
VmaAllocation allocation;
|
||||||
VkExtent3D extent;
|
vk::Extent3D extent;
|
||||||
VkFormat format;
|
vk::Format format;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AllocatedBuffer {
|
struct AllocatedBuffer {
|
||||||
VkBuffer buffer;
|
vk::Buffer buffer;
|
||||||
VmaAllocation allocation;
|
VmaAllocation allocation;
|
||||||
VmaAllocationInfo info;
|
VmaAllocationInfo info;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FrameData {
|
struct FrameData {
|
||||||
VkCommandPool command_pool;
|
vk::UniqueCommandPool command_pool;
|
||||||
VkCommandBuffer main_command_buffer;
|
vk::UniqueCommandBuffer main_command_buffer;
|
||||||
VkSemaphore swapchain_semaphore;
|
vk::UniqueSemaphore swapchain_semaphore;
|
||||||
VkFence render_fence;
|
vk::UniqueFence render_fence;
|
||||||
|
|
||||||
DeletionQueue deletion_queue;
|
DeletionQueue deletion_queue;
|
||||||
DescriptorAllocatorGrowable frame_descriptors;
|
DescriptorAllocatorGrowable frame_descriptors;
|
||||||
@@ -43,7 +43,7 @@ struct Vertex {
|
|||||||
|
|
||||||
struct GPUMeshBuffers {
|
struct GPUMeshBuffers {
|
||||||
AllocatedBuffer index_buffer, vertex_buffer;
|
AllocatedBuffer index_buffer, vertex_buffer;
|
||||||
VkDeviceAddress vertex_buffer_address;
|
vk::DeviceAddress vertex_buffer_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GPUSceneData {
|
struct GPUSceneData {
|
||||||
|
|||||||
220
src/Util.cpp
220
src/Util.cpp
@@ -4,140 +4,110 @@
|
|||||||
|
|
||||||
namespace vkutil {
|
namespace vkutil {
|
||||||
|
|
||||||
auto transition_image(VkCommandBuffer cmd, VkImage image,
|
auto transition_image(vk::CommandBuffer cmd, vk::Image image,
|
||||||
VkImageLayout current_layout, VkImageLayout new_layout) -> void
|
vk::ImageLayout current_layout, vk::ImageLayout new_layout) -> void
|
||||||
{
|
{
|
||||||
VkImageAspectFlags aspect_mask
|
auto aspect_mask = (new_layout == vk::ImageLayout::eDepthAttachmentOptimal)
|
||||||
= (new_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL)
|
? vk::ImageAspectFlagBits::eDepth
|
||||||
? VK_IMAGE_ASPECT_DEPTH_BIT
|
: vk::ImageAspectFlagBits::eColor;
|
||||||
: VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
|
|
||||||
VkImageMemoryBarrier image_barrier {
|
vk::ImageMemoryBarrier image_barrier {};
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
image_barrier.srcAccessMask = vk::AccessFlagBits::eMemoryWrite;
|
||||||
.pNext = nullptr,
|
image_barrier.dstAccessMask
|
||||||
|
= vk::AccessFlagBits::eMemoryWrite | vk::AccessFlagBits::eMemoryRead;
|
||||||
|
image_barrier.oldLayout = current_layout;
|
||||||
|
image_barrier.newLayout = new_layout;
|
||||||
|
image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
image_barrier.image = image;
|
||||||
|
image_barrier.subresourceRange.aspectMask = aspect_mask;
|
||||||
|
image_barrier.subresourceRange.baseMipLevel = 0;
|
||||||
|
image_barrier.subresourceRange.levelCount = 1;
|
||||||
|
image_barrier.subresourceRange.baseArrayLayer = 0;
|
||||||
|
image_barrier.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
|
cmd.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
|
||||||
.dstAccessMask
|
vk::PipelineStageFlagBits::eAllCommands, {}, {}, {}, image_barrier);
|
||||||
= VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT,
|
|
||||||
.oldLayout = current_layout,
|
|
||||||
.newLayout = new_layout,
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.image = image,
|
|
||||||
.subresourceRange = {
|
|
||||||
.aspectMask = aspect_mask,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.levelCount = 1,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
|
||||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
|
|
||||||
&image_barrier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto copy_image_to_image(VkCommandBuffer cmd, VkImage source,
|
auto copy_image_to_image(vk::CommandBuffer cmd, vk::Image source,
|
||||||
VkImage destination, VkExtent2D src_size, VkExtent2D dst_size) -> void
|
vk::Image destination, vk::Extent2D src_size, vk::Extent2D dst_size) -> void
|
||||||
{
|
{
|
||||||
VkImageBlit2 blit_region {};
|
vk::ImageBlit2 blit_region {};
|
||||||
blit_region.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2;
|
blit_region.srcOffsets[0] = vk::Offset3D { 0, 0, 0 };
|
||||||
blit_region.pNext = nullptr;
|
blit_region.srcOffsets[1]
|
||||||
|
= vk::Offset3D { static_cast<int32_t>(src_size.width),
|
||||||
blit_region.srcOffsets[0] = { 0, 0, 0 };
|
|
||||||
blit_region.srcOffsets[1] = { static_cast<int32_t>(src_size.width),
|
|
||||||
static_cast<int32_t>(src_size.height), 1 };
|
static_cast<int32_t>(src_size.height), 1 };
|
||||||
|
|
||||||
blit_region.dstOffsets[0] = { 0, 0, 0 };
|
blit_region.dstOffsets[0] = vk::Offset3D { 0, 0, 0 };
|
||||||
blit_region.dstOffsets[1] = { static_cast<int32_t>(dst_size.width),
|
blit_region.dstOffsets[1]
|
||||||
|
= vk::Offset3D { static_cast<int32_t>(dst_size.width),
|
||||||
static_cast<int32_t>(dst_size.height), 1 };
|
static_cast<int32_t>(dst_size.height), 1 };
|
||||||
|
|
||||||
blit_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
blit_region.srcSubresource.aspectMask = vk::ImageAspectFlagBits::eColor;
|
||||||
blit_region.srcSubresource.baseArrayLayer = 0;
|
blit_region.srcSubresource.baseArrayLayer = 0;
|
||||||
blit_region.srcSubresource.layerCount = 1;
|
blit_region.srcSubresource.layerCount = 1;
|
||||||
blit_region.srcSubresource.mipLevel = 0;
|
blit_region.srcSubresource.mipLevel = 0;
|
||||||
|
|
||||||
blit_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
blit_region.dstSubresource.aspectMask = vk::ImageAspectFlagBits::eColor;
|
||||||
blit_region.dstSubresource.baseArrayLayer = 0;
|
blit_region.dstSubresource.baseArrayLayer = 0;
|
||||||
blit_region.dstSubresource.layerCount = 1;
|
blit_region.dstSubresource.layerCount = 1;
|
||||||
blit_region.dstSubresource.mipLevel = 0;
|
blit_region.dstSubresource.mipLevel = 0;
|
||||||
|
|
||||||
VkBlitImageInfo2 blit_info {};
|
vk::BlitImageInfo2 blit_info {};
|
||||||
blit_info.sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2;
|
|
||||||
blit_info.pNext = nullptr;
|
|
||||||
blit_info.dstImage = destination;
|
blit_info.dstImage = destination;
|
||||||
blit_info.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
blit_info.dstImageLayout = vk::ImageLayout::eTransferDstOptimal;
|
||||||
blit_info.srcImage = source;
|
blit_info.srcImage = source;
|
||||||
blit_info.srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
blit_info.srcImageLayout = vk::ImageLayout::eTransferSrcOptimal;
|
||||||
blit_info.filter = VK_FILTER_LINEAR;
|
blit_info.filter = vk::Filter::eLinear;
|
||||||
blit_info.regionCount = 1;
|
blit_info.regionCount = 1;
|
||||||
blit_info.pRegions = &blit_region;
|
blit_info.pRegions = &blit_region;
|
||||||
|
|
||||||
vkCmdBlitImage2(cmd, &blit_info);
|
cmd.blitImage2(blit_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto load_shader_module(std::span<uint8_t> spirv_data, VkDevice device,
|
auto load_shader_module(std::span<uint8_t> spirv_data, vk::Device device)
|
||||||
VkShaderModule *out_shader_module) -> bool
|
-> vk::UniqueShaderModule
|
||||||
{
|
{
|
||||||
if (!device || !out_shader_module)
|
if (!device || spirv_data.empty() || (spirv_data.size() % 4) != 0) {
|
||||||
return false;
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (spirv_data.empty() || (spirv_data.size() % 4) != 0)
|
vk::ShaderModuleCreateInfo create_info {};
|
||||||
return false;
|
|
||||||
|
|
||||||
VkShaderModuleCreateInfo create_info {};
|
|
||||||
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
|
||||||
create_info.pNext = nullptr;
|
|
||||||
create_info.flags = 0;
|
|
||||||
create_info.codeSize = spirv_data.size();
|
create_info.codeSize = spirv_data.size();
|
||||||
create_info.pCode = reinterpret_cast<uint32_t const *>(spirv_data.data());
|
create_info.pCode = reinterpret_cast<uint32_t const *>(spirv_data.data());
|
||||||
|
|
||||||
VkResult const res = vkCreateShaderModule(
|
try {
|
||||||
device, &create_info, nullptr, out_shader_module);
|
return device.createShaderModuleUnique(create_info);
|
||||||
if (res != VK_SUCCESS) {
|
} catch (vk::SystemError const &) {
|
||||||
*out_shader_module = VK_NULL_HANDLE;
|
return {};
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vkutil
|
} // namespace vkutil
|
||||||
|
|
||||||
namespace vkinit {
|
namespace vkinit {
|
||||||
|
|
||||||
auto image_create_info(VkFormat format, VkImageUsageFlags usage_flags,
|
auto image_create_info(vk::Format format, vk::ImageUsageFlags usage_flags,
|
||||||
VkExtent3D extent) -> VkImageCreateInfo
|
vk::Extent3D extent) -> vk::ImageCreateInfo
|
||||||
{
|
{
|
||||||
VkImageCreateInfo info = {};
|
vk::ImageCreateInfo info {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
info.imageType = vk::ImageType::e2D;
|
||||||
info.pNext = nullptr;
|
|
||||||
|
|
||||||
info.imageType = VK_IMAGE_TYPE_2D;
|
|
||||||
|
|
||||||
info.format = format;
|
info.format = format;
|
||||||
info.extent = extent;
|
info.extent = extent;
|
||||||
|
|
||||||
info.mipLevels = 1;
|
info.mipLevels = 1;
|
||||||
info.arrayLayers = 1;
|
info.arrayLayers = 1;
|
||||||
|
info.samples = vk::SampleCountFlagBits::e1;
|
||||||
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
info.tiling = vk::ImageTiling::eOptimal;
|
||||||
|
|
||||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
||||||
info.usage = usage_flags;
|
info.usage = usage_flags;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto imageview_create_info(VkFormat format, VkImage image,
|
auto imageview_create_info(vk::Format format, vk::Image image,
|
||||||
VkImageAspectFlags aspect_flags) -> VkImageViewCreateInfo
|
vk::ImageAspectFlags aspect_flags) -> vk::ImageViewCreateInfo
|
||||||
{
|
{
|
||||||
VkImageViewCreateInfo info = {};
|
vk::ImageViewCreateInfo info {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
info.viewType = vk::ImageViewType::e2D;
|
||||||
info.pNext = nullptr;
|
|
||||||
|
|
||||||
info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
info.image = image;
|
info.image = image;
|
||||||
info.format = format;
|
info.format = format;
|
||||||
info.subresourceRange.baseMipLevel = 0;
|
info.subresourceRange.baseMipLevel = 0;
|
||||||
@@ -145,27 +115,22 @@ auto imageview_create_info(VkFormat format, VkImage image,
|
|||||||
info.subresourceRange.baseArrayLayer = 0;
|
info.subresourceRange.baseArrayLayer = 0;
|
||||||
info.subresourceRange.layerCount = 1;
|
info.subresourceRange.layerCount = 1;
|
||||||
info.subresourceRange.aspectMask = aspect_flags;
|
info.subresourceRange.aspectMask = aspect_flags;
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto command_buffer_submit_info(VkCommandBuffer cmd)
|
auto command_buffer_submit_info(vk::CommandBuffer cmd)
|
||||||
-> VkCommandBufferSubmitInfo
|
-> vk::CommandBufferSubmitInfo
|
||||||
{
|
{
|
||||||
VkCommandBufferSubmitInfo info {};
|
vk::CommandBufferSubmitInfo info {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.commandBuffer = cmd;
|
info.commandBuffer = cmd;
|
||||||
info.deviceMask = 0;
|
info.deviceMask = 0;
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto semaphore_submit_info(VkPipelineStageFlags2 stage_mask,
|
auto semaphore_submit_info(vk::PipelineStageFlags2 stage_mask,
|
||||||
VkSemaphore semaphore) -> VkSemaphoreSubmitInfo
|
vk::Semaphore semaphore) -> vk::SemaphoreSubmitInfo
|
||||||
{
|
{
|
||||||
VkSemaphoreSubmitInfo info {};
|
vk::SemaphoreSubmitInfo info {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.semaphore = semaphore;
|
info.semaphore = semaphore;
|
||||||
info.value = 0;
|
info.value = 0;
|
||||||
info.stageMask = stage_mask;
|
info.stageMask = stage_mask;
|
||||||
@@ -173,14 +138,11 @@ auto semaphore_submit_info(VkPipelineStageFlags2 stage_mask,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto submit_info2(VkCommandBufferSubmitInfo *cmd_info,
|
auto submit_info2(vk::CommandBufferSubmitInfo *cmd_info,
|
||||||
VkSemaphoreSubmitInfo *wait_semaphore_info,
|
vk::SemaphoreSubmitInfo *wait_semaphore_info,
|
||||||
VkSemaphoreSubmitInfo *signal_semaphore_info) -> VkSubmitInfo2
|
vk::SemaphoreSubmitInfo *signal_semaphore_info) -> vk::SubmitInfo2
|
||||||
{
|
{
|
||||||
VkSubmitInfo2 info {};
|
vk::SubmitInfo2 info {};
|
||||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.flags = 0;
|
|
||||||
info.waitSemaphoreInfoCount = wait_semaphore_info ? 1u : 0u;
|
info.waitSemaphoreInfoCount = wait_semaphore_info ? 1u : 0u;
|
||||||
info.pWaitSemaphoreInfos = wait_semaphore_info;
|
info.pWaitSemaphoreInfos = wait_semaphore_info;
|
||||||
info.commandBufferInfoCount = cmd_info ? 1u : 0u;
|
info.commandBufferInfoCount = cmd_info ? 1u : 0u;
|
||||||
@@ -190,18 +152,15 @@ auto submit_info2(VkCommandBufferSubmitInfo *cmd_info,
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto attachment_info(VkImageView view, VkClearValue *clear,
|
auto attachment_info(vk::ImageView view, vk::ClearValue *clear,
|
||||||
VkImageLayout layout) -> VkRenderingAttachmentInfo
|
vk::ImageLayout layout) -> vk::RenderingAttachmentInfo
|
||||||
{
|
{
|
||||||
VkRenderingAttachmentInfo color_at {};
|
vk::RenderingAttachmentInfo color_at {};
|
||||||
color_at.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
|
|
||||||
color_at.pNext = nullptr;
|
|
||||||
|
|
||||||
color_at.imageView = view;
|
color_at.imageView = view;
|
||||||
color_at.imageLayout = layout;
|
color_at.imageLayout = layout;
|
||||||
color_at.loadOp
|
color_at.loadOp
|
||||||
= clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
|
= clear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad;
|
||||||
color_at.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
color_at.storeOp = vk::AttachmentStoreOp::eStore;
|
||||||
if (clear) {
|
if (clear) {
|
||||||
color_at.clearValue = *clear;
|
color_at.clearValue = *clear;
|
||||||
}
|
}
|
||||||
@@ -209,27 +168,22 @@ auto attachment_info(VkImageView view, VkClearValue *clear,
|
|||||||
return color_at;
|
return color_at;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pipeline_shader_stage(VkShaderStageFlagBits stage, VkShaderModule module)
|
auto pipeline_shader_stage(vk::ShaderStageFlagBits stage,
|
||||||
-> VkPipelineShaderStageCreateInfo
|
vk::ShaderModule module) -> vk::PipelineShaderStageCreateInfo
|
||||||
{
|
{
|
||||||
VkPipelineShaderStageCreateInfo stage_ci {};
|
vk::PipelineShaderStageCreateInfo stage_ci {};
|
||||||
stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
||||||
stage_ci.pNext = nullptr;
|
|
||||||
stage_ci.stage = stage;
|
stage_ci.stage = stage;
|
||||||
stage_ci.module = module;
|
stage_ci.module = module;
|
||||||
stage_ci.pName = "main";
|
stage_ci.pName = "main";
|
||||||
return stage_ci;
|
return stage_ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto render_info(VkExtent2D extent, VkRenderingAttachmentInfo const *color_att,
|
auto render_info(vk::Extent2D extent,
|
||||||
VkRenderingAttachmentInfo const *depth_att) -> VkRenderingInfo
|
vk::RenderingAttachmentInfo const *color_att,
|
||||||
|
vk::RenderingAttachmentInfo const *depth_att) -> vk::RenderingInfo
|
||||||
{
|
{
|
||||||
|
vk::RenderingInfo render_info {};
|
||||||
VkRenderingInfo render_info {};
|
render_info.renderArea = vk::Rect2D { {}, extent };
|
||||||
render_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
|
|
||||||
render_info.pNext = nullptr;
|
|
||||||
render_info.flags = 0;
|
|
||||||
render_info.renderArea = { {}, extent };
|
|
||||||
render_info.layerCount = 1;
|
render_info.layerCount = 1;
|
||||||
render_info.colorAttachmentCount = color_att ? 1 : 0;
|
render_info.colorAttachmentCount = color_att ? 1 : 0;
|
||||||
render_info.pColorAttachments = color_att;
|
render_info.pColorAttachments = color_att;
|
||||||
@@ -237,19 +191,15 @@ auto render_info(VkExtent2D extent, VkRenderingAttachmentInfo const *color_att,
|
|||||||
return render_info;
|
return render_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto depth_attachment_info(VkImageView view, VkImageLayout layout)
|
auto depth_attachment_info(vk::ImageView view, vk::ImageLayout layout)
|
||||||
-> VkRenderingAttachmentInfo
|
-> vk::RenderingAttachmentInfo
|
||||||
{
|
{
|
||||||
VkRenderingAttachmentInfo depth_att {};
|
vk::RenderingAttachmentInfo depth_att {};
|
||||||
depth_att.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
|
|
||||||
depth_att.pNext = nullptr;
|
|
||||||
|
|
||||||
depth_att.imageView = view;
|
depth_att.imageView = view;
|
||||||
depth_att.imageLayout = layout;
|
depth_att.imageLayout = layout;
|
||||||
depth_att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
depth_att.loadOp = vk::AttachmentLoadOp::eClear;
|
||||||
depth_att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
depth_att.storeOp = vk::AttachmentStoreOp::eStore;
|
||||||
depth_att.clearValue.depthStencil.depth = 1.f;
|
depth_att.clearValue.depthStencil.depth = 1.f;
|
||||||
|
|
||||||
return depth_att;
|
return depth_att;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
65
src/Util.h
65
src/Util.h
@@ -3,7 +3,7 @@
|
|||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#include <vulkan/vk_enum_string_helper.h>
|
#include <vulkan/vk_enum_string_helper.h>
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
template<typename F> struct privDefer {
|
template<typename F> struct privDefer {
|
||||||
F f;
|
F f;
|
||||||
@@ -29,46 +29,49 @@ template<typename F> privDefer<F> defer_func(F f) { return privDefer<F>(f); }
|
|||||||
|
|
||||||
#define VK_CHECK(logger, x) \
|
#define VK_CHECK(logger, x) \
|
||||||
do { \
|
do { \
|
||||||
VkResult err { x }; \
|
auto err { x }; \
|
||||||
if (err) { \
|
auto result = vk::Result(err); \
|
||||||
(logger).err("Detected Vulkan error: {}", string_VkResult(err)); \
|
if (result != vk::Result::eSuccess) { \
|
||||||
|
(logger).err("Detected Vulkan error: {}", vk::to_string(result)); \
|
||||||
throw std::runtime_error("Vulkan error"); \
|
throw std::runtime_error("Vulkan error"); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
namespace vkutil {
|
namespace vkutil {
|
||||||
|
|
||||||
auto transition_image(VkCommandBuffer cmd, VkImage image,
|
auto transition_image(vk::CommandBuffer cmd, vk::Image image,
|
||||||
VkImageLayout current_layout, VkImageLayout new_layout) -> void;
|
vk::ImageLayout current_layout, vk::ImageLayout new_layout) -> void;
|
||||||
auto copy_image_to_image(VkCommandBuffer cmd, VkImage source,
|
auto copy_image_to_image(vk::CommandBuffer cmd, vk::Image source,
|
||||||
VkImage destination, VkExtent2D src_size, VkExtent2D dst_size) -> void;
|
vk::Image destination, vk::Extent2D src_size, vk::Extent2D dst_size)
|
||||||
auto load_shader_module(std::span<uint8_t> spirv_data, VkDevice device,
|
-> void;
|
||||||
VkShaderModule *out_shader_module) -> bool;
|
auto load_shader_module(std::span<uint8_t> spirv_data, vk::Device device)
|
||||||
|
-> vk::UniqueShaderModule;
|
||||||
|
|
||||||
} // namespace vkutil
|
} // namespace vkutil
|
||||||
|
|
||||||
namespace vkinit {
|
namespace vkinit {
|
||||||
|
|
||||||
auto image_create_info(VkFormat format, VkImageUsageFlags usage_flags,
|
auto image_create_info(vk::Format format, vk::ImageUsageFlags usage_flags,
|
||||||
VkExtent3D extent) -> VkImageCreateInfo;
|
vk::Extent3D extent) -> vk::ImageCreateInfo;
|
||||||
auto imageview_create_info(VkFormat format, VkImage image,
|
auto imageview_create_info(vk::Format format, vk::Image image,
|
||||||
VkImageAspectFlags aspect_flags) -> VkImageViewCreateInfo;
|
vk::ImageAspectFlags aspect_flags) -> vk::ImageViewCreateInfo;
|
||||||
auto command_buffer_submit_info(VkCommandBuffer cmd)
|
auto command_buffer_submit_info(vk::CommandBuffer cmd)
|
||||||
-> VkCommandBufferSubmitInfo;
|
-> vk::CommandBufferSubmitInfo;
|
||||||
auto semaphore_submit_info(VkPipelineStageFlags2 stage_mask,
|
auto semaphore_submit_info(vk::PipelineStageFlags2 stage_mask,
|
||||||
VkSemaphore semaphore) -> VkSemaphoreSubmitInfo;
|
vk::Semaphore semaphore) -> vk::SemaphoreSubmitInfo;
|
||||||
auto submit_info2(VkCommandBufferSubmitInfo *cmd_info,
|
auto submit_info2(vk::CommandBufferSubmitInfo *cmd_info,
|
||||||
VkSemaphoreSubmitInfo *wait_semaphore_info,
|
vk::SemaphoreSubmitInfo *wait_semaphore_info,
|
||||||
VkSemaphoreSubmitInfo *signal_semaphore_info) -> VkSubmitInfo2;
|
vk::SemaphoreSubmitInfo *signal_semaphore_info) -> vk::SubmitInfo2;
|
||||||
auto attachment_info(VkImageView view, VkClearValue *clear,
|
auto attachment_info(vk::ImageView view, vk::ClearValue *clear,
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
vk::ImageLayout layout = vk::ImageLayout::eColorAttachmentOptimal)
|
||||||
-> VkRenderingAttachmentInfo;
|
-> vk::RenderingAttachmentInfo;
|
||||||
auto pipeline_shader_stage(VkShaderStageFlagBits stage, VkShaderModule module)
|
auto pipeline_shader_stage(vk::ShaderStageFlagBits stage,
|
||||||
-> VkPipelineShaderStageCreateInfo;
|
vk::ShaderModule module) -> vk::PipelineShaderStageCreateInfo;
|
||||||
auto render_info(VkExtent2D extent, VkRenderingAttachmentInfo const *color_att,
|
auto render_info(vk::Extent2D extent,
|
||||||
VkRenderingAttachmentInfo const *depth_att) -> VkRenderingInfo;
|
vk::RenderingAttachmentInfo const *color_att,
|
||||||
auto depth_attachment_info(VkImageView view,
|
vk::RenderingAttachmentInfo const *depth_att) -> vk::RenderingInfo;
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL)
|
auto depth_attachment_info(vk::ImageView view,
|
||||||
-> VkRenderingAttachmentInfo;
|
vk::ImageLayout layout = vk::ImageLayout::eDepthAttachmentOptimal)
|
||||||
|
-> vk::RenderingAttachmentInfo;
|
||||||
|
|
||||||
} // namespace vkinit
|
} // namespace vkinit
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,43 +1,149 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <SDL3/SDL_video.h>
|
#include <SDL3/SDL_video.h>
|
||||||
#include <VkBootstrap.h>
|
#include <VkBootstrap.h>
|
||||||
#include <smath.hpp>
|
#include <smath.hpp>
|
||||||
#include <vk_mem_alloc.h>
|
#include <vk_mem_alloc.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
#include "Colors.h"
|
||||||
#include "DeletionQueue.h"
|
#include "DeletionQueue.h"
|
||||||
#include "DescriptorAllocator.h"
|
#include "DescriptorAllocator.h"
|
||||||
#include "Loader.h"
|
#include "Loader.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "Pipeline.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
namespace Lunar {
|
namespace Lunar {
|
||||||
|
|
||||||
struct GPUDrawPushConstants {
|
struct GPUDrawPushConstants {
|
||||||
smath::Mat4 world_matrix;
|
smath::Mat4 world_matrix;
|
||||||
VkDeviceAddress vertex_buffer;
|
vk::DeviceAddress vertex_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr unsigned FRAME_OVERLAP = 2;
|
constexpr unsigned FRAME_OVERLAP = 2;
|
||||||
|
|
||||||
struct VulkanRenderer {
|
struct VulkanRenderer {
|
||||||
|
struct GL {
|
||||||
|
enum class GeometryKind {
|
||||||
|
Triangles,
|
||||||
|
TriangleStrip,
|
||||||
|
TriangleFan,
|
||||||
|
Quads
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit GL(VulkanRenderer &renderer);
|
||||||
|
|
||||||
|
auto begin_drawing(vk::CommandBuffer cmd, AllocatedImage &color_target,
|
||||||
|
AllocatedImage *depth_target = nullptr) -> void;
|
||||||
|
auto end_drawing() -> void;
|
||||||
|
|
||||||
|
auto begin(GeometryKind kind) -> void;
|
||||||
|
template<size_t N>
|
||||||
|
auto vert(smath::Vec<N, float> const &position) -> void
|
||||||
|
{
|
||||||
|
static_assert(N == 2 || N == 3 || N == 4,
|
||||||
|
"Position must be a 2D, 3D, or 4D vec");
|
||||||
|
|
||||||
|
smath::Vec3 pos { 0.0f, 0.0f, 0.0f };
|
||||||
|
pos[0] = position[0];
|
||||||
|
pos[1] = position[1];
|
||||||
|
if constexpr (N >= 3) {
|
||||||
|
pos[2] = position[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
push_vertex(pos);
|
||||||
|
}
|
||||||
|
auto color(smath::Vec3 const &rgb) -> void;
|
||||||
|
auto color(smath::Vec4 const &rgba) -> void;
|
||||||
|
auto uv(smath::Vec2 const &uv) -> void;
|
||||||
|
auto normal(smath::Vec3 const &normal) -> void;
|
||||||
|
auto set_texture(std::optional<AllocatedImage const *> texture
|
||||||
|
= std::nullopt) -> void;
|
||||||
|
auto draw_rectangle(smath::Vec2 pos, smath::Vec2 size,
|
||||||
|
smath::Vec4 color = smath::Vec4 { Colors::WHITE, 1.0f },
|
||||||
|
float rotation = 0.0f) -> void;
|
||||||
|
auto end() -> void;
|
||||||
|
auto flush() -> void;
|
||||||
|
|
||||||
|
auto use_pipeline(Pipeline &pipeline) -> void;
|
||||||
|
auto set_transform(smath::Mat4 const &transform) -> void;
|
||||||
|
auto draw_mesh(GPUMeshBuffers const &mesh, smath::Mat4 const &transform,
|
||||||
|
uint32_t index_count, uint32_t first_index = 0,
|
||||||
|
int32_t vertex_offset = 0) -> void;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto push_vertex(smath::Vec3 const &pos) -> void;
|
||||||
|
auto emit_indices(size_t start, size_t count) -> void;
|
||||||
|
auto bind_pipeline_if_needed() -> void;
|
||||||
|
|
||||||
|
VulkanRenderer &m_renderer;
|
||||||
|
vk::CommandBuffer m_cmd {};
|
||||||
|
AllocatedImage *m_color_target { nullptr };
|
||||||
|
AllocatedImage *m_depth_target { nullptr };
|
||||||
|
GeometryKind m_current_kind { GeometryKind::Triangles };
|
||||||
|
bool m_inside_primitive { false };
|
||||||
|
bool m_drawing { false };
|
||||||
|
Pipeline *m_active_pipeline { nullptr };
|
||||||
|
smath::Mat4 m_transform { smath::Mat4::identity() };
|
||||||
|
smath::Vec4 m_current_color { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
smath::Vec3 m_current_normal { 0.0f, 0.0f, 1.0f };
|
||||||
|
smath::Vec2 m_current_uv { 0.0f, 0.0f };
|
||||||
|
AllocatedImage const *m_bound_texture { nullptr };
|
||||||
|
size_t m_primitive_start { 0 };
|
||||||
|
std::vector<Vertex> m_vertices;
|
||||||
|
std::vector<uint32_t> m_indices;
|
||||||
|
};
|
||||||
|
|
||||||
VulkanRenderer(SDL_Window *window, Logger &logger);
|
VulkanRenderer(SDL_Window *window, Logger &logger);
|
||||||
~VulkanRenderer();
|
~VulkanRenderer();
|
||||||
|
|
||||||
auto render() -> void;
|
auto render(std::function<void(GL &)> const &record = {}) -> void;
|
||||||
auto resize(uint32_t width, uint32_t height) -> void;
|
auto resize(uint32_t width, uint32_t height) -> void;
|
||||||
|
|
||||||
auto immediate_submit(std::function<void(VkCommandBuffer cmd)> &&function)
|
auto immediate_submit(std::function<void(vk::CommandBuffer cmd)> &&function,
|
||||||
-> void;
|
bool flush_frame_deletion_queue = true,
|
||||||
|
bool clear_frame_descriptors = true) -> void;
|
||||||
auto upload_mesh(std::span<uint32_t> indices, std::span<Vertex> vertices)
|
auto upload_mesh(std::span<uint32_t> indices, std::span<Vertex> vertices)
|
||||||
-> GPUMeshBuffers;
|
-> GPUMeshBuffers;
|
||||||
|
auto rectangle_mesh() const -> GPUMeshBuffers const &
|
||||||
|
{
|
||||||
|
return m_vk.rectangle;
|
||||||
|
}
|
||||||
|
auto test_meshes() const -> std::vector<std::shared_ptr<Mesh>> const &
|
||||||
|
{
|
||||||
|
return m_vk.test_meshes;
|
||||||
|
}
|
||||||
|
auto white_texture() const -> AllocatedImage const &
|
||||||
|
{
|
||||||
|
return m_vk.white_image;
|
||||||
|
}
|
||||||
|
auto gray_texture() const -> AllocatedImage const &
|
||||||
|
{
|
||||||
|
return m_vk.gray_image;
|
||||||
|
}
|
||||||
|
auto black_texture() const -> AllocatedImage const &
|
||||||
|
{
|
||||||
|
return m_vk.black_image;
|
||||||
|
}
|
||||||
|
auto error_texture() const -> AllocatedImage const &
|
||||||
|
{
|
||||||
|
return m_vk.error_image;
|
||||||
|
}
|
||||||
|
auto draw_extent() const -> vk::Extent2D { return m_vk.draw_extent; }
|
||||||
|
auto mesh_pipeline() -> Pipeline & { return m_vk.mesh_pipeline; }
|
||||||
|
auto triangle_pipeline() -> Pipeline & { return m_vk.triangle_pipeline; }
|
||||||
|
auto gl_api() -> GL & { return gl; }
|
||||||
|
|
||||||
auto logger() const -> Logger & { return m_logger; }
|
auto logger() const -> Logger & { return m_logger; }
|
||||||
|
|
||||||
|
GL gl;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto vk_init() -> void;
|
auto vk_init() -> void;
|
||||||
auto swapchain_init() -> void;
|
auto swapchain_init() -> void;
|
||||||
@@ -51,9 +157,9 @@ private:
|
|||||||
auto imgui_init() -> void;
|
auto imgui_init() -> void;
|
||||||
auto default_data_init() -> void;
|
auto default_data_init() -> void;
|
||||||
|
|
||||||
auto draw_background(VkCommandBuffer cmd) -> void;
|
auto draw_background(vk::CommandBuffer cmd) -> void;
|
||||||
auto draw_geometry(VkCommandBuffer cmd) -> void;
|
auto draw_imgui(vk::CommandBuffer cmd, vk::ImageView target_image_view)
|
||||||
auto draw_imgui(VkCommandBuffer cmd, VkImageView target_image_view) -> void;
|
-> void;
|
||||||
|
|
||||||
auto create_swapchain(uint32_t width, uint32_t height) -> void;
|
auto create_swapchain(uint32_t width, uint32_t height) -> void;
|
||||||
auto create_draw_image(uint32_t width, uint32_t height) -> void;
|
auto create_draw_image(uint32_t width, uint32_t height) -> void;
|
||||||
@@ -63,16 +169,20 @@ private:
|
|||||||
auto destroy_depth_image() -> void;
|
auto destroy_depth_image() -> void;
|
||||||
auto recreate_swapchain(uint32_t width, uint32_t height) -> void;
|
auto recreate_swapchain(uint32_t width, uint32_t height) -> void;
|
||||||
auto destroy_swapchain() -> void;
|
auto destroy_swapchain() -> void;
|
||||||
auto create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags flags,
|
auto create_image(vk::Extent3D size, vk::Format format,
|
||||||
bool mipmapped = false) -> AllocatedImage;
|
vk::ImageUsageFlags flags, bool mipmapped = false) -> AllocatedImage;
|
||||||
auto create_image(void const *data, VkExtent3D size, VkFormat format,
|
auto create_image(void const *data, vk::Extent3D size, vk::Format format,
|
||||||
VkImageUsageFlags flags, bool mipmapped = false) -> AllocatedImage;
|
vk::ImageUsageFlags flags, bool mipmapped = false) -> AllocatedImage;
|
||||||
auto destroy_image(AllocatedImage const &img) -> void;
|
auto destroy_image(AllocatedImage const &img) -> void;
|
||||||
|
|
||||||
auto create_buffer(size_t alloc_size, VkBufferUsageFlags usage,
|
auto create_buffer(size_t alloc_size, vk::BufferUsageFlags usage,
|
||||||
VmaMemoryUsage memory_usage) -> AllocatedBuffer;
|
VmaMemoryUsage memory_usage) -> AllocatedBuffer;
|
||||||
auto destroy_buffer(AllocatedBuffer const &buffer) -> void;
|
auto destroy_buffer(AllocatedBuffer const &buffer) -> void;
|
||||||
|
|
||||||
|
vk::Instance m_instance {};
|
||||||
|
vk::PhysicalDevice m_physical_device {};
|
||||||
|
vk::Device m_device {};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
vkb::Instance instance;
|
vkb::Instance instance;
|
||||||
vkb::PhysicalDevice phys_dev;
|
vkb::PhysicalDevice phys_dev;
|
||||||
@@ -86,50 +196,47 @@ private:
|
|||||||
return frames.at(frame_number % frames.size());
|
return frames.at(frame_number % frames.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSwapchainKHR swapchain { VK_NULL_HANDLE };
|
vk::SwapchainKHR swapchain {};
|
||||||
VkSurfaceKHR surface { nullptr };
|
vk::SurfaceKHR surface {};
|
||||||
VkFormat swapchain_image_format;
|
vk::Format swapchain_image_format {};
|
||||||
|
|
||||||
uint32_t graphics_queue_family { 0 };
|
uint32_t graphics_queue_family { 0 };
|
||||||
VkQueue graphics_queue { nullptr };
|
vk::Queue graphics_queue {};
|
||||||
|
|
||||||
std::vector<VkImage> swapchain_images;
|
std::vector<vk::Image> swapchain_images;
|
||||||
std::vector<VkImageView> swapchain_image_views;
|
std::vector<vk::UniqueImageView> swapchain_image_views;
|
||||||
std::vector<VkSemaphore> present_semaphores;
|
std::vector<vk::UniqueSemaphore> present_semaphores;
|
||||||
VkExtent2D swapchain_extent;
|
vk::Extent2D swapchain_extent;
|
||||||
|
|
||||||
std::array<FrameData, FRAME_OVERLAP> frames;
|
std::array<FrameData, FRAME_OVERLAP> frames;
|
||||||
AllocatedImage draw_image {};
|
AllocatedImage draw_image {};
|
||||||
AllocatedImage depth_image {};
|
AllocatedImage depth_image {};
|
||||||
VkExtent2D draw_extent {};
|
vk::Extent2D draw_extent {};
|
||||||
|
|
||||||
VmaAllocator allocator;
|
VmaAllocator allocator;
|
||||||
DescriptorAllocator descriptor_allocator;
|
DescriptorAllocator descriptor_allocator;
|
||||||
|
|
||||||
VkDescriptorSet draw_image_descriptors;
|
VkDescriptorSet draw_image_descriptors {};
|
||||||
VkDescriptorSetLayout draw_image_descriptor_layout;
|
vk::DescriptorSetLayout draw_image_descriptor_layout {};
|
||||||
|
|
||||||
GPUSceneData scene_data {};
|
GPUSceneData scene_data {};
|
||||||
VkDescriptorSetLayout gpu_scene_data_descriptor_layout;
|
vk::DescriptorSetLayout gpu_scene_data_descriptor_layout {};
|
||||||
|
|
||||||
VkPipeline gradient_pipeline {};
|
vk::DescriptorSetLayout single_image_descriptor_layout {};
|
||||||
VkPipelineLayout gradient_pipeline_layout {};
|
|
||||||
|
|
||||||
VkPipeline triangle_pipeline {};
|
Pipeline gradient_pipeline;
|
||||||
VkPipelineLayout triangle_pipeline_layout {};
|
Pipeline triangle_pipeline;
|
||||||
|
Pipeline mesh_pipeline;
|
||||||
VkPipeline mesh_pipeline {};
|
|
||||||
VkPipelineLayout mesh_pipeline_layout {};
|
|
||||||
|
|
||||||
GPUMeshBuffers rectangle;
|
GPUMeshBuffers rectangle;
|
||||||
|
|
||||||
VkDescriptorPool imgui_descriptor_pool { VK_NULL_HANDLE };
|
vk::UniqueDescriptorPool imgui_descriptor_pool;
|
||||||
|
|
||||||
DeletionQueue deletion_queue;
|
DeletionQueue deletion_queue;
|
||||||
|
|
||||||
VkFence imm_fence {};
|
vk::UniqueFence imm_fence;
|
||||||
VkCommandBuffer imm_command_buffer {};
|
vk::UniqueCommandBuffer imm_command_buffer;
|
||||||
VkCommandPool imm_command_pool {};
|
vk::UniqueCommandPool imm_command_pool;
|
||||||
|
|
||||||
uint64_t frame_number { 0 };
|
uint64_t frame_number { 0 };
|
||||||
|
|
||||||
@@ -140,8 +247,8 @@ private:
|
|||||||
AllocatedImage gray_image {};
|
AllocatedImage gray_image {};
|
||||||
AllocatedImage error_image {};
|
AllocatedImage error_image {};
|
||||||
|
|
||||||
VkSampler default_sampler_linear;
|
vk::UniqueSampler default_sampler_linear;
|
||||||
VkSampler default_sampler_nearest;
|
vk::UniqueSampler default_sampler_nearest;
|
||||||
} m_vk;
|
} m_vk;
|
||||||
|
|
||||||
SDL_Window *m_window { nullptr };
|
SDL_Window *m_window { nullptr };
|
||||||
|
|||||||
Reference in New Issue
Block a user