From a14237d6ce93ac3c3724f8887a1003a13f3842e7 Mon Sep 17 00:00:00 2001 From: HOEGLER Stefan Date: Tue, 25 Feb 2020 00:44:40 +0100 Subject: [PATCH] Implemented basic containers and ref pointers --- CMakeLists.txt | 33 ++- CMakeSettings.json | 11 +- cmake/SuperBuild.cmake | 45 ++-- src/CMakeLists.txt | 2 + src/Engine/CMakeLists.txt | 8 + src/Engine/Containers/Array.h | 281 ++++++++++++++++++++++ src/Engine/Containers/CMakeLists.txt | 3 + src/Engine/Containers/Map.h | 262 ++++++++++++++++++++ src/Engine/Graphics/CMakeLists.txt | 12 + src/Engine/Graphics/Graphics.cpp | 15 +- src/Engine/Graphics/Graphics.h | 34 ++- src/Engine/Graphics/GraphicsResources.h | 9 + src/Engine/Graphics/View.h | 10 + src/Engine/Graphics/Vulkan/CMakeLists.txt | 0 src/Engine/Graphics/Window.cpp | 12 + src/Engine/Graphics/Window.h | 39 +++ src/Engine/Graphics/WindowManager.cpp | 16 ++ src/Engine/Graphics/WindowManager.h | 16 ++ src/Engine/Math/CMakeLists.txt | 5 + src/Engine/Math/Math.h | 0 src/Engine/Math/Matrix.h | 10 + src/Engine/Math/Vector.h | 17 ++ src/Engine/MinimalEngine.h | 129 ++++++++++ src/Engine/main.cpp | 5 +- test/CMakeLists.txt | 13 + test/Engine/CMakeLists.txt | 6 + test/Engine/Containers/Array.cpp | 141 +++++++++++ test/Engine/Containers/CMakeLists.txt | 4 + test/Engine/Containers/Map.cpp | 67 ++++++ test/Engine/EngineTest.cpp | 42 ++++ test/Engine/EngineTest.h | 1 + 31 files changed, 1212 insertions(+), 36 deletions(-) create mode 100644 src/CMakeLists.txt create mode 100644 src/Engine/CMakeLists.txt create mode 100644 src/Engine/Containers/Array.h create mode 100644 src/Engine/Containers/CMakeLists.txt create mode 100644 src/Engine/Containers/Map.h create mode 100644 src/Engine/Graphics/CMakeLists.txt create mode 100644 src/Engine/Graphics/GraphicsResources.h create mode 100644 src/Engine/Graphics/View.h create mode 100644 src/Engine/Graphics/Vulkan/CMakeLists.txt create mode 100644 src/Engine/Graphics/Window.cpp create mode 100644 src/Engine/Graphics/Window.h create mode 100644 src/Engine/Graphics/WindowManager.cpp create mode 100644 src/Engine/Graphics/WindowManager.h create mode 100644 src/Engine/Math/CMakeLists.txt create mode 100644 src/Engine/Math/Math.h create mode 100644 src/Engine/Math/Matrix.h create mode 100644 src/Engine/Math/Vector.h create mode 100644 src/Engine/MinimalEngine.h create mode 100644 test/CMakeLists.txt create mode 100644 test/Engine/CMakeLists.txt create mode 100644 test/Engine/Containers/Array.cpp create mode 100644 test/Engine/Containers/CMakeLists.txt create mode 100644 test/Engine/Containers/Map.cpp create mode 100644 test/Engine/EngineTest.cpp create mode 100644 test/Engine/EngineTest.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b5d1b87..6fe0aec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,25 @@ cmake_minimum_required(VERSION 3.15) +set(CMAKE_CXX_STANDARD_REQUIRED 17) + # Handle superbuild first option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON) -set (GLOBAL_OUTPUT_PATH ${CMAKE_BINARY_DIR}) +set(ENGINE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src/Engine) +set(EXTERNAL_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/external) +set(SLANG_ROOT ${EXTERNAL_ROOT}/slang) +set(BOOST_ROOT ${EXTERNAL_ROOT}/boost) +set(GLM_ROOT ${EXTERNAL_ROOT}/glm) +set(GLFW_ROOT ${EXTERNAL_ROOT}/glfw) +set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}) +set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}) + +# Configuration types +SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) +IF(DEFINED CMAKE_BUILD_TYPE AND CMAKE_VERSION VERSION_GREATER "2.8") + SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES}) +ENDIF() set(Boost_USE_STATIC_LIBS ON) set(Boost_LIB_PREFIX lib) @@ -26,12 +42,19 @@ include_directories(${GLFW_INCLUDE_DIRS}) include_directories(${GLM_INCLUDE_DIRS}) include_directories(${Vulkan_INCLUDE_DIR}) include_directories(${Boost_INCLUDE_DIRS}) +include_directories(${SLANG_INCLUDE_DIRS}) +include_directories(src/Engine) add_definitions(${GLM_DEFINITIONS}) -add_definitions(${VULKAN_DEFINITIONS}) -add_definitions(${BOOST_DEFINITIONS}) -add_executable(SeeleEngine src/Engine/main.cpp src/Engine/Graphics/Graphics.cpp) +add_definitions(${Vulkan_DEFINITIONS}) +add_definitions(${Boost_DEFINITIONS}) +add_executable(SeeleEngine "") +add_subdirectory(src/) target_link_libraries(SeeleEngine ${Boost_LIBRARIES}) target_link_libraries(SeeleEngine ${Vulkan_LIBRARY}) target_link_libraries(SeeleEngine ${GLFW_LIBRARY}) +target_link_libraries(SeeleEngine ${SLANG_LIBRARY}) + +add_subdirectory(test/) + +add_custom_command(TARGET SeeleEngine POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DEPENDENT_BINARIES} $) -message(STATUS "TEST") \ No newline at end of file diff --git a/CMakeSettings.json b/CMakeSettings.json index 94a4610..49da498 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -1,17 +1,16 @@ { "configurations": [ { - "name": "x64-Debug", + "name": "Debug", "generator": "Ninja", "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x64" ], + "inheritEnvironments": [ "msvc_x64_x64" ], "buildRoot": "${projectDir}\\bin\\${name}", - "installRoot": "${projectDir}\\out\\install\\${name}", + "installRoot": "${projectDir}\\install\\${name}", "cmakeCommandArgs": "", - "buildCommandArgs": "", + "buildCommandArgs": "-v", "ctestCommandArgs": "", - "variables": [], - "intelliSenseMode": "windows-clang-x86" + "variables": [] } ] } \ No newline at end of file diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index 226d7f8..845667b 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -4,33 +4,39 @@ set_property(DIRECTORY PROPERTY EP_BASE external) set(DEPENDENCIES) set(EXTRA_CMAKE_ARGS) +set(DEPENDENT_BINARIES "") #-------------BOOST---------------- list(APPEND DEPENDENCIES boost) +if(WIN32) + set(BOOTSTRAP_EXTENSION bat) +elseif(UNIX) + set(BOOTSTRAP_EXTENSION sh) +endif() ExternalProject_Add(boost - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/boost - CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=serialization + SOURCE_DIR ${BOOST_ROOT} + UPDATE_COMMAND "" + CONFIGURE_COMMAND ./bootstrap.${BOOTSTRAP_EXTENSION} --with-libraries=serialization,test BUILD_COMMAND ./b2 link=static BUILD_IN_SOURCE 1 INSTALL_COMMAND "") list (APPEND EXTRA_CMAKE_ARGS - -DBOOST_ROOT=${CMAKE_CURRENT_SOURCE_DIR}/external/boost -DBoost_NO_SYSTEM_PATHS=ON) #----------------GLM----------------------- list(APPEND DEPENDENCIES glm) ExternalProject_Add(glm - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/glm - BINARY_DIR ${CMAKE_BINARY_DIR}/lib + SOURCE_DIR ${GLM_ROOT} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "") list(APPEND EXTRA_CMAKE_ARGS - -DGLM_INCLUDE_DIRS=${CMAKE_CURRENT_SOURCE_DIR}/external/glm + -DGLM_INCLUDE_DIRS=${GLM_ROOT} ) + #--------------GLFW------------------------------ list(APPEND DEPENDENCIES glfw) set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) @@ -38,31 +44,40 @@ set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) ExternalProject_Add(glfw - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/glfw - BINARY_DIR ${CMAKE_BINARY_DIR}/lib/glfw + SOURCE_DIR ${GLFW_ROOT} + BINARY_DIR ${CMAKE_BINARY_DIR}/lib INSTALL_COMMAND "") list(APPEND EXTRA_CMAKE_ARGS - -DGLFW_INCLUDE_DIRS=${CMAKE_CURRENT_SOURCE_DIR}/external/glfw/include - -DGLFW_LIBRARY=${CMAKE_BINARY_DIR}/lib/glfw/src/glfw3.lib + -DGLFW_INCLUDE_DIRS=${GLFW_ROOT}/include + -DGLFW_LIBRARY=${CMAKE_BINARY_DIR}/lib/src/glfw3.lib ) #--------------SLang------------------------------ list(APPEND DEPENDENCIES slang) ExternalProject_Add(slang - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/slang + SOURCE_DIR ${SLANG_ROOT} BINARY_DIR ${CMAKE_BINARY_DIR}/lib CONFIGURE_COMMAND "" - - BUILD_COMMAND msbuild -m /p:WindowsTargetPlatformVersion=10.0 ${CMAKE_SOURCE_DIR}/external/slang/slang.sln - + BUILD_COMMAND "" + # BUILD_COMMAND devenv /upgrade ${SLANG_ROOT}/source/slang/slang.vcxproj + # COMMAND msbuild -m /p:WindowsTargetPlatformVersion=10.0 ${SLANG_ROOT}/source/slang/slang.vcxproj INSTALL_COMMAND "") +list(APPEND EXTRA_CMAKE_ARGS + -DSLANG_INCLUDE_DIRS=${EXTERNAL_ROOT} + -DSLANG_LIBRARY=${SLANG_ROOT}/bin/windows-x64/${CMAKE_BUILD_TYPE}/slang.lib) + +set(SLANG_DLL) +string(TOLOWER bin/windows-x64/${CMAKE_BUILD_TYPE}/slang.dll SLANG_DLL) +list(APPEND DEPENDENT_BINARIES ${SLANG_ROOT}/${SLANG_DLL}) +list(APPEND EXTRA_CMAKE_ARGS + -DDEPENDENT_BINARIES=${DEPENDENT_BINARIES}) #-----------------SeeleEngine-------------------- ExternalProject_Add(SeeleEngine DEPENDS ${DEPENDENCIES} SOURCE_DIR ${PROJECT_SOURCE_DIR} CMAKE_ARGS -DUSE_SUPERBUILD=OFF ${EXTRA_CMAKE_ARGS} INSTALL_COMMAND "" - BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin) \ No newline at end of file + BINARY_DIR ${CMAKE_BINARY_DIR}) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..21f038b --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(Engine/) \ No newline at end of file diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt new file mode 100644 index 0000000..80334e8 --- /dev/null +++ b/src/Engine/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(SeeleEngine + PRIVATE + MinimalEngine.h + main.cpp) + +add_subdirectory(Graphics/) +add_subdirectory(Math/) +add_subdirectory(Containers/) \ No newline at end of file diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h new file mode 100644 index 0000000..8f95001 --- /dev/null +++ b/src/Engine/Containers/Array.h @@ -0,0 +1,281 @@ +#pragma once +#include "MinimalEngine.h" +#include + +#ifndef DEFAULT_ALLOC_SIZE +#define DEFAULT_ALLOC_SIZE 16 +#endif + +namespace Seele +{ + template + struct Array + { + public: + Array() + : allocated(DEFAULT_ALLOC_SIZE) + , arraySize(0) + { + _data = new T[DEFAULT_ALLOC_SIZE]; + refreshIterators(); + } + Array(size_t size, T value = T()) + : allocated(size) + , arraySize(size) + { + _data = new T[size]; + for (int i = 0; i < size; ++i) + { + _data[i] = value; + } + refreshIterators(); + } + ~Array() + { + delete _data; + _data = nullptr; + } + template + class IteratorBase { + public: + typedef std::forward_iterator_tag iterator_category; + typedef X value_type; + typedef std::ptrdiff_t difference_type; + typedef X& reference; + typedef X* pointer; + + IteratorBase(X* x = nullptr) + : p(x) + {} + IteratorBase(const IteratorBase& i) + : p(i.p) + {} + reference operator*() const + { + return *p; + } + pointer operator->() const + { + return p; + } + inline bool operator!=(const IteratorBase& other) + { + return p != other.p; + } + inline bool operator==(const IteratorBase& other) + { + return p == other.p; + } + inline bool operator-(const IteratorBase& other) + { + return p - other.p; + } + IteratorBase& operator++() { + p++; + return *this; + } + IteratorBase operator++(int) { + IteratorBase tmp(*this); + ++*this; + return tmp; + } + private: + X* p; + }; + typedef IteratorBase Iterator; + typedef IteratorBase ConstIterator; + + Iterator find(const T& item) + { + for (int i = 0; i < arraySize; ++i) + { + if (_data[i] == item) + { + return Iterator(&_data[i]); + } + } + return endIt; + } + Iterator begin() + { + return beginIt; + } + Iterator end() + { + return endIt; + } + + T& add(const T& item) + { + if (arraySize == allocated) + { + allocated += DEFAULT_ALLOC_SIZE; + T* tempArray = new T[allocated]; + std::memcpy(tempArray, _data, arraySize * sizeof(T)); + delete _data; + _data = tempArray; + } + _data[arraySize++] = item; + refreshIterators(); + return _data[arraySize - 1]; + } + void remove(Iterator it, bool keepOrder = true) + { + remove(it - beginIt, keepOrder); + } + void remove(int index, bool keepOrder = true) + { + if (keepOrder) + { + std::memcpy(&_data[index], &_data[index + 1], sizeof(T) * (arraySize - index)); + } + else + { + _data[index] = _data[arraySize - 1]; + } + arraySize--; + } + void clear() + { + arraySize = 0; + allocated = 0; + refreshIterators(); + } + void resize(uint32 newSize) + { + if (newSize < allocated) + { + arraySize = newSize; + } + else + { + T* newData = new T[newSize]; + allocated = newSize; + std::memcpy(newData, _data, sizeof(T) * arraySize); + arraySize = newSize; + delete _data; + _data = newData; + } + refreshIterators(); + } + inline uint32 size() const + { + return arraySize; + } + inline uint32 capacity() const + { + return allocated; + } + inline T* data() const + { + return _data; + } + T& back() const + { + return _data[arraySize - 1]; + } + T& operator[](int index) const + { + assert(index >= 0 && index < arraySize); + return _data[index]; + } + private: + void refreshIterators() + { + beginIt = Iterator(_data); + endIt = Iterator(_data + arraySize); + } + uint32 arraySize; + uint32 allocated; + Iterator beginIt; + Iterator endIt; + T* _data; + }; + + template + struct StaticArray + { + public: + StaticArray() + { + beginIt = Iterator(_data); + endIt = Iterator(_data + N); + } + StaticArray(T value) + { + for (int i = 0; i < N; ++i) + { + _data[i] = value; + } + beginIt = Iterator(_data); + endIt = Iterator(_data + N); + } + ~StaticArray() + {} + + inline uint32 size() const + { + return N; + } + inline T* data() const + { + return _data; + } + T& operator[](int index) + { + assert(index >= 0 && index < N); + return _data[index]; + } + + template + class IteratorBase { + public: + typedef std::forward_iterator_tag iterator_category; + typedef X value_type; + typedef std::ptrdiff_t difference_type; + typedef X& reference; + typedef X* pointer; + + IteratorBase(X* x = nullptr) + : p(x) + {} + IteratorBase(const IteratorBase& i) + : p(i.p) + {} + reference operator*() const + { + return *p; + } + pointer operator->() const + { + return p; + } + inline bool operator!=(const IteratorBase& other) + { + return p != other.p; + } + inline bool operator==(const IteratorBase& other) + { + return p == other.p; + } + IteratorBase& operator++() { + p++; + return *this; + } + IteratorBase operator++(int) { + IteratorBase tmp(*this); + ++*this; + return tmp; + } + private: + X* p; + }; + typedef IteratorBase Iterator; + typedef IteratorBase ConstIterator; + + private: + T _data[N]; + Iterator beginIt; + Iterator endIt; + }; +} \ No newline at end of file diff --git a/src/Engine/Containers/CMakeLists.txt b/src/Engine/Containers/CMakeLists.txt new file mode 100644 index 0000000..9775328 --- /dev/null +++ b/src/Engine/Containers/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(SeeleEngine + PRIVATE + Array.h) \ No newline at end of file diff --git a/src/Engine/Containers/Map.h b/src/Engine/Containers/Map.h new file mode 100644 index 0000000..6c9c5b0 --- /dev/null +++ b/src/Engine/Containers/Map.h @@ -0,0 +1,262 @@ +#pragma once +#include "Array.h" + +namespace Seele +{ + template + struct Pair + { + public: + Pair() + : key(K()) + , value(V()) + {} + Pair(K key, V value) + : key(key) + , value(value) + {} + K key; + V value; + }; + template + struct Map + { + private: + struct Node + { + Pair pair; + Node* leftChild; + Node* rightChild; + Node(const K& key) + : leftChild(nullptr) + , rightChild(nullptr) + , pair(key, V()) + {} + Node() + : leftChild(nullptr) + , rightChild(nullptr) + , pair(K(), V()) + {} + }; + + public: + Map() + : root(nullptr) + {} + ~Map() + {} + V& operator[](const K& key) + { + root = splay(root, key); + if (root == nullptr || root->pair.key < key || key < root->pair.key) + { + root = insert(root, key); + } + refreshIterators(); + return root->pair.value; + } + class Iterator { + public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef Pair value_type; + typedef std::ptrdiff_t difference_type; + typedef Pair& reference; + typedef Pair* pointer; + + Iterator(Node* x = nullptr) + : node(x) + { + } + Iterator(const Iterator& i) + : node(i.node) + {} + reference operator*() const + { + return node->pair; + } + pointer operator->() const + { + return &node->pair; + } + inline bool operator!=(const Iterator& other) + { + return node != other.node; + } + inline bool operator==(const Iterator& other) + { + return node == other.node; + } + Iterator& operator++() { + node++; + return *this; + } + Iterator& operator--() { + node--; + return *this; + } + Iterator operator--(int) { + Iterator tmp(*this); + ++* this; + return tmp; + } + Iterator operator++(int) { + Iterator tmp(*this); + ++* this; + return tmp; + } + private: + Node* node; + }; + Iterator find(const K& key) + { + root = splay(root, key); + if (root == nullptr || root->pair.key != key) + { + return endIt; + } + return Iterator(root); + } + bool exists(const K& key) + { + return find(key) != endIt; + } + Iterator begin() const + { + return beginIt; + } + Iterator end() const + { + return endIt; + } + private: + void refreshIterators() + { + beginIt = Iterator(&nodes[0]); + endIt = Iterator(&nodes[0] + nodes.size()); + } + Node* root; + Array nodes; + Iterator beginIt; + Iterator endIt; + Node* rotateRight(Node* node) + { + Node* y = node->leftChild; + node->leftChild = y->rightChild; + y->rightChild = node; + return y; + } + Node* rotateLeft(Node* node) + { + Node* y = node->rightChild; + node->rightChild = y->leftChild; + y->leftChild = node; + return y; + } + Node* makeNode(const K& key) + { + return &nodes.add(Node(key)); + } + Node* insert(Node* root, const K& key) + { + if (root == nullptr) return makeNode(key); + + root = splay(root, key); + + if (!(root->pair.key < key || key < root->pair.key)) return root; + + Node* newNode = makeNode(key); + + if (key < root->pair.key) + { + newNode->rightChild = root; + newNode->leftChild = root->leftChild; + root->leftChild = nullptr; + } + else + { + newNode->leftChild = root; + newNode->rightChild = root->rightChild; + root->rightChild = nullptr; + } + return newNode; + } + Node* remove(Node* root, const K& key) + { + Node* temp; + if (!root) + return nullptr; + + root = splay(root, key); + + if (key != root->pair.key) + return root; + + if (!root->leftChild) + { + temp = root; + root = root->rightChild; + } + else + { + temp = root; + + root = splay(root->leftChild, key); + root->rightChild = temp->rightChild; + } + nodes.remove(temp); + delete temp; + return root; + } + Node* splay(Node* root, const K& key) + { + if (root == nullptr || !(root->pair.key < key || key < root->pair.key)) + { + return root; + } + + if (key < root->pair.key) + { + if (root->leftChild == nullptr) + return root; + + if (key < root->leftChild->pair.key) + { + root->leftChild->leftChild = splay(root->leftChild->leftChild, key); + + root = rotateRight(root); + } + else if (root->leftChild->pair.key < key) + { + root->leftChild->rightChild = splay(root->leftChild->rightChild, key); + + if (root->leftChild->rightChild != nullptr) + { + root->leftChild = rotateLeft(root->leftChild); + } + } + return (root->leftChild == nullptr) ? root : rotateRight(root); + } + else + { + if (root->rightChild == nullptr) + return root; + + if (key < root->rightChild->pair.key) + { + root->rightChild->leftChild = splay(root->rightChild->leftChild, key); + + if (root->rightChild->leftChild != nullptr) + { + root->rightChild = rotateRight(root->rightChild); + } + } + else if (root->rightChild->pair.key < key) + { + root->rightChild->rightChild = splay(root->rightChild->rightChild, key); + root = rotateLeft(root); + } + return (root->rightChild == nullptr) ? root : rotateLeft(root); + } + } + }; +} \ No newline at end of file diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt new file mode 100644 index 0000000..54a2362 --- /dev/null +++ b/src/Engine/Graphics/CMakeLists.txt @@ -0,0 +1,12 @@ +target_sources(SeeleEngine + PRIVATE + Graphics.h + Graphics.cpp + View.h + WindowManager.h + WindowManager.cpp + Window.h + Window.cpp + GraphicsResources.h) + +add_subdirectory(Vulkan/) \ No newline at end of file diff --git a/src/Engine/Graphics/Graphics.cpp b/src/Engine/Graphics/Graphics.cpp index 0f5b812..f57e142 100644 --- a/src/Engine/Graphics/Graphics.cpp +++ b/src/Engine/Graphics/Graphics.cpp @@ -1,11 +1,20 @@ #include "Graphics.h" +#include +#include -Graphics::Graphics() +Seele::Graphics::Graphics() { - + Array arr; + arr.add('2'); + arr.add('4'); + std::cout << "Test" << std::endl; + for (auto a : arr) + { + std::cout << "Element: " << a << std::endl; + } } -Graphics::~Graphics() +Seele::Graphics::~Graphics() { } \ No newline at end of file diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 9a3ae32..ce42019 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -1,6 +1,28 @@ -class Graphics -{ -public: - Graphics(); - ~Graphics(); -}; \ No newline at end of file +#pragma once +#include "MinimalEngine.h" +#include "GraphicsResources.h" + +namespace Seele { + class Window; + class Graphics + { + public: + static Graphics& getInstance() + { + static Graphics instance; + + return instance; + } + void init(GraphicsInitializer initializer); + void beginFrame(); + void endFrame(); + + //Singleton + private: + Graphics(); + Graphics(Graphics const&) = delete; + void operator=(Graphics const&) = delete; + ~Graphics(); + + }; +} \ No newline at end of file diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h new file mode 100644 index 0000000..1be0e41 --- /dev/null +++ b/src/Engine/Graphics/GraphicsResources.h @@ -0,0 +1,9 @@ +#pragma once + +namespace Seele +{ + struct GraphicsInitializer + { + const char* windowLayoutFile; + }; +} \ No newline at end of file diff --git a/src/Engine/Graphics/View.h b/src/Engine/Graphics/View.h new file mode 100644 index 0000000..f2e2888 --- /dev/null +++ b/src/Engine/Graphics/View.h @@ -0,0 +1,10 @@ +#pragma once +#include "Window.h" + +// A view is a part of the window, which can be anything from a viewport to an editor +class View +{ +public: +private: + Window::Section* owner; +}; \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/CMakeLists.txt b/src/Engine/Graphics/Vulkan/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp new file mode 100644 index 0000000..e1613e1 --- /dev/null +++ b/src/Engine/Graphics/Window.cpp @@ -0,0 +1,12 @@ +#include "Window.h" +#include "Graphics.h" +#include + +Seele::Window::Window(const WindowCreateInfo& createInfo) +{ +} + +Seele::Window::~Window() +{ + +} \ No newline at end of file diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h new file mode 100644 index 0000000..2e6bcbc --- /dev/null +++ b/src/Engine/Graphics/Window.h @@ -0,0 +1,39 @@ +#pragma once +#include "MinimalEngine.h" +namespace Seele { + struct WindowCreateInfo + { + int32 width; + int32 height; + const char* title; + }; + class Window + { + public: + Window(const WindowCreateInfo& createInfo); + ~Window(); + private: + // A window is divided into 5 sections, using a border layout + // +--------------TOP------------------+ + // | | + // L R + // E I + // F CENTER G + // T H + // | T + // +-------------BOTTOM----------------+ + // In every section, there can be any number + // of views, when there are multiple, they stack to tabs + struct Section + { + + }; + Section top; + Section bot; + Section left; + Section right; + Section center; + uint32 width; + uint32 height; + }; +} \ No newline at end of file diff --git a/src/Engine/Graphics/WindowManager.cpp b/src/Engine/Graphics/WindowManager.cpp new file mode 100644 index 0000000..c07ea56 --- /dev/null +++ b/src/Engine/Graphics/WindowManager.cpp @@ -0,0 +1,16 @@ +#include "WindowManager.h" + +Seele::WindowManager::WindowManager(GraphicsInitializer initializer) +{ + //TODO Parse layout file + WindowCreateInfo mainWindowInfo; + mainWindowInfo.title = "SeeleEngine"; + mainWindowInfo.width = 1280; + mainWindowInfo.height = 720; + Window* mainWindow = new Window(mainWindowInfo); + windows.add(mainWindow); +} + +Seele::WindowManager::~WindowManager() +{ +} diff --git a/src/Engine/Graphics/WindowManager.h b/src/Engine/Graphics/WindowManager.h new file mode 100644 index 0000000..63ce4a3 --- /dev/null +++ b/src/Engine/Graphics/WindowManager.h @@ -0,0 +1,16 @@ +#pragma once +#include "GraphicsResources.h" +#include "Window.h" +#include "Containers/Array.h" + +namespace Seele +{ + class WindowManager + { + public: + WindowManager(GraphicsInitializer initializer); + ~WindowManager(); + private: + Array> windows; + }; +} \ No newline at end of file diff --git a/src/Engine/Math/CMakeLists.txt b/src/Engine/Math/CMakeLists.txt new file mode 100644 index 0000000..e840f15 --- /dev/null +++ b/src/Engine/Math/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(SeeleEngine + PRIVATE + Math.h + Matrix.h + Vector.h) \ No newline at end of file diff --git a/src/Engine/Math/Math.h b/src/Engine/Math/Math.h new file mode 100644 index 0000000..e69de29 diff --git a/src/Engine/Math/Matrix.h b/src/Engine/Math/Matrix.h new file mode 100644 index 0000000..b462589 --- /dev/null +++ b/src/Engine/Math/Matrix.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include +#include +namespace Seele { + typedef glm::mat2 Matrix2; + typedef glm::mat3 Matrix3; + typedef glm::mat4 Matrix4; +} \ No newline at end of file diff --git a/src/Engine/Math/Vector.h b/src/Engine/Math/Vector.h new file mode 100644 index 0000000..e02324f --- /dev/null +++ b/src/Engine/Math/Vector.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include +namespace Seele { + typedef glm::vec2 Vector2; + typedef glm::vec3 Vector3; + typedef glm::vec4 Vector4; + + typedef glm::uvec2 UVector2; + typedef glm::uvec3 UVector3; + typedef glm::uvec4 UVector4; + + typedef glm::ivec2 IVector2; + typedef glm::ivec3 IVector3; + typedef glm::ivec4 IVector4; +} \ No newline at end of file diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h new file mode 100644 index 0000000..360efcc --- /dev/null +++ b/src/Engine/MinimalEngine.h @@ -0,0 +1,129 @@ +#pragma once +#include +#include +#include +#include + +namespace Seele +{ + typedef uint64_t uint64; + typedef uint32_t uint32; + typedef uint16_t uint16; + typedef uint8_t uint8; + + typedef int64_t int64; + typedef int32_t int32; + typedef int16_t int16; + typedef int8_t int8; + + + template + class RefPtr + { + public: + RefPtr(T* ptr) + { + object = new RefObject(ptr); + } + RefPtr(const RefPtr& other) + : object(other.object) + { + object->addRef(); + } + RefPtr& operator=(const RefPtr& other) + { + if (this != &other) + { + object->removeRef(); + object = other->object; + object->addRef(); + } + return *this; + } + ~RefPtr() + { + object->removeRef(); + } + T* operator->() + { + return object->getHandle(); + } + private: + class RefObject + { + public: + RefObject(T* ptr) + : handle(ptr) + , refCount(1) + { + } + RefObject(const RefObject& rhs) + : handle(rhs.handle) + , refCount(rhs.refCount) + { + + } + ~RefObject() + {} + + void addRef() + { + refCount++; + } + void removeRef() + { + refCount--; + if (refCount.load() <= 0) + { + delete handle; + handle = nullptr; + delete this; + } + } + inline T* getHandle() const + { + return handle; + } + private: + T* handle; + std::atomic_uint64_t refCount; + }; + RefObject* object; + }; + + template + class UniquePtr + { + public: + UniquePtr(T* ptr) + : handle(ptr) + {} + UniquePtr(const UniquePtr& rhs) = delete; + UniquePtr(UniquePtr&& rhs) noexcept + : handle(rhs.handle) + { + rhs.handle = nullptr; + } + UniquePtr& operator=(const UniquePtr& rhs) = delete; + UniquePtr& operator=(UniquePtr&& rhs) + { + handle = rhs.handle; + rhs.handle = nullptr; + return *this; + } + ~UniquePtr() + { + delete handle; + } + T* operator->() + { + return handle; + } + bool isValid() + { + return handle != nullptr; + } + private: + T* handle; + }; +} diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index 2ad59ef..66bd235 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "Graphics/Graphics.h" ///////////////////////////////////////////////////////////// // gps coordinate @@ -44,7 +45,7 @@ int main() { // create class instance const gps_position g(35, 59, 24.567f); - // save data to archive + // save _data to archive { boost::archive::text_oarchive oa(ofs); // write class instance to archive @@ -65,7 +66,9 @@ int main() { std::cout << "Hello World! " << std::endl; VkInstance instance; glm::vec4 vector(0, 1, 0, 1); + Seele::Graphics& graphics = Seele::Graphics::getInstance(); std::cout << vector.y << std::endl; std::cout << glfwInit() << std::endl; + return 0; } \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..e68159a --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,13 @@ +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ".") + +find_package(Boost COMPONENTS unit_test_framework REQUIRED) + +include_directories(${ENGINE_ROOT}) +include_directories(${Boost_INCLUDE_DIRS}) + +add_executable(Seele_unit_tests "") +add_subdirectory(Engine/) +target_link_libraries(Seele_unit_tests ${Boost_LIBRARIES}) + +enable_testing() +add_test(SeeleEngineTest Seele_unit_tests) diff --git a/test/Engine/CMakeLists.txt b/test/Engine/CMakeLists.txt new file mode 100644 index 0000000..c728ab0 --- /dev/null +++ b/test/Engine/CMakeLists.txt @@ -0,0 +1,6 @@ +target_sources(Seele_unit_tests + PRIVATE + EngineTest.h + EngineTest.cpp) +target_include_directories(Seele_unit_tests PUBLIC ./) +add_subdirectory(Containers/) \ No newline at end of file diff --git a/test/Engine/Containers/Array.cpp b/test/Engine/Containers/Array.cpp new file mode 100644 index 0000000..29ecc24 --- /dev/null +++ b/test/Engine/Containers/Array.cpp @@ -0,0 +1,141 @@ +#include "EngineTest.h" +#include "Containers/Array.h" +#define BOOST_TEST_MODULE SeeleEngine +#include + +using namespace Seele; + +BOOST_AUTO_TEST_SUITE(Array_Suite) + +BOOST_AUTO_TEST_CASE(empty_constructur) +{ + Array array; + BOOST_CHECK_EQUAL(array.size(), 0); +} + +BOOST_AUTO_TEST_CASE(initialial_size) +{ + Array array(3); + BOOST_CHECK_EQUAL(array.size(), 3); +} + +BOOST_AUTO_TEST_CASE(resize) +{ + Array array; + array.add(2); + array.add(3); + BOOST_CHECK_EQUAL(array.size(), 2); + array.resize(5); + BOOST_CHECK_EQUAL(array.size(), 5); +} +BOOST_AUTO_TEST_CASE(clear) +{ + Array array; + array.add(3); + array.add(2); + array.add(6); + BOOST_CHECK_EQUAL(array.size(), 3); + array.clear(); + BOOST_CHECK_EQUAL(array.size(), 0); +} +BOOST_AUTO_TEST_CASE(remove_keeporder) +{ + Array array; + array.add(1); + array.add(2); + array.add(3); + array.add(4); + array.add(5); + array.remove(1); + BOOST_CHECK_EQUAL(array[1], 3); + BOOST_CHECK_EQUAL(array[2], 4); + BOOST_CHECK_EQUAL(array[3], 5); + BOOST_CHECK_EQUAL(array.size(), 4); +} + +BOOST_AUTO_TEST_CASE(remove_swap) +{ + Array array; + array.add(1); + array.add(2); + array.add(3); + array.add(4); + array.add(5); + array.remove(1, false); + BOOST_CHECK_EQUAL(array[1], 5); + BOOST_CHECK_EQUAL(array[2], 3); + BOOST_CHECK_EQUAL(array[3], 4); + BOOST_CHECK_EQUAL(array.size(), 4); +} + +BOOST_AUTO_TEST_CASE(remove_iterator) +{ + Array array; + array.add(1); + array.add(2); + array.add(3); + array.add(4); + array.add(5); + array.remove(array.find(1), false); + BOOST_CHECK_EQUAL(array[0], 5); + BOOST_CHECK_EQUAL(array[1], 2); + BOOST_CHECK_EQUAL(array[2], 3); + BOOST_CHECK_EQUAL(array[3], 4); + BOOST_CHECK_EQUAL(array.size(), 4); +} + +BOOST_AUTO_TEST_CASE(remove_iterator_keep_order) +{ + Array array; + array.add(1); + array.add(2); + array.add(3); + array.add(4); + array.add(5); + array.remove(array.find(1)); + BOOST_CHECK_EQUAL(array[0], 2); + BOOST_CHECK_EQUAL(array[1], 3); + BOOST_CHECK_EQUAL(array[2], 4); + BOOST_CHECK_EQUAL(array[3], 5); + BOOST_CHECK_EQUAL(array.size(), 4); +} + +BOOST_AUTO_TEST_CASE(random_access) +{ + Array array; + array.add(4); + array.add(5); + array.add(6); + BOOST_CHECK_EQUAL(array[2], 6); + BOOST_CHECK_EQUAL(array[0], 4); +} + +BOOST_AUTO_TEST_SUITE_END() + + +BOOST_AUTO_TEST_SUITE(StaticArray_Suite) + +BOOST_AUTO_TEST_CASE(empty_constructur) +{ + StaticArray array; + BOOST_CHECK_EQUAL(array.size(), 2); +} + +BOOST_AUTO_TEST_CASE(initialial_size) +{ + StaticArray array(3); + BOOST_CHECK_EQUAL(array.size(), 3); + BOOST_CHECK_EQUAL(array[1], 3); +} + +BOOST_AUTO_TEST_CASE(random_access) +{ + StaticArray array; + array[0] = 4; + array[1] = 5; + array[2] = 6; + BOOST_CHECK_EQUAL(array[0], 4); + BOOST_CHECK_EQUAL(array[2], 6); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/Engine/Containers/CMakeLists.txt b/test/Engine/Containers/CMakeLists.txt new file mode 100644 index 0000000..62ef8fb --- /dev/null +++ b/test/Engine/Containers/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(Seele_unit_tests + PRIVATE + Array.cpp + Map.cpp) \ No newline at end of file diff --git a/test/Engine/Containers/Map.cpp b/test/Engine/Containers/Map.cpp new file mode 100644 index 0000000..424279e --- /dev/null +++ b/test/Engine/Containers/Map.cpp @@ -0,0 +1,67 @@ +#include "EngineTest.h" +#include "Containers/Map.h" +#include + +using namespace Seele; + +BOOST_AUTO_TEST_SUITE(CachedMap) + +BOOST_AUTO_TEST_CASE(insert_find_basic) +{ + Map map; + map[2] = 3; + map[1] = 5; + map[6] = 4; + map[4] = 7; + BOOST_REQUIRE_EQUAL(map[2], 3); + BOOST_REQUIRE_EQUAL(map[1], 5); + BOOST_REQUIRE_EQUAL(map[6], 4); + BOOST_REQUIRE_EQUAL(map[4], 7); + map[2] = 5; + map[4] = 4; + BOOST_REQUIRE_EQUAL(map[2], 5); + BOOST_REQUIRE_EQUAL(map[4], 4); +} + +BOOST_AUTO_TEST_CASE(for_each) +{ + Map map; + map[2] = 3; + map[1] = 5; + map[6] = 4; + map[4] = 7; + int count = 0; + for (auto entry : map) + { + count++; + } + BOOST_REQUIRE_EQUAL(count, 4); +} + +BOOST_AUTO_TEST_CASE(key_exists) +{ + Map map; + map[2] = 3; + BOOST_REQUIRE_EQUAL(map.exists(2), true); + BOOST_REQUIRE_EQUAL(map.exists(4), false); +} + +BOOST_AUTO_TEST_CASE(custom_key) +{ + struct Key + { + int id; + bool operator<(const Key& other) const + { + return id < other.id; + } + }; + Map map; + map[Key{ 2 }] = 3; + map[Key{ 3 }] = 4; + BOOST_REQUIRE_EQUAL(map[Key{ 2 }], 3); + BOOST_REQUIRE_EQUAL(map[Key{ 3 }], 4); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/Engine/EngineTest.cpp b/test/Engine/EngineTest.cpp new file mode 100644 index 0000000..b3b1d6b --- /dev/null +++ b/test/Engine/EngineTest.cpp @@ -0,0 +1,42 @@ +#include "EngineTest.h" +#include "MinimalEngine.h" +#include + +using namespace Seele; + +BOOST_AUTO_TEST_SUITE(RefPtr) + +struct TestStruct +{ + TestStruct() + : data(10) + { + } + ~TestStruct() + { + } + uint32 data; +}; +BOOST_AUTO_TEST_CASE(basic_refcount) +{ + { + Seele::RefPtr ptr = new TestStruct(); + BOOST_REQUIRE_EQUAL(ptr->data, 10); + { + Seele::RefPtr secondPtr = ptr; + BOOST_REQUIRE_EQUAL(secondPtr->data, 10); + BOOST_REQUIRE_EQUAL(ptr->data, 10); + } + BOOST_REQUIRE_EQUAL(ptr->data, 10); + } +} + +BOOST_AUTO_TEST_CASE(unique_ptr) +{ + UniquePtr uptr = new TestStruct(); + UniquePtr uptr2 = std::move(uptr); + BOOST_REQUIRE_EQUAL(uptr2->data, 10); + BOOST_REQUIRE_EQUAL(uptr.isValid(), false); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/Engine/EngineTest.h b/test/Engine/EngineTest.h new file mode 100644 index 0000000..7b9637e --- /dev/null +++ b/test/Engine/EngineTest.h @@ -0,0 +1 @@ +#pragma once \ No newline at end of file