You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.3 KiB
163 lines
4.3 KiB
// Copyright 2022 Simon Boyé
|
|
#include <VkExpe.h>
|
|
|
|
#include <core/utils.h>
|
|
#include <core/Logger.h>
|
|
|
|
#include <stdexcept>
|
|
#include <iostream>
|
|
#include <chrono>
|
|
|
|
|
|
void SdlWindowDeleter::operator()(SDL_Window* window) const {
|
|
SDL_DestroyWindow(window);
|
|
}
|
|
|
|
|
|
VkExpe::VkExpe(int argc, char** argv) {
|
|
}
|
|
|
|
VkExpe::~VkExpe() {
|
|
shutdown();
|
|
}
|
|
|
|
void VkExpe::initialize() {
|
|
SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO);
|
|
|
|
auto const window = SDL_CreateWindow(
|
|
"vk_expe",
|
|
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
|
1920, 1080,
|
|
SDL_WINDOW_VULKAN
|
|
| SDL_WINDOW_ALLOW_HIGHDPI
|
|
| SDL_WINDOW_SHOWN
|
|
| SDL_WINDOW_RESIZABLE
|
|
);
|
|
m_window = WindowUP(
|
|
window
|
|
);
|
|
if(!m_window)
|
|
throw std::runtime_error("failed to create window");
|
|
|
|
m_vulkan.initialize(m_window.get());
|
|
}
|
|
|
|
void VkExpe::shutdown() {
|
|
m_vulkan.shutdown();
|
|
|
|
m_window.reset();
|
|
|
|
if (SDL_WasInit(0))
|
|
SDL_Quit();
|
|
}
|
|
|
|
void VkExpe::run() {
|
|
if(m_running)
|
|
throw std::runtime_error("calling run while already running");
|
|
|
|
initialize();
|
|
|
|
m_running = true;
|
|
auto running_guard = make_guard([this] {
|
|
m_running = false;
|
|
});
|
|
|
|
auto last_time = std::chrono::high_resolution_clock::now();
|
|
|
|
SDL_Event event;
|
|
while(m_running) {
|
|
while(SDL_PollEvent(&event)) {
|
|
switch(event.type) {
|
|
case SDL_QUIT:
|
|
m_running = false;
|
|
break;
|
|
case SDL_KEYDOWN: {
|
|
if(event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
|
|
m_running = false;
|
|
break;
|
|
}
|
|
case SDL_MOUSEMOTION: {
|
|
m_mouse_offset += Vector2(
|
|
event.motion.xrel,
|
|
event.motion.yrel
|
|
);
|
|
break;
|
|
}
|
|
case SDL_WINDOWEVENT: {
|
|
switch(event.window.event) {
|
|
case SDL_WINDOWEVENT_RESIZED: {
|
|
m_vulkan.invalidate_swapchain();
|
|
break;
|
|
}
|
|
case SDL_WINDOWEVENT_FOCUS_GAINED: {
|
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
|
break;
|
|
}
|
|
case SDL_WINDOWEVENT_FOCUS_LOST: {
|
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
const auto new_time = std::chrono::high_resolution_clock::now();
|
|
const auto elapsed = new_time - last_time;
|
|
last_time = new_time;
|
|
|
|
update(std::chrono::duration<double>(elapsed).count());
|
|
|
|
m_vulkan.set_camera(m_camera_position, m_camera_z, m_camera_y);
|
|
m_vulkan.draw_frame();
|
|
|
|
m_mouse_offset = Vector2::Zero();
|
|
}
|
|
}
|
|
|
|
void VkExpe::update(double elapsed) {
|
|
int key_count = 0;
|
|
const auto keys = SDL_GetKeyboardState(&key_count);
|
|
|
|
const auto test_key = [key_count, keys](int scan_code) {
|
|
return scan_code < key_count && keys[scan_code];
|
|
};
|
|
|
|
if (!m_mouse_offset.isZero()) {
|
|
const Real x_sensi = 0.001;
|
|
const Real y_sensi = -0.001;
|
|
|
|
const Vector3 camera_x = m_camera_y.cross(m_camera_z);
|
|
Vector3 axis =
|
|
x_sensi * m_mouse_offset[0] * m_camera_y +
|
|
y_sensi * m_mouse_offset[1] * camera_x;
|
|
Real rot_norm = axis.norm();
|
|
AngleAxis rot(rot_norm, axis / rot_norm);
|
|
m_camera_y = rot * m_camera_y;
|
|
m_camera_z = rot * m_camera_z;
|
|
}
|
|
|
|
Vector3 walk_direction = Vector3::Zero();
|
|
if(test_key(SDL_SCANCODE_W))
|
|
walk_direction += Vector3::UnitZ();
|
|
if(test_key(SDL_SCANCODE_S))
|
|
walk_direction -= Vector3::UnitZ();
|
|
if(test_key(SDL_SCANCODE_A))
|
|
walk_direction -= Vector3::UnitX();
|
|
if(test_key(SDL_SCANCODE_D))
|
|
walk_direction += Vector3::UnitX();
|
|
if(test_key(SDL_SCANCODE_SPACE))
|
|
walk_direction -= Vector3::UnitY();
|
|
if(test_key(SDL_SCANCODE_LCTRL))
|
|
walk_direction += Vector3::UnitY();
|
|
|
|
if(!walk_direction.isZero()) {
|
|
walk_direction.normalize();
|
|
const Real base_velocity = 1;
|
|
|
|
Matrix3 camera_basis;
|
|
camera_basis << m_camera_y.cross(m_camera_z), m_camera_y, m_camera_z;
|
|
m_camera_position += elapsed * base_velocity * (camera_basis * walk_direction);
|
|
}
|
|
}
|
|
|