From a3b43ab111e8fe4e422dd465439dc5fbee5cfe8e Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Fri, 11 Feb 2022 21:56:51 +0100 Subject: [PATCH 01/10] feat: drawable hierarchy draft --- lib/CMakeLists.txt | 2 ++ lib/include/Vulk/Graphics/Drawable.hpp | 42 ++++++++++++++++++++++++++ lib/include/Vulk/Graphics/Shape.hpp | 32 ++++++++++++++++++++ lib/src/Graphics/Drawable.cpp | 25 +++++++++++++++ lib/src/Graphics/Shape.cpp | 20 ++++++++++++ 5 files changed, 121 insertions(+) create mode 100644 lib/include/Vulk/Graphics/Drawable.hpp create mode 100644 lib/include/Vulk/Graphics/Shape.hpp create mode 100644 lib/src/Graphics/Drawable.cpp create mode 100644 lib/src/Graphics/Shape.cpp diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index c132b6d..ced21c0 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -17,6 +17,8 @@ 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/Drawable.cpp include/Vulk/Graphics/Drawable.hpp + src/Graphics/Shape.cpp include/Vulk/Graphics/Shape.hpp ) target_include_directories(${PROJECT_NAME} PRIVATE include) diff --git a/lib/include/Vulk/Graphics/Drawable.hpp b/lib/include/Vulk/Graphics/Drawable.hpp new file mode 100644 index 0000000..5e97407 --- /dev/null +++ b/lib/include/Vulk/Graphics/Drawable.hpp @@ -0,0 +1,42 @@ +/* + * 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() = default; + explicit ADrawable(const glm::vec2& position) : m_position{position} {} + + virtual ~ADrawable() = default; + + virtual void draw() const = 0; + + virtual void setPosition(const glm::vec2& position); + + [[nodiscard]] const auto& getPosition() const noexcept { return m_position; } + +protected: + glm::vec2 m_position{}; +}; +} // namespace vulk diff --git a/lib/include/Vulk/Graphics/Shape.hpp b/lib/include/Vulk/Graphics/Shape.hpp new file mode 100644 index 0000000..0429b5f --- /dev/null +++ b/lib/include/Vulk/Graphics/Shape.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 "Drawable.hpp" +#include "Vulk/Graphics/Drawable.hpp" + +namespace vulk { +class Shape : public ADrawable +{ +public: + Shape() = default; + explicit Shape(const glm::vec2& position) : ADrawable{position} {} +}; +} // namespace vulk diff --git a/lib/src/Graphics/Drawable.cpp b/lib/src/Graphics/Drawable.cpp new file mode 100644 index 0000000..f7a9fde --- /dev/null +++ b/lib/src/Graphics/Drawable.cpp @@ -0,0 +1,25 @@ +/* + * 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/Drawable.hpp" + +void vulk::ADrawable::setPosition(const glm::vec2& position) +{ + m_position = position; +} diff --git a/lib/src/Graphics/Shape.cpp b/lib/src/Graphics/Shape.cpp new file mode 100644 index 0000000..e2dc56a --- /dev/null +++ b/lib/src/Graphics/Shape.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/Shape.hpp" From 4e9cbd77e218fb53ffcbc5126a84586e1fa75bbd Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Sat, 26 Feb 2022 19:47:30 +0100 Subject: [PATCH 02/10] other: create base for primitive shape classes --- lib/CMakeLists.txt | 6 ++-- .../Graphics/{Drawable.hpp => ADrawable.hpp} | 3 ++ .../Vulk/Graphics/{Shape.hpp => AShape.hpp} | 10 +++---- lib/include/Vulk/Graphics/Circle.hpp | 27 ++++++++++++++++++ lib/include/Vulk/Graphics/Rectangle.hpp | 27 ++++++++++++++++++ lib/include/Vulk/Graphics/Triangle.hpp | 28 +++++++++++++++++++ .../Graphics/{Drawable.cpp => ADrawable.cpp} | 7 ++++- lib/src/Graphics/{Shape.cpp => AShape.cpp} | 2 +- lib/src/Graphics/Circle.cpp | 20 +++++++++++++ lib/src/Graphics/Rectangle.cpp | 20 +++++++++++++ lib/src/Graphics/Triangle.cpp | 20 +++++++++++++ 11 files changed, 160 insertions(+), 10 deletions(-) rename lib/include/Vulk/Graphics/{Drawable.hpp => ADrawable.hpp} (89%) rename lib/include/Vulk/Graphics/{Shape.hpp => AShape.hpp} (83%) create mode 100644 lib/include/Vulk/Graphics/Circle.hpp create mode 100644 lib/include/Vulk/Graphics/Rectangle.hpp create mode 100644 lib/include/Vulk/Graphics/Triangle.hpp rename lib/src/Graphics/{Drawable.cpp => ADrawable.cpp} (89%) rename lib/src/Graphics/{Shape.cpp => AShape.cpp} (96%) create mode 100644 lib/src/Graphics/Circle.cpp create mode 100644 lib/src/Graphics/Rectangle.cpp create mode 100644 lib/src/Graphics/Triangle.cpp diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index ced21c0..e7f7ddb 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -17,9 +17,9 @@ 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/Drawable.cpp include/Vulk/Graphics/Drawable.hpp - src/Graphics/Shape.cpp include/Vulk/Graphics/Shape.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) target_include_directories(${PROJECT_NAME} PRIVATE include) diff --git a/lib/include/Vulk/Graphics/Drawable.hpp b/lib/include/Vulk/Graphics/ADrawable.hpp similarity index 89% rename from lib/include/Vulk/Graphics/Drawable.hpp rename to lib/include/Vulk/Graphics/ADrawable.hpp index 5e97407..7993d11 100644 --- a/lib/include/Vulk/Graphics/Drawable.hpp +++ b/lib/include/Vulk/Graphics/ADrawable.hpp @@ -32,11 +32,14 @@ class ADrawable virtual void draw() const = 0; + virtual void setOrigin(const glm::vec2& origin); virtual void setPosition(const glm::vec2& position); + [[nodiscard]] const auto& getOrigin() const noexcept { return m_origin; } [[nodiscard]] const auto& getPosition() const noexcept { return m_position; } protected: + glm::vec2 m_origin{}; glm::vec2 m_position{}; }; } // namespace vulk diff --git a/lib/include/Vulk/Graphics/Shape.hpp b/lib/include/Vulk/Graphics/AShape.hpp similarity index 83% rename from lib/include/Vulk/Graphics/Shape.hpp rename to lib/include/Vulk/Graphics/AShape.hpp index 0429b5f..86bd831 100644 --- a/lib/include/Vulk/Graphics/Shape.hpp +++ b/lib/include/Vulk/Graphics/AShape.hpp @@ -19,14 +19,14 @@ #pragma once -#include "Drawable.hpp" -#include "Vulk/Graphics/Drawable.hpp" +#include "ADrawable.hpp" +#include "Vulk/Graphics/ADrawable.hpp" namespace vulk { -class Shape : public ADrawable +class AShape : public ADrawable { public: - Shape() = default; - explicit Shape(const glm::vec2& position) : ADrawable{position} {} + AShape() = default; + explicit AShape(const glm::vec2& position) : ADrawable{position} {} }; } // namespace vulk diff --git a/lib/include/Vulk/Graphics/Circle.hpp b/lib/include/Vulk/Graphics/Circle.hpp new file mode 100644 index 0000000..487df34 --- /dev/null +++ b/lib/include/Vulk/Graphics/Circle.hpp @@ -0,0 +1,27 @@ +/* + * 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 +{ +}; +} // namespace vulk diff --git a/lib/include/Vulk/Graphics/Rectangle.hpp b/lib/include/Vulk/Graphics/Rectangle.hpp new file mode 100644 index 0000000..39b367f --- /dev/null +++ b/lib/include/Vulk/Graphics/Rectangle.hpp @@ -0,0 +1,27 @@ +/* + * 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 +{ +}; +} // namespace vulk diff --git a/lib/include/Vulk/Graphics/Triangle.hpp b/lib/include/Vulk/Graphics/Triangle.hpp new file mode 100644 index 0000000..20845dd --- /dev/null +++ b/lib/include/Vulk/Graphics/Triangle.hpp @@ -0,0 +1,28 @@ +/* + * 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 +{ +}; +} // namespace vulk diff --git a/lib/src/Graphics/Drawable.cpp b/lib/src/Graphics/ADrawable.cpp similarity index 89% rename from lib/src/Graphics/Drawable.cpp rename to lib/src/Graphics/ADrawable.cpp index f7a9fde..ae4734b 100644 --- a/lib/src/Graphics/Drawable.cpp +++ b/lib/src/Graphics/ADrawable.cpp @@ -17,7 +17,12 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include "Vulk/Graphics/Drawable.hpp" +#include "Vulk/Graphics/ADrawable.hpp" + +void vulk::ADrawable::setOrigin(const glm::vec2& origin) +{ + m_origin = origin; +} void vulk::ADrawable::setPosition(const glm::vec2& position) { diff --git a/lib/src/Graphics/Shape.cpp b/lib/src/Graphics/AShape.cpp similarity index 96% rename from lib/src/Graphics/Shape.cpp rename to lib/src/Graphics/AShape.cpp index e2dc56a..4122a11 100644 --- a/lib/src/Graphics/Shape.cpp +++ b/lib/src/Graphics/AShape.cpp @@ -17,4 +17,4 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include "Vulk/Graphics/Shape.hpp" +#include "Vulk/Graphics/AShape.hpp" 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..92854b3 --- /dev/null +++ b/lib/src/Graphics/Rectangle.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/Rectangle.hpp" diff --git a/lib/src/Graphics/Triangle.cpp b/lib/src/Graphics/Triangle.cpp new file mode 100644 index 0000000..071a0d3 --- /dev/null +++ b/lib/src/Graphics/Triangle.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/Triangle.hpp" From 833f0c6be660f93d6f9436dcb7b6e7f4ec8f7e13 Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Sun, 27 Feb 2022 03:44:18 +0100 Subject: [PATCH 03/10] refactor/feat: macros / shape progress --- cmake/flags.cmake | 7 -- lib/CMakeLists.txt | 2 +- lib/include/Vulk/ClassUtils.hpp | 24 ------ lib/include/Vulk/Contexts/ContextGLFW.hpp | 2 +- lib/include/Vulk/Contexts/ContextVulkan.hpp | 2 +- lib/include/Vulk/Exceptions.hpp | 2 +- lib/include/Vulk/Graphics/ADrawable.hpp | 3 + lib/include/Vulk/Graphics/Circle.hpp | 1 + lib/include/Vulk/Graphics/Rectangle.hpp | 1 + lib/include/Vulk/Macros.hpp | 83 +++++++++++++++++++++ lib/include/Vulk/ScopedProfiler.hpp | 7 +- lib/src/Contexts/ContextVulkan.cpp | 6 +- lib/src/Graphics/ADrawable.cpp | 5 ++ 13 files changed, 103 insertions(+), 42 deletions(-) create mode 100644 lib/include/Vulk/Macros.hpp 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/lib/CMakeLists.txt b/lib/CMakeLists.txt index e7f7ddb..be071b1 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -19,7 +19,7 @@ add_library( 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/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 include/Vulk/Macros.hpp) target_include_directories(${PROJECT_NAME} PRIVATE include) 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/Contexts/ContextGLFW.hpp b/lib/include/Vulk/Contexts/ContextGLFW.hpp index 88e217e..c8e2023 100644 --- a/lib/include/Vulk/Contexts/ContextGLFW.hpp +++ b/lib/include/Vulk/Contexts/ContextGLFW.hpp @@ -21,7 +21,7 @@ #include -#include "Vulk/ClassUtils.hpp" +#include "Vulk/Macros.hpp" namespace vulk { class ContextGLFW diff --git a/lib/include/Vulk/Contexts/ContextVulkan.hpp b/lib/include/Vulk/Contexts/ContextVulkan.hpp index 522a8c8..795ecdd 100644 --- a/lib/include/Vulk/Contexts/ContextVulkan.hpp +++ b/lib/include/Vulk/Contexts/ContextVulkan.hpp @@ -25,7 +25,7 @@ #include #include -#include "Vulk/ClassUtils.hpp" +#include "Vulk/Macros.hpp" #include "Vulk/Objects.hpp" #include "Vulk/Window.hpp" 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 index 7993d11..d050f37 100644 --- a/lib/include/Vulk/Graphics/ADrawable.hpp +++ b/lib/include/Vulk/Graphics/ADrawable.hpp @@ -34,12 +34,15 @@ class ADrawable 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/Circle.hpp b/lib/include/Vulk/Graphics/Circle.hpp index 487df34..90577fe 100644 --- a/lib/include/Vulk/Graphics/Circle.hpp +++ b/lib/include/Vulk/Graphics/Circle.hpp @@ -18,6 +18,7 @@ */ #pragma once + #include "Vulk/Graphics/AShape.hpp" namespace vulk { diff --git a/lib/include/Vulk/Graphics/Rectangle.hpp b/lib/include/Vulk/Graphics/Rectangle.hpp index 39b367f..7962eca 100644 --- a/lib/include/Vulk/Graphics/Rectangle.hpp +++ b/lib/include/Vulk/Graphics/Rectangle.hpp @@ -18,6 +18,7 @@ */ #pragma once + #include "Vulk/Graphics/AShape.hpp" namespace vulk { diff --git a/lib/include/Vulk/Macros.hpp b/lib/include/Vulk/Macros.hpp new file mode 100644 index 0000000..fe99cdd --- /dev/null +++ b/lib/include/Vulk/Macros.hpp @@ -0,0 +1,83 @@ +/* + * 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 +#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/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/src/Contexts/ContextVulkan.cpp b/lib/src/Contexts/ContextVulkan.cpp index 08d8bb8..7e09279 100644 --- a/lib/src/Contexts/ContextVulkan.cpp +++ b/lib/src/Contexts/ContextVulkan.cpp @@ -55,7 +55,7 @@ vulk::ContextVulkan::ContextVulkan(GLFWwindow* windowHandle) : m_windowHandle{wi glfwSetFramebufferSizeCallback(m_windowHandle, &framebufferResizeCallback); #if VULK_DEBUG - printAvailableValidationLayers(); + // printAvailableValidationLayers(); #endif createInstance(); @@ -867,11 +867,11 @@ void vulk::ContextVulkan::recordCommandBuffer(vk::CommandBuffer& commandBuffer, commandBuffer.beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline); commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, m_pipeline); + commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, m_pipelineLayout, 0, 1, + &m_descriptorSets[m_currentFrame], 0, nullptr); 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); commandBuffer.endRenderPass(); commandBuffer.end(); diff --git a/lib/src/Graphics/ADrawable.cpp b/lib/src/Graphics/ADrawable.cpp index ae4734b..a8af506 100644 --- a/lib/src/Graphics/ADrawable.cpp +++ b/lib/src/Graphics/ADrawable.cpp @@ -19,6 +19,11 @@ #include "Vulk/Graphics/ADrawable.hpp" +void vulk::ADrawable::setScale(const glm::vec2& scale) +{ + m_scale = scale; +} + void vulk::ADrawable::setOrigin(const glm::vec2& origin) { m_origin = origin; From f61344a3c72e637d5305757435b284e751add2df Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Sun, 27 Feb 2022 03:46:11 +0100 Subject: [PATCH 04/10] format: lib/CMakeLists.txt --- lib/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index be071b1..1a02e1f 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 @@ -19,7 +20,10 @@ add_library( 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 include/Vulk/Macros.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 +) target_include_directories(${PROJECT_NAME} PRIVATE include) From 56a81560ffa25e9bf760781f4271cc94f1f62a13 Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Sun, 27 Feb 2022 05:42:37 +0100 Subject: [PATCH 05/10] other: progress on shapes --- lib/include/Vulk/Contexts/ContextGLFW.hpp | 4 +- lib/include/Vulk/Contexts/ContextVulkan.hpp | 18 +- lib/include/Vulk/Graphics/AShape.hpp | 7 + lib/include/Vulk/Macros.hpp | 10 +- lib/src/Contexts/ContextGLFW.cpp | 8 +- lib/src/Contexts/ContextVulkan.cpp | 177 +++++++------------- lib/src/Graphics/AShape.cpp | 12 ++ lib/src/Window.cpp | 8 +- 8 files changed, 105 insertions(+), 139 deletions(-) diff --git a/lib/include/Vulk/Contexts/ContextGLFW.hpp b/lib/include/Vulk/Contexts/ContextGLFW.hpp index c8e2023..9932774 100644 --- a/lib/include/Vulk/Contexts/ContextGLFW.hpp +++ b/lib/include/Vulk/Contexts/ContextGLFW.hpp @@ -23,7 +23,7 @@ #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 795ecdd..dfefa4a 100644 --- a/lib/include/Vulk/Contexts/ContextVulkan.hpp +++ b/lib/include/Vulk/Contexts/ContextVulkan.hpp @@ -29,7 +29,7 @@ #include "Vulk/Objects.hpp" #include "Vulk/Window.hpp" -namespace vulk { +namespace vulk::detail { class ContextVulkan { public: @@ -41,6 +41,11 @@ class ContextVulkan */ void draw(); + void createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties, + vk::Buffer& outBuffer, vk::DeviceMemory& outDeviceMemory); + void destroyBuffer(vk::Buffer buffer); + void freeBufferMem(vk::DeviceMemory deviceMemory); + // TODO: should not be public, remove once events are implemented void setFrameBufferResized(bool value) noexcept { m_frameBufferResized = value; } @@ -130,8 +135,6 @@ class ContextVulkan void createGraphicsPipeline(); void createFrameBuffers(); void createCommandPool(); - void createVertexBuffer(); - void createIndexBuffer(); void createUniformBuffers(); void createDescriptorPool(); void createDescriptorSets(); @@ -141,8 +144,6 @@ class ContextVulkan void recordCommandBuffer(vk::CommandBuffer& commandBuffer, uint32_t imageIndex); void recreateSwapChain(); - 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); @@ -202,11 +203,6 @@ 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{}; @@ -244,4 +240,4 @@ class ContextVulkan static std::unique_ptr s_instance; }; -} // namespace vulk +} // namespace vulk::detail diff --git a/lib/include/Vulk/Graphics/AShape.hpp b/lib/include/Vulk/Graphics/AShape.hpp index 86bd831..ad0ece7 100644 --- a/lib/include/Vulk/Graphics/AShape.hpp +++ b/lib/include/Vulk/Graphics/AShape.hpp @@ -27,6 +27,13 @@ class AShape : public ADrawable { public: AShape() = default; + ~AShape() override; explicit AShape(const glm::vec2& position) : ADrawable{position} {} + +private: + vk::Buffer m_vertexBuffer{}; + vk::DeviceMemory m_vertexBufferMemory{}; + vk::Buffer m_indexBuffer{}; + vk::DeviceMemory m_indexBufferMemory{}; }; } // namespace vulk diff --git a/lib/include/Vulk/Macros.hpp b/lib/include/Vulk/Macros.hpp index fe99cdd..762ae8c 100644 --- a/lib/include/Vulk/Macros.hpp +++ b/lib/include/Vulk/Macros.hpp @@ -64,12 +64,14 @@ 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 + #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 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 7e09279..381826a 100644 --- a/lib/src/Contexts/ContextVulkan.cpp +++ b/lib/src/Contexts/ContextVulkan.cpp @@ -33,19 +33,19 @@ #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()"); @@ -69,8 +69,6 @@ vulk::ContextVulkan::ContextVulkan(GLFWwindow* windowHandle) : m_windowHandle{wi createGraphicsPipeline(); createFrameBuffers(); createCommandPool(); - createVertexBuffer(); - createIndexBuffer(); createUniformBuffers(); createDescriptorPool(); createDescriptorSets(); @@ -82,7 +80,7 @@ vulk::ContextVulkan::ContextVulkan(GLFWwindow* windowHandle) : m_windowHandle{wi #endif } -vulk::ContextVulkan::~ContextVulkan() +vulk::detail::ContextVulkan::~ContextVulkan() { VULK_SCOPED_PROFILER("ContextVulkan::~ContextVulkan()"); @@ -107,12 +105,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 +112,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 +134,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 +148,7 @@ void vulk::ContextVulkan::cleanupSwapchainSubObjects() m_swapchainImageViews.clear(); } -void vulk::ContextVulkan::createInstance(GLFWwindow* windowHandle) +void vulk::detail::ContextVulkan::createInstance(GLFWwindow* windowHandle) { assert(windowHandle); @@ -167,7 +159,7 @@ 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)); @@ -226,7 +218,19 @@ 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.destroy(buffer); +} + +void vulk::detail::ContextVulkan::freeBufferMem(vk::DeviceMemory deviceMemory) +{ + if (m_device) + m_device.freeMemory(deviceMemory); +} + +[[maybe_unused]] void vulk::detail::ContextVulkan::printAvailableValidationLayers() { std::cout << "Available Layers:\n"; @@ -237,7 +241,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 +270,7 @@ std::vector vulk::ContextVulkan::getSupportedValidationLayers() return supported; } -void vulk::ContextVulkan::createInstance() +void vulk::detail::ContextVulkan::createInstance() { VULK_SCOPED_PROFILER("ContextVulkan::createInstance()"); @@ -298,7 +302,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 +313,7 @@ void vulk::ContextVulkan::createSurface() m_surface = surface; } -void vulk::ContextVulkan::pickPhysicalDevice() +void vulk::detail::ContextVulkan::pickPhysicalDevice() { VULK_SCOPED_PROFILER("ContextVulkan::pickPhysicalDevice()"); @@ -339,7 +343,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 +388,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 +419,7 @@ void vulk::ContextVulkan::recreateSwapChain() createCommandBuffers(); } -void vulk::ContextVulkan::createSwapChain() +void vulk::detail::ContextVulkan::createSwapChain() { VULK_SCOPED_PROFILER("ContextVulkan::createSwapChain()"); @@ -471,7 +475,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 +503,7 @@ void vulk::ContextVulkan::createImageViews() } } -void vulk::ContextVulkan::createRenderPass() +void vulk::detail::ContextVulkan::createRenderPass() { VULK_SCOPED_PROFILER("ContextVulkan::createRenderPass()"); @@ -542,7 +546,7 @@ void vulk::ContextVulkan::createRenderPass() assert(m_renderPass); } -void vulk::ContextVulkan::createDescriptorSetLayout() +void vulk::detail::ContextVulkan::createDescriptorSetLayout() { VULK_SCOPED_PROFILER("ContextVulkan::createDescriptorSetLayout()"); @@ -559,7 +563,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()"); @@ -655,7 +659,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 +685,7 @@ void vulk::ContextVulkan::createFrameBuffers() } } -void vulk::ContextVulkan::createCommandPool() +void vulk::detail::ContextVulkan::createCommandPool() { VULK_SCOPED_PROFILER("ContextVulkan::createCommandPool()"); @@ -692,61 +696,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 +713,7 @@ void vulk::ContextVulkan::createUniformBuffers() } } -void vulk::ContextVulkan::createDescriptorPool() +void vulk::detail::ContextVulkan::createDescriptorPool() { VULK_SCOPED_PROFILER("ContextVulkan::createDescriptorPool()"); @@ -778,7 +728,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 +760,7 @@ void vulk::ContextVulkan::createDescriptorSets() } } -void vulk::ContextVulkan::createCommandBuffers() +void vulk::detail::ContextVulkan::createCommandBuffers() { VULK_SCOPED_PROFILER("ContextVulkan::createCommandBuffers()"); @@ -824,7 +774,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 +792,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 +811,23 @@ 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()); + // std::array vertexBuffers{m_vertexBuffer}; + // std::array offsets{vk::DeviceSize{0}}; + // static_assert(vertexBuffers.size() == offsets.size()); commandBuffer.beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline); commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, m_pipeline); commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, m_pipelineLayout, 0, 1, &m_descriptorSets[m_currentFrame], 0, nullptr); - commandBuffer.bindVertexBuffers(0, static_cast(vertexBuffers.size()), vertexBuffers.data(), - offsets.data()); - commandBuffer.bindIndexBuffer(m_indexBuffer, 0, getIndexType()); - commandBuffer.drawIndexed(static_cast(s_indices.size()), 1, 0, 0, 0); + // commandBuffer.bindVertexBuffers(0, static_cast(vertexBuffers.size()), vertexBuffers.data(), + // offsets.data()); + // commandBuffer.bindIndexBuffer(m_indexBuffer, 0, getIndexType()); + // 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 +846,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 +864,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 +883,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 +902,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 +924,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 +959,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 +981,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 +1007,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 +1022,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 +1032,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/AShape.cpp b/lib/src/Graphics/AShape.cpp index 4122a11..9d9e389 100644 --- a/lib/src/Graphics/AShape.cpp +++ b/lib/src/Graphics/AShape.cpp @@ -18,3 +18,15 @@ */ #include "Vulk/Graphics/AShape.hpp" + +#include "Vulk/Contexts/ContextVulkan.hpp" + +vulk::AShape::~AShape() +{ + auto& vulkInstance = detail::ContextVulkan::getInstance(); + + vulkInstance.destroyBuffer(m_indexBuffer); + vulkInstance.destroyBuffer(m_vertexBuffer); + vulkInstance.freeBufferMem(m_indexBufferMemory); + vulkInstance.freeBufferMem(m_vertexBufferMemory); +} 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(); } From af5d3beb630ea40a9a1da5456bf3c072ecd75eab Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Sun, 27 Feb 2022 16:40:49 +0100 Subject: [PATCH 06/10] fix: build errors --- lib/include/Vulk/Contexts/ContextVulkan.hpp | 4 ---- lib/include/Vulk/Graphics/AShape.hpp | 2 ++ lib/include/Vulk/Macros.hpp | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/include/Vulk/Contexts/ContextVulkan.hpp b/lib/include/Vulk/Contexts/ContextVulkan.hpp index dfefa4a..399debf 100644 --- a/lib/include/Vulk/Contexts/ContextVulkan.hpp +++ b/lib/include/Vulk/Contexts/ContextVulkan.hpp @@ -35,10 +35,6 @@ 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(); void createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties, diff --git a/lib/include/Vulk/Graphics/AShape.hpp b/lib/include/Vulk/Graphics/AShape.hpp index ad0ece7..7fad3e2 100644 --- a/lib/include/Vulk/Graphics/AShape.hpp +++ b/lib/include/Vulk/Graphics/AShape.hpp @@ -19,6 +19,8 @@ #pragma once +#include + #include "ADrawable.hpp" #include "Vulk/Graphics/ADrawable.hpp" diff --git a/lib/include/Vulk/Macros.hpp b/lib/include/Vulk/Macros.hpp index 762ae8c..a9e2434 100644 --- a/lib/include/Vulk/Macros.hpp +++ b/lib/include/Vulk/Macros.hpp @@ -63,9 +63,9 @@ 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 +// 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 From 11c2048bacf0179675519afb70a6b452d6cfefb7 Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Mon, 28 Feb 2022 01:22:48 +0100 Subject: [PATCH 07/10] feat: progress on shapes --- example-app/src/Main.cpp | 7 +++ lib/include/Vulk/Contexts/ContextVulkan.hpp | 64 +++++++++++++-------- lib/include/Vulk/Graphics/ADrawable.hpp | 4 +- lib/include/Vulk/Graphics/AShape.hpp | 37 ++++++++++-- lib/include/Vulk/Graphics/Circle.hpp | 2 + lib/include/Vulk/Graphics/Rectangle.hpp | 4 ++ lib/include/Vulk/Graphics/Triangle.hpp | 4 ++ lib/include/Vulk/Objects.hpp | 2 + lib/shaders/shader.vert | 2 +- lib/src/Contexts/ContextVulkan.cpp | 53 ++++++++++++++--- lib/src/Graphics/ADrawable.cpp | 12 ++++ lib/src/Graphics/AShape.cpp | 18 +++++- lib/src/Graphics/Rectangle.cpp | 10 ++++ lib/src/Graphics/Triangle.cpp | 9 +++ lib/src/Objects.cpp | 4 +- 15 files changed, 191 insertions(+), 41 deletions(-) diff --git a/example-app/src/Main.cpp b/example-app/src/Main.cpp index 3ffa7a2..a089339 100644 --- a/example-app/src/Main.cpp +++ b/example-app/src/Main.cpp @@ -18,6 +18,8 @@ */ #include +#include +#include #include #include @@ -37,10 +39,15 @@ int main() win.setTitle(buffer); }); + vulk::Triangle triangle{}; + vulk::Rectangle rectangle{}; + while (win.isOpen()) { win.pollEvents(); + triangle.draw(); + rectangle.draw(); win.display(); } diff --git a/lib/include/Vulk/Contexts/ContextVulkan.hpp b/lib/include/Vulk/Contexts/ContextVulkan.hpp index 399debf..b6ead83 100644 --- a/lib/include/Vulk/Contexts/ContextVulkan.hpp +++ b/lib/include/Vulk/Contexts/ContextVulkan.hpp @@ -25,6 +25,9 @@ #include #include +#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" @@ -37,11 +40,41 @@ class ContextVulkan void draw(); - void createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties, - vk::Buffer& outBuffer, vk::DeviceMemory& outDeviceMemory); + 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; } @@ -142,6 +175,9 @@ class ContextVulkan 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 cleanupSwapchain(vk::SwapchainKHR& swapchain); void cleanupSwapchainSubObjects(); @@ -205,6 +241,8 @@ class ContextVulkan 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; @@ -212,27 +250,7 @@ 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; }; diff --git a/lib/include/Vulk/Graphics/ADrawable.hpp b/lib/include/Vulk/Graphics/ADrawable.hpp index d050f37..2aac296 100644 --- a/lib/include/Vulk/Graphics/ADrawable.hpp +++ b/lib/include/Vulk/Graphics/ADrawable.hpp @@ -25,10 +25,10 @@ namespace vulk { class ADrawable { public: - ADrawable() = default; + ADrawable(); explicit ADrawable(const glm::vec2& position) : m_position{position} {} - virtual ~ADrawable() = default; + virtual ~ADrawable(); virtual void draw() const = 0; diff --git a/lib/include/Vulk/Graphics/AShape.hpp b/lib/include/Vulk/Graphics/AShape.hpp index 7fad3e2..a72fbba 100644 --- a/lib/include/Vulk/Graphics/AShape.hpp +++ b/lib/include/Vulk/Graphics/AShape.hpp @@ -21,21 +21,50 @@ #include -#include "ADrawable.hpp" #include "Vulk/Graphics/ADrawable.hpp" +#include "Vulk/Objects.hpp" namespace vulk { class AShape : public ADrawable { public: - AShape() = default; + AShape(); ~AShape() override; explicit AShape(const glm::vec2& position) : ADrawable{position} {} + [[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: vk::Buffer m_vertexBuffer{}; - vk::DeviceMemory m_vertexBufferMemory{}; + vk::DeviceMemory m_vertexMemory{}; vk::Buffer m_indexBuffer{}; - vk::DeviceMemory m_indexBufferMemory{}; + 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 index 90577fe..6d03d61 100644 --- a/lib/include/Vulk/Graphics/Circle.hpp +++ b/lib/include/Vulk/Graphics/Circle.hpp @@ -24,5 +24,7 @@ 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 index 7962eca..f1e9e16 100644 --- a/lib/include/Vulk/Graphics/Rectangle.hpp +++ b/lib/include/Vulk/Graphics/Rectangle.hpp @@ -24,5 +24,9 @@ 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 index 20845dd..ccd84a5 100644 --- a/lib/include/Vulk/Graphics/Triangle.hpp +++ b/lib/include/Vulk/Graphics/Triangle.hpp @@ -24,5 +24,9 @@ namespace vulk { class Triangle : public AShape { +public: + Triangle(); + + void draw() const override {} }; } // namespace vulk 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/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/ContextVulkan.cpp b/lib/src/Contexts/ContextVulkan.cpp index 381826a..4897a16 100644 --- a/lib/src/Contexts/ContextVulkan.cpp +++ b/lib/src/Contexts/ContextVulkan.cpp @@ -29,6 +29,7 @@ #include #include "Vulk/Exceptions.hpp" +#include "Vulk/Graphics/AShape.hpp" #include "Vulk/ScopedProfiler.hpp" #include "Vulk/Shader.hpp" #include "Vulk/Utils.hpp" @@ -161,10 +162,10 @@ void vulk::detail::ContextVulkan::createInstance(GLFWwindow* windowHandle) 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) { @@ -221,13 +222,29 @@ void vulk::detail::ContextVulkan::draw() 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() @@ -609,7 +626,7 @@ void vulk::detail::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{}; @@ -811,17 +828,39 @@ void vulk::detail::ContextVulkan::recordCommandBuffer(vk::CommandBuffer& command 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.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, m_pipelineLayout, 0, 1, &m_descriptorSets[m_currentFrame], 0, nullptr); + + int32_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, vertexOffset, 0); + vertexOffset += static_cast(m_shape->getVertexCount()); + } // commandBuffer.bindVertexBuffers(0, static_cast(vertexBuffers.size()), vertexBuffers.data(), // offsets.data()); - // commandBuffer.bindIndexBuffer(m_indexBuffer, 0, getIndexType()); + // commandBuffer.bindIndexBuffer(m_indexBuffer, 0, vk::IndexType::eUint32); // commandBuffer.drawIndexed(static_cast(s_indices.size()), 1, 0, 0, 0); commandBuffer.endRenderPass(); commandBuffer.end(); diff --git a/lib/src/Graphics/ADrawable.cpp b/lib/src/Graphics/ADrawable.cpp index a8af506..0b9ffa0 100644 --- a/lib/src/Graphics/ADrawable.cpp +++ b/lib/src/Graphics/ADrawable.cpp @@ -19,6 +19,18 @@ #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; diff --git a/lib/src/Graphics/AShape.cpp b/lib/src/Graphics/AShape.cpp index 9d9e389..d89e183 100644 --- a/lib/src/Graphics/AShape.cpp +++ b/lib/src/Graphics/AShape.cpp @@ -21,12 +21,26 @@ #include "Vulk/Contexts/ContextVulkan.hpp" +vulk::AShape::AShape() +{ + detail::ContextVulkan::getInstance().registerDrawable(*this); +} + vulk::AShape::~AShape() { auto& vulkInstance = detail::ContextVulkan::getInstance(); vulkInstance.destroyBuffer(m_indexBuffer); vulkInstance.destroyBuffer(m_vertexBuffer); - vulkInstance.freeBufferMem(m_indexBufferMemory); - vulkInstance.freeBufferMem(m_vertexBufferMemory); + vulkInstance.freeBufferMem(m_indexMemory); + vulkInstance.freeBufferMem(m_vertexMemory); + vulkInstance.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); } diff --git a/lib/src/Graphics/Rectangle.cpp b/lib/src/Graphics/Rectangle.cpp index 92854b3..66525d7 100644 --- a/lib/src/Graphics/Rectangle.cpp +++ b/lib/src/Graphics/Rectangle.cpp @@ -18,3 +18,13 @@ */ #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 index 071a0d3..2c3fc01 100644 --- a/lib/src/Graphics/Triangle.cpp +++ b/lib/src/Graphics/Triangle.cpp @@ -18,3 +18,12 @@ */ #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{}; From f651043b4751206cee97e66b1dee870e41dd9ee1 Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Mon, 28 Feb 2022 13:40:02 +0100 Subject: [PATCH 08/10] feat: shapes can now have a color --- example-app/src/Main.cpp | 9 ++++----- lib/include/Vulk/Color.hpp | 7 +++++++ lib/include/Vulk/Graphics/AShape.hpp | 5 +++++ lib/src/Graphics/AShape.cpp | 27 +++++++++++++++++++++------ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/example-app/src/Main.cpp b/example-app/src/Main.cpp index a089339..ff276a2 100644 --- a/example-app/src/Main.cpp +++ b/example-app/src/Main.cpp @@ -17,7 +17,6 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include #include #include #include @@ -39,15 +38,15 @@ int main() win.setTitle(buffer); }); - vulk::Triangle triangle{}; - vulk::Rectangle rectangle{}; + vulk::Rectangle obj{}; + + obj.setColor(vulk::Color::White); while (win.isOpen()) { win.pollEvents(); - triangle.draw(); - rectangle.draw(); + obj.draw(); win.display(); } 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/Graphics/AShape.hpp b/lib/include/Vulk/Graphics/AShape.hpp index a72fbba..852d8c9 100644 --- a/lib/include/Vulk/Graphics/AShape.hpp +++ b/lib/include/Vulk/Graphics/AShape.hpp @@ -23,6 +23,7 @@ #include "Vulk/Graphics/ADrawable.hpp" #include "Vulk/Objects.hpp" +#include "Vulk/Color.hpp" namespace vulk { class AShape : public ADrawable @@ -32,6 +33,8 @@ class AShape : public ADrawable ~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(); } @@ -59,6 +62,8 @@ class AShape : public ADrawable void makeBuffers(); private: + void resetBuffers(); + vk::Buffer m_vertexBuffer{}; vk::DeviceMemory m_vertexMemory{}; vk::Buffer m_indexBuffer{}; diff --git a/lib/src/Graphics/AShape.cpp b/lib/src/Graphics/AShape.cpp index d89e183..cfc9ec9 100644 --- a/lib/src/Graphics/AShape.cpp +++ b/lib/src/Graphics/AShape.cpp @@ -27,6 +27,20 @@ vulk::AShape::AShape() } 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(); @@ -34,13 +48,14 @@ vulk::AShape::~AShape() vulkInstance.destroyBuffer(m_vertexBuffer); vulkInstance.freeBufferMem(m_indexMemory); vulkInstance.freeBufferMem(m_vertexMemory); - vulkInstance.unregisterDrawable(*this); } -void vulk::AShape::makeBuffers() +void vulk::AShape::setColor(vulk::Color color) { - 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); + resetBuffers(); + for (auto& vertex : m_vertices) + { + vertex.color = color.to_glm_color(); + } + makeBuffers(); } From b20447465526715c42ee729252c9ad6035495208 Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Mon, 28 Feb 2022 14:17:04 +0100 Subject: [PATCH 09/10] fix: gcc warnings --- lib/src/Contexts/ContextVulkan.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/Contexts/ContextVulkan.cpp b/lib/src/Contexts/ContextVulkan.cpp index 4897a16..c3965f6 100644 --- a/lib/src/Contexts/ContextVulkan.cpp +++ b/lib/src/Contexts/ContextVulkan.cpp @@ -849,14 +849,15 @@ void vulk::detail::ContextVulkan::recordCommandBuffer(vk::CommandBuffer& command commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, m_pipelineLayout, 0, 1, &m_descriptorSets[m_currentFrame], 0, nullptr); - int32_t vertexOffset{}; + 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, vertexOffset, 0); - vertexOffset += static_cast(m_shape->getVertexCount()); + 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()); From 65f240e246d18630c45380f742361c170ab122c7 Mon Sep 17 00:00:00 2001 From: Maxime Houis Date: Mon, 28 Feb 2022 14:17:25 +0100 Subject: [PATCH 10/10] format: apply clang format --- lib/include/Vulk/Graphics/AShape.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/Vulk/Graphics/AShape.hpp b/lib/include/Vulk/Graphics/AShape.hpp index 852d8c9..22e59e1 100644 --- a/lib/include/Vulk/Graphics/AShape.hpp +++ b/lib/include/Vulk/Graphics/AShape.hpp @@ -21,9 +21,9 @@ #include +#include "Vulk/Color.hpp" #include "Vulk/Graphics/ADrawable.hpp" #include "Vulk/Objects.hpp" -#include "Vulk/Color.hpp" namespace vulk { class AShape : public ADrawable