Commit for 2022.07.19 16-59-42.7z

This commit is contained in:
mrq 2022-07-19 16:59:00 -05:00
parent 0c76838ea1
commit 686a4f5e3e
68 changed files with 846 additions and 558 deletions

View File

@ -1,18 +1,25 @@
{
"engine": {
"scenes": {
"start": "SS2",
"start": "SourceEngine",
"matrix": { "reverseInfinite": true },
"meshes": { "interleaved": false },
"lights": { "enabled": true,
"useLightmaps": false,
"max": 48
},
"shadows": {
"enabled": true,
"update": 4,
"max": 24,
"samples": 1
"max": 48,
"shadows": {
"enabled": true,
"update": 4,
"max": 24,
"samples": 1
},
"bloom": {
"scale": 1.0,
"strength": 0.125,
"sigma": 0.8,
"samples": 5,
"threshold": 1.0
}
},
"textures": {
"max": {
@ -45,13 +52,6 @@
"samples": 1,
"paths": 2,
"frameAccumulationMinimum": 0
},
"bloom": {
"scale": 1.0,
"strength": 0.125,
"sigma": 0.8,
"samples": 5,
"threshold": 1.0
}
},
"graph": {
@ -298,6 +298,9 @@
},
"loader": {
"assert": true
},
"hooks": {
"defer lazy calls": true
}
}
},
@ -318,8 +321,8 @@
"mode" : "windowed", // fullscreen, borderless, windowed
"icon" : "./data/textures/icon.png",
// "size" : [ 1920, 1080 ],
"size" : [ 1280, 720 ],
// "size" : [ 960, 540 ],
// "size" : [ 1280, 720 ],
"size" : [ 960, 540 ],
// "size" : [ 640, 480 ],
// "size" : [ 256, 224 ],
"title" : "Grimgram",

View File

@ -34,7 +34,7 @@
"type": "bounding box",
"recenter": false
},
"model": {
"graph": {
"exporter": {
"enabled": true,
"unwrap": false,

View File

@ -24,7 +24,7 @@
"metadata": {
"track": true,
"hide": true,
"model": {
"graph": {
"lightmap": false,
"exporter": {
"enabled": false,

View File

@ -8,6 +8,7 @@ Static = {
end
}
local ent = ent
local scene = entities.currentScene()
local controller = entities.controller()
local camera = controller:getComponent("Camera")

View File

@ -23,7 +23,7 @@
"events": {
"click": {
"name": "game:Scene.Load",
"payload": { "scene": "SS2" }
"payload": { "scene": "SourceEngine" }
}
},
"text settings": {

View File

@ -1,3 +1,4 @@
local ent = ent
local scene = entities.currentScene()
local metadata = ent:getComponent("Metadata")
local masterdata = scene:getComponent("Metadata")

View File

@ -9,7 +9,7 @@
"scale": [ 1, 1, 1 ]
},
"metadata": {
"model": {
"graph": {
"debug": {
"no cleanup": false,
"print": {

View File

@ -28,7 +28,7 @@
"metadata": {
"track": true,
"hide": true,
"model": {
"graph": {
"debug": {
"print": {
"animations": true

View File

@ -11,7 +11,7 @@
"mass": 10,
"type": "bounding box",
"recenter": true
"recenter": false
}
}
}

View File

@ -1,3 +1,4 @@
local ent = ent
local scene = entities.currentScene()
local controller = entities.controller()

View File

@ -1,3 +1,4 @@
local ent = ent
local scene = entities.currentScene()
local metadata = ent:getComponent("Metadata")
local transform = ent:getComponent("Transform")
@ -49,7 +50,7 @@ light.entity:setComponent("Metadata", { light = { power = 0 } })
local playSound = function( key, loop )
if not loop then loop = false end
local url = "/ui/" .. key .. ".ogg"
ent:queueHook("sound:Emit.%UID%", {
ent:callHook("sound:Emit.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"]),
spatial = true,
streamed = true,
@ -59,7 +60,7 @@ local playSound = function( key, loop )
end
local stopSound = function( key )
local url = "/ui/" .. key .. ".ogg"
ent:queueHook("sound:Stop.%UID%", {
ent:callHook("sound:Stop.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"])
}, 0)
end
@ -118,9 +119,9 @@ ent:bind( "tick", function(self)
depth = depth,
}
if prop then
prop:callHook("entity:Use.%UID%", payload)
prop:lazyCallHook("entity:Use.%UID%", payload)
end
ent:callHook("entity:Use.%UID%", payload)
ent:lazyCallHook("entity:Use.%UID%", payload)
end
-- update HOLP

View File

@ -11,7 +11,7 @@
{ "filename": "./models/sponza-cornell/graph.json" }
],
"metadata": {
"model": {
"graph": {
"baking": {
"enabled": false,
"resolution": 2048,

View File

@ -4,60 +4,10 @@
// "./loading.json"
"./cornell.json"
],
"system": {
"hot reload": {
"enabled": true
},
"renderer": {
"clear values": [
[ 0, 0, 0, 0 ]
],
"shader": {
"mode": 1,
"scalar": 16,
"parameters": [ 0, 0, 0, "time" ]
}
}
},
"metadata": {
"menus": {
"pause": "/gui/pause/menu.json"
},
"bloom": {
"scale": 1.0,
"strength": 0.125,
"sigma": 0.8,
"samples": 5
},
"rt": {
"defaultRayBounds": [ 0.001, 1024.0 ],
"alphaTestOffset": 0.001,
"samples": 1,
"paths": 4,
"frameAccumulationMinimum": 0
},
"light": {
"exposure": 1.0,
"gamma": 1.0,
"brightnessThreshold": 1.2,
// "ambient": [ 0.0, 0.0, 0.0 ],
"ambient": [ 0.5, 0.5, 0.5 ],
"fog": {
"color": [ 0.025, 0.025, 0.1 ],
"step scale": 0.0,
"range": [ 1, 1 ],
"absorbtion": 0.85,
"density": {
"threshold": 0.5,
"multiplier": 5.0,
"scale": 50.0,
"offset": "time"
}
},
"should": true,
"shadows": true
"ambient": [ 0.5, 0.5, 0.5 ]
}
}
}

View File

@ -7,6 +7,21 @@
"SceneBehavior",
"ExtSceneBehavior"
],
"system": {
"hot reload": {
"enabled": true
},
"renderer": {
"clear values": [
[ 0, 0, 0, 0 ]
],
"shader": {
"mode": 1,
"scalar": 16,
"parameters": [ 0, 0, 0, "time" ]
}
}
},
"metadata": {
// sky, and not skybox, so i can supply parameters for global lighting
"sky": {
@ -14,6 +29,32 @@
"box": {
"filename": "/skybox/%d.png"
}
},
"menus": {
"pause": "/gui/pause/menu.json"
},
"light": {
"enabled": true,
"ambient": [ 0.0, 0.0, 0.0 ],
// "ambient": [ 0.1, 0.1, 0.2 ],
"exposure": 1.0,
"gamma": 2.2,
"brightnessThreshold": 1.2,
"bloom": {
"scale": 1.0,
"strength": 0.125,
"sigma": 0.8,
"samples": 5
},
"shadows": {
"enabled": true
}
},
"noise": {
"size": [ 32, 32, 32 ]
}
}
}

View File

@ -4,36 +4,8 @@
// "./loading.json",
"./sm64.json"
],
"system": {
"hot reload": {
"enabled": true
},
"renderer": {
"shader": {
"mode": 1,
"scalar": 16,
"parameters": [ 0, 0, 0, "time" ],
"frame accumulate limit": 0
},
"clear values": [
[ 1, 1, 1, 0 ]
]
}
},
"metadata": {
"menus": {
"pause": "/gui/pause/menu.json"
},
"bloom": {
"scale": 6.0,
"strength": 0.125,
"sigma": 0.125,
"samples": 8
},
"light": {
"exposure": 1.0,
"gamma": 1.0,
"brightnessThreshold": 1.2,
// "ambient": [ 0, 0, 0 ],
// "ambient": [ 0.025, 0.025, 0.025 ],
// "ambient": [ 0.075, 0.075, 0.075 ],
@ -42,48 +14,8 @@
// "ambient": [ 0.8, 0.8, 0.8 ],
"fog-": {
"color": [ 0.5, 0.5, 0.5 ],
"range": [ 16, 32 ],
"step scale": 2,
"absorbtion": 0.01,
"density": {
"threshold": 0.35,
"multiplier": 5.0,
"scale": 25.0,
"offset": [0, -1, 1],
"timescale": 8
}
},
"should": true,
"shadows": true
},
"noise": {
"size": [ 32, 32, 32 ]
},
"vxgi": {
/*
"limiter": 1,
"size": 96,
"dispatch": 8,
"cascades": 2,
"cascadePower": 4,
"voxelizeScale": 1,
"shadows": 0,
*/
"occlusionFalloff": 2,
"traceStartOffsetFactor": 1,
"granularity": 2,
"extents": {
"min": [ -1.5, -1.5, -1.5 ],
"max": [ 1.5, 1.5, 1.5 ]
}
},
"rt": {
"defaultRayBounds": [ 0.001, 1024.0 ],
"alphaTestOffset": 1.125,
"samples": 1,
"paths": 1,
"frameAccumulationMinimum": 0
}
}
}

View File

@ -5,7 +5,7 @@
{ "filename": "./models/sm64_bbb/graph.json" }
],
"metadata": {
"model": {
"graph": {
"baking": {
"enabled": true,
"resolution": 2048,

View File

@ -1,7 +1,7 @@
{
"import": "/model.json",
"metadata": {
"model": {
"graph": {
// "renderer": { "separate": true },
"baking": { "enabled": false },
"tags": {
@ -14,7 +14,7 @@
},
"info_player_spawn": { "action": "attach", "filename": "./player.json", "transform": { "orientation": [ 0, 1, 0, 0 ] } },
"light_environment": { "transform": { "orientation": [0,0,0,1] }, "light": {
"power": 100000,
"power": 1,
"global": true,
"bias": {
"constant": 1.25,
@ -26,7 +26,7 @@
} },
// regexp matches
"/^worldspawn/": { "physics": { "type": "mesh", "static": true } },
"/^worldspawn_/": { "physics": { "type": "mesh", "static": true } },
"/^func_door_/": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"/^prop_door_/": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"/^prop_static/": { /*"action": "load", "payload": { "import": "/prop.json", "metadata": { "physics": { "gravity": [ 0, 0, 0 ] } } }*/ },

View File

@ -5,7 +5,10 @@
{ "filename": "./models/gm_construct/graph.json" }
],
"metadata": {
"model": {
"graph": {
"assets": [
"./audio/soundscape/ambience.ogg"
],
"tags": {
// exact matches
"worldspawn_skybox": { "ignore": true },

View File

@ -5,7 +5,10 @@
{ "filename": "./models/mds_mcdonalds/graph.json" }
],
"metadata": {
"model": {
"graph": {
"assets": [
"./audio/soundscape/sh2_ambience.ogg"
],
"tags": {
// exact matches
"func_door_rotating_5473": { "action": "load", "payload": { "import": "/door.json", "metadata": { "angle":-1.570795, "normal": [1,0,0] } } },

View File

@ -2,6 +2,9 @@
"import": "/player.json",
"assets": [
// { "filename": "/gui/hud/hud.json", "delay": 0 }
]
],
"transform": {
"orientation": [ 0, 1, 0, 0 ]
}
// "metadata": { "physics": { "gravity": [ 0, 0, 0 ] } }
}

View File

@ -1,13 +1,14 @@
{
"import": "./base_sourceengine.json",
"assets": [
"./audio/soundscape/ambience.ogg",
// { "filename": "./models/rp_downtown_v2.glb" }
{ "filename": "./models/rp_downtown_v2/graph.json" }
],
"metadata": {
"model": {
"graph": {
"assets": [
"./audio/soundscape/ambience.ogg"
],
"renderer": { "separate": true },
"tags": {
// exact matches

View File

@ -1,41 +1,24 @@
{
"import": "/scene.json",
"assets": [
"./audio/soundscape/sh2_ambience.ogg",
"./sourceengine.json"
// "./loading.json"
],
"system": {
"hot reload": {
"enabled": true
},
"renderer": {
"clear values": [
[ 0, 0, 0, 0 ]
],
"shader": {
"mode": 1,
"scalar": 16,
"parameters": [ 0, 0, 0, "time" ]
}
}
},
"metadata": {
"menus": {
"pause": "/gui/pause/menu.json"
},
"light": {
"exposure": 1.0,
"gamma": 1.0,
// "ambient": [ 0, 0, 0 ],
"ambient": [ 0.05, 0.05, 0.05 ],
"ambient": [ 0, 0, 0 ],
// "ambient": [ 0.05, 0.05, 0.05 ],
// "ambient": [ 0.15, 0.15, 0.15 ],
// "ambient": [ 0.5, 0.5, 0.5 ],
// "ambient": [ 0.8, 0.8, 0.8 ],
// "ambient": [ 0.1, 0.1, 0.2 ],
"exposure": 0.25,
"gamma": 2.2,
"brightnessThreshold": 1.2,
"fog": {
"color": [ 0.5, 0.5, 0.5 ],
"color": [ 0.1, 0.1, 0.1 ],
"range": [ 64, 256 ],
"step scale": 2,
"absorbtion": 0.0125,
@ -46,19 +29,7 @@
"offset": [0.2, 0, 1],
"timescale": 8
}
},
"should": true,
"shadows": true
},
"noise": {
"size": [ 32, 32, 32 ]
},
"rt": {
"defaultRayBounds": [ 0.5, 1024.0 ],
"alphaTestOffset": 0.01,
"samples": 1,
"paths": 1,
"frameAccumulationMinimum": 0
}
}
}
}

View File

@ -5,7 +5,10 @@
{ "filename": "./models/sh2_mcdonalds/graph.json" }
],
"metadata": {
"model": {
"graph": {
"assets": [
"./audio/soundscape/sh2_ambience.ogg"
],
"tags": {
// exact matches
"worldspawn_sh2": {

View File

@ -1,4 +1,6 @@
{
// "import": "./rp_downtown_v2.json"
// "import": "./ss2_medsci1.json"
"import": "./sh2_mcdonalds.json"
// "import": "./gm_construct.json"
}

View File

@ -0,0 +1,18 @@
{
"import": "./base_sourceengine.json",
"assets": [
// { "filename": "./models/ss2_medsci1.glb" }
{ "filename": "./models/ss2_medsci1/graph.json" }
],
"metadata": {
"graph": {
"assets": [
"./audio/music/medsci1.ogg"
],
"tags": {
"/^prop_/": { "action": "load", "payload": { "import": "/prop.json", "metadata": { "physics": { "gravity": [ 0, 0, 0 ] } } } },
"/^func_/": { "action": "load", "payload": { "import": "/prop.json", "metadata": { "physics": { "gravity": [ 0, 0, 0 ] } } } }
}
}
}
}

View File

@ -9,7 +9,7 @@
"scale": [8, 8, 8]
},
"metadata": {
"model": {
"graph": {
"cull mode": "none"
}
}

View File

@ -17,7 +17,7 @@
// { "filename": "./models/medsci/graph.json" }
],
"metadata": {
"model": {
"graph": {
"baking": {
"enabled": true,
"resolution": 2048
@ -41,8 +41,8 @@
"light_30145": { "light": { "power": 120 } },
"/^prop_camera_.+?_light/": { /*"bake": false,*/ "light": { "shadows": false, "static": false, "dynamic": true, "power": 30 } },
"/prop_camera_/": { /*"bake": false,*/ "action": "load", "payload": { "import": "./camera.json" } },
"/^prop_camera_\\d+_light/": { /*"bake": false,*/ "light": { "shadows": false, "static": false, "dynamic": true, "power": 30 } },
"/^prop_camera_\\d+$/": { /*"bake": false,*/ "action": "load", "payload": { "import": "./camera.json" } },
"func_movelinear_57637": { /*"bake": false,*/ "action": "load", "payload": { "import": "./lift.json", "metadata": { "delta": [ 0,8.6,0 ] } } },
"func_movelinear_82820": { /*"bake": false,*/ "action": "load", "payload": { "import": "./lift.json", "metadata": { "delta": [ 0,9.2,0 ] } } },

View File

@ -5,38 +5,10 @@
// "./loading.json"
"./medsci.json"
],
"system": {
"hot reload": {
"enabled": true
},
"renderer": {
"clear values": [
[ 0, 0, 0, 0 ]
],
"shader": {
"mode": 1,
"scalar": 16,
"parameters": [ 0, 0, 0, "time" ]
}
}
},
"metadata": {
"menus": {
"pause": "/gui/pause/menu.json"
},
"bloom": {
"scale": 1.0,
"strength": 0.125,
"sigma": 0.8,
"samples": 5
},
"light": {
"exposure": 1.0,
"gamma": 1.0,
"brightnessThreshold": 1.2,
// "ambient": [ 0.0, 0.0, 0.0 ],
"ambient": [ 0.1, 0.1, 0.2 ],
"ambient": [ 0.0, 0.0, 0.0 ],
// "ambient": [ 0.1, 0.1, 0.2 ],
"fog": {
"color": [ 0.025, 0.025, 0.1 ],
@ -49,9 +21,7 @@
"scale": 50.0,
"offset": "time"
}
},
"should": true,
"shadows": true
}
}
}
}

View File

@ -1,12 +1,15 @@
local ent = ent
local scene = entities.currentScene()
local controller = entities.controller()
local controllerTransform = controller:getComponent("Transform")
local timer = Timer.new()
if not timer:running() then
timer:start();
end
if not timer:running() then timer:start() end
local metadata = ent:getComponent("Metadata")
local soundEmitter = ent:loadChild("/sound.json",true)
local transform = ent:getComponent("Transform")
local physicsState = ent:getComponent("PhysicsState")
local soundEmitter = ent --ent:loadChild("/sound.json",true)
local playSound = function( key )
if not loop then loop = false end
local url = "./audio/sfx/" .. key .. ".ogg"
@ -36,7 +39,6 @@ local stopSoundscape = function( key )
end
local target = Vector3f(0,0,0)
local transform = ent:getComponent("Transform")
local speed = metadata["speed"] or 1.0 / 3.0
local angle = metadata["angle"] or 1.5
transform.orientation = Quaternion.axisAngle( Vector3f(0,1,0), 1.5 )
@ -62,11 +64,6 @@ ent:bind( "tick", function(self)
local angleThreshold = metadata["sensitivity"] or 20
local controllerPosition = Vector3f(controllerTransform.position.x, 0, controllerTransform.position.z)
local cameraPosition = Vector3f(transform.position.x, 0, transform.position.z)
local distance = cameraPosition:distance(controllerPosition)
local direction = cameraPosition - controllerPosition
local lightTransform = light and light:getComponent("Transform") or nil
local lightMetadata = light and light:getComponent("Metadata") or {}
if lightTransform ~= nil then
@ -76,6 +73,10 @@ ent:bind( "tick", function(self)
end
end
local controllerPosition = Vector3f(controllerTransform.position.x, 0, controllerTransform.position.z)
local cameraPosition = Vector3f(transform.position.x, 0, transform.position.z)
local distance = cameraPosition:distance(controllerPosition)
local direction = cameraPosition - controllerPosition
local angle = math.acos(transform.orientation:rotate( Vector3f(0,0,1):normalize() ):dot( direction:normalize() )) * 180.0 / 3.1415926
if angle < angleThreshold and distance < 16 then
if watch == 0 then
@ -181,11 +182,13 @@ ent:bind( "tick", function(self)
delta = delta + time.delta() * speed
local nextRotation = starting:slerp( ending, math.cos(delta) * 0.5 + 0.5 )
--[[
-- stop if we are going to look away from player
local angleNext = math.acos(nextRotation:rotate( Vector3f(0,0,1):normalize() ):dot( direction:normalize() )) * 180.0 / 3.1415926
if watch > 0 and angleNext > angle then
delta = delta - time.delta() * speed * 3
nextRotation = starting:slerp( ending, math.cos(delta) * 0.5 + 0.5 )
end
]]
transform.orientation = nextRotation
end )

View File

@ -1,3 +1,4 @@
local ent = ent
local scene = entities.currentScene()
local controller = entities.controller()
@ -10,7 +11,6 @@ local target = Vector3f(0,0,0)
local transform = ent:getComponent("Transform")
local metadata = ent:getComponent("Metadata")
local physics = ent:getComponent("Physics")
local bullet = ent:getComponent("Bullet")
-- local velocty = physics:linearVelocity()
local speed = metadata["speed"] or 1.0
local starting = transform.position + Vector3f(0,0,0)
@ -73,10 +73,8 @@ ent:bind( "tick", function(self)
stopSound("lift_start")
playSound("lift_stop")
startingSound = true
-- bullet:setVelocity( Vector3f(0,0,0) )
-- physics:setLinearVelocity( Vector3f(0,0,0) )
else
-- bullet:setVelocity( Vector3f(0,direction,0) )
-- physics:setLinearVelocity( Vector3f(0,direction / math.abs(direction),0) )
end
end

View File

@ -6,14 +6,9 @@
],
"assets": [
"/gui.json",
// "./player.json",
"/ui/main menu.ogg",
"/gui/mainmenu/menu.json"
],
"hot reload": {
"enabled": true
},
"clear color": [ 0, 0, 0, 1 ],
"metadata": {
"volumes": {
"sfx": 0.25,

View File

@ -133,6 +133,7 @@ void client::tick() {
client::window.toggleFullscreen( false );
}
// mouse move
uf::inputs::kbm::states::Mouse = {};
if ( client::config["window"]["mouse"]["center"].as<bool>() ) {
auto size = client::window.getSize();
auto current = client::window.getMousePosition();
@ -140,6 +141,12 @@ void client::tick() {
client::window.setMousePosition(client::window.getSize() / 2.0f);
client::window.setCursorVisible(false);
#if UF_INPUT_USE_ENUM_MOUSE
uf::inputs::kbm::states::Mouse = {
(current.x - center.x) / (float) size.x,
(current.y - center.y) / (float) size.y,
};
#else
uf::hooks.call("window:Mouse.Moved", pod::payloads::windowMouseMoved{
{
{ "window:Mouse.Moved", "client", },
@ -147,6 +154,7 @@ void client::tick() {
},
{ center, current - center, 0 }
});
#endif
}
}
}

View File

@ -14,6 +14,7 @@ namespace uf {
public:
static uf::Timer<long long> timer;
static bool assertionLoad;
static bool deferLazyCalls;
Object();
@ -21,6 +22,8 @@ namespace uf {
bool load( const uf::stl::string&, bool = false );
bool load( const uf::Serializer& );
void loadAssets( const uf::Serializer& );
uf::Object& loadChild( const uf::Serializer&, bool = true );
uf::Object* loadChildPointer( const uf::Serializer&, bool = true );
std::size_t loadChildUid( const uf::Serializer&, bool = true );
@ -41,7 +44,12 @@ namespace uf {
uf::Hooks::return_t callHook( const uf::stl::string& );
uf::Hooks::return_t callHook( const uf::stl::string&, const pod::Hook::userdata_t& );
uf::Hooks::return_t lazyCallHook( const uf::stl::string& );
uf::Hooks::return_t lazyCallHook( const uf::stl::string&, const pod::Hook::userdata_t& );
template<typename T> uf::Hooks::return_t callHook( const uf::stl::string& name, const T& payload );
template<typename T> uf::Hooks::return_t lazyCallHook( const uf::stl::string& name, const T& payload );
void queueHook( const uf::stl::string&, float = 0 );
void queueHook( const uf::stl::string&, double );

View File

@ -34,6 +34,15 @@ uf::Hooks::return_t uf::Object::callHook( const uf::stl::string& name, const T&
return uf::hooks.call( this->formatHookName( name ), payload );
}
template<typename T>
uf::Hooks::return_t uf::Object::lazyCallHook( const uf::stl::string& name, const T& p ) {
if ( uf::Object::deferLazyCalls ) {
this->queueHook( name, p, 0.0f );
return {};
}
return this->callHook( name, p );
}
template<typename T>
void uf::Object::queueHook( const uf::stl::string& name, const T& p, float d ) {
// if ( !uf::Object::timer.running() ) uf::Object::timer.start();

View File

@ -67,13 +67,7 @@ namespace ext {
size_t initializeBuffer( const void*, VkDeviceSize, VkBufferUsageFlags, VkMemoryPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, bool = VK_DEFAULT_STAGE_BUFFERS );
bool updateBuffer( const void*, VkDeviceSize, const Buffer&, bool = VK_DEFAULT_STAGE_BUFFERS ) const;
// template<typename T> inline size_t initializeBuffer( const T* data, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryProperties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return initializeBuffer( (const void*) data, static_cast<VkDeviceSize>(sizeof(T)), usage, memoryProperties, stage ); }
// template<typename T> inline size_t initializeBuffer( const T& data, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryProperties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, bool stage = VK_DEFAULT_STAGE_BUFFERS ) { return initializeBuffer( (const void*) &data, static_cast<VkDeviceSize>(sizeof(T)), usage, memoryProperties, stage ); }
inline bool updateBuffer( const void* data, VkDeviceSize length, size_t index = 0, bool stage = VK_DEFAULT_STAGE_BUFFERS ) const { return updateBuffer( data, length, buffers.at(index), stage ); }
// template<typename T> inline bool updateBuffer( const T* data, const Buffer& buffer, bool stage = VK_DEFAULT_STAGE_BUFFERS ) const { return updateBuffer( (const void*) data, static_cast<VkDeviceSize>(sizeof(T)), buffer, stage ); }
// template<typename T> inline bool updateBuffer( const T& data, const Buffer& buffer, bool stage = VK_DEFAULT_STAGE_BUFFERS ) const { return updateBuffer( (const void*) &data, static_cast<VkDeviceSize>(sizeof(T)), buffer, stage ); }
};
struct AccelerationStructure {

View File

@ -8,6 +8,18 @@
namespace ext {
namespace vulkan {
enum QueueEnum {
GRAPHICS,
PRESENT,
COMPUTE,
TRANSFER,
};
struct CommandBuffer {
bool immediate{true};
QueueEnum queueType{QueueEnum::TRANSFER};
VkCommandBuffer handle{VK_NULL_HANDLE};
};
struct UF_API Device {
VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger;
@ -50,14 +62,20 @@ namespace ext {
uf::ThreadUnique<VkQueue> transfer;
} queues;
struct {
uf::stl::vector<Buffer> buffers;
uf::stl::unordered_map<QueueEnum, uf::stl::vector<VkCommandBuffer>> commandBuffers;
} transient;
/*
struct {
uf::stl::vector<Buffer> buffers;
uf::stl::unordered_map<QueueEnum, CommandBuffer> commandBuffers;
} reusable;
*/
uf::Window* window;
enum QueueEnum {
GRAPHICS,
PRESENT,
COMPUTE,
TRANSFER,
};
struct QueueFamilyIndices {
uint32_t graphics;
uint32_t present;
@ -69,27 +87,25 @@ namespace ext {
// helpers
uint32_t getQueueFamilyIndex( VkQueueFlagBits queueFlags );
uint32_t getMemoryType( uint32_t typeBits, VkMemoryPropertyFlags properties, VkBool32 *memTypeFound = nullptr );
VkCommandBuffer createCommandBuffer( VkCommandBufferLevel level, bool begin = true );
VkCommandBuffer createCommandBuffer( VkCommandBufferLevel level, QueueEnum queue, bool begin = true );
void flushCommandBuffer( VkCommandBuffer commandBuffer, QueueEnum queue, bool wait = false );
void flushCommandBuffer( VkCommandBuffer commandBuffer, bool free = true );
void flushCommandBuffer( VkCommandBuffer commandBuffer, QueueEnum queue, bool free = true );
CommandBuffer fetchCommandBuffer( QueueEnum queue, bool waits = true );
void flushCommandBuffer( CommandBuffer commandBuffer );
VkResult createBuffer(
const void* data,
VkDeviceSize size,
VkBufferUsageFlags usage,
VkMemoryPropertyFlags memoryProperties,
VkDeviceSize size,
VkBuffer* buffer,
VkDeviceMemory *memory,
const void* data = nullptr
ext::vulkan::Buffer& buffer
);
VkResult createBuffer(
VkBufferUsageFlags usage,
VkMemoryPropertyFlags memoryProperties,
ext::vulkan::Buffer& buffer,
ext::vulkan::Buffer fetchTransientBuffer(
const void* data,
VkDeviceSize size,
const void* data = nullptr
VkBufferUsageFlags usage,
VkMemoryPropertyFlags memoryProperties
);
VkQueue& getQueue( QueueEnum );

View File

@ -4,6 +4,8 @@
#include <uf/utils/string/string.h>
#include <uf/utils/math/vector.h>
#define UF_INPUT_USE_ENUM_MOUSE 1
namespace uf {
namespace inputs {
#if UF_WINDOW_KEYCODE_STRINGS
@ -126,6 +128,7 @@ namespace uf {
constexpr key_t Num9 = UF_KEY("Num9");
constexpr key_t Num0 = UF_KEY("Num0");
constexpr key_t Mouse = UF_KEY("Mouse");
constexpr key_t Mouse1 = UF_KEY("Mouse1");
constexpr key_t Mouse2 = UF_KEY("Mouse2");
constexpr key_t Mouse3 = UF_KEY("Mouse3");
@ -234,6 +237,7 @@ namespace uf {
extern UF_API state_t Num9;
extern UF_API state_t Num0;
extern UF_API analog2_t Mouse;
extern UF_API state_t Mouse1;
extern UF_API state_t Mouse2;
extern UF_API state_t Mouse3;

View File

@ -75,7 +75,7 @@ void uf::Behaviors::generateGraph() {
std::reverse( m_graph.destroy.begin(), m_graph.destroy.end() );
}
// uf::scene::invalidateGraphs();
uf::scene::invalidateGraphs();
}
#define UF_BEHAVIOR_POLYFILL UF_BEHAVIOR_POLYFILL_GRAPH

View File

@ -107,7 +107,7 @@ pod::Graph& UF_API uf::graph::convert( uf::Object& object, bool process ) {
auto& graph = object.getComponent<pod::Graph>();
graph.name = object.getName();
graph.metadata = object.getComponent<uf::Serializer>()["model"];
graph.metadata = object.getComponent<uf::Serializer>()["graph"];
graph.root.entity = &object;
::process( object, graph, graph.root );

View File

@ -462,6 +462,49 @@ void uf::graph::process( pod::Graph& graph ) {
//
if ( !graph.root.entity ) graph.root.entity = new uf::Object;
// copy lighting settings from graph
auto& scene = uf::scene::getCurrentScene();
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
#if 1
// merge light settings with global settings
{
const auto& globalSettings = graph.metadata["light"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( sceneMetadataJson["light"][key] ) ) return;
sceneMetadataJson["light"][key] = value;
} );
}
// merge bloom settings with global settings
{
const auto& globalSettings = graph.metadata["light"]["bloom"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( sceneMetadataJson["light"]["bloom"][key] ) ) return;
sceneMetadataJson["light"]["bloom"][key] = value;
} );
}
// merge shadows settings with global settings
{
const auto& globalSettings = graph.metadata["light"]["shadows"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( sceneMetadataJson["light"]["shadows"][key] ) ) return;
sceneMetadataJson["light"]["shadows"][key] = value;
} );
}
// merge fog settings with global settings
{
const auto& globalSettings = graph.metadata["light"]["fog"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( sceneMetadataJson["light"]["fog"][key] ) ) return;
sceneMetadataJson["light"]["fog"][key] = value;
} );
}
#endif
#if 0
if ( ext::json::isObject(graph.metadata["assets"]) || ext::json::isArray(graph.metadata["assets"]) ) {
scene.loadAssets(graph.metadata["assets"]);
}
#endif
//
uf::stl::unordered_map<uf::stl::string, bool> isSrgb;
@ -490,9 +533,7 @@ void uf::graph::process( pod::Graph& graph ) {
}
}
auto& scene = uf::scene::getCurrentScene();
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
if ( !sceneMetadataJson["system"]["config"]["engine"]["scenes"]["lights"]["useLightmaps"].as<bool>(true) ) {
if ( !sceneMetadataJson["light"]["useLightmaps"].as<bool>(true) ) {
graph.metadata["lights"]["lightmap"] = false;
graph.metadata["baking"]["enabled"] = false;
}
@ -941,10 +982,13 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
auto& childMetadataJson = child.getComponent<uf::Serializer>();
auto flatten = uf::transform::flatten( node.transform );
if ( !tag["preserve position"].as<bool>() ) childTransform.position = flatten.position;
if ( !tag["preserve orientation"].as<bool>() ) childTransform.orientation = flatten.orientation;
// if ( !tag["preserve position"].as<bool>(false) ) childTransform.position = flatten.position;
// if ( !tag["preserve orientation"].as<bool>(false) ) childTransform.orientation = flatten.orientation;
// childTransform.position = flatten.position;
// childTransform.orientation = flatten.orientation;
childTransform = flatten;
// childMetadataJson["transform"] = uf::transform::encode( flatten );
}
if ( tag["static"].is<bool>() ) {

View File

@ -36,7 +36,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
pod::payloads::assetLoad payload;
payload.uid = this->getUid();
parent.callHook("asset:Parsed.%UID%", payload);
parent.lazyCallHook("asset:Parsed.%UID%", payload);
}
}
@ -93,7 +93,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
auto& parent = this->getParent().as<uf::Object>();
payload.uid = this->getUid();
parent.callHook("asset:Parsed.%UID%", payload);
parent.lazyCallHook("asset:Parsed.%UID%", payload);
}
});

View File

@ -34,8 +34,8 @@ void uf::GraphBehavior::initialize( uf::Object& self ) {
auto& graph = (this->getComponent<pod::Graph>() = std::move( assetLoader.get<pod::Graph>(payload.filename) ));
assetLoader.remove<pod::Graph>(payload.filename);
#if 0
bool shouldUpdate = false;
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
if ( !ext::json::isNull(graph.metadata["ambient"]) ) {
sceneMetadataJson["light"]["ambient"] = graph.metadata["ambient"];
@ -54,6 +54,7 @@ void uf::GraphBehavior::initialize( uf::Object& self ) {
shouldUpdate = true;
}
if ( shouldUpdate ) scene.callHook("object:Deserialize.%UID%");
#endif
// deferred shader loading
auto& transform = this->getComponent<pod::Transform<>>();
@ -62,8 +63,8 @@ void uf::GraphBehavior::initialize( uf::Object& self ) {
uf::graph::initialize( graph );
if ( graph.metadata["renderer"]["skinned"].as<bool>() ) {
if ( metadata["model"]["animation"].is<uf::stl::string>() ) {
uf::graph::animate( graph, metadata["model"]["animation"].as<uf::stl::string>() );
if ( metadata["graph"]["animation"].is<uf::stl::string>() ) {
uf::graph::animate( graph, metadata["graph"]["animation"].as<uf::stl::string>() );
}
}

View File

@ -73,7 +73,7 @@ void uf::LoadingBehavior::tick( uf::Object& self ) {
if ( loading == loaded ) {
metadata.system.loaded = true;
this->callHook("system:Load.Finished.%UID%");
this->lazyCallHook("system:Load.Finished.%UID%");
}
}
void uf::LoadingBehavior::render( uf::Object& self ) {}

View File

@ -18,6 +18,7 @@ namespace {
uf::Timer<long long> uf::Object::timer(false);
bool uf::Object::assertionLoad = true;
bool uf::Object::deferLazyCalls = true;
UF_OBJECT_REGISTER_BEGIN(uf::Object)
UF_OBJECT_REGISTER_BEHAVIOR(uf::EntityBehavior)
@ -39,6 +40,21 @@ uf::Hooks::return_t uf::Object::callHook( const uf::stl::string& name ) {
uf::Hooks::return_t uf::Object::callHook( const uf::stl::string& name, const pod::Hook::userdata_t& payload ) {
return uf::hooks.call( this->formatHookName( name ), payload );
}
uf::Hooks::return_t uf::Object::lazyCallHook( const uf::stl::string& name ) {
if ( uf::Object::deferLazyCalls ) {
this->queueHook( name, 0.0f );
return {};
}
return this->callHook( name );
}
uf::Hooks::return_t uf::Object::lazyCallHook( const uf::stl::string& name, const pod::Hook::userdata_t& payload ) {
if ( uf::Object::deferLazyCalls ) {
this->queueHook( name, payload, 0.0f );
return {};
}
return this->callHook( name, payload );
}
void uf::Object::queueHook( const uf::stl::string& name, double timeout ) {
return queueHook( name, (float) timeout );
}
@ -147,10 +163,80 @@ bool uf::Object::reload( bool hard ) {
return true;
}
void uf::Object::loadAssets( const uf::Serializer& _json ){
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
auto& metadataJson = this->getComponent<uf::Serializer>();
auto& scene = uf::scene::getCurrentScene();
auto& assetLoader = scene.getComponent<uf::Asset>();
ext::json::Value json = _json;
#define ASSET_ENTRY(type) { uf::string::lowercase(#type), uf::Asset::Type::type }
const uf::stl::unordered_map<uf::stl::string, uf::Asset::Type> assets = {
ASSET_ENTRY(AUDIO),
ASSET_ENTRY(IMAGE),
ASSET_ENTRY(GRAPH),
ASSET_ENTRY(LUA),
};
for ( auto& pair : assets ) {
auto& assetType = pair.second;
auto& assetTypeString = pair.first;
uf::Serializer target;
bool override = false;
if ( ext::json::isObject( json ) && ext::json::isArray( json["assets"] ) ) {
target = json["assets"];
} else if ( ext::json::isObject( json ) && ext::json::isObject( json["assets"] ) && !ext::json::isNull( json["assets"][assetTypeString] ) ) {
target = json["assets"][assetTypeString];
} else if ( ext::json::isArray( json ) ) {
target = json;
} else if ( ext::json::isObject( json ) && !ext::json::isNull( json[assetTypeString] ) ) {
target = json[assetTypeString];
}/* else if ( ext::json::isObject( metadataJson["system"]["assets"] ) ) {
target = metadataJson["system"]["assets"];
}*/
for ( size_t i = 0; i < target.size(); ++i ) {
bool isObject = ext::json::isObject( target[i] );
uf::stl::string f = isObject ? target[i]["filename"].as<uf::stl::string>() : target[i].as<uf::stl::string>();
uf::stl::string filename = uf::io::resolveURI( f, metadata.system.root );
uf::stl::string mime = isObject ? target[i]["mime"].as<uf::stl::string>("") : "";
uf::Asset::Payload payload = uf::Asset::resolveToPayload( filename, mime );
if ( !uf::Asset::isExpected( payload, assetType ) ) continue;
payload.hash = isObject ? target[i]["hash"].as<uf::stl::string>("") : "";
payload.monoThreaded = isObject ? !target[i]["multithreaded"].as<bool>(true) : !true;
this->queueHook( "asset:QueueLoad.%UID%", payload, isObject ? target[i]["delay"].as<float>() : 0 );
bool bind = isObject ? target[i]["bind"].as<bool>(true) : true;
switch ( assetType ) {
case uf::Asset::Type::LUA: {
if ( bind ) uf::instantiator::bind("LuaBehavior", *this);
} break;
case uf::Asset::Type::GRAPH: {
auto graphMetadata = json["metadata"]["graph"];
auto& aMetadata = assetLoader.getComponent<uf::Serializer>();
aMetadata[filename] = graphMetadata;
aMetadata[filename]["root"] = json["root"];
if ( bind ) uf::instantiator::bind("GraphBehavior", *this);
// nasty hack to get soundscapes/music to load while the rest of the graph loads
if ( ext::json::isObject(graphMetadata["assets"]) || ext::json::isArray(graphMetadata["assets"]) ) {
scene.loadAssets(graphMetadata["assets"]);
}
} break;
}
}
}
}
bool uf::Object::load( const uf::Serializer& _json ) {
auto& metadata = this->getComponent<uf::ObjectBehavior::Metadata>();
auto& metadataJson = this->getComponent<uf::Serializer>();
auto& scene = uf::scene::getCurrentScene();
auto& assetLoader = scene.getComponent<uf::Asset>();
uf::Serializer json = _json;
// setup root/source/mtime
if ( json["source"].is<uf::stl::string>() ) {
metadata.system.filename = json["source"].as<uf::stl::string>();
@ -204,8 +290,6 @@ bool uf::Object::load( const uf::Serializer& _json ) {
// Basic entity information
// Set name
this->m_name = json["name"].is<uf::stl::string>() ? json["name"].as<uf::stl::string>() : json["type"].as<uf::stl::string>();
uf::Scene& scene = uf::scene::getCurrentScene();
uf::Asset& assetLoader = scene.getComponent<uf::Asset>();
// Set transform
{
bool load = true;
@ -233,6 +317,15 @@ bool uf::Object::load( const uf::Serializer& _json ) {
}
}
// Load assets
#if 1
{
this->loadAssets( json );
}
#else
auto& scene = uf::scene::getCurrentScene();
auto& assetLoader = scene.getComponent<uf::Asset>();
#define ASSET_ENTRY(type) { uf::string::lowercase(#type), uf::Asset::Type::type }
const uf::stl::unordered_map<uf::stl::string, uf::Asset::Type> assets = {
ASSET_ENTRY(AUDIO),
@ -273,13 +366,14 @@ bool uf::Object::load( const uf::Serializer& _json ) {
} break;
case uf::Asset::Type::GRAPH: {
auto& aMetadata = assetLoader.getComponent<uf::Serializer>();
aMetadata[filename] = json["metadata"]["model"];
aMetadata[filename] = json["metadata"]["graph"];
aMetadata[filename]["root"] = json["root"];
if ( bind ) uf::instantiator::bind("GraphBehavior", *this);
} break;
}
}
}
#endif
// Bind behaviors
{
if ( json["type"].is<uf::stl::string>() ) uf::instantiator::bind( json["type"].as<uf::stl::string>(), *this );

View File

@ -449,7 +449,7 @@ void ext::imgui::initialize() {
imguiInitInfo.PhysicalDevice = uf::renderer::device.physicalDevice;
imguiInitInfo.Device = uf::renderer::device.logicalDevice;
imguiInitInfo.QueueFamily = uf::renderer::device.queueFamilyIndices.graphics;
imguiInitInfo.Queue = uf::renderer::device.getQueue( uf::renderer::Device::GRAPHICS );
imguiInitInfo.Queue = uf::renderer::device.getQueue( uf::renderer::QueueEnum::GRAPHICS );
imguiInitInfo.PipelineCache = uf::renderer::device.pipelineCache;
imguiInitInfo.DescriptorPool = ::descriptorPool;
imguiInitInfo.Subpass = 0;
@ -463,9 +463,9 @@ void ext::imgui::initialize() {
}
{
// Use any command queue
VkCommandBuffer commandBuffer = uf::renderer::device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::TRANSFER);
VkCommandBuffer commandBuffer = uf::renderer::device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::QueueEnum::TRANSFER);
ImGui_ImplVulkan_CreateFontsTexture(commandBuffer);
uf::renderer::device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::TRANSFER);
uf::renderer::device.flushCommandBuffer(commandBuffer, uf::renderer::QueueEnum::TRANSFER);
ImGui_ImplVulkan_DestroyFontUploadObjects();
}

View File

@ -9,11 +9,64 @@
#include <uf/engine/object/behaviors/lua.h>
namespace binds {
namespace enums {
enum Components {
Metadata,
Transform,
Audio,
Asset,
Camera,
Physics,
PhysicsState,
};
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{
#define UF_LUA_REGISTER_ENUM(E) #E, enums::Components::E
ext::lua::onInitialization( []{
auto enums = ext::lua::state.new_enum("Components",
UF_LUA_REGISTER_ENUM(Metadata),
UF_LUA_REGISTER_ENUM(Transform),
UF_LUA_REGISTER_ENUM(Audio),
UF_LUA_REGISTER_ENUM(Asset),
UF_LUA_REGISTER_ENUM(Camera),
UF_LUA_REGISTER_ENUM(Physics),
UF_LUA_REGISTER_ENUM(PhysicsState)
);
});
});
}
uf::stl::string formatHookName(uf::Object& self, const uf::stl::string n ){
return self.formatHookName(n);
}
sol::object getComponent( uf::Object& self, const uf::stl::string& type ) {
#define UF_LUA_RETRIEVE_COMPONENT( T )\
sol::object getComponentFromEnum( uf::Object& self, binds::enums::Components type ) {
#define UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( E, T )\
case enums::Components::E: return sol::make_object( ext::lua::state, std::ref(self.getComponent<T>()) );
switch ( type ) {
case enums::Components::Metadata: {
self.callHook( "object:Serialize.%UID%" );
auto& metadata = self.getComponent<uf::Serializer>();
auto decoded = ext::lua::decode( metadata );
if ( decoded ) {
sol::table table = decoded.value();
return sol::make_object( ext::lua::state, table );
}
UF_MSG_ERROR("Failed to deserialize metadata for {}: {}", self.getName(), self.getUid());
} break;
UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( Transform, pod::Transform<> );
UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( Audio, uf::Audio );
UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( Asset, uf::Asset );
UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( Camera, uf::Camera );
UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( Physics, pod::Physics );
UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( PhysicsState, pod::PhysicsState );
}
UF_MSG_ERROR("Invalid component of {} requested for {}: {}", type, self.getName(), self.getUid());
return sol::make_object( ext::lua::state, sol::lua_nil );
}
sol::object getComponentFromString( uf::Object& self, const uf::stl::string& type ) {
#define UF_LUA_RETRIEVE_COMPONENT_FROM_STRING( T )\
else if ( type == UF_NS_GET_LAST(T) ) return sol::make_object( ext::lua::state, std::ref(self.getComponent<T>()) );
if ( type == "Metadata" ) {
@ -24,13 +77,15 @@ namespace binds {
sol::table table = decoded.value();
return sol::make_object( ext::lua::state, table );
}
UF_MSG_ERROR("Failed to deserialize metadata for {}: {}", self.getName(), self.getUid());
}
UF_LUA_RETRIEVE_COMPONENT(pod::Transform<>)
UF_LUA_RETRIEVE_COMPONENT(uf::Audio)
UF_LUA_RETRIEVE_COMPONENT(uf::Asset)
UF_LUA_RETRIEVE_COMPONENT(uf::Camera)
UF_LUA_RETRIEVE_COMPONENT(pod::Physics)
UF_LUA_RETRIEVE_COMPONENT(pod::PhysicsState)
UF_LUA_RETRIEVE_COMPONENT_FROM_STRING(pod::Transform<>)
UF_LUA_RETRIEVE_COMPONENT_FROM_STRING(uf::Audio)
UF_LUA_RETRIEVE_COMPONENT_FROM_STRING(uf::Asset)
UF_LUA_RETRIEVE_COMPONENT_FROM_STRING(uf::Camera)
UF_LUA_RETRIEVE_COMPONENT_FROM_STRING(pod::Physics)
UF_LUA_RETRIEVE_COMPONENT_FROM_STRING(pod::PhysicsState)
UF_MSG_ERROR("Invalid component of {} requested for {}: {}", type, self.getName(), self.getUid());
return sol::make_object( ext::lua::state, sol::lua_nil );
}
void setComponent(uf::Object& self, const uf::stl::string& type, sol::object value ) {
@ -147,6 +202,10 @@ namespace binds {
ext::json::Value payload = uf::Serializer(table);
self.callHook( name, payload );
}
void lazyCallHook( uf::Object& self, const uf::stl::string& name, sol::table table = ext::lua::createTable() ) {
ext::json::Value payload = uf::Serializer(table);
self.lazyCallHook( name, payload );
}
void queueHook( uf::Object& self, const uf::stl::string& name, sol::table table, float delay = 0.0f ) {
ext::json::Value payload = uf::Serializer(table);
self.queueHook( name, payload, delay );
@ -159,6 +218,7 @@ namespace binds {
uf::stl::string getName( const uf::Object& o ) { return o.getName(); }
}
UF_LUA_REGISTER_USERTYPE(uf::Object,
sol::call_constructor, sol::initializers(
[]( uf::Object& self, sol::object arg, bool init = true ){
@ -177,7 +237,8 @@ UF_LUA_REGISTER_USERTYPE(uf::Object,
UF_LUA_REGISTER_USERTYPE_DEFINE( uid, UF_LUA_C_FUN(::binds::getUid) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( name, UF_LUA_C_FUN(::binds::getName) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( formatHookName, UF_LUA_C_FUN(::binds::formatHookName) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, UF_LUA_C_FUN(::binds::getComponent) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, UF_LUA_C_FUN(::binds::getComponentFromEnum) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, UF_LUA_C_FUN(::binds::getComponentFromString) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( setComponent, UF_LUA_C_FUN(::binds::setComponent) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( bind, UF_LUA_C_FUN(::binds::bind) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( findByUid, UF_LUA_C_FUN(::binds::findByUid) ),
@ -189,46 +250,8 @@ UF_LUA_REGISTER_USERTYPE(uf::Object,
UF_LUA_REGISTER_USERTYPE_DEFINE( getParent, UF_LUA_C_FUN(::binds::getParent) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( addHook, UF_LUA_C_FUN(::binds::addHook) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( callHook, UF_LUA_C_FUN(::binds::callHook) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( lazyCallHook, UF_LUA_C_FUN(::binds::lazyCallHook) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( queueHook, UF_LUA_C_FUN(::binds::queueHook) ),
UF_LUA_REGISTER_USERTYPE_DEFINE( __tostring, UF_LUA_C_FUN(::binds::toString) )
)
/*
namespace {
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{
ext::lua::onInitialization( []{
ext::lua::state.new_usertype<uf::Object>(UF_NS_GET_LAST(uf::Object),
sol::call_constructor, sol::initializers( []( uf::Object& self, sol::object arg, bool init = true ){
if ( arg.is<uf::stl::string>() ) {
self.load( arg.as<uf::stl::string>() );
} else if ( arg.is<sol::table>() ) {
auto encoded = ext::lua::encode( arg.as<sol::table>() );
if ( encoded ) {
uf::Serializer json = encoded.value();
self.load(json);
}
}
if ( init ) self.initialize();
}),
"uid", UF_LUA_C_FUN(::binds::getUid),
"name", UF_LUA_C_FUN(::binds::getName),
"formatHookName", UF_LUA_C_FUN(::binds::formatHookName),
"getComponent", UF_LUA_C_FUN(::binds::getComponent),
"setComponent", UF_LUA_C_FUN(::binds::setComponent),
"bind", UF_LUA_C_FUN(::binds::bind),
"findByUid", UF_LUA_C_FUN(::binds::findByUid),
"findByName", UF_LUA_C_FUN(::binds::findByName),
"addChild", UF_LUA_C_FUN(::binds::addChild),
"removeChild", UF_LUA_C_FUN(::binds::removeChild),
"loadChild", UF_LUA_C_FUN(::binds::loadChild),
"getChildren", UF_LUA_C_FUN(::binds::getChildren),
"getParent", UF_LUA_C_FUN(::binds::getParent),
"addHook", UF_LUA_C_FUN(::binds::addHook),
"callHook", UF_LUA_C_FUN(::binds::callHook),
"queueHook", UF_LUA_C_FUN(::binds::queueHook),
"__tostring", UF_LUA_C_FUN(::binds::toString)
);
});
});
}
*/
#endif

View File

@ -446,7 +446,7 @@ void ext::openvr::submit() { bool invert = swapEyes;
vulkanData.m_pDevice = ( VkDevice_T * ) uf::renderer::device;
vulkanData.m_pPhysicalDevice = ( VkPhysicalDevice_T * ) uf::renderer::device.physicalDevice;
vulkanData.m_pInstance = ( VkInstance_T *) uf::renderer::device.instance;
vulkanData.m_pQueue = ( VkQueue_T * ) uf::renderer::device.getQueue( uf::renderer::Device::QueueEnum::PRESENT );
vulkanData.m_pQueue = ( VkQueue_T * ) uf::renderer::device.getQueue( uf::renderer::QueueEnum::PRESENT );
vulkanData.m_nQueueFamilyIndex = uf::renderer::device.queueFamilyIndices.present;
vulkanData.m_nWidth = width;

View File

@ -129,10 +129,11 @@ void ext::vulkan::Buffer::initialize( const void* data, VkDeviceSize length, VkB
if ( !device ) device = &ext::vulkan::device;
if ( stage ) usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; // implicitly set properties
VK_CHECK_RESULT(device->createBuffer(
nullptr,
length,
usage,
memoryProperties,
*this,
length
*this
));
if ( data && length ) update( data, length, stage );
}
@ -157,26 +158,37 @@ bool ext::vulkan::Buffer::update( const void* data, VkDeviceSize length, bool st
return false;
}
Buffer staging;
ext::vulkan::Device* device = this->device ? this->device : &ext::vulkan::device;
#if 1
Buffer staging = device->fetchTransientBuffer(
data,
length,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);
VkCommandBuffer copyCommand = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::TRANSFER);
VkBufferCopy region = {};
region.size = length;
vkCmdCopyBuffer(copyCommand, staging.buffer, buffer, 1, &region);
device->flushCommandBuffer(copyCommand, QueueEnum::TRANSFER);
#else
Buffer staging;
device->createBuffer(
data,
length,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
staging,
length,
data
staging
);
// Copy to staging buffer
VkCommandBuffer copyCommand = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, Device::QueueEnum::TRANSFER);
VkBufferCopy region = {};
region.size = length;
vkCmdCopyBuffer(copyCommand, staging.buffer, buffer, 1, &region);
device->flushCommandBuffer(copyCommand, Device::QueueEnum::TRANSFER);
VkCommandBuffer copyCommand = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::TRANSFER);
VkBufferCopy region = {};
region.size = length;
vkCmdCopyBuffer(copyCommand, staging.buffer, buffer, 1, &region);
device->flushCommandBuffer(copyCommand, QueueEnum::TRANSFER);
staging.destroy();
#endif
return false;
}

View File

@ -555,9 +555,6 @@ uint32_t ext::vulkan::Device::getMemoryType( uint32_t typeBits, VkMemoryProperty
UF_EXCEPTION("Vulkan error: could not find a matching memory type");
}
VkCommandBuffer ext::vulkan::Device::createCommandBuffer( VkCommandBufferLevel level, bool begin ){
return createCommandBuffer( level, QueueEnum::TRANSFER, begin );
}
VkCommandBuffer ext::vulkan::Device::createCommandBuffer( VkCommandBufferLevel level, QueueEnum queue, bool begin ){
VkCommandBufferAllocateInfo cmdBufAllocateInfo = ext::vulkan::initializers::commandBufferAllocateInfo( getCommandPool(queue), level, 1 );
@ -570,11 +567,7 @@ VkCommandBuffer ext::vulkan::Device::createCommandBuffer( VkCommandBufferLevel l
}
return commandBuffer;
}
void ext::vulkan::Device::flushCommandBuffer( VkCommandBuffer commandBuffer, bool wait ) {
return flushCommandBuffer( commandBuffer, QueueEnum::TRANSFER, wait );
}
void ext::vulkan::Device::flushCommandBuffer( VkCommandBuffer commandBuffer, QueueEnum queueType, bool wait ) {
void ext::vulkan::Device::flushCommandBuffer( VkCommandBuffer commandBuffer, QueueEnum queueType, bool immediate ) {
if ( commandBuffer == VK_NULL_HANDLE ) return;
VK_CHECK_RESULT( vkEndCommandBuffer( commandBuffer ) );
@ -585,56 +578,54 @@ void ext::vulkan::Device::flushCommandBuffer( VkCommandBuffer commandBuffer, Que
auto& queue = getQueue( queueType );
VK_CHECK_RESULT(vkQueueSubmit( queue, 1, &submitInfo, VK_NULL_HANDLE));
if ( wait ) {
if ( immediate ) {
VK_CHECK_RESULT(vkQueueWaitIdle( queue ));
vkFreeCommandBuffers(logicalDevice, getCommandPool( queueType ), 1, &commandBuffer);
} else {
this->transient.commandBuffers[queueType].emplace_back(commandBuffer);
}
}
ext::vulkan::CommandBuffer ext::vulkan::Device::fetchCommandBuffer( ext::vulkan::QueueEnum queueType, bool immediate ){
return {
.immediate = immediate,
.queueType = queueType,
.handle = this->createCommandBuffer( VK_COMMAND_BUFFER_LEVEL_PRIMARY, queueType, true ),
};
#if 0
VkResult ext::vulkan::Device::createBuffer( VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryProperties, VkDeviceSize size, VkBuffer* buffer, VkDeviceMemory* memory, const void* data ) {
// Create the buffer handle
VkBufferCreateInfo bufferCreateInfo = ext::vulkan::initializers::bufferCreateInfo(usage, size);
bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VK_CHECK_RESULT( vkCreateBuffer(logicalDevice, &bufferCreateInfo, nullptr, buffer));
// Create the memory backing up the buffer handle
VkMemoryRequirements memReqs;
VkMemoryAllocateInfo memAlloc = ext::vulkan::initializers::memoryAllocateInfo();
vkGetBufferMemoryRequirements(logicalDevice, *buffer, &memReqs);
memAlloc.allocationSize = memReqs.size;
// Find a memory type index that fits the properties of the buffer
memAlloc.memoryTypeIndex = getMemoryType(memReqs.memoryTypeBits, memoryProperties);
VK_CHECK_RESULT( vkAllocateMemory(logicalDevice, &memAlloc, nullptr, memory));
// If a pointer to the buffer data has been passed, map the buffer and copy over the data
if ( data != nullptr ) {
void *mapped;
VK_CHECK_RESULT(vkMapMemory(logicalDevice, *memory, 0, size, 0, &mapped));
memcpy(mapped, data, size);
// If host coherency hasn't been requested, do a manual flush to make writes visible
if ( (memoryProperties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0 ) {
VkMappedMemoryRange mappedRange = ext::vulkan::initializers::mappedMemoryRange();
mappedRange.memory = *memory;
mappedRange.offset = 0;
mappedRange.size = size;
vkFlushMappedMemoryRanges(logicalDevice, 1, &mappedRange);
}
vkUnmapMemory(logicalDevice, *memory);
if ( transient ) {
ext::vulkan::CommandBuffer commandBuffer;
commandBuffer.waits = waits;
commandBuffer.queueType = queueType;
commandBuffer.handle = this->createCommandBuffer( VK_COMMAND_BUFFER_LEVEL_PRIMARY, queueType, true );
return;
}
// Attach the memory to the buffer object
VK_CHECK_RESULT(vkBindBufferMemory(logicalDevice, *buffer, *memory, 0));
return VK_SUCCESS;
}
// bool exists = this->reusable.commandBuffers.count( queueType ) > 0;
auto& commandBuffer = this->reusable.commandBuffers[queueType];
// if ( !exists ) {
if ( commandBuffer.handle == VK_NULL_HANDLE ) {
commandBuffer.state = 1;
commandBuffer.handle = this->createCommandBuffer( VK_COMMAND_BUFFER_LEVEL_PRIMARY, queueType, true );
return commandBuffer;
}
if ( commandBuffer.state == 0 ) {
commandBuffer.state = 1;
VkCommandBufferBeginInfo cmdBufInfo = ext::vulkan::initializers::commandBufferBeginInfo();
VK_CHECK_RESULT( vkBeginCommandBuffer( commandBuffer.handle, &cmdBufInfo ) );
}
return commandBuffer;
#endif
}
void ext::vulkan::Device::flushCommandBuffer( ext::vulkan::CommandBuffer commandBuffer ) {
return this->flushCommandBuffer( commandBuffer.handle, commandBuffer.queueType, commandBuffer.immediate );
}
VkResult ext::vulkan::Device::createBuffer(
const void* data,
VkDeviceSize size,
VkBufferUsageFlags usage,
VkMemoryPropertyFlags memoryProperties,
ext::vulkan::Buffer& buffer,
VkDeviceSize size,
const void* data
ext::vulkan::Buffer& buffer
) {
buffer.device = this;
buffer.usage = usage;
@ -657,13 +648,23 @@ VkResult ext::vulkan::Device::createBuffer(
// Attach the memory to the buffer object
return buffer.bind();
}
VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::Device::QueueEnum queueEnum) {
ext::vulkan::Buffer ext::vulkan::Device::fetchTransientBuffer(
const void* data,
VkDeviceSize size,
VkBufferUsageFlags usage,
VkMemoryPropertyFlags memoryProperties
) {
auto& buffer = this->transient.buffers.emplace_back();
VK_CHECK_RESULT(this->createBuffer(data, size, usage, memoryProperties, buffer));
return buffer.alias();
}
VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::QueueEnum queueEnum) {
return this->getCommandPool( queueEnum, std::this_thread::get_id() );
}
VkQueue& ext::vulkan::Device::getQueue( ext::vulkan::Device::QueueEnum queueEnum ) {
VkQueue& ext::vulkan::Device::getQueue( ext::vulkan::QueueEnum queueEnum ) {
return this->getQueue( queueEnum, std::this_thread::get_id() );
}
VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::Device::QueueEnum queueEnum, std::thread::id id ) {
VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::QueueEnum queueEnum, std::thread::id id ) {
uint32_t index = 0;
VkCommandPool* pool = NULL;
bool exists = false;
@ -701,7 +702,7 @@ VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::Device::QueueEn
}
return *pool;
}
VkQueue& ext::vulkan::Device::getQueue( ext::vulkan::Device::QueueEnum queueEnum, std::thread::id id ) {
VkQueue& ext::vulkan::Device::getQueue( ext::vulkan::QueueEnum queueEnum, std::thread::id id ) {
uint32_t index = 0;
VkQueue* queue = NULL;
bool exists = false;

View File

@ -1357,7 +1357,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
scratchBuffer.alignment = acclerationStructureProperties.minAccelerationStructureScratchOffsetAlignment;
scratchBuffer.update( NULL, maxScratchBufferSize );
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::QueueEnum::COMPUTE);
for ( auto& blasData : blasDatas ) {
blasData.as.buffer = this->buffers[blasBufferIndex].alias();
blasData.as.buffer.descriptor.offset = blasBufferOffset;
@ -1402,7 +1402,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
queryCount++
);
}
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
device.flushCommandBuffer(commandBuffer, uf::renderer::QueueEnum::COMPUTE);
}
// compact
if ( queryPool ) {
@ -1426,7 +1426,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
this->buffers[blasBufferIndex].swap(oldBuffer);
size_t blasBufferOffset{};
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::QueueEnum::COMPUTE);
for ( auto& blasData : blasDatas ) {
blasData.as.buffer = this->buffers[blasBufferIndex].alias();
blasData.as.buffer.descriptor.offset = blasBufferOffset;
@ -1452,7 +1452,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() {
uf::renderer::vkCmdCopyAccelerationStructureKHR(commandBuffer, &copyInfo);
}
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
device.flushCommandBuffer(commandBuffer, uf::renderer::QueueEnum::COMPUTE);
oldBuffer.destroy();
}
@ -1644,7 +1644,7 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
VkAccelerationStructureBuildRangeInfoKHR buildOffsetInfo{countInstance, 0, 0, 0};
const VkAccelerationStructureBuildRangeInfoKHR* rangeInfo = &buildOffsetInfo;
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::QueueEnum::COMPUTE);
uf::renderer::vkCmdBuildAccelerationStructuresKHR(
commandBuffer,
1,
@ -1661,7 +1661,7 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
0
);
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
device.flushCommandBuffer(commandBuffer, uf::renderer::QueueEnum::COMPUTE);
}
#if TLAS_FRONT_AND_BACK
@ -1671,9 +1671,9 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
copyInfo.dst = tlasBack.handle;
copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR;
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::QueueEnum::COMPUTE);
uf::renderer::vkCmdCopyAccelerationStructureKHR(commandBuffer, &copyInfo);
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
device.flushCommandBuffer(commandBuffer, uf::renderer::QueueEnum::COMPUTE);
}
#endif
@ -1711,9 +1711,9 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect
copyInfo.dst = tlas.handle;
copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR;
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE);
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::QueueEnum::COMPUTE);
uf::renderer::vkCmdCopyAccelerationStructureKHR(commandBuffer, &copyInfo);
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE);
device.flushCommandBuffer(commandBuffer, uf::renderer::QueueEnum::COMPUTE);
uf::renderer::vkDestroyAccelerationStructureKHR(device, cleanup.handle, nullptr);
oldBuffer.destroy();

View File

@ -77,7 +77,7 @@ uf::Image ext::vulkan::RenderMode::screenshot( size_t attachmentID, size_t layer
VK_CHECK_RESULT(vmaCreateImage(allocator, &imageCreateInfo, &allocationCreateInfo, &temporary, &allocation, &allocationInfo));
VkDeviceMemory temporaryMemory = allocationInfo.deviceMemory;
VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, Device::QueueEnum::GRAPHICS);
VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::GRAPHICS);
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
@ -162,7 +162,7 @@ uf::Image ext::vulkan::RenderMode::screenshot( size_t attachmentID, size_t layer
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
imageMemoryBarrier.newLayout = attachment.descriptor.layout;
vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
device->flushCommandBuffer(copyCmd, Device::QueueEnum::GRAPHICS);
device->flushCommandBuffer(copyCmd, QueueEnum::GRAPHICS);
const uint8_t* data;
vmaMapMemory( allocator, allocation, (void**)&data );
@ -220,7 +220,7 @@ ext::vulkan::RenderMode::commands_container_t& ext::vulkan::RenderMode::getComma
commands.resize( swapchain.buffers );
VkCommandBufferAllocateInfo cmdBufAllocateInfo = ext::vulkan::initializers::commandBufferAllocateInfo(
device->getCommandPool(this->getType() == "Compute" ? Device::QueueEnum::COMPUTE : Device::QueueEnum::GRAPHICS),
device->getCommandPool(this->getType() == "Compute" ? QueueEnum::COMPUTE : QueueEnum::GRAPHICS),
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
static_cast<uint32_t>(commands.size())
);
@ -245,7 +245,7 @@ void ext::vulkan::RenderMode::cleanupAllCommands() {
auto& container = this->commands.container();
for ( auto& pair : container ) {
if ( pair.second.empty() ) continue;
vkFreeCommandBuffers( *device, device->getCommandPool(this->getType() == "Compute" ? Device::QueueEnum::COMPUTE : Device::QueueEnum::GRAPHICS, pair.first), static_cast<uint32_t>(pair.second.size()), pair.second.data());
vkFreeCommandBuffers( *device, device->getCommandPool(this->getType() == "Compute" ? QueueEnum::COMPUTE : QueueEnum::GRAPHICS, pair.first), static_cast<uint32_t>(pair.second.size()), pair.second.data());
pair.second.clear();
}
container.clear();
@ -255,7 +255,7 @@ void ext::vulkan::RenderMode::cleanupCommands( std::thread::id id ) {
for ( auto& pair : container ) {
if ( pair.first == id ) continue;
if ( pair.second.empty() ) continue;
vkFreeCommandBuffers( *device, device->getCommandPool(this->getType() == "Compute" ? Device::QueueEnum::COMPUTE : Device::QueueEnum::GRAPHICS, pair.first), static_cast<uint32_t>(pair.second.size()), pair.second.data());
vkFreeCommandBuffers( *device, device->getCommandPool(this->getType() == "Compute" ? QueueEnum::COMPUTE : QueueEnum::GRAPHICS, pair.first), static_cast<uint32_t>(pair.second.size()), pair.second.data());
pair.second.clear();
}
this->commands.cleanup( id );
@ -379,7 +379,7 @@ void ext::vulkan::RenderMode::destroy() {
for ( auto& pair : this->commands.container() ) {
if ( !pair.second.empty() ) {
vkFreeCommandBuffers( *device, device->getCommandPool(this->getType() == "Compute" ? Device::QueueEnum::COMPUTE : Device::QueueEnum::GRAPHICS, pair.first), static_cast<uint32_t>(pair.second.size()), pair.second.data());
vkFreeCommandBuffers( *device, device->getCommandPool(this->getType() == "Compute" ? QueueEnum::COMPUTE : QueueEnum::GRAPHICS, pair.first), static_cast<uint32_t>(pair.second.size()), pair.second.data());
}
pair.second.clear();
}

View File

@ -240,14 +240,14 @@ void ext::vulkan::BaseRenderMode::render() {
submitInfo.commandBufferCount = 1;
// Submit to the graphics queue passing a wait fence
VK_CHECK_RESULT(vkQueueSubmit( device->getQueue( Device::QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
VK_CHECK_RESULT(vkQueueSubmit( device->getQueue( QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
//vkQueueSubmit(device->queues.graphics, 1, &submitInfo, fences[states::currentBuffer]);
// Present the current buffer to the swap chain
// Pass the semaphore signaled by the command buffer submission from the submit info as the wait semaphore for swap chain presentation
// This ensures that the image is not presented to the windowing system until all commands have been submitted
VK_CHECK_RESULT(swapchain.queuePresent(device->getQueue( Device::QueueEnum::PRESENT ), states::currentBuffer, renderCompleteSemaphore));
VK_CHECK_RESULT(vkQueueWaitIdle(device->getQueue( Device::QueueEnum::PRESENT )));
VK_CHECK_RESULT(swapchain.queuePresent(device->getQueue( QueueEnum::PRESENT ), states::currentBuffer, renderCompleteSemaphore));
VK_CHECK_RESULT(vkQueueWaitIdle(device->getQueue( QueueEnum::PRESENT )));
this->executed = true;
@ -474,7 +474,7 @@ void ext::vulkan::BaseRenderMode::initialize( Device& device ) {
}
#if 0
if ( true ) {
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::TRANSFER);
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::QueueEnum::TRANSFER);
for ( size_t i = 0; i < images.size(); ++i ) {
VkImageMemoryBarrier imageMemoryBarrier = {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@ -496,7 +496,7 @@ void ext::vulkan::BaseRenderMode::initialize( Device& device ) {
vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier);
}
device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::TRANSFER);
device.flushCommandBuffer(commandBuffer, uf::renderer::QueueEnum::TRANSFER);
}
#endif
/*

View File

@ -210,7 +210,7 @@ void ext::vulkan::ComputeRenderMode::render() {
submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission)
submitInfo.commandBufferCount = 1;
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( uf::renderer::Device::QueueEnum::COMPUTE ), 1, &submitInfo, fences[states::currentBuffer]));
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( uf::renderer::QueueEnum::COMPUTE ), 1, &submitInfo, fences[states::currentBuffer]));
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{} );

View File

@ -522,7 +522,7 @@ void ext::vulkan::DeferredRenderMode::render() {
submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission)
submitInfo.commandBufferCount = 1;
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( Device::QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{} );

View File

@ -353,6 +353,15 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
}
}
} else if ( metadata.type != uf::renderer::settings::pipelines::names::rt ) {
/*
auto previousTextures = std::move(blitter.material.textures);
blitter.material.textures.clear();
auto& shader = blitter.material.getShader("fragment");
for ( auto& prevTex : previousTextures ) {
shader.textures.emplace_back(prevTex);
}
*/
for ( auto& attachment : renderTarget.attachments ) {
if ( !(attachment.descriptor.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue;
@ -458,7 +467,7 @@ void ext::vulkan::RenderTargetRenderMode::render() {
submitInfo.pCommandBuffers = &commands[states::currentBuffer]; // Command buffers(s) to execute in this batch (submission)
submitInfo.commandBufferCount = 1;
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( Device::QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{} );

View File

@ -528,7 +528,7 @@ void ext::vulkan::Texture::fromBuffers(
subresourceRange.levelCount = this->mips;
subresourceRange.layerCount = this->layers;
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, Device::QueueEnum::GRAPHICS);
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::GRAPHICS);
setImageLayout(
commandBuffer,
image,
@ -536,7 +536,7 @@ void ext::vulkan::Texture::fromBuffers(
imageLayout,
subresourceRange
);
device.flushCommandBuffer(commandBuffer, Device::QueueEnum::GRAPHICS);
device.flushCommandBuffer(commandBuffer, QueueEnum::GRAPHICS);
this->imageLayout = imageLayout;
}
@ -575,7 +575,7 @@ void ext::vulkan::Texture::asRenderTarget( Device& device, uint32_t width, uint3
VK_CHECK_RESULT(vmaCreateImage(allocator, &imageCreateInfo, &allocInfo, &image, &allocation, &allocationInfo));
deviceMemory = allocationInfo.deviceMemory;
VkCommandBuffer layoutCmd = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, Device::QueueEnum::GRAPHICS);
VkCommandBuffer layoutCmd = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::GRAPHICS);
imageLayout = VK_IMAGE_LAYOUT_GENERAL;
setImageLayout(
@ -587,7 +587,7 @@ void ext::vulkan::Texture::asRenderTarget( Device& device, uint32_t width, uint3
this->mips
);
device.flushCommandBuffer(layoutCmd, Device::QueueEnum::GRAPHICS);
device.flushCommandBuffer(layoutCmd, QueueEnum::GRAPHICS);
// Create sampler
// sampler.initialize( device );
@ -702,17 +702,16 @@ void ext::vulkan::Texture::update( void* data, VkDeviceSize bufferSize, VkImageL
bufferCopyRegion.imageExtent.depth = depth;
bufferCopyRegion.bufferOffset = 0;
//
Buffer staging;
VK_CHECK_RESULT(device.createBuffer(
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
staging,
#if 1
Buffer staging = device.fetchTransientBuffer(
data,
bufferSize,
data
));
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);
// Use a separate command buffer for texture loading
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, Device::QueueEnum::GRAPHICS);
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::GRAPHICS);
// Image barrier for optimal image (target)
// Optimal image will be used as destination for the copy
@ -741,9 +740,51 @@ void ext::vulkan::Texture::update( void* data, VkDeviceSize bufferSize, VkImageL
subresourceRange
);
device.flushCommandBuffer(commandBuffer, Device::QueueEnum::GRAPHICS);
device.flushCommandBuffer(commandBuffer, QueueEnum::GRAPHICS);
#else
Buffer staging;
VK_CHECK_RESULT(device.createBuffer(
data,
bufferSize,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
staging
));
// Use a separate command buffer for texture loading
VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::GRAPHICS);
// Image barrier for optimal image (target)
// Optimal image will be used as destination for the copy
setImageLayout(
commandBuffer,
image,
imageLayout,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange
);
// Copy mip levels from staging buffer
vkCmdCopyBufferToImage(
commandBuffer,
staging.buffer,
image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&bufferCopyRegion
);
if ( this->mips > 1 ) this->generateMipmaps(commandBuffer, layer);
setImageLayout(
commandBuffer,
image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
targetImageLayout,
subresourceRange
);
device.flushCommandBuffer(commandBuffer, QueueEnum::GRAPHICS);
// Clean up staging resources
staging.destroy();
#endif
this->imageLayout = targetImageLayout;
@ -867,7 +908,7 @@ uf::Image ext::vulkan::Texture2D::screenshot( uint32_t layerID ) {
VK_CHECK_RESULT(vmaCreateImage(allocator, &imageCreateInfo, &allocationCreateInfo, &temporary, &allocation, &allocationInfo));
VkDeviceMemory temporaryMemory = allocationInfo.deviceMemory;
VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, Device::QueueEnum::GRAPHICS);
VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::GRAPHICS);
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
@ -934,7 +975,7 @@ uf::Image ext::vulkan::Texture2D::screenshot( uint32_t layerID ) {
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
imageMemoryBarrier.newLayout = descriptor.imageLayout;
vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
device->flushCommandBuffer(copyCmd, Device::QueueEnum::GRAPHICS);
device->flushCommandBuffer(copyCmd, QueueEnum::GRAPHICS);
const uint8_t* data;
vmaMapMemory( allocator, allocation, (void**)&data );
@ -975,7 +1016,7 @@ uf::Image ext::vulkan::Texture3D::screenshot( uint32_t layerID ) {
VK_CHECK_RESULT(vmaCreateImage(allocator, &imageCreateInfo, &allocationCreateInfo, &temporary, &allocation, &allocationInfo));
VkDeviceMemory temporaryMemory = allocationInfo.deviceMemory;
VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, Device::QueueEnum::GRAPHICS);
VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, QueueEnum::GRAPHICS);
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
@ -1047,7 +1088,7 @@ uf::Image ext::vulkan::Texture3D::screenshot( uint32_t layerID ) {
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
imageMemoryBarrier.newLayout = descriptor.imageLayout;
vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
device->flushCommandBuffer(copyCmd, Device::QueueEnum::GRAPHICS);
device->flushCommandBuffer(copyCmd, QueueEnum::GRAPHICS);
const uint8_t* data;
vmaMapMemory( allocator, allocation, (void**)&data );

View File

@ -436,6 +436,45 @@ void ext::vulkan::tick() {
void ext::vulkan::render() {
ext::vulkan::mutex.lock();
// process in-flight resources
{
// cleanup in-flight commands
for ( auto& pair : device.transient.commandBuffers ) {
auto queueType = pair.first;
auto& commandBuffers = pair.second;
auto& queue = device.getQueue( queueType );
auto& commandPool = device.getCommandPool( queueType );
VK_CHECK_RESULT(vkQueueWaitIdle( queue ));
vkFreeCommandBuffers(device, commandPool, commandBuffers.size(), commandBuffers.data());
commandBuffers.clear();
}
// cleanup in-flight buffers
for ( auto& buffer : device.transient.buffers ) {
buffer.destroy();
}
device.transient.buffers.clear();
}
#if 0
// process reusable commands
{
for ( auto& pair : device.reusable.commandBuffers ) {
auto queueType = pair.first;
auto& cb = pair.second;
auto& commandBuffer = cb.commandBuffer;
auto& queue = device.getQueue( queueType );
auto& commandPool = device.getCommandPool( queueType );
VK_CHECK_RESULT(vkQueueWaitIdle( queue ));
vkResetCommandBuffer(device, commandPool, 1, &commandBuffer);
cb.state = 0;
}
}
#endif
if ( settings::experimental::batchQueueSubmissions ) {
uf::stl::vector<RenderMode*> auxRenderModes; auxRenderModes.reserve( renderModes.size() );
uf::stl::vector<RenderMode*> specialRenderModes; specialRenderModes.reserve( renderModes.size() );
@ -476,12 +515,12 @@ void ext::vulkan::render() {
if ( !submitsCompute.empty() ) {
VK_CHECK_RESULT(vkWaitForFences(device, 1, &::auxFencesCompute[states::currentBuffer], VK_TRUE, VK_DEFAULT_FENCE_TIMEOUT));
VK_CHECK_RESULT(vkResetFences(device, 1, &::auxFencesCompute[states::currentBuffer]));
VK_CHECK_RESULT(vkQueueSubmit(device.getQueue( Device::QueueEnum::COMPUTE ), submitsCompute.size(), submitsCompute.data(), ::auxFencesCompute[states::currentBuffer]));
VK_CHECK_RESULT(vkQueueSubmit(device.getQueue( QueueEnum::COMPUTE ), submitsCompute.size(), submitsCompute.data(), ::auxFencesCompute[states::currentBuffer]));
}
if ( !submitsGraphics.empty() ) {
VK_CHECK_RESULT(vkWaitForFences(device, 1, &::auxFencesGraphics[states::currentBuffer], VK_TRUE, VK_DEFAULT_FENCE_TIMEOUT));
VK_CHECK_RESULT(vkResetFences(device, 1, &::auxFencesGraphics[states::currentBuffer]));
VK_CHECK_RESULT(vkQueueSubmit(device.getQueue( Device::QueueEnum::GRAPHICS ), submitsGraphics.size(), submitsGraphics.data(), ::auxFencesGraphics[states::currentBuffer]));
VK_CHECK_RESULT(vkQueueSubmit(device.getQueue( QueueEnum::GRAPHICS ), submitsGraphics.size(), submitsGraphics.data(), ::auxFencesGraphics[states::currentBuffer]));
}
}
// stuff we can't batch

View File

@ -102,6 +102,7 @@ uf::inputs::state_t uf::inputs::kbm::states::Num8 = false;
uf::inputs::state_t uf::inputs::kbm::states::Num9 = false;
uf::inputs::state_t uf::inputs::kbm::states::Num0 = false;
uf::inputs::analog2_t uf::inputs::kbm::states::Mouse = {};
uf::inputs::state_t uf::inputs::kbm::states::Mouse1 = false;
uf::inputs::state_t uf::inputs::kbm::states::Mouse2 = false;
uf::inputs::state_t uf::inputs::kbm::states::Mouse3 = false;
@ -280,7 +281,8 @@ uf::inputs::analog_t uf::inputs::analog( const uf::stl::string& key ) {
return 0.0;
}
uf::inputs::analog2_t uf::inputs::analog2( const uf::stl::string& key ) {
if ( key == uf::inputs::controller::enums::L_JOYSTICK ) return uf::inputs::controller::states::L_JOYSTICK;
if ( key == uf::inputs::kbm::enums::Mouse ) return uf::inputs::kbm::states::Mouse;
else if ( key == uf::inputs::controller::enums::L_JOYSTICK ) return uf::inputs::controller::states::L_JOYSTICK;
else if ( key == uf::inputs::controller::enums::R_JOYSTICK ) return uf::inputs::controller::states::R_JOYSTICK;
return {};

View File

@ -56,7 +56,7 @@ void ext::LightBehavior::initialize( uf::Object& self ) {
#if UF_USE_OPENGL
metadataJson["light"]["shadows"] = false;
#endif
if ( !sceneMetadata["system"]["config"]["engine"]["scenes"]["shadows"]["enabled"].as<bool>(true) )
if ( !sceneMetadata["light"]["shadows"]["enabled"].as<bool>(true) )
metadataJson["light"]["shadows"] = false;
if ( metadataJson["light"]["shadows"].as<bool>() ) {
auto& cameraTransform = camera.getTransform();
@ -259,18 +259,21 @@ void ext::LightBehavior::Metadata::serialize( uf::Object& self, uf::Serializer&
}
void ext::LightBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ){
/*this->*/color = uf::vector::decode( serializer["light"]["color"], /*this->*/color );
/*this->*/power = serializer["light"]["power"].as<float>(/*this->*/power);
/*this->*/bias = serializer["light"]["bias"]["shader"].as<float>(/*this->*/bias);
/*this->*/shadows = serializer["light"]["shadows"].as<bool>(/*this->*/shadows);
/*this->*/global = serializer["light"]["global"].as<bool>(/*this->*/global);
/*this->*/renderer.mode = serializer["system"]["renderer"]["mode"].as<uf::stl::string>(/*this->*/renderer.mode);
/*this->*/power = serializer["light"]["power"].as(/*this->*/power);
/*this->*/bias = serializer["light"]["bias"]["shader"].as(/*this->*/bias);
/*this->*/shadows = serializer["light"]["shadows"].as(/*this->*/shadows);
/*this->*/global = serializer["light"]["global"].as(/*this->*/global);
/*this->*/renderer.mode = serializer["system"]["renderer"]["mode"].as(/*this->*/renderer.mode);
// /*this->*/renderer.rendered = false;
/*this->*/renderer.external = serializer["light"]["external update"].as<bool>(/*this->*/renderer.external);
/*this->*/renderer.external = serializer["light"]["external update"].as(/*this->*/renderer.external);
// /*this->*/renderer.limiter = serializer["system"]["renderer"]["timer"].as<float>(/*this->*/renderer.limiter);
if ( serializer["light"]["type"].is<size_t>() ) {
/*this->*/type = serializer["light"]["type"].as<size_t>(/*this->*/type);
/*this->*/type = serializer["light"]["type"].as(/*this->*/type);
if ( serializer["light"]["dynamic"].as<bool>() ) /*this->*/type = -/*this->*/type;
} else if ( serializer["light"]["type"].is<uf::stl::string>() ) {
uf::stl::string lightType = serializer["light"]["type"].as<uf::stl::string>();
if ( lightType == "point" ) /*this->*/type = 1;
else if ( lightType == "spot" ) /*this->*/type = 2;

View File

@ -81,16 +81,18 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
});
// Rotate Camera
#if !UF_INPUT_USE_ENUM_MOUSE
this->addHook( "window:Mouse.Moved", [&](pod::payloads::windowMouseMoved& payload ){
const pod::Vector2ui deadZone{0, 0};
if ( (payload.mouse.delta.x == 0 && payload.mouse.delta.y == 0) || !metadata.system.control ) return;
pod::Vector2f delta = {
(float) metadata.mouse.sensitivity.x * (abs(payload.mouse.delta.x) < deadZone.x ? 0 : payload.mouse.delta.x) / payload.window.size.x,
(float) metadata.mouse.sensitivity.y * (abs(payload.mouse.delta.y) < deadZone.y ? 0 : payload.mouse.delta.y) / payload.window.size.y
};
metadata.camera.queued += delta;
});
#endif
#if UF_USE_DISCORD
// Discord Integration
@ -232,13 +234,13 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
payload["user"] = this->getUid();
payload["uid"] = pointer->getUid();
payload["depth"] = uf::vector::norm(direction * depth);
pointer->callHook( "entity:Use.%UID%", payload );
pointer->lazyCallHook( "entity:Use.%UID%", payload );
} else {
payload["user"] = this->getUid();
payload["uid"] = 0;
payload["depth"] = -1;
}
this->callHook( "entity:Use.%UID%", payload );
this->lazyCallHook( "entity:Use.%UID%", payload );
/*
auto& emitter = this->getComponent<uf::MappedSoundEmitter>();
uf::stl::string filename = pointer ? "./ui/select.ogg" : "./ui/deny.ogg";
@ -384,6 +386,22 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
metadata.system.crouching = false;
}
//
#if UF_INPUT_USE_ENUM_MOUSE
{
const pod::Vector2ui deadZone{0, 0};
const auto& mouseDelta = uf::inputs::kbm::states::Mouse;
bool shouldnt = (mouseDelta.x == 0 && mouseDelta.y == 0) || !metadata.system.control;
if ( !shouldnt ) {
pod::Vector2f delta = {
(float) metadata.mouse.sensitivity.x * (abs(mouseDelta.x) < deadZone.x ? 0 : mouseDelta.x),
(float) metadata.mouse.sensitivity.y * (abs(mouseDelta.y) < deadZone.y ? 0 : mouseDelta.y)
};
metadata.camera.queued += delta;
}
}
#endif
if ( metadata.camera.queued.x != 0 || metadata.camera.queued.y != 0 ) {
auto lookDelta = metadata.camera.queued;
if ( abs(lookDelta.x) > uf::physics::time::delta / metadata.mouse.smoothing.x ) lookDelta.x *= uf::physics::time::delta * metadata.mouse.smoothing.x;

View File

@ -67,8 +67,8 @@ void ext::PlayerModelBehavior::Metadata::serialize( uf::Object& self, uf::Serial
void ext::PlayerModelBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ){
auto& transform = this->getComponent<pod::Transform<>>();
/*this->*/track = serializer["track"].as<bool>();
/*this->*/hide = serializer["hide"].as<bool>();
/*this->*/track = serializer["track"].as(/*this->*/track);
/*this->*/hide = serializer["hide"].as(/*this->*/hide);
/*this->*/scale = transform.scale;
/*this->*/set = false;

View File

@ -16,6 +16,10 @@
#include "../light/behavior.h"
#include "../scene/behavior.h"
namespace {
uf::renderer::Texture emptyTexture;
}
UF_BEHAVIOR_REGISTER_CPP(ext::RayTraceSceneBehavior)
UF_BEHAVIOR_TRAITS_CPP(ext::RayTraceSceneBehavior, ticks = true, renders = false, multithread = true)
#define this (&self)
@ -40,6 +44,20 @@ void ext::RayTraceSceneBehavior::initialize( uf::Object& self ) {
uf::renderer::addRenderMode( renderMode, "Compute" );
}
{
uf::stl::vector<uint8_t> pixels = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
::emptyTexture.sampler.descriptor.filter.min = VK_FILTER_NEAREST;
::emptyTexture.sampler.descriptor.filter.mag = VK_FILTER_NEAREST;
::emptyTexture.fromBuffers( (void*) &pixels[0], pixels.size(), ext::vulkan::enums::Format::R8G8B8A8_UNORM, 2, 2, ext::vulkan::device, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_IMAGE_LAYOUT_GENERAL );
auto& renderMode = uf::renderer::getRenderMode("Compute", true);
auto& blitter = *renderMode.getBlitter();
blitter.material.textures.emplace_back().aliasTexture( ::emptyTexture );
}
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
}
void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
@ -51,12 +69,14 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
static uf::stl::vector<uf::Graphic*> previousGraphics;
uf::stl::vector<uf::Graphic*> graphics;
this->process([&]( uf::Entity* entity ) {
if ( !entity->hasComponent<uf::Graphic>() ) return;
auto& scene = uf::scene::getCurrentScene();
auto& graph = scene.getGraph();
for ( auto entity : graph ) {
if ( !entity->hasComponent<uf::Graphic>() ) continue;
auto& graphic = entity->getComponent<uf::Graphic>();
if ( graphic.accelerationStructures.bottoms.empty() ) return;
if ( graphic.accelerationStructures.bottoms.empty() ) continue;
graphics.emplace_back(&graphic);
});
}
if ( graphics.empty() ) return;
bool update = false;
@ -168,7 +188,8 @@ void ext::RayTraceSceneBehavior::tick( uf::Object& self ) {
auto& blitter = *renderMode.getBlitter();
if ( blitter.material.hasShader("fragment") ) {
auto& shader = blitter.material.getShader("fragment");
if ( shader.textures.empty() ) {
if ( shader.textures.empty() || ( !shader.textures.empty() && shader.textures.front().image == ::emptyTexture.image ) ) {
shader.textures.clear();
auto& tex = shader.textures.emplace_back();
tex.aliasTexture( image );

View File

@ -596,7 +596,6 @@ void ext::ExtSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serialize
serializer["light"]["should"] = /*this->*/light.enabled;
serializer["light"]["ambient"] = uf::vector::encode( /*this->*/light.ambient );
serializer["light"]["specular"] = uf::vector::encode( /*this->*/light.specular );
serializer["light"]["exposure"] = /*this->*/light.exposure;
serializer["light"]["gamma"] = /*this->*/light.gamma;
serializer["light"]["brightnessThreshold"] = /*this->*/light.brightnessThreshold;
@ -618,49 +617,84 @@ void ext::ExtSceneBehavior::Metadata::serialize( uf::Object& self, uf::Serialize
serializer["system"]["renderer"]["shader"]["parameters"] = uf::vector::encode( /*this->*/shader.parameters );
}
void ext::ExtSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ) {
/*this->*/max.textures2D = ext::config["engine"]["scenes"]["textures"]["max"]["2D"].as<uint32_t>(/*this->*/max.textures2D);
/*this->*/max.texturesCube = ext::config["engine"]["scenes"]["textures"]["max"]["cube"].as<uint32_t>(/*this->*/max.texturesCube);
/*this->*/max.textures3D = ext::config["engine"]["scenes"]["textures"]["max"]["3D"].as<uint32_t>(/*this->*/max.textures3D);
// merge light settings with global settings
{
const auto& globalSettings = ext::config["engine"]["scenes"]["lights"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( serializer["light"][key] ) ) return;
serializer["light"][key] = value;
} );
}
// merge bloom settings with global settings
{
const auto& globalSettings = ext::config["engine"]["scenes"]["lights"]["bloom"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( serializer["light"]["bloom"][key] ) ) return;
serializer["light"]["bloom"][key] = value;
} );
}
// merge shadows settings with global settings
{
const auto& globalSettings = ext::config["engine"]["scenes"]["lights"]["shadows"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( serializer["light"]["shadows"][key] ) ) return;
serializer["light"]["shadows"][key] = value;
} );
}
// merge fog settings with global settings
{
const auto& globalSettings = ext::config["engine"]["scenes"]["lights"]["fog"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( serializer["light"]["fog"][key] ) ) return;
serializer["light"]["fog"][key] = value;
} );
}
/*this->*/shadow.enabled = ext::config["engine"]["scenes"]["shadows"]["enabled"].as<bool>(true) && serializer["light"]["shadows"].as<bool>(true);
/*this->*/shadow.samples = ext::config["engine"]["scenes"]["shadows"]["samples"].as<uint32_t>();
/*this->*/shadow.max = ext::config["engine"]["scenes"]["shadows"]["max"].as<uint32_t>();
/*this->*/shadow.update = ext::config["engine"]["scenes"]["shadows"]["update"].as<uint32_t>();
/*this->*/shadow.typeMap = ext::config["engine"]["scenes"]["shadows"]["map type"].as<uint32_t>(1);
/*this->*/max.textures2D = ext::config["engine"]["scenes"]["textures"]["max"]["2D"].as(/*this->*/max.textures2D);
/*this->*/max.texturesCube = ext::config["engine"]["scenes"]["textures"]["max"]["cube"].as(/*this->*/max.texturesCube);
/*this->*/max.textures3D = ext::config["engine"]["scenes"]["textures"]["max"]["3D"].as(/*this->*/max.textures3D);
/*this->*/light.enabled = ext::config["engine"]["scenes"]["lights"]["enabled"].as<bool>(true) && serializer["light"]["should"].as<bool>(true);
/*this->*/light.max = ext::config["engine"]["scenes"]["lights"]["max"].as<uint32_t>(/*this->*/light.max);
/*this->*/light.ambient = uf::vector::decode( serializer["light"]["ambient"], pod::Vector4f{ 1, 1, 1, 1 } );
/*this->*/light.specular = uf::vector::decode( serializer["light"]["specular"], pod::Vector4f{ 1, 1, 1, 1 } );
/*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->*/shadow.enabled = serializer["light"]["shadows"]["enabled"].as(/*this->*/shadow.enabled);
/*this->*/shadow.samples = serializer["light"]["shadows"]["samples"].as(/*this->*/shadow.samples);
/*this->*/shadow.max = serializer["light"]["shadows"]["max"].as(/*this->*/shadow.max);
/*this->*/shadow.update = serializer["light"]["shadows"]["update"].as(/*this->*/shadow.update);
/*this->*/shadow.typeMap = serializer["light"]["shadows"]["map type"].as(/*this->*/shadow.typeMap);
/*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));
/*this->*/bloom.sigma = serializer["bloom"]["sigma"].as(ext::config["engine"]["scenes"]["bloom"]["sigma"].as(bloom.sigma));
/*this->*/bloom.samples = serializer["bloom"]["samples"].as(ext::config["engine"]["scenes"]["bloom"]["samples"].as(bloom.samples));
/*this->*/light.enabled = serializer["light"]["enabled"].as(/*this->*/light.enabled) && serializer["light"]["should"].as(/*this->*/light.enabled);
/*this->*/light.max = serializer["light"]["max"].as(/*this->*/light.max);
/*this->*/light.ambient = uf::vector::decode( serializer["light"]["ambient"], /*this->*/light.ambient);
/*this->*/fog.color = uf::vector::decode( serializer["light"]["fog"]["color"], pod::Vector3f{ 1, 1, 1 } );
/*this->*/fog.stepScale = serializer["light"]["fog"]["step scale"].as<float>();
/*this->*/fog.absorbtion = serializer["light"]["fog"]["absorbtion"].as<float>();
/*this->*/fog.range = uf::vector::decode( serializer["light"]["fog"]["range"], pod::Vector2f{ 0, 0 } );
/*this->*/fog.density.offset = uf::vector::decode( serializer["light"]["fog"]["density"]["offset"], pod::Vector4f{ 0, 0, 0, 0 } );
/*this->*/fog.density.timescale = serializer["light"]["fog"]["density"]["timescale"].as<float>();
/*this->*/fog.density.threshold = serializer["light"]["fog"]["density"]["threshold"].as<float>();
/*this->*/fog.density.multiplier = serializer["light"]["fog"]["density"]["multiplier"].as<float>();
/*this->*/fog.density.scale = serializer["light"]["fog"]["density"]["scale"].as<float>();
/*this->*/light.exposure = serializer["light"]["exposure"].as(/*this->*/light.exposure);
/*this->*/light.gamma = serializer["light"]["gamma"].as(/*this->*/light.gamma);
/*this->*/light.brightnessThreshold = serializer["light"]["brightnessThreshold"].as(/*this->*/light.brightnessThreshold);
/*this->*/light.useLightmaps = serializer["light"]["useLightmaps"].as(/*this->*/light.useLightmaps);
/*this->*/bloom.scale = serializer["light"]["bloom"]["scale"].as(/*this->*/bloom.scale);
/*this->*/bloom.strength = serializer["light"]["bloom"]["strength"].as(/*this->*/bloom.strength);
/*this->*/bloom.sigma = serializer["light"]["bloom"]["sigma"].as(/*this->*/bloom.sigma);
/*this->*/bloom.samples = serializer["light"]["bloom"]["samples"].as(/*this->*/bloom.samples);
/*this->*/fog.color = uf::vector::decode( serializer["light"]["fog"]["color"], /*this->*/fog.color );
/*this->*/fog.stepScale = serializer["light"]["fog"]["step scale"].as( /*this->*/fog.stepScale );
/*this->*/fog.absorbtion = serializer["light"]["fog"]["absorbtion"].as( /*this->*/fog.absorbtion );
/*this->*/fog.range = uf::vector::decode( serializer["light"]["fog"]["range"], /*this->*/fog.range );
/*this->*/fog.density.offset = uf::vector::decode( serializer["light"]["fog"]["density"]["offset"], /*this->*/fog.density.offset );
/*this->*/fog.density.timescale = serializer["light"]["fog"]["density"]["timescale"].as(/*this->*/fog.density.timescale);
/*this->*/fog.density.threshold = serializer["light"]["fog"]["density"]["threshold"].as(/*this->*/fog.density.threshold);
/*this->*/fog.density.multiplier = serializer["light"]["fog"]["density"]["multiplier"].as(/*this->*/fog.density.multiplier);
/*this->*/fog.density.scale = serializer["light"]["fog"]["density"]["scale"].as(/*this->*/fog.density.scale);
/*this->*/sky.box.filename = serializer["sky"]["box"]["filename"].as<uf::stl::string>(sky.box.filename);
/*this->*/sky.box.filename = serializer["sky"]["box"]["filename"].as(/*this->*/sky.box.filename);
/*this->*/shader.mode = serializer["system"]["renderer"]["shader"]["mode"].as(/*this->*/shader.mode);
/*this->*/shader.scalar = serializer["system"]["renderer"]["shader"]["scalar"].as(/*this->*/shader.scalar);
/*this->*/shader.parameters = uf::vector::decode( serializer["system"]["renderer"]["shader"]["parameters"], /*this->*/shader.parameters );
/*this->*/shader.frameAccumulateLimit = serializer["system"]["renderer"]["shader"]["frame accumulate limit"].as(/*this->*/shader.frameAccumulateLimit);
/*this->*/shader.mode = serializer["system"]["renderer"]["shader"]["mode"].as<uint32_t>();
/*this->*/shader.scalar = serializer["system"]["renderer"]["shader"]["scalar"].as<uint32_t>();
/*this->*/shader.parameters = uf::vector::decode( serializer["system"]["renderer"]["shader"]["parameters"], pod::Vector4f{0,0,0,0} );
/*this->*/shader.frameAccumulateLimit = serializer["system"]["renderer"]["shader"]["frame accumulate limit"].as<uint32_t>(0);
ext::json::forEach( serializer["system"]["renderer"]["shader"]["parameters"], [&]( uint32_t i, const ext::json::Value& value ){
if ( value.as<uf::stl::string>() == "time" ) /*this->*/shader.time = i;
});
if ( 0 <= /*this->*/shader.time && /*this->*/shader.time < 4 ) {
/*this->*/shader.parameters[/*this->*/shader.time] = uf::physics::time::current;
}

View File

@ -22,7 +22,7 @@ namespace ext {
bool enabled = true;
uint32_t max = 256;
pod::Vector4f ambient = {0,0,0,1};
pod::Vector4f specular = {1,1,1,1};
pod::Vector4f _placeholder = {1,1,1,1};
float exposure = 1.0f;
float gamma = 1.0f;
float brightnessThreshold = 1.0f;

View File

@ -86,7 +86,7 @@ void ext::SoundEmitterBehavior::initialize( uf::Object& self ) {
ext::json::Value json = metadata["audio"];
json["filename"] = payload.filename;
this->callHook("sound:Emit.%UID%", json);
this->lazyCallHook("sound:Emit.%UID%", json);
});
}
void ext::SoundEmitterBehavior::tick( uf::Object& self ) {

View File

@ -31,15 +31,6 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
auto& sceneMetadataJson = scene.getComponent<uf::Serializer>();
auto& sceneTextures = this->getComponent<pod::SceneTextures>();
// merge vxgi settings with global settings
{
const auto& globalSettings = ext::config["engine"]["scenes"]["vxgi"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( metadataJson["vxgi"][key] ) ) return;
metadataJson["vxgi"][key] = value;
} );
}
UF_BEHAVIOR_METADATA_BIND_SERIALIZER_HOOKS(metadata, metadataJson);
// initialize voxel map
@ -465,26 +456,35 @@ void ext::VoxelizerSceneBehavior::Metadata::serialize( uf::Object& self, uf::Ser
serializer["vxgi"]["extents"]["max"] = uf::vector::encode(/*this->*/extents.max);
}
void ext::VoxelizerSceneBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ) {
/*this->*/voxelSize.x = serializer["vxgi"]["size"].as<size_t>(96);
/*this->*/voxelSize.y = serializer["vxgi"]["size"].as<size_t>(96);
/*this->*/voxelSize.z = serializer["vxgi"]["size"].as<size_t>(96);
// merge vxgi settings with global settings
{
const auto& globalSettings = ext::config["engine"]["scenes"]["vxgi"];
ext::json::forEach( globalSettings, [&]( const uf::stl::string& key, const ext::json::Value& value ){
if ( !ext::json::isNull( serializer["vxgi"][key] ) ) return;
serializer["vxgi"][key] = value;
} );
}
/*this->*/voxelSize.x = serializer["vxgi"]["size"].as(/*this->*/voxelSize.x);
/*this->*/voxelSize.y = serializer["vxgi"]["size"].as(/*this->*/voxelSize.y);
/*this->*/voxelSize.z = serializer["vxgi"]["size"].as(/*this->*/voxelSize.z);
/*this->*/limiter.frequency = serializer["vxgi"]["limiter"].as<float>(1);
/*this->*/limiter.frequency = serializer["vxgi"]["limiter"].as(/*this->*/limiter.frequency);
/*this->*/dispatchSize.x = serializer["vxgi"]["dispatch"].as<float>(8);
/*this->*/dispatchSize.y = serializer["vxgi"]["dispatch"].as<float>(8);
/*this->*/dispatchSize.z = serializer["vxgi"]["dispatch"].as<float>(8);
/*this->*/dispatchSize.x = serializer["vxgi"]["dispatch"].as(/*this->*/dispatchSize.x);
/*this->*/dispatchSize.y = serializer["vxgi"]["dispatch"].as(/*this->*/dispatchSize.x);
/*this->*/dispatchSize.z = serializer["vxgi"]["dispatch"].as(/*this->*/dispatchSize.x);
/*this->*/cascades = serializer["vxgi"]["cascades"].as<size_t>(4);
/*this->*/cascadePower = serializer["vxgi"]["cascadePower"].as<size_t>(4);
/*this->*/granularity = serializer["vxgi"]["granularity"].as<float>(4);
/*this->*/voxelizeScale = serializer["vxgi"]["voxelizeScale"].as<float>(1);
/*this->*/occlusionFalloff = serializer["vxgi"]["occlusionFalloff"].as<float>(128);
/*this->*/traceStartOffsetFactor = serializer["vxgi"]["traceStartOffsetFactor"].as<float>(1.0f);
/*this->*/shadows = serializer["vxgi"]["shadows"].as<size_t>(0);
/*this->*/cascades = serializer["vxgi"]["cascades"].as(/*this->*/cascades);
/*this->*/cascadePower = serializer["vxgi"]["cascadePower"].as(/*this->*/cascadePower);
/*this->*/granularity = serializer["vxgi"]["granularity"].as(/*this->*/granularity);
/*this->*/voxelizeScale = serializer["vxgi"]["voxelizeScale"].as(/*this->*/voxelizeScale);
/*this->*/occlusionFalloff = serializer["vxgi"]["occlusionFalloff"].as(/*this->*/occlusionFalloff);
/*this->*/traceStartOffsetFactor = serializer["vxgi"]["traceStartOffsetFactor"].as(/*this->*/traceStartOffsetFactor);
/*this->*/shadows = serializer["vxgi"]["shadows"].as(/*this->*/shadows);
/*this->*/extents.min = uf::vector::decode( serializer["vxgi"]["extents"]["min"], pod::Vector3f{-32, -32, -32} );
/*this->*/extents.max = uf::vector::decode( serializer["vxgi"]["extents"]["max"], pod::Vector3f{ 32, 32, 32} );
/*this->*/extents.min = uf::vector::decode( serializer["vxgi"]["extents"]["min"], /*this->*/extents.min );
/*this->*/extents.max = uf::vector::decode( serializer["vxgi"]["extents"]["max"], /*this->*/extents.max );
}
#undef this
#endif

View File

@ -1019,21 +1019,26 @@ void ext::GuiBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer&
serializer["gui"][key] = serializer["text settings"][key];
}
color = uf::vector::decode( serializer["gui"]["color"], color );
world = serializer["gui"]["world"].as<bool>();
/*this->*/color = uf::vector::decode( serializer["gui"]["color"], /*this->*/color );
/*this->*/world = serializer["gui"]["world"].as(/*this->*/world);
if ( serializer["gui"]["only model"].as<bool>() ) mode = 1;
else if ( serializer["gui"]["world"].as<bool>() ) mode = 2;
else if ( serializer["gui"]["projection"].as<bool>() ) mode = 3;
box.min = uf::vector::decode( serializer["box"]["min"], box.min );
box.max = uf::vector::decode( serializer["box"]["max"], box.max );
clickable = serializer["gui"]["clickable"].as<bool>();
clicked = serializer["gui"]["clicked"].as<bool>();
hoverable = serializer["gui"]["hoverable"].as<bool>();
hovered = serializer["gui"]["hovered"].as<bool>();
uv = uf::vector::decode( serializer["gui"]["uv"], uv );
shader = serializer["gui"]["shader"].as<int>();
depth = serializer["gui"]["depth"].as<float>();
alpha = serializer["gui"]["alpha"].as<float>();
/*this->*/box.min = uf::vector::decode( serializer["box"]["min"], /*this->*/box.min );
/*this->*/box.max = uf::vector::decode( serializer["box"]["max"], /*this->*/box.max );
/*this->*/clickable = serializer["gui"]["clickable"].as(/*this->*/clickable);
/*this->*/clicked = serializer["gui"]["clicked"].as(/*this->*/clicked);
/*this->*/hoverable = serializer["gui"]["hoverable"].as(/*this->*/hoverable);
/*this->*/hovered = serializer["gui"]["hovered"].as(/*this->*/hovered);
/*this->*/uv = uf::vector::decode( serializer["gui"]["uv"], /*this->*/uv );
/*this->*/shader = serializer["gui"]["shader"].as(/*this->*/shader);
/*this->*/depth = serializer["gui"]["depth"].as(/*this->*/depth);
/*this->*/alpha = serializer["gui"]["alpha"].as(/*this->*/alpha);
if ( serializer["gui"]["alpha"].is<float>() ) color[3] *= alpha;
}
@ -1066,24 +1071,24 @@ void ext::GuiBehavior::GlyphMetadata::deserialize( uf::Object& self, uf::Seriali
if ( !ext::json::isNull( serializer[key] ) ) serializer["gui"][key] = serializer[key];
if ( !ext::json::isNull( serializer["text settings"][key] ) ) serializer["gui"][key] = serializer["text settings"][key];
}
/*this->*/font = serializer["gui"]["font"].as<uf::stl::string>();
/*this->*/string = serializer["gui"]["string"].as<uf::stl::string>();
/*this->*/font = serializer["gui"]["font"].as(/*this->*/font);
/*this->*/string = serializer["gui"]["string"].as(/*this->*/string);
/*this->*/scale = serializer["gui"]["scale"].as<float>();
/*this->*/scale = serializer["gui"]["scale"].as(/*this->*/scale);
/*this->*/padding = uf::vector::decode( serializer["gui"]["padding"], /*this->*/padding );
/*this->*/spread = serializer["gui"]["spread"].as<float>();
/*this->*/size = serializer["gui"]["size"].as<float>();
/*this->*/weight = serializer["gui"]["weight"].as<float>();
/*this->*/spread = serializer["gui"]["spread"].as(/*this->*/spread);
/*this->*/size = serializer["gui"]["size"].as(/*this->*/size);
/*this->*/weight = serializer["gui"]["weight"].as(/*this->*/weight);
#if UF_USE_OPENGL
/*this->*/sdf = false;
#else
/*this->*/sdf = serializer["gui"]["sdf"].as<bool>();
/*this->*/sdf = serializer["gui"]["sdf"].as(/*this->*/sdf);
#endif
/*this->*/shadowbox = serializer["gui"]["shadowbox"].as<bool>();
/*this->*/shadowbox = serializer["gui"]["shadowbox"].as(/*this->*/shadowbox);
/*this->*/stroke = uf::vector::decode( serializer["gui"]["stroke"], /*this->*/stroke );
/*this->*/origin = serializer["gui"]["origin"].as<uf::stl::string>();
/*this->*/align = serializer["gui"]["align"].as<uf::stl::string>();
/*this->*/direction = serializer["gui"]["direction"].as<uf::stl::string>();
/*this->*/origin = serializer["gui"]["origin"].as(/*this->*/origin);
/*this->*/align = serializer["gui"]["align"].as(/*this->*/align);
/*this->*/direction = serializer["gui"]["direction"].as(/*this->*/direction);
}
#undef this

View File

@ -240,6 +240,8 @@ void EXT_API ext::initialize() {
uf::userdata::autoDestruct = ::json["engine"]["debug"]["userdata"]["auto destruct"].as( uf::userdata::autoDestruct );
uf::userdata::autoValidate = ::json["engine"]["debug"]["userdata"]["auto validate"].as( uf::userdata::autoValidate );
uf::Object::deferLazyCalls = ::json["engine"]["debug"]["hooks"]["defer lazy calls"].as( uf::Object::deferLazyCalls );
}
{
@ -436,7 +438,7 @@ void EXT_API ext::initialize() {
if ( uf::renderer::settings::pipelines::rt ) {
uf::renderer::settings::pipelines::vxgi = false;
uf::renderer::settings::pipelines::culling = false;
::json["engine"]["scenes"]["shadows"]["enabled"] = false;
::json["engine"]["scenes"]["lights"]["shadows"]["enabled"] = false;
}
#define JSON_TO_VKFORMAT( key ) if ( configRenderJson["formats"][#key].is<uf::stl::string>() ) {\