diff --git a/VulkanTest b/VulkanTest index 5fc6210..a0bf688 100755 Binary files a/VulkanTest and b/VulkanTest differ diff --git a/first_app.cpp b/first_app.cpp index b9e4b06..e0a6014 100644 --- a/first_app.cpp +++ b/first_app.cpp @@ -1,6 +1,7 @@ #include "first_app.hpp" #include "simple_render_system.hpp" #include "rainbow_system.hpp" +#include "hk_camera.hpp" // libs #define GLM_FORCE_RADIANS @@ -28,6 +29,8 @@ namespace hk { SimpleRenderSystem simpleRenderSystem{m_device, m_renderer.getSwapChainRenderPass()}; RainbowSystem rainbowSystem(2000.0f); + Camera camera{}; + while (!m_window.shouldClose()) { @@ -36,10 +39,13 @@ namespace hk // update objects color rainbowSystem.update(5.0f, m_gameObjects); + float aspect = m_renderer.getAspectRatio(); + //camera.setOrthographicProjection(-aspect, aspect, -1, 1, -1, 1); + camera.setPerspectiveProjection(glm::radians(50.f), aspect, 0.1f, 10.f); if (auto commandBuffer = m_renderer.beginFrame()) { m_renderer.beginSwapChainRenderPass(commandBuffer); - simpleRenderSystem.renderGameObjects(commandBuffer, m_gameObjects); + simpleRenderSystem.renderGameObjects(commandBuffer, m_gameObjects, camera); m_renderer.endSwapChainRenderPass(commandBuffer); m_renderer.endFrame(); } @@ -114,7 +120,7 @@ namespace hk std::shared_ptr cubeModel = createCubeModel(m_device, {0.f, 0.f, 0.f}); auto cube = GameObject::createGameObject(); cube.m_model = cubeModel; - cube.m_transform.translation = {0.f, 0.f, .5f}; + cube.m_transform.translation = {0.f, 0.f, 2.5f}; cube.m_transform.scale = {.5f, .5f, .5f}; m_gameObjects.push_back(std::move(cube)); } diff --git a/hk_camera.cpp b/hk_camera.cpp new file mode 100644 index 0000000..f6fce96 --- /dev/null +++ b/hk_camera.cpp @@ -0,0 +1,27 @@ +#include "hk_camera.hpp" + +namespace hk +{ + void Camera::setOrthographicProjection(float left, float right, float top, float bottom, float near, float far) + { + m_projectionMatrix = glm::mat4{1.0f}; + m_projectionMatrix[0][0] = 2.f / (right - left); + m_projectionMatrix[1][1] = 2.f / (bottom - top); + m_projectionMatrix[2][2] = 1.f / (far - near); + m_projectionMatrix[3][0] = -(right + left) / (right - left); + m_projectionMatrix[3][1] = -(bottom + top) / (bottom - top); + m_projectionMatrix[3][2] = -near / (far - near); + } + + void Camera::setPerspectiveProjection(float fovY, float aspect, float near, float far) + { + assert(glm::abs(aspect - std::numeric_limits::epsilon()) > 0.0f); + const float tanHalfFovy = tan(fovY / 2.f); + m_projectionMatrix = glm::mat4{0.0f}; + m_projectionMatrix[0][0] = 1.f / (aspect * tanHalfFovy); + m_projectionMatrix[1][1] = 1.f / (tanHalfFovy); + m_projectionMatrix[2][2] = far / (far - near); + m_projectionMatrix[2][3] = 1.f; + m_projectionMatrix[3][2] = -(far * near) / (far - near); + } +} // namespace hk \ No newline at end of file diff --git a/hk_camera.hpp b/hk_camera.hpp new file mode 100644 index 0000000..6750192 --- /dev/null +++ b/hk_camera.hpp @@ -0,0 +1,24 @@ +#pragma once + +// libs +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#include + +namespace hk +{ + class Camera + { + public: + Camera() = default; + ~Camera() = default; + + void setOrthographicProjection(float left, float right, float top, float bottom, float near, float far); + + void setPerspectiveProjection(float fovY, float aspect, float near, float far); + + const glm::mat4& getProjection() const { return m_projectionMatrix; } + private: + glm::mat4 m_projectionMatrix{1.0f}; + }; +} // namespace hk \ No newline at end of file diff --git a/hk_renderer.hpp b/hk_renderer.hpp index a1ecfcc..b93efb2 100644 --- a/hk_renderer.hpp +++ b/hk_renderer.hpp @@ -22,6 +22,7 @@ namespace hk Renderer &operator=(const Renderer &) = delete; VkRenderPass getSwapChainRenderPass() const { return m_swapChain->getRenderPass(); } + float getAspectRatio() const { return m_swapChain->extentAspectRatio(); } bool isFrameInProgress() const {return m_isFrameStarted;} VkCommandBuffer getCurrentCommandBuffer() const { assert(m_isFrameStarted && "Cannot get command buffer when frame not in progress"); diff --git a/simple_render_system.cpp b/simple_render_system.cpp index 1e127b9..46a153c 100644 --- a/simple_render_system.cpp +++ b/simple_render_system.cpp @@ -66,7 +66,7 @@ namespace hk pipelineConfig); } - void SimpleRenderSystem::renderGameObjects(VkCommandBuffer commandBuffer, std::vector &gameObjects) + void SimpleRenderSystem::renderGameObjects(VkCommandBuffer commandBuffer, std::vector &gameObjects, const Camera &camera) { m_pipeline->bind(commandBuffer); for (auto &obj : gameObjects) @@ -76,7 +76,7 @@ namespace hk SimplePushConstantData push{}; push.color = obj.m_color; - push.transform = obj.m_transform.mat4(); + push.transform = camera.getProjection() * obj.m_transform.mat4(); vkCmdPushConstants( commandBuffer, diff --git a/simple_render_system.hpp b/simple_render_system.hpp index 2f09343..eed5d97 100644 --- a/simple_render_system.hpp +++ b/simple_render_system.hpp @@ -1,5 +1,6 @@ #pragma once +#include "hk_camera.hpp" #include "hk_device.hpp" #include "hk_game_object.hpp" #include "hk_pipeline.hpp" @@ -20,7 +21,7 @@ namespace hk SimpleRenderSystem(const SimpleRenderSystem &) = delete; SimpleRenderSystem &operator=(const SimpleRenderSystem &) = delete; - void renderGameObjects(VkCommandBuffer commandBuffer, std::vector &gameObjects); + void renderGameObjects(VkCommandBuffer commandBuffer, std::vector &gameObjects, const Camera &camera); private: void createPipelineLayout();