- Moved OpenGL library wrapper into platform
- Finished reorganizing PLANNING.md
This commit is contained in:
64
planning/2D_GRAPHICS.md
Normal file
64
planning/2D_GRAPHICS.md
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
# 2D Graphics (`gfx2d`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<!-- TOC -->
|
||||
* [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)
|
||||
<!-- TOC -->
|
||||
|
||||
|
||||
## 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.
|
||||
211
planning/3D_GRAPHICS.md
Normal file
211
planning/3D_GRAPHICS.md
Normal file
@@ -0,0 +1,211 @@
|
||||
|
||||
# 3D Graphics (`gfx3d`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<!-- TOC -->
|
||||
* [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)
|
||||
<!-- TOC -->
|
||||
|
||||
|
||||
## 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
|
||||
48
planning/3D_PHYSICS.md
Normal file
48
planning/3D_PHYSICS.md
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
# 3D Physics (`physics3d`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<!-- TOC -->
|
||||
* [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)
|
||||
<!-- TOC -->
|
||||
|
||||
|
||||
## 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.
|
||||
<br><br>
|
||||
|
||||
* 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.
|
||||
<br><br>
|
||||
|
||||
* 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.
|
||||
29
planning/ARTIFICIAL_INTELLIGENCE.md
Normal file
29
planning/ARTIFICIAL_INTELLIGENCE.md
Normal file
@@ -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.
|
||||
@@ -3,15 +3,53 @@
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<!-- TOC -->
|
||||
* [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)
|
||||
<!-- TOC -->
|
||||
|
||||
|
||||
## 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 | ✔ | ✔ |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<!-- TOC -->
|
||||
* [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:
|
||||
|
||||
131
planning/ENGINE.md
Normal file
131
planning/ENGINE.md
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
# fennec
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<!-- TOC -->
|
||||
* [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)
|
||||
<!-- TOC -->
|
||||
|
||||
|
||||
## 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)
|
||||
|
||||
|
||||
|
||||
248
planning/LANGUAGE_PROCESSING.md
Normal file
248
planning/LANGUAGE_PROCESSING.md
Normal file
@@ -0,0 +1,248 @@
|
||||
|
||||
# Language Processing Library (`langproc`)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<!-- TOC -->
|
||||
* [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)
|
||||
<!-- TOC -->
|
||||
|
||||
|
||||
## 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 | ❌ | ❌ |
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<!-- TOC -->
|
||||
* [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.
|
||||
|
||||
|
||||
@@ -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("<file>", "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.
|
||||
<br><br>
|
||||
|
||||
* 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.
|
||||
<br><br>
|
||||
|
||||
* 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.
|
||||
Reference in New Issue
Block a user