Camera + fix swapchain crash.
This commit is contained in:
@@ -56,10 +56,11 @@ add_executable(vk_expe
|
|||||||
src/vk/Swapchain.cpp
|
src/vk/Swapchain.cpp
|
||||||
|
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
|
src/Camera.cpp
|
||||||
src/Simplex.cpp
|
src/Simplex.cpp
|
||||||
src/Planet.cpp
|
src/Planet.cpp
|
||||||
src/VkExpe.cpp
|
src/VkExpe.cpp
|
||||||
src/VulkanTutorial.cpp
|
src/Renderer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_shaders(vk_expe
|
add_shaders(vk_expe
|
||||||
|
|||||||
70
src/Camera.cpp
Normal file
70
src/Camera.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
// Copyright 2022 Simon Boyé
|
||||||
|
|
||||||
|
#include <Camera.h>
|
||||||
|
|
||||||
|
|
||||||
|
Camera::Camera() noexcept
|
||||||
|
: m_left(-1)
|
||||||
|
, m_right(1)
|
||||||
|
, m_top(-1)
|
||||||
|
, m_bottom(1)
|
||||||
|
, m_near(0.1)
|
||||||
|
, m_far(100)
|
||||||
|
, m_position(Vector3::Zero())
|
||||||
|
, m_direction(Vector3::UnitZ())
|
||||||
|
, m_down(Vector3::UnitY())
|
||||||
|
{}
|
||||||
|
|
||||||
|
Camera::~Camera() = default;
|
||||||
|
|
||||||
|
|
||||||
|
void Camera::set_projection(Real h_fov, Real width_height_ratio) noexcept {
|
||||||
|
const Real hx = std::tan(h_fov / Real(2));
|
||||||
|
const Real hy = hx / width_height_ratio;
|
||||||
|
set_projection(
|
||||||
|
-hx, hx,
|
||||||
|
-hy, hy
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::update_aspect_ratio(Real width_height_ratio) noexcept {
|
||||||
|
const Real prev_ratio = (m_right - m_left) / (m_bottom - m_top);
|
||||||
|
const Real next_ratio = width_height_ratio;
|
||||||
|
|
||||||
|
const Real sx = (Real(1) + Real(1) / prev_ratio) / (Real(1) + Real(1) / next_ratio);
|
||||||
|
const Real sy = (Real(1) + prev_ratio) / (Real(1) + next_ratio);
|
||||||
|
|
||||||
|
m_left *= sx;
|
||||||
|
m_right *= sx;
|
||||||
|
m_top *= sy;
|
||||||
|
m_bottom *= sy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Matrix3 Camera::basis() const noexcept {
|
||||||
|
Matrix3 basis;
|
||||||
|
basis << m_down.cross(m_direction), m_down, m_direction;
|
||||||
|
return basis;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4 Camera::view_matrix() const noexcept {
|
||||||
|
Matrix3 linear_view;
|
||||||
|
linear_view <<
|
||||||
|
m_down.cross(m_direction).transpose(),
|
||||||
|
m_down.transpose(),
|
||||||
|
m_direction.transpose();
|
||||||
|
Matrix4 view;
|
||||||
|
view << linear_view, linear_view * -m_position,
|
||||||
|
Vector4::UnitW().transpose();
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4 Camera::projection_matrix() const noexcept {
|
||||||
|
return ::projection_matrix(
|
||||||
|
m_near * m_left, m_near * m_right,
|
||||||
|
m_near * m_top, m_near * m_bottom,
|
||||||
|
m_near, m_far
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
92
src/Camera.h
Normal file
92
src/Camera.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// Copyright 2022 Simon Boyé
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <core/math.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Camera {
|
||||||
|
public:
|
||||||
|
Camera() noexcept;
|
||||||
|
~Camera();
|
||||||
|
|
||||||
|
inline Real left() const noexcept {
|
||||||
|
return m_left;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Real right() const noexcept {
|
||||||
|
return m_right;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Real top() const noexcept {
|
||||||
|
return m_top;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Real bottom() const noexcept {
|
||||||
|
return m_bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_projection(Real left, Real right, Real top, Real bottom) noexcept {
|
||||||
|
m_left = left;
|
||||||
|
m_right = right;
|
||||||
|
m_top = top;
|
||||||
|
m_bottom = bottom;
|
||||||
|
}
|
||||||
|
void set_projection(Real h_fov, Real width_height_ratio) noexcept;
|
||||||
|
void update_aspect_ratio(Real width_height_ratio) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
inline Real near() const noexcept {
|
||||||
|
return m_near;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Real far() const noexcept {
|
||||||
|
return m_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_clip_distances(Real near, Real far) noexcept {
|
||||||
|
m_near = near;
|
||||||
|
m_far = far;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Vector3 position() const noexcept {
|
||||||
|
return m_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set_position(const Vector3& position) noexcept {
|
||||||
|
m_position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 direction() const noexcept {
|
||||||
|
return m_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set_direction(const Vector3& direction) noexcept {
|
||||||
|
m_direction = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 down() const noexcept {
|
||||||
|
return m_down;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set_down(const Vector3& down) noexcept {
|
||||||
|
m_down = down;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix3 basis() const noexcept;
|
||||||
|
Matrix4 view_matrix() const noexcept;
|
||||||
|
Matrix4 projection_matrix() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Real m_left;
|
||||||
|
Real m_right;
|
||||||
|
Real m_top;
|
||||||
|
Real m_bottom;
|
||||||
|
|
||||||
|
Real m_near;
|
||||||
|
Real m_far;
|
||||||
|
|
||||||
|
Vector3 m_position;
|
||||||
|
Vector3 m_direction;
|
||||||
|
Vector3 m_down;
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// Copyright 2022 Simon Boyé
|
// Copyright 2022 Simon Boyé
|
||||||
#include <VulkanTutorial.h>
|
#include <Renderer.h>
|
||||||
|
|
||||||
#include <Planet.h>
|
#include <Planet.h>
|
||||||
|
|
||||||
@@ -98,9 +98,9 @@ struct Uniforms {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
VulkanTutorial::VulkanTutorial() {
|
Renderer::Renderer() {
|
||||||
m_swapchain.register_creation_callback(
|
m_swapchain.register_creation_callback(
|
||||||
std::bind(&VulkanTutorial::create_swapchain_objects, this));
|
std::bind(&Renderer::create_swapchain_objects, this));
|
||||||
|
|
||||||
auto const subdiv_count = 4;
|
auto const subdiv_count = 4;
|
||||||
|
|
||||||
@@ -151,13 +151,13 @@ VulkanTutorial::VulkanTutorial() {
|
|||||||
// abort();
|
// abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanTutorial::~VulkanTutorial() {
|
Renderer::~Renderer() {
|
||||||
if(m_context)
|
if(m_context)
|
||||||
vkDeviceWaitIdle(m_context.device());
|
vkDeviceWaitIdle(m_context.device());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::initialize(SDL_Window* window) {
|
void Renderer::initialize(SDL_Window* window) {
|
||||||
auto const context_settings = vk::ContextSettings()
|
auto const context_settings = vk::ContextSettings()
|
||||||
#if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG)
|
#if defined(VKEXPE_ENABLE_VALIDATION) || !defined(NDEBUG)
|
||||||
.with_debug(true)
|
.with_debug(true)
|
||||||
@@ -183,43 +183,19 @@ void VulkanTutorial::initialize(SDL_Window* window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::set_camera(const Vector3& camera_position, const Vector3& camera_z, const Vector3& camera_y) {
|
void Renderer::set_camera(const Camera& camera) {
|
||||||
m_camera_position = camera_position;
|
m_camera = camera;
|
||||||
m_camera_z = camera_z;
|
|
||||||
m_camera_y = camera_y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::draw_frame() {
|
void Renderer::draw_frame() {
|
||||||
m_swapchain.begin_frame();
|
m_swapchain.begin_frame();
|
||||||
const auto image_index = m_swapchain.current_image_index();
|
const auto image_index = m_swapchain.current_image_index();
|
||||||
auto& image_states = m_image_states[image_index];
|
auto& image_states = m_image_states[image_index];
|
||||||
|
|
||||||
const auto now = Clock::now();
|
m_camera.update_aspect_ratio(Real(m_swapchain.extent().width) / Real(m_swapchain.extent().height));
|
||||||
if(m_last_frame_time.time_since_epoch() != Duration(0)) {
|
const Matrix4 view = m_camera.view_matrix();
|
||||||
m_time += now - m_last_frame_time;
|
const Matrix4 proj = m_camera.projection_matrix();
|
||||||
}
|
|
||||||
m_last_frame_time = now;
|
|
||||||
|
|
||||||
Matrix3 linear_view;
|
|
||||||
linear_view <<
|
|
||||||
m_camera_y.cross(m_camera_z).transpose(),
|
|
||||||
m_camera_y.transpose(),
|
|
||||||
m_camera_z.transpose();
|
|
||||||
Matrix4 view;
|
|
||||||
view << linear_view, linear_view * -m_camera_position,
|
|
||||||
Vector4::UnitW().transpose();
|
|
||||||
|
|
||||||
const float fov = M_PI / 3.0f;
|
|
||||||
const float near = 0.1f;
|
|
||||||
const float far = 10.0f;
|
|
||||||
const float hx = near * std::tan(fov / 2.0f);
|
|
||||||
const float hy = hx * m_swapchain.extent().height / m_swapchain.extent().width;
|
|
||||||
const Eigen::Matrix4f proj = projection_matrix(
|
|
||||||
-hx, hx,
|
|
||||||
-hy, hy,
|
|
||||||
near, far
|
|
||||||
);
|
|
||||||
|
|
||||||
Transform model = Transform::Identity();
|
Transform model = Transform::Identity();
|
||||||
|
|
||||||
@@ -293,12 +269,12 @@ void VulkanTutorial::draw_frame() {
|
|||||||
m_swapchain.swap_buffers(done_semaphores);
|
m_swapchain.swap_buffers(done_semaphores);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanTutorial::invalidate_swapchain() {
|
void Renderer::invalidate_swapchain() {
|
||||||
m_swapchain.invalidate();
|
m_swapchain.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::create_swapchain_objects() {
|
void Renderer::create_swapchain_objects() {
|
||||||
m_image_states.clear();
|
m_image_states.clear();
|
||||||
m_swapchain_states.~SwapchainStates();
|
m_swapchain_states.~SwapchainStates();
|
||||||
|
|
||||||
@@ -311,7 +287,7 @@ void VulkanTutorial::create_swapchain_objects() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::create_command_pool() {
|
void Renderer::create_command_pool() {
|
||||||
m_command_pool = vk::CommandPool(
|
m_command_pool = vk::CommandPool(
|
||||||
m_context,
|
m_context,
|
||||||
m_context.queue_family(GRAPHIC_QUEUE)
|
m_context.queue_family(GRAPHIC_QUEUE)
|
||||||
@@ -319,7 +295,7 @@ void VulkanTutorial::create_command_pool() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::create_descriptor_set_layout() {
|
void Renderer::create_descriptor_set_layout() {
|
||||||
VkDescriptorSetLayoutBinding binding[] {
|
VkDescriptorSetLayoutBinding binding[] {
|
||||||
{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
@@ -331,14 +307,14 @@ void VulkanTutorial::create_descriptor_set_layout() {
|
|||||||
m_descriptor_set_layout = vk::DescriptorSetLayout(m_context, binding);
|
m_descriptor_set_layout = vk::DescriptorSetLayout(m_context, binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanTutorial::create_pipeline_layout() {
|
void Renderer::create_pipeline_layout() {
|
||||||
VkDescriptorSetLayout set_layouts[] {
|
VkDescriptorSetLayout set_layouts[] {
|
||||||
m_descriptor_set_layout,
|
m_descriptor_set_layout,
|
||||||
};
|
};
|
||||||
m_pipeline_layout = vk::PipelineLayout(m_context, set_layouts);
|
m_pipeline_layout = vk::PipelineLayout(m_context, set_layouts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanTutorial::create_render_pass() {
|
void Renderer::create_render_pass() {
|
||||||
VkAttachmentDescription color_attachment {
|
VkAttachmentDescription color_attachment {
|
||||||
.format = m_context.surface_format().format,
|
.format = m_context.surface_format().format,
|
||||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||||
@@ -384,7 +360,7 @@ void VulkanTutorial::create_render_pass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::create_vertex_buffer() {
|
void Renderer::create_vertex_buffer() {
|
||||||
VkDeviceSize size = sizeof(vertices[0]) * vertices.size();
|
VkDeviceSize size = sizeof(vertices[0]) * vertices.size();
|
||||||
m_vertex_buffer = vk::Buffer(
|
m_vertex_buffer = vk::Buffer(
|
||||||
m_context,
|
m_context,
|
||||||
@@ -396,7 +372,7 @@ void VulkanTutorial::create_vertex_buffer() {
|
|||||||
m_vertex_buffer.upload(size, vertices.data(), m_context.queue_family(GRAPHIC_QUEUE));
|
m_vertex_buffer.upload(size, vertices.data(), m_context.queue_family(GRAPHIC_QUEUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanTutorial::create_index_buffer() {
|
void Renderer::create_index_buffer() {
|
||||||
VkDeviceSize size = sizeof(indices[0]) * indices.size();
|
VkDeviceSize size = sizeof(indices[0]) * indices.size();
|
||||||
m_index_buffer = vk::Buffer(
|
m_index_buffer = vk::Buffer(
|
||||||
m_context,
|
m_context,
|
||||||
@@ -409,13 +385,13 @@ void VulkanTutorial::create_index_buffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::initialize_swapchain_states() {
|
void Renderer::initialize_swapchain_states() {
|
||||||
create_descriptor_pool();
|
create_descriptor_pool();
|
||||||
create_graphic_pipeline();
|
create_graphic_pipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::create_descriptor_pool() {
|
void Renderer::create_descriptor_pool() {
|
||||||
VkDescriptorPoolSize pool_sizes[] {
|
VkDescriptorPoolSize pool_sizes[] {
|
||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
@@ -430,7 +406,7 @@ void VulkanTutorial::create_descriptor_pool() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanTutorial::create_graphic_pipeline() {
|
void Renderer::create_graphic_pipeline() {
|
||||||
auto vertex_shader_module = vk::ShaderModule(m_context, "shaders/shader.vert.spv");
|
auto vertex_shader_module = vk::ShaderModule(m_context, "shaders/shader.vert.spv");
|
||||||
auto geometry_shader_module = vk::ShaderModule(m_context, "shaders/shader.geom.spv");
|
auto geometry_shader_module = vk::ShaderModule(m_context, "shaders/shader.geom.spv");
|
||||||
auto fragment_shader_module = vk::ShaderModule(m_context, "shaders/shader.frag.spv");
|
auto fragment_shader_module = vk::ShaderModule(m_context, "shaders/shader.frag.spv");
|
||||||
@@ -569,7 +545,7 @@ void VulkanTutorial::create_graphic_pipeline() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::initialize_image_states(size_t image_index) {
|
void Renderer::initialize_image_states(size_t image_index) {
|
||||||
auto& image_states = m_image_states[image_index];
|
auto& image_states = m_image_states[image_index];
|
||||||
image_states.m_image_index = image_index;
|
image_states.m_image_index = image_index;
|
||||||
|
|
||||||
@@ -586,7 +562,7 @@ void VulkanTutorial::initialize_image_states(size_t image_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::create_framebuffer(ImageStates& image_states) {
|
void Renderer::create_framebuffer(ImageStates& image_states) {
|
||||||
auto view = m_swapchain.image_view(image_states.m_image_index);
|
auto view = m_swapchain.image_view(image_states.m_image_index);
|
||||||
image_states.m_framebuffer = vk::Framebuffer(
|
image_states.m_framebuffer = vk::Framebuffer(
|
||||||
m_context,
|
m_context,
|
||||||
@@ -597,7 +573,7 @@ void VulkanTutorial::create_framebuffer(ImageStates& image_states) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void VulkanTutorial::create_uniform_buffer(ImageStates& image_states) {
|
void Renderer::create_uniform_buffer(ImageStates& image_states) {
|
||||||
const auto image_index = image_states.m_image_index;
|
const auto image_index = image_states.m_image_index;
|
||||||
|
|
||||||
image_states.m_uniform_buffer = vk::Buffer(
|
image_states.m_uniform_buffer = vk::Buffer(
|
||||||
@@ -629,7 +605,7 @@ void VulkanTutorial::create_uniform_buffer(ImageStates& image_states) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanTutorial::create_descriptor_set(ImageStates& image_states) {
|
void Renderer::create_descriptor_set(ImageStates& image_states) {
|
||||||
image_states.m_descriptor_set = vk::DescriptorSet(
|
image_states.m_descriptor_set = vk::DescriptorSet(
|
||||||
m_context,
|
m_context,
|
||||||
m_swapchain_states.m_descriptor_pool,
|
m_swapchain_states.m_descriptor_pool,
|
||||||
@@ -657,7 +633,7 @@ void VulkanTutorial::create_descriptor_set(ImageStates& image_states) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanTutorial::create_draw_buffer(ImageStates& image_states) {
|
void Renderer::create_draw_buffer(ImageStates& image_states) {
|
||||||
image_states.m_draw_buffer = vk::Buffer(
|
image_states.m_draw_buffer = vk::Buffer(
|
||||||
m_context,
|
m_context,
|
||||||
DrawBufferOffset + MaxDrawTileCount * sizeof(VkDrawIndexedIndirectCommand),
|
DrawBufferOffset + MaxDrawTileCount * sizeof(VkDrawIndexedIndirectCommand),
|
||||||
@@ -667,7 +643,7 @@ void VulkanTutorial::create_draw_buffer(ImageStates& image_states) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanTutorial::create_command_buffer(ImageStates& image_states) {
|
void Renderer::create_command_buffer(ImageStates& image_states) {
|
||||||
image_states.m_command_buffer = vk::CommandBuffer(m_context, m_command_pool);
|
image_states.m_command_buffer = vk::CommandBuffer(m_context, m_command_pool);
|
||||||
|
|
||||||
VkCommandBufferBeginInfo begin_info {
|
VkCommandBufferBeginInfo begin_info {
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright 2022 Simon Boyé
|
// Copyright 2022 Simon Boyé
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Camera.h>
|
||||||
|
|
||||||
#include <vk/Swapchain.h>
|
#include <vk/Swapchain.h>
|
||||||
#include <vk/DescriptorSet.h>
|
#include <vk/DescriptorSet.h>
|
||||||
#include <vk/DescriptorPool.h>
|
#include <vk/DescriptorPool.h>
|
||||||
@@ -31,7 +33,7 @@ VkVertexInputBindingDescription vertex_binding_description();
|
|||||||
std::array<VkVertexInputAttributeDescription, 4> vertex_attributes_description();
|
std::array<VkVertexInputAttributeDescription, 4> vertex_attributes_description();
|
||||||
|
|
||||||
|
|
||||||
class VulkanTutorial {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
enum QueueIndex {
|
enum QueueIndex {
|
||||||
GRAPHIC_QUEUE,
|
GRAPHIC_QUEUE,
|
||||||
@@ -43,15 +45,15 @@ public:
|
|||||||
using SecondsD = std::chrono::duration<double>;
|
using SecondsD = std::chrono::duration<double>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VulkanTutorial();
|
Renderer();
|
||||||
VulkanTutorial(const VulkanTutorial&) = delete;
|
Renderer(const Renderer&) = delete;
|
||||||
~VulkanTutorial();
|
~Renderer();
|
||||||
|
|
||||||
VulkanTutorial& operator=(const VulkanTutorial&) = delete;
|
Renderer& operator=(const Renderer&) = delete;
|
||||||
|
|
||||||
void initialize(SDL_Window* window);
|
void initialize(SDL_Window* window);
|
||||||
|
|
||||||
void set_camera(const Vector3& camera_position, const Vector3& camera_z, const Vector3& camera_y);
|
void set_camera(const Camera& camera);
|
||||||
|
|
||||||
void draw_frame();
|
void draw_frame();
|
||||||
void invalidate_swapchain();
|
void invalidate_swapchain();
|
||||||
@@ -130,11 +132,5 @@ private:
|
|||||||
};
|
};
|
||||||
std::vector<ImageStates> m_image_states;
|
std::vector<ImageStates> m_image_states;
|
||||||
|
|
||||||
|
Camera m_camera;
|
||||||
Vector3 m_camera_position = Vector3(0.0f, 0.0f, -3.0f);
|
|
||||||
Vector3 m_camera_z = Vector3(0.0f, 0.0f, 1.0f);
|
|
||||||
Vector3 m_camera_y = Vector3(0.0f, 1.0f, 0.0f);
|
|
||||||
|
|
||||||
TimePoint m_last_frame_time;
|
|
||||||
Duration m_time = Duration(0);
|
|
||||||
};
|
};
|
||||||
@@ -15,6 +15,12 @@ void SdlWindowDeleter::operator()(SDL_Window* window) const {
|
|||||||
|
|
||||||
|
|
||||||
VkExpe::VkExpe(int argc, char** argv) {
|
VkExpe::VkExpe(int argc, char** argv) {
|
||||||
|
m_camera.set_position(Vector3(0.0f, 0.0f, -3.0f));
|
||||||
|
m_camera.set_direction(Vector3::UnitZ());
|
||||||
|
m_camera.set_down(Vector3::UnitY());
|
||||||
|
|
||||||
|
m_camera.set_projection(M_PI / 3.0, 1.0);
|
||||||
|
m_camera.set_clip_distances(0.1, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkExpe::~VkExpe() {
|
VkExpe::~VkExpe() {
|
||||||
@@ -109,7 +115,7 @@ void VkExpe::run() {
|
|||||||
|
|
||||||
update(std::chrono::duration<double>(elapsed).count());
|
update(std::chrono::duration<double>(elapsed).count());
|
||||||
|
|
||||||
m_vulkan.set_camera(m_camera_position, m_camera_z, m_camera_y);
|
m_vulkan.set_camera(m_camera);
|
||||||
m_vulkan.draw_frame();
|
m_vulkan.draw_frame();
|
||||||
|
|
||||||
m_mouse_offset = Vector2::Zero();
|
m_mouse_offset = Vector2::Zero();
|
||||||
@@ -128,14 +134,16 @@ void VkExpe::update(double elapsed) {
|
|||||||
const Real x_sensi = 0.001;
|
const Real x_sensi = 0.001;
|
||||||
const Real y_sensi = -0.001;
|
const Real y_sensi = -0.001;
|
||||||
|
|
||||||
const Vector3 camera_x = m_camera_y.cross(m_camera_z);
|
const Vector3 camera_z = m_camera.direction();
|
||||||
|
const Vector3 camera_y = m_camera.down();
|
||||||
|
const Vector3 camera_x = camera_y.cross(camera_z);
|
||||||
Vector3 axis =
|
Vector3 axis =
|
||||||
x_sensi * m_mouse_offset[0] * m_camera_y +
|
x_sensi * m_mouse_offset[0] * camera_y +
|
||||||
y_sensi * m_mouse_offset[1] * camera_x;
|
y_sensi * m_mouse_offset[1] * camera_x;
|
||||||
Real rot_norm = axis.norm();
|
Real rot_norm = axis.norm();
|
||||||
AngleAxis rot(rot_norm, axis / rot_norm);
|
AngleAxis rot(rot_norm, axis / rot_norm);
|
||||||
m_camera_y = rot * m_camera_y;
|
m_camera.set_down(rot * camera_y);
|
||||||
m_camera_z = rot * m_camera_z;
|
m_camera.set_direction(rot * camera_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 walk_direction = Vector3::Zero();
|
Vector3 walk_direction = Vector3::Zero();
|
||||||
@@ -156,8 +164,9 @@ void VkExpe::update(double elapsed) {
|
|||||||
walk_direction.normalize();
|
walk_direction.normalize();
|
||||||
const Real base_velocity = 1;
|
const Real base_velocity = 1;
|
||||||
|
|
||||||
Matrix3 camera_basis;
|
const Matrix3 basis = m_camera.basis();
|
||||||
camera_basis << m_camera_y.cross(m_camera_z), m_camera_y, m_camera_z;
|
m_camera.set_position(
|
||||||
m_camera_position += elapsed * base_velocity * (camera_basis * walk_direction);
|
m_camera.position() + elapsed * base_velocity * (basis * walk_direction)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// Copyright 2022 Simon Boyé
|
// Copyright 2022 Simon Boyé
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <VulkanTutorial.h>
|
#include <Renderer.h>
|
||||||
|
#include <Camera.h>
|
||||||
|
|
||||||
#include <core/math.h>
|
#include <core/math.h>
|
||||||
|
|
||||||
@@ -32,11 +33,9 @@ public:
|
|||||||
void update(double elapsed);
|
void update(double elapsed);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VulkanTutorial m_vulkan;
|
Renderer m_vulkan;
|
||||||
|
|
||||||
Vector3 m_camera_position = Vector3(0.0f, 0.0f, -3.0f);
|
Camera m_camera;
|
||||||
Vector3 m_camera_z = Vector3(0.0f, 0.0f, 1.0f);
|
|
||||||
Vector3 m_camera_y = Vector3(0.0f, 1.0f, 0.0f);
|
|
||||||
|
|
||||||
WindowUP m_window;
|
WindowUP m_window;
|
||||||
bool m_running = false;
|
bool m_running = false;
|
||||||
|
|||||||
@@ -332,11 +332,7 @@ void Swapchain::destroy() {
|
|||||||
callback();
|
callback();
|
||||||
|
|
||||||
m_frame_resources.clear();
|
m_frame_resources.clear();
|
||||||
|
m_image_resources.clear();
|
||||||
for(auto& image_resources: m_image_resources) {
|
|
||||||
image_resources.render_done.destroy();
|
|
||||||
image_resources.view.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_context->destroy_swapchain(m_swapchain);
|
m_context->destroy_swapchain(m_swapchain);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user