diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 522371a..7ee62a1 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -9,13 +9,6 @@ if (MSVC) # link_libraries(legacy_stdio_definitions) endif () -# TODO: proper std::execution availability check -if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - add_compile_definitions(${PROJECT_PREFIX}_HAS_EXEC_POLICIES=0) -else () - add_compile_definitions(${PROJECT_PREFIX}_HAS_EXEC_POLICIES=1) -endif () - if (${CMAKE_BUILD_TYPE} MATCHES "Debug") add_compile_definitions(${PROJECT_PREFIX}_DEBUG=1) add_compile_definitions(${PROJECT_PREFIX}_RELEASE=0) diff --git a/example-app/src/Main.cpp b/example-app/src/Main.cpp index 3ffa7a2..ff276a2 100644 --- a/example-app/src/Main.cpp +++ b/example-app/src/Main.cpp @@ -17,7 +17,8 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include +#include +#include #include #include @@ -37,10 +38,15 @@ int main() win.setTitle(buffer); }); + vulk::Rectangle obj{}; + + obj.setColor(vulk::Color::White); + while (win.isOpen()) { win.pollEvents(); + obj.draw(); win.display(); } diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 68294b6..58b1177 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -5,6 +5,7 @@ add_library( include/Vulk/Vec3.hpp include/Vulk/Rect.hpp include/Vulk/Mat3.hpp + include/Vulk/Macros.hpp include/Vulk/ClassUtils.hpp src/Window.cpp include/Vulk/Window.hpp src/Exceptions.cpp include/Vulk/Exceptions.hpp @@ -17,6 +18,11 @@ add_library( src/Keyboard.cpp include/Vulk/Keyboard.hpp src/Mouse.cpp include/Vulk/Mouse.hpp src/Objects.cpp include/Vulk/Objects.hpp + src/Graphics/ADrawable.cpp include/Vulk/Graphics/ADrawable.hpp + src/Graphics/AShape.cpp include/Vulk/Graphics/AShape.hpp + src/Graphics/Triangle.cpp include/Vulk/Graphics/Triangle.hpp + src/Graphics/Rectangle.cpp include/Vulk/Graphics/Rectangle.hpp + src/Graphics/Circle.cpp include/Vulk/Graphics/Circle.hpp src/Color.cpp include/Vulk/Color.hpp ) diff --git a/lib/include/Vulk/ClassUtils.hpp b/lib/include/Vulk/ClassUtils.hpp index 8cf681c..a64eddd 100644 --- a/lib/include/Vulk/ClassUtils.hpp +++ b/lib/include/Vulk/ClassUtils.hpp @@ -19,30 +19,6 @@ #pragma once -#define VULK_NO_COPY(ClassName) \ - ClassName(const ClassName&) = delete; \ - ClassName& operator=(const ClassName&) = delete; - -#define VULK_NO_MOVE(ClassName) \ - ClassName(ClassName&&) = delete; \ - ClassName& operator=(ClassName&&) = delete; - -#define VULK_NO_MOVE_OR_COPY(ClassName) \ - VULK_NO_COPY(ClassName) \ - VULK_NO_MOVE(ClassName) - -#define VULK_DEFAULT_COPY(ClassName) \ - ClassName(const ClassName&) = default; \ - ClassName& operator=(const ClassName&) = default; - -#define VULK_DEFAULT_MOVE(ClassName) \ - ClassName(ClassName&&) = default; \ - ClassName& operator=(ClassName&&) = default; - -#define VULK_DEFAULT_MOVE_AND_COPY(ClassName) \ - VULK_DEFAULT_COPY(ClassName) \ - VULK_DEFAULT_MOVE(ClassName) - /** * Forces a compile error and shows the type of a variable. * Useful tool when searching for an auto type or deep library calls. diff --git a/lib/include/Vulk/Color.hpp b/lib/include/Vulk/Color.hpp index 4b7af27..4f63265 100644 --- a/lib/include/Vulk/Color.hpp +++ b/lib/include/Vulk/Color.hpp @@ -19,6 +19,8 @@ #pragma once +#include + #include #include @@ -66,6 +68,11 @@ struct Color return value; } + [[nodiscard]] constexpr glm::vec3 to_glm_color() const noexcept + { + return glm::vec3{static_cast(r) / 255.f, static_cast(g) / 255.f, static_cast(b) / 255.f}; + } + static Color Red; static Color Green; static Color Blue; diff --git a/lib/include/Vulk/Contexts/ContextGLFW.hpp b/lib/include/Vulk/Contexts/ContextGLFW.hpp index 88e217e..9932774 100644 --- a/lib/include/Vulk/Contexts/ContextGLFW.hpp +++ b/lib/include/Vulk/Contexts/ContextGLFW.hpp @@ -21,9 +21,9 @@ #include -#include "Vulk/ClassUtils.hpp" +#include "Vulk/Macros.hpp" -namespace vulk { +namespace vulk::detail { class ContextGLFW { public: @@ -43,4 +43,4 @@ class ContextGLFW static std::unique_ptr s_instance; }; -} // namespace vulk +} // namespace vulk::detail diff --git a/lib/include/Vulk/Contexts/ContextVulkan.hpp b/lib/include/Vulk/Contexts/ContextVulkan.hpp index 522a8c8..b6ead83 100644 --- a/lib/include/Vulk/Contexts/ContextVulkan.hpp +++ b/lib/include/Vulk/Contexts/ContextVulkan.hpp @@ -25,22 +25,56 @@ #include #include -#include "Vulk/ClassUtils.hpp" +#include "Vulk/Exceptions.hpp" +#include "Vulk/Graphics/ADrawable.hpp" +#include "Vulk/Graphics/AShape.hpp" +#include "Vulk/Macros.hpp" #include "Vulk/Objects.hpp" #include "Vulk/Window.hpp" -namespace vulk { +namespace vulk::detail { class ContextVulkan { public: ~ContextVulkan(); - /** - * TODO: This should not be public. The Vulkan context should only be exposed to the window. - * Calling this function from the static `getInstance().draw()` can break stuff. - */ void draw(); + template + void createBuffers(const std::vector& vertices, vk::Buffer& outBuffer, vk::DeviceMemory& outDeviceMemory, + vk::BufferUsageFlagBits flags) + { + const size_t bufferSize = sizeof(std::remove_cvref_t::value_type) * vertices.size(); + + vk::Buffer stagingBuffer; + vk::DeviceMemory stagingBufferMemory; + + createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, + stagingBuffer, stagingBufferMemory); + + void* data; + handleVulkanError(m_device.mapMemory(stagingBufferMemory, 0, bufferSize, {}, &data)); + std::memcpy(data, vertices.data(), bufferSize); + m_device.unmapMemory(stagingBufferMemory); + + createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferDst | flags, + vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, outBuffer, + outDeviceMemory); + + copyBuffer(stagingBuffer, outBuffer, bufferSize); + + // TODO: vk::raii + m_device.destroy(stagingBuffer); + m_device.freeMemory(stagingBufferMemory); + } + + void destroyBuffer(vk::Buffer buffer); + void freeBufferMem(vk::DeviceMemory deviceMemory); + + void registerDrawable(AShape& drawable); + void unregisterDrawable(AShape& drawable); + // TODO: should not be public, remove once events are implemented void setFrameBufferResized(bool value) noexcept { m_frameBufferResized = value; } @@ -130,8 +164,6 @@ class ContextVulkan void createGraphicsPipeline(); void createFrameBuffers(); void createCommandPool(); - void createVertexBuffer(); - void createIndexBuffer(); void createUniformBuffers(); void createDescriptorPool(); void createDescriptorSets(); @@ -141,9 +173,10 @@ class ContextVulkan void recordCommandBuffer(vk::CommandBuffer& commandBuffer, uint32_t imageIndex); void recreateSwapChain(); + void copyBuffer(const vk::Buffer& sourceBuffer, vk::Buffer& destinationBuffer, vk::DeviceSize size); + void createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties, vk::Buffer& outBuffer, vk::DeviceMemory& outDeviceMemory); - void copyBuffer(const vk::Buffer& sourceBuffer, vk::Buffer& destinationBuffer, vk::DeviceSize size); void cleanupSwapchain(vk::SwapchainKHR& swapchain); void cleanupSwapchainSubObjects(); @@ -202,17 +235,14 @@ class ContextVulkan std::vector m_frameSyncObjects{}; std::vector m_imagesInFlight{}; - vk::Buffer m_vertexBuffer{}; - vk::DeviceMemory m_vertexBufferMemory{}; - vk::Buffer m_indexBuffer{}; - vk::DeviceMemory m_indexBufferMemory{}; - std::vector m_uniformBuffers{}; std::vector m_uniformBuffersMemory{}; vk::DescriptorPool m_descriptorPool{}; std::vector m_descriptorSets{}; + std::vector m_shapes{}; + // TODO: May be better to store in the FrameManager size_t m_currentFrame{}; static const size_t s_maxFramesInFlight; @@ -220,28 +250,8 @@ class ContextVulkan bool m_frameBufferResized{false}; - template - static constexpr vk::IndexType getIndexType() - { - // could be a concept with C++20 - static_assert(std::is_same_v || std::is_same_v); - - if (std::is_same_v) - return vk::IndexType::eUint16; - if (std::is_same_v) - return vk::IndexType::eUint32; - - assert(0); - return vk::IndexType::eNoneKHR; - } - - static constexpr auto s_noTimeout = std::numeric_limits::max(); - static constexpr std::array s_vertices{Vertex{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, // - Vertex{{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}}, // - Vertex{{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}, // - Vertex{{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}}}; - static constexpr std::array s_indices{0, 1, 2, 2, 3, 0}; + static constexpr auto NO_TIMEOUT = std::numeric_limits::max(); static std::unique_ptr s_instance; }; -} // namespace vulk +} // namespace vulk::detail diff --git a/lib/include/Vulk/Exceptions.hpp b/lib/include/Vulk/Exceptions.hpp index 3619682..67bba42 100644 --- a/lib/include/Vulk/Exceptions.hpp +++ b/lib/include/Vulk/Exceptions.hpp @@ -23,7 +23,7 @@ #include -#include "Vulk/ClassUtils.hpp" +#include "Vulk/Macros.hpp" namespace vulk { class Exception : public std::exception diff --git a/lib/include/Vulk/Graphics/ADrawable.hpp b/lib/include/Vulk/Graphics/ADrawable.hpp new file mode 100644 index 0000000..2aac296 --- /dev/null +++ b/lib/include/Vulk/Graphics/ADrawable.hpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#pragma once + +#include + +namespace vulk { +class ADrawable +{ +public: + ADrawable(); + explicit ADrawable(const glm::vec2& position) : m_position{position} {} + + virtual ~ADrawable(); + + virtual void draw() const = 0; + + virtual void setOrigin(const glm::vec2& origin); + virtual void setPosition(const glm::vec2& position); + virtual void setScale(const glm::vec2& scale); + + [[nodiscard]] const auto& getOrigin() const noexcept { return m_origin; } + [[nodiscard]] const auto& getPosition() const noexcept { return m_position; } + [[nodiscard]] const auto& getScale() const noexcept { return m_scale; } + +protected: + glm::vec2 m_origin{}; + glm::vec2 m_position{}; + glm::vec2 m_scale{}; +}; +} // namespace vulk diff --git a/lib/include/Vulk/Graphics/AShape.hpp b/lib/include/Vulk/Graphics/AShape.hpp new file mode 100644 index 0000000..22e59e1 --- /dev/null +++ b/lib/include/Vulk/Graphics/AShape.hpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#pragma once + +#include + +#include "Vulk/Color.hpp" +#include "Vulk/Graphics/ADrawable.hpp" +#include "Vulk/Objects.hpp" + +namespace vulk { +class AShape : public ADrawable +{ +public: + AShape(); + ~AShape() override; + explicit AShape(const glm::vec2& position) : ADrawable{position} {} + + void setColor(Color color); + + [[nodiscard]] size_t getVertexCount() const noexcept { return m_vertices.size(); } + [[nodiscard]] size_t getIndexCount() const noexcept { return m_indices.size(); } + + // TODO: these two should NOT be public, dirty workaround until a proper renderer is made + [[nodiscard]] const auto& getVertexBuffer() const noexcept { return m_vertexBuffer; } + [[nodiscard]] const auto& getIndexBuffer() const noexcept { return m_indexBuffer; } + +protected: + static constexpr vk::IndexType INDEX_TYPE = vk::IndexType::eUint32; + + template + void setVertices(const std::array& vertices) + { + m_vertices.reserve(Count); + m_vertices.insert(m_vertices.end(), vertices.cbegin(), vertices.cend()); + } + + template + void setIndices(const std::array& indices) + { + m_indices.reserve(Count); + m_indices.insert(m_indices.end(), indices.cbegin(), indices.cend()); + } + + void makeBuffers(); + +private: + void resetBuffers(); + + vk::Buffer m_vertexBuffer{}; + vk::DeviceMemory m_vertexMemory{}; + vk::Buffer m_indexBuffer{}; + vk::DeviceMemory m_indexMemory{}; + + std::vector m_vertices{}; + std::vector m_indices{}; +}; +} // namespace vulk diff --git a/lib/include/Vulk/Graphics/Circle.hpp b/lib/include/Vulk/Graphics/Circle.hpp new file mode 100644 index 0000000..6d03d61 --- /dev/null +++ b/lib/include/Vulk/Graphics/Circle.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#pragma once + +#include "Vulk/Graphics/AShape.hpp" + +namespace vulk { +class Circle : public AShape +{ +public: + void draw() const override {} +}; +} // namespace vulk diff --git a/lib/include/Vulk/Graphics/Rectangle.hpp b/lib/include/Vulk/Graphics/Rectangle.hpp new file mode 100644 index 0000000..f1e9e16 --- /dev/null +++ b/lib/include/Vulk/Graphics/Rectangle.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#pragma once + +#include "Vulk/Graphics/AShape.hpp" + +namespace vulk { +class Rectangle : public AShape +{ +public: + Rectangle(); + + void draw() const override {} +}; +} // namespace vulk diff --git a/lib/include/Vulk/Graphics/Triangle.hpp b/lib/include/Vulk/Graphics/Triangle.hpp new file mode 100644 index 0000000..ccd84a5 --- /dev/null +++ b/lib/include/Vulk/Graphics/Triangle.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#pragma once + +#include "Vulk/Graphics/AShape.hpp" + +namespace vulk { +class Triangle : public AShape +{ +public: + Triangle(); + + void draw() const override {} +}; +} // namespace vulk diff --git a/lib/include/Vulk/Macros.hpp b/lib/include/Vulk/Macros.hpp new file mode 100644 index 0000000..a9e2434 --- /dev/null +++ b/lib/include/Vulk/Macros.hpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#pragma once + +#include + +/** + * Ensure 2 levels of macro expansion to stringify preprocessor macros + */ +#define _VULK_STR2(x) #x +#define _VULK_STR1(x) _VULK_STR2(x) +#define _VULK_STRCAT2(x, y) x##y +#define _VULK_STRCAT1(x, y) _VULK_STRCAT2(x, y) + +/** + * Stringify preprocessor + */ +#define VULK_STR(x) _VULK_STR1(x) + +/** + * Concatenates x and y + */ +#define VULK_STRCAT(x, y) _VULK_STRCAT1(x, y) + +#define VULK_NO_COPY(ClassName) \ + ClassName(const ClassName&) = delete; \ + ClassName& operator=(const ClassName&) = delete; + +#define VULK_NO_MOVE(ClassName) \ + ClassName(ClassName&&) = delete; \ + ClassName& operator=(ClassName&&) = delete; + +#define VULK_NO_MOVE_OR_COPY(ClassName) \ + VULK_NO_COPY(ClassName) \ + VULK_NO_MOVE(ClassName) + +#define VULK_DEFAULT_COPY(ClassName) \ + ClassName(const ClassName&) = default; \ + ClassName& operator=(const ClassName&) = default; + +#define VULK_DEFAULT_MOVE(ClassName) \ + ClassName(ClassName&&) = default; \ + ClassName& operator=(ClassName&&) = default; + +#define VULK_DEFAULT_MOVE_AND_COPY(ClassName) \ + VULK_DEFAULT_COPY(ClassName) \ + VULK_DEFAULT_MOVE(ClassName) + +// Check if std::execution is supported, still need to include in files using the feature. +// Added a comma at the end so that we can use `std::for_each(VULK_EXEC_PAR_UNSEQ vec.begin(), ...)` +// regardless std::execution is supported or not. +#if defined(__cpp_lib_execution) && defined(__cpp_lib_parallel_algorithm) + #define VULK_HAS_EXECUTION_POLICIES 1 + #define VULK_EXEC_SEQ std::execution::seq, // C++17 + #define VULK_EXEC_PAR std::execution::par, // C++17 + #define VULK_EXEC_PAR_UNSEQ std::execution::par_unseq, // C++17 + #define VULK_EXEC_UNSEQ std::execution::unseq, // C++20 +#else + #define VULK_HAS_EXECUTION_POLICIES 0 + #define VULK_EXEC_SEQ + #define VULK_EXEC_PAR + #define VULK_EXEC_PAR_UNSEQ + #define VULK_EXEC_UNSEQ +#endif + +namespace vulk::features { +static constexpr bool execution_policies = VULK_HAS_EXECUTION_POLICIES; +} diff --git a/lib/include/Vulk/Objects.hpp b/lib/include/Vulk/Objects.hpp index 7c2be9d..a74672f 100644 --- a/lib/include/Vulk/Objects.hpp +++ b/lib/include/Vulk/Objects.hpp @@ -22,6 +22,7 @@ #include #include +namespace vulk { struct Vertex { glm::vec2 position{}; @@ -39,3 +40,4 @@ struct alignas(16) UniformBufferObject glm::mat4 view{}; glm::mat4 projection{}; }; +} // namespace vulk diff --git a/lib/include/Vulk/ScopedProfiler.hpp b/lib/include/Vulk/ScopedProfiler.hpp index f982096..e0cce58 100644 --- a/lib/include/Vulk/ScopedProfiler.hpp +++ b/lib/include/Vulk/ScopedProfiler.hpp @@ -22,6 +22,8 @@ #include #include +#include "Vulk/Macros.hpp" + namespace vulk::utils { class ScopedProfiler final { @@ -45,11 +47,8 @@ class ScopedProfiler final }; } // namespace vulk::utils -#define VULK_STR_IMPL(x, y) x##y -#define VULK_STR(x, y) VULK_STR_IMPL(x, y) - #if VULK_WITH_SCOPED_PROFILER - #define VULK_SCOPED_PROFILER(x) const vulk::utils::ScopedProfiler VULK_STR(_SCOPED_PROFILER_, __LINE__)(x) + #define VULK_SCOPED_PROFILER(x) const vulk::utils::ScopedProfiler VULK_STRCAT(_SCOPED_PROFILER_, __LINE__)(x) #else #define VULK_SCOPED_PROFILER(x) (void) 0 #endif diff --git a/lib/shaders/shader.vert b/lib/shaders/shader.vert index e56d3aa..dfb0807 100644 --- a/lib/shaders/shader.vert +++ b/lib/shaders/shader.vert @@ -13,6 +13,6 @@ layout(location = 0) out vec3 fragColor; void main() { - gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); + gl_Position = vec4(inPosition, 0.0, 1.0); fragColor = inColor; } diff --git a/lib/src/Contexts/ContextGLFW.cpp b/lib/src/Contexts/ContextGLFW.cpp index 5117b35..c7fa797 100644 --- a/lib/src/Contexts/ContextGLFW.cpp +++ b/lib/src/Contexts/ContextGLFW.cpp @@ -26,20 +26,20 @@ #include "Vulk/Exceptions.hpp" -std::unique_ptr vulk::ContextGLFW::s_instance{nullptr}; +std::unique_ptr vulk::detail::ContextGLFW::s_instance{nullptr}; -vulk::ContextGLFW::ContextGLFW() +vulk::detail::ContextGLFW::ContextGLFW() { if (glfwInit() != GLFW_TRUE) throw GLFWException(); } -vulk::ContextGLFW::~ContextGLFW() +vulk::detail::ContextGLFW::~ContextGLFW() { glfwTerminate(); } -vulk::ContextGLFW& vulk::ContextGLFW::getInstance() +vulk::detail::ContextGLFW& vulk::detail::ContextGLFW::getInstance() { if (!s_instance) s_instance = std::unique_ptr{new ContextGLFW}; diff --git a/lib/src/Contexts/ContextVulkan.cpp b/lib/src/Contexts/ContextVulkan.cpp index 08d8bb8..c3965f6 100644 --- a/lib/src/Contexts/ContextVulkan.cpp +++ b/lib/src/Contexts/ContextVulkan.cpp @@ -29,23 +29,24 @@ #include #include "Vulk/Exceptions.hpp" +#include "Vulk/Graphics/AShape.hpp" #include "Vulk/ScopedProfiler.hpp" #include "Vulk/Shader.hpp" #include "Vulk/Utils.hpp" -const size_t vulk::ContextVulkan::s_maxFramesInFlight{2}; -std::unique_ptr vulk::ContextVulkan::s_instance{nullptr}; +const size_t vulk::detail::ContextVulkan::s_maxFramesInFlight{2}; +std::unique_ptr vulk::detail::ContextVulkan::s_instance{nullptr}; // TODO: This should be in the Window class and then fire an event, once those are implemented. static void framebufferResizeCallback(GLFWwindow* windowHandle, int, int) { - auto* context = reinterpret_cast(glfwGetWindowUserPointer(windowHandle)); + auto* context = reinterpret_cast(glfwGetWindowUserPointer(windowHandle)); assert(context); context->setFrameBufferResized(true); } -vulk::ContextVulkan::ContextVulkan(GLFWwindow* windowHandle) : m_windowHandle{windowHandle} +vulk::detail::ContextVulkan::ContextVulkan(GLFWwindow* windowHandle) : m_windowHandle{windowHandle} { VULK_SCOPED_PROFILER("ContextVulkan::ContextVulkan()"); @@ -55,7 +56,7 @@ vulk::ContextVulkan::ContextVulkan(GLFWwindow* windowHandle) : m_windowHandle{wi glfwSetFramebufferSizeCallback(m_windowHandle, &framebufferResizeCallback); #if VULK_DEBUG - printAvailableValidationLayers(); + // printAvailableValidationLayers(); #endif createInstance(); @@ -69,8 +70,6 @@ vulk::ContextVulkan::ContextVulkan(GLFWwindow* windowHandle) : m_windowHandle{wi createGraphicsPipeline(); createFrameBuffers(); createCommandPool(); - createVertexBuffer(); - createIndexBuffer(); createUniformBuffers(); createDescriptorPool(); createDescriptorSets(); @@ -82,7 +81,7 @@ vulk::ContextVulkan::ContextVulkan(GLFWwindow* windowHandle) : m_windowHandle{wi #endif } -vulk::ContextVulkan::~ContextVulkan() +vulk::detail::ContextVulkan::~ContextVulkan() { VULK_SCOPED_PROFILER("ContextVulkan::~ContextVulkan()"); @@ -107,12 +106,6 @@ vulk::ContextVulkan::~ContextVulkan() frameSemaphore.destroy(m_device); m_device.destroy(m_commandPool); - - m_device.destroy(m_indexBuffer); - m_device.freeMemory(m_indexBufferMemory); - - m_device.destroy(m_vertexBuffer); - m_device.freeMemory(m_vertexBufferMemory); } m_instance.destroy(m_surface); @@ -120,7 +113,7 @@ vulk::ContextVulkan::~ContextVulkan() m_instance.destroy(); } -void vulk::ContextVulkan::cleanupSwapchain(vk::SwapchainKHR& swapchain) +void vulk::detail::ContextVulkan::cleanupSwapchain(vk::SwapchainKHR& swapchain) { if (!m_device) return; @@ -142,7 +135,7 @@ void vulk::ContextVulkan::cleanupSwapchain(vk::SwapchainKHR& swapchain) swapchain = nullptr; } -void vulk::ContextVulkan::cleanupSwapchainSubObjects() +void vulk::detail::ContextVulkan::cleanupSwapchainSubObjects() { if (!m_device) return; @@ -156,7 +149,7 @@ void vulk::ContextVulkan::cleanupSwapchainSubObjects() m_swapchainImageViews.clear(); } -void vulk::ContextVulkan::createInstance(GLFWwindow* windowHandle) +void vulk::detail::ContextVulkan::createInstance(GLFWwindow* windowHandle) { assert(windowHandle); @@ -167,12 +160,12 @@ void vulk::ContextVulkan::createInstance(GLFWwindow* windowHandle) assert(s_instance); } -void vulk::ContextVulkan::draw() +void vulk::detail::ContextVulkan::draw() { - handleVulkanError(m_device.waitForFences(1, &m_frameSyncObjects[m_currentFrame].fence, true, s_noTimeout)); + handleVulkanError(m_device.waitForFences(1, &m_frameSyncObjects[m_currentFrame].fence, true, NO_TIMEOUT)); const auto& [result, imageIndex] = - m_device.acquireNextImageKHR(m_swapchain, s_noTimeout, m_frameSyncObjects[m_currentFrame].imageAvailable); + m_device.acquireNextImageKHR(m_swapchain, NO_TIMEOUT, m_frameSyncObjects[m_currentFrame].imageAvailable); if (result == vk::Result::eErrorOutOfDateKHR) { @@ -226,7 +219,35 @@ void vulk::ContextVulkan::draw() m_currentFrame = (m_currentFrame + 1) % s_maxFramesInFlight; } -[[maybe_unused]] void vulk::ContextVulkan::printAvailableValidationLayers() +void vulk::detail::ContextVulkan::destroyBuffer(vk::Buffer buffer) +{ + if (m_device) + { + m_device.waitIdle(); + m_device.destroy(buffer); + } +} + +void vulk::detail::ContextVulkan::freeBufferMem(vk::DeviceMemory deviceMemory) +{ + if (m_device) + { + m_device.waitIdle(); + m_device.freeMemory(deviceMemory); + } +} + +void vulk::detail::ContextVulkan::registerDrawable(AShape& drawable) +{ + m_shapes.push_back(&drawable); +} + +void vulk::detail::ContextVulkan::unregisterDrawable(AShape& drawable) +{ + m_shapes.erase(std::remove(m_shapes.begin(), m_shapes.end(), &drawable), m_shapes.end()); +} + +[[maybe_unused]] void vulk::detail::ContextVulkan::printAvailableValidationLayers() { std::cout << "Available Layers:\n"; @@ -237,7 +258,7 @@ void vulk::ContextVulkan::draw() std::cout.flush(); } -std::vector vulk::ContextVulkan::getSupportedValidationLayers() +std::vector vulk::detail::ContextVulkan::getSupportedValidationLayers() { const auto& availableLayers = vk::enumerateInstanceLayerProperties(); std::vector supported{}; @@ -266,7 +287,7 @@ std::vector vulk::ContextVulkan::getSupportedValidationLayers() return supported; } -void vulk::ContextVulkan::createInstance() +void vulk::detail::ContextVulkan::createInstance() { VULK_SCOPED_PROFILER("ContextVulkan::createInstance()"); @@ -298,7 +319,7 @@ void vulk::ContextVulkan::createInstance() handleVulkanError(vk::createInstance(&createInfo, nullptr, &m_instance)); } -void vulk::ContextVulkan::createSurface() +void vulk::detail::ContextVulkan::createSurface() { VULK_SCOPED_PROFILER("ContextVulkan::createSurface()"); @@ -309,7 +330,7 @@ void vulk::ContextVulkan::createSurface() m_surface = surface; } -void vulk::ContextVulkan::pickPhysicalDevice() +void vulk::detail::ContextVulkan::pickPhysicalDevice() { VULK_SCOPED_PROFILER("ContextVulkan::pickPhysicalDevice()"); @@ -339,7 +360,7 @@ void vulk::ContextVulkan::pickPhysicalDevice() throw VulkanException("Failed to find an appropriate GPU"); } -void vulk::ContextVulkan::createLogicalDevice() +void vulk::detail::ContextVulkan::createLogicalDevice() { VULK_SCOPED_PROFILER("ContextVulkan::createLogicalDevice()"); @@ -384,7 +405,7 @@ void vulk::ContextVulkan::createLogicalDevice() throw VulkanException("Failed to retrieve present queue"); } -void vulk::ContextVulkan::recreateSwapChain() +void vulk::detail::ContextVulkan::recreateSwapChain() { { int width, height; @@ -415,7 +436,7 @@ void vulk::ContextVulkan::recreateSwapChain() createCommandBuffers(); } -void vulk::ContextVulkan::createSwapChain() +void vulk::detail::ContextVulkan::createSwapChain() { VULK_SCOPED_PROFILER("ContextVulkan::createSwapChain()"); @@ -471,7 +492,7 @@ void vulk::ContextVulkan::createSwapChain() m_swapchainFormat = m_surfaceFormat.format; } -void vulk::ContextVulkan::createImageViews() +void vulk::detail::ContextVulkan::createImageViews() { VULK_SCOPED_PROFILER("ContextVulkan::createImageViews()"); @@ -499,7 +520,7 @@ void vulk::ContextVulkan::createImageViews() } } -void vulk::ContextVulkan::createRenderPass() +void vulk::detail::ContextVulkan::createRenderPass() { VULK_SCOPED_PROFILER("ContextVulkan::createRenderPass()"); @@ -542,7 +563,7 @@ void vulk::ContextVulkan::createRenderPass() assert(m_renderPass); } -void vulk::ContextVulkan::createDescriptorSetLayout() +void vulk::detail::ContextVulkan::createDescriptorSetLayout() { VULK_SCOPED_PROFILER("ContextVulkan::createDescriptorSetLayout()"); @@ -559,7 +580,7 @@ void vulk::ContextVulkan::createDescriptorSetLayout() handleVulkanError(m_device.createDescriptorSetLayout(&createInfo, nullptr, &m_descriptorSetLayout)); } -void vulk::ContextVulkan::createGraphicsPipeline() +void vulk::detail::ContextVulkan::createGraphicsPipeline() { VULK_SCOPED_PROFILER("ContextVulkan::createGraphicsPipeline()"); @@ -605,7 +626,7 @@ void vulk::ContextVulkan::createGraphicsPipeline() rasterizer.polygonMode = vk::PolygonMode::eFill; rasterizer.lineWidth = 1; rasterizer.cullMode = vk::CullModeFlagBits::eBack; - rasterizer.frontFace = vk::FrontFace::eCounterClockwise; + rasterizer.frontFace = vk::FrontFace::eClockwise; rasterizer.depthBiasEnable = false; vk::PipelineMultisampleStateCreateInfo multisampling{}; @@ -655,7 +676,7 @@ void vulk::ContextVulkan::createGraphicsPipeline() handleVulkanError(m_device.createGraphicsPipelines(nullptr, 1, &pipelineInfo, nullptr, &m_pipeline)); } -void vulk::ContextVulkan::createFrameBuffers() +void vulk::detail::ContextVulkan::createFrameBuffers() { VULK_SCOPED_PROFILER("ContextVulkan::createFrameBuffers()"); @@ -681,7 +702,7 @@ void vulk::ContextVulkan::createFrameBuffers() } } -void vulk::ContextVulkan::createCommandPool() +void vulk::detail::ContextVulkan::createCommandPool() { VULK_SCOPED_PROFILER("ContextVulkan::createCommandPool()"); @@ -692,61 +713,7 @@ void vulk::ContextVulkan::createCommandPool() handleVulkanError(m_device.createCommandPool(&commandPoolCreateInfo, nullptr, &m_commandPool)); } -void vulk::ContextVulkan::createVertexBuffer() -{ - static constexpr vk::DeviceSize BufferSize = sizeof(decltype(s_vertices)::value_type) * s_vertices.size(); - - vk::Buffer stagingBuffer; - vk::DeviceMemory stagingBufferMemory; - - createBuffer(BufferSize, vk::BufferUsageFlagBits::eTransferSrc, - vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, stagingBuffer, - stagingBufferMemory); - - void* data; - handleVulkanError(m_device.mapMemory(stagingBufferMemory, 0, BufferSize, {}, &data)); - std::memcpy(data, s_vertices.data(), BufferSize); - m_device.unmapMemory(stagingBufferMemory); - - createBuffer(BufferSize, vk::BufferUsageFlagBits::eTransferDst | vk::BufferUsageFlagBits::eVertexBuffer, - vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, m_vertexBuffer, - m_vertexBufferMemory); - - copyBuffer(stagingBuffer, m_vertexBuffer, BufferSize); - - // TODO: vk::raii - m_device.destroy(stagingBuffer); - m_device.freeMemory(stagingBufferMemory); -} - -void vulk::ContextVulkan::createIndexBuffer() -{ - static constexpr vk::DeviceSize BufferSize = sizeof(decltype(s_indices)::value_type) * s_indices.size(); - - vk::Buffer stagingBuffer; - vk::DeviceMemory stagingBufferMemory; - - createBuffer(BufferSize, vk::BufferUsageFlagBits::eTransferSrc, - vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, stagingBuffer, - stagingBufferMemory); - - void* data; - handleVulkanError(m_device.mapMemory(stagingBufferMemory, 0, BufferSize, {}, &data)); - std::memcpy(data, s_indices.data(), BufferSize); - m_device.unmapMemory(stagingBufferMemory); - - createBuffer(BufferSize, vk::BufferUsageFlagBits::eTransferDst | vk::BufferUsageFlagBits::eIndexBuffer, - vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent, m_indexBuffer, - m_indexBufferMemory); - - copyBuffer(stagingBuffer, m_indexBuffer, BufferSize); - - // TODO: vk::raii - m_device.destroy(stagingBuffer); - m_device.freeMemory(stagingBufferMemory); -} - -void vulk::ContextVulkan::createUniformBuffers() +void vulk::detail::ContextVulkan::createUniformBuffers() { VULK_SCOPED_PROFILER("ContextVulkan::createUniformBuffers()"); @@ -763,7 +730,7 @@ void vulk::ContextVulkan::createUniformBuffers() } } -void vulk::ContextVulkan::createDescriptorPool() +void vulk::detail::ContextVulkan::createDescriptorPool() { VULK_SCOPED_PROFILER("ContextVulkan::createDescriptorPool()"); @@ -778,7 +745,7 @@ void vulk::ContextVulkan::createDescriptorPool() handleVulkanError(m_device.createDescriptorPool(&createInfo, nullptr, &m_descriptorPool)); } -void vulk::ContextVulkan::createDescriptorSets() +void vulk::detail::ContextVulkan::createDescriptorSets() { VULK_SCOPED_PROFILER("ContextVulkan::createDescriptorSets()"); @@ -810,7 +777,7 @@ void vulk::ContextVulkan::createDescriptorSets() } } -void vulk::ContextVulkan::createCommandBuffers() +void vulk::detail::ContextVulkan::createCommandBuffers() { VULK_SCOPED_PROFILER("ContextVulkan::createCommandBuffers()"); @@ -824,7 +791,7 @@ void vulk::ContextVulkan::createCommandBuffers() handleVulkanError(m_device.allocateCommandBuffers(&allocateInfo, m_commandBuffers.data())); } -void vulk::ContextVulkan::createSyncObject() +void vulk::detail::ContextVulkan::createSyncObject() { vk::SemaphoreCreateInfo semaphoreInfo{}; vk::FenceCreateInfo fenceInfo{}; @@ -842,7 +809,7 @@ void vulk::ContextVulkan::createSyncObject() } } -void vulk::ContextVulkan::recordCommandBuffer(vk::CommandBuffer& commandBuffer, uint32_t imageIndex) +void vulk::detail::ContextVulkan::recordCommandBuffer(vk::CommandBuffer& commandBuffer, uint32_t imageIndex) { vk::CommandBufferBeginInfo beginInfo{}; // beginInfo.flags = vk::CommandBufferUsageFlagBits::...; @@ -861,23 +828,46 @@ void vulk::ContextVulkan::recordCommandBuffer(vk::CommandBuffer& commandBuffer, renderPassBeginInfo.clearValueCount = 1; renderPassBeginInfo.pClearValues = &clearValue; - std::array vertexBuffers{m_vertexBuffer}; - std::array offsets{vk::DeviceSize{0}}; - static_assert(vertexBuffers.size() == offsets.size()); + // TODO: *Highly* inefficient, will have to do until a proper renderer system is written. + uint32_t vertexCount{}; + std::vector vertexBuffers{}; + std::vector indexBuffers{}; + std::vector offsets{}; + vertexBuffers.reserve(m_shapes.size()); + indexBuffers.reserve(m_shapes.size()); + offsets.resize(m_shapes.size(), vk::DeviceSize{0}); + + for (const auto* drawable : m_shapes) + { + vertexBuffers.push_back(drawable->getVertexBuffer()); + indexBuffers.push_back(drawable->getIndexBuffer()); + vertexCount += static_cast(drawable->getVertexCount()); + } commandBuffer.beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline); commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, m_pipeline); - commandBuffer.bindVertexBuffers(0, static_cast(vertexBuffers.size()), vertexBuffers.data(), - offsets.data()); - commandBuffer.bindIndexBuffer(m_indexBuffer, 0, getIndexType()); commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, m_pipelineLayout, 0, 1, &m_descriptorSets[m_currentFrame], 0, nullptr); - commandBuffer.drawIndexed(static_cast(s_indices.size()), 1, 0, 0, 0); + + uint32_t vertexOffset{}; + for (const auto& m_shape : m_shapes) + { + commandBuffer.bindVertexBuffers(vertexOffset, static_cast(vertexBuffers.size()), vertexBuffers.data(), + offsets.data()); + commandBuffer.bindIndexBuffer(m_shape->getIndexBuffer(), 0, vk::IndexType::eUint32); + commandBuffer.drawIndexed(static_cast(m_shape->getIndexCount()), 1, 0, + static_cast(vertexOffset), 0); + vertexOffset += static_cast(m_shape->getVertexCount()); + } + // commandBuffer.bindVertexBuffers(0, static_cast(vertexBuffers.size()), vertexBuffers.data(), + // offsets.data()); + // commandBuffer.bindIndexBuffer(m_indexBuffer, 0, vk::IndexType::eUint32); + // commandBuffer.drawIndexed(static_cast(s_indices.size()), 1, 0, 0, 0); commandBuffer.endRenderPass(); commandBuffer.end(); } -void vulk::ContextVulkan::chooseSwapSurfaceFormat() +void vulk::detail::ContextVulkan::chooseSwapSurfaceFormat() { assert(!m_swapchainSupport.formats.empty()); @@ -896,7 +886,7 @@ void vulk::ContextVulkan::chooseSwapSurfaceFormat() m_surfaceFormat = m_swapchainSupport.formats[0]; } -void vulk::ContextVulkan::chooseSwapPresentMode() +void vulk::detail::ContextVulkan::chooseSwapPresentMode() { for (const auto& presentMode : PRESENT_MODES_PREFERRED) { @@ -914,7 +904,7 @@ void vulk::ContextVulkan::chooseSwapPresentMode() throw VulkanException("No present mode available."); } -void vulk::ContextVulkan::chooseSwapExtent() +void vulk::detail::ContextVulkan::chooseSwapExtent() { const auto& caps = m_swapchainSupport.capabilities; @@ -933,7 +923,7 @@ void vulk::ContextVulkan::chooseSwapExtent() } } -void vulk::ContextVulkan::updateUniformBuffer(uint32_t currentImage) +void vulk::detail::ContextVulkan::updateUniformBuffer(uint32_t currentImage) { static auto startTime = Clock::now(); auto currentTime = Clock::now(); @@ -952,9 +942,9 @@ void vulk::ContextVulkan::updateUniformBuffer(uint32_t currentImage) m_device.unmapMemory(m_uniformBuffersMemory[currentImage]); } -void vulk::ContextVulkan::createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage, - vk::MemoryPropertyFlags properties, vk::Buffer& outBuffer, - vk::DeviceMemory& outDeviceMemory) +void vulk::detail::ContextVulkan::createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage, + vk::MemoryPropertyFlags properties, vk::Buffer& outBuffer, + vk::DeviceMemory& outDeviceMemory) { VULK_SCOPED_PROFILER("ContextVulkan::createBuffer()"); @@ -974,7 +964,8 @@ void vulk::ContextVulkan::createBuffer(vk::DeviceSize size, vk::BufferUsageFlags m_device.bindBufferMemory(outBuffer, outDeviceMemory, 0); } -void vulk::ContextVulkan::copyBuffer(const vk::Buffer& sourceBuffer, vk::Buffer& destinationBuffer, vk::DeviceSize size) +void vulk::detail::ContextVulkan::copyBuffer(const vk::Buffer& sourceBuffer, vk::Buffer& destinationBuffer, + vk::DeviceSize size) { VULK_SCOPED_PROFILER("ContextVulkan::copyBuffer()"); @@ -1008,7 +999,7 @@ void vulk::ContextVulkan::copyBuffer(const vk::Buffer& sourceBuffer, vk::Buffer& m_device.freeCommandBuffers(m_commandPool, 1, &commandBuffer); } -bool vulk::ContextVulkan::verifyExtensionsSupport(const vk::PhysicalDevice& device) +bool vulk::detail::ContextVulkan::verifyExtensionsSupport(const vk::PhysicalDevice& device) { VULK_SCOPED_PROFILER("ContextVulkan::verifyExtensionsSupport()"); @@ -1030,8 +1021,8 @@ bool vulk::ContextVulkan::verifyExtensionsSupport(const vk::PhysicalDevice& devi return allValid; } -vulk::ContextVulkan::QueueFamilyEntry -vulk::ContextVulkan::findQueueFamilies(const vk::PhysicalDevice& physicalDevice) const noexcept +vulk::detail::ContextVulkan::QueueFamilyEntry +vulk::detail::ContextVulkan::findQueueFamilies(const vk::PhysicalDevice& physicalDevice) const noexcept { VULK_SCOPED_PROFILER("ContextVulkan::findQueueFamilies()"); @@ -1056,7 +1047,7 @@ vulk::ContextVulkan::findQueueFamilies(const vk::PhysicalDevice& physicalDevice) return std::make_pair(std::move(queueFamilies), indices); } -uint32_t vulk::ContextVulkan::findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties) const +uint32_t vulk::detail::ContextVulkan::findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties) const { vk::PhysicalDeviceMemoryProperties memoryProperties{m_physicalDevice.getMemoryProperties()}; @@ -1071,8 +1062,8 @@ uint32_t vulk::ContextVulkan::findMemoryType(uint32_t typeFilter, vk::MemoryProp throw VulkanException("Could not find a suitable memory type"); } -vulk::ContextVulkan::SwapChainSupportDetails -vulk::ContextVulkan::querySwapChainSupport(const vk::PhysicalDevice& device) const noexcept +vulk::detail::ContextVulkan::SwapChainSupportDetails +vulk::detail::ContextVulkan::querySwapChainSupport(const vk::PhysicalDevice& device) const noexcept { SwapChainSupportDetails details{device.getSurfaceCapabilitiesKHR(m_surface), // device.getSurfaceFormatsKHR(m_surface), // @@ -1081,7 +1072,7 @@ vulk::ContextVulkan::querySwapChainSupport(const vk::PhysicalDevice& device) con return details; } -vulk::ContextVulkan& vulk::ContextVulkan::getInstance() +vulk::detail::ContextVulkan& vulk::detail::ContextVulkan::getInstance() { assert(s_instance); return *s_instance; diff --git a/lib/src/Graphics/ADrawable.cpp b/lib/src/Graphics/ADrawable.cpp new file mode 100644 index 0000000..0b9ffa0 --- /dev/null +++ b/lib/src/Graphics/ADrawable.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "Vulk/Graphics/ADrawable.hpp" + +#include "Vulk/Contexts/ContextVulkan.hpp" + +vulk::ADrawable::ADrawable() +{ + // detail::ContextVulkan::getInstance().registerDrawable(*this); +} + +vulk::ADrawable::~ADrawable() +{ + // detail::ContextVulkan::getInstance().unregisterDrawable(*this); +} + +void vulk::ADrawable::setScale(const glm::vec2& scale) +{ + m_scale = scale; +} + +void vulk::ADrawable::setOrigin(const glm::vec2& origin) +{ + m_origin = origin; +} + +void vulk::ADrawable::setPosition(const glm::vec2& position) +{ + m_position = position; +} diff --git a/lib/src/Graphics/AShape.cpp b/lib/src/Graphics/AShape.cpp new file mode 100644 index 0000000..cfc9ec9 --- /dev/null +++ b/lib/src/Graphics/AShape.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "Vulk/Graphics/AShape.hpp" + +#include "Vulk/Contexts/ContextVulkan.hpp" + +vulk::AShape::AShape() +{ + detail::ContextVulkan::getInstance().registerDrawable(*this); +} + +vulk::AShape::~AShape() +{ + resetBuffers(); + detail::ContextVulkan::getInstance().unregisterDrawable(*this); +} + +void vulk::AShape::makeBuffers() +{ + auto& vulkInstance = detail::ContextVulkan::getInstance(); + + vulkInstance.createBuffers(m_vertices, m_vertexBuffer, m_vertexMemory, vk::BufferUsageFlagBits::eVertexBuffer); + vulkInstance.createBuffers(m_indices, m_indexBuffer, m_indexMemory, vk::BufferUsageFlagBits::eIndexBuffer); +} + +void vulk::AShape::resetBuffers() +{ + auto& vulkInstance = detail::ContextVulkan::getInstance(); + + vulkInstance.destroyBuffer(m_indexBuffer); + vulkInstance.destroyBuffer(m_vertexBuffer); + vulkInstance.freeBufferMem(m_indexMemory); + vulkInstance.freeBufferMem(m_vertexMemory); +} + +void vulk::AShape::setColor(vulk::Color color) +{ + resetBuffers(); + for (auto& vertex : m_vertices) + { + vertex.color = color.to_glm_color(); + } + makeBuffers(); +} diff --git a/lib/src/Graphics/Circle.cpp b/lib/src/Graphics/Circle.cpp new file mode 100644 index 0000000..0a6ecae --- /dev/null +++ b/lib/src/Graphics/Circle.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "Vulk/Graphics/Circle.hpp" diff --git a/lib/src/Graphics/Rectangle.cpp b/lib/src/Graphics/Rectangle.cpp new file mode 100644 index 0000000..66525d7 --- /dev/null +++ b/lib/src/Graphics/Rectangle.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "Vulk/Graphics/Rectangle.hpp" + +vulk::Rectangle::Rectangle() +{ + setVertices(std::array{Vertex{{-0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}}, // + Vertex{{0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}}, // + Vertex{{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}, // + Vertex{{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}}); + setIndices(std::array{0, 1, 2, 2, 3, 0}); + makeBuffers(); +} diff --git a/lib/src/Graphics/Triangle.cpp b/lib/src/Graphics/Triangle.cpp new file mode 100644 index 0000000..2c3fc01 --- /dev/null +++ b/lib/src/Graphics/Triangle.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021-2021 [fill name later] + * + * This software is provided "as-is", without any express or implied warranty. In no event + * will the authors be held liable for any damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, including commercial + * applications, and to alter it and redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not claim that you + * wrote the original software. If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented + * as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include "Vulk/Graphics/Triangle.hpp" + +vulk::Triangle::Triangle() +{ + setVertices(std::array{Vertex{{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}}, // + Vertex{{0.5f, 0.5f}, {1.0f, 0.0f, 0.0f}}, // + Vertex{{-0.5f, 0.5f}, {1.0f, 0.0f, 0.0f}}}); + setIndices(std::array{0, 1, 2}); + makeBuffers(); +} diff --git a/lib/src/Objects.cpp b/lib/src/Objects.cpp index f1a2d92..8b953c2 100644 --- a/lib/src/Objects.cpp +++ b/lib/src/Objects.cpp @@ -19,7 +19,7 @@ #include "Vulk/Objects.hpp" -vk::VertexInputBindingDescription Vertex::getBindingDescription() noexcept +vk::VertexInputBindingDescription vulk::Vertex::getBindingDescription() noexcept { vk::VertexInputBindingDescription bindingDescription{}; @@ -30,7 +30,7 @@ vk::VertexInputBindingDescription Vertex::getBindingDescription() noexcept return bindingDescription; } -Vertex::AttributeDescriptions Vertex::getAttributeDescriptions() noexcept +vulk::Vertex::AttributeDescriptions vulk::Vertex::getAttributeDescriptions() noexcept { AttributeDescriptions attributeDescriptions{}; diff --git a/lib/src/Window.cpp b/lib/src/Window.cpp index 90c2f2a..4eed04b 100644 --- a/lib/src/Window.cpp +++ b/lib/src/Window.cpp @@ -21,8 +21,6 @@ #include -#include - #include "Vulk/Contexts/ContextGLFW.hpp" #include "Vulk/Contexts/ContextVulkan.hpp" #include "Vulk/Exceptions.hpp" @@ -36,7 +34,7 @@ vulk::Window::Window(unsigned int width, unsigned int height, const char* title) assert(height != 0); assert(title != nullptr); - ContextGLFW::ensureInstance(); + detail::ContextGLFW::ensureInstance(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // TODO: Dynamic from arguments @@ -52,7 +50,7 @@ vulk::Window::Window(unsigned int width, unsigned int height, const char* title) glfwSetKeyCallback(m_windowHandle, onKeyPressed); glfwSetMouseButtonCallback(m_windowHandle, onButtonPressed); - ContextVulkan::createInstance(m_windowHandle); + detail::ContextVulkan::createInstance(m_windowHandle); } vulk::Window::~Window() @@ -76,7 +74,7 @@ vulk::Window& vulk::Window::operator=(Window&& rhs) noexcept void vulk::Window::display() { - ContextVulkan::getInstance().draw(); + detail::ContextVulkan::getInstance().draw(); m_frameManager.update(); }