From 0f721f57eaa95a750b698747a9c8d24b2810d7fa Mon Sep 17 00:00:00 2001 From: Medusa Slockbower Date: Tue, 5 Aug 2025 16:14:00 -0400 Subject: [PATCH] - Moved OpenGL library wrapper into platform - Finished reorganizing PLANNING.md --- CMakeLists.txt | 3 +- cmake/opengl.cmake | 9 +- doxy/Doxyfile | 2 +- .../opengl/lib/buffer.h | 0 .../{renderers => platform}/opengl/lib/enum.h | 0 .../{renderers => platform}/opengl/lib/fwd.h | 0 .../opengl/lib/texture.h | 0 .../opengl/lib/vertex_array.h | 0 include/fennec/renderers/interface/renderer.h | 188 ----- include/fennec/renderers/opengl/fallback.h | 38 - include/fennec/renderers/opengl/modern.h | 38 - planning/2D_GRAPHICS.md | 64 ++ planning/3D_GRAPHICS.md | 211 +++++ planning/3D_PHYSICS.md | 48 ++ planning/ARTIFICIAL_INTELLIGENCE.md | 29 + planning/CONTAINERS.md | 42 +- planning/CONTENTS.md | 19 +- planning/CPP_LANGUAGE.md | 4 +- planning/ENGINE.md | 131 +++ planning/LANGUAGE_PROCESSING.md | 248 ++++++ planning/MEMORY.md | 4 +- planning/PLANNING.md | 761 ------------------ 22 files changed, 794 insertions(+), 1045 deletions(-) rename include/fennec/{renderers => platform}/opengl/lib/buffer.h (100%) rename include/fennec/{renderers => platform}/opengl/lib/enum.h (100%) rename include/fennec/{renderers => platform}/opengl/lib/fwd.h (100%) rename include/fennec/{renderers => platform}/opengl/lib/texture.h (100%) rename include/fennec/{renderers => platform}/opengl/lib/vertex_array.h (100%) delete mode 100644 include/fennec/renderers/interface/renderer.h delete mode 100644 include/fennec/renderers/opengl/fallback.h delete mode 100644 include/fennec/renderers/opengl/modern.h create mode 100644 planning/2D_GRAPHICS.md create mode 100644 planning/3D_GRAPHICS.md create mode 100644 planning/3D_PHYSICS.md create mode 100644 planning/ARTIFICIAL_INTELLIGENCE.md create mode 100644 planning/ENGINE.md create mode 100644 planning/LANGUAGE_PROCESSING.md delete mode 100644 planning/PLANNING.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ddc076..ee8014d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,7 @@ add_library(fennec STATIC include/fennec/containers/map.h include/fennec/containers/optional.h include/fennec/containers/pair.h + include/fennec/containers/rdtree.h include/fennec/containers/set.h include/fennec/containers/tuple.h @@ -192,8 +193,6 @@ add_library(fennec STATIC # EXTRA SOURCES ======================================================================================================== ${FENNEC_EXTRA_SOURCES} - include/fennec/renderers/interface/renderer.h - include/fennec/containers/rdtree.h include/fennec/scene/scene.h include/fennec/scene/component.h include/fennec/core/system.h diff --git a/cmake/opengl.cmake b/cmake/opengl.cmake index 38e1eb0..f6fded0 100644 --- a/cmake/opengl.cmake +++ b/cmake/opengl.cmake @@ -39,12 +39,9 @@ if(FENNEC_GRAPHICS_WANT_EGL) list(APPEND FENNEC_LINK_LIBRARIES OpenGL::EGL) list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_EGL=1) list(APPEND FENNEC_EXTRA_SOURCES - include/fennec/renderers/opengl/lib/fwd.h - include/fennec/renderers/opengl/lib/enum.h - include/fennec/renderers/opengl/lib/buffer.h - - include/fennec/renderers/opengl/modern.h - include/fennec/renderers/opengl/fallback.h + include/fennec/platform/opengl/lib/fwd.h + include/fennec/platform/opengl/lib/enum.h + include/fennec/platform/opengl/lib/buffer.h include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp ) diff --git a/doxy/Doxyfile b/doxy/Doxyfile index 26d134c..df913ab 100644 --- a/doxy/Doxyfile +++ b/doxy/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = fennec # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = 1.0.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/include/fennec/renderers/opengl/lib/buffer.h b/include/fennec/platform/opengl/lib/buffer.h similarity index 100% rename from include/fennec/renderers/opengl/lib/buffer.h rename to include/fennec/platform/opengl/lib/buffer.h diff --git a/include/fennec/renderers/opengl/lib/enum.h b/include/fennec/platform/opengl/lib/enum.h similarity index 100% rename from include/fennec/renderers/opengl/lib/enum.h rename to include/fennec/platform/opengl/lib/enum.h diff --git a/include/fennec/renderers/opengl/lib/fwd.h b/include/fennec/platform/opengl/lib/fwd.h similarity index 100% rename from include/fennec/renderers/opengl/lib/fwd.h rename to include/fennec/platform/opengl/lib/fwd.h diff --git a/include/fennec/renderers/opengl/lib/texture.h b/include/fennec/platform/opengl/lib/texture.h similarity index 100% rename from include/fennec/renderers/opengl/lib/texture.h rename to include/fennec/platform/opengl/lib/texture.h diff --git a/include/fennec/renderers/opengl/lib/vertex_array.h b/include/fennec/platform/opengl/lib/vertex_array.h similarity index 100% rename from include/fennec/renderers/opengl/lib/vertex_array.h rename to include/fennec/platform/opengl/lib/vertex_array.h diff --git a/include/fennec/renderers/interface/renderer.h b/include/fennec/renderers/interface/renderer.h deleted file mode 100644 index 20ff169..0000000 --- a/include/fennec/renderers/interface/renderer.h +++ /dev/null @@ -1,188 +0,0 @@ -// ===================================================================================================================== -// fennec, a free and open source game engine -// Copyright © 2025 Medusa Slockbower -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ===================================================================================================================== - -#ifndef FENNEC_RENDERERS_INTERFACE_RENDERER_H -#define FENNEC_RENDERERS_INTERFACE_RENDERER_H - -#include -#include -#include -#include -#include -#include - -/* - * Some ramblings on deciding what objects are needed to support the features in PLANNING.md - * - * - * Definitions: - * Static Mesh -> A mesh whose number of vertices and attributes does not change after creation - * Object -> A static mesh instance - * Skeletal Mesh -> A static mesh with support for skinned rigs - * Animation -> A set of keys for a skeletal mesh - * Puppet -> A skeletal mesh instance - * Static Object -> An object whose transform does not change after scene start - * Dynamic Object -> An object whose transform can change after scene start, all puppets must be dynamic objects - * Static Light -> A light whose transform does not change after scene start. Other attributes may change, which will - * be specified per light - * Dynamic Light -> A light whose transform can change after scene start, including all attributes - * - * Static mesh rendering - * Skeletal mesh rendering - * Lights with or without shadows (PCSS for soft shadowing) - * - Sun Light - * - Skybox - * - Point Light - * - Spotlight - * - Area light - * Post-Processing - * - * Materials - */ - -namespace fennec -{ - -class renderer3d { -public: - // These refer to assets - // texture -> 8-bit type, 24-bit id (256, 16,777,216) - // mesh -> 32-bit id (4,294,967,296) - // skeleton -> 32-bit id (4,294,967,296) - // animation -> 32-bit id (4,294,967,296) - // shader -> 32-bit id (4,294,967,296) - - // model -> 8-bit flag, 24-bit id (8, 16,777,216) - // puppet -> 32-bit id (4,294,967,296) - // light -> 8-bit type, 24-bit id (256, 16,777,216) - // material -> 32-bit id (4,294,967,296) - -// TYPEDEFS & CONSTANTS ================================================================================================ - - using uid_t = uint32_t; - - static constexpr uid_t null = -1; - static constexpr uint_t max_bone_weights = 8; - - -// ENUMS =============================================================================================================== - - enum format_ : uint8_t { - format_r = 0, - format_rg, - format_rgb, - format_rgba, - format_shadow, // TODO: decide whether end-users may create shadow buffers - - format_count, - format_last = format_count - 1, - }; - - enum texture_ : uint8_t { - texture_2d = 0, - texture_3d, - texture_cubemap, - }; - - enum light_ : uint8_t { - light_sun = 0, - light_sky, - light_point, - light_spot, - light_area, - }; - - enum iterp_ : uint8_t { - iterp_step = 0, - iterp_linear, - iterp_spherical, - iterp_cubic, - }; - - -// STRUCTURES ========================================================================================================== - - struct mesh_vertex { - vec3 location; - vec3 normal; - vec3 tangent; - vec2 uv; - }; - - struct skin_vertex { - vec3 location; - vec3 normal; - vec3 tangent; - vec2 uv; - - uint32_t bones[max_bone_weights]; - uint32_t weights[max_bone_weights]; - }; - - struct bone { - mat4 localSpace; // I was going to use quaternions, but Assimp, glTF, FBX, Unity, Unreal, and Godot all use matrices - }; - - struct skeleton { - mat4 root; - uint boneStart, boneEnd; // APIs job to figure out how to store bones, should be in a SSBO regardless of API - }; - - // Wrapper for animation keys - template - struct key { - double time; - ValueT val; - uint8_t mode; - }; - - // Wrapper for a track, essentially the keyframes for a single bone - struct track { - uint posStart, posEnd; // APIs job to figure out how to store keys, should be in a SSBO regardless of API - uint rotStart, rotEnd; - uint sclStart, sclEnd; - }; - - struct animation { - uint trkStart, trkEnd; // APIs job to figure out how to store tracks, should be in a SSBO regardless of API - }; - - -// FUNCTIONS =========================================================================================================== - - virtual uid_t create_mesh(const dynarray& indices, const dynarray& vertices) = 0; - virtual void release_mesh(uid_t id); - - // TODO: virtual uid_t create_skeleton() - // TODO: virtual uid_t create_shader() - - virtual uid_t create_texture(uint8_t type, uint8_t format, bool hdr) = 0; - virtual void release_texture(uid_t); - - - - // TODO: virtual uid_t create_light() - - virtual ~renderer3d() = default; -private: -}; - - -} - -#endif // FENNEC_RENDERERS_INTERFACE_RENDERER_H diff --git a/include/fennec/renderers/opengl/fallback.h b/include/fennec/renderers/opengl/fallback.h deleted file mode 100644 index fcd6f0d..0000000 --- a/include/fennec/renderers/opengl/fallback.h +++ /dev/null @@ -1,38 +0,0 @@ -// ===================================================================================================================== -// fennec, a free and open source game engine -// Copyright © 2025 Medusa Slockbower -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ===================================================================================================================== - -#ifndef FENNEC_RENDERERS_OPENGL_FALLBACK_H -#define FENNEC_RENDERERS_OPENGL_FALLBACK_H - -/* - * This should be implemented using the OpenGL ES 3.2 profile - * https://registry.khronos.org/OpenGL/specs/es/3.2/es_spec_3.2.pdf - * - * Requires the following: -* OpenGL ES 3.2 / OpenGL 4.3 OR - * - ARB_compute_shader - * - ARB_shader_image_load_store - * - ARB_shader_storage_buffer_object - * - ARB_texture_cube_map_array - * - ARB_texture_storage - * - EXT_texture_array - * - * This will support all mobile devices since 2012 - */ - -#endif // FENNEC_RENDERERS_OPENGL_FALLBACK_H diff --git a/include/fennec/renderers/opengl/modern.h b/include/fennec/renderers/opengl/modern.h deleted file mode 100644 index 9d23899..0000000 --- a/include/fennec/renderers/opengl/modern.h +++ /dev/null @@ -1,38 +0,0 @@ -// ===================================================================================================================== -// fennec, a free and open source game engine -// Copyright © 2025 Medusa Slockbower -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// ===================================================================================================================== - -#ifndef FENNEC_RENDERERS_OPENGL_MODERN_H -#define FENNEC_RENDERERS_OPENGL_MODERN_H - -/* - * - * Requires the following: - * OpenGL 4.6 OR - * - ARB_buffer_storage - * - ARB_compute_shader - * - ARB_multi_draw_indirect - * - ARB_shader_draw_parameters - * - ARB_shader_image_load_store - * - ARB_texture_cube_map_array - * - ARB_texture_storage - * - EXT_texture_array - * - * This will support >91.31% of devices on Steam, including all Desktop GPUs and iGPUs since 2012 - */ - -#endif // FENNEC_RENDERERS_OPENGL_MODERN_H diff --git a/planning/2D_GRAPHICS.md b/planning/2D_GRAPHICS.md new file mode 100644 index 0000000..f8aee36 --- /dev/null +++ b/planning/2D_GRAPHICS.md @@ -0,0 +1,64 @@ + +# 2D Graphics (`gfx2d`) + +## Table of Contents + + +* [Home](./CONTENTS.md#planning-documentation-for-fennec) +* [2D Graphics (`gfx2d`)](#2d-graphics-gfx2d) + * [Table of Contents](#table-of-contents) + * [Introduction](#introduction) + * [Structures (`gfx2d`)](#structures-gfx2d) + + + +## Introduction + +  This system handles the rendering of 2D meshes and textures. + +Links: +- https://en.wikipedia.org/wiki/Quadtree +- https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-25-rendering-vector-art-gpu + + +### Structures (`gfx2d`) + +For the 2d rendering framework, Materials need to be rendered independently because we have +no size constraints for images. This disallows us from using a meta-shader like in +the 3d rendering framework. + +```c++ +struct Object +{ + vec2 location, scale; // A matrix would be 36 bytes, this is instead 20 bytes + float rotation; +} +``` + +- BVH + - Quadtree + - Leaf Size and Tree Depth should be calculated by the scene, constraints are as follows: + - Min Object Size + - Max Object Size + - Scene Center + - Scene Edge + - Insertions and Updates are done on the CPU + - Nodes + - Start Index 32-bits + - Object Count 32-bits + - Objects + - Buffer of Object IDs grouped by Octree Node + - Culling + - Starting at each Octree Leaf, traverse upwards. + - Insert Visible Leaf IDs + - Track using atomic buffer + - Generate the Command Buffer for Culled Meshes from the Visible Leaf Buffer + - Count Materials + - Count Meshes per Material + - Generate the Culled Object Buffer by copying objects from the Object Buffer + - Adjust Buffer Size using the counts + - Insert using another atomic buffer + +- Translucent objects will be sorted. We can cheat by using a z-index instead of a z-coordinate. + This will allow us to sort objects as they are created. We can still bulk render each z-index, + with meshes and objects being grouped by material. \ No newline at end of file diff --git a/planning/3D_GRAPHICS.md b/planning/3D_GRAPHICS.md new file mode 100644 index 0000000..48c111b --- /dev/null +++ b/planning/3D_GRAPHICS.md @@ -0,0 +1,211 @@ + +# 3D Graphics (`gfx3d`) + +## Table of Contents + + +* [Home](./CONTENTS.md#planning-documentation-for-fennec) +* [3D Graphics (`gfx3d`)](#3d-graphics-gfx3d) + * [Table of Contents](#table-of-contents) + * [Introduction](#introduction) + * [Structures](#structures) + * [Stages](#stages) + + + +## Introduction + +  This system handles the rendering of 3D meshes, materials, lights, and post-processing +effects. +**DirectX will never have official support.** +If you would like to make a fork, have at it, but know that I will hold a deep disdain for you. + +The graphics pipeline will have a buffer with a list of objects and their rendering data. +This will be referred to as the Object Buffer. There will be two, for both the Deferred and Forward Passes. + +The buffers will be optimized by scene prediction. +This involves tracking the meshes and textures directly and indirectly used by a scene. +A callback function in the graphics system for scene loading can do this. + + +Materials and Lighting models will be run via a shader metaprogram to make the pipeline independent of this aspect. +This allows the GPU to draw every single deferred rendered mesh in a single draw call for each stage of the renderer. + +Specifications for debugging views via early breaks are included in the stages. + + +Links: +- https://en.wikipedia.org/wiki/Octree +- https://www.adriancourreges.com/blog/2015/11/02/gta-v-graphics-study/ +- https://learnopengl.com/PBR/Lighting +- https://learnopengl.com/PBR/IBL/Diffuse-irradiance +- https://en.wikipedia.org/wiki/Schlick%27s_approximation +- https://pixelandpoly.com/ior.html +- https://developer.download.nvidia.com/SDK/10/opengl/screenshots/samples/dual_depth_peeling.html + + + + +## Structures + +Object Structure. The mesh is implicit data. + +```c++ +struct Object +{ + vec3 location, scale; // A matrix would be 64 bytes, this is instead 28 bytes + quat rotation; + uint32 material, lighting; +} +``` + +Textures for 3D rendering are stored in various buffers with sizes of powers of 2. +Ratios of `1:1` and `2:1` are allowed. The `2:1` ratio is specifically for spherical and cylindrical projection. +UVs may be transformed to use a `2:1` as if it were `1:2`. +Cubemaps and 3D textures may only be `1:1`, I would be concerned if you are using any other ratio. + +- 8-Bit R Texture `4096, 2048, 1024, 512` (8) +- 8-Bit RG Texture `4096, 2048, 1024, 512` (8) +- 8-Bit RGB Texture `4096, 2048, 1024, 512` (8) +- 8-Bit RGBA Texture `4096, 2048, 1024, 512` (8) +- 8-Bit R Cubemap `1024, 512, 256, 128` (4) +- 8-Bit RGB Cubemap `1024, 512, 256, 128` (4) + +* 16-Bit HDR R Texture `4096, 2048, 1024, 512` (8) +* 16-Bit HDR RGB Texture `4096, 2048, 1024, 512` (8) +* 16-Bit HDR RGBA Texture `4096, 2048, 1024, 512` (8) +* 16-Bit HDR R Cubemap `1024, 512, 256, 128` (4) +* 16-Bit HDR RGB Cubemap `1024, 512, 256, 128` (4) + +- 16-Bit Shadow Texture `4096, 2048, 1024, 512` (8) +- 16-Bit Shadow Cubemap `2048, 1024, 512, 256` (4) + +* 8-Bit 3D R Texture `256, 128, 64, 32` (4) +* 8-Bit 3D RGB Texture `256, 128, 64, 32` (4) +* 16-Bit 3D HDR R Texture `256, 128, 64, 32` (4) +* 16-Bit 3D HDR RGB Texture `256, 128, 64, 32` (4) + +Documentation should provide guidelines on categories of Art Assets and the resolution of textures to use. + +Textures are identified by a 32-bit integer. +- `8 bits` → the texture buffer +- `24 bits` → the layer in the buffer + +Artists should be informed on the texture structure of the engine and its limitations. +However, these principles should be followed in other game engines as these are +guided by what is most efficient for typical GPU hardware. + + +Materials are, for the most part, user-defined. Documentation should make the user aware of this. +Material buffers will be a sequence of the Material Struct instances. +They will at the very least contain the id of their shader. + +Types of materials: +- Surface (Vertex & Fragment) + - Opaque / Masked + - Translucent (Forward) +- Volume (Path Traced Volumetrics / Forward) +- Light (Lighting Model) +- Post-Process + + + +## Stages + +This is the set of stages for the graphics pipeline that runs every frame: +Unless otherwise specified, each stage will be run on the GPU. + +- BVH + - Octree `(8 Bpn, 64 bpn) [6-Layers ≈ 2.1MB]` + - Leaf Size and Tree Depth should be calculated by the scene, constraints are as follows: + - Min Object Size + - Max Object Size + - Scene Center + - Scene Edge + - Buffer has implicit locations due to the tree having 8 children. + - Insertions and Updates are done on the CPU + - Nodes + - Start Index `int32` + - Object Count `int32` + - Objects + - Buffer of Object IDs grouped by Octree Node + - Leaf Culling + - Starting at each Octree Leaf, traverse upwards. + - Insert Visible Leaf IDs + - Track using atomic buffer + - Generate the Command Buffer for Culled Mesh LODs from the Visible Leaf Buffer + - Track counts using atomic buffers + - To avoid double counting due to the construction of the Octree output, we have some options + - Ignore Leaf Instances based on occurrences of the mesh in the surrounding 8 Quadtree Leaves. This would require + a bias towards a specific corner of the filter. + - Perform a preprocessing step on the CPU to erase duplicate elements and fix the buffer continuity. + - Let the duplicates be rendered. + - Generate the Culled Object Buffer with the respective object IDs + - Adjust Buffer Size using the counts + - Insert by reusing the count buffer, clipped to only contain used meshes + +Debug View: Object ID, Mesh ID, LOD + +- Visibility + - Buffer `(15 Bpp, 120 bpp) [1920x1080] ≈ 39.4MB` + - Depth Buffer → `D24` + - Visibility Info → `RGB32I` + - R = Object ID + - G = Mesh ID + - B = Material ID + - Regenerate the Command Buffer for Visible Mesh LODs + - Regenerate the Culled Object Buffer + +Debug View: Visibility Buffer + +* G-Buffer Pass `(17 Bpp, 136 bpp) [1920x1080] ≈ 35.3MB` + * Depth - Stencil → `D24_S8` + * S → used to represent the lighting model. + * Diffuse → `RGBA8` + * A → Ambient Occlusion + * Emission → `RGB8` + * Normal → `RGB8` + * Specular → `RGB8` + * R → Roughness + * G → Specularity (sometimes called the Metallicness) + * B → Index of Refraction (IOR) + +Debug View: Depth, Stencil, Diffuse, Emission, Normal, Specularity + +- Generate Dynamic Shadows +- Generate Dynamic Reflections (Optional) +- SSAO (Optional) +- Deferred Lighting Pass `(10 Bpp, 80 bpp) [1920x1080] ≈ 2 x 16.3MB + 8.3MB ≈ 24.6MB` + - Depth Buffer → `D24` + - Lighting Buffer → `RGB16` w/ Mipmapping + - Stencil Buffer $rarr; `S8` + - Apply Lighting Model + +Debug View: Shadows, Reflections, SSAO, Deferred Lighting + +We can combine all of these into one framebuffer: + +- Depth - Stencil → `D24_S8` +- Visibility Info → `RGB32I` +- Diffuse → `RGBA8` +- Emission → `RGB8` +- Normal → `RGB8` +- Specular → `RGB8` +- Lighting Buffer → `RGB16` w/ Mipmapping +- One more slot left open for another + +* Forward Pass + * BVH, Same as Above + * LOD Selection, Same as Above + * Translucent Materials + * Dual Depth Peeling + +Debug View: Forward Mask + +- Post Processing + - Depth of Field (Optional) + - When enabled, the Visiblity Buffer, G-Buffer, and Deferred Lighting Pass will be double layered. + - At this point the Lighting Buffers will be Flattened + - Bloom (Optional) → Mipmap Blurring `(6Bpp, 48bpp) [1920x1080] ≈ 16.3MB` + - Tonemapping (Optional) + - HDR Correction diff --git a/planning/3D_PHYSICS.md b/planning/3D_PHYSICS.md new file mode 100644 index 0000000..79e28f1 --- /dev/null +++ b/planning/3D_PHYSICS.md @@ -0,0 +1,48 @@ + +# 3D Physics (`physics3d`) + +## Table of Contents + + +* [Home](./CONTENTS.md#planning-documentation-for-fennec) +* [3D Physics (`physics3d`)](#3d-physics-physics3d) + * [Table of Contents](#table-of-contents) + * [Introduction](#introduction) + * [System Layout](#system-layout) + + + +## Introduction + +  This system will handle newtonian physics for 3D rigid and soft-bodies. This should include +articulated skeletal systems, particle physics, and soft-body physics. The following soft-body systems +will be supported with the associated implementation; elastics with finite element simulation, cloth +physics with position-based dynamics, oceans with iWave, 3D fluid dynamics with smoothed-particle +hydrodynamics, 2D surface fluid dynamics with force-based dynamics. + + +## System Layout + +* Rigid Body Physics + * Newtonian Physics and Collision Resolution + * Articulated Skeletal Systems + * Inverse Kinematics + * Stiff Rods +- Particle Physics +* Soft Body Physics + * Elastics → Finite Element Simulation + * Cloth → Position-Based Dynamics + * Water + * Oceans → iWave + * Reasoning: iWave provides interactive lightweight fluid dynamics suitable for flat planes of water. +

+ + * 3D Fluid Dynamics → Smoothed-Particle Hydrodynamics + * Reasoning: This is the simplest method for simulating 3D bodies of water. This should exclusively be + used for small scale simulations where self-interactive fluids are necessary. I.E. pouring water into + a glass. +

+ + * 2D Surface Fluid Dynamics → Force-Based Dynamics + * Reasoning: This model, like iWave, provides lightweight interactive fluid dynamics, but is more easily + adapted to flowing surfaces such as streams and rivers. \ No newline at end of file diff --git a/planning/ARTIFICIAL_INTELLIGENCE.md b/planning/ARTIFICIAL_INTELLIGENCE.md new file mode 100644 index 0000000..da90348 --- /dev/null +++ b/planning/ARTIFICIAL_INTELLIGENCE.md @@ -0,0 +1,29 @@ + +# Artifical Intelligence (`ai`) + +## Table of Contents + + + + +## Introduction + +  This system implements pathing and decision systems for general-purpose traditional +artifical intelligence algorithms. This library will not support Machine-Learning Artificial +Intelligence (ML/AI). This artificial intelligence method only differs in static generation +between 2D and 3D. The solvers are dimension independent since they work on a graph. + + +## General Process + +### Static +- generate a static navigation graph (sometimes called a NavMesh) + + +### Tick +* resolve dynamic blockers +* update paths using dijkstra's algorithm +* apply rigid-body forces with constraints + +The update loop for artificial intelligence should only update every `n` ticks. Where +`n <= k`, with `k` being the tick rate of the physics engine. diff --git a/planning/CONTAINERS.md b/planning/CONTAINERS.md index 071ea1b..3189d97 100644 --- a/planning/CONTAINERS.md +++ b/planning/CONTAINERS.md @@ -3,15 +3,53 @@ ## Table of Contents + +* [Home](./CONTENTS.md#planning-documentation-for-fennec) +* [Containers Library](#containers-library-containers) + * [Table of Contents](#table-of-contents) + * [Introduction](#introduction) + * [Implementation](#implementation) + * [C++ Standard Template Library](#c-standard-template-library) + * [fennec](#fennec) + + ## Introduction   This library contains headers and classes that implement common data -structures. The contents are restricted to the Containers Library of the C++ -Standard Library and Template Library. +structures. The contents include the Containers Library of the C++ Standard +Library and Template Library. ## Implementation +### C++ Standard Template Library +| Symbol | Implemented | Passed | +|:-------------------------------------|:-----------:|:------:| +| pair | ✔ | ✔ | +| tuple | ⭕ | ❌ | +| optional | ✔ | ✔ | +| variant | ❌ | ❌ | +| any | ❌ | ❌ | +| bitset | ❌ | ❌ | +| array | ✔ | ✔ | +| dynarray (`std::vector`) | ✔ | ✔ | +| list | ✔ | ✔ | +| set (`std::unordered_set`) | ✔ | ✔ | +| ordered_set (`std::set`) | ✔ | ✔ | +| map (`std::unordered_map`) | ✔ | ✔ | +| ordered_map (`std::map`) | ✔ | ✔ | +| multiset (`std::unordered_multiset`) | ✔ | ✔ | +| ordered_multiset (`std::multiset`) | ✔ | ✔ | +| multimap (`std::unordered_multimap`) | ✔ | ✔ | +| ordered_multimap (`std::multimap`) | ✔ | ✔ | + + +### fennec + +| Symbol | Implemented | Passed | +|:--------|:-----------:|:------:| +| graph | ✔ | ✔ | +| rd_tree | ✔ | ✔ | diff --git a/planning/CONTENTS.md b/planning/CONTENTS.md index 83ab7ce..2c3f79e 100644 --- a/planning/CONTENTS.md +++ b/planning/CONTENTS.md @@ -52,11 +52,20 @@ be achieved using events at different stages of those engines that are on-demand   Many subpages of these documents will contain tables that use symbols to denote implementation and testing progress. The symbols are defined below. -| Symbol | Meaning | -|:-------:|:------------------------| -| ✔ | Completed | -| ❓ | Partial | -| ❌ | Unimplemented / Failing | +| Symbol | Meaning | Notes | +|:------:|:------------------------|:----------------------------------------------------------| +| ✔ | Completed | Complete implementation and all tests passing. | +| ⭕ | Partial | Partial implementation and all tests implemented passing. | +| ❓ | Untested | Not tested | +| ❌ | Unimplemented / Failing | Not implemented or any test is failing. | + +| Implemented / Passed | ✔ | ⭕ | ❓ | ❌ | +|:--------------------:|--------------------------------------------------------------------|-------------------------------------------------------------------------------|---------|-----------------| +| ✔ | Implemented and Passing | Invalid | Invalid | Not Implemented | +| ⭕ | Implemented and Partial Testing with all implemented tests passing | Partial Implementation and Partial Testing with all implemented tests passing | Invalid | Not Implemented | +| ❓ | Implemented and Untested | Partial Implementation and Untested | Invalid | Not Implemented | +| ❌ | Implemented and Any Test is Failing | Partial Implementation and any test is Failing | Invalid | Not Implemented | + ## Libraries diff --git a/planning/CPP_LANGUAGE.md b/planning/CPP_LANGUAGE.md index 6cdd906..8e6f25c 100644 --- a/planning/CPP_LANGUAGE.md +++ b/planning/CPP_LANGUAGE.md @@ -5,7 +5,7 @@ * [Home](./CONTENTS.md#planning-documentation-for-fennec) -* [C++ Language Library (`lang`)](#c-language-library-lang) +* [C++ Language Library](#c-language-library-lang) * [Table of Contents](#table-of-contents) * [Introduction](#introduction) * [Implementation](#implementation) @@ -27,7 +27,7 @@ ## Introduction   This library contains headers and classes related to the C++ language. The -contents of this library are restricted to the Language Support, Diagnostics, and +contents of this library include the Language Support, Diagnostics, and Metaprogramming libraries of the C++ Standard Library and Template Library. See: diff --git a/planning/ENGINE.md b/planning/ENGINE.md new file mode 100644 index 0000000..0eb808c --- /dev/null +++ b/planning/ENGINE.md @@ -0,0 +1,131 @@ + +# fennec + +## Table of Contents + + +* [Home](./CONTENTS.md#planning-documentation-for-fennec) +* [fennec](#fennec) + * [Table of Contents](#table-of-contents) + * [Introduction](#introduction) + * [Systems](#systems) + * [Events](#events) + * [Scene](#scene) + * [Scripts](#scripts) + * [AI](#ai) + * [Physics](#physics) + * [Graphics](#graphics) + * [Audio](#audio) + * [Core Game Loop](#core-game-loop) + * [Tick](#tick) + * [Frame](#frame) + + + +## Introduction + +  This file outlines the core engine structure and all necessary systems for +the engine to run. + + +## Systems + +This section outlines core systems to the engine and brief overviews. + + +### Events + +  fennec will be largely event based, the system should be able to handle multiple +event types without having any type-specific code. There will be a few categories of events, +predominantly on-demand and delayed events. On-demand events are fired immediately, which is +useful for events related to graphics and audio. Delayed events are fired at the next tick or +after a certain period of time, this is useful for physics events which can't be handled +immediately without potentially harming the state of the physics engine. Events should be +optionally able to be handled with multithreading. + + +### Scene + +  The core structure of the engine and its levels will be a scene hierarchy. The hierarchy +will be implemented using a rooted-directed tree (rdtree, not to be confused with rbtree). +Each element in the tree will be a node with a name and some very basic flags. Component +dependent behaviour *must* be handled in systems to avoid the overhead of an object-oriented +scene hierarchy. This is predominantly caused by the recursive nature of parsing an object- +oriented scene hierarchy where each node records its children and updates them accordingly. + + +### Scripts + +  Scripts won't be handled the same way scripts are in other engines, they will be translated +as a system which will be data-oriented. This is to reduce the overhead of the object-oriented +approach in C++ while maintaining the appearance of being object-oriented. + + +### AI + +  AI will be a fairly multi-parted system as we need to handle different use-cases. +The first use case is characters that can "walk" and "jump" on surfaces. The second use-case +is characters that "fly" in some manner. The static path generation will be the only difference +between 2D and 3D. + + +### Physics + +  Physics, like other systems, will be separated into 2D and 3D specific implementations. +This system should be able to handle both Newtonian Rigid-Bodies and Soft-Bodies. The 2D +and 3D systems should be able to co-exist but not interact. This is for such cases where one +might decide to have a minigame with physics enabled in a 2D environment. + + +### Graphics + +  Graphics, like other systems, will be separated into 2D and 3D specific implementations. +Graphics will exist on a separate thread that handles "frames" vs "ticks," see definitions below +for more information. From an abstract, the graphics system should be able to handle static models, +dynamic models, skeletons, materials, lights, lighting models, and post-processing effects. + + +### Audio + +  Audio may actually be implemented generically since the principles of spatial audio apply +identically in both 2D and 3D. The only thing that may change for 2D is which axis is "up" and which +axis is "forwards," for example side-scrollers vs top-down. However, this does not mandate specific +implementations and rather just aliases which axis is "up." The X-axis can always be "left" and "right" +while the Y axis may be interpreted as "up" or "forwards." Audio also won't be handled in the same +manner as other systems which have explicit ticks and frames. + + + +## Core Game Loop + +  The core game loop is divided into Ticks and Frames. Ticks represent updates in the engine +state while Frames represent the generation of the visual output of the engine. + +### Tick +- **Update** + - Events + - Scripts + - AI +- **Physics** + - Newtonian Commit + - Apply Forces (Updates Accelerations) + - Acceleration (Updates Velocities) + - Apply Velocities (Updates Position and Rotation) + - Constraint Resolution + - Collision Detection + - Collision Resolution + - Collision Response + - Calculate Forces & Velocities + - Queue events for next tick + + +### Frame +- **Physics** + - Physics Interpolation +- **Graphics** + - [2D Graphics](./2D_GRAPHICS.md#2d-graphics-gfx2d) + - Generate 3D Mask + - [3D Graphics](./3D_GRAPHICS.md#3d-graphics-gfx3d) + + + diff --git a/planning/LANGUAGE_PROCESSING.md b/planning/LANGUAGE_PROCESSING.md new file mode 100644 index 0000000..cff71b9 --- /dev/null +++ b/planning/LANGUAGE_PROCESSING.md @@ -0,0 +1,248 @@ + +# Language Processing Library (`langproc`) + +## Table of Contents + + +* [Home](./CONTENTS.md#planning-documentation-for-fennec) +* [Language Processing Library (`langproc`)](#language-processing-library-langproc) + * [Table of Contents](#table-of-contents) + * [Introduction](#introduction) + * [String Analysis (`langproc/strings`)](#string-analysis-langprocstrings) + * [Implementation](#implementation) + * [File System (`filesystem`)](#file-system-filesystem) + * [Implementation](#implementation-1) + + + +## Introduction + +  This library contains implementations of headers and classes related to processing +languages. This includes; ascii/utf8/utf16 string processing, file formats, machine language, +and programming languages. + +  fennec should be able to process documentation in files, the main ways it will support +this is through Doxygen and LaTeX. Consider including binaries with releases. + + +## String Analysis (`langproc/strings`) + +  fennec reimplements the C++ Strings Library as a submodule of this library. This +is because C++ `std::string` has a lot of overhead. I would say that `std::string` +is a Jeep, while `fennec::string` is an F2 Car, if that analogy makes any sense. i.e. +`std::string` offers a lot of use cases, but is slower, while an F2 Car is barebones and +highly performant on the right surface. + +### Implementation + +| Symbol | Implemented | Passed | +|:---------|:-----------:|:------:| +| cstring | ✔ | ✔ | +| string | ✔ | ✔ | +| wcstring | ✔ | ✔ | +| wstring | ✔ | ✔ | + + + +## File System (`filesystem`) + +  fennec *does not* reimplement the C++ I/O Library. What it does do +is create C++ classes that handle file streams, directory streams, and file paths. + +### Implementation + +| Symbol | Implemented | Passed | +|:----------|:-----------:|:------:| +| path | ✔ | ✔ | +| file | ✔ | ✔ | +| directory | ❌ | ❌ | + + + +## Interpreter (`langproc/interpret`) + +  This submodule will contain classes for interpreting data, particularly +through parsers. We will need to be able to do the following things to achieve +support for files that adhere to a certain specification. Here are some concepts +that will need to be implemented as classes: + + +### Reading + + - Tokenization + - Useful for text-based formats + - Data Parser + - Useful for binary-based formats + - Lexical Analysis + - Necessary for Syntax Coloring + - Syntax Analysis + - Necessary for Syntax Coloring + - Semantic Analysis + - Necessary for Code Completion + - Intermediate Code Generation + - Necessary for any custom programming language in fennec + - Target Code Generation / Optimization? + - Necessary for any custom programming language that needs to compile to binary + + +### Writing + +  The writers will be responsible for writing data as a specific format. I.E. converting +data values (e.g. floats, ints, etc.) to a readable language (e.g. ascii/utf8/utf16). + + - Writer + - Binary Writer + + + +## Formats (`langproc/formats`) + +  This submodule will contain classes for processing a variety of file formats. + +### Serialization + +| Symbol | Implemented | Passed | +|:-------|:-----------:|:------:| +| JSON | ❌ | ❌ | +| HTML | ❌ | ❌ | +| XML | ❌ | ❌ | +| YAML | ❌ | ❌ | + + +### Configuration + +| Symbol | Implemented | Passed | +|:-------|:-----------:|:------:| +| INI | ❌ | ❌ | +| TOML | ❌ | ❌ | + + +### Documents + +| Symbol | Implemented | Passed | +|:---------|:-----------:|:------:| +| ODF | ❌ | ❌ | +| Markdown | ❌ | ❌ | +| PDF | ❌ | ❌ | + + +### Spreadsheets & Tables + +| Symbol | Implemented | Passed | +|:---------|:-----------:|:------:| +| ODS | ❌ | ❌ | +| CSV | ❌ | ❌ | + + +### Audio Formats + +| Symbol | Implemented | Passed | +|:---------|:-----------:|:------:| +| MP3 | ❌ | ❌ | +| WAV | ❌ | ❌ | +| AAC | ❌ | ❌ | + + +### Graphics Formats + +#### Raster Textures + +| Symbol | Implemented | Passed | +|:-------|:-----------:|:------:| +| BMP | ❌ | ❌ | +| DDS | ❌ | ❌ | +| JPG | ❌ | ❌ | +| PNG | ❌ | ❌ | +| TIFF | ❌ | ❌ | + + +#### Vector Graphics + +| Symbol | Implemented | Passed | +|:-------|:-----------:|:------:| +| OTF | ❌ | ❌ | +| SVG | ❌ | ❌ | +| TTF | ❌ | ❌ | + + +#### 3D Model Formats + +  unfortunately, most formats are esoteric due to copyright/trademark/etc. +I will be using assimp for the time being, below is a list of formats supported +by assimp. + +| Symbol | Implemented | Passed | +|:----------------|:-----------:|:------:| +| 3D | ❌ | ❌ | +| 3DS | ❌ | ❌ | +| 3MF | ❌ | ❌ | +| AC | ❌ | ❌ | +| AC3D | ❌ | ❌ | +| ACC | ❌ | ❌ | +| AMJ | ❌ | ❌ | +| ASE | ❌ | ❌ | +| ASK | ❌ | ❌ | +| B3D | ❌ | ❌ | +| BVH | ❌ | ❌ | +| CSM | ❌ | ❌ | +| COB | ❌ | ❌ | +| DAE/Collada | ❌ | ❌ | +| DXF | ❌ | ❌ | +| ENFF | ❌ | ❌ | +| FBX | ❌ | ❌ | +| glTF 1.0 + GLB | ❌ | ❌ | +| glTF 2.0 | ❌ | ❌ | +| HMB | ❌ | ❌ | +| IFC-STEP | ❌ | ❌ | +| IQM | ❌ | ❌ | +| IRR / IRRMESH | ❌ | ❌ | +| LWO | ❌ | ❌ | +| LWS | ❌ | ❌ | +| LXO | ❌ | ❌ | +| M3D | ❌ | ❌ | +| MD2 | ❌ | ❌ | +| MD3 | ❌ | ❌ | +| MD5 | ❌ | ❌ | +| MDC | ❌ | ❌ | +| MDL | ❌ | ❌ | +| MESH / MESH.XML | ❌ | ❌ | +| MOT | ❌ | ❌ | +| MS3D | ❌ | ❌ | +| NDO | ❌ | ❌ | +| NFF | ❌ | ❌ | +| OBJ | ❌ | ❌ | +| OFF | ❌ | ❌ | +| OGEX | ❌ | ❌ | +| PLY | ❌ | ❌ | +| PMX | ❌ | ❌ | +| PRJ | ❌ | ❌ | +| Q3O | ❌ | ❌ | +| Q3S | ❌ | ❌ | +| RAW | ❌ | ❌ | +| SCN | ❌ | ❌ | +| SIB | ❌ | ❌ | +| SMD | ❌ | ❌ | +| STP | ❌ | ❌ | +| STL | ❌ | ❌ | +| TER | ❌ | ❌ | +| UC | ❌ | ❌ | +| USD | ❌ | ❌ | +| VTA | ❌ | ❌ | +| X | ❌ | ❌ | +| X3D | ❌ | ❌ | +| XGL | ❌ | ❌ | +| ZGL | ❌ | ❌ | + + +#### Video Formats + +| Symbol | Implemented | Passed | +|:-------|:-----------:|:------:| +| MP4 | ❌ | ❌ | +| AVI | ❌ | ❌ | +| MPG | ❌ | ❌ | +| MOV | ❌ | ❌ | + + + + diff --git a/planning/MEMORY.md b/planning/MEMORY.md index 55ea032..e64cadd 100644 --- a/planning/MEMORY.md +++ b/planning/MEMORY.md @@ -5,7 +5,7 @@ * [Home](./CONTENTS.md#planning-documentation-for-fennec) -* [Memory Library (`memory`)](#memory-library-memory) +* [Memory Library](#memory-library-memory) * [Table of Contents](#table-of-contents) * [Introduction](#introduction) * [Implementation](#implementation) @@ -15,7 +15,7 @@ ## Introduction   This library contains headers and classes related to memory allocation and -management in C++. The contents are restricted to the Memory Management Library of +management in C++. The contents include the Memory Management Library of the C++ Standard Library and Template Library. This pulls some functions from the C stdlib and either wraps them or aliases them. diff --git a/planning/PLANNING.md b/planning/PLANNING.md deleted file mode 100644 index 8c75112..0000000 --- a/planning/PLANNING.md +++ /dev/null @@ -1,761 +0,0 @@ - - -# Planning Documentation for fennec - -## Table of Contents - - 1. [Introduction](#introduction) - 2. [TODO](#todo) - 1. [Security Ramblings](#file-security-ramblings) - 2. [Platform Support](#platform--api-support) - 3. [C++ Language](#c-language-library-lang) - 4. [Math Library](#math-library-math) - 5. [Memory Library](#memory-library-memory) - 6. [Containers Library](#containers-library-containers) - 7. [Format Processing](#format-processing-langproc) - 8. [Core](#core-core) - 1. [Tick](#tick) - 2. [Frame](#frame) - 9. [Platform Support Layer](#platform-support-layer-platform) - 10. [Scene](#scene-scene) - 11. [2D Graphics](#2d-graphics-gfx2d) - 12. [3D Graphics](#3d-graphics-gfx3d) - 1. [Structures](#structures-gfx3d) - 2. [Stages](#stages-gfx3d) - 13. [3D Physics](#3d-physics-physics3d) - 14. [Artificial Intelligence](#artificial-intelligence-ai) - - - -## Introduction - -This file serves as a general planning document for engine structure, systems, pipelines, and implementation. - - -Implementations of core engine systems should strive to be `O(1)` in implementations, -both in terms of runtime and memory performance. This is obviously not a realistic goal, -so rather than the goal requiring the entire engine to be `O(1)`, we should more specifically look -at achieving `O(1)` performance on hot paths. I distinctly use 'strive' and 'goal' as different concepts, where designs -should *strive* to accommodate function implementations for `O(1)`, however the specifics of the implementation might not always -be able to achieve that, so the end *goal* is that hot paths should be `O(1)`. - -Functions should be highly verbose and any bugprone or erroneous behaviour should throw -assertions. **DO NOT USE EXCEPTIONS**. - -System implementations should be independent of architecture or platforms. i.e. the code of the graphics system should -not care if OpenGL or Vulkan is used and should not use any direct calls to OpenGL or Vulkan. - -The engine should not care about the types of objects loaded from a so/dll. In fact, most of the code should -be type independent. Any shared information among a collection of objects should be held either implicitly or explicitly -in the super-class. It will be the responsibility of the linked code to initialize and cleanup the objects related to it. -This principle should extend to the submodules of the engine. - -It is also best to avoid objects having behaviour that is not defined by the system they are in. There are some exceptions -in extensions or mods and should be given configurability and programmability within those systems and their stages. -This however can be achieved using events at different stages of those engines that are on-demand. - - - - - -## TODO - - - 2D Graphics (`gfx2d`) - - 2D Physics (`physics2d`) - - 2D & 3D Audio (`audio`) - - -### File Security Ramblings: - -Windows is starting to piss me off, so I am considering dropping official support for MSVC. MinGW and Cygwin -will still work for compiling on Windows if this ends up being the case. The reason for this is that there are -*a lot* of platform dependent security issues. MinGW and Cygwin wrap Linux and glibc headers for Windows, which would -push the security onus onto the compiler and end-user. - -The biggest blocker at the moment in terms of this is the filesystem. If we want to implement a filesystem that -is safe across platforms, stdc++ *and* iso libc have no guarantees about the safety of their functions. - -The crux of this issue falls at the following specific behaviour: - - User selects an existing file to write to - - Application interface confirms overwrite action - - Application writes to the file after confirmation - -A threat actor can introduce a malicious file or symlink to the file that was attempted access between the check and -usage of the file. This is called TOCTOU (time of check, time of use). - -This issue can be solved using `fopen("", "a+")` and `ftell`, however this specific behaviour is not intuitive to -those first learning how to work with file systems. We can attempt to abstract this away with another wrapper, or simply -write the file structure to handle this behaviour properly. The downside to this method overall is that it will break -common conventions of how humans interpret filesystems and the related control flow logic. What we can do is force the -`'+'` flag to always be present for write operations, and raise an error when desired, if the file is not empty. This -unfortunately would have the downside of being unable to open a file as write only. - -Using `"wx"` in this instance would not be sufficient since it would require a second call to fopen, which would -create the conditions for the TOCTOU error described above. - -Another issue arises when we are parsing a directory tree. The best we can do is take ownership of the directory that -is opened as the root. However, this requires `dirent.h` which is not implemented in MSVC. A custom implementation of -`dirent.h` may be written for MSVC, however this is one of the few things I am not willing to outsource to another -library. Developing our own implementation would take a non-insignificant amount of time, between writing the library, -debugging it, and testing for vulnerabilities. As stated above, this implementation is native to MinGW and Cygwin, -so we would not have to entirely drop support for Windows. However, MSVC is the most widely used compiler for Windows -applications and is native to Visual Studio and VSCode. - -What is probably the best solution is to wrap everything in a file interface that does not allow the direct setting of -these flags. Then we set our own usage type for the file that informs which flags should be used. - -We need to be able to handle the following types of files: - - Assets, such as scenes, audio, textures, metadata, meshes, etc. - - Save files, setting files, etc. - -One of the nice things about the assets is that they are guaranteed to be read-only once an application is installed -on the computer of the end-user. Therefore, this issue only arises with save files and custom file formats. - -When the editor is run, all these files should be opened in read/write mode. - -Naming conventions should exist for the types of files and how they are read. For example, in release mode, -most assets should be opened once, and then closed immediately. However, this does not make sense for formats -that are continuous and too large to be kept around in memory, such as video formats. - -Perhaps the following conventions: - - Static Asset - - Stream Asset - - Resource - -We can turn this into an object-oriented approach by having different formats inherit these base types. We may still -have a base file type that wraps C functionality, but discourage developers from using the interface. - -We could also declare the file interface extern so that only internal files know the implementation. However, I would -not be satisfied by doing this since it would prevent developers from implementing custom file type implementations. - -Conserving memory is not really an issue here as long as we are smart about our implementation. Files should only be -open when necessary and be closed when it is no longer necessary to have them open. Data should be streamed unless the -all the data in the file is required. - -When built in release mode, we also need to pack static assets into some sort of archive that is mountable to reduce -disk space consumption of a program. - -I was considering encryption for archives, however it does not make much sense. Assuming someone intends to pirate the -game, there is not much stopping them from running the files. I will add Steam support at some point which would allow -you to use Steam's DRM to prevent the executable from being run. Otherwise, there is no point in attempting to encrypt -game files. Even Unreal PAK files can be cracked in seconds, and even if I managed to write something that cannot be -trivially cracked locally, you can scrape most assets from the GPU and Audio Card. - -I have managed to solve the specific case provided at the top of this section, which was done by wrapping C I/O calls -into a file wrapper. This wrapper can handle a few different mode flags and has specific conditions for the flags. See -the documentation for `fennec/langproc/io/file.h` for more info. - -One question remains unanswered on this front; should a read/write file open as `r+` or `a+`. `rewind` is slightly faster -than `fseek(SEEK_END)`, however for the case of save files and editor assets, `r+` makes more sense from a usage perspective - -Directories remain an issue, with `dirent.h` being the only sensible option at time of writing. The issue with using -`dirent.h` boils back down to security issues on Windows. However, the only option is to write a custom implementation -for MSVC. - - -### Platform & API Support - -I have decided to forgo SDL, this is so the engine can provide specific support for specific platforms. -Also, SDL implements a lot of things that will need to be implemented specifically for the engine, so only the window -management would be used. - -Platform support will be implemented in the following order: - - Linux/BSD - - Wayland - - OpenGL (EGL) ✔ - - XKB - - PulseAudio - - Vulkan - - X11 - - ALSA - - Vulkan - - Microsoft Windows - - XInput - - OpenGL (WGL) - - WASAPI - - Vulkan - - Android - - OpenGL ES - - AAudio - - openslES - - macOS/iOS - - cocoa - - OpenGL - - Core Audio - - Vulkan - - Metal - -Linux Wayland will be implemented first. Once setup, the core engine will be implemented and tested on top of Wayland. -Once the engine is in a stable state, then support for other platforms will be resumed. - -Most consoles will never get official platform support due to NDAs which conflict with the principles of this engine. -fennec will avoid using proprietary libraries except when strictly necessary, such as support for Windows and MacOS. -fennec will interact with any drivers required for the listed operating systems above, even if proprietary. - - -## C++ Language Library (`lang`) - -Implement header files for standard functions relating to the C++ Language. - -So far this is implemented on an as-needed basis. A full implementation should be worked on continuously. - - - - - -## Math Library (`math`) - -Implement math functions according to the [OpenGL 4.6 Shading Language Specification](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf). - -"Extensions" has a different meaning here. Extensions for the math library are any functions that are not defined within -the Specification. - -Additional extensions should be implemented to provide standard definitions for functions predominantly related -to Linear Algebra, Mathematical Analysis, and more specifically Discrete Analysis. Additional extensions will be -implemented on an as-needed basis. - - - - - -## Memory Library (`memory`) - -Implement headers related to memory allocation in C++. - - * Smart Pointers - * Unique Pointer - * Shared Pointer - - - Memory Allocation - - Allocation - - - - - - -## Containers Library (`containers`) - -All containers of the [C++ Standard Library](https://cppreference.com/w/cpp/container.html) should be implemented. - -Here are essential data-structures not specified in the C++ stdlib: - - Graph → AI `graph` - - Necessary for 2D and 3D navigation. - - Rooted Directed Tree → Scene `rd_tree` - - Defines the scene structure. - - - - - -## Language Processing (`langproc`) - -This library contains information for any data that is formatted. This includes basic string formats, file formats, -and eventually programming languages - -fennec should be able to use Doxygen and LaTeX externally. Consider including binaries with releases. - -### Notes - - * String Analysis (`langproc/strings`) - * Search - * Manipulation - * Delimiting - * Regex - - - File Formats (`langproc/formats`) - - Serialization - - JSON - - HTML - - XML - - YAML - - Configuration - - INI - - TOML - - Documents - - ODF - - Markdown - - PDF - - Spreadsheets & Tables - - ODS - - CSV - - Audio Formats - - MP3 - - WAV - - AAC - - Graphics Formats - - Textures - - BMP - - DDS - - JPG - - PNG - - TIFF - - Vectors - - OTF - - SVG - - TTF - - Models - unfortunately, most formats are esoteric due to copyright/trademark/etc. I will be using assimp for the - time being, below is a list of formats supported by assimp. - - 3D - - 3DS - - 3MF - - AC - - AC3D - - ACC - - AMJ - - ASE - - ASK - - B3D - - BVH - - CSM - - COB - - DAE/Collada - - DXF - - ENFF - - FBX - - glTF 1.0 + GLB - - glTF 2.0 - - HMB - - IFC-STEP - - IQM - - IRR / IRRMESH - - LWO - - LWS - - LXO - - M3D - - MD2 - - MD3 - - MD5 - - MDC - - MDL - - MESH / MESH.XML - - MOT - - MS3D - - NDO - - NFF - - OBJ - - OFF - - OGEX - - PLY - - PMX - - PRJ - - Q3O - - Q3S - - RAW - - SCN - - SIB - - SMD - - STP - - STL - - TER - - UC - - USD - - VTA - - X - - X3D - - XGL - - ZGL - - Video Formats - - MP4 - - AVI - - MPG - - MOV - -**TODO LATER** - * Compilation (`langproc/code`) - * Lexical Analysis - * Syntax Analysis - * Semantic Analysis - * Intermediate Code Generation - * Optimization - * Target Code Generation - - - - - -## Core (`core`) - -This will be the core of the engine. - - - Event System - - Most events will fire at the start of the next tick, especially those related to physics and input. - - Events for graphics or audio should propagate immediately. - - Events for stages should also propagate immediately, this is to support extensions and mods. - - Core Engine Loop - - System Manager - - Ticks vs. Frames - -The following systems are not essential to the core engine, but are instead major systems that should be defined -in their operation order: - -### Tick - - **Update** - - Events - - Scripts - - AI - - **Physics** - - Newtonian Commit - - Apply Forces (Updates Accelerations) - - Acceleration (Updates Velocities) - - Apply Velocities (Updates Position and Rotation) - - Constraint Resolution - - Collision Detection - - Collision Resolution - - Collision Response - - Calculate Forces & Velocities - - Queue events for next tick - - -### Frame - - **Physics** - - Physics Interpolation - - **Graphics** - - [2D Graphics](#2d-graphics-gfx2d) - - Generate 3D Mask - - [3D Graphics](#3d-graphics-gfx3d) - - **Audio** - - - - - -## Platform Support Layer (`platform`) - -This is the core part of platform support for fennec. All necessary drivers -and OS specific functionality will be wrapped up nicely into these interfaces. - -See implementation order [here](#platform--api-support) - - -## Scene (`scene`) - -* In-Array Directed Tree - * Elegant method for providing `O(1)` insertions and `O(log(n))` deletions. -* Bounding Volume Hierarchy - * Octree - - - - - -## 2D Graphics (`gfx2d`) - -Links: - - https://en.wikipedia.org/wiki/Quadtree - - https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-25-rendering-vector-art-gpu - -Object Structure. The mesh is implicit data. - - -### Structures (`gfx2d`) - -For the 2d rendering framework, Materials need to be rendered independently because we have -no size constraints for images. This disallows us from using a meta-shader like in -the 3d rendering framework. - -```c++ -struct Object -{ - vec2 location, scale; // A matrix would be 36 bytes, this is instead 20 bytes - float rotation; -} -``` - - - BVH - - Quadtree - - Leaf Size and Tree Depth should be calculated by the scene, constraints are as follows: - - Min Object Size - - Max Object Size - - Scene Center - - Scene Edge - - Insertions and Updates are done on the CPU - - Nodes - - Start Index 32-bits - - Object Count 32-bits - - Objects - - Buffer of Object IDs grouped by Octree Node - - Culling - - Starting at each Octree Leaf, traverse upwards. - - Insert Visible Leaf IDs - - Track using atomic buffer - - Generate the Command Buffer for Culled Meshes from the Visible Leaf Buffer - - Count Materials - - Count Meshes per Material - - Generate the Culled Object Buffer by copying objects from the Object Buffer - - Adjust Buffer Size using the counts - - Insert using another atomic buffer - - - Translucent objects will be sorted. We can cheat by using a z-index instead of a z-coordinate. - This will allow us to sort objects as they are created. We can still bulk render each z-index, - with meshes and objects being grouped by material. - - - - - -## 3D Graphics (`gfx3d`) - -Links: -- https://en.wikipedia.org/wiki/Octree -- https://www.adriancourreges.com/blog/2015/11/02/gta-v-graphics-study/ -- https://learnopengl.com/PBR/Lighting -- https://learnopengl.com/PBR/IBL/Diffuse-irradiance -- https://en.wikipedia.org/wiki/Schlick%27s_approximation -- https://pixelandpoly.com/ior.html -- https://developer.download.nvidia.com/SDK/10/opengl/screenshots/samples/dual_depth_peeling.html - -**DirectX will never have official support.** -If you would like to make a fork, have at it, but know that I will hold a deep disdain for you. - -The graphics pipeline will have a buffer with a list of objects and their rendering data. -This will be referred to as the Object Buffer. There will be two, for both the Deferred and Forward Passes. - -The buffers will be optimized by scene prediction. -This involves tracking the meshes and textures directly and indirectly used by a scene. -A callback function in the graphics system for scene loading can do this. - - -Materials and Lighting models will be run via a shader metaprogram to make the pipeline independent of this aspect. -This allows the GPU to draw every single deferred rendered mesh in a single draw call for each stage of the renderer. - -Specifications for debugging views via early breaks are included in the stages. - -There will be three profiles for OpenGL implementation: - - modern - - fallback - - legacy - -All profiles will have the same feature set, however their implementations will differ. -The modern context will use up-to-date features to get as much performance out of the pipeline as -possible. - - - -### Structures (`gfx3d`) - -Object Structure. The mesh is implicit data. - -```c++ -struct Object -{ - vec3 location, scale; // A matrix would be 64 bytes, this is instead 28 bytes - quat rotation; - uint32 material, lighting; -} -``` - -Textures for 3D rendering are stored in various buffers with sizes of powers of 2. -Ratios of `1:1` and `2:1` are allowed. The `2:1` ratio is specifically for spherical and cylindrical projection. -UVs may be transformed to use a `2:1` as if it were `1:2`. -Cubemaps and 3D textures may only be `1:1`, I would be concerned if you are using any other ratio. - - - 8-Bit R Texture `4096, 2048, 1024, 512` (8) - - 8-Bit RG Texture `4096, 2048, 1024, 512` (8) - - 8-Bit RGB Texture `4096, 2048, 1024, 512` (8) - - 8-Bit RGBA Texture `4096, 2048, 1024, 512` (8) - - 8-Bit R Cubemap `1024, 512, 256, 128` (4) - - 8-Bit RGB Cubemap `1024, 512, 256, 128` (4) - - * 16-Bit HDR R Texture `4096, 2048, 1024, 512` (8) - * 16-Bit HDR RGB Texture `4096, 2048, 1024, 512` (8) - * 16-Bit HDR RGBA Texture `4096, 2048, 1024, 512` (8) - * 16-Bit HDR R Cubemap `1024, 512, 256, 128` (4) - * 16-Bit HDR RGB Cubemap `1024, 512, 256, 128` (4) - - - 16-Bit Shadow Texture `4096, 2048, 1024, 512` (8) - - 16-Bit Shadow Cubemap `2048, 1024, 512, 256` (4) - - * 8-Bit 3D R Texture `256, 128, 64, 32` (4) - * 8-Bit 3D RGB Texture `256, 128, 64, 32` (4) - * 16-Bit 3D HDR R Texture `256, 128, 64, 32` (4) - * 16-Bit 3D HDR RGB Texture `256, 128, 64, 32` (4) - -Documentation should provide guidelines on categories of Art Assets and the resolution of textures to use. - -Textures are identified by a 32-bit integer. - - `8 bits` → the texture buffer - - `24 bits` → the layer in the buffer - -Artists should be informed on the texture structure of the engine and its limitations. -However, these principles should be followed in other game engines as these are -guided by what is most efficient for typical GPU hardware. - - -Materials are, for the most part, user-defined. Documentation should make the user aware of this. -Material buffers will be a sequence of the Material Struct instances. -They will at the very least contain the id of their shader. - -Types of materials: - - Surface (Vertex & Fragment) - - Opaque / Masked - - Translucent (Forward) - - Volume (Path Traced Volumetrics / Forward) - - Light (Lighting Model) - - Post-Process - - - - - -### Stages (`gfx3d`) - -This is the set of stages for the graphics pipeline that runs every frame: -Unless otherwise specified, each stage will be run on the GPU. - - - BVH - - Octree `(8 Bpn, 64 bpn) [6-Layers ≈ 2.1MB]` - - Leaf Size and Tree Depth should be calculated by the scene, constraints are as follows: - - Min Object Size - - Max Object Size - - Scene Center - - Scene Edge - - Buffer has implicit locations due to the tree having 8 children. - - Insertions and Updates are done on the CPU - - Nodes - - Start Index `int32` - - Object Count `int32` - - Objects - - Buffer of Object IDs grouped by Octree Node - - Leaf Culling - - Starting at each Octree Leaf, traverse upwards. - - Insert Visible Leaf IDs - - Track using atomic buffer - - Generate the Command Buffer for Culled Mesh LODs from the Visible Leaf Buffer - - Track counts using atomic buffers - - To avoid double counting due to the construction of the Octree output, we have some options - - Ignore Leaf Instances based on occurrences of the mesh in the surrounding 8 Quadtree Leaves. This would require - a bias towards a specific corner of the filter. - - Perform a preprocessing step on the CPU to erase duplicate elements and fix the buffer continuity. - - Let the duplicates be rendered. - - Generate the Culled Object Buffer with the respective object IDs - - Adjust Buffer Size using the counts - - Insert by reusing the count buffer, clipped to only contain used meshes - -Debug View: Object ID, Mesh ID, LOD - -- Visibility - - Buffer `(15 Bpp, 120 bpp) [1920x1080] ≈ 39.4MB` - - Depth Buffer → `D24` - - Visibility Info → `RGB32I` - - R = Object ID - - G = Mesh ID - - B = Material ID - - Regenerate the Command Buffer for Visible Mesh LODs - - Regenerate the Culled Object Buffer - -Debug View: Visibility Buffer - -* G-Buffer Pass `(17 Bpp, 136 bpp) [1920x1080] ≈ 35.3MB` - * Depth - Stencil → `D24_S8` - * S → used to represent the lighting model. - * Diffuse → `RGBA8` - * A → Ambient Occlusion - * Emission → `RGB8` - * Normal → `RGB8` - * Specular → `RGB8` - * R → Roughness - * G → Specularity (sometimes called the Metallicness) - * B → Index of Refraction (IOR) - -Debug View: Depth, Stencil, Diffuse, Emission, Normal, Specularity - -- Generate Dynamic Shadows -- Generate Dynamic Reflections (Optional) -- SSAO (Optional) -- Deferred Lighting Pass `(10 Bpp, 80 bpp) [1920x1080] ≈ 2 x 16.3MB + 8.3MB ≈ 24.6MB` - - Depth Buffer → `D24` - - Lighting Buffer → `RGB16` w/ Mipmapping - - Stencil Buffer $rarr; `S8` - - Apply Lighting Model - -Debug View: Shadows, Reflections, SSAO, Deferred Lighting - -We can combine all of these into one framebuffer: - - - Depth - Stencil → `D24_S8` - - Visibility Info → `RGB32I` - - Diffuse → `RGBA8` - - Emission → `RGB8` - - Normal → `RGB8` - - Specular → `RGB8` - - Lighting Buffer → `RGB16` w/ Mipmapping - - One more slot left open for another - -* Forward Pass - * BVH, Same as Above - * LOD Selection, Same as Above - * Translucent Materials - * Dual Depth Peeling - -Debug View: Forward Mask - -- Post Processing - - Depth of Field (Optional) - - When enabled, the Visiblity Buffer, G-Buffer, and Deferred Lighting Pass will be double layered. - - At this point the Lighting Buffers will be Flattened - - Bloom (Optional) → Mipmap Blurring `(6Bpp, 48bpp) [1920x1080] ≈ 16.3MB` - - Tonemapping (Optional) - - HDR Correction - - - - -## 3D Physics `(physics3d)` - -Links: -- https://www.researchgate.net/publication/264839743_Simulating_Ocean_Water -- https://arxiv.org/pdf/2109.00104 -- https://www.youtube.com/watch?v=rSKMYc1CQHE -- https://tflsguoyu.github.io/webpage/pdf/2013ICIA.pdf -- https://animation.rwth-aachen.de/publication/0557/ -- https://github.com/InteractiveComputerGraphics/PositionBasedDynamics?tab=readme-ov-file -- https://www.cs.umd.edu/class/fall2019/cmsc828X/LEC/PBD.pdf - -Systems - -* Rigid Body Physics - * Newtonian Physics and Collision Resolution - * Articulated Skeletal Systems - * Inverse Kinematics - * Stiff Rods -- Particle Physics -* Soft Body Physics - * Elastics → Finite Element Simulation - * Cloth → Position-Based Dynamics - * Water - * Oceans → iWave - * Reasoning: iWave provides interactive lightweight fluid dynamics suitable for flat planes of water. -

- - * 3D Fluid Dynamics → Smoothed-Particle Hydrodynamics - * Reasoning: This is the simplest method for simulating 3D bodies of water. This should exclusively be - used for small scale simulations where self-interactive fluids are necessary. I.E. pouring water into - a glass. -

- - * 2D Fluid Dynamics → Force-Based Dynamics - * Reasoning: This model, like iWave, provides lightweight interactive fluid dynamics, but is more easily - adapted to flowing surfaces such as streams and rivers. - - - - - -## Artificial Intelligence (`ai`) - -This artificial intelligence method only differs in static generation between 2D and 3D. -The solvers are dimension independent since they work on a graph. - -The general process is; - -Static: - - generate a static navigation graph (sometimes called a NavMesh) - -Update: - * resolve dynamic blockers - * update paths using dijkstra's algorithm - * apply rigid-body forces with constraints - -The update loop for artificial intelligence should only update every `n` ticks. Where `n <= k`, with `k` being the -tick rate of the physics engine. \ No newline at end of file