barebones documentation, commit in case I butcher code migration
This commit is contained in:
parent
0b40786798
commit
acfadd5c2d
@ -116,10 +116,10 @@
|
||||
"gui": true,
|
||||
"vsync": false,
|
||||
"hdr": true,
|
||||
"vxgi": true,
|
||||
"vxgi": false,
|
||||
"culling": true,
|
||||
"bloom": true,
|
||||
"rt": false,
|
||||
"rt": true,
|
||||
"fsr": false,
|
||||
"postProcess": false // "postProcess.chromab" // false
|
||||
},
|
||||
|
@ -1,32 +0,0 @@
|
||||
{
|
||||
"name": "Gui: Loading",
|
||||
"type": "Object",
|
||||
"behaviors": [
|
||||
// "GuiBehavior"
|
||||
],
|
||||
"assets": [
|
||||
{ "filename": "./sm64.json", "delay": 0 }
|
||||
],
|
||||
"ignore": false,
|
||||
"transform": {
|
||||
"position": [ -0.830591, -0.699509, 0 ],
|
||||
"rotation": {
|
||||
"axis": [ 1, 0, 0 ],
|
||||
"angle": 0
|
||||
},
|
||||
"scale": [ 0.258737, 0.115371, 1 ]
|
||||
},
|
||||
"metadata": {
|
||||
"uv": [ 0, 0, 1, 1 ],
|
||||
"color": [ 1, 1, 1, 0.1 ],
|
||||
"location": "",
|
||||
"scaling": "relative",
|
||||
"text settings": {
|
||||
"stroke": [ 1, 0.749, 0.368, 1 ],
|
||||
"color": [ 1, 0.749, 0.368, 1 ],
|
||||
|
||||
"string": "Loading...",
|
||||
"string1": "コマンド"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"import": "/player.json",
|
||||
"assets": [
|
||||
// { "filename": "/gui/hud/hud.json", "delay": 0 }
|
||||
],
|
||||
"metadata": {
|
||||
"movement": {
|
||||
"jump": [0, 1, 0],
|
||||
"floored": {
|
||||
"feet": [ 0, 0, 0 ],
|
||||
"floor": [ 0, -0.8, 0 ]
|
||||
}
|
||||
},
|
||||
"physics": {
|
||||
"radius": 0.25,
|
||||
"height": 0.25
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
{
|
||||
"import": "/scene.json",
|
||||
"assets": [
|
||||
// "./loading.json",
|
||||
"./sm64.json"
|
||||
],
|
||||
"metadata": {
|
||||
"light": {
|
||||
// "ambient": [ 0, 0, 0 ],
|
||||
// "ambient": [ 0.025, 0.025, 0.025 ],
|
||||
// "ambient": [ 0.075, 0.075, 0.075 ],
|
||||
"ambient": [ 0.1, 0.1, 0.1 ],
|
||||
// "ambient": [ 0.4, 0.4, 0.4 ],
|
||||
// "ambient": [ 0.8, 0.8, 0.8 ],
|
||||
|
||||
"fog-": {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
{
|
||||
"import": "/model.json",
|
||||
"assets": [
|
||||
{ "filename": "./models/sm64_bbb.glb" }
|
||||
// { "filename": "./models/sm64_bbb/graph.json" }
|
||||
],
|
||||
"metadata": {
|
||||
"graph": {
|
||||
"baking": { "enabled": true },
|
||||
"renderer": {
|
||||
"cull mode": "none",
|
||||
"filter": "nearest"
|
||||
},
|
||||
"tags": {
|
||||
"/^worldspawn/": {
|
||||
"physics": { "type": "mesh", "static": true },
|
||||
"grid": { "size": [3,1,3], "epsilon": 1.0, "cleanup": true, "print": true },
|
||||
"optimize mesh": { "simplify": 0 },
|
||||
"unwrap mesh": true
|
||||
},
|
||||
"info_player_spawn": { "action": "attach", "filename": "./player.json" },
|
||||
|
||||
"Material.071_574B138E_c.bmp": { "material": { "modeAlpha": "blend" } },
|
||||
"Material.070_41A41EE3_c.bmp": { "material": { "modeAlpha": "blend" } },
|
||||
|
||||
"light_sun": { "light": { "power": 25000000 } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
// "import": "./rp_downtown_v2.json"
|
||||
"import": "./ss2_medsci1.json"
|
||||
// "import": "./ss2_medsci1.json"
|
||||
// "import": "./sh2_mcdonalds.json"
|
||||
// "import": "./animal_crossing.json"
|
||||
// "import": "./mds_mcdonalds.json"
|
||||
"import": "./mds_mcdonalds.json"
|
||||
// "import": "./gm_construct.json"
|
||||
}
|
@ -1 +1 @@
|
||||
opengl
|
||||
vulkan
|
@ -7,32 +7,35 @@ To be filled.
|
||||
* a Unity-like ECS + scene + asset system
|
||||
* entities stores components and behaviors
|
||||
* scenes load a tree of entities
|
||||
* entities are defined through JSON files (which are processed as gunzipped msgpacks for subsequent loads) which can reference assets or further entities
|
||||
* entities are defined through JSON files which can reference assets or other JSON files, and can instantiate other entities
|
||||
* Lua to extend the engine
|
||||
* Garry's Mod-like hook system for dispatching events
|
||||
* events are dispatched through the hook system by sending a payload to hooks tied to a given name / payload type
|
||||
* by default, these are JSON payloads, but most internal hooks send unique structs instead
|
||||
* events are dispatched through the hook system by sending objects hooks tied to a given name + payload type
|
||||
* Vulkan (or OpenGL) as the rendering backend
|
||||
* the Vulkan backend heavily makes use of an almost-GPU driven deferred rendering system
|
||||
* "G-buffer" can consist solely of IDs, barycentrics, and depth, and all geometry information is then reconstructed during the deferred compute pass
|
||||
* "G-buffer" can consist solely of IDs and depth, and all geometry information is then reconstructed during the deferred compute pass
|
||||
* optionally can fall back to a quasi-traditional setup of IDs, UVs, normals, and depth
|
||||
* shadow maps are rendered to each light's shadow maps
|
||||
* point lights are treated as a cubemap
|
||||
* optional light map baking
|
||||
* basic PBR shading
|
||||
* a sovlful (sloppy) VXGI for GI and reflections
|
||||
* (partially broken) hardware RT support
|
||||
* hardware RT support via `VK_KHR_ray_query`
|
||||
* "full" `VK_KHR_ray_tracing` mode is partially broken
|
||||
* bloom and additional post processing
|
||||
* FSR2 or something cringe
|
||||
* OpenGL uses a very, very naive OpenGL 1.2 API with a homebrewed command recording system
|
||||
* pre-baked light maps can be loaded for lighting
|
||||
* ReactPhysics3D for physics
|
||||
* *very* loosely integrated
|
||||
* basic shapes and triangulated mesh collision and some form of ray queries
|
||||
* OpenAL for audio
|
||||
* Currently only loads from `.ogg` (vorbis) files
|
||||
* Supports loading in full and streaming
|
||||
* Loads from `.ogg` or `.wav` files
|
||||
* Supports loading in full and streaming
|
||||
* *very* loosely integrated
|
||||
* Speech synthesis using [vall_e.cpp](https://github.com/e-c-k-e-r/vall-e/)
|
||||
* `win64.gcc.vulkan` binaries can be found [here](https://github.com/e-c-k-e-r/vall-e/releases/tag/vall_e.cpp), if compiled.
|
||||
* currently only generates `.wav` files
|
||||
* `win64.gcc.vulkan` binaries can be found [here](https://github.com/e-c-k-e-r/vall-e/releases/tag/vall_e.cpp), if compiled with `-DUF_USE_VALL_E`
|
||||
* asynchronously synthesizes speech and plays back the PCM audio
|
||||
|
||||
## Supported Systems
|
||||
|
||||
|
37
docs/bin.md
Normal file
37
docs/bin.md
Normal file
@ -0,0 +1,37 @@
|
||||
# `bin/`
|
||||
|
||||
This folder contains the engine binaries and game data. For all intents and purposes, `bin/` can be any folder name.
|
||||
|
||||
## `bin/data`
|
||||
|
||||
This folder contains the necessary game data loaded by the engine. This *can* be modified as it's tied to `uf::io::root`.
|
||||
|
||||
### `bin/data/config.json`
|
||||
|
||||
This JSON contains application-specific configuration data.
|
||||
|
||||
### `bin/data/audio/`
|
||||
|
||||
### `bin/data/cache/`
|
||||
|
||||
### `bin/data/entities/`
|
||||
|
||||
### `bin/data/fonts/`
|
||||
|
||||
### `bin/data/html/`
|
||||
|
||||
### `bin/data/log/`
|
||||
|
||||
### `bin/data/llm/`
|
||||
|
||||
### `bin/data/models/`
|
||||
|
||||
### `bin/data/scenes/`
|
||||
|
||||
### `bin/data/screenshots/`
|
||||
|
||||
### `bin/data/scripts/`
|
||||
|
||||
### `bin/data/shaders/`
|
||||
|
||||
### `bin/data/textures/`
|
15
docs/client.md
Normal file
15
docs/client.md
Normal file
@ -0,0 +1,15 @@
|
||||
# `client/`
|
||||
|
||||
This section of the project solely governs the executable and the outer layer of the program.
|
||||
|
||||
Its sole purpose is to:
|
||||
* attach signal handlers
|
||||
* initialize the engine
|
||||
* create the window and hook its events into the engine
|
||||
* the engine tick loop
|
||||
* terminate the engine
|
||||
|
||||
Additional logic *can* be added such as:
|
||||
* integrity checks
|
||||
* update handling
|
||||
* loading additional DLLs
|
558
docs/engine.md
Normal file
558
docs/engine.md
Normal file
@ -0,0 +1,558 @@
|
||||
# `engine/`
|
||||
|
||||
This section of the project handles all the systems and structs needed for the engine.
|
||||
|
||||
This is further divided into four parts:
|
||||
* `utils`: lower level systems and structs that the engine may need
|
||||
* `engine`: contains the highest level of objects used for the engine
|
||||
* `ext`: any abstraction that implements an external library
|
||||
* `spec`: any abstraction that requires specialization / platform-specific code
|
||||
|
||||
Confusingly, these namespaces are exposed:
|
||||
* `pod`: (mostly) contains plain-old-data structs, as they're safe to directly interact with its members, and get operated on through functions under `uf::{namespace}`
|
||||
* `uf`: contains complex classes whose underlying members are not safe to directly interact with; contains their own member functions
|
||||
* `ext`: contains code that directly interacts with external libraries; typically shouldn't be directly invoked
|
||||
|
||||
This documentation is barebones as actual more examples and detailing of the functions provided are required, rather than just the classes and namespaces exposed. However, some examples are provided.
|
||||
|
||||
## `engine/utils/`
|
||||
|
||||
### `engine/utils/audio/`
|
||||
|
||||
This provides the `uf::Audio`, `uf::AudioEmitter` and `uf::MappedAudioEmitter` classes.
|
||||
|
||||
### `engine/utils/camera/`
|
||||
|
||||
This provides the `uf::Camera` class.
|
||||
|
||||
### `engine/utils/component/`
|
||||
|
||||
This provides the `uf::Component` system, allowing an entity to own `pod::Component<T>`s.
|
||||
|
||||
A `uf::Component` maps a `pod::Component<T>` by its underlying userdata typing.
|
||||
|
||||
`.hasComponent<T>()` can be used to check if an entity has a component.
|
||||
|
||||
By default, `.getComponent<T>()` will automatically invoke `.addComponent<T>()` if that component isn't already added.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& camera = this->getComponent<uf::Camera>();
|
||||
|
||||
// only do something if there's already a physics state
|
||||
if ( this->hasComponent<pod::PhysicsState>() ) {
|
||||
auto& physics = this->getComponent<pod::PhysicsState>();
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### `engine/utils/hook/`
|
||||
|
||||
This provides the `uf::hooks` system, allowing data and events to dispatch across the engine to anyone listening to the hook name and payload type.
|
||||
|
||||
Confusingly, this is a singleton and not a namespace to allow for separate hook pools to be utilized, although this usecase is currently not used.
|
||||
|
||||
While it's not usually used this way, return types from a hook are collected into a `uf::stl::vector<uf::Userdata>` returned by `uf::hooks.callHook`.
|
||||
|
||||
Arguments passed by non-`const` reference can mutate along for other hooks to see.
|
||||
|
||||
Examples:
|
||||
```
|
||||
// add a hook
|
||||
uf::hooks.addHook( "llm:VALL-E.synthesize", [&](ext::json::Value& json){
|
||||
auto text = json["text"].as<uf::stl::string>();
|
||||
auto prom = json["prom"].as<uf::stl::string>();
|
||||
auto play = json["play"].as<bool>();
|
||||
auto callback = json["callback"].as<uf::stl::string>("");
|
||||
|
||||
uf::thread::queue( uf::thread::asyncThreadName, [=](){
|
||||
auto waveform = ext::vall_e::generate( text, prom );
|
||||
if ( callback != "" ) {
|
||||
uf::hooks.call( callback, waveform );
|
||||
} else if ( play ) {
|
||||
uf::Audio audio;
|
||||
audio.load( waveform );
|
||||
audio.play();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// dispatch via JSON
|
||||
ext::json::Value payload;
|
||||
payload["text"] = "The birch canoe slid on the smooth planks.";
|
||||
payload["prom"] = "./data/tmp/prom.wav";
|
||||
payload["play"] = true;
|
||||
uf::hooks.call( "llm:VALL-E.synthesize", payload );
|
||||
```
|
||||
|
||||
```
|
||||
// or through a payload struct
|
||||
struct TTSPayload {
|
||||
uf::stl::string text;
|
||||
uf::stl::string prom;
|
||||
};
|
||||
|
||||
uf::hooks.addHook( "llm:VALL-E.synthesize", [&]( TTSPayload& payload ){
|
||||
return ext::vall_e::generate( payload.text, payload.prom );
|
||||
});
|
||||
|
||||
auto waveform = uf::hooks.callHook("llm:VALL-E.synthesize", {
|
||||
"The birch canoe slid on the smooth planks.", "./data/tmp/prom.wav"
|
||||
})[0];
|
||||
```
|
||||
|
||||
### `engine/utils/http/`
|
||||
|
||||
This provides the `uf::http` system through cURL.
|
||||
|
||||
Currently, only `uf::http::get` is provided for `GET`ting resources.
|
||||
|
||||
### `engine/utils/image/`
|
||||
|
||||
This provides the `uf::Image` class for storing image data.
|
||||
|
||||
Images are loaded as `RGBA8` buffers using [nothings/stb](https://github.com/nothings/stb)'s `stb_image`.
|
||||
|
||||
#### `engine/utils/image/atlas`
|
||||
|
||||
This provides the `uf::Atlas` class for storing images into an atlas, using [InfinityTools/binpack2d](https://github.com/InfinityTools/binpack2d) as the packer.
|
||||
|
||||
### `engine/utils/io/`
|
||||
|
||||
This folder provies:
|
||||
* `uf::console`
|
||||
* `uf::io`
|
||||
* `uf::inputs`
|
||||
* `uf::IoStream`
|
||||
|
||||
### `engine/utils/math/`
|
||||
|
||||
This folder provides:
|
||||
* `pod::Vector<>`
|
||||
* examples: `pod::Vector3f`, `pod::Vector4f`, `pod::Vector2ui`, `pod::Vector<6, char>`
|
||||
* `pod::Quaternion<>`
|
||||
* `pod::Matrix<>`
|
||||
* example: `pod::Matrix4f`
|
||||
* `pod::Transform<>`
|
||||
* `uf::quant`
|
||||
* `uf::physics`
|
||||
* unused collision detection
|
||||
* and other things
|
||||
|
||||
To-do: document the `uf::vector`, `uf::quaternion`, `uf::matrix`, `uf::transform` namespaces
|
||||
|
||||
### `engine/utils/memory/`
|
||||
|
||||
This folder provides wrappers for STL containers to optionally integrate with the internal memory pools:
|
||||
* `uf::stl::vector`
|
||||
* `uf::stl::unordered_map`
|
||||
* `uf::stl::fifo_map`
|
||||
* `uf::stl::KeyMap`
|
||||
* `uf::stl::deque`
|
||||
* `uf::stl::stack`
|
||||
* `uf::stl::queue`
|
||||
* `uf::stl::map`
|
||||
|
||||
And the memory pool through `uf::memoryPool`.
|
||||
|
||||
### `engine/utils/mesh/`
|
||||
|
||||
This contains
|
||||
* a struct for attribute descriptors
|
||||
* vertex descriptors for meshes
|
||||
* structs for draw commands, instances, and primitives
|
||||
* a generic class `uf::Mesh` for inserting and binding vertex data for rendering
|
||||
|
||||
#### `engine/mesh/grid`
|
||||
|
||||
This contains `uf::meshgrid` for slicing a mesh into grids.
|
||||
|
||||
This is primarily only used within `engine/ext/gltf/gltf.cpp` for partitioning existing models before saving to the engine's internal format.
|
||||
|
||||
This *can* be invoked outside of this context, but currently does is not used beyond the above use-case.
|
||||
|
||||
### `engine/utils/noise/`
|
||||
|
||||
This provides noising functions, such as perlin noise through `uf::PerlinNoise`.
|
||||
|
||||
However, this implementation is quite cringe as it's from 2013 or 2014.
|
||||
|
||||
### `engine/utils/resolveable/`
|
||||
|
||||
This provides a wrapper class `pod::Resolveable<T>` that either returns its ID or its pointer type. This is seldomly used for handling entity information, where it can be defined by its UID or pointer directly.
|
||||
|
||||
### `engine/utils/serialize/`
|
||||
|
||||
This provides `uf::Serializer`, a wrapper around `ext::json::Value` to read from / write to disk.
|
||||
|
||||
For the most part, this is used interchangeably with `ext::json::Value`.
|
||||
|
||||
### `engine/utils/singletons/`
|
||||
|
||||
This provides `uf::StaticInitialization`, a cringe way to implement pre-`main()` static initialization through singletons.
|
||||
|
||||
This is primarily used for registering component enums through Lua.
|
||||
|
||||
### `engine/utils/string/`
|
||||
|
||||
This provides a myriad of string functions through `uf::string`.
|
||||
|
||||
### `engine/utils/text/`
|
||||
|
||||
This provides `uf::Glyph`, a wrapper around `FreeType2` for holding glyph information.
|
||||
|
||||
This shouldn't directly be interfaced with, as the GUI system handles this.
|
||||
|
||||
### `engine/utils/thread/`
|
||||
|
||||
This provides `uf::thread` system for multithreading.
|
||||
|
||||
For the most part, this should only be interfaced per the example:
|
||||
```
|
||||
// something asynchronously
|
||||
uf::thread::queue( uf::thread::asyncThreadName, [=](){
|
||||
// ...
|
||||
});
|
||||
```
|
||||
```
|
||||
// something via a worker thread
|
||||
uf::thread::queue( uf::thread::fetchWorker(), [=](){
|
||||
// ...
|
||||
});
|
||||
```
|
||||
```
|
||||
auto tasks = uf::thread::schedule(true); // true to multithread, false to not
|
||||
tasks.queue([&](){
|
||||
// ...
|
||||
})
|
||||
uf::thread::execute( tasks );
|
||||
```
|
||||
|
||||
### `engine/utils/time/`
|
||||
|
||||
This provides `uf::Timer<>` and `uf::time`, time and timer related functions.
|
||||
|
||||
For the most part, timers are used via a macro, and deltaTime is grabbed through `uf::physics::time::delta`.
|
||||
|
||||
### `engine/utils/userdata/`
|
||||
|
||||
This provides `uf::userdata` and `uf::pointeredUserdata` (to-do: alias the latter into the former), where `pod::Userdata` (and the `uf::Userdata` wrapper) contains arbitrary userdata identified by its size and type.
|
||||
|
||||
For the most part, this shouldn't directly be interfaced, as this is used for other systems to operate, but an example:
|
||||
```
|
||||
someMap[k] = uf::userdata::create<uf::Camera>();
|
||||
// ...
|
||||
auto& v = uf::userdata::get<T>( someMap[key] );
|
||||
// ...
|
||||
if ( someMap[k] ) uf::userdata::destroy( someMap[k] );
|
||||
```
|
||||
|
||||
## `engine/engine/`
|
||||
|
||||
### `engine/engine/asset/`
|
||||
|
||||
This implements the `uf::asset` system which governs asset loading.
|
||||
|
||||
Assets can be cached for subsequent loads.
|
||||
|
||||
When an asset is loaded, it's dispatched through the hook system by invoking the hook name specified as its callback (usually `asset:Load.%UID%`).
|
||||
|
||||
This shouldn't be directly invoked, rather utilized through an entity's JSON configuration or existing hooks (usually `asset:QueueLoad.%UID%`).
|
||||
|
||||
Assets can implicitly resolve absolutely based on the extension per `uf::io::resolveURI`.
|
||||
|
||||
|
||||
### `engine/engine/behavior/`
|
||||
|
||||
This implements the `pod::Behavior` struct and `uf::Behaviors` system.
|
||||
|
||||
`pod::Behavior` stores function pointers for the primary entity functions:
|
||||
* `initialize`: called on entity initialization
|
||||
* `tick`: called when the engine ticks
|
||||
* `render`: called when a render mode ticks for rendering
|
||||
* `destroy`: called when the entity is to be destroyed
|
||||
|
||||
`uf::Behaviors` is a class for instantiation to handle an entity's list of behaviors. A graph is generated that flattens a scene graph tree for subsequent use.
|
||||
|
||||
This should ***never*** be directly interfaced with. Macros handle everything required, and reference to these macros can be found in any `behavior.cpp` and `behavior.h` pairs.
|
||||
|
||||
### `engine/engine/entity/`
|
||||
|
||||
This implements `uf::Entity` and `uf::EntityBehavior`, the core for an entity in this engine.
|
||||
|
||||
`uf::Entity` *should* handle the lowest level functions needed, such as UID and name, its parent and children, and containing its components and behaviors.
|
||||
|
||||
### `engine/engine/graph/`
|
||||
|
||||
This system implements everything for rendering objects in a scene.
|
||||
|
||||
A `pod::Graph` contains all the information needed to render a scene, from its textures and material information, to meshes, instance information, animations, to draw calls and how additional entities are to be loaded.
|
||||
|
||||
*Anything* non-GUI entity is expected to be registered through here. Having said that, the object system should handle the gorey details of passing an entity through here.
|
||||
|
||||
Additional functions:
|
||||
* `uf::graph::convert` handles "importing" a naive entity scene graph into the `uf::graph` graph system.
|
||||
* `uf::graph::load` handles loading, from disk, a pre-processed scene graph into the engine.
|
||||
* `uf::graph::save` handles saving, to disk, a scene graph to disk.
|
||||
|
||||
### `engine/engine/instantiator/`
|
||||
|
||||
This implements the `uf::instantiator` system, which governs instantiating entities as objects against a given list of object names and behavior names.
|
||||
|
||||
This system is responsible for binding behaviors to a named entity type, but use of this feature seems to have been removed in favor of another implementation.
|
||||
|
||||
For the most part, this does handle allocation and garbage collection of entities.
|
||||
|
||||
### `engine/engine/object/`
|
||||
|
||||
This implements `uf::Object` and `uf::ObjectBehavior`, where an object extends upon an entity by implementing additional features, such as:
|
||||
* instantiating the object and initializing components per the configuration JSON
|
||||
* pre-defined cleanup behaviors for given components
|
||||
* resolving relative pathnames and relative hook names
|
||||
* asset loading
|
||||
* processing hooks (adding, calling, queueing)
|
||||
* reloading from the JSON when its updated
|
||||
|
||||
If `UF_ENTITY_OBJECT_UNIFIED` is set, then an entity and an object are truly interchangeable, but for the most part one can be casted to the other.
|
||||
|
||||
|
||||
### `engine/engine/scene/`
|
||||
|
||||
This implements `uf::Scene` and `uf::SceneBehavior` structs and the `uf::scene` system.
|
||||
|
||||
A scene contains all of its entities, and orchestrates the scene graph. A scene is responsible for finding a controller (and thus camera) for a given render mode,
|
||||
|
||||
A scene's JSON is defined under `./data/scene/{name}/` and can be directly loaded on startup under `./data/config.json`'s `engine.scene.start` value.
|
||||
|
||||
While it's not utilized, additional scenes can be loaded onto the stack, or unloaded to "go back" to the prior scene.
|
||||
|
||||
## `engine/ext/`
|
||||
|
||||
### `engine/ext/audio/`
|
||||
|
||||
This abstracts audio codecs for use under OpenAL.
|
||||
|
||||
Currently implemented:
|
||||
* `pcm`: processes raw PCM audio into buffers
|
||||
* `vorbis`: processes audio from an `.ogg` file through `libvorbis` (or `libtremor`) into buffers
|
||||
* `wav`: processes audio from a `.wav` file through `dr_wav` into buffers
|
||||
|
||||
Audio is first read for its metadata, then either fully loaded into one buffer, or streamed into smaller buffers.
|
||||
|
||||
Enabled through their respective compile feature flag, and flagged through their respective `UF_USE_{NAME}` flags.
|
||||
|
||||
### `engine/ext/discord/`
|
||||
|
||||
This abstracts around the Discord library for activity integration.
|
||||
|
||||
For the most part this is left uncompiled as it was just a loose gimmick by dispatching through the `discord:Activity.Update` hook.
|
||||
|
||||
Enabled through the `discord` compile feature flag, and flagged through `UF_USE_DISCORD`.
|
||||
|
||||
### `engine/ext/ffx/`
|
||||
|
||||
This abstracts around AMD's FSR2 library.
|
||||
|
||||
This is *semi*-unused as I need to update it to FSR3, and it's a bit of a sloppy implementation, given how much pain was needed to get it to compile under GCC and how poor the documentation was.
|
||||
|
||||
Enabled through the `ffx:fsr` compile feature flag, and flagged through `UF_USE_FFX_FSR`.
|
||||
|
||||
### `engine/ext/freetype/`
|
||||
|
||||
This abstracts around FreeType2 for creating bitmaps for a given font file, as well as provide metrics for a given glyph.
|
||||
|
||||
Enabled through the `freetype` compile feature flag, and flagged through `UF_USE_FREETYPE`.
|
||||
|
||||
### `engine/ext/gltf/`
|
||||
|
||||
This abstracts around the GTLf file specification through `tiny_gltf`.
|
||||
|
||||
For the most part, this handles loading a `.gltf` (or `.glb`) and processes it through the engine's `uf::graph` system, from which it can be saved to disk using its own internal format.
|
||||
|
||||
Enabled through the `gltf` compile feature flag, and flagged through `UF_USE_GLTF`.
|
||||
|
||||
### `engine/ext/imgui/`
|
||||
|
||||
This abstracts around the `Dear ImGui` library for a more-in-depth GUI system.
|
||||
|
||||
For the most part, this only (poorly) implements a console window.
|
||||
|
||||
Enabled through the `imgui` compile feature flag, and flagged through `UF_USE_IMGUI`.
|
||||
|
||||
### `engine/ext/json/`
|
||||
|
||||
This abstracts around [nlohmann/json](https://github.com/nlohmann/json) to provide an `ext::json::Value` object and `ext::json` namespace for operating on JSON objects.
|
||||
|
||||
Enabled through the `json:nlohmann` compile feature flag, and flagged through `UF_JSON_USE_NLOHMANN`.
|
||||
* it is ***highly*** recommended to enable this.
|
||||
|
||||
### `engine/ext/lua/`
|
||||
|
||||
This abstracts around Lua through [ThePhD/sol2](https://github.com/ThePhD/sol2) to extend the engine through Lua scripts.
|
||||
|
||||
Usertypes are provided under `engine/ext/lua/usertypes`:
|
||||
* `uf::Asset`
|
||||
* `uf::Audio`
|
||||
* `uf::Camera`
|
||||
* `pod::Matrix4f`
|
||||
* `uf::Object`
|
||||
* `pod::Physics`
|
||||
* `pod::Quaternion<>`
|
||||
* `uf::Timer<>`
|
||||
* `pod::Transform<>`
|
||||
* `pod::Vector<>`
|
||||
|
||||
On load, `./data/scripts/main.lua` is called, although nothing is directly in there yet.
|
||||
|
||||
Additional library tables are provided that map to internal engine functions through:
|
||||
* `hooks.add`: `uf::hooks::addHook`
|
||||
* `hooks.call`: `uf::hooks::callHook`
|
||||
* `entities.get`
|
||||
* `entities.currentScene`: `uf::scene::getCurrentScene`
|
||||
* `entities.controller`: `uf::scene::getCurrentScene().getController`
|
||||
* `entities.destroy`: `self:queueDeletion`
|
||||
* `string.extension`: `uf::string::extension`
|
||||
* `string.resolveURI`: `uf::string::resolveURI`
|
||||
* `string.si`: `uf::string::si`
|
||||
* `string.match`: `uf::string::match`
|
||||
* `string.matched`: `uf::string::matched`
|
||||
* `io.print`
|
||||
* `math.clamp`: `math::clamp`
|
||||
* `time.current`: `uf::physics::time::current`
|
||||
* `time.previous`: `uf::physics::time::previous`
|
||||
* `time.delta`: `uf::physics::time::delta`
|
||||
* `json.pretty`: `uf::Serializer::serialize`
|
||||
* `json.readFromFile`: `uf::Serializer::readFromFile`
|
||||
* `json.writeToFile`: `uf::Serializer::writeToFile`
|
||||
* `window.keyPressed`: `uf::Window::isKeyPressed`
|
||||
* `os.arch`: `UF_ENV`
|
||||
* `inputs.key`: `uf::inputs::key`
|
||||
* `inputs.analog`: `uf::inputs::analog`
|
||||
* `inputs.analog2`: `uf::inputs::analog2`
|
||||
|
||||
Enabled through the `lua` compile feature flag, and flagged through `UF_USE_LUA`.
|
||||
|
||||
### `engine/ext/meshopt/`
|
||||
|
||||
This abstracts around [zeux/meshoptimizer](https://github.com/zeux/meshoptimizer) to optimize meshes.
|
||||
|
||||
For the most part, this is automatically called when loading from a gLTF file.
|
||||
|
||||
The `ext::meshopt` namespace is provided if needed.
|
||||
|
||||
Enabled through the `meshopt` compile feature flag, and flagged through `UF_USE_MESHOPT`.
|
||||
|
||||
### `engine/ext/oal/`
|
||||
|
||||
This abstracts around OpenAL for the audio system through `ext::al`.
|
||||
|
||||
Most OpenAL parameters are handled. This shouldn't directly be invoked, as it's handled through `uf::Audio`
|
||||
|
||||
Enabled through the `openal` compile feature flag, and flagged through `UF_USE_OPENAL`.
|
||||
|
||||
### `engine/ext/opengl/`
|
||||
|
||||
This abstracts around OpenGL to provide the rendering system.
|
||||
|
||||
Most of this is enough to allow the engine to render using OpenGL 1.2.
|
||||
|
||||
A hand-crafted command buffer system is provided through `engine/ext/opengl/commands.cpp` to keep it seamlessly integrated with the engine that was primarily Vulkan-integrated.
|
||||
|
||||
Enabled through the `opengl` compile feature flag, and flagged through `UF_USE_OPENGL`.
|
||||
|
||||
### `engine/ext/openvr/`
|
||||
|
||||
This abstracts around [ValveSoftware/openvr](https://github.com/ValveSoftware/openvr) to provide VR support.
|
||||
|
||||
Support needs to be repaired as the rendering system was modified heavily after adding VR support.
|
||||
|
||||
Enabled through the `openvr` compile feature flag, and flagged through `UF_USE_OPENVR`.
|
||||
|
||||
### `engine/ext/reactphysics/`
|
||||
|
||||
This abstracts around [DanielChappuis/reactphysics3d](https://github.com/DanielChappuis/reactphysics3d) to provide a physics system through `uf::physics`.
|
||||
|
||||
Confusingly, this aliases to `uf::physics::impl`.
|
||||
|
||||
Enabled through the `reactphysics` compile feature flag, and flagged through `UF_USE_REACTPHYSICS`.
|
||||
|
||||
### `engine/ext/toml/`
|
||||
|
||||
This abstracts around [marzer/tomlplusplus](https://github.com/marzer/tomlplusplus) to provide TOML support.
|
||||
|
||||
For the most part, this is left unused and just wraps around to `ext::json::Value`, as it was explored as an alternative to JSON for reading configuration data.
|
||||
|
||||
Enabled through the `toml` compile feature flag, and flagged through `UF_USE_TOML`.
|
||||
|
||||
### `engine/ext/ultralight/`
|
||||
|
||||
This abstracts around [ultralight-ux/Ultralight](https://github.com/ultralight-ux/Ultralight) to provide rendering websites.
|
||||
|
||||
For the most part, this is left unused as it was a one-off gimmick in lieu of using something like Awesomium (or Chromium).
|
||||
|
||||
Enabled through the `ultralight-ux` compile feature flag, and flagged through `UF_USE_ULTRALIGHT_UX`.
|
||||
|
||||
### `engine/ext/vall_e/`
|
||||
|
||||
This abstracts around [e-c-k-e-r/vall-e/](https://github.com/e-c-k-e-r/vall-e/) to provide TTS support.
|
||||
|
||||
For the most part, this is added to provide an example on how to integrate a C++ project, and to justify burning two years on this meme.
|
||||
|
||||
Enabled through the `vall_e` compile feature flag, and flagged through `UF_USE_VALL_E`.
|
||||
|
||||
### `engine/ext/vulkan/`
|
||||
|
||||
This abstracts around Vulkan to provide the rendering system.
|
||||
|
||||
There's a *ton* of stuff it exposes that should necessitate its own documentation.
|
||||
|
||||
Enabled through the `vulkan` compile feature flag, and flagged through `UF_USE_VULKAN`.
|
||||
|
||||
### `engine/ext/xatlas/`
|
||||
|
||||
This abstracts around [jpcy/xatlas](https://github.com/jpcy/xatlas) to provide UV unwrapping used for lightmap baking.
|
||||
|
||||
Enabled through the `xatlas` compile feature flag, and flagged through `UF_USE_XATLAS`.
|
||||
|
||||
### `engine/ext/zlib/`
|
||||
|
||||
This abstracts around `zlib` to provide compression and decompression of `.gz` files.
|
||||
|
||||
Enabled through the `zlib` compile feature flag, and flagged through `UF_USE_ZLIB`.
|
||||
|
||||
## `engine/spec/`
|
||||
|
||||
### `engine/spec/context/`
|
||||
|
||||
This handles per-platform OpenGL context code.
|
||||
|
||||
### `engine/spec/controller/`
|
||||
|
||||
This handles per-platform code for handling controllers.
|
||||
|
||||
For now, only the Dreacmast has code for its controllers. Controller support via OpenVR *was* handled, but it lives in its own code.
|
||||
|
||||
### `engine/spec/renderer/`
|
||||
|
||||
This provides an alias to which rendering backend to utilize.
|
||||
|
||||
### `engine/spec/terminal/`
|
||||
|
||||
This handles per-platform code for configuring the terminal window the program loads under.
|
||||
|
||||
For the most part, this *was* used for `engine/utils/io/iostream` with locale black magic and Ncurses, but Ncurses has been dropped for a while now.
|
||||
|
||||
### `engine/spec/time/`
|
||||
|
||||
This handles per-platform code for getting time information.
|
||||
|
||||
For the most part, this is quasi-necessary for the Dreamcast to get a timestamp for timing, but I'm pretty sure the universal approach can work too.
|
||||
|
||||
### `engine/spec/window/`
|
||||
|
||||
This handles per-platform code for providing a window to run the program within.
|
||||
|
||||
Windows is mainly supported through `win32` black magic, but Dreamcast-specific code lives within here as well (despite there not being a windowing system).
|
173
docs/ext.md
Normal file
173
docs/ext.md
Normal file
@ -0,0 +1,173 @@
|
||||
# `ext/`
|
||||
|
||||
This section of the project orchestrates the engine's systems and extends it for the overall program, and is intended to hold anything that isn't crucial to the underlying engine itself.
|
||||
|
||||
In the past, this compiled to its own DLL, but for the most part it's better to compile as one DLL.
|
||||
|
||||
## Files
|
||||
|
||||
### `ext/main.cpp`
|
||||
|
||||
This file handles loading settings from `./data/config.json` and initializes the engine's systems accordingly.
|
||||
|
||||
After everything is initialized, the main scene is requested for loading. From there, the tick and render loops are handled, as well as """garbage collection""" and thread orchestration.
|
||||
|
||||
On exit, cleanup is handled gracefully, as segfaulting is not a valid exit path.
|
||||
|
||||
### `ext/behaviors/`
|
||||
|
||||
This folder handles extended engine logic for the program. While most of these can live within the engine (and later should), they're separated off to here to serve as references when implementing the engine for use in a program.
|
||||
|
||||
#### `ext/behaviors/audio/bgm/`
|
||||
|
||||
The `ext::BgmEmitterBehavior` behavior handles logic for playing the background music for a scene.
|
||||
|
||||
Features such as looping, transitions from an `intro` to the main track OR fading to other tracks, are handled here.
|
||||
|
||||
Invoking the `bgm:Play.%UID%` hook will signal for this behavior to play a track, but tracks can be defined through an entity's `bgm.tracks` metadata.
|
||||
|
||||
#### `ext/behaviors/audio/emitter`
|
||||
|
||||
The `ext::SoundEmitterBehavior` behavior handles logic for playing (emitting) sound from an entity.
|
||||
|
||||
Invoking the `sound:Emit.%UID%` hook will signal for this behavior to emit a sound. Most of the parameters through OpenAL can be set through this payload.
|
||||
|
||||
#### `ext/behaviors/baking/`
|
||||
|
||||
The `ext::BakingBehavior` behavior handles orchestrating the rendering system to bake lightmaps for a scene.
|
||||
|
||||
#### `ext/behaviors/craeture/`
|
||||
|
||||
The `ext::CraetureBehavior` behavior serves as a barebone behavior for NPCs.
|
||||
|
||||
In reality it's barebones due to most of an entity's data being handled through its JSON.
|
||||
|
||||
Additional player logic is defined through `/data/entity/scripts/craeture.lua`
|
||||
|
||||
#### `ext/behaviors/gui/`
|
||||
|
||||
The `ext::GuiBehavior` behavior governs everything for handling GUI elements, from loading, to rendering, to handling mouse events.
|
||||
|
||||
This GUI system is still a bit of a mess as its a relic from prior iterations of this engine having messy configuration settings.
|
||||
|
||||
Menus can be implemented through Lua scripts, or additional behaviors.
|
||||
|
||||
##### `ext/behaviors/gui/glyph/`
|
||||
|
||||
The `ext::GuiGlyphBehavior` behavior extends the `ext::GuiBehavior` by handling text through glyphs.
|
||||
|
||||
Currently, this behavior loads glyphs through `FreeType2`, and handles the gorey bits of generating an SDF (if requested), combining the glyphs into an atlas, configuring the metadata to utilize the glyph shader, and updating the GUI when the text updates.
|
||||
|
||||
Like the overall GUI system, most of this is still a bit of a mess from its past iterations.
|
||||
|
||||
##### `ext/behavior/gui/manager/`
|
||||
|
||||
The `ext::GuiManagerBehavior` behavior handles the `gui` rendermode layer, in which all GUI elements render to, and the shader used when blitting to the swapchain.
|
||||
|
||||
#### `ext/behavior/light/`
|
||||
|
||||
The `ext::LightBehavior` behavior handles the logic for light sources and its shadow maps.
|
||||
|
||||
For the most part, this signals to the scene that this entity is a light source. If the entity is marked as a shadow caster, then the behavior handles everything for generating a shadow map. Point lights are implemented as a cubemap.
|
||||
|
||||
Additional logic is included to handle determining which lights get loaded when signaled through the scene, to reduce frame times.
|
||||
|
||||
#### `ext/behavior/player/`
|
||||
|
||||
The `ext::PlayerBehavior` behavior handles the primary controller, the player.
|
||||
|
||||
While inputs *can* be handled through hooks, it's better to instead read from `uf::inputs::kbm` (or `uf::inputs::controller`) directly to handle it. Movement is also handled here in a """Source""" style system.
|
||||
|
||||
Additional player logic is defined through `/data/entity/scripts/player.lua` (primarily `E`-use interactions and `F`-flashlight toggling).
|
||||
|
||||
This is a bit of a mess as it's a relic from prior engine iterations.
|
||||
|
||||
##### `ext/behavior/player/model/`
|
||||
|
||||
The `ext::PlayerModelBehavior` behavior handles the player model, as it shouldn't render in the primary render mode, but should in other render modes.
|
||||
|
||||
Additionally, the model should bind to the player model's `pod::Transform<>`.
|
||||
|
||||
#### `ext/behavior/raytrace/`
|
||||
|
||||
The `ext::RayTraceSceneBehavior` behavior extends the scene's behavior to handle everything for use of `VK_KHR_ray_tracing`.
|
||||
|
||||
#### `ext/behavior/region/`
|
||||
|
||||
The `ext::RegionBehavior` behavior *should* handle everything related to the chunk system. Additional chunks are loaded when the player (or other entities) requests them to load, and unloads unused chunks.
|
||||
|
||||
This was implemented in prior iterations of the engine, but requires a rewrite.
|
||||
|
||||
##### `ext/behavior/region/chunk/`
|
||||
|
||||
The `ext::RegionChunkBehavior` behavior *should* handle everything related to the chunk loaded through `ext::RegionBehavior`.
|
||||
|
||||
#### `ext/behavior/scene/`
|
||||
|
||||
The `ext::ExtSceneBehavior` behavior extends a scene's behavior to handle everything else related to the scene, such as:
|
||||
* menus
|
||||
* entity spawning
|
||||
* noise generation
|
||||
* binding descriptors to shaders
|
||||
* skybox loading
|
||||
* lag detection
|
||||
* screenshots
|
||||
* updating the OpenAL listener
|
||||
* locking the cursor when not in a menu
|
||||
* processing light information to shader buffers, and enabling/disabling used/unused lights
|
||||
* gamma correction, ambient light, fog color, volume levels, and shader modes
|
||||
|
||||
#### `ext/behavior/voxelizer/`
|
||||
|
||||
The `ext::VoxelizerSceneBehavior` behavior extends the scene's behavior to handle everything to implement VXGI (voxel global illumination).
|
||||
|
||||
The scene's graph gets an additional pipeline `vxgi` to "voxelize" all geometry into a voxel map (atomically to integer buffers). This voxel map is then processed accordingly and lit to output a radiance map, which is then mipmapped and bound to the deferred render pass for VXGI queries.
|
||||
|
||||
Voxel cascades are centered around the player, where additional cascades are scaled to a specified power at reduced LOD, but a consistent resolution.
|
||||
|
||||
## Behaviors
|
||||
|
||||
A behavior can easily be implemented and registered through macros.
|
||||
|
||||
An example `behavior.h`:
|
||||
```
|
||||
namespace ext {
|
||||
namespace SomeNameForABehavior {
|
||||
UF_BEHAVIOR_DEFINE_TYPE();
|
||||
EXT_BEHAVIOR_DEFINE_TRAITS();
|
||||
EXT_BEHAVIOR_DEFINE_FUNCTIONS();
|
||||
UF_BEHAVIOR_DEFINE_METADATA(
|
||||
pod::Vector3ui someVector = {};
|
||||
uf::stl::string someString = "";
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
An example `behavior.cpp`:
|
||||
```
|
||||
UF_BEHAVIOR_REGISTER_CPP(ext::SomeNameForABehavior)
|
||||
UF_BEHAVIOR_TRAITS_CPP(ext::SomeNameForABehavior, ticks = true, renders = false, multithread = false)
|
||||
#define this (&self)
|
||||
void ext::SomeNameForABehavior::initialize( uf::Object& self ) {
|
||||
// attach some components
|
||||
auto& metadata = this->getComponent<ext::SomeNameForABehavior::Metadata>();
|
||||
auto& metadataJson = this->getComponent<uf::Serializer>();
|
||||
|
||||
// bind some hooks
|
||||
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
|
||||
}
|
||||
void ext::SomeNameForABehavior::tick( uf::Object& self ) {}
|
||||
void ext::SomeNameForABehavior::render( uf::Object& self ){}
|
||||
void ext::SomeNameForABehavior::destroy( uf::Object& self ){}
|
||||
void ext::SomeNameForABehavior::Metadata::serialize( uf::Object& self, uf::Serializer& serializer ){
|
||||
serializer["some vector"] = uf::vector::encode(/*this->*/someVector);
|
||||
serializer["some string"] = /*this->*/someString;
|
||||
}
|
||||
void ext::SomeNameForABehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ){
|
||||
/*this->*/someVector = uf::vector::decode( serializer["some vector"], /*this->*/someVector );
|
||||
/*this->*/someString = serializer["some string"].as(/*this->*/someString);
|
||||
}
|
||||
```
|
||||
|
||||
While it's not required to specify a behavior's metadata struct (as you *can* use the JSON state of an entity), it's heavily encouraged to keep a behavior's state within the `UF_BEHAVIOR_DEFINE_METADATA` metadata struct. If you do, it's imperative to call `UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS` as it attaches hooks when an entity needs to serialize/deserialize to its JSON state (for example, for access within Lua), and the `serialize`/`deserialize` functions must be filled.
|
@ -15,7 +15,7 @@
|
||||
namespace uf {
|
||||
namespace physics {
|
||||
typedef pod::Math::num_t num_t;
|
||||
namespace time = uf::time;
|
||||
namespace time = uf::time; // to-do: have separate values from the physics system
|
||||
|
||||
void UF_API initialize();
|
||||
void UF_API tick();
|
||||
|
11
ext/ext.h
11
ext/ext.h
@ -1,10 +1 @@
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <uf/utils/string/string.h>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/math/vector.h>
|
||||
#include <uf/utils/time/time.h>
|
||||
#include <uf/utils/string/ext.h>
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
#pragma once
|
16
ext/main.cpp
16
ext/main.cpp
@ -1030,20 +1030,4 @@ void EXT_API ext::terminate() {
|
||||
io.output << "\nTerminated after " << times.sys.elapsed().asDouble() << " seconds" << "\n";
|
||||
io.output.close();
|
||||
}
|
||||
|
||||
/* Write persistent data */ if ( false ) {
|
||||
struct {
|
||||
bool exists = false;
|
||||
uf::stl::string filename = uf::io::root+"/persistent.json";
|
||||
} file;
|
||||
struct {
|
||||
uf::Serializer file;
|
||||
} config;
|
||||
/* Read from file */ {
|
||||
file.exists = config.file.readFromFile(file.filename);
|
||||
}
|
||||
/* Write persistent data */ {
|
||||
config.file.writeToFile(file.filename);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,8 +2,6 @@
|
||||
|
||||
#include <uf/ext/ext.h>
|
||||
|
||||
#include <uf/utils/camera/camera.h>
|
||||
|
||||
namespace ext {
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user