- Created Layout for Textures

- Separated Build and Output directories
This commit is contained in:
Medusa Slockbower 2025-06-14 22:17:46 -04:00
parent 885cca6ca7
commit 096e82f47a
11 changed files with 365 additions and 176 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
/build/ /build/
/docs/ /docs/
/bin/
/lib/

View File

@ -13,6 +13,14 @@ include_directories(include)
# Metaprogramming is a dependency for generating various type info before compilation of the engine. # Metaprogramming is a dependency for generating various type info before compilation of the engine.
add_subdirectory(metaprogramming) add_subdirectory(metaprogramming)
string(TOLOWER ${CMAKE_BUILD_TYPE} FENNEC_BUILD_NAME)
set(CMAKE_BINARY_DIR ${PROJECT_SOURCE_DIR}/build/${CMAKE_PLATFORM_NO_VERSIONED_SONAME})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib/${FENNEC_BUILD_NAME})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/${FENNEC_BUILD_NAME})
add_library(fennec STATIC add_library(fennec STATIC
# CORE ================================================================================================================= # CORE =================================================================================================================
@ -24,7 +32,8 @@ add_library(fennec STATIC
include/fennec/containers/dynarray.h include/fennec/containers/dynarray.h
# LANG ================================================================================================================= # LANG =================================================================================================================h
include/fennec/lang/bits.h
include/fennec/lang/constants.h include/fennec/lang/constants.h
include/fennec/lang/conditional_types.h include/fennec/lang/conditional_types.h
include/fennec/lang/intrinsics.h include/fennec/lang/intrinsics.h
@ -43,10 +52,10 @@ add_library(fennec STATIC
# MEMORY =============================================================================================================== # MEMORY ===============================================================================================================
include/fennec/memory/allocator.h
include/fennec/lang/bits.h
include/fennec/memory/memory.h
include/fennec/memory/new.h source/memory/new.cpp include/fennec/memory/new.h source/memory/new.cpp
include/fennec/memory/allocator.h
include/fennec/memory/memory.h
include/fennec/memory/pointers.h include/fennec/memory/pointers.h
include/fennec/memory/ptr_traits.h include/fennec/memory/ptr_traits.h
@ -78,6 +87,7 @@ add_library(fennec STATIC
include/fennec/math/detail/__types.h include/fennec/math/detail/__types.h
include/fennec/math/detail/__vector_traits.h include/fennec/math/detail/__vector_traits.h
include/fennec/lang/lang.h include/fennec/lang/lang.h
include/fennec/lang/detail/__bits.h
) )
# add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled # add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled

View File

@ -4,20 +4,24 @@
## Table of Contents ## Table of Contents
1. [Introduction](#introduction) 1. [Introduction](#introduction)
2. [TODO](#todo) 2. [TODO](#todo)
3. [C++ Language](#c-language-library-lang) 3. [C++ Language](#c-language-library-lang)
4. [Math Library](#math-library-math) 4. [Math Library](#math-library-math)
5. [Memory Library](#memory-library-memory) 5. [Memory Library](#memory-library-memory)
6. [Containers Library](#containers-containers) 6. [Containers Library](#containers-containers)
7. [Language Processing](#language-processing-proclang) 7. [Format Processing](#format-processing-fproc)
8. [Core](#core-core) 8. [Core](#core-core)
1. [Tick](#tick) 1. [Tick](#tick)
2. [Frame](#frame) 2. [Frame](#frame)
9. [Scene](#scene-scene) 9. [Application Layer](#application-layer-app)
10. [3D Graphics](#3d-graphics-gfx3d) 10. [Scene](#scene-scene)
11. [3D Physics](#3d-physics-physics3d) 11. [2D Graphics](#2d-graphics-gfx2d)
12. [Artificial Intelligence](#artificial-intelligence-ai) 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)
@ -82,7 +86,7 @@ Implement headers related to memory allocation in C++.
## Containers (`containers`) ## Containers Library (`containers`)
All containers of the [C++ Standard Library](https://cppreference.com/w/cpp/container.html) should be implemented. All containers of the [C++ Standard Library](https://cppreference.com/w/cpp/container.html) should be implemented.
@ -96,20 +100,18 @@ Here are essential data-structures not specified in the C++ stdlib:
## Language Processing (`proclang`) ## Format Processing (`fproc`)
Pronounced [ˈɒkh,læŋ](https://itinerarium.github.io/phoneme-synthesis/?w=pɹˈɒkh,læŋ)
No, this won't include Machine Learning, it will mostly include tools for processing human-readable files. No, this won't include Machine Learning, it will mostly include tools for processing human-readable files.
fennec should be able to use Doxygen and LaTeX externally. Consider including binaries with releases. fennec should be able to use Doxygen and LaTeX externally. Consider including binaries with releases.
* String Analysis (`proclang/strings`) * String Analysis (`fproc/strings`)
* Search * Search
* Manipulation * Manipulation
* Delimiting * Delimiting
* Regex * Regex
- File Formats (`proclang/formats`) - File Formats (`fproc/formats`)
- Serialization - Serialization
- JSON - JSON
- HTML - HTML
@ -135,7 +137,7 @@ fennec should be able to use Doxygen and LaTeX externally. Consider including bi
- FBX - FBX
**MAYBE** **MAYBE**
* Compilation (`proclang/code`) * Compilation (`fproc/code`)
* Lexical Analysis * Lexical Analysis
* Syntax Analysis * Syntax Analysis
* Semantic Analysis * Semantic Analysis
@ -212,7 +214,29 @@ implementations than I could write.
## 2D Graphics (`gfx2d`) ## 2D Graphics (`gfx2d`)
- 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
@ -235,7 +259,10 @@ If you would like to make a fork, have at it, but know that I will hold a deep d
The graphics pipeline will have a buffer with a list of objects and their rendering data. 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. 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 directly and indirectly used by a scene. 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. 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. This allows the GPU to draw every single deferred rendered mesh in a single draw call for each stage of the renderer.
@ -243,13 +270,62 @@ This allows the GPU to draw every single deferred rendered mesh in a single draw
Specifications for debugging views via early breaks are included in the stages. Specifications for debugging views via early breaks are included in the stages.
### 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;
int material;
}
```
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 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 RGB Cubemap `1024, 512, 256, 128` (4)
* 16-Bit HDR RGB Texture `4096, 2048, 1024, 512` (8)
* 16-Bit HDR RGBA Texture `4096, 2048, 1024, 512` (8)
* 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)
Documentation should provide guidelines on categories of Art Assets and the resolution of textures to use.
Textures are identified by an 8-bit integer and 16-bit integer.
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.
### Stages (`gfx3d`) ### Stages (`gfx3d`)
This is the set of stages for the graphics pipeline that runs every frame: 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. Unless otherwise specified, each stage will be run on the GPU.
- BVH - BVH
- Octree - Octree `(8 Bpn, 64 bpn) [6-Layers ≈ 2.1MB]`
- Leaf Size and Tree Depth should be calculated by the scene, constraints are as follows: - Leaf Size and Tree Depth should be calculated by the scene, constraints are as follows:
- Min Object Size - Min Object Size
- Max Object Size - Max Object Size
@ -257,60 +333,61 @@ Unless otherwise specified, each stage will be run on the GPU.
- Scene Edge - Scene Edge
- Insertions and Updates are done on the CPU - Insertions and Updates are done on the CPU
- Nodes - Nodes
- ID 16-bits
- Start Index 32-bits - Start Index 32-bits
- Object Count 16-bits - Object Count 32-bits
- Objects - Objects
- Buffer of Object IDs grouped by Octree Node - Buffer of Object IDs grouped by Octree Node
- Culling - Leaf Culling
- Starting at each Octree Leaf, traverse upwards. - Starting at each Octree Leaf, traverse upwards.
- Insert Visible Leaf IDs - Insert Visible Leaf IDs
- Track using atomic buffer - Track using atomic buffer
- Output: Buffer of Visible Leaves - Generate the Command Buffer for Culled Mesh LODs from the Visible Leaf Buffer
- Track counts using atomic buffers
* LOD Selection - To avoid double counting due to the construction of the Octree output, we have some options
* Generate the Command Buffer for Culled Mesh LODs from the Visible Leaf Buffer - Ignore Leaf Instances based on occurrences of the mesh in the surrounding 8 Quadtree Leaves. This would require
* Track counts using atomic buffers a bias towards a specific corner of the filter.
* To avoid double counting due to the structure of the Octree output, we have some options - Perform a preprocessing step on the CPU to erase duplicate elements and fix the buffer continuity.
* Ignore Leaf Instances based on occurrences of the mesh in the surrounding 16 Octree Leaves. This would require - Let the duplicates be rendered.
a bias towards a specific corner of the filter. - Generate the Culled Object Buffer by copying objects from the Object Buffer
* Perform a preprocessing step on the CPU to erase duplicate elements and fix the buffer continuity. - Adjust Buffer Size using the counts
* Let the duplicates be rendered. - Insert using another atomic buffer
* Generate the Culled Object Buffer by copying objects from the Object Buffer
* Adjust Buffer Size using the counts
* Insert using another atomic buffer
Debug View: Object ID, Mesh ID, LOD Debug View: Object ID, Mesh ID, LOD
- Visibility - Visibility
- Buffer - RGB32I w/ Depth24 - Buffer `(15 Bpp, 120 bpp) [1920x1080] ≈ 39.4MB`
- G = Object ID - 24-Bit Depth Buffer
- B = Mesh ID - RGB32I Visiblity Info
- R = Object ID
- G = Mesh ID
- B = Material ID
- Regenerate the Command Buffer for Visible Mesh LODs - Regenerate the Command Buffer for Visible Mesh LODs
- Regenerate the Culled Object Buffer - Regenerate the Culled Object Buffer
Debug View: Visibility Buffer Debug View: Visibility Buffer
* G-Buffer Pass * G-Buffer Pass `(17 Bpp, 136 bpp) [1920x1080] ≈ 35.3MB`
* Depth - Stencil * Depth - Stencil → D24_S8
* 24-Bit Depth Buffer * S → used to represent the lighting model.
* 8-Bit Stencil Buffer, used to represent the lighting model. * Diffuse → RGBA8
* Diffuse - RGB8 * A → Ambient Occlusion
* Emission - RGB8 * Emission → RGB8
* Normal - RGB8 * Normal → RGB8
* Specular - RGB8 * Specular → RGB8
* R → Roughness * R → Roughness
* G → Specularity (sometimes called metallicism) * G → Specularity (sometimes called the Metallicness)
* B → Index of Refraction (IOR) * B → Index of Refraction (IOR)
Debug View: Depth, Stencil, Diffuse, Emission, Normal, Specularity Debug View: Depth, Stencil, Diffuse, Emission, Normal, Specularity
- Lighting Pass - Deferred Lighting Pass `(10 Bpp, 80 bpp) [1920x1080] ≈ 2 x 16.3MB + 8.3MB ≈ 24.6MB`
- Depth Buffer → D24
- Lighting Buffer → RGB16 (w/ Mipmapping when Bloom or DoF are enabled)
- Stencil Buffer $rarr; S8
- Generate Dynamic Shadows - Generate Dynamic Shadows
- Generate Dynamic Reflections (Optional) - Generate Dynamic Reflections (Optional)
- SSAO (Optional) - SSAO (Optional)
- Apply Lighting Model - Apply Lighting Model
- Output → RGB16
Debug View: Shadows, Reflections, SSAO, Deferred Lighting Debug View: Shadows, Reflections, SSAO, Deferred Lighting
@ -320,11 +397,13 @@ Debug View: Shadows, Reflections, SSAO, Deferred Lighting
* Translucent Materials * Translucent Materials
* Dual Depth Peeling * Dual Depth Peeling
Debug View: Deferred and Forward Mask Debug View: Forward Mask
- Post Processing - Post Processing
- Depth of Field (Optional) → Poisson Sampling - Depth of Field (Optional)
- Bloom (Optional) → Mipmap Blurring - 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) - Tonemapping (Optional)
- HDR Correction - HDR Correction
@ -355,7 +434,7 @@ Systems
* Cloth → Position-Based Dynamics * Cloth → Position-Based Dynamics
* Water * Water
* Oceans → iWave * Oceans → iWave
* Reasoning: iWave provides interactive lightweight fluid dynamics suitable for flat planes of water. Simulat * Reasoning: iWave provides interactive lightweight fluid dynamics suitable for flat planes of water.
<br><br> <br><br>
* 3D Fluid Dynamics &rarr; Smoothed-Particle Hydrodynamics * 3D Fluid Dynamics &rarr; Smoothed-Particle Hydrodynamics

View File

@ -21,7 +21,7 @@
#define FENNEC_LANG_BITS_H #define FENNEC_LANG_BITS_H
#include <fennec/lang/intrinsics.h> #include <fennec/lang/intrinsics.h>
#include <fennec/memory/memory.h> #include <fennec/lang/detail/__bits.h>
namespace fennec namespace fennec
{ {
@ -46,6 +46,20 @@ constexpr ToT bit_cast(const FromT& from)
} }
} }
constexpr void* bitmask(void* arr, const void* mask, size_t n)
{
if (arr == mask) return arr;
uint8_t* d = static_cast<uint8_t*>(arr);
const uint8_t* s = static_cast<const uint8_t*>(mask);
while (n >= 8) { detail::__bitmask_64(d, s); d += 8; s += 8; n -= 8; }
while (n >= 4) { detail::__bitmask_32(d, s); d += 4; s += 4; n -= 4; }
while (n >= 2) { detail::__bitmask_16(d, s); d += 2; s += 2; n -= 2; }
while (n >= 1) { *d++ = *s++; --n; }
return arr;
}
} }
#endif // FENNEC_LANG_BITS_H #endif // FENNEC_LANG_BITS_H

View File

@ -0,0 +1,46 @@
// =====================================================================================================================
// 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 <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#ifndef FENNEC_LANG_DETAIL_BITS_H
#define FENNEC_LANG_DETAIL_BITS_H
#include <fennec/lang/types.h>
namespace fennec
{
namespace detail
{
// helper for copying 2 bytes at once
constexpr size_t __bitmask_16(void* dst, const void* src)
{ *static_cast<uint16_t*>(dst) = *static_cast<const uint16_t*>(src); return 2; }
// helper for copying 4 bytes at once
constexpr size_t __bitmask_32(void* dst, const void* src)
{ *static_cast<uint32_t*>(dst) = *static_cast<const uint32_t*>(src); return 4; }
// helper for copying 8 bytes at once
constexpr size_t __bitmask_64(void* dst, const void* src)
{ *static_cast<uint64_t*>(dst) = *static_cast<const uint64_t*>(src); return 8; }
}
}
#endif // FENNEC_LANG_DETAIL_BITS_H

View File

@ -30,7 +30,7 @@
#ifndef FENNEC_LANG_FLOAT_H #ifndef FENNEC_LANG_FLOAT_H
#define FENNEC_LANG_FLOAT_H #define FENNEC_LANG_FLOAT_H
#include <fennec/memory/bits.h> #include <fennec/lang/bits.h>
#define FLT_HAS_INFINITY 1 #define FLT_HAS_INFINITY 1
#define FLT_HAS_QUIET_NAN 1 #define FLT_HAS_QUIET_NAN 1

View File

@ -276,7 +276,6 @@
#include <cmath> #include <cmath>
#include <fennec/math/vector.h> #include <fennec/math/vector.h>
#include <../lang/bits.h>
namespace fennec namespace fennec
{ {

View File

@ -75,6 +75,14 @@ constexpr int memcmp(const void* lhs, const void* rhs, size_t n)
return 0; return 0;
} }
///
/// \brief Safe version of memcmp
/// \copydoc fennec::memcmp
/// \param n0 The size, in bytes, of lhs
/// \param n1 The size, in bytes, of rhs
constexpr int memcmp_s(const void* lhs, size_t n0, const void* rhs, size_t n1)
{ return memcmp(lhs, rhs, n0 < n1 ? n0 : n1); }
/// ///
/// \brief Copies the first \f$n\f$ bytes of \f$src\f$ to \f$dst\f$. /// \brief Copies the first \f$n\f$ bytes of \f$src\f$ to \f$dst\f$.
/// \param dst The destination object, interpreted as an array of bytes /// \param dst The destination object, interpreted as an array of bytes
@ -101,6 +109,14 @@ constexpr void* memcpy(void* dst, const void* src, size_t n)
return dst; return dst;
} }
///
/// \brief Safe version of memcpy
/// \copydoc fennec::memcpy
/// \param n0 The size, in bytes, of dst
/// \param n1 The size, in bytes, of src
constexpr void* memcpy_s(void* dst, size_t n0, const void* src, size_t n1)
{ return memcpy(dst, src, n0 < n1 ? n0 : n1); }
/// ///
/// \brief Copies the first \f$n\f$ bytes of \f$src\f$ to \f$dst\f$, with overlap correction.. /// \brief Copies the first \f$n\f$ bytes of \f$src\f$ to \f$dst\f$, with overlap correction..
/// \param dst The destination object, interpreted as an array of bytes /// \param dst The destination object, interpreted as an array of bytes
@ -131,6 +147,14 @@ constexpr void* memmove(void* dst, const void* src, size_t n)
return dst; return dst;
} }
///
/// \brief Safe version of memmove
/// \copydoc fennec::memmove
/// \param n0 The size, in bytes, of dst
/// \param n1 The size, in bytes, of src
constexpr void* memmove_s(void* dst, size_t n0, const void* src, size_t n1)
{ return memmove(dst, src, n0 < n1 ? n0 : n1); }
/// ///
/// \brief Sets all bytes of \f$dst\f$ to \f$ch\f$, interpreted as an \f$uint8_t\f$ /// \brief Sets all bytes of \f$dst\f$ to \f$ch\f$, interpreted as an \f$uint8_t\f$
/// \param dst The destination object, interpreted as an array of bytes /// \param dst The destination object, interpreted as an array of bytes

View File

@ -3,7 +3,8 @@ project(fennec-metaprogramming)
set(CMAKE_CXX_STANDARD 26) set(CMAKE_CXX_STANDARD 26)
add_executable(fennec-metaprogramming main.cpp) add_executable(fennec-metaprogramming main.cpp
float.h)
add_custom_command( add_custom_command(
OUTPUT .metaprogramming OUTPUT .metaprogramming
COMMAND fennec-metaprogramming COMMAND fennec-metaprogramming

123
metaprogramming/float.h Normal file
View File

@ -0,0 +1,123 @@
//
// Created by medusa on 6/14/25.
//
#ifndef FENNEC_METAPROGRAMMING_FLOAT_H
#define FENNEC_METAPROGRAMMING_FLOAT_H
#include <iosfwd>
inline void float_h()
{
std::ofstream flt("float.h");
flt << "// =====================================================================================================================" << std::endl;
flt << "// fennec, a free and open source game engine" << std::endl;
flt << "// Copyright © 2025 Medusa Slockbower" << std::endl;
flt << "//" << std::endl;
flt << "// This program is free software: you can redistribute it and/or modify" << std::endl;
flt << "// it under the terms of the GNU General Public License as published by" << std::endl;
flt << "// the Free Software Foundation, either version 3 of the License, or" << std::endl;
flt << "// (at your option) any later version." << std::endl;
flt << "//" << std::endl;
flt << "// This program is distributed in the hope that it will be useful," << std::endl;
flt << "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl;
flt << "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl;
flt << "// GNU General Public License for more details." << std::endl;
flt << "//" << std::endl;
flt << "// You should have received a copy of the GNU General Public License" << std::endl;
flt << "// along with this program. If not, see <https://www.gnu.org/licenses/>." << std::endl;
flt << "// =====================================================================================================================" << std::endl;
flt << "" << std::endl;
flt << "///" << std::endl;
flt << "/// \\file float.h" << std::endl;
flt << "/// \\brief metaprogramming floating point type info" << std::endl;
flt << "///" << std::endl;
flt << "///" << std::endl;
flt << "/// \\details this file is automatically generated for the current build environment" << std::endl;
flt << "///" << std::endl;
flt << "/// \\copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))" << std::endl;
flt << "///" << std::endl;
flt << "///" << std::endl;
flt << "" << std::endl;
flt << "#ifndef FENNEC_LANG_FLOAT_H" << std::endl;
flt << "#define FENNEC_LANG_FLOAT_H" << std::endl;
flt << "" << std::endl;
flt << "#include <fennec/lang/bits.h>" << std::endl;
flt << "" << std::endl;
// TODO: Fix this to generate info without using the c++stdlib for platforms without this available.
flt << "#define FLT_HAS_INFINITY " << std::dec << std::numeric_limits<float>::has_infinity << std::endl;
flt << "#define FLT_HAS_QUIET_NAN " << std::dec << std::numeric_limits<float>::has_quiet_NaN << std::endl;
flt << "#define FLT_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits<float>::has_signaling_NaN << std::endl;
flt << "#define FLT_HAS_DENORM " << std::dec << std::numeric_limits<float>::has_denorm << std::endl;
flt << "#define FLT_HAS_DENORM_LOSS " << std::dec << std::numeric_limits<float>::has_denorm_loss << std::endl;
flt << "#define FLT_ROUNDS " << std::dec << std::numeric_limits<float>::round_style << std::endl;
flt << "#define FLT_IS_IEC559 " << std::dec << std::numeric_limits<float>::is_iec559 << std::endl;
flt << "#define FLT_MANT_DIG " << std::dec << std::numeric_limits<float>::digits << std::endl;
flt << "#define FLT_DIG " << std::dec << std::numeric_limits<float>::digits10 << std::endl;
flt << "#define FLT_DECIMAL_DIG " << std::dec << std::numeric_limits<float>::max_digits10 << std::endl;
flt << "#define FLT_RADIX " << std::dec << std::numeric_limits<float>::radix << std::endl;
flt << "#define FLT_MIN_EXP " << std::dec << std::numeric_limits<float>::min_exponent << std::endl;
flt << "#define FLT_MAX_EXP " << std::dec << std::numeric_limits<float>::max_exponent << std::endl;
flt << "#define FLT_MIN_10_EXP " << std::dec << std::numeric_limits<float>::min_exponent10 << std::endl;
flt << "#define FLT_MAX_10_EXP " << std::dec << std::numeric_limits<float>::max_exponent10 << std::endl;
flt << "#define FLT_TRAPS " << std::dec << std::numeric_limits<float>::traps << std::endl;
flt << "#define FLT_TINYNESS_BEFORE " << std::dec << std::numeric_limits<float>::tinyness_before << std::endl;
flt << "#define FLT_MIN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::min() ) << ")" << std::endl;
flt << "#define FLT_MAX " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::max() ) << ")" << std::endl;
flt << "#define FLT_EPSILON " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::epsilon() ) << ")" << std::endl;
flt << "#define FLT_INF " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::infinity() ) << ")" << std::endl;
flt << "#define FLT_QUIET_NAN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::quiet_NaN() ) << ")" << std::endl;
flt << "#define FLT_SIGNALING_NAN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::signaling_NaN()) << ")" << std::endl;
flt << "#define FLT_DENORM_MIN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::denorm_min() ) << ")" << std::endl;
flt << "#define FLT_ROUND_ERR " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::round_error() ) << ")" << std::endl;
flt << "" << std::endl;
flt << "#define DBL_HAS_INFINITY " << std::dec << std::numeric_limits<double>::has_infinity << std::endl;
flt << "#define DBL_HAS_QUIET_NAN " << std::dec << std::numeric_limits<double>::has_quiet_NaN << std::endl;
flt << "#define DBL_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits<double>::has_signaling_NaN << std::endl;
flt << "#define DBL_HAS_DENORM " << std::dec << std::numeric_limits<double>::has_denorm << std::endl;
flt << "#define DBL_HAS_DENORM_LOSS " << std::dec << std::numeric_limits<double>::has_denorm_loss << std::endl;
flt << "#define DBL_ROUNDS " << std::dec << std::numeric_limits<double>::round_style << std::endl;
flt << "#define DBL_IS_IEC559 " << std::dec << std::numeric_limits<double>::is_iec559 << std::endl;
flt << "#define DBL_MANT_DIG " << std::dec << std::numeric_limits<double>::digits << std::endl;
flt << "#define DBL_DIG " << std::dec << std::numeric_limits<double>::digits10 << std::endl;
flt << "#define DBL_DECIMAL_DIG " << std::dec << std::numeric_limits<double>::max_digits10 << std::endl;
flt << "#define DBL_RADIX " << std::dec << std::numeric_limits<double>::radix << std::endl;
flt << "#define DBL_MIN_EXP " << std::dec << std::numeric_limits<double>::min_exponent << std::endl;
flt << "#define DBL_MAX_EXP " << std::dec << std::numeric_limits<double>::max_exponent << std::endl;
flt << "#define DBL_MIN_10_EXP " << std::dec << std::numeric_limits<double>::min_exponent10 << std::endl;
flt << "#define DBL_MAX_10_EXP " << std::dec << std::numeric_limits<double>::max_exponent10 << std::endl;
flt << "#define DBL_TRAPS " << std::dec << std::numeric_limits<double>::traps << std::endl;
flt << "#define DBL_TINYNESS_BEFORE " << std::dec << std::numeric_limits<double>::tinyness_before << std::endl;
flt << "#define DBL_MIN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::min() ) << "l)" << std::endl;
flt << "#define DBL_MAX " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::max() ) << "l)" << std::endl;
flt << "#define DBL_EPSILON " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::epsilon() ) << "l)" << std::endl;
flt << "#define DBL_INF " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::infinity() ) << "l)" << std::endl;
flt << "#define DBL_QUIET_NAN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::quiet_NaN() ) << "l)" << std::endl;
flt << "#define DBL_SIGNALING_NAN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::signaling_NaN()) << "l)" << std::endl;
flt << "#define DBL_DENORM_MIN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::denorm_min() ) << "l)" << std::endl;
flt << "#define DBL_ROUND_ERR " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::round_error() ) << "l)" << std::endl;
flt << "" << std::endl;
flt << "#endif // FENNEC_LANG_FLOAT_H" << std::endl;
flt.close();
return 0;
}
#endif //FLOAT_H

View File

@ -21,113 +21,4 @@
int main(int, const char**) int main(int, const char**)
{ {
std::ofstream flt("float.h");
flt << "// =====================================================================================================================" << std::endl;
flt << "// fennec, a free and open source game engine" << std::endl;
flt << "// Copyright © 2025 Medusa Slockbower" << std::endl;
flt << "//" << std::endl;
flt << "// This program is free software: you can redistribute it and/or modify" << std::endl;
flt << "// it under the terms of the GNU General Public License as published by" << std::endl;
flt << "// the Free Software Foundation, either version 3 of the License, or" << std::endl;
flt << "// (at your option) any later version." << std::endl;
flt << "//" << std::endl;
flt << "// This program is distributed in the hope that it will be useful," << std::endl;
flt << "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl;
flt << "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl;
flt << "// GNU General Public License for more details." << std::endl;
flt << "//" << std::endl;
flt << "// You should have received a copy of the GNU General Public License" << std::endl;
flt << "// along with this program. If not, see <https://www.gnu.org/licenses/>." << std::endl;
flt << "// =====================================================================================================================" << std::endl;
flt << "" << std::endl;
flt << "///" << std::endl;
flt << "/// \\file float.h" << std::endl;
flt << "/// \\brief metaprogramming floating point type info" << std::endl;
flt << "///" << std::endl;
flt << "///" << std::endl;
flt << "/// \\details this file is automatically generated for the current build environment" << std::endl;
flt << "///" << std::endl;
flt << "/// \\copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))" << std::endl;
flt << "///" << std::endl;
flt << "///" << std::endl;
flt << "" << std::endl;
flt << "#ifndef FENNEC_LANG_FLOAT_H" << std::endl;
flt << "#define FENNEC_LANG_FLOAT_H" << std::endl;
flt << "" << std::endl;
flt << "#include <fennec/memory/bits.h>" << std::endl;
flt << "" << std::endl;
// TODO: Fix this to generate info without using the c++stdlib for platforms without this available.
flt << "#define FLT_HAS_INFINITY " << std::dec << std::numeric_limits<float>::has_infinity << std::endl;
flt << "#define FLT_HAS_QUIET_NAN " << std::dec << std::numeric_limits<float>::has_quiet_NaN << std::endl;
flt << "#define FLT_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits<float>::has_signaling_NaN << std::endl;
flt << "#define FLT_HAS_DENORM " << std::dec << std::numeric_limits<float>::has_denorm << std::endl;
flt << "#define FLT_HAS_DENORM_LOSS " << std::dec << std::numeric_limits<float>::has_denorm_loss << std::endl;
flt << "#define FLT_ROUNDS " << std::dec << std::numeric_limits<float>::round_style << std::endl;
flt << "#define FLT_IS_IEC559 " << std::dec << std::numeric_limits<float>::is_iec559 << std::endl;
flt << "#define FLT_MANT_DIG " << std::dec << std::numeric_limits<float>::digits << std::endl;
flt << "#define FLT_DIG " << std::dec << std::numeric_limits<float>::digits10 << std::endl;
flt << "#define FLT_DECIMAL_DIG " << std::dec << std::numeric_limits<float>::max_digits10 << std::endl;
flt << "#define FLT_RADIX " << std::dec << std::numeric_limits<float>::radix << std::endl;
flt << "#define FLT_MIN_EXP " << std::dec << std::numeric_limits<float>::min_exponent << std::endl;
flt << "#define FLT_MAX_EXP " << std::dec << std::numeric_limits<float>::max_exponent << std::endl;
flt << "#define FLT_MIN_10_EXP " << std::dec << std::numeric_limits<float>::min_exponent10 << std::endl;
flt << "#define FLT_MAX_10_EXP " << std::dec << std::numeric_limits<float>::max_exponent10 << std::endl;
flt << "#define FLT_TRAPS " << std::dec << std::numeric_limits<float>::traps << std::endl;
flt << "#define FLT_TINYNESS_BEFORE " << std::dec << std::numeric_limits<float>::tinyness_before << std::endl;
flt << "#define FLT_MIN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::min() ) << ")" << std::endl;
flt << "#define FLT_MAX " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::max() ) << ")" << std::endl;
flt << "#define FLT_EPSILON " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::epsilon() ) << ")" << std::endl;
flt << "#define FLT_INF " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::infinity() ) << ")" << std::endl;
flt << "#define FLT_QUIET_NAN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::quiet_NaN() ) << ")" << std::endl;
flt << "#define FLT_SIGNALING_NAN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::signaling_NaN()) << ")" << std::endl;
flt << "#define FLT_DENORM_MIN " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::denorm_min() ) << ")" << std::endl;
flt << "#define FLT_ROUND_ERR " << "fennec::bit_cast<float>(0x" << std::hex << std::bit_cast<int>(std::numeric_limits<float>::round_error() ) << ")" << std::endl;
flt << "" << std::endl;
flt << "#define DBL_HAS_INFINITY " << std::dec << std::numeric_limits<double>::has_infinity << std::endl;
flt << "#define DBL_HAS_QUIET_NAN " << std::dec << std::numeric_limits<double>::has_quiet_NaN << std::endl;
flt << "#define DBL_HAS_SIGNALING_NAN " << std::dec << std::numeric_limits<double>::has_signaling_NaN << std::endl;
flt << "#define DBL_HAS_DENORM " << std::dec << std::numeric_limits<double>::has_denorm << std::endl;
flt << "#define DBL_HAS_DENORM_LOSS " << std::dec << std::numeric_limits<double>::has_denorm_loss << std::endl;
flt << "#define DBL_ROUNDS " << std::dec << std::numeric_limits<double>::round_style << std::endl;
flt << "#define DBL_IS_IEC559 " << std::dec << std::numeric_limits<double>::is_iec559 << std::endl;
flt << "#define DBL_MANT_DIG " << std::dec << std::numeric_limits<double>::digits << std::endl;
flt << "#define DBL_DIG " << std::dec << std::numeric_limits<double>::digits10 << std::endl;
flt << "#define DBL_DECIMAL_DIG " << std::dec << std::numeric_limits<double>::max_digits10 << std::endl;
flt << "#define DBL_RADIX " << std::dec << std::numeric_limits<double>::radix << std::endl;
flt << "#define DBL_MIN_EXP " << std::dec << std::numeric_limits<double>::min_exponent << std::endl;
flt << "#define DBL_MAX_EXP " << std::dec << std::numeric_limits<double>::max_exponent << std::endl;
flt << "#define DBL_MIN_10_EXP " << std::dec << std::numeric_limits<double>::min_exponent10 << std::endl;
flt << "#define DBL_MAX_10_EXP " << std::dec << std::numeric_limits<double>::max_exponent10 << std::endl;
flt << "#define DBL_TRAPS " << std::dec << std::numeric_limits<double>::traps << std::endl;
flt << "#define DBL_TINYNESS_BEFORE " << std::dec << std::numeric_limits<double>::tinyness_before << std::endl;
flt << "#define DBL_MIN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::min() ) << "l)" << std::endl;
flt << "#define DBL_MAX " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::max() ) << "l)" << std::endl;
flt << "#define DBL_EPSILON " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::epsilon() ) << "l)" << std::endl;
flt << "#define DBL_INF " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::infinity() ) << "l)" << std::endl;
flt << "#define DBL_QUIET_NAN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::quiet_NaN() ) << "l)" << std::endl;
flt << "#define DBL_SIGNALING_NAN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::signaling_NaN()) << "l)" << std::endl;
flt << "#define DBL_DENORM_MIN " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::denorm_min() ) << "l)" << std::endl;
flt << "#define DBL_ROUND_ERR " << "fennec::bit_cast<double>(0x" << std::hex << std::bit_cast<long long>(std::numeric_limits<double>::round_error() ) << "l)" << std::endl;
flt << "" << std::endl;
flt << "#endif // FENNEC_LANG_FLOAT_H" << std::endl;
flt.close();
return 0;
} }