diff --git a/CMakeLists.txt b/CMakeLists.txt index e521dae..d16f9eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2026 Tesseract Interactive +# Copyright 2026 Singularity Engine # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index 339edbf..150cc8b 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2026 Tesseract Interactive +# Copyright 2026 Singularity Engine # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ set(SNGL_PLATFORM_SOURCES set(SNGL_CORE_SOURCES "include/sngl/Core/Engine.h" "src/Core/Engine.cpp" + "src/Core/Math.h" "src/Core/LinearArenaAllocator.h" "src/Core/LinearArenaAllocator.cpp" "src/Core/POTSlabAllocator.h" diff --git a/Engine/include/sngl/Core/Engine.h b/Engine/include/sngl/Core/Engine.h index bc3d40d..634e4a4 100644 --- a/Engine/include/sngl/Core/Engine.h +++ b/Engine/include/sngl/Core/Engine.h @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/include/sngl/Graphics/Device.h b/Engine/include/sngl/Graphics/Device.h index f2f4959..3230618 100644 --- a/Engine/include/sngl/Graphics/Device.h +++ b/Engine/include/sngl/Graphics/Device.h @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/include/sngl/Graphics/Instance.h b/Engine/include/sngl/Graphics/Instance.h index 1e9f988..3d237c6 100644 --- a/Engine/include/sngl/Graphics/Instance.h +++ b/Engine/include/sngl/Graphics/Instance.h @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/include/sngl/Graphics/Types.h b/Engine/include/sngl/Graphics/Types.h index d426d5c..af3dc2e 100644 --- a/Engine/include/sngl/Graphics/Types.h +++ b/Engine/include/sngl/Graphics/Types.h @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/src/Core/Engine.cpp b/Engine/src/Core/Engine.cpp index 4cc63f4..022274a 100644 --- a/Engine/src/Core/Engine.cpp +++ b/Engine/src/Core/Engine.cpp @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/src/Core/LinearArenaAllocator.cpp b/Engine/src/Core/LinearArenaAllocator.cpp index 7e5041a..a5660bb 100644 --- a/Engine/src/Core/LinearArenaAllocator.cpp +++ b/Engine/src/Core/LinearArenaAllocator.cpp @@ -1,3 +1,17 @@ +// Copyright 2026 Singularity Engine +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "LinearArenaAllocator.h" #include diff --git a/Engine/src/Core/LinearArenaAllocator.h b/Engine/src/Core/LinearArenaAllocator.h index 670ec01..d14e039 100644 --- a/Engine/src/Core/LinearArenaAllocator.h +++ b/Engine/src/Core/LinearArenaAllocator.h @@ -1,3 +1,17 @@ +// Copyright 2026 Singularity Engine +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef __SNGL_CORE_LINEARARENAALLOCATOR_H_INCLUDED__ #define __SNGL_CORE_LINEARARENAALLOCATOR_H_INCLUDED__ diff --git a/Engine/src/Core/Math.h b/Engine/src/Core/Math.h new file mode 100644 index 0000000..313ef7b --- /dev/null +++ b/Engine/src/Core/Math.h @@ -0,0 +1,51 @@ +#ifndef __SNGL_CORE_MATH_H_INCLUDED__ +#define __SNGL_CORE_MATH_H_INCLUDED__ + +#include +#include + +namespace sngl::core::math +{ + template + requires std::is_integral_v + constexpr bool isPOT(T x) + { + return (x > 0) && ((x & (x - 1)) == 0); + } + + template + constexpr size_t floor_log2(T x) + { + if (x == 0) return 0; + return static_cast((std::numeric_limits::digits - 1) - std::countl_zero(x)); + } + + template + constexpr size_t ceil_log2(T x) + { + if (x <= 1) return 0; + + if (std::is_constant_evaluated()) + { + size_t log = 0; + T val = x - 1; + while (val > 0) + { + val >>= 1; + log++; + } + + return log; + } + else + return std::bit_width(x - 1); + } +} + +static_assert(sngl::core::math::isPOT(2ull)); +static_assert(sngl::core::math::floor_log2(2ull) == 1); +static_assert(sngl::core::math::floor_log2(3ull) == 1); +static_assert(sngl::core::math::ceil_log2(2ull) == 1); +static_assert(sngl::core::math::ceil_log2(3ull) == 2); + +#endif __SNGL_CORE_MATH_H_INCLUDED__ \ No newline at end of file diff --git a/Engine/src/Core/POTSlabAllocator.cpp b/Engine/src/Core/POTSlabAllocator.cpp index 07e817d..26ce38a 100644 --- a/Engine/src/Core/POTSlabAllocator.cpp +++ b/Engine/src/Core/POTSlabAllocator.cpp @@ -1,138 +1,51 @@ #include "POTSlabAllocator.h" -#include -#include -#include -#include - using namespace sngl::core; -void POTSlabAllocator::FixedSizePool::init(size_t blockSize) -{ - assert(blockSize >= sizeof(Node) && "blockSize must be large enough to hold a pointer"); - m_blockSize = blockSize; -} +FixedSizeBlock::FixedSizeBlock() + : m_freeList(nullptr), + m_blockSize(0), + m_pageSize(0) +{ } -void POTSlabAllocator::FixedSizePool::supplyNewPage(void* rawMemory, size_t pageSize) +void FixedSizeBlock::init(size_t blockSize) { - size_t blocksInPage = pageSize / m_blockSize; - uint8_t* pageStart = static_cast(rawMemory); - - for (size_t i = 0; i < blocksInPage; i++) - { - uint8_t* currentBlockAddress = pageStart + (m_blockSize * i); - Node* node = reinterpret_cast(currentBlockAddress); - node->next = m_freeList; - m_freeList = node; - } + m_pageSize = sngl::platform::GetPageSize(); + assert(math::isPOT(blockSize)); // blockSize should be a power of 2 + m_blockSize = blockSize; } -void* POTSlabAllocator::FixedSizePool::pop() +void* FixedSizeBlock::pop() { - if (!m_freeList) - return nullptr; + if (m_freeList == nullptr) + return nullptr; // supply a page to partition - Node* freeBlock = m_freeList; - m_freeList = freeBlock->next; + Node* currentNode = m_freeList; + m_freeList = m_freeList->next; - return freeBlock; + return m_freeList; } -void POTSlabAllocator::FixedSizePool::push(void* ptr) +void FixedSizeBlock::push(void* ptr) { if (!ptr) return; - Node* node = reinterpret_cast(ptr); - node->next = m_freeList; - m_freeList = node; + Node* newNode = reinterpret_cast(ptr); + newNode->next = m_freeList; + m_freeList = newNode; } -POTSlabAllocator::POTSlabAllocator(size_t reservationSize) - : m_commitedSize(0) +void FixedSizeBlock::supplyNewMemory(void* ptr, size_t memSize) { - assert(sngl::platform::IsInitialized()); - m_pageSize = sngl::platform::GetPageSize(); - - m_reservedSize = (reservationSize + m_pageSize - 1) & ~(m_pageSize - 1); - m_reservedPtr = sngl::platform::memory::Reserve(reservationSize); + assert(memSize % m_pageSize == 0); // Block size should be a multiple of system page size + const size_t nodeCount = memSize / m_blockSize; + uint8_t* const startPtr = static_cast(ptr); - size_t currentPoolSize = MIN_POOL_SIZE; - for (size_t i = 0; i < POOL_COUNT; i++) + for (size_t i = 0; i < nodeCount; i++) { - m_pools[i].init(currentPoolSize); - currentPoolSize *= 2; - } -} - -POTSlabAllocator::~POTSlabAllocator() -{ - sngl::platform::memory::Release(m_reservedPtr); -} - -void* POTSlabAllocator::allocate(size_t size) -{ - const size_t potSize = std::max(MIN_POOL_SIZE, std::bit_ceil(size + sizeof(AllocHeader))); - const int poolIndex = getPoolIndexForSize(potSize); - - void* rawMemory = nullptr; - if (poolIndex >= 0) - { - rawMemory = m_pools[poolIndex].pop(); - if (!rawMemory) - { - m_pools[poolIndex].supplyNewPage(requestPage(), m_pageSize); - rawMemory = m_pools[poolIndex].pop(); - } - } - else - { - // fallback - rawMemory = sngl::platform::memory::Reserve(potSize); - if (!rawMemory) - throw std::runtime_error("Failed to allocate memory"); - - sngl::platform::memory::Commit(rawMemory, potSize); + Node* node = reinterpret_cast(startPtr + (i * m_blockSize)); + node->next = m_freeList; + m_freeList = node; } - - assert(rawMemory); - AllocHeader* allocHeader = reinterpret_cast(rawMemory); - allocHeader->allocationSize = potSize; - - return reinterpret_cast(rawMemory) + sizeof(AllocHeader); -} - -int POTSlabAllocator::getPoolIndexForSize(size_t potSize) const -{ - // log2(x) - 4 is array index - // POT gives us O(1) complexity making this allocator super fast - // since std::bit_width gives us log2(x) + 1, we need to subtract additional 1 - // https://en.cppreference.com/w/cpp/numeric/bit_width.html - const int poolIndex = std::bit_width(potSize) - 5; - if (poolIndex > POOL_COUNT - 1) - return -1; - - return poolIndex; -} - -void POTSlabAllocator::free(void* ptr) -{ - const AllocHeader* header = reinterpret_cast(ptr); - const int poolIndex = getPoolIndexForSize(header->allocationSize); - - if (poolIndex >= 0) - m_pools[poolIndex].push(ptr); - else - sngl::platform::memory::Release(ptr); -} - -void* POTSlabAllocator::requestPage() -{ - uint8_t* currentPtr = static_cast(m_reservedPtr) + m_commitedSize; - uint8_t* newPtr = currentPtr + m_pageSize; - if (!sngl::platform::memory::Commit(newPtr, m_pageSize)) - throw std::runtime_error("POTSlabAllocator: Failed to commit memory."); - - m_commitedSize += m_pageSize; - return newPtr; } \ No newline at end of file diff --git a/Engine/src/Core/POTSlabAllocator.h b/Engine/src/Core/POTSlabAllocator.h index fd140ee..a25e778 100644 --- a/Engine/src/Core/POTSlabAllocator.h +++ b/Engine/src/Core/POTSlabAllocator.h @@ -1,55 +1,171 @@ +// Copyright 2026 Singularity Engine +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #ifndef __SNGL_CORE_POTSLABALLOCATOR_H_INCLUDED__ #define __SNGL_CORE_POTSLABALLOCATOR_H_INCLUDED__ #include #include +#include +#include +#include + +#include namespace sngl::core { + class FixedSizeBlock + { + private: + struct Node { Node* next; }; + Node* m_freeList; + size_t m_blockSize; + size_t m_pageSize; + + public: + FixedSizeBlock(); + + void init(size_t blockSize); + + void* pop(); + void push(void* ptr); + void supplyNewMemory(void* ptr, size_t memSize); + + inline size_t getSize() const { return m_blockSize; } + }; + + template class POTSlabAllocator { private: - class FixedSizePool + static constexpr size_t getBlockSize(size_t arrIx) + { + return (1ull << (arrIx + 4)); + } + + static constexpr int getBlockIxFromSize(size_t blockSize) { - private: - struct Node { Node* next; }; - Node* m_freeList = nullptr; - size_t m_blockSize; + int result = math::ceil_log2(blockSize) - 5; + if (result > MAX_BLOCK_COUNT) + return -1; + + return result; + } - public: - void init(size_t blockSize); - void supplyNewPage(void* rawMemory, size_t pageSize); + static_assert(math::isPOT(reservationSize), "Reservation size must be a power of 2"); + static constexpr size_t MIN_CELL_SIZE = 16ull; + static constexpr size_t MAX_BLOCK_COUNT = 16ull; + static constexpr size_t MAX_EFFECTIVE_ALLOCATION = getBlockSize(MAX_BLOCK_COUNT - 1); - void* pop(); - void push(void* ptr); - }; + FixedSizeBlock m_blocks[MAX_BLOCK_COUNT]; + + bool m_initialized = false; + void* m_reservedMemory = nullptr; + size_t m_currentOffset = 0; + size_t m_pageSize = 0; struct AllocHeader { + static constexpr uint64_t MAGIC_VALUE = std::bit_cast("POTSLAB"); + uint64_t magicValue; size_t allocationSize; }; - private: - static constexpr size_t POOL_COUNT = 16; - static constexpr size_t MIN_POOL_SIZE = 16; + public: + ~POTSlabAllocator() + { + sngl::platform::memory::Release(m_reservedMemory); + } - FixedSizePool m_pools[POOL_COUNT]; + void init() + { + assert(!m_initialized); // You can't initialize an allocator twice + m_pageSize = sngl::platform::GetPageSize(); + m_reservedMemory = sngl::platform::memory::Reserve(reservationSize); + if (!m_reservedMemory) + throw std::runtime_error("POTSlabAllocator: Failed to reserve memory for allocations"); - void* m_reservedPtr; - size_t m_reservedSize; - size_t m_commitedSize; - size_t m_pageSize; + for (size_t i = 0; i < MAX_BLOCK_COUNT; i++) + m_blocks[i].init(getBlockSize(i)); - public: - POTSlabAllocator(size_t reservationSize); - ~POTSlabAllocator(); + m_initialized = true; + } - void* allocate(size_t size); - void free(void* ptr); + void* allocate(size_t size) + { + assert(m_initialized); // Using an uninitialized allocator + const size_t potSize = std::max(MIN_CELL_SIZE, std::bit_ceil(size + sizeof(AllocHeader))); + const int blockIx = getBlockIxFromSize(potSize); + void* memPtr = nullptr; - private: - void* requestPage(); - int getPoolIndexForSize(size_t potSize) const; + if (blockIx >= 0) + { + auto& block = m_blocks[blockIx]; + memPtr = block.pop(); + + if (!memPtr) + { + uint8_t* currentMem = static_cast(m_reservedMemory) + m_currentOffset; + + const size_t blockSize = block.getSize(); + size_t commitSize = m_pageSize; + if (blockSize > m_pageSize) + commitSize = 4 * blockSize; + + if (!sngl::platform::memory::Commit(currentMem, commitSize)) + throw std::runtime_error("POTSlabAllocator: Failed to commit new memory"); + + block.supplyNewMemory(currentMem, commitSize); + memPtr = block.pop(); + m_currentOffset += commitSize; + } + } + else + { + // FALLBACK + // if we can't allocate in the pool + // we just allocate memory almost like malloc does + memPtr = sngl::platform::memory::Reserve(potSize); + if (!memPtr) + throw std::runtime_error("POTSlabAllocator: Failed to reserve fallback memory"); + + if (!sngl::platform::memory::Commit(memPtr, potSize)) + throw std::runtime_error("POTSlabAllocator: Failed to commit fallback memory"); + } + + AllocHeader* header = static_cast(memPtr); + header->magicValue = AllocHeader::MAGIC_VALUE; + header->allocationSize = potSize; + + return reinterpret_cast(memPtr) + sizeof(AllocHeader); + } + + void free(void* ptr) + { + AllocHeader* allocHeader = reinterpret_cast( + static_cast(ptr) - sizeof(AllocHeader) + ); + + assert(allocHeader->magicValue == AllocHeader::MAGIC_VALUE); // Wrong memory pointer used + const int blockIx = getBlockIxFromSize(allocHeader->allocationSize); + if (blockIx < 0) + sngl::platform::memory::Release(allocHeader); + else + m_blocks->push(allocHeader); + } + + static constexpr size_t getMaxEffectiveAllocSize() { return MAX_EFFECTIVE_ALLOCATION; } }; } diff --git a/Engine/src/Graphics/Instance.cpp b/Engine/src/Graphics/Instance.cpp index 9ff7567..420918d 100644 --- a/Engine/src/Graphics/Instance.cpp +++ b/Engine/src/Graphics/Instance.cpp @@ -1,3 +1,17 @@ +// Copyright 2026 Singularity Engine +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include "Vulkan/VulkanInstance.h" diff --git a/Engine/src/Graphics/Vulkan/VulkanDevice.cpp b/Engine/src/Graphics/Vulkan/VulkanDevice.cpp index 3a7c3c6..b36de8a 100644 --- a/Engine/src/Graphics/Vulkan/VulkanDevice.cpp +++ b/Engine/src/Graphics/Vulkan/VulkanDevice.cpp @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/src/Graphics/Vulkan/VulkanDevice.h b/Engine/src/Graphics/Vulkan/VulkanDevice.h index b9101d8..ef3fcd7 100644 --- a/Engine/src/Graphics/Vulkan/VulkanDevice.h +++ b/Engine/src/Graphics/Vulkan/VulkanDevice.h @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/src/Graphics/Vulkan/VulkanInstance.cpp b/Engine/src/Graphics/Vulkan/VulkanInstance.cpp index d6fac2b..e15f6c0 100644 --- a/Engine/src/Graphics/Vulkan/VulkanInstance.cpp +++ b/Engine/src/Graphics/Vulkan/VulkanInstance.cpp @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/src/Graphics/Vulkan/VulkanInstance.h b/Engine/src/Graphics/Vulkan/VulkanInstance.h index 4b2cc36..4667bc6 100644 --- a/Engine/src/Graphics/Vulkan/VulkanInstance.h +++ b/Engine/src/Graphics/Vulkan/VulkanInstance.h @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/src/Platform/OS.h b/Engine/src/Platform/OS.h index d317e6c..2ee89c1 100644 --- a/Engine/src/Platform/OS.h +++ b/Engine/src/Platform/OS.h @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/src/Platform/OS_win32.cpp b/Engine/src/Platform/OS_win32.cpp index 6f0116c..47138a1 100644 --- a/Engine/src/Platform/OS_win32.cpp +++ b/Engine/src/Platform/OS_win32.cpp @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/Engine/src/Platform/SDLWindow.cpp b/Engine/src/Platform/SDLWindow.cpp index 2baf0c3..06c8bcb 100644 --- a/Engine/src/Platform/SDLWindow.cpp +++ b/Engine/src/Platform/SDLWindow.cpp @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c7b6a15 --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +# Singularity Engine +## A lightweight, code driven 3D game engine built for performance + +Singularity Engine is a minimalist game engine designed for people who prefer writing code +over clicking over menus. It prioritizes low-overhead, platform agnosticism, fast compilation and straightforward API. +The engine embraces the verbosity of the newest graphics APIs (Vulkan, D3D12) to deliver performance tuned display system. + +> [!IMPORTANT] +> This project is in very early development state (Alpha). It's not functional yet. +> The API may go through fundamental changes and core features are still being implemented. + +# 🚀 Key Features +- Editor-less Workflow: Build your entire game in your IDE of choice. You don't need to worry about installing ton of heavy SDKs. +- High performance: Minimal abstraction for maximum frame rates. +- Platform agnostic: Support for Windows, Linux and MacOS + +> [!WARNING] +> Abstractions for Linux and MacOS aren't implemented yet, but they will be soon. + +# 🛠 Gettning Started +## Prerequisities +List of what you need to compile and run the engine +- A compiler capable of compiling C++20 +- CMake +- VulkanSDK (only if taking part in engine development around Vulkan API) + +> [!NOTE] +> Please note, that the list of prerequisities may change in the future due to the engine's early state of development. + +## Quick start +``` +# Clone the repository +git clone https://github.com/SingularityEngineDevelopers/SingularityEngine.git + +# Build the engine +cd SingularityEngine +cmake --preset vulkan-release . +cmake --build --preset build-vulkan-release . +``` + +# 🗺 Current Status & Roadmap +- [ ] Custom memory allocators (in progress) +- [ ] 3D Rendering +- [ ] Editor interface (long term goal) + +> [!IMPORTANT] +> Current roadmap contains only several entries now. More of them are going to be added +> in the future as more ideas would come. + +# 🤝 Contributions +I'm aiming to make this engine one of the fastest indie game engines available. If you'd like to help +in development or bug fixes, feel free to open a pull request! +1. Fork the project +2. Create a branch +3. Commit +4. Open a Pull Request + +# ⚖️ License +This project is licensed under Apache License, version 2.0. See the [LICENSE.md](/LICENSE.md) file for details. + +# 📜 Credits +## Open-Source projects +- [SDL3](https://github.com/libsdl-org/SDL): Used for window management and input handling +- [volk](https://github.com/zeux/volk): meta loader for Vulkan to ease development \ No newline at end of file diff --git a/Sandbox/CMakeLists.txt b/Sandbox/CMakeLists.txt index c584b02..42ef297 100644 --- a/Sandbox/CMakeLists.txt +++ b/Sandbox/CMakeLists.txt @@ -1,3 +1,17 @@ +# Copyright 2026 Singularity Engine +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + add_executable(Singularity_SandboxApp "main.cpp") target_link_libraries( Singularity_SandboxApp diff --git a/Sandbox/main.cpp b/Sandbox/main.cpp index 5236a51..cdb2ba9 100644 --- a/Sandbox/main.cpp +++ b/Sandbox/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2026 Tesseract Interactive +// Copyright 2026 Singularity Engine // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License.