Commit for 2022.06.02 00-03-46.7z

This commit is contained in:
mrq 2022-06-02 00:03:00 -05:00
parent 27980e0de9
commit 6418a76456
40 changed files with 319 additions and 113 deletions

View File

@ -34,8 +34,9 @@ EXT_LIB_NAME += ext
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.162.0/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.176.1/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.182.0/
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.198.1/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.198.1/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.3.204.1/
VULKAN_SDK_PATH += /c/VulkanSDK/1.3.211.0/
#GLSLC += $(VULKAN_SDK_PATH)/Bin/glslangValidator
GLSLC += $(VULKAN_SDK_PATH)/Bin/glslc
@ -59,7 +60,7 @@ else ifneq (,$(findstring dreamcast,$(ARCH)))
endif
ifneq (,$(findstring vulkan,$(REQ_DEPS)))
FLAGS += -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN
DEPS += -lvulkan -lspirv-cross
DEPS += -lvulkan -lspirv-cross #-lVulkanMemoryAllocator
INCS += -I$(VULKAN_SDK_PATH)/include
LIBS += -L$(VULKAN_SDK_PATH)/Lib
endif

View File

@ -1,12 +1,12 @@
{
"engine": {
"scenes": {
"start": "SH2_McDonalds",
"start": "SS2",
"meshes": { "interleave": true },
"matrix": { "reverseInfinite": true },
"lights": {
"max": 16,
"enabled": true
"lights": { "enabled": true,
"useLightmaps": false,
"max": 16
},
"shadows": {
"enabled": true,
@ -255,7 +255,7 @@
"cursor" : {
"visible" : true,
"center" : false,
"sensitivity": [ 0.5, 0.5 ]
"sensitivity": [ 1, 1 ]
},
"mode" : "windowed", // fullscreen, borderless, windowed
"icon" : "./data/textures/icon.png",

View File

@ -18,12 +18,14 @@
"exporter": {
"enabled": true,
"pretty": false,
"compress": true,
"encoding": "auto",
"compression": "auto",
"quantize": false,
"precision": 4,
"combined": false,
"encode buffers": true,
"unwrap": true,
"quit": true,
"mesh": {
// "print": true
}
@ -51,6 +53,7 @@
}
},
// "filter": "NEAREST",
"lightmap": true,
"flags": {
"ATLAS": false,
"INVERT": false,

View File

@ -2,13 +2,13 @@
"import": "/model.json",
"assets": [
// { "filename": "./models/gm_construct.glb" }
{ "filename": "./models/gm_construct/graph.json.gz" }
{ "filename": "./models/gm_construct/graph.json" }
],
"metadata": {
"model": {
"lightmap": true,
// "lightmap": false,
"baking": {
"enabled": false,
"enabled": true,
"resolution": 1024,
"settings": {
// "useInputMeshUvs": false

View File

@ -1,6 +1,7 @@
{
"import": "/scene.json",
"assets": [
"./audio/soundscape/ambience.ogg",
"./loading.json"
],
"system": {
@ -28,7 +29,7 @@
"ambient": [ 0.15, 0.15, 0.15 ],
"fog": {
"fog-disabled": {
"color": [ 0.5, 0.5, 0.5 ],
"range": [ 64, 256 ],
"step scale": 2,

View File

@ -4,16 +4,16 @@
// { "filename": "./static.json", "delay": 8 },
// { "filename": "./models/mcdonalds.glb" }
{ "filename": "./models/mcdonalds/graph.json.gz" }
{ "filename": "./models/mcdonalds/graph.json" }
// { "filename": "./models/mini_mcd.glb" }
// { "filename": "./models/mini_mcd/graph.json.gz" }
// { "filename": "./models/mini_mcd/graph.json" }
],
"metadata": {
"model": {
"lightmap": true,
// "lightmap": false,
"baking": {
"enabled": false,
"enabled": true,
"resolution": 2048,
"settings": {
"useInputMeshUvs": false
@ -23,7 +23,7 @@
"tags": {
"/^worldspawn/": {
"physics": { "type": "mesh", "static": true },
"grid": { "size": [3,2,3], "epsilon": 1.0, "cleanup": true, "print": true }
"grid": { "size": [4,1,4], "epsilon": 1.0, "cleanup": true, "print": true }
},
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },

View File

@ -10,9 +10,9 @@
"model": {
"cull mode": "none",
"alpha mode": "BLEND",
"lightmap": true,
// "lightmap": false,
"baking": {
"enabled": false,
"enabled": true,
"resolution": 1024,
"settings": {
"useInputMeshUvs": false

View File

@ -3,26 +3,21 @@
"assets": [
// { "filename": "./craeture.json", "delay": 1 },
// { "filename": "./models/tiny_msci.glb", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/tiny_msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/tiny_msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/tiny_msci.glb" }
// { "filename": "./models/tiny_msci/graph.json" }
// { "filename": "./models/micro_sci.glb", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/micro_sci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
{ "filename": "./models/micro_sci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/micro_sci.glb" }
// { "filename": "./models/micro_sci/graph.json" }
// { "filename": "./models/msci.glb", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/msci.glb" }
// { "filename": "./models/msci/graph.json" }
// { "filename": "./models/medsci.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/medsci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/medsci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/medsci.glb" }
{ "filename": "./models/medsci/graph.json" }
],
"metadata": {
"model": {
"lightmap": true,
// "lightmap": false,
"baking": {
"enabled": true,
"resolution": 1024
@ -31,7 +26,7 @@
"tags": {
"/^worldspawn/": {
"physics": { "type": "mesh", "static": true },
"grid": { "size": [5,2,5], "epsilon": 1.0, "cleanup": true, "print": true }
"grid": { "size": [5,1,5], "epsilon": 1.0, "cleanup": true, "print": true }
},
"info_player_spawn": {
"action": "attach",

View File

@ -15,7 +15,7 @@ float gaSchlickGGX(float cosLi, float cosLo, float roughness) {
vec3 fresnelSchlick(vec3 F0, float cosTheta) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); }
#if !BAKING && !COMPUTE
void pbr() {
if ( validTextureIndex( surface.instance.lightmapID ) ) return;
if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) return;
const float Rs = 4.0; // specular lighting looks gross without this
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);

View File

@ -62,7 +62,7 @@ layout (binding = 5) uniform UBO {
uint shadowSamples;
uint indexSkybox;
uint padding1;
uint useLightmaps;
uint padding2;
uint padding3;
} ubo;
@ -235,7 +235,7 @@ void populateSurface() {
}
// Lightmap
if ( validTextureIndex( surface.instance.lightmapID ) ) {
if ( bool(ubo.useLightmaps) && validTextureIndex( surface.instance.lightmapID ) ) {
surface.light += surface.material.albedo * sampleTexture( surface.instance.lightmapID, surface.st );
}
// Emissive textures

View File

@ -25,6 +25,7 @@ namespace {
#if UF_ENV_DREAMCAST
arch_stk_trace(1);
#endif
if ( client::terminated ) return;
UF_MSG_INFO("Termination via std::atexit()!");
ext::ready = false;
client::ready = false;
@ -125,6 +126,7 @@ int main(int argc, char** argv){
#endif
}
if ( !client::terminated ) {
client::terminated = true;
UF_MSG_INFO("Natural termination!");
ext::terminate();
client::terminate();

View File

@ -20,12 +20,19 @@
namespace ext {
namespace json {
extern uf::stl::string PREFERRED_COMPRESSION;
extern uf::stl::string PREFERRED_ENCODING;
struct UF_API EncodingSettings {
uf::stl::string compression = ""; // auto-assume compression scheme
uf::stl::string encoding = ""; // auto-assume re-encoding scheme
bool pretty = false;
bool compress = false;
bool quantize = false;
uint8_t precision = 0;
};
struct UF_API DecodingSettings {
uf::stl::string encoding = "";
};
// cares not about breaking
void UF_API forEach( ext::json::Value& json, const std::function<void(ext::json::Value&)>& function );
@ -50,7 +57,8 @@ namespace ext {
uf::stl::string UF_API encode( const ext::json::Value& json, bool pretty = true );
uf::stl::string UF_API encode( const ext::json::Value& json, const ext::json::EncodingSettings& settings );
ext::json::Value& UF_API decode( ext::json::Value& json, const uf::stl::string& str );
ext::json::Value& UF_API decode( ext::json::Value& json, const uf::stl::string& str, const DecodingSettings& = {} );
#if UF_USE_LUA
uf::stl::string UF_API encode( const sol::table& table );
#endif

View File

@ -94,6 +94,7 @@ template<> inline bool ext::json::Value::is<uint64_t>(bool strict) const { retur
template<> inline bool ext::json::Value::is<float>(bool strict) const { return strict ? is_number_float() : is_number(); }
template<> inline bool ext::json::Value::is<double>(bool strict) const { return strict ? is_number_float() : is_number(); }
template<> inline bool ext::json::Value::is<uf::stl::string>(bool strict) const { return is_string(); }
// template<> inline bool ext::json::Value::is<std::string>(bool strict) const { return is_string(); }
#if UF_ENV_DREAMCAST
template<> inline bool ext::json::Value::is<int>(bool strict) const { return strict ? is_number_integer() : is_number(); }

View File

@ -54,8 +54,10 @@
#define UF_MSG_ERROR(X) UF_MSG(X, " ERROR ");
#if UF_NO_EXCEPTIONS
#define UF_EXCEPTIONS 0
#define UF_EXCEPTION(X) { UF_MSG_ERROR(X); std::abort(); }
#else
#define UF_NO_EXCEPTIONS 0
#define UF_EXCEPTION(X) {\
uf::stl::stringstream str;\
str << X;\

View File

@ -50,6 +50,7 @@ namespace uf {
public:
bool exists( const name_t& name );
void removeHook( const name_t& name, size_t uid );
void removeHooks();
size_t addHook( const name_t& name, const pod::Hook::function_t& callback, const pod::Hook::Type& = {UF_USERDATA_CTTI(void), 0} );
size_t addHook( const name_t& name, const std::function<void()>& callback );

View File

@ -11,6 +11,8 @@
namespace uf {
class UF_API Serializer : public ext::json::Document {
protected:
uf::stl::string m_filename = "";
public:
typedef uf::stl::string output_t;
typedef uf::stl::string input_t;
@ -24,7 +26,7 @@ namespace uf {
Serializer::output_t serialize( bool pretty = false ) const;
Serializer::output_t serialize( const ext::json::EncodingSettings& ) const;
void deserialize( const uf::stl::string& );
void deserialize( const uf::stl::string&, const ext::json::DecodingSettings& = {} );
// serializeable
template<typename T>
@ -60,6 +62,7 @@ namespace uf {
return res;
}
static uf::stl::string resolveFilename( const uf::stl::string& filename, bool compareTimes = true );
bool readFromFile( const uf::stl::string& from, const uf::stl::string& hash = "" );
bool writeToFile( const uf::stl::string& to, const ext::json::EncodingSettings& = {} ) const;

View File

@ -11,7 +11,10 @@ namespace uf {
namespace string {
// bool match( const uf::stl::string& str, const uf::stl::string& r );
bool UF_API isRegex( const uf::stl::string& str );
uf::stl::vector<uf::stl::string> UF_API matches( const uf::stl::string& str, const uf::stl::string& r );
uf::stl::vector<uf::stl::string> UF_API match( const uf::stl::string& str, const uf::stl::string& r );
inline uf::stl::vector<uf::stl::string> UF_API matches( const uf::stl::string& str, const uf::stl::string& r ) { return uf::string::match( str, r ); }
bool UF_API matched( const uf::stl::string& str, const uf::stl::string& r );
uf::stl::string UF_API replace( const uf::stl::string&, const uf::stl::string&, const uf::stl::string& );
uf::stl::string UF_API lowercase( const uf::stl::string& );

View File

@ -181,7 +181,7 @@ void uf::Asset::load( const uf::stl::string& callback, const uf::Asset::Payload&
uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, const uf::stl::string& mime ) {
uf::stl::string extension = uf::string::lowercase( uf::io::extension( uri, -1 ) );
uf::stl::string basename = uf::string::lowercase( uf::string::replace( uf::io::filename( uri ), ".gz", "" ) );
uf::stl::string basename = uf::string::lowercase( uf::string::replace( uf::io::filename( uri ), "/.(?:gz|lz)$/", "" ) );
uf::Asset::Payload payload;
static uf::stl::unordered_map<uf::stl::string,uf::Asset::Type> typemap = {
@ -192,6 +192,8 @@ uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, cons
{ "ogg", uf::Asset::Type::AUDIO },
{ "json", uf::Asset::Type::JSON },
{ "bson", uf::Asset::Type::JSON },
{ "cbor", uf::Asset::Type::JSON },
{ "lua", uf::Asset::Type::LUA },
@ -207,6 +209,8 @@ uf::Asset::Payload uf::Asset::resolveToPayload( const uf::stl::string& uri, cons
if ( typemap.count( extension ) == 1 ) payload.type = typemap[extension];
if ( basename == "graph.json" ) payload.type = uf::Asset::Type::GRAPH;
if ( basename == "graph.bson" ) payload.type = uf::Asset::Type::GRAPH;
if ( basename == "graph.cbor" ) payload.type = uf::Asset::Type::GRAPH;
return payload;
}
@ -232,6 +236,12 @@ uf::stl::string uf::Asset::cache( const uf::Asset::Payload& payload ) {
return "";
}
filename = cached;
} else {
// do implicit loading of json files (could be encoded as bson, cbor, and compressed as gz, lz)
if ( extension == "json" ) {
filename = uf::Serializer::resolveFilename( filename );
extension = uf::io::extension( extension );
}
}
if ( !uf::io::exists( filename ) ) {
if ( !uf::Asset::assertionLoad ) {
@ -255,7 +265,7 @@ uf::stl::string uf::Asset::cache( const uf::Asset::Payload& payload ) {
uf::stl::string uf::Asset::load(const uf::Asset::Payload& payload ) {
uf::stl::string filename = payload.filename;
uf::stl::string extension = uf::string::lowercase(uf::io::extension( payload.filename, -1 ));
uf::stl::string basename = uf::string::replace( uf::io::filename( payload.filename ), ".gz", "" );
uf::stl::string basename = uf::string::lowercase( uf::string::replace( uf::io::filename( payload.filename ), "/.(?:gz|lz)$/", "" ) );
if ( payload.filename.substr(0,5) == "https" ) {
uf::stl::string hash = uf::string::sha256( payload.filename );
uf::stl::string cached = uf::io::root + "/cache/http/" + hash + "." + extension;
@ -268,6 +278,12 @@ uf::stl::string uf::Asset::load(const uf::Asset::Payload& payload ) {
return "";
}
filename = cached;
} else {
// do implicit loading of json files (could be encoded as bson, cbor, and compressed as gz, lz)
if ( extension == "json" ) {
filename = uf::Serializer::resolveFilename( filename );
extension = uf::io::extension( extension );
}
}
if ( !uf::io::exists( filename ) ) {
if ( !uf::Asset::assertionLoad ) {

View File

@ -112,6 +112,12 @@ void uf::Behaviors::destroy() {
uf::Object& self = *((uf::Object*) this);
if ( !self.isValid() ) return;
UF_BEHAVIOR_POLYFILL(destroy)
m_behaviors.clear();
m_graph.initialize.clear();
m_graph.tick.clear();
m_graph.tickMT.clear();
m_graph.render.clear();
m_graph.destroy.clear();
}
#if 0

View File

@ -197,7 +197,7 @@ namespace {
ext::json::reserve( json["buffers"], mesh.buffers.size() );
for ( auto i = 0; i < mesh.buffers.size(); ++i ) {
const uf::stl::string filename = settings.filename + ".buffer." + std::to_string(i) + "." + ( settings.compress ? "gz" : "bin" );
const uf::stl::string filename = settings.filename + ".buffer." + std::to_string(i) + "." + ( settings.compression != "" ? settings.compression : "bin" );
uf::io::write( filename, mesh.buffers[i] );
json["buffers"].emplace_back(uf::io::filename( filename ));
}
@ -224,10 +224,11 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
uf::Serializer serializer;
uf::Serializer metadata;
const ::EncodingSettings settings = ::EncodingSettings{
::EncodingSettings settings = ::EncodingSettings{
{
/*.compression = */graph.metadata["exporter"]["compression"].as<uf::stl::string>("auto"),
/*.encoding = */graph.metadata["exporter"]["encoding"].as<uf::stl::string>("auto"),
/*.pretty = */graph.metadata["exporter"]["pretty"].as<bool>(),
/*.compress = */graph.metadata["exporter"]["compress"].as<bool>(),
/*.quantize = */graph.metadata["exporter"]["quantize"].as<bool>(),
/*.precision = */graph.metadata["exporter"]["precision"].as<uint8_t>(),
},
@ -236,6 +237,10 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
/*.unwrap = */graph.metadata["exporter"]["unwrap"].as<bool>(true),
/*.filename = */directory + "/graph.json",
};
if ( settings.encoding == "auto" ) settings.encoding = ext::json::PREFERRED_ENCODING;
if ( settings.compression == "auto" ) settings.compression = ext::json::PREFERRED_COMPRESSION;
if ( !settings.combined ) uf::io::mkdir(directory);
#if UF_USE_XATLAS
/*
@ -297,7 +302,8 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
encode(mesh, s).writeToFile(s.filename, settings);
uf::Serializer json;
json["name"] = name;
json["filename"] = uf::io::filename(s.filename + (settings.compress ? ".gz" : ""));
// json["filename"] = uf::io::filename(s.filename + (settings.compress ? ".gz" : ""));
json["filename"] = uf::io::filename(s.filename);
serializer["meshes"].emplace_back( json );
} else {
s.filename = directory+"/mesh."+std::to_string(i);
@ -403,7 +409,8 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
uf::stl::string f = "animation."+std::to_string(i)+".json";
auto& animation = /*graph.storage*/uf::graph::storage.animations.map.at(name);
encode(animation, settings).writeToFile(directory+"/"+f, settings);
serializer["animations"].emplace_back(f + (settings.compress ? ".gz" : ""));
// serializer["animations"].emplace_back(f + (settings.compress ? ".gz" : ""));
serializer["animations"].emplace_back(f);
}
} else {
for ( auto& name : graph.animations ) {
@ -435,6 +442,12 @@ void uf::graph::save( const pod::Graph& graph, const uf::stl::string& filename )
if ( !settings.combined ) target = directory + "/graph.json";
serializer.writeToFile( target, settings );
UF_MSG_DEBUG("Saving graph to `" << target << "`");
if ( graph.metadata["exporter"]["quit"].as<bool>(true) ) {
ext::json::Value payload;
payload["message"] = "Termination after gltf conversion requested.";
uf::scene::getCurrentScene().queueHook("system:Quit", payload);
}
}
uf::stl::string uf::graph::print( const pod::Graph& graph ) {

View File

@ -693,7 +693,7 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
*/
ext::json::forEach( graph.metadata["tags"], [&]( const uf::stl::string& key, ext::json::Value& value ) {
if ( uf::string::isRegex( key ) ) {
if ( uf::string::matches( node.name, key ).empty() ) return;
if ( !uf::string::matched( node.name, key ) ) return;
} else if ( node.name != key ) return;
tag = value;
});

View File

@ -28,7 +28,9 @@ UF_API bool ext::freetype::initialized() {
return ext::freetype::library.loaded;
}
UF_API void ext::freetype::terminate() {
if ( !ext::freetype::library.loaded ) return;
FT_Done_FreeType(ext::freetype::library.library);
ext::freetype::library.loaded = false;
}
UF_API ext::freetype::Glyph ext::freetype::initialize( const uf::stl::string& font ) {

View File

@ -265,7 +265,7 @@ pod::Graph ext::gltf::load( const uf::stl::string& filename, const uf::Serialize
if ( !ext::json::isObject( value["grid"] ) ) return; // no tag["grid"] defined
if ( ext::json::isNull( value["grid"]["size"] ) ) return; // no tag["grid"]["size"] defined
if ( uf::string::isRegex( key ) ) {
if ( uf::string::matches( m.name, key ).empty() ) return;
if ( !uf::string::matched( m.name, key ) ) return;
} else if ( m.name != key ) return;
meshgrid.metadata = value["grid"];
});

View File

@ -111,7 +111,7 @@ void ext::json::forEach( const ext::json::Value& json, const std::function<void(
}
}
#if defined(UF_JSON_USE_NLOHMANN) && UF_JSON_USE_NLOHMANN
#if UF_JSON_USE_NLOHMANN
uf::stl::vector<uf::stl::string> ext::json::keys( const ext::json::Value& v ) {
uf::stl::vector<uf::stl::string> keys;
if ( !ext::json::isObject( v ) ) return keys;
@ -120,7 +120,7 @@ uf::stl::vector<uf::stl::string> ext::json::keys( const ext::json::Value& v ) {
}
return keys;
}
#elif defined(UF_JSON_USE_RAPIDJSON) && UF_JSON_USE_RAPIDJSON
#elif UF_JSON_USE_RAPIDJSON
rapidjson::Document::AllocatorType ext::json::allocator;
#endif
@ -150,20 +150,33 @@ ext::json::Value& ext::json::reencode( ext::json::Value& x, const EncodingSettin
return x;
}
uf::stl::string ext::json::PREFERRED_COMPRESSION = "gz";
uf::stl::string ext::json::PREFERRED_ENCODING = "bson";
uf::stl::string ext::json::encode( const ext::json::Value& json, bool pretty ) {
return ext::json::encode( json, ext::json::EncodingSettings{ .pretty = true } );
}
uf::stl::string ext::json::encode( const ext::json::Value& _json, const ext::json::EncodingSettings& settings ) {
ext::json::Value json = ext::json::reencode( _json, settings );
#if defined(UF_JSON_USE_NLOHMANN) && UF_JSON_USE_NLOHMANN
return settings.pretty ? json.dump(1, '\t') : json.dump();
#elif defined(UF_JSON_USE_JSONCPP) && UF_JSON_USE_JSONCPP
Json::FastWriter fast;
Json::StyledWriter styled;
uf::stl::string output = settings.pretty ? styled.write(json) : fast.write(json);
if ( output.back() == '\n' ) output.pop_back();
return output;
#elif defined(UF_JSON_USE_LUA) && UF_JSON_USE_LUA
#if UF_JSON_USE_NLOHMANN
// emit raw json
if ( settings.encoding == "" || settings.encoding == "json" ) {
return settings.pretty ? json.dump(1, '\t') : json.dump();
}
// emit bson
if ( settings.encoding == "bson" ) {
auto buffer = nlohmann::json::to_bson( static_cast<ext::json::base_value>(json) );
return uf::stl::string( buffer.begin(), buffer.end() );
}
// emit cbor
if ( settings.encoding == "cbor" ) {
auto buffer = nlohmann::json::to_cbor( static_cast<ext::json::base_value>(json) );
return uf::stl::string( buffer.begin(), buffer.end() );
}
// should probably default to json, not my problem
UF_MSG_ERROR("invalid encoding requested: " << settings.encoding);
return "";
#elif UF_JSON_USE_LUA
return ext::lua::state["json"]["encode"]( _json );
#endif
}
@ -173,23 +186,24 @@ uf::stl::string ext::json::encode( const sol::table& table ) {
return ext::lua::state["json"]["encode"]( table );
}
#endif
ext::json::Value& ext::json::decode( ext::json::Value& json, const uf::stl::string& str ) {
#if defined(UF_JSON_USE_NLOHMANN) && UF_JSON_USE_NLOHMANN
#if UF_NO_EXCEPTIONS
json = nlohmann::json::parse(str, nullptr, true, true);
#else
ext::json::Value& ext::json::decode( ext::json::Value& json, const uf::stl::string& str, const DecodingSettings& settings ) {
#if UF_JSON_USE_NLOHMANN
#if !UF_NO_EXCEPTIONS
bool exceptions = true;
try {
json = nlohmann::json::parse(str, nullptr, true, true);
#endif
if ( settings.encoding == "" || settings.encoding == "json" )
json = nlohmann::json::parse(str, nullptr, exceptions, true);
else if ( settings.encoding == "bson" )
json = nlohmann::json::from_bson(str, exceptions, true);
else if ( settings.encoding == "cbor" )
json = nlohmann::json::from_cbor(str, exceptions, true);
#if !UF_NO_EXCEPTIONS
} catch ( nlohmann::json::parse_error& e ) {
UF_MSG_ERROR("JSON error: " << e.what() << "\tAttempted to parse: " << str)
}
#endif
#elif defined(UF_JSON_USE_JSONCPP) && UF_JSON_USE_JSONCPP
Json::Reader reader;
if ( !reader.parse(str, json) ) {
UF_MSG_ERROR("JSON error: " << reader.getFormattedErrorMessages() << "\tAttempted to parse: " << str)
}
#elif defined(UF_JSON_USE_LUA) && UF_JSON_USE_LUA
#elif UF_JSON_USE_LUA
json = ext::lua::state["json"]["decode"]( str );
#endif
return json;

View File

@ -233,6 +233,7 @@ void ext::reactphysics::tick( float delta ) {
ext::reactphysics::syncFrom( accumulator / ext::reactphysics::timescale );
}
void ext::reactphysics::terminate() {
if ( !::world ) return;
::common.destroyPhysicsWorld(::world);
::world = NULL;
}

View File

@ -1,5 +1,6 @@
#if UF_USE_VULKAN
#define VMA_VULKAN_VERSION 1002000
#define VMA_IMPLEMENTATION
#include <uf/ext/vulkan/buffer.h>

View File

@ -552,10 +552,10 @@ void ext::vulkan::Device::initialize() {
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Program";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 2, 0);
appInfo.applicationVersion = VK_MAKE_VERSION(1, 3, 0);
appInfo.pEngineName = "Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 2, 0);
appInfo.apiVersion = VK_API_VERSION_1_2;
appInfo.engineVersion = VK_MAKE_VERSION(1, 3, 0);
appInfo.apiVersion = VK_API_VERSION_1_3;
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
@ -937,7 +937,7 @@ void ext::vulkan::Device::initialize() {
{
/*
VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2;
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_3;
allocatorInfo.physicalDevice = physicalDevice;
allocatorInfo.instance = instance;
allocatorInfo.device = logicalDevice;
@ -950,7 +950,7 @@ void ext::vulkan::Device::initialize() {
vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
VmaAllocatorCreateInfo allocatorInfo = {};
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2;
allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_3;
allocatorInfo.physicalDevice = physicalDevice;
allocatorInfo.instance = instance;
allocatorInfo.device = logicalDevice;

View File

@ -141,7 +141,7 @@ bool ext::vulkan::Texture::generated() const {
return view != VK_NULL_HANDLE;
}
void ext::vulkan::Texture::destroy() {
if ( !device ) return;
if ( !device || !device->logicalDevice ) return; // device->logicalDevice should never be null, but it happens, somehow
if ( view != VK_NULL_HANDLE ) {
vkDestroyImageView(device->logicalDevice, view, nullptr);

View File

@ -384,7 +384,7 @@ void ext::vulkan::destroy() {
*/
for ( auto& renderMode : renderModes ) {
if ( !renderMode ) continue;
if ( !renderMode || !renderMode->device ) continue;
renderMode->destroy();
// delete renderMode;
renderMode = NULL;

View File

@ -21,6 +21,9 @@ void uf::Hooks::removeHook( const uf::Hooks::name_t& name, size_t uid ) {
}
}
}
void uf::Hooks::removeHooks() {
this->m_container.clear();
}
/*
uf::Hooks::return_t uf::Hooks::call( const uf::Hooks::name_t& name ) {
pod::Hook::userdata_t payload{};

View File

@ -77,14 +77,14 @@ uf::stl::string UF_API uf::io::sanitize( const uf::stl::string& str, const uf::s
// flatten all "/./"
{
uf::stl::string tmp;
while ( path != (tmp = uf::string::replace(path, "/./", "/")) ) {
while ( path != (tmp = uf::string::replace(path, "/\\/\\.\\//", "/")) ) {
path = tmp;
}
}
// flatten all "//"
{
uf::stl::string tmp;
while ( path != (tmp = uf::string::replace(path, "//", "/")) ) {
while ( path != (tmp = uf::string::replace(path, "/\\/\\//", "/")) ) {
path = tmp;
}
}
@ -151,10 +151,16 @@ size_t UF_API uf::io::write( const uf::stl::string& filename, const void* buffer
// indirection for different compression formats, currently only using zlib's gzFile shit
uf::stl::vector<uint8_t> UF_API uf::io::decompress( const uf::stl::string& filename ) {
return ext::zlib::decompressFromFile( filename );
uf::stl::string extension = uf::io::extension( filename );
if ( extension == "gz" ) return ext::zlib::decompressFromFile( filename );
UF_MSG_ERROR("unsupported compression format requested: " << extension);
return {};
}
size_t UF_API uf::io::compress( const uf::stl::string& filename, const void* buffer, size_t size ) {
return ext::zlib::compressToFile( filename, buffer, size );
uf::stl::string extension = uf::io::extension( filename );
if ( extension == "gz" ) return ext::zlib::compressToFile( filename, buffer, size );
UF_MSG_ERROR("unsupported compression format requested: " << extension);
return 0;
}
uf::stl::string UF_API uf::io::hash( const uf::stl::string& filename ) {

View File

@ -159,7 +159,9 @@ char UF_API_CALL uf::IoStream::readChar(const bool& loop) {
if ( !ext::ncurses.initialized() ) this->initialize();
#endif
if ( !uf::IoStream::ncurses ) {
return std::cin.get();
auto ch = std::cin.get();
::info.input.history.push_back( std::to_string(ch) );
return ch;
}
#if UF_USE_NCURSES
while ( loop ) {
@ -167,8 +169,8 @@ char UF_API_CALL uf::IoStream::readChar(const bool& loop) {
if ( ::info.character == ERR ) continue;
if ( ::info.character > 0 && ::info.character < 128 ) return ::info.character;
}
return 0;
#endif
return 0;
}
uf::stl::string UF_API_CALL uf::IoStream::readString(const bool& loop) {
#if UF_USE_NCURSES
@ -178,6 +180,7 @@ uf::stl::string UF_API_CALL uf::IoStream::readString(const bool& loop) {
if ( !uf::IoStream::ncurses ) {
uf::stl::string in;
std::getline(std::cin, in);
::info.input.history.push_back( in );
return in;
}
#if UF_USE_NCURSES
@ -259,8 +262,8 @@ uf::stl::string UF_API_CALL uf::IoStream::readString(const bool& loop) {
}
uf::iostream << "\n";
::info.input.history.push_back(::info.input.buffer);
return ::info.input.buffer;
#endif
return ::info.input.buffer;
}
uf::String UF_API_CALL uf::IoStream::readUString(const bool& loop) {
#if UF_USE_NCURSES
@ -270,6 +273,7 @@ uf::String UF_API_CALL uf::IoStream::readUString(const bool& loop) {
if ( !uf::IoStream::ncurses ) {
uf::stl::string in;
std::getline(std::cin, in);
::info.input.history.push_back( in );
return in;
}
#if UF_USE_NCURSES
@ -377,8 +381,8 @@ uf::String UF_API_CALL uf::IoStream::readUString(const bool& loop) {
}
uf::iostream << "\n";
::info.input.history.push_back(::info.input.buffer);
return ::info.input.buffer;
#endif
return ::info.input.buffer;
}
char UF_API_CALL uf::IoStream::writeChar( char ch ) {
#if UF_USE_NCURSES
@ -398,13 +402,14 @@ char UF_API_CALL uf::IoStream::writeChar( char ch ) {
if ( !uf::IoStream::ncurses ) {
if ( ch == '\n' ) std::cout << std::endl;
else std::cout << ch;
::info.input.history.push_back( std::to_string(ch) );
return ch;
}
#if UF_USE_NCURSES
ext::ncurses.addChar(ch);
ext::ncurses.refresh();
return ch;
#endif
return ch;
}
const uf::stl::string& UF_API_CALL uf::IoStream::writeString( const uf::stl::string& str ) {
#if UF_USE_NCURSES
@ -425,13 +430,14 @@ const uf::stl::string& UF_API_CALL uf::IoStream::writeString( const uf::stl::str
if ( !uf::IoStream::ncurses ) {
if ( str == "\n" ) std::cout << std::endl;
else std::cout << str;
::info.input.history.push_back( str );
return str;
}
#if UF_USE_NCURSES
ext::ncurses.addStr(str.c_str());
ext::ncurses.refresh();
return str;
#endif
return str;
}
const uf::String& UF_API_CALL uf::IoStream::writeUString( const uf::String& str ) {
#if UF_USE_NCURSES
@ -450,13 +456,14 @@ const uf::String& UF_API_CALL uf::IoStream::writeUString( const uf::String& str
*/
if ( !uf::IoStream::ncurses ) {
std::cout << (const char*) str.getString().c_str();
::info.input.history.push_back( str );
return str;
}
#if UF_USE_NCURSES
ext::ncurses.addStr((const char*) str.getString().c_str());
ext::ncurses.refresh();
return str;
#endif
return str;
}
void UF_API_CALL uf::IoStream::operator>> (bool& val) {

View File

@ -68,12 +68,13 @@ void uf::memoryPool::initialize( pod::MemoryPool& pool, size_t size ) {
pool.size = size;
}
void uf::memoryPool::destroy( pod::MemoryPool& pool ) {
if ( uf::memoryPool::size( pool ) <= 0 ) return;
if ( uf::memoryPool::size( pool ) <= 0 ) goto CLEAR;
if ( uf::memoryPool::subPool && &pool != &uf::memoryPool::global.data() ) {
uf::memoryPool::global.free( pool.memory );
} else {
uf::allocator::free_m(pool.memory);
}
CLEAR:
pool.size = 0;
pool.memory = NULL;
}
@ -243,6 +244,9 @@ bool uf::memoryPool::exists( pod::MemoryPool& pool, void* pointer, size_t size )
#endif
}
bool uf::memoryPool::free( pod::MemoryPool& pool, void* pointer, size_t size ) {
// skip freeing, we're already a deallocated pool
// this comes up because of how backasswards C++ static initialization/destruction order is
if ( !pool.memory ) return false;
// passed a NULL, for some reason
if ( !pointer ) return false;
#if UF_MEMORYPOOL_MUTEX

View File

@ -9,6 +9,12 @@
#include <fstream>
#include <functional>
#define UF_SERIALIZER_IMPLICIT_LOAD 1
#define UF_SERIALIZER_AUTO_CONVERT 1
//#define UF_MSG_DEBUG_(...) UF_MSG_DEBUG(__VA_ARGS__)
#define UF_MSG_DEBUG_(...)
uf::Serializer::Serializer( const uf::stl::string& str ) { //: sol::table(ext::lua::state, sol::create) {
this->deserialize(str);
}
@ -31,14 +37,37 @@ uf::Serializer::output_t uf::Serializer::serialize( bool pretty ) const {
uf::Serializer::output_t uf::Serializer::serialize( const ext::json::EncodingSettings& settings ) const {
return ext::json::encode( *this, settings );
}
void uf::Serializer::deserialize( const uf::stl::string& str ) {
void uf::Serializer::deserialize( const uf::stl::string& str, const ext::json::DecodingSettings& settings ) {
if ( str == "" ) return;
ext::json::decode( *this, str );
ext::json::decode( *this, str, settings );
}
uf::stl::string uf::Serializer::resolveFilename( const uf::stl::string& filename, bool compareTimes ) {
uf::stl::string _filename = filename;
if ( ext::json::PREFERRED_ENCODING != "" && ext::json::PREFERRED_ENCODING != "json" ) {
_filename = uf::string::replace( _filename, "/.json$/", "." + ext::json::PREFERRED_ENCODING );
}
if ( ext::json::PREFERRED_COMPRESSION != "" ) {
_filename = _filename + "." + ext::json::PREFERRED_COMPRESSION;
}
if ( !compareTimes ) return _filename;
if ( uf::io::exists( _filename ) ) {
bool should = !uf::io::exists( filename ); // implicit load if our requested filename doesnt exist anyways, but our preferred source does
if ( !should ) should = uf::io::mtime( _filename ) > uf::io::mtime( filename ); // implicit load the preferred source is newer than the requested filename
if ( should ) return _filename;
}
return filename;
}
bool uf::Serializer::readFromFile( const uf::stl::string& filename, const uf::stl::string& hash ) {
uf::String string;
// uf::stl::string filename = _filename + ( uf::io::exists(_filename + ".gz") ? ".gz" : "" );
#if UF_SERIALIZER_IMPLICIT_LOAD
// implicitly check for optimal format for plain .json requests
if ( uf::string::matched( filename, "/.json$/" ) ) {
uf::stl::string _filename = uf::Serializer::resolveFilename( filename );
if ( _filename != filename ) return readFromFile( _filename, hash );
}
#endif
bool exists = uf::io::exists( filename );
if ( !exists ) {
UF_MSG_ERROR("Failed to read JSON file `" << filename << "`: does not exist");
@ -48,19 +77,80 @@ bool uf::Serializer::readFromFile( const uf::stl::string& filename, const uf::st
if ( buffer.empty() ) {
UF_MSG_ERROR("Failed to read JSON file `" << filename << "`: empty file or hash mismatch");
return false;
}
}
this->m_filename = filename;
/*
uf::String string;
auto& str = string.getString();
str.reserve(buffer.size());
str.assign(buffer.begin(), buffer.end());
*/
uf::stl::string string{ buffer.begin(), buffer.end() };
ext::json::DecodingSettings settings;
if ( uf::string::matched( filename, "/.bson/" ) ) settings.encoding = "bson";
else if ( uf::string::matched( filename, "/.cbor/" ) ) settings.encoding = "cbor";
this->deserialize( string, settings );
#if UF_SERIALIZER_AUTO_CONVERT
if ( uf::string::matched( filename, "/.json$/" ) ) {
if ( ext::json::PREFERRED_COMPRESSION != "" || (ext::json::PREFERRED_ENCODING != "" || ext::json::PREFERRED_ENCODING != "json") ) {
ext::json::EncodingSettings _settings;
_settings.encoding = ext::json::PREFERRED_ENCODING;
_settings.compression = ext::json::PREFERRED_COMPRESSION;
uf::stl::string _filename = filename;
if ( ext::json::PREFERRED_ENCODING != "" && ext::json::PREFERRED_ENCODING != "json" ) {
_settings.encoding = ext::json::PREFERRED_ENCODING;
_filename = uf::string::replace( _filename, "/.json$/", "." + ext::json::PREFERRED_ENCODING );
}
if ( ext::json::PREFERRED_COMPRESSION != "" ) {
_settings.compression = ext::json::PREFERRED_COMPRESSION;
_filename = _filename + "." + ext::json::PREFERRED_COMPRESSION;
}
bool should = !uf::io::exists( _filename ); // auto convert if preferred file doesn't already exist
if ( !should ) should = uf::io::mtime( _filename ) < uf::io::mtime( filename ); // auto convert if preferred file is older than source file
if ( should ) {
UF_MSG_DEBUG_("Auto converting: " << _filename );
writeToFile( _filename, _settings );
}
}
}
#endif
this->deserialize(string);
return true;
}
bool uf::Serializer::writeToFile( const uf::stl::string& filename, const ext::json::EncodingSettings& settings ) const {
uf::stl::string output = filename;
if ( settings.encoding != "" && settings.encoding != "json" )
output = uf::string::replace( output, "/.json/", "." + settings.encoding );
if ( settings.compression != "" && !uf::string::matched( output, "/."+settings.compression+"/" ) )
output += "." + settings.compression;
uf::stl::string buffer = this->serialize( settings );
size_t written = uf::io::write( filename + ( settings.compress ? ".gz" : "" ) , buffer.c_str(), buffer.size() );
if ( !written ) UF_MSG_ERROR("Failed to write JSON file `" << filename << "`");
size_t written = uf::io::write( output, buffer.c_str(), buffer.size() );
#if UF_SERIALIZER_AUTO_CONVERT
// implicitly check for optimal format for plain .json requests
if ( uf::string::matched( output, "/.json$/" ) && settings.compression != ext::json::PREFERRED_COMPRESSION ) {
uf::stl::string _filename = output;
auto _settings = settings;
if ( ext::json::PREFERRED_ENCODING != "" && ext::json::PREFERRED_ENCODING != "json" ) {
_settings.encoding = ext::json::PREFERRED_ENCODING;
// _filename = uf::string::replace( _filename, "/.json$/", "." + ext::json::PREFERRED_ENCODING );
}
if ( ext::json::PREFERRED_COMPRESSION != "" ) {
_settings.compression = ext::json::PREFERRED_COMPRESSION;
// _filename = _filename + "." + ext::json::PREFERRED_COMPRESSION;
}
writeToFile( _filename, _settings );
}
#endif
if ( !written ) UF_MSG_ERROR("Failed to write JSON file: " << output);
return written;
}

View File

@ -18,8 +18,7 @@ bool UF_API uf::string::match( const uf::stl::string& str, const uf::stl::string
bool UF_API uf::string::isRegex( const uf::stl::string& str ) {
return str.front() == '/' && str.back() == '/';
}
uf::stl::vector<uf::stl::string> UF_API uf::string::matches( const uf::stl::string& str, const uf::stl::string& r ) {
uf::stl::vector<uf::stl::string> UF_API uf::string::match( const uf::stl::string& str, const uf::stl::string& r ) {
std::regex regex(r.substr(1,r.length()-2));
std::smatch match;
uf::stl::vector<uf::stl::string> matches;
@ -31,6 +30,11 @@ uf::stl::vector<uf::stl::string> UF_API uf::string::matches( const uf::stl::stri
return matches;
}
bool UF_API uf::string::matched( const uf::stl::string& str, const uf::stl::string& r ) {
std::regex regex(r.substr(1,r.length()-2));
std::smatch match;
return std::regex_search( str, match, regex );
}
uf::stl::string UF_API uf::string::lowercase( const uf::stl::string& str ) {
uf::stl::string lower = str;
@ -78,9 +82,15 @@ uf::stl::string UF_API uf::string::join( const uf::stl::vector<uf::stl::string>&
*/
uf::stl::string UF_API uf::string::replace( const uf::stl::string& string, const uf::stl::string& search, const uf::stl::string& replace ) {
uf::stl::string result = string;
size_t start_pos = string.find(search);
if( start_pos == uf::stl::string::npos ) return result;
result.replace(start_pos, search.length(), replace);
if ( uf::string::isRegex(search) ) {
std::regex regex(search.substr(1,search.length()-2));
result = std::regex_replace( string, regex, replace );
} else {
size_t start_pos = string.find(search);
if( start_pos == uf::stl::string::npos ) return result;
result.replace(start_pos, search.length(), replace);
}
return result;
}
bool UF_API uf::string::contains( const uf::stl::string& string, const uf::stl::string& search ) {

View File

@ -156,7 +156,10 @@ SAVE: {
payload["uid"] = this->getUid();
uf::scene::getCurrentScene().queueHook("system:Destroy", payload);
if ( metadata.trigger.quits ) uf::scene::getCurrentScene().queueHook("system:Quit", payload);
if ( metadata.trigger.quits ) {
payload["message"] = "Termination after lightmap baking requested.";
uf::scene::getCurrentScene().queueHook("system:Quit", payload);
}
#endif
return;
}

View File

@ -79,7 +79,9 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
// Rotate Camera
this->addHook( "window:Mouse.Moved", [&](pod::payloads::windowMouseMoved& payload ){
pod::Vector2 relta = { (float) metadata.mouse.sensitivity.x * payload.mouse.delta.x / payload.window.size.x, (float) metadata.mouse.sensitivity.y * payload.mouse.delta.y / payload.window.size.y };
// pod::Vector2 relta = { (float) metadata.mouse.sensitivity.x * payload.mouse.delta.x * uf::physics::time::delta, (float) metadata.mouse.sensitivity.y * payload.mouse.delta.y * uf::physics::time::delta };
if ( (payload.mouse.delta.x == 0 && payload.mouse.delta.y == 0) || !metadata.system.control ) return;
// relta *= uf::physics::time::delta;
if ( payload.mouse.delta.x != 0 ) {
if ( metadata.camera.invert.x ) relta.x *= -1;
@ -93,11 +95,8 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
if ( metadata.camera.invert.y ) relta.y *= -1;
metadata.camera.limit.current.y += relta.y;
if ( metadata.camera.limit.current.y != metadata.camera.limit.current.y || ( metadata.camera.limit.current.y < metadata.camera.limit.max.y && metadata.camera.limit.current.y > metadata.camera.limit.min.y ) ) {
// if ( collider.body && !collider.shared ) {
// uf::physics::impl::applyRotation( collider, cameraTransform.right, relta.y );
// } else {
// if ( collider.body && !collider.shared ) uf::physics::impl::applyRotation( collider, cameraTransform.right, relta.y ); else
uf::transform::rotate( cameraTransform, cameraTransform.right, relta.y );
// }
} else metadata.camera.limit.current.y -= relta.y;
}
camera.update(true);

View File

@ -566,6 +566,7 @@ void ext::ExtSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serialize
serializer["light"]["exposure"] = /*this->*/light.exposure;
serializer["light"]["gamma"] = /*this->*/light.gamma;
serializer["light"]["brightnessThreshold"] = /*this->*/light.brightnessThreshold;
serializer["light"]["useLightmaps"] = /*this->*/light.useLightmaps;
serializer["light"]["fog"]["color"] = uf::vector::encode( /*this->*/fog.color );
serializer["light"]["fog"]["step scale"] = /*this->*/fog.stepScale;
@ -600,6 +601,7 @@ void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Seriali
/*this->*/light.exposure = serializer["light"]["exposure"].as<float>(1.0f);
/*this->*/light.gamma = serializer["light"]["gamma"].as<float>(2.2f);
/*this->*/light.brightnessThreshold = serializer["light"]["brightnessThreshold"].as<float>(ext::config["engine"]["scenes"]["bloom"]["brightnessThreshold"].as<float>(1.0f));
/*this->*/light.useLightmaps = ext::config["engine"]["scenes"]["lights"]["useLightmaps"].as<bool>(true);
/*this->*/bloom.scale = serializer["bloom"]["scale"].as(ext::config["engine"]["scenes"]["bloom"]["scale"].as(bloom.scale));
/*this->*/bloom.strength = serializer["bloom"]["strength"].as(ext::config["engine"]["scenes"]["bloom"]["strength"].as(bloom.strength));
@ -740,7 +742,7 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string
alignas(4) uint32_t shadowSamples;
alignas(4) uint32_t indexSkybox;
alignas(4) uint32_t padding1;
alignas(4) uint32_t useLightmaps;
alignas(4) uint32_t padding2;
alignas(4) uint32_t padding3;
};
@ -839,6 +841,8 @@ void ext::ExtSceneBehavior::bindBuffers( uf::Object& self, const uf::stl::string
uniforms.shadowSamples = std::min( 0, metadata.shadow.samples );
uniforms.indexSkybox = indexSkybox;
// use sample lightmaps during deferred pass
uniforms.useLightmaps = metadata.light.useLightmaps;
}
for ( auto* blitter : blitters ) {

View File

@ -25,6 +25,7 @@ namespace ext {
float exposure = 1.0f;
float gamma = 1.0f;
float brightnessThreshold = 1.0f;
bool useLightmaps = true;
} light;
struct {
float scale = 1.0f;

View File

@ -95,7 +95,7 @@ namespace {
}
void EXT_API ext::load() {
ext::config = uf::io::readAsString(uf::io::root+"/config.json");
ext::config.readFromFile(uf::io::root+"/config.json");
}
void EXT_API ext::initialize() {
@ -555,6 +555,9 @@ void EXT_API ext::initialize() {
uf::scene::unloadScene();
});
uf::hooks.addHook( "system:Quit", [&](ext::json::Value& json){
if ( json["message"].is<uf::stl::string>() ) {
UF_MSG_DEBUG( json["message"].as<uf::stl::string>() );
}
ext::ready = false;
});
}
@ -732,6 +735,9 @@ void EXT_API ext::terminate() {
ext::openvr::terminate();
}
#endif
{
uf::hooks.removeHooks();
}
#if UF_USE_LUA
{
ext::lua::terminate();
@ -744,7 +750,7 @@ void EXT_API ext::terminate() {
uf::scene::destroy();
}
/* Garbage collection */ if ( false ) {
/* Garbage collection */ if ( false ) { // segfaults, for some reason
size_t collected = uf::instantiator::collect( ::config.engine.gc.mode );
if ( ::config.engine.gc.announce && collected > 0 ) UF_MSG_DEBUG("GC collected " << (int) collected << " unused entities");
}