Commit for 2021.10.28 23-52-39.7z

This commit is contained in:
mrq 2021-10-28 23:52:00 -05:00
parent 3c11536d7f
commit fb5749d8a3
60 changed files with 1513 additions and 824 deletions

View File

@ -29,7 +29,8 @@ EXT_LIB_NAME += ext
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.154.0/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.162.0/
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.176.1/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.176.1/
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.182.0/
#GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin32/glslangValidator
GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin32/glslc

View File

@ -1,21 +1,17 @@
{
"engine": {
"scenes": {
"start": "Construct",
"meshes": {
"interleave": false
},
"matrix": {
"reverseInfinite": true
},
"start": "McDonalds",
"meshes": { "interleave": false },
"matrix": { "reverseInfinite": true },
"lights": {
"max": 32,
"max": 24,
"enabled": true
},
"shadows": {
"enabled": true,
"update": 2,
"max": 6,
"update": 4,
"max": 12,
"samples": 2,
"experimental mode": 1
},
@ -27,7 +23,7 @@
}
},
"vxgi": {
"limiter": 0.125,
"limiter": 0.5,
"size": 128,
"dispatch": 8,
"cascades": 3,
@ -61,12 +57,8 @@
},
"framebuffer": {
"size": 1,
// "size": [ 1280, 720 ],
// "size": [ 1920, 1080 ],
// "size": [ 640, 480, "NEAREST" ],
// "size": [ 256, 224, "NEAREST" ],
// "msaa": 16
"msaa": 4
"msaa": 12
},
"experimental": {
"rebuild on tick begin": false,
@ -80,7 +72,7 @@
"vsync": true,
"hdr": false,
"vxgi": true,
"deferred sampling": false,
"deferred sampling": true,
"culling": true,
"bloom": true
},
@ -113,19 +105,12 @@
"VK_KHR_get_physical_device_properties2",
"VK_KHR_get_surface_capabilities2"
],
"device": [
]
"device": []
}
},
"opengl": {
"validation": {
"enabled": true
},
"framebuffer": {
"size": 1,
"msaa": 1
},
"validation": { "enabled": true },
"framebuffer": { "size": 1, "msaa": 1 },
"experimental": {
"rebuild on tick begin": false,
"wait on render end": false,
@ -146,10 +131,7 @@
"position": "R16G16B16A16_SFLOAT"
},
"features": [],
"extensions": {
"instance": [],
"device": []
}
"extensions": { "instance": [], "device": [] }
},
"lua": {
"enabled": true,
@ -158,17 +140,6 @@
"json": "/json.lua"
}
},
"vr" : {
"enable" : false,
"manifest": "./data/openvr_manifest.json",
"swap eyes": false,
"dominant eye": 0,
"scale": 1.0
},
"ultralight": {
"enabled": true,
"scale": 1.5
},
"bullet": {
"iterations": 1,
"substeps": 12,
@ -184,9 +155,15 @@
"rate": 0.0125
}
},
"discord": {
"enabled": false
}
"vr" : {
"enable" : false,
"manifest": "./data/openvr_manifest.json",
"swap eyes": false,
"dominant eye": 0,
"scale": 1.0
},
"ultralight": { "enabled": true, "scale": 1.5 },
"discord": { "enabled": false }
},
"audio": {
"mute": false,
@ -213,18 +190,13 @@
"component": "256 MiB"
}
},
"render modes": {
"gui": true,
"deferred": true,
"stereo deferred": false,
"multiview stereo deferred": false
},
"render modes": { "gui": true, "deferred": true },
"limiters": {
"deltaTime": 10,
"framerate": "auto"
},
"threads": {
"workers" : "auto",
"workers" : "async", // "auto"
"frame limiter": "auto"
},
"debug": {
@ -258,10 +230,11 @@
},
"mode" : "windowed", // fullscreen, borderless, windowed
"icon" : "./data/textures/icon.png",
"size" : [ 1920, 1080 ],
// "size" : [ 1280, 720 ],
// "size" : [ 1920, 1080 ],
"size" : [ 1280, 720 ],
// "size" : [ 960, 540 ],
// "size" : [ 640, 480 ],
// "size" : [ 256, 224 ],
"title" : "Grimgram",
"visible" : true
}

View File

@ -33,7 +33,7 @@
"output": "./lightmap.png"
},
// "lightmap": "./lightmap.min.png",
"lightmap": "./lightmap.png",
// "lightmap": "./lightmap.png",
"filter": "NEAREST",
"flags": {
"ATLAS": false,
@ -45,7 +45,10 @@
"SEPARATE": false,
"NORMALS": false
},
"lights": { "shadows": true }
"lights": {
// "disable if lightmapped": false,
"shadows": true
}
}
}
}

View File

@ -75,7 +75,7 @@
},
"camera": {
"offset": [ 0, 0, 0 ],
"position" : [ 0, 2, 0 ],
"position" : [ 0, 1.8, 0 ],
"scale": [ 1, 1, 1 ],
"invert": [ false, false, false ],
"limit": {

View File

@ -1,7 +1,7 @@
{
"type": "Object",
"name": "Player: Model",
"ignore": true,
"ignore": false,
"assets": [
"/player/bear.glb"
// { "filename": "/player/bear/graph.json", "delay": 0, "single threaded": false, "category": "models" }

View File

@ -1,9 +1,9 @@
{
"import": "/model.json",
"assets": [
{ "filename": "./models/gm_construct.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/gm_construct.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/gm_construct/graph.json", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/gm_construct/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
{ "filename": "./models/gm_construct/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
],
"metadata": {
"model": {

View File

@ -13,17 +13,17 @@
"worldspawn": { "physics": { "type": "mesh", "static": true } },
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },
"func_door_rotating_5409": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5487": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795 } } },
"func_door_rotating_5495": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795 } } },
"func_door_rotating_5568": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5576": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795 } } },
"func_door_rotating_5584": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5656": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795 } } },
"func_door_rotating_5664": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5689": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5698": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5712": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } }
"func_door_rotating_5409": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5487": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
"func_door_rotating_5495": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
"func_door_rotating_5568": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5576": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
"func_door_rotating_5584": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5656": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
"func_door_rotating_5664": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5689": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5698": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5712": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } }
}
}
}

View File

@ -25,15 +25,15 @@
"pause": "/gui/pause/menu.json"
},
"bloom": {
"scale": 1.0,
"strength": 0.5,
"sigma": 0.75,
"scale": 2.0,
"strength": 0.125,
"sigma": 0.125,
"samples": 8
},
"light": {
"exposure": 1.0,
"gamma": 1.0,
"brightnessThreshold": 1.0,
"brightnessThreshold": 1.2,
"ambient": [ 0.1, 0.1, 0.1 ],
"fog": {

View File

@ -6,13 +6,105 @@ if not timer:running() then
timer:start();
end
local polarity = 1
local state = 0
local targetAlpha = 1
local alpha = 0
local target = Vector3f(0,0,0)
local transform = ent:getComponent("Transform")
local metadata = ent:getComponent("Metadata")
local speed = metadata["speed"] or 1.0 / 3.0
local speed = metadata["speed"] or 1.0
local normal = Vector3f(0,0,-1)
if metadata["normal"] ~= nil then
local sign = -1
if metadata["angle"] < 0 then sign = 1 end
normal = Vector3f( metadata["normal"][1] * sign, metadata["normal"][2] * sign, metadata["normal"][3] * sign ):normalize()
end
local starting = Quaternion(transform.orientation)
local ending = transform.orientation:multiply(Quaternion.axisAngle( Vector3f(0,1,0), metadata["angle"] ))
local soundEmitter = ent:loadChild("./sound.json",true)
local playSound = function( key, loop )
if not loop then loop = false end
local url = "/door/" .. key .. ".ogg"
soundEmitter:queueHook("sound:Emit.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"]),
spatial = true,
streamed = true,
volume = "sfx",
loop = loop
}, 0)
end
local stopSound = function( key )
local url = "/door/" .. key .. ".ogg"
soundEmitter:queueHook("sound:Stop.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"])
}, 0)
end
local playSoundscape = function( key )
local url = "/soundscape/" .. key .. ".ogg"
soundEmitter:queueHook("sound:Emit.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"]),
spatial = false,
volume = "sfx",
loop = true,
streamed = true
}, 0)
end
local stopSoundscape = function( key )
local url = "/soundscape/" .. key .. ".ogg"
soundEmitter:queueHook("sound:Stop.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"])
}, 0)
end
soundEmitter:getComponent("Transform"):setReference( transform )
-- on tick
ent:bind( "tick", function(self)
transform.orientation = starting:slerp( ending, math.cos(time.current() * speed) * 0.5 + 0.5 )
-- transform.orientation = starting:slerp( ending, math.cos(time.current() * speed) * 0.5 + 0.5 )
if state == 1 then
alpha = alpha + time.delta() * speed
if alpha > targetAlpha then
state = 2
alpha = targetAlpha
playSound("default_stop")
end
end
if state == 3 then
alpha = alpha - time.delta() * speed
if alpha < 0 then
state = 0
alpha = 0
playSound("default_stop")
end
end
if state > 0 then
transform.orientation = starting:slerp( ending, alpha * polarity )
end
end )
-- on use
ent:addHook( "entity:Use.%UID%", function( payload )
if state == 0 then
state = 1
playSound("default_move")
if payload.uid ~= nil then
local player = entities.get( payload.uid )
local pTransform = player:getComponent("Transform")
local delta = transform.position - pTransform.position
local side = normal:dot(delta)
if side > 0 then
polarity = 1
elseif side < 0 then
polarity = -1
end
end
io.print(ent:name())
end
if state == 2 then
state = 3
playSound("default_move")
end
io.print( state, json.encode( payload ) )
end )

View File

@ -0,0 +1,34 @@
{
"type": "Object",
"name": "Sound Emitter",
"ignore": false,
"assets": [
],
"behaviors": [
"SoundEmitterBehavior"
],
"transform": {
"reference": true
},
"system": {
"hot reload": {
"enabled": true
},
"defaults": {
"render": true,
"asset load": true
},
"load": {
"ignore": true
}
},
"metadata": {
"audio": {
"spatial": true,
"loop": false,
"volume": 1,
"rolloffFactor": 0.5,
"epsilon": 0.5
}
}
}

View File

@ -26,13 +26,14 @@
},
"bloom": {
"scale": 1.0,
"strength": 0.5,
"strength": 0.125,
"sigma": 0.75,
"samples": 8
},
"light": {
"exposure": 1.0,
"gamma": 1.0,
"brightnessThreshold": 1.2,
"ambient": [ 0.15, 0.15, 0.15 ],

View File

@ -6,13 +6,105 @@ if not timer:running() then
timer:start();
end
local polarity = 1
local state = 0
local targetAlpha = 1
local alpha = 0
local target = Vector3f(0,0,0)
local transform = ent:getComponent("Transform")
local metadata = ent:getComponent("Metadata")
local speed = metadata["speed"] or 1.0 / 3.0
local speed = metadata["speed"] or 1.0
local normal = Vector3f(0,0,-1)
if metadata["normal"] ~= nil then
local sign = -1
if metadata["angle"] < 0 then sign = 1 end
normal = Vector3f( metadata["normal"][1] * sign, metadata["normal"][2] * sign, metadata["normal"][3] * sign ):normalize()
end
local starting = Quaternion(transform.orientation)
local ending = transform.orientation:multiply(Quaternion.axisAngle( Vector3f(0,1,0), metadata["angle"] ))
local soundEmitter = ent:loadChild("./sound.json",true)
local playSound = function( key, loop )
if not loop then loop = false end
local url = "/door/" .. key .. ".ogg"
soundEmitter:queueHook("sound:Emit.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"]),
spatial = true,
streamed = true,
volume = "sfx",
loop = loop
}, 0)
end
local stopSound = function( key )
local url = "/door/" .. key .. ".ogg"
soundEmitter:queueHook("sound:Stop.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"])
}, 0)
end
local playSoundscape = function( key )
local url = "/soundscape/" .. key .. ".ogg"
soundEmitter:queueHook("sound:Emit.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"]),
spatial = false,
volume = "sfx",
loop = true,
streamed = true
}, 0)
end
local stopSoundscape = function( key )
local url = "/soundscape/" .. key .. ".ogg"
soundEmitter:queueHook("sound:Stop.%UID%", {
filename = string.resolveURI(url, metadata["system"]["root"])
}, 0)
end
soundEmitter:getComponent("Transform"):setReference( transform )
-- on tick
ent:bind( "tick", function(self)
transform.orientation = starting:slerp( ending, math.cos(time.current() * speed) * 0.5 + 0.5 )
-- transform.orientation = starting:slerp( ending, math.cos(time.current() * speed) * 0.5 + 0.5 )
if state == 1 then
alpha = alpha + time.delta() * speed
if alpha > targetAlpha then
state = 2
alpha = targetAlpha
playSound("default_stop")
end
end
if state == 3 then
alpha = alpha - time.delta() * speed
if alpha < 0 then
state = 0
alpha = 0
playSound("default_stop")
end
end
if state > 0 then
transform.orientation = starting:slerp( ending, alpha * polarity )
end
end )
-- on use
ent:addHook( "entity:Use.%UID%", function( payload )
if state == 0 then
state = 1
playSound("default_move")
if payload.uid ~= nil then
local player = entities.get( payload.uid )
local pTransform = player:getComponent("Transform")
local delta = transform.position - pTransform.position
local side = normal:dot(delta)
if side > 0 then
polarity = 1
elseif side < 0 then
polarity = -1
end
end
io.print(ent:name())
end
if state == 2 then
state = 3
playSound("default_move")
end
io.print( state, json.encode( payload ) )
end )

View File

@ -3,27 +3,28 @@
"assets": [
// { "filename": "./static.json", "delay": 8 },
{ "filename": "./models/sh_mcd.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/sh_mcd.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/sh_mcd/graph.json", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/sh_mcd/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
{ "filename": "./models/sh_mcd/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
],
"metadata": {
"cull mode": "none",
"model": {
"tags": {
"worldspawn": { "physics": { "type": "mesh", "static": true } },
"info_player_spawn": { "action": "attach", "filename": "./player.json", "preserve orientation": true },
"func_door_rotating_5409": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5487": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795 } } },
"func_door_rotating_5495": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795 } } },
"func_door_rotating_5568": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5576": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795 } } },
"func_door_rotating_5584": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5656": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795 } } },
"func_door_rotating_5664": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5689": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5698": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } },
"func_door_rotating_5712": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795 } } }
"func_door_rotating_5409": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5487": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
"func_door_rotating_5495": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
"func_door_rotating_5568": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5576": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
"func_door_rotating_5584": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5656": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle": 1.570795, "normal": [ 1,0,0] } } },
"func_door_rotating_5664": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5689": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5698": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } },
"func_door_rotating_5712": { "action": "load", "payload": { "import": "./door.json", "metadata": { "angle":-1.570795, "normal": [-1,0,0] } } }
}
}
}

View File

@ -0,0 +1,34 @@
{
"type": "Object",
"name": "Sound Emitter",
"ignore": false,
"assets": [
],
"behaviors": [
"SoundEmitterBehavior"
],
"transform": {
"reference": true
},
"system": {
"hot reload": {
"enabled": true
},
"defaults": {
"render": true,
"asset load": true
},
"load": {
"ignore": true
}
},
"metadata": {
"audio": {
"spatial": true,
"loop": false,
"volume": 1,
"rolloffFactor": 0.5,
"epsilon": 0.5
}
}
}

View File

@ -3,11 +3,11 @@
"assets": [
// { "filename": "./models/micro_sci.glb", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/micro_sci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/micro_sci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
{ "filename": "./models/micro_sci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/msci.glb", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/msci/graph.json", "delay": 0, "single threaded": false, "category": "models" }
{ "filename": "./models/msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/msci/graph.json.gz", "delay": 0, "single threaded": false, "category": "models" }
// { "filename": "./models/medsci.glb", "delay": 0, "single threaded": false }
// { "filename": "./models/medsci/graph.json", "delay": 0, "single threaded": false, "category": "models" }

View File

@ -32,7 +32,8 @@
"light": {
"exposure": 1.0,
"gamma": 1.0,
"brightnessThreshold": 1.2,
"ambient": [ 0.0, 0.0, 0.0 ],
"fog": {

View File

@ -15,7 +15,7 @@ layout (location = 3) in vec3 inPosition;
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
layout (location = 2) out vec4 outUvs;
#else
layout (location = 2) out vec4 outAlbedo;
#endif
@ -27,7 +27,8 @@ void main() {
vec3 P = inPosition;
vec3 N = inNormal;
#if DEFERRED_SAMPLING
outUvs = wrap(inUv.xy);
outUvs.xy = wrap(inUv.xy);
outUvs.zw = vec2(0,0);
vec4 outAlbedo = vec4(0,0,0,0);
#endif
#if !DEFERRED_SAMPLING || CAN_DISCARD

View File

@ -38,7 +38,12 @@ bool validTextureIndex( int textureIndex ) {
bool validCubemapIndex( int textureIndex ) {
return 0 <= textureIndex && textureIndex < CUBEMAPS;
}
#if !BLOOM && (DEFERRED || COMPUTE)
#if !BLOOM && (DEFERRED || FRAGMENT || COMPUTE)
#if !NO_NONUNIFORM_EXT
#extension GL_EXT_nonuniform_qualifier : enable
#endif
bool validTextureIndex( uint id ) {
return 0 <= id && id < MAX_TEXTURES;
}
@ -48,34 +53,16 @@ bool validTextureIndex( uint start, int offset ) {
uint textureIndex( uint start, int offset ) {
return start + offset;
}
vec4 sampleTexture( uint id ) {
vec4 sampleTexture( uint id, vec2 uv ) {
const Texture t = textures[id];
return texture( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, surface.uv ) );
return texture( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ) );
}
vec4 sampleTexture( uint id, float mip ) {
vec4 sampleTexture( uint id, vec2 uv, float mip ) {
const Texture t = textures[id];
return textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, surface.uv ), mip );
return textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
}
#if 0
vec4 sampleTexture( uint start, uint slot, int offset, int atlas ) {
Texture a;
const bool useAtlas = 0 <= atlas && validTextureIndex( start, atlas );
if ( useAtlas ) a = textures[textureIndex( start, atlas )];
const Texture t = textures[textureIndex( start, offset )];
const vec2 uv = ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv;
const uint i = slot + ( useAtlas ? a.index : t.index );
return texture( samplerTextures[nonuniformEXT(i)], uv );
}
vec4 sampleTexture( uint start, uint slot, int offset, int atlas, float mip ) {
Texture a;
const bool useAtlas = 0 <= atlas && validTextureIndex( start, atlas );
if ( useAtlas ) a = textures[textureIndex( start, atlas )];
const Texture t = textures[textureIndex( start, offset )];
const vec2 uv = ( useAtlas ) ? mix( t.lerp.xy, t.lerp.zw, surface.uv ) : surface.uv;
const uint i = slot + ( useAtlas ? a.index : t.index );
return textureLod( samplerTextures[nonuniformEXT(i)], uv, mip );
}
#endif
vec4 sampleTexture( uint id ) { return sampleTexture( id, surface.uv ); }
vec4 sampleTexture( uint id, float mip ) { return sampleTexture( id, surface.uv, mip ); }
#endif
vec2 rayBoxDst( vec3 boundsMin, vec3 boundsMax, in Ray ray ) {
const vec3 t0 = (boundsMin - ray.origin) / ray.direction;

View File

@ -1,3 +1,8 @@
#ifndef NO_NONUNIFORM_EXT
#define NO_NONUNIFORM_EXT 0
// enable if shaderNonUniform is not supported
// Nvidia hardware does not require nonuniformEXT, but AMD does
#endif
#ifndef MULTISAMPLING
#define MULTISAMPLING 1
#endif
@ -40,6 +45,10 @@
#define PBR 1
#endif
#if NO_NONUNIFORM_EXT
#define nonuniformEXT(X) X
#endif
const float PI = 3.14159265359;
const float EPSILON = 0.00001;
const float SQRT2 = 1.41421356237;

View File

@ -47,6 +47,7 @@ void pbr() {
// point light, compute only diffuse
// else if ( abs(light.type) == 1 ) surface.fragment.rgb += (diffuse) * Lr * cosLi;
else surface.fragment.rgb += (diffuse + specular) * Lr * cosLi;
surface.fragment.rgb += (diffuse + specular) * Lr * cosLi;
surface.fragment.a += light.power * La * Ls;
}
}

View File

@ -151,6 +151,7 @@ struct SurfaceMaterial {
struct Surface {
uint pass;
vec2 uv;
vec2 st;
Space position;
Space normal;

View File

@ -189,13 +189,21 @@ void populateSurface() {
const Material material = materials[surface.material.id];
surface.material.albedo = material.colorBase;
surface.material.metallic = material.factorMetallic;
surface.material.roughness = material.factorRoughness;
surface.material.occlusion = material.factorOcclusion;
surface.fragment = material.colorEmissive;
#if DEFERRED_SAMPLING
#if !MULTISAMPLING
surface.uv = subpassLoad(samplerUv).xy;
#else
surface.uv = resolve(samplerUv, ubo.msaa).xy;
#endif
{
#if !MULTISAMPLING
vec4 uv = subpassLoad(samplerUv);
#else
vec4 uv = resolve(samplerUv, ubo.msaa);
#endif
surface.uv = uv.xy;
surface.st = uv.zw;
}
const float mip = mipLevel(inUv.xy);
if ( validTextureIndex( material.indexAlbedo ) ) {
surface.material.albedo = sampleTexture( material.indexAlbedo, mip );
@ -209,10 +217,24 @@ void populateSurface() {
// MASK
} else if ( material.modeAlpha == 2 ) {
}
// Lightmap
if ( validTextureIndex( surface.material.lightmapID ) ) {
surface.material.albedo.rgb *= sampleTexture( surface.material.lightmapID, surface.st ).rgb;
}
// Emissive textures
if ( validTextureIndex( material.indexEmissive ) ) {
surface.fragment += sampleTexture( material.indexEmissive, mip );
surface.material.albedo += sampleTexture( material.indexEmissive, mip );
}
// Occlusion map
if ( validTextureIndex( material.indexOcclusion ) ) {
surface.material.occlusion = sampleTexture( material.indexOcclusion, mip ).r;
}
// Metallic/Roughness map
if ( validTextureIndex( material.indexMetallicRoughness ) ) {
vec4 samp = sampleTexture( material.indexMetallicRoughness, mip );
surface.material.metallic = samp.r;
surface.material.roughness = samp.g;
}
#else
#if !MULTISAMPLING
@ -221,20 +243,18 @@ void populateSurface() {
surface.material.albedo = resolve(samplerAlbedo, ubo.msaa);
#endif
#endif
surface.material.metallic = material.factorMetallic;
surface.material.roughness = material.factorRoughness;
surface.material.occlusion = material.factorOcclusion;
}
void directLighting() {
const vec3 ambient = ubo.ambient.rgb * surface.material.occlusion + surface.material.indirect.rgb;
// surface.fragment.rgb += surface.material.albedo.rgb * ambient;
if ( validTextureIndex( surface.material.lightmapID ) ) {
// surface.fragment.rgb += sampleTexture( surface.material.lightmapID ).rgb;
surface.fragment.rgb += surface.material.albedo.rgb + ambient;
} else {
surface.fragment.rgb += surface.material.albedo.rgb * ambient;
}
if ( ubo.lights == 0 ) { surface.fragment.rgb = surface.material.albedo.rgb; return; }
// if ( ubo.lights == 0 ) { surface.fragment.rgb = surface.material.albedo.rgb; return; }
#if PBR
pbr();
#elif LAMBERT

View File

@ -99,7 +99,11 @@ void main() {
surface.fragment = material.colorEmissive;
surface.material.lightmapID = instance.lightmapID;
#if DEFERRED_SAMPLING
surface.uv = imageLoad(voxelUv[CASCADE], ivec3(tUvw) ).xy;
{
vec4 uv = imageLoad(voxelUv[CASCADE], ivec3(tUvw) );
surface.uv = uv.xy;
surface.st = uv.zw;
}
if ( validTextureIndex( material.indexAlbedo ) ) {
surface.material.albedo = sampleTexture( material.indexAlbedo );
}
@ -113,10 +117,14 @@ void main() {
// MASK
} else if ( material.modeAlpha == 2 ) {
}
// Lightmap
if ( validTextureIndex( surface.material.lightmapID ) ) {
surface.material.albedo.rgb *= sampleTexture( surface.material.lightmapID, surface.st ).rgb;
}
// Emissive textures
if ( validTextureIndex( material.indexEmissive ) ) {
surface.fragment += sampleTexture( material.indexEmissive );
surface.material.albedo += sampleTexture( material.indexEmissive, mip );
}
#else
surface.material.albedo = imageLoad(voxelRadiance[CASCADE], ivec3(tUvw) );
@ -127,13 +135,13 @@ void main() {
float litFactor = 1.0;
if ( validTextureIndex( surface.material.lightmapID ) ) {
// surface.fragment.rgb += sampleTexture( surface.material.lightmapID ).rgb;
surface.fragment.rgb += surface.material.albedo.rgb + ubo.ambient.rgb * surface.material.occlusion;
} else {
surface.fragment.rgb += surface.material.albedo.rgb * ubo.ambient.rgb * surface.material.occlusion;
}
// corrections
surface.material.roughness *= 4.0;
if ( !validTextureIndex( surface.material.lightmapID ) )
{
const vec3 F0 = mix(vec3(0.04), surface.material.albedo.rgb, surface.material.metallic);
const vec3 Lo = normalize( surface.position.world );
@ -141,7 +149,7 @@ void main() {
for ( uint i = 0; i < ubo.lights; ++i ) {
const Light light = lights[i];
if ( light.power <= LIGHT_POWER_CUTOFF ) continue;
if ( light.type >= 0 && validTextureIndex( instance.lightmapID ) ) continue;
if ( light.type >= 0 && validTextureIndex( surface.material.lightmapID ) ) continue;
const vec3 Lp = light.position;
const vec3 Liu = light.position - surface.position.world;
const vec3 Li = normalize(Liu);

View File

@ -1,7 +1,7 @@
#version 450
#pragma shader_stage(fragment)
#extension GL_EXT_nonuniform_qualifier : enable
//#extension GL_EXT_nonuniform_qualifier : enable
layout (constant_id = 0) const uint TEXTURES = 512;
layout (constant_id = 1) const uint CUBEMAPS = 128;
@ -10,17 +10,13 @@ layout (binding = 4) uniform sampler2D samplerTextures[TEXTURES];
layout (binding = 5) uniform samplerCube samplerCubemaps[CUBEMAPS];
#define SHADOW_SAMPLES 16
#define FRAGMENT 1
#define BAKING 1
#define PBR 1
#define LAMBERT 0
#include "../../common/macros.h"
#include "../../common/structs.h"
#include "../../common/functions.h"
#include "../../common/shadows.h"
#if PBR
#include "../../common/pbr.h"
#endif
layout (std140, binding = 6) readonly buffer Instances {
Instance instances[];
@ -35,6 +31,12 @@ layout (std140, binding = 9) readonly buffer Lights {
Light lights[];
};
#include "../../common/functions.h"
#include "../../common/shadows.h"
#if PBR
#include "../../common/pbr.h"
#endif
layout (location = 0) in vec2 inUv;
layout (location = 1) in vec2 inSt;
layout (location = 2) in vec4 inColor;

View File

@ -1,6 +1,7 @@
#extension GL_EXT_nonuniform_qualifier : enable
//#extension GL_EXT_nonuniform_qualifier : enable
#define CUBEMAPS 1
#define FRAGMENT 1
// #define MAX_TEXTURES TEXTURES
#define MAX_TEXTURES textures.length()
layout (constant_id = 0) const uint TEXTURES = 1;
@ -32,7 +33,7 @@ layout (location = 8) flat in uvec4 inId;
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
layout (location = 2) out vec4 outUvs;
#else
layout (location = 2) out vec4 outAlbedo;
#endif
@ -44,6 +45,9 @@ void main() {
const float mip = mipLevel(inUv.xy);
const vec2 uv = wrap(inUv.xy);
const vec3 P = inPosition;
surface.uv = uv;
surface.st = inSt;
vec3 N = inNormal;
vec4 A = vec4(0, 0, 0, 0);
@ -60,8 +64,7 @@ void main() {
// sample albedo
if ( !validTextureIndex( material.indexAlbedo ) ) discard; {
const Texture t = textures[material.indexAlbedo];
A = textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
A = sampleTexture( material.indexAlbedo, mip );
// alpha mode OPAQUE
if ( material.modeAlpha == 0 ) {
A.a = 1;
@ -75,16 +78,9 @@ void main() {
}
if ( A.a == 0 ) discard;
}
#if USE_LIGHTMAP
#if USE_LIGHTMAP && !DEFERRED_SAMPLING
if ( validTextureIndex( instance.lightmapID ) ) {
#if DEFERRED_SAMPLING
outUvs = inSt;
#else
const Texture t = textures[instance.lightmapID];
const float gamma = LIGHTMAP_GAMMA;
const vec4 L = pow(textureLod( samplerTextures[nonuniformEXT(t.index)], inSt, mip ), vec4(1.0 / gamma));
A.rgb *= L.rgb;
#endif
A.rgb *= sampleTexture( instance.lightmapID, inSt, mip ).rgb;
}
#endif
#endif
@ -92,7 +88,7 @@ void main() {
// sample normal
if ( validTextureIndex( material.indexNormal ) ) {
Texture t = textures[material.indexNormal];
N = inTBN * normalize( textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip ).xyz * 2.0 - vec3(1.0));
N = inTBN * normalize( sampleTexture( material.indexNormal, mip ).xyz * 2.0 - vec3(1.0));
}
#if 0
// sample metallic/roughness
@ -111,7 +107,8 @@ void main() {
#endif
outAlbedo = A * inColor;
#else
outUvs = wrap(inUv.xy);
outUvs.xy = surface.uv;
outUvs.zw = surface.st;
#endif
outNormals = encodeNormals( N );
outId = uvec2(drawID + 1, instanceID + 1);

View File

@ -76,7 +76,8 @@ void main() {
#else
const mat4 skinned = mat4(1.0);
#endif
const mat4 model = instances.length() <= 0 ? skinned : (instance.model * skinned);
// const mat4 model = instances.length() <= 0 ? skinned : (instance.model * skinned);
const mat4 model = instance.model * skinned;
outId = ivec4(drawID, instanceID, materialID, PushConstant.pass);
outColor = instance.color;

View File

@ -1,7 +1,7 @@
#version 450
#pragma shader_stage(compute)
#extension GL_EXT_nonuniform_qualifier : enable
//#extension GL_EXT_nonuniform_qualifier : enable
layout (constant_id = 0) const uint PASSES = 6;
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -1,8 +1,7 @@
#version 450
#pragma shader_stage(fragment)
#extension GL_EXT_nonuniform_qualifier : enable
#define FRAGMENT 1
#define CUBEMAPS 1
// #define MAX_TEXTURES TEXTURES
#define MAX_TEXTURES textures.length()
@ -39,12 +38,14 @@ void main() {
const float mip = mipLevel(inUv.xy);
const vec2 uv = wrap(inUv.xy);
vec4 A = vec4(0, 0, 0, 0);
surface.uv = uv;
const Material material = materials[materialID];
// sample albedo
if ( !validTextureIndex( material.indexAlbedo ) ) discard; {
const Texture t = textures[material.indexAlbedo];
A = textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
// const Texture t = textures[material.indexAlbedo];
// A = textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
A = sampleTexture( material.indexAlbedo, mip );
// alpha mode OPAQUE
if ( material.modeAlpha == 0 ) {
A.a = 1;

View File

@ -1,6 +1,6 @@
#version 450
#pragma shader_stage(fragment)
#extension GL_EXT_nonuniform_qualifier : enable
//#extension GL_EXT_nonuniform_qualifier : enable
#define DEFERRED_SAMPLING 0
#include "./voxelize.frag.h"

View File

@ -1,3 +1,4 @@
#define FRAGMENT 1
#define BLEND 1
#define DEPTH_TEST 0
#define CUBEMAPS 1
@ -44,7 +45,7 @@ layout (location = 8) flat in uvec4 inId;
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
layout (location = 2) out vec4 outUvs;
#else
layout (location = 2) out vec4 outAlbedo;
#endif
@ -65,6 +66,8 @@ void main() {
const uint materialID = int(inId.z);
const Instance instance = instances[instanceID];
const Material material = materials[materialID];
surface.uv = uv;
surface.st = inSt.xy;
const float M = material.factorMetallic;
const float R = material.factorRoughness;
@ -72,8 +75,9 @@ void main() {
// sample albedo
if ( !validTextureIndex( material.indexAlbedo ) ) discard; {
const Texture t = textures[material.indexAlbedo];
A = textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
// const Texture t = textures[material.indexAlbedo];
// A = textureLod( samplerTextures[nonuniformEXT(t.index)], mix( t.lerp.xy, t.lerp.zw, uv ), mip );
A = sampleTexture( material.indexAlbedo, mip );
// alpha mode OPAQUE
if ( material.modeAlpha == 0 ) {
A.a = 1;
@ -87,16 +91,9 @@ void main() {
}
if ( A.a == 0 ) discard;
}
#if USE_LIGHTMAP
#if USE_LIGHTMAP && !DEFERRED_SAMPLING
if ( validTextureIndex( instance.lightmapID ) ) {
#if DEFERRED_SAMPLING
outUvs = inSt;
#else
Texture t = textures[instance.lightmapID];
const float gamma = LIGHTMAP_GAMMA;
const vec4 L = pow(textureLod( samplerTextures[nonuniformEXT(t.index)], inSt, mip ), vec4(1.0 / gamma));
A.rgb *= L.rgb;
#endif
A.rgb *= sampleTexture( instance.lightmapID, inSt, mip ).rgb;
}
#endif

View File

@ -16,7 +16,7 @@ layout (location = 7) in flat Glyph inGlyph;
layout (location = 0) out uvec2 outId;
layout (location = 1) out vec2 outNormals;
#if DEFERRED_SAMPLING
layout (location = 2) out vec2 outUvs;
layout (location = 2) out vec4 outUvs;
#else
layout (location = 2) out vec4 outAlbedo;
#endif

View File

@ -2,18 +2,14 @@
"engine": {
"scenes": {
"start": "SS2",
"meshes": {
"interleave": false
},
"matrix": {
"reverseInfinite": false
},
"meshes": { "interleave": false },
"matrix": { "reverseInfinite": false },
"lights": {
"max": 64,
"max": 8,
"enabled": true
},
"shadows": {
"enabled": true,
"enabled": false,
"update": 2,
"max": 8,
"samples": 2,
@ -21,8 +17,8 @@
},
"textures": {
"max": {
"2D": 192,
"cube": 8,
"2D": 128,
"cube": 1,
"3D": 1
}
}
@ -69,7 +65,7 @@
},
"bullet": {
"iterations": 1,
"substeps": 1,
"substeps": 6,
"timescale": 1,
"multithreaded": false,
"pool size": {
@ -83,7 +79,7 @@
}
},
"audio": {
"mute": false,
"mute": true,
"buffers": {
"size": 16384,
"count": 2
@ -96,7 +92,7 @@
"streams by default": true
},
"memory pool": {
"enabled": true,
"enabled": false,
"subPools": true,
"alignment": 32,
"override": true,

View File

@ -118,6 +118,7 @@ void client::initialize() {
}
void client::tick() {
client::window.bufferInputs();
client::window.pollEvents();
if ( client::window.hasFocus() && client::config["window"]["mouse"]["center"].as<bool>() ) {

View File

@ -97,6 +97,8 @@ namespace ext {
// ray casting
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f& );
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, size_t& );
float UF_API rayCast( const pod::Vector3f&, const pod::Vector3f&, uf::Object*& );
// allows noclip
void UF_API activateCollision( pod::Bullet&, bool = true );

View File

@ -32,8 +32,6 @@ namespace ext {
uf::stl::string errorString( VkResult result );
VkSampleCountFlagBits sampleCount( uint8_t );
void* alignedAlloc( size_t size, size_t alignment );
void alignedFree(void* data);
typedef VmaAllocator Allocator;

View File

@ -53,6 +53,7 @@ namespace spec {
/*virtual*/ void UF_API requestFocus();
/*virtual*/ bool UF_API hasFocus() const;
// Update
/*virtual*/ void UF_API bufferInputs();
/*virtual*/ void UF_API processEvents();
static /*virtual*/ bool UF_API isKeyPressed(const uf::stl::string&);
bool UF_API pollEvents( bool block = false );

View File

@ -47,6 +47,7 @@ namespace spec {
void requestFocus();/* = 0;*/
bool hasFocus() const;/* = 0;*/
// Update
void bufferInputs();/* = 0;*/
void processEvents();/* = 0;*/
void pushEvent( const uf::Hooks::name_t& name, const uf::stl::string& payload );

View File

@ -41,6 +41,7 @@ namespace spec {
/*virtual*/ void UF_API_CALL requestFocus() {}
/*virtual*/ bool UF_API_CALL hasFocus() const { return false; }
// Update
/*virtual*/ void UF_API_CALL bufferInputs() {}
/*virtual*/ void UF_API_CALL processEvents() {}
};
}

View File

@ -60,6 +60,7 @@ namespace spec {
/*virtual*/ void UF_API_CALL requestFocus();
/*virtual*/ bool UF_API_CALL hasFocus() const;
// Update
/*virtual*/ void UF_API_CALL bufferInputs();
/*virtual*/ void UF_API_CALL processEvents();
static /*virtual*/ bool UF_API_CALL isKeyPressed(const uf::stl::string&);
bool UF_API_CALL pollEvents( bool block = false );

View File

@ -0,0 +1,283 @@
#pragma once
#include <uf/config.h>
#include <uf/utils/string/string.h>
namespace uf {
namespace inputs {
#if UF_WINDOW_KEYCODE_STRINGS
typedef uint_fast8_t key_t;
#define UF_KEY(x) __LINE__
#else
typedef const char* key_t;
#define UF_KEY(x) x
#endif
typedef bool state_t;
namespace kbm {
namespace enums {
constexpr key_t LShift = UF_KEY("LShift");
constexpr key_t RShift = UF_KEY("RShift");
constexpr key_t LControl = UF_KEY("LControl");
constexpr key_t RControl = UF_KEY("RControl");
constexpr key_t LAlt = UF_KEY("LAlt");
constexpr key_t RAlt = UF_KEY("RAlt");
constexpr key_t LSystem = UF_KEY("LSystem");
constexpr key_t RSystem = UF_KEY("RSystem");
constexpr key_t Menu = UF_KEY("Menu");
constexpr key_t SemiColon = UF_KEY("SemiColon");
constexpr key_t Slash = UF_KEY("Slash");
constexpr key_t Equal = UF_KEY("Equal");
constexpr key_t Dash = UF_KEY("Dash");
constexpr key_t LBracket = UF_KEY("LBracket");
constexpr key_t RBracket = UF_KEY("RBracket");
constexpr key_t Comma = UF_KEY("Comma");
constexpr key_t Period = UF_KEY("Period");
constexpr key_t Quote = UF_KEY("Quote");
constexpr key_t BackSlash = UF_KEY("BackSlash");
constexpr key_t Tilde = UF_KEY("Tilde");
constexpr key_t Escape = UF_KEY("Escape");
constexpr key_t Space = UF_KEY("Space");
constexpr key_t Enter = UF_KEY("Enter");
constexpr key_t BackSpace = UF_KEY("BackSpace");
constexpr key_t Tab = UF_KEY("Tab");
constexpr key_t PageUp = UF_KEY("PageUp");
constexpr key_t PageDown = UF_KEY("PageDown");
constexpr key_t End = UF_KEY("End");
constexpr key_t Home = UF_KEY("Home");
constexpr key_t Insert = UF_KEY("Insert");
constexpr key_t Delete = UF_KEY("Delete");
constexpr key_t Add = UF_KEY("Add");
constexpr key_t Subtract = UF_KEY("Subtract");
constexpr key_t Multiply = UF_KEY("Multiply");
constexpr key_t Divide = UF_KEY("Divide");
constexpr key_t Pause = UF_KEY("Pause");
constexpr key_t F1 = UF_KEY("F1");
constexpr key_t F2 = UF_KEY("F2");
constexpr key_t F3 = UF_KEY("F3");
constexpr key_t F4 = UF_KEY("F4");
constexpr key_t F5 = UF_KEY("F5");
constexpr key_t F6 = UF_KEY("F6");
constexpr key_t F7 = UF_KEY("F7");
constexpr key_t F8 = UF_KEY("F8");
constexpr key_t F9 = UF_KEY("F9");
constexpr key_t F10 = UF_KEY("F10");
constexpr key_t F11 = UF_KEY("F11");
constexpr key_t F12 = UF_KEY("F12");
constexpr key_t F13 = UF_KEY("F13");
constexpr key_t F14 = UF_KEY("F14");
constexpr key_t F15 = UF_KEY("F15");
constexpr key_t Left = UF_KEY("Left");
constexpr key_t Right = UF_KEY("Right");
constexpr key_t Up = UF_KEY("Up");
constexpr key_t Down = UF_KEY("Down");
constexpr key_t Numpad0 = UF_KEY("Numpad0");
constexpr key_t Numpad1 = UF_KEY("Numpad1");
constexpr key_t Numpad2 = UF_KEY("Numpad2");
constexpr key_t Numpad3 = UF_KEY("Numpad3");
constexpr key_t Numpad4 = UF_KEY("Numpad4");
constexpr key_t Numpad5 = UF_KEY("Numpad5");
constexpr key_t Numpad6 = UF_KEY("Numpad6");
constexpr key_t Numpad7 = UF_KEY("Numpad7");
constexpr key_t Numpad8 = UF_KEY("Numpad8");
constexpr key_t Numpad9 = UF_KEY("Numpad9");
constexpr key_t Q = UF_KEY("Q");
constexpr key_t W = UF_KEY("W");
constexpr key_t E = UF_KEY("E");
constexpr key_t R = UF_KEY("R");
constexpr key_t T = UF_KEY("T");
constexpr key_t Y = UF_KEY("Y");
constexpr key_t U = UF_KEY("U");
constexpr key_t I = UF_KEY("I");
constexpr key_t O = UF_KEY("O");
constexpr key_t P = UF_KEY("P");
constexpr key_t A = UF_KEY("A");
constexpr key_t S = UF_KEY("S");
constexpr key_t D = UF_KEY("D");
constexpr key_t F = UF_KEY("F");
constexpr key_t G = UF_KEY("G");
constexpr key_t H = UF_KEY("H");
constexpr key_t J = UF_KEY("J");
constexpr key_t K = UF_KEY("K");
constexpr key_t L = UF_KEY("L");
constexpr key_t Z = UF_KEY("Z");
constexpr key_t X = UF_KEY("X");
constexpr key_t C = UF_KEY("C");
constexpr key_t V = UF_KEY("V");
constexpr key_t B = UF_KEY("B");
constexpr key_t N = UF_KEY("N");
constexpr key_t M = UF_KEY("M");
constexpr key_t Num1 = UF_KEY("Num1");
constexpr key_t Num2 = UF_KEY("Num2");
constexpr key_t Num3 = UF_KEY("Num3");
constexpr key_t Num4 = UF_KEY("Num4");
constexpr key_t Num5 = UF_KEY("Num5");
constexpr key_t Num6 = UF_KEY("Num6");
constexpr key_t Num7 = UF_KEY("Num7");
constexpr key_t Num8 = UF_KEY("Num8");
constexpr key_t Num9 = UF_KEY("Num9");
constexpr key_t Num0 = UF_KEY("Num0");
};
namespace states {
extern UF_API state_t LShift;
extern UF_API state_t RShift;
extern UF_API state_t LAlt;
extern UF_API state_t RAlt;
extern UF_API state_t LControl;
extern UF_API state_t RControl;
extern UF_API state_t LSystem;
extern UF_API state_t RSystem;
extern UF_API state_t Menu;
extern UF_API state_t SemiColon;
extern UF_API state_t Slash;
extern UF_API state_t Equal;
extern UF_API state_t Dash;
extern UF_API state_t LBracket;
extern UF_API state_t RBracket;
extern UF_API state_t Comma;
extern UF_API state_t Period;
extern UF_API state_t Quote;
extern UF_API state_t BackSlash;
extern UF_API state_t Tilde;
extern UF_API state_t Escape;
extern UF_API state_t Space;
extern UF_API state_t Enter;
extern UF_API state_t BackSpace;
extern UF_API state_t Tab;
extern UF_API state_t PageUp;
extern UF_API state_t PageDown;
extern UF_API state_t End;
extern UF_API state_t Home;
extern UF_API state_t Insert;
extern UF_API state_t Delete;
extern UF_API state_t Add;
extern UF_API state_t Subtract;
extern UF_API state_t Multiply;
extern UF_API state_t Divide;
extern UF_API state_t Pause;
extern UF_API state_t F1;
extern UF_API state_t F2;
extern UF_API state_t F3;
extern UF_API state_t F4;
extern UF_API state_t F5;
extern UF_API state_t F6;
extern UF_API state_t F7;
extern UF_API state_t F8;
extern UF_API state_t F9;
extern UF_API state_t F10;
extern UF_API state_t F11;
extern UF_API state_t F12;
extern UF_API state_t F13;
extern UF_API state_t F14;
extern UF_API state_t F15;
extern UF_API state_t Left;
extern UF_API state_t Right;
extern UF_API state_t Up;
extern UF_API state_t Down;
extern UF_API state_t Numpad0;
extern UF_API state_t Numpad1;
extern UF_API state_t Numpad2;
extern UF_API state_t Numpad3;
extern UF_API state_t Numpad4;
extern UF_API state_t Numpad5;
extern UF_API state_t Numpad6;
extern UF_API state_t Numpad7;
extern UF_API state_t Numpad8;
extern UF_API state_t Numpad9;
extern UF_API state_t Q;
extern UF_API state_t W;
extern UF_API state_t E;
extern UF_API state_t R;
extern UF_API state_t T;
extern UF_API state_t Y;
extern UF_API state_t U;
extern UF_API state_t I;
extern UF_API state_t O;
extern UF_API state_t P;
extern UF_API state_t A;
extern UF_API state_t S;
extern UF_API state_t D;
extern UF_API state_t F;
extern UF_API state_t G;
extern UF_API state_t H;
extern UF_API state_t J;
extern UF_API state_t K;
extern UF_API state_t L;
extern UF_API state_t Z;
extern UF_API state_t X;
extern UF_API state_t C;
extern UF_API state_t V;
extern UF_API state_t B;
extern UF_API state_t N;
extern UF_API state_t M;
extern UF_API state_t Num1;
extern UF_API state_t Num2;
extern UF_API state_t Num3;
extern UF_API state_t Num4;
extern UF_API state_t Num5;
extern UF_API state_t Num6;
extern UF_API state_t Num7;
extern UF_API state_t Num8;
extern UF_API state_t Num9;
extern UF_API state_t Num0;
};
}
namespace controller {
namespace enums {
constexpr key_t R_DPAD_UP = UF_KEY("R_DPAD_UP");
constexpr key_t R_DPAD_DOWN = UF_KEY("R_DPAD_DOWN");
constexpr key_t R_DPAD_LEFT = UF_KEY("R_DPAD_LEFT");
constexpr key_t R_DPAD_RIGHT = UF_KEY("R_DPAD_RIGHT");
constexpr key_t R_JOYSTICK = UF_KEY("R_JOYSTICK");
constexpr key_t R_A = UF_KEY("R_A");
constexpr key_t L_DPAD_UP = UF_KEY("L_DPAD_UP");
constexpr key_t L_DPAD_DOWN = UF_KEY("L_DPAD_DOWN");
constexpr key_t L_DPAD_LEFT = UF_KEY("L_DPAD_LEFT");
constexpr key_t L_DPAD_RIGHT = UF_KEY("L_DPAD_RIGHT");
constexpr key_t L_JOYSTICK = UF_KEY("L_JOYSTICK");
constexpr key_t L_A = UF_KEY("L_A");
constexpr key_t DPAD_UP = UF_KEY("DPAD_UP");
constexpr key_t DPAD_DOWN = UF_KEY("DPAD_DOWN");
constexpr key_t DPAD_LEFT = UF_KEY("DPAD_LEFT");
constexpr key_t DPAD_RIGHT = UF_KEY("DPAD_RIGHT");
constexpr key_t A = UF_KEY("A");
constexpr key_t B = UF_KEY("B");
constexpr key_t X = UF_KEY("X");
constexpr key_t Y = UF_KEY("Y");
constexpr key_t L_TRIGGER = UF_KEY("L_TRIGGER");
constexpr key_t R_TRIGGER = UF_KEY("R_TRIGGER");
constexpr key_t START = UF_KEY("START");
};
namespace states {
extern UF_API state_t R_DPAD_UP;
extern UF_API state_t R_DPAD_DOWN;
extern UF_API state_t R_DPAD_LEFT;
extern UF_API state_t R_DPAD_RIGHT;
extern UF_API state_t R_JOYSTICK;
extern UF_API state_t R_A;
extern UF_API state_t L_DPAD_UP;
extern UF_API state_t L_DPAD_DOWN;
extern UF_API state_t L_DPAD_LEFT;
extern UF_API state_t L_DPAD_RIGHT;
extern UF_API state_t L_JOYSTICK;
extern UF_API state_t L_A;
extern UF_API state_t DPAD_UP;
extern UF_API state_t DPAD_DOWN;
extern UF_API state_t DPAD_LEFT;
extern UF_API state_t DPAD_RIGHT;
extern UF_API state_t A;
extern UF_API state_t B;
extern UF_API state_t X;
extern UF_API state_t Y;
extern UF_API state_t L_TRIGGER;
extern UF_API state_t R_TRIGGER;
extern UF_API state_t START;
};
}
}
}

View File

@ -21,7 +21,7 @@ namespace pod {
typedef uf::stl::vector<pod::Thread::function_t> container_t;
uint uid;
double limiter;
float limiter;
uf::stl::string name;
bool running, terminates;
@ -39,9 +39,10 @@ namespace pod {
namespace uf {
namespace thread {
extern UF_API double limiter;
extern UF_API float limiter;
extern UF_API uint workers;
extern UF_API std::thread::id mainThreadId;
extern UF_API bool async;
/* Acts on thread */
void UF_API start( pod::Thread& );
@ -51,6 +52,7 @@ namespace uf {
// void UF_API tick( pod::Thread&, const std::function<void()>& = NULL );
pod::Thread& UF_API fetchWorker( const uf::stl::string& name = "Aux" );
void UF_API batchWorker( const pod::Thread::function_t&, const uf::stl::string& name = "Aux" );
void UF_API batchWorkers( const uf::stl::vector<pod::Thread::function_t>&, bool = true, const uf::stl::string& name = "Aux" );
void UF_API add( pod::Thread&, const pod::Thread::function_t&, bool = false );
void UF_API process( pod::Thread& );

View File

@ -41,13 +41,16 @@ namespace uf {
bool UF_API_CALL hasFocus() const;
static pod::Vector2ui UF_API_CALL getResolution();
void UF_API_CALL switchToFullscreen( bool borderless = false );
// Update
#if defined(UF_USE_VULKAN) && UF_USE_VULKAN == 1
uf::stl::vector<uf::stl::string> getExtensions( bool validationEnabled = true );
void createSurface( VkInstance instance, VkSurfaceKHR& surface );
#endif
static bool focused;
static bool UF_API_CALL isKeyPressed(const uf::stl::string&);
void UF_API_CALL bufferInputs();
void UF_API_CALL processEvents();
bool UF_API_CALL pollEvents(bool block = false);
bool UF_API_CALL setActive( bool active = true );

View File

@ -59,6 +59,28 @@ namespace {
uf::Asset uf::Asset::masterAssetLoader;
void uf::Asset::processQueue() {
#if 0
auto& jobs = this->getComponent<std::queue<Job>>();
mutex.lock();
uf::stl::vector<std::function<void()>> tasks;
while ( !jobs.empty() ) {
auto job = jobs.front();
jobs.pop();
if ( job.uri == "" || job.callback == "" ) continue;
tasks.emplace_back([=](){
auto filename = job.type == "cache" ? this->cache(job.uri, job.hash, job.category) : this->load(job.uri, job.hash, job.category);
if ( filename == "" ) return;
uf::Serializer payload;
payload["filename"] = filename;
payload["hash"] = job.hash;
payload["category"] = job.category;
uf::hooks.call(job.callback, payload);
});
}
uf::thread::batchWorkers( tasks, false );
mutex.unlock();
#elif 0
auto& jobs = this->getComponent<std::queue<Job>>();
mutex.lock();
while ( !jobs.empty() ) {
@ -82,6 +104,56 @@ void uf::Asset::processQueue() {
}
}
mutex.unlock();
#elif 1
uf::thread::batchWorker( [&](){
mutex.lock();
auto jobs = std::move(this->getComponent<std::queue<Job>>());
while ( !jobs.empty() ) {
auto job = jobs.front();
jobs.pop();
uf::stl::string callback = job.callback;
uf::stl::string type = job.type;
uf::stl::string uri = job.uri;
uf::stl::string hash = job.hash;
uf::stl::string category = job.category;
if ( uri == "" || callback == "" ) {
continue;
}
uf::stl::string filename = type == "cache" ? this->cache(uri, hash, category) : this->load(uri, hash, category);
if ( callback != "" && filename != "" ) {
uf::Serializer payload;
payload["filename"] = filename;
payload["hash"] = hash;
payload["category"] = category;
uf::hooks.call(callback, payload);
}
}
mutex.unlock();
});
#elif 0
uf::thread::batchWorker( [&](){
mutex.lock();
auto jobs = std::move(this->getComponent<std::queue<Job>>());
uf::stl::vector<std::function<void()>> tasks;
while ( !jobs.empty() ) {
auto job = jobs.front();
jobs.pop();
if ( job.uri == "" || job.callback == "" ) continue;
tasks.emplace_back([=](){
auto filename = job.type == "cache" ? this->cache(job.uri, job.hash, job.category) : this->load(job.uri, job.hash, job.category);
if ( filename == "" ) return;
uf::Serializer payload;
payload["filename"] = filename;
payload["hash"] = job.hash;
payload["category"] = job.category;
uf::hooks.call(job.callback, payload);
});
}
uf::thread::batchWorkers( tasks, false );
mutex.unlock();
});
#endif
}
void uf::Asset::cache( const uf::stl::string& callback, const uf::stl::string& uri, const uf::stl::string& hash, const uf::stl::string& category ) {
mutex.lock();

View File

@ -365,22 +365,17 @@ void uf::graph::process( pod::Graph& graph ) {
{
const uf::stl::string lightmapFilename = graph.metadata["lightmap"].as<uf::stl::string>(UF_GRAPH_DEFAULT_LIGHTMAP);
// load lightmap, if requested
if ( lightmapFilename != "" && !uf::renderer::settings::experimental::deferredSampling ) {
if ( lightmapFilename != "" ) {
// check if valid filename, if not it's a texture name
uf::stl::string f = uf::io::sanitize( lightmapFilename, uf::io::directory( graph.name ) );
if ( uf::io::exists( f ) ) {
graph.metadata["baking"]["enabled"] = false;
// auto materialID = graph.materials.size();
auto textureID = graph.textures.size();
auto imageID = graph.images.size();
// auto& material = /*graph.storage*/uf::graph::storage.materials[graph.materials.emplace_back(f)];
auto& texture = /*graph.storage*/uf::graph::storage.textures[graph.textures.emplace_back(f)];
auto& image = /*graph.storage*/uf::graph::storage.images[graph.images.emplace_back(f)];
image.open( f, false );
// material.indexAlbedo = textureID;
texture.index = imageID;
for ( auto& name : graph.instances ) {
@ -393,10 +388,12 @@ void uf::graph::process( pod::Graph& graph ) {
primitive.instance.lightmapID = textureID;
}
}
graph.metadata["lightmapped"] = f;
graph.metadata["baking"]["enabled"] = false;
}
}
}
// add atlas
// setup textures
@ -405,7 +402,8 @@ void uf::graph::process( pod::Graph& graph ) {
auto& image = uf::graph::storage.images[keyName];
auto& texture = uf::graph::storage.texture2Ds[keyName];
if ( !texture.generated() ) {
if ( graph.metadata["filter"].as<uf::stl::string>() == "NEAREST" ) {
bool isLightmap = graph.metadata["lightmapped"].as<uf::stl::string>() == keyName;
if ( graph.metadata["filter"].as<uf::stl::string>() == "NEAREST" && !isLightmap ) {
texture.sampler.descriptor.filter.min = uf::renderer::enums::Filter::NEAREST;
texture.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::NEAREST;
}
@ -517,10 +515,9 @@ void uf::graph::process( pod::Graph& graph, int32_t index, uf::Object& parent )
// ignore pesky light_Orientation nodes
if ( uf::string::split( node.name, "_" ).back() == "Orientation" ) return;
// for dreamcast, ignore lights if we're baked
#if UF_USE_OPENGL
// if ( graph.metadata["lightmapped"].as<bool>() )
if ( graph.lights.count(node.name) > 0 ) return;
#endif
if ( graph.metadata["lightmapped"].as<bool>() && graph.metadata["lights"]["disable if lightmapped"].as<bool>(true) ) if ( graph.lights.count(node.name) > 0 ) return;
//UF_MSG_DEBUG( "Loading " << node.name );
// create child if requested
uf::Object* pointer = new uf::Object;

View File

@ -552,6 +552,24 @@ float UF_API ext::bullet::rayCast( const pod::Vector3f& from, const pod::Vector3
*/
return uf::vector::distance( from, pod::Vector3f{ res.m_hitPointWorld.getX(), res.m_hitPointWorld.getY(), res.m_hitPointWorld.getZ() } );
}
float UF_API ext::bullet::rayCast( const pod::Vector3f& from, const pod::Vector3f& to, uf::Object*& uid ) {
float pen = -1.0;
uid = 0;
btVector3 _from(from.x, from.y, from.z);
btVector3 _to(to.x, to.y, to.z);
btCollisionWorld::ClosestRayResultCallback res(_from, _to);
ext::bullet::dynamicsWorld->rayTest(_from, _to, res);
if ( !res.hasHit() ) return pen;
pen = uf::vector::distance( from, pod::Vector3f{ res.m_hitPointWorld.getX(), res.m_hitPointWorld.getY(), res.m_hitPointWorld.getZ() } );
const btCollisionObject* obj = res.m_collisionObject;
const btRigidBody* body = btRigidBody::upcast(obj);
if ( !body || !body->getMotionState() ) return pen;
uid = (uf::Object*) body->getUserPointer();
return pen;
}
void UF_API ext::bullet::debugDraw( uf::Object& object ) {
auto& mesh = ext::bullet::debugDrawer.getMesh();

View File

@ -153,13 +153,8 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
}
} else {
subpass = 0;
VkBool32 blendEnabled = VK_FALSE;
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
if ( true ) {
blendEnabled = VK_TRUE;
writeMask |= VK_COLOR_COMPONENT_A_BIT;
}
VkBool32 blendEnabled = VK_TRUE;
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState(
writeMask,

View File

@ -49,6 +49,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
size_t id, normals, uvs, albedo, depth, color, bright, scratch, output;
} attachments = {};
bool blend = true; // !ext::vulkan::settings::experimental::deferredSampling;
attachments.id = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */VK_FORMAT_R16G16_UINT,
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
@ -57,7 +58,8 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.samples = */msaa,
});
attachments.normals = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */VK_FORMAT_R16G16_SFLOAT,
// /*.format = */VK_FORMAT_R16G16_SFLOAT,
/*.format = */VK_FORMAT_R16G16_SNORM,
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
/*.blend = */false,
@ -65,7 +67,8 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
});
if ( ext::vulkan::settings::experimental::deferredSampling ) {
attachments.uvs = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */VK_FORMAT_R16G16_UNORM,
// /*.format = */VK_FORMAT_R32G32B32A32_SFLOAT,
/*.format = */VK_FORMAT_R16G16B16A16_UNORM,
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
/*.blend = */false,
@ -73,10 +76,10 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
});
} else {
attachments.albedo = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */VK_FORMAT_R8G8B8A8_UNORM,
/*.format = */ext::vulkan::settings::experimental::hdr ? VK_FORMAT_R16G16B16A16_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM,
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
/*.blend = */true,
/*.blend = */blend,
/*.samples = */msaa,
});
}
@ -91,21 +94,21 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
/*.blend =*/ true,
/*.blend =*/ blend,
/*.samples =*/ 1,
});
attachments.bright = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
/*.blend =*/ true,
/*.blend =*/ blend,
/*.samples =*/ 1,
});
attachments.scratch = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
/*.blend =*/ true,
/*.blend =*/ blend,
/*.samples =*/ 1,
});
@ -118,7 +121,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
swapchainAttachment.descriptor.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
swapchainAttachment.descriptor.aliased = true;
{
VkBool32 blendEnabled = VK_TRUE;
VkBool32 blendEnabled = blend;
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState(
writeMask,
@ -139,7 +142,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.format =*/ VK_FORMAT_R16G16B16A16_SFLOAT,
/*.layout = */ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage =*/ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
/*.blend =*/ true,
/*.blend =*/ blend,
/*.samples =*/ 1,
});
}
@ -172,20 +175,6 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.autoBuildPipeline =*/ false
);
}
#if 0
// Third pass: solely to transition
if ( settings::experimental::bloom ) {
renderTarget.addPass(
/*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
/*.colors =*/ {},
/*.inputs =*/ { attachments.color, attachments.bright, attachments.scratch, attachments.output, attachments.depth },
/*.resolve =*/{},
/*.depth = */ attachments.depth,
/*.layer = */eye,
/*.autoBuildPipeline =*/ false
);
}
#endif
} else {
// First pass: fill the G-Buffer
{
@ -211,20 +200,6 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.autoBuildPipeline =*/ false
);
}
#if 0
// Third pass: solely to transition
if ( settings::experimental::bloom ) {
renderTarget.addPass(
/*.*/ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
/*.colors =*/ {},
/*.inputs =*/ { attachments.color, attachments.bright, attachments.scratch, attachments.output, attachments.depth },
/*.resolve =*/{},
/*.depth = */ attachments.depth,
/*.layer = */eye,
/*.autoBuildPipeline =*/ false
);
}
#endif
}
}

View File

@ -213,7 +213,7 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
});
if ( !true && ext::vulkan::settings::experimental::deferredMode != "" ) {
attachments.uvs = renderTarget.attach(RenderTarget::Attachment::Descriptor{
/*.format = */VK_FORMAT_R16G16_UNORM,
/*.format = */VK_FORMAT_R16G16B16A16_UNORM,
/*.layout = */VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
/*.usage = */VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
/*.blend = */false,

View File

@ -123,19 +123,14 @@ size_t ext::vulkan::RenderTarget::attach( const Attachment::Descriptor& descript
}
{
VkBool32 blendEnabled = VK_FALSE;
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
if ( attachment->descriptor.blend ) {
blendEnabled = VK_TRUE;
writeMask |= VK_COLOR_COMPONENT_A_BIT;
}
VkBool32 blendEnabled = attachment->descriptor.blend ? VK_TRUE : VK_FALSE;
VkColorComponentFlags writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState(
writeMask,
blendEnabled
);
if ( blendEnabled == VK_TRUE ) {
if ( attachment->descriptor.blend ) {
blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;

View File

@ -421,6 +421,7 @@ void ext::vulkan::Texture::fromBuffers(
if ( std::find( queueFamilyIndices.begin(), queueFamilyIndices.end(), device.queueFamilyIndices.compute ) == queueFamilyIndices.end() ) queueFamilyIndices.emplace_back(device.queueFamilyIndices.compute);
if ( std::find( queueFamilyIndices.begin(), queueFamilyIndices.end(), device.queueFamilyIndices.transfer ) == queueFamilyIndices.end() ) queueFamilyIndices.emplace_back(device.queueFamilyIndices.transfer);
bool exclusive = device.queueFamilyIndices.graphics == 0 && device.queueFamilyIndices.present == 0 && device.queueFamilyIndices.compute == 0 && device.queueFamilyIndices.transfer == 0;
// Create optimal tiled target image
VkImageCreateInfo imageCreateInfo = ext::vulkan::initializers::imageCreateInfo();
imageCreateInfo.imageType = this->type;
@ -432,7 +433,7 @@ void ext::vulkan::Texture::fromBuffers(
imageCreateInfo.queueFamilyIndexCount = queueFamilyIndices.size();
imageCreateInfo.pQueueFamilyIndices = queueFamilyIndices.data();
// imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.sharingMode = VK_SHARING_MODE_CONCURRENT;
imageCreateInfo.sharingMode = exclusive ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCreateInfo.extent = { width, height, depth };
imageCreateInfo.usage = imageUsageFlags;

View File

@ -134,26 +134,6 @@ VkSampleCountFlagBits ext::vulkan::sampleCount( uint8_t count ) {
if ( counts & VK_SAMPLE_COUNT_2_BIT ) return VK_SAMPLE_COUNT_2_BIT;
return VK_SAMPLE_COUNT_1_BIT;
}
void* ext::vulkan::alignedAlloc( size_t size, size_t alignment ) {
void *data = nullptr;
#if defined(_MSC_VER) || defined(__MINGW32__)
data = _aligned_malloc(size, alignment);
#else
int res = posix_memalign(&data, alignment, size);
if (res != 0)
data = nullptr;
#endif
return data;
}
void ext::vulkan::alignedFree(void* data) {
#if defined(_MSC_VER) || defined(__MINGW32__)
_aligned_free(data);
#else
free(data);
#endif
}
bool ext::vulkan::hasRenderMode( const uf::stl::string& name, bool isName ) {
if ( isName && ext::vulkan::renderModesMap.count(name) > 0 ) return true;
for ( auto& renderMode: ext::vulkan::renderModes ) {

View File

@ -355,6 +355,9 @@ bool UF_API_CALL spec::dreamcast::Window::hasFocus() const {
#include <uf/utils/serialize/serializer.h>
void UF_API_CALL spec::dreamcast::Window::bufferInputs() {
}
void UF_API_CALL spec::dreamcast::Window::processEvents() {
if ( !::keyboard.device ) ::keyboard.device = maple_enum_type(0, MAPLE_FUNC_KEYBOARD);
if ( ::keyboard.device ) ::keyboard.state = (kbd_state_t*) maple_dev_status(::keyboard.device);

View File

@ -3,6 +3,7 @@
#include <uf/utils/string/utf.h>
#include <uf/utils/serialize/serializer.h>
#include <uf/utils/window/payloads.h>
#include <uf/utils/io/inputs.h>
#define UF_USE_USERDATA 1
#define UF_USE_JSON 1
@ -63,117 +64,124 @@ namespace {
uf::stl::vector<WPARAM> keys;
keys.reserve(8);
if ( GetAsyncKeyState('A') & 0x8000 ) keys.push_back('A');
if ( GetAsyncKeyState('B') & 0x8000 ) keys.push_back('B');
if ( GetAsyncKeyState('C') & 0x8000 ) keys.push_back('C');
if ( GetAsyncKeyState('D') & 0x8000 ) keys.push_back('D');
if ( GetAsyncKeyState('E') & 0x8000 ) keys.push_back('E');
if ( GetAsyncKeyState('F') & 0x8000 ) keys.push_back('F');
if ( GetAsyncKeyState('G') & 0x8000 ) keys.push_back('G');
if ( GetAsyncKeyState('H') & 0x8000 ) keys.push_back('H');
if ( GetAsyncKeyState('I') & 0x8000 ) keys.push_back('I');
if ( GetAsyncKeyState('J') & 0x8000 ) keys.push_back('J');
if ( GetAsyncKeyState('K') & 0x8000 ) keys.push_back('K');
if ( GetAsyncKeyState('L') & 0x8000 ) keys.push_back('L');
if ( GetAsyncKeyState('M') & 0x8000 ) keys.push_back('M');
if ( GetAsyncKeyState('N') & 0x8000 ) keys.push_back('N');
if ( GetAsyncKeyState('O') & 0x8000 ) keys.push_back('O');
if ( GetAsyncKeyState('P') & 0x8000 ) keys.push_back('P');
if ( GetAsyncKeyState('Q') & 0x8000 ) keys.push_back('Q');
if ( GetAsyncKeyState('R') & 0x8000 ) keys.push_back('R');
if ( GetAsyncKeyState('S') & 0x8000 ) keys.push_back('S');
if ( GetAsyncKeyState('T') & 0x8000 ) keys.push_back('T');
if ( GetAsyncKeyState('U') & 0x8000 ) keys.push_back('U');
if ( GetAsyncKeyState('V') & 0x8000 ) keys.push_back('V');
if ( GetAsyncKeyState('W') & 0x8000 ) keys.push_back('W');
if ( GetAsyncKeyState('X') & 0x8000 ) keys.push_back('X');
if ( GetAsyncKeyState('Y') & 0x8000 ) keys.push_back('Y');
if ( GetAsyncKeyState('Z') & 0x8000 ) keys.push_back('Z');
if ( GetAsyncKeyState('0') & 0x8000 ) keys.push_back('0');
if ( GetAsyncKeyState('1') & 0x8000 ) keys.push_back('1');
if ( GetAsyncKeyState('2') & 0x8000 ) keys.push_back('2');
if ( GetAsyncKeyState('3') & 0x8000 ) keys.push_back('3');
if ( GetAsyncKeyState('4') & 0x8000 ) keys.push_back('4');
if ( GetAsyncKeyState('5') & 0x8000 ) keys.push_back('5');
if ( GetAsyncKeyState('6') & 0x8000 ) keys.push_back('6');
if ( GetAsyncKeyState('7') & 0x8000 ) keys.push_back('7');
if ( GetAsyncKeyState('8') & 0x8000 ) keys.push_back('8');
if ( GetAsyncKeyState('9') & 0x8000 ) keys.push_back('9');
if ( GetAsyncKeyState(VK_ESCAPE) & 0x8000 ) keys.push_back(VK_ESCAPE);
if ( GetAsyncKeyState(VK_LCONTROL) & 0x8000 ) keys.push_back(VK_LCONTROL);
if ( GetAsyncKeyState(VK_LSHIFT) & 0x8000 ) keys.push_back(VK_LSHIFT);
if ( GetAsyncKeyState(VK_LMENU) & 0x8000 ) keys.push_back(VK_LMENU);
if ( GetAsyncKeyState(VK_LWIN) & 0x8000 ) keys.push_back(VK_LWIN);
if ( GetAsyncKeyState(VK_RCONTROL) & 0x8000 ) keys.push_back(VK_RCONTROL);
if ( GetAsyncKeyState(VK_RSHIFT) & 0x8000 ) keys.push_back(VK_RSHIFT);
if ( GetAsyncKeyState(VK_RMENU) & 0x8000 ) keys.push_back(VK_RMENU);
if ( GetAsyncKeyState(VK_RWIN) & 0x8000 ) keys.push_back(VK_RWIN);
if ( GetAsyncKeyState(VK_APPS) & 0x8000 ) keys.push_back(VK_APPS);
if ( GetAsyncKeyState(VK_OEM_4) & 0x8000 ) keys.push_back(VK_OEM_4);
if ( GetAsyncKeyState(VK_OEM_6) & 0x8000 ) keys.push_back(VK_OEM_6);
if ( GetAsyncKeyState(VK_OEM_1) & 0x8000 ) keys.push_back(VK_OEM_1);
if ( GetAsyncKeyState(VK_OEM_COMMA) & 0x8000 ) keys.push_back(VK_OEM_COMMA);
if ( GetAsyncKeyState(VK_OEM_PERIOD) & 0x8000 ) keys.push_back(VK_OEM_PERIOD);
if ( GetAsyncKeyState(VK_OEM_7) & 0x8000 ) keys.push_back(VK_OEM_7);
if ( GetAsyncKeyState(VK_OEM_2) & 0x8000 ) keys.push_back(VK_OEM_2);
if ( GetAsyncKeyState(VK_OEM_5) & 0x8000 ) keys.push_back(VK_OEM_5);
if ( GetAsyncKeyState(VK_OEM_3) & 0x8000 ) keys.push_back(VK_OEM_3);
if ( GetAsyncKeyState(VK_OEM_PLUS) & 0x8000 ) keys.push_back(VK_OEM_PLUS);
if ( GetAsyncKeyState(VK_OEM_MINUS) & 0x8000 ) keys.push_back(VK_OEM_MINUS);
if ( GetAsyncKeyState(VK_SPACE) & 0x8000 ) keys.push_back(VK_SPACE);
if ( GetAsyncKeyState(VK_RETURN) & 0x8000 ) keys.push_back(VK_RETURN);
if ( GetAsyncKeyState(VK_BACK) & 0x8000 ) keys.push_back(VK_BACK);
if ( GetAsyncKeyState(VK_TAB) & 0x8000 ) keys.push_back(VK_TAB);
if ( GetAsyncKeyState(VK_PRIOR) & 0x8000 ) keys.push_back(VK_PRIOR);
if ( GetAsyncKeyState(VK_NEXT) & 0x8000 ) keys.push_back(VK_NEXT);
if ( GetAsyncKeyState(VK_END) & 0x8000 ) keys.push_back(VK_END);
if ( GetAsyncKeyState(VK_HOME) & 0x8000 ) keys.push_back(VK_HOME);
if ( GetAsyncKeyState(VK_INSERT) & 0x8000 ) keys.push_back(VK_INSERT);
if ( GetAsyncKeyState(VK_DELETE) & 0x8000 ) keys.push_back(VK_DELETE);
if ( GetAsyncKeyState(VK_ADD) & 0x8000 ) keys.push_back(VK_ADD);
if ( GetAsyncKeyState(VK_SUBTRACT) & 0x8000 ) keys.push_back(VK_SUBTRACT);
if ( GetAsyncKeyState(VK_MULTIPLY) & 0x8000 ) keys.push_back(VK_MULTIPLY);
if ( GetAsyncKeyState(VK_DIVIDE) & 0x8000 ) keys.push_back(VK_DIVIDE);
if ( GetAsyncKeyState(VK_LEFT) & 0x8000 ) keys.push_back(VK_LEFT);
if ( GetAsyncKeyState(VK_RIGHT) & 0x8000 ) keys.push_back(VK_RIGHT);
if ( GetAsyncKeyState(VK_UP) & 0x8000 ) keys.push_back(VK_UP);
if ( GetAsyncKeyState(VK_DOWN) & 0x8000 ) keys.push_back(VK_DOWN);
if ( GetAsyncKeyState(VK_NUMPAD0) & 0x8000 ) keys.push_back(VK_NUMPAD0);
if ( GetAsyncKeyState(VK_NUMPAD1) & 0x8000 ) keys.push_back(VK_NUMPAD1);
if ( GetAsyncKeyState(VK_NUMPAD2) & 0x8000 ) keys.push_back(VK_NUMPAD2);
if ( GetAsyncKeyState(VK_NUMPAD3) & 0x8000 ) keys.push_back(VK_NUMPAD3);
if ( GetAsyncKeyState(VK_NUMPAD4) & 0x8000 ) keys.push_back(VK_NUMPAD4);
if ( GetAsyncKeyState(VK_NUMPAD5) & 0x8000 ) keys.push_back(VK_NUMPAD5);
if ( GetAsyncKeyState(VK_NUMPAD6) & 0x8000 ) keys.push_back(VK_NUMPAD6);
if ( GetAsyncKeyState(VK_NUMPAD7) & 0x8000 ) keys.push_back(VK_NUMPAD7);
if ( GetAsyncKeyState(VK_NUMPAD8) & 0x8000 ) keys.push_back(VK_NUMPAD8);
if ( GetAsyncKeyState(VK_NUMPAD9) & 0x8000 ) keys.push_back(VK_NUMPAD9);
if ( GetAsyncKeyState(VK_F1) & 0x8000 ) keys.push_back(VK_F1);
if ( GetAsyncKeyState(VK_F2) & 0x8000 ) keys.push_back(VK_F2);
if ( GetAsyncKeyState(VK_F3) & 0x8000 ) keys.push_back(VK_F3);
if ( GetAsyncKeyState(VK_F4) & 0x8000 ) keys.push_back(VK_F4);
if ( GetAsyncKeyState(VK_F5) & 0x8000 ) keys.push_back(VK_F5);
if ( GetAsyncKeyState(VK_F6) & 0x8000 ) keys.push_back(VK_F6);
if ( GetAsyncKeyState(VK_F7) & 0x8000 ) keys.push_back(VK_F7);
if ( GetAsyncKeyState(VK_F8) & 0x8000 ) keys.push_back(VK_F8);
if ( GetAsyncKeyState(VK_F9) & 0x8000 ) keys.push_back(VK_F9);
if ( GetAsyncKeyState(VK_F10) & 0x8000 ) keys.push_back(VK_F10);
if ( GetAsyncKeyState(VK_F11) & 0x8000 ) keys.push_back(VK_F11);
if ( GetAsyncKeyState(VK_F12) & 0x8000 ) keys.push_back(VK_F12);
if ( GetAsyncKeyState(VK_F13) & 0x8000 ) keys.push_back(VK_F13);
if ( GetAsyncKeyState(VK_F14) & 0x8000 ) keys.push_back(VK_F14);
if ( GetAsyncKeyState(VK_F15) & 0x8000 ) keys.push_back(VK_F15);
if ( GetAsyncKeyState(VK_PAUSE) & 0x8000 ) keys.push_back(VK_PAUSE);
if ( uf::inputs::kbm::states::LShift ) keys.emplace_back(VK_LSHIFT);
if ( uf::inputs::kbm::states::RShift ) keys.emplace_back(VK_RSHIFT);
if ( uf::inputs::kbm::states::LAlt ) keys.emplace_back(VK_LMENU);
if ( uf::inputs::kbm::states::RAlt ) keys.emplace_back(VK_RMENU);
if ( uf::inputs::kbm::states::LControl ) keys.emplace_back(VK_LCONTROL);
if ( uf::inputs::kbm::states::RControl ) keys.emplace_back(VK_RCONTROL);
if ( uf::inputs::kbm::states::LSystem ) keys.emplace_back(VK_LWIN);
if ( uf::inputs::kbm::states::RSystem ) keys.emplace_back(VK_RWIN);
if ( uf::inputs::kbm::states::Menu ) keys.emplace_back(VK_APPS);
if ( uf::inputs::kbm::states::SemiColon ) keys.emplace_back(VK_OEM_1);
if ( uf::inputs::kbm::states::Slash ) keys.emplace_back(VK_OEM_2);
if ( uf::inputs::kbm::states::Equal ) keys.emplace_back(VK_OEM_PLUS);
if ( uf::inputs::kbm::states::Dash ) keys.emplace_back(VK_OEM_MINUS);
if ( uf::inputs::kbm::states::LBracket ) keys.emplace_back(VK_OEM_4);
if ( uf::inputs::kbm::states::RBracket ) keys.emplace_back(VK_OEM_6);
if ( uf::inputs::kbm::states::Comma ) keys.emplace_back(VK_OEM_COMMA);
if ( uf::inputs::kbm::states::Period ) keys.emplace_back(VK_OEM_PERIOD);
if ( uf::inputs::kbm::states::Quote ) keys.emplace_back(VK_OEM_7);
if ( uf::inputs::kbm::states::BackSlash ) keys.emplace_back(VK_OEM_5);
if ( uf::inputs::kbm::states::Tilde ) keys.emplace_back(VK_OEM_3);
if ( uf::inputs::kbm::states::Escape ) keys.emplace_back(VK_ESCAPE);
if ( uf::inputs::kbm::states::Space ) keys.emplace_back(VK_SPACE);
if ( uf::inputs::kbm::states::Enter ) keys.emplace_back(VK_RETURN);
if ( uf::inputs::kbm::states::BackSpace ) keys.emplace_back(VK_BACK);
if ( uf::inputs::kbm::states::Tab ) keys.emplace_back(VK_TAB);
if ( uf::inputs::kbm::states::PageUp ) keys.emplace_back(VK_PRIOR);
if ( uf::inputs::kbm::states::PageDown ) keys.emplace_back(VK_NEXT);
if ( uf::inputs::kbm::states::End ) keys.emplace_back(VK_END);
if ( uf::inputs::kbm::states::Home ) keys.emplace_back(VK_HOME);
if ( uf::inputs::kbm::states::Insert ) keys.emplace_back(VK_INSERT);
if ( uf::inputs::kbm::states::Delete ) keys.emplace_back(VK_DELETE);
if ( uf::inputs::kbm::states::Add ) keys.emplace_back(VK_ADD);
if ( uf::inputs::kbm::states::Subtract ) keys.emplace_back(VK_SUBTRACT);
if ( uf::inputs::kbm::states::Multiply ) keys.emplace_back(VK_MULTIPLY);
if ( uf::inputs::kbm::states::Divide ) keys.emplace_back(VK_DIVIDE);
if ( uf::inputs::kbm::states::Pause ) keys.emplace_back(VK_PAUSE);
if ( uf::inputs::kbm::states::F1 ) keys.emplace_back(VK_F1);
if ( uf::inputs::kbm::states::F2 ) keys.emplace_back(VK_F2);
if ( uf::inputs::kbm::states::F3 ) keys.emplace_back(VK_F3);
if ( uf::inputs::kbm::states::F4 ) keys.emplace_back(VK_F4);
if ( uf::inputs::kbm::states::F5 ) keys.emplace_back(VK_F5);
if ( uf::inputs::kbm::states::F6 ) keys.emplace_back(VK_F6);
if ( uf::inputs::kbm::states::F7 ) keys.emplace_back(VK_F7);
if ( uf::inputs::kbm::states::F8 ) keys.emplace_back(VK_F8);
if ( uf::inputs::kbm::states::F9 ) keys.emplace_back(VK_F9);
if ( uf::inputs::kbm::states::F10 ) keys.emplace_back(VK_F10);
if ( uf::inputs::kbm::states::F11 ) keys.emplace_back(VK_F11);
if ( uf::inputs::kbm::states::F12 ) keys.emplace_back(VK_F12);
if ( uf::inputs::kbm::states::F13 ) keys.emplace_back(VK_F13);
if ( uf::inputs::kbm::states::F14 ) keys.emplace_back(VK_F14);
if ( uf::inputs::kbm::states::F15 ) keys.emplace_back(VK_F15);
if ( uf::inputs::kbm::states::Left ) keys.emplace_back(VK_LEFT);
if ( uf::inputs::kbm::states::Right ) keys.emplace_back(VK_RIGHT);
if ( uf::inputs::kbm::states::Up ) keys.emplace_back(VK_UP);
if ( uf::inputs::kbm::states::Down ) keys.emplace_back(VK_DOWN);
if ( uf::inputs::kbm::states::Numpad0 ) keys.emplace_back(VK_NUMPAD0);
if ( uf::inputs::kbm::states::Numpad1 ) keys.emplace_back(VK_NUMPAD1);
if ( uf::inputs::kbm::states::Numpad2 ) keys.emplace_back(VK_NUMPAD2);
if ( uf::inputs::kbm::states::Numpad3 ) keys.emplace_back(VK_NUMPAD3);
if ( uf::inputs::kbm::states::Numpad4 ) keys.emplace_back(VK_NUMPAD4);
if ( uf::inputs::kbm::states::Numpad5 ) keys.emplace_back(VK_NUMPAD5);
if ( uf::inputs::kbm::states::Numpad6 ) keys.emplace_back(VK_NUMPAD6);
if ( uf::inputs::kbm::states::Numpad7 ) keys.emplace_back(VK_NUMPAD7);
if ( uf::inputs::kbm::states::Numpad8 ) keys.emplace_back(VK_NUMPAD8);
if ( uf::inputs::kbm::states::Numpad9 ) keys.emplace_back(VK_NUMPAD9);
if ( uf::inputs::kbm::states::Q ) keys.emplace_back('Q');
if ( uf::inputs::kbm::states::W ) keys.emplace_back('W');
if ( uf::inputs::kbm::states::E ) keys.emplace_back('E');
if ( uf::inputs::kbm::states::R ) keys.emplace_back('R');
if ( uf::inputs::kbm::states::T ) keys.emplace_back('T');
if ( uf::inputs::kbm::states::Y ) keys.emplace_back('Y');
if ( uf::inputs::kbm::states::U ) keys.emplace_back('U');
if ( uf::inputs::kbm::states::I ) keys.emplace_back('I');
if ( uf::inputs::kbm::states::O ) keys.emplace_back('O');
if ( uf::inputs::kbm::states::P ) keys.emplace_back('P');
if ( uf::inputs::kbm::states::A ) keys.emplace_back('A');
if ( uf::inputs::kbm::states::S ) keys.emplace_back('S');
if ( uf::inputs::kbm::states::D ) keys.emplace_back('D');
if ( uf::inputs::kbm::states::F ) keys.emplace_back('F');
if ( uf::inputs::kbm::states::G ) keys.emplace_back('G');
if ( uf::inputs::kbm::states::H ) keys.emplace_back('H');
if ( uf::inputs::kbm::states::J ) keys.emplace_back('J');
if ( uf::inputs::kbm::states::K ) keys.emplace_back('K');
if ( uf::inputs::kbm::states::L ) keys.emplace_back('L');
if ( uf::inputs::kbm::states::Z ) keys.emplace_back('Z');
if ( uf::inputs::kbm::states::X ) keys.emplace_back('X');
if ( uf::inputs::kbm::states::C ) keys.emplace_back('C');
if ( uf::inputs::kbm::states::V ) keys.emplace_back('V');
if ( uf::inputs::kbm::states::B ) keys.emplace_back('B');
if ( uf::inputs::kbm::states::N ) keys.emplace_back('N');
if ( uf::inputs::kbm::states::M ) keys.emplace_back('M');
if ( uf::inputs::kbm::states::Num1 ) keys.emplace_back('1');
if ( uf::inputs::kbm::states::Num2 ) keys.emplace_back('2');
if ( uf::inputs::kbm::states::Num3 ) keys.emplace_back('3');
if ( uf::inputs::kbm::states::Num4 ) keys.emplace_back('4');
if ( uf::inputs::kbm::states::Num5 ) keys.emplace_back('5');
if ( uf::inputs::kbm::states::Num6 ) keys.emplace_back('6');
if ( uf::inputs::kbm::states::Num7 ) keys.emplace_back('7');
if ( uf::inputs::kbm::states::Num8 ) keys.emplace_back('8');
if ( uf::inputs::kbm::states::Num9 ) keys.emplace_back('9');
if ( uf::inputs::kbm::states::Num0 ) keys.emplace_back('0');
if ( GetAsyncKeyState(VK_LBUTTON) & 0x8000 ) keys.push_back(VK_LBUTTON);
if ( GetAsyncKeyState(VK_RBUTTON) & 0x8000 ) keys.push_back(VK_RBUTTON);
if ( GetAsyncKeyState(VK_MBUTTON) & 0x8000 ) keys.push_back(VK_MBUTTON);
if ( GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ) keys.push_back(VK_XBUTTON1);
if ( GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ) keys.push_back(VK_XBUTTON2);
return keys;
}
uf::stl::string _GetKeyName( WPARAM key, LPARAM flags = 0 ) {
#if 1
switch ( key ) {
// Check the scancode to distinguish between left and right shift
case VK_SHIFT: {
@ -291,117 +299,6 @@ namespace {
case '9': return "Num9";
case '0': return "Num0";
}
#else
switch ( key ) {
case 'A': return "A";
case 'B': return "B";
case 'C': return "C";
case 'D': return "D";
case 'E': return "E";
case 'F': return "F";
case 'G': return "G";
case 'H': return "H";
case 'I': return "I";
case 'J': return "J";
case 'K': return "K";
case 'L': return "L";
case 'M': return "M";
case 'N': return "N";
case 'O': return "O";
case 'P': return "P";
case 'Q': return "Q";
case 'R': return "R";
case 'S': return "S";
case 'T': return "T";
case 'U': return "U";
case 'V': return "V";
case 'W': return "W";
case 'X': return "X";
case 'Y': return "Y";
case 'Z': return "Z";
case '0': return "0";
case '1': return "1";
case '2': return "2";
case '3': return "3";
case '4': return "4";
case '5': return "5";
case '6': return "6";
case '7': return "7";
case '8': return "8";
case '9': return "9";
case VK_ESCAPE: return "Escape";
case VK_LCONTROL: return "LControl";
case VK_LSHIFT: return "LShift";
case VK_LMENU: return "LAlt";
case VK_LWIN: return "LSystem";
case VK_RCONTROL: return "RControl";
case VK_RSHIFT: return "RShift";
case VK_RMENU: return "RAlt";
case VK_RWIN: return "RSystem";
case VK_APPS: return "Apps";
case VK_OEM_4: return "OEM4";
case VK_OEM_6: return "OEM6";
case VK_OEM_1: return "OEM1";
case VK_OEM_COMMA: return "OEMComma";
case VK_OEM_PERIOD: return "OEMPeriod";
case VK_OEM_7: return "OEM7";
case VK_OEM_2: return "OEM2";
case VK_OEM_5: return "OEM5";
case VK_OEM_3: return "OEM3";
case VK_OEM_PLUS: return "OEM+";
case VK_OEM_MINUS: return "OEM-";
case VK_SPACE: return " ";
case VK_RETURN: return "Enter";
case VK_BACK: return "Back";
case VK_TAB: return "Tab";
case VK_PRIOR: return "Prior";
case VK_NEXT: return "Next";
case VK_END: return "End";
case VK_HOME: return "Home";
case VK_INSERT: return "Insert";
case VK_DELETE: return "Delete";
case VK_ADD: return "+";
case VK_SUBTRACT: return "-";
case VK_MULTIPLY: return "*";
case VK_DIVIDE: return "/";
case VK_LEFT: return "Left";
case VK_RIGHT: return "Right";
case VK_UP: return "Up";
case VK_DOWN: return "Down";
case VK_NUMPAD0: return "Num0";
case VK_NUMPAD1: return "Num1";
case VK_NUMPAD2: return "Num2";
case VK_NUMPAD3: return "Num3";
case VK_NUMPAD4: return "Num4";
case VK_NUMPAD5: return "Num5";
case VK_NUMPAD6: return "Num6";
case VK_NUMPAD7: return "Num7";
case VK_NUMPAD8: return "Num8";
case VK_NUMPAD9: return "Num9";
case VK_F1: return "F1";
case VK_F2: return "F2";
case VK_F3: return "F3";
case VK_F4: return "F4";
case VK_F5: return "F5";
case VK_F6: return "F6";
case VK_F7: return "F7";
case VK_F8: return "F8";
case VK_F9: return "F9";
case VK_F10: return "F10";
case VK_F11: return "F11";
case VK_F12: return "F12";
case VK_F13: return "F13";
case VK_F14: return "F14";
case VK_F15: return "F15";
case VK_PAUSE: return "Pause";
case VK_LBUTTON: return "LeftMouse";
case VK_RBUTTON: return "RightMouse";
case VK_MBUTTON: return "MiddleMouse";
case VK_XBUTTON1: return "XButton1";
case VK_XBUTTON2: return "XButton2";
}
#endif
return std::to_string((int) key);
}
uf::stl::string GetKeyName( WPARAM key, LPARAM flags = 0 ) {
@ -468,6 +365,7 @@ namespace {
else if ( name == "OEM+" ) return VK_OEM_PLUS;
else if ( name == "OEM-" ) return VK_OEM_MINUS;
else if ( name == " " ) return VK_SPACE;
else if ( name == "SPACE" ) return VK_SPACE;
else if ( name == "ENTER" ) return VK_RETURN;
else if ( name == "BACK" ) return VK_BACK;
else if ( name == "TAB" ) return VK_TAB;
@ -511,7 +409,6 @@ namespace {
else if ( name == "F14" ) return VK_F14;
else if ( name == "F15" ) return VK_F15;
else if ( name == "PAUSE" ) return VK_PAUSE;
else if ( name == "LEFTMOUSE" ) return VK_LBUTTON;
else if ( name == "RIGHTMOUSE" ) return VK_RBUTTON;
else if ( name == "MIDDLEMOUSE" ) return VK_MBUTTON;
@ -764,6 +661,121 @@ bool UF_API_CALL spec::win32::Window::hasFocus() const {
return this->m_handle == GetForegroundWindow();
}
void UF_API_CALL spec::win32::Window::bufferInputs() {
uf::inputs::kbm::states::LShift = GetAsyncKeyState(VK_LSHIFT) & 0x8000;
uf::inputs::kbm::states::RShift = GetAsyncKeyState(VK_RSHIFT) & 0x8000;
uf::inputs::kbm::states::LAlt = GetAsyncKeyState(VK_LMENU) & 0x8000;
uf::inputs::kbm::states::RAlt = GetAsyncKeyState(VK_RMENU) & 0x8000;
uf::inputs::kbm::states::LControl = GetAsyncKeyState(VK_LCONTROL) & 0x8000;
uf::inputs::kbm::states::RControl = GetAsyncKeyState(VK_RCONTROL) & 0x8000;
uf::inputs::kbm::states::LSystem = GetAsyncKeyState(VK_LWIN) & 0x8000;
uf::inputs::kbm::states::RSystem = GetAsyncKeyState(VK_RWIN) & 0x8000;
uf::inputs::kbm::states::Menu = GetAsyncKeyState(VK_APPS) & 0x8000;
uf::inputs::kbm::states::SemiColon = GetAsyncKeyState(VK_OEM_1) & 0x8000;
uf::inputs::kbm::states::Slash = GetAsyncKeyState(VK_OEM_2) & 0x8000;
uf::inputs::kbm::states::Equal = GetAsyncKeyState(VK_OEM_PLUS) & 0x8000;
uf::inputs::kbm::states::Dash = GetAsyncKeyState(VK_OEM_MINUS) & 0x8000;
uf::inputs::kbm::states::LBracket = GetAsyncKeyState(VK_OEM_4) & 0x8000;
uf::inputs::kbm::states::RBracket = GetAsyncKeyState(VK_OEM_6) & 0x8000;
uf::inputs::kbm::states::Comma = GetAsyncKeyState(VK_OEM_COMMA) & 0x8000;
uf::inputs::kbm::states::Period = GetAsyncKeyState(VK_OEM_PERIOD) & 0x8000;
uf::inputs::kbm::states::Quote = GetAsyncKeyState(VK_OEM_7) & 0x8000;
uf::inputs::kbm::states::BackSlash = GetAsyncKeyState(VK_OEM_5) & 0x8000;
uf::inputs::kbm::states::Tilde = GetAsyncKeyState(VK_OEM_3) & 0x8000;
uf::inputs::kbm::states::Escape = GetAsyncKeyState(VK_ESCAPE) & 0x8000;
uf::inputs::kbm::states::Space = GetAsyncKeyState(VK_SPACE) & 0x8000;
uf::inputs::kbm::states::Enter = GetAsyncKeyState(VK_RETURN) & 0x8000;
uf::inputs::kbm::states::BackSpace = GetAsyncKeyState(VK_BACK) & 0x8000;
uf::inputs::kbm::states::Tab = GetAsyncKeyState(VK_TAB) & 0x8000;
uf::inputs::kbm::states::PageUp = GetAsyncKeyState(VK_PRIOR) & 0x8000;
uf::inputs::kbm::states::PageDown = GetAsyncKeyState(VK_NEXT) & 0x8000;
uf::inputs::kbm::states::End = GetAsyncKeyState(VK_END) & 0x8000;
uf::inputs::kbm::states::Home = GetAsyncKeyState(VK_HOME) & 0x8000;
uf::inputs::kbm::states::Insert = GetAsyncKeyState(VK_INSERT) & 0x8000;
uf::inputs::kbm::states::Delete = GetAsyncKeyState(VK_DELETE) & 0x8000;
uf::inputs::kbm::states::Add = GetAsyncKeyState(VK_ADD) & 0x8000;
uf::inputs::kbm::states::Subtract = GetAsyncKeyState(VK_SUBTRACT) & 0x8000;
uf::inputs::kbm::states::Multiply = GetAsyncKeyState(VK_MULTIPLY) & 0x8000;
uf::inputs::kbm::states::Divide = GetAsyncKeyState(VK_DIVIDE) & 0x8000;
uf::inputs::kbm::states::Pause = GetAsyncKeyState(VK_PAUSE) & 0x8000;
uf::inputs::kbm::states::F1 = GetAsyncKeyState(VK_F1) & 0x8000;
uf::inputs::kbm::states::F2 = GetAsyncKeyState(VK_F2) & 0x8000;
uf::inputs::kbm::states::F3 = GetAsyncKeyState(VK_F3) & 0x8000;
uf::inputs::kbm::states::F4 = GetAsyncKeyState(VK_F4) & 0x8000;
uf::inputs::kbm::states::F5 = GetAsyncKeyState(VK_F5) & 0x8000;
uf::inputs::kbm::states::F6 = GetAsyncKeyState(VK_F6) & 0x8000;
uf::inputs::kbm::states::F7 = GetAsyncKeyState(VK_F7) & 0x8000;
uf::inputs::kbm::states::F8 = GetAsyncKeyState(VK_F8) & 0x8000;
uf::inputs::kbm::states::F9 = GetAsyncKeyState(VK_F9) & 0x8000;
uf::inputs::kbm::states::F10 = GetAsyncKeyState(VK_F10) & 0x8000;
uf::inputs::kbm::states::F11 = GetAsyncKeyState(VK_F11) & 0x8000;
uf::inputs::kbm::states::F12 = GetAsyncKeyState(VK_F12) & 0x8000;
uf::inputs::kbm::states::F13 = GetAsyncKeyState(VK_F13) & 0x8000;
uf::inputs::kbm::states::F14 = GetAsyncKeyState(VK_F14) & 0x8000;
uf::inputs::kbm::states::F15 = GetAsyncKeyState(VK_F15) & 0x8000;
uf::inputs::kbm::states::Left = GetAsyncKeyState(VK_LEFT) & 0x8000;
uf::inputs::kbm::states::Right = GetAsyncKeyState(VK_RIGHT) & 0x8000;
uf::inputs::kbm::states::Up = GetAsyncKeyState(VK_UP) & 0x8000;
uf::inputs::kbm::states::Down = GetAsyncKeyState(VK_DOWN) & 0x8000;
uf::inputs::kbm::states::Numpad0 = GetAsyncKeyState(VK_NUMPAD0) & 0x8000;
uf::inputs::kbm::states::Numpad1 = GetAsyncKeyState(VK_NUMPAD1) & 0x8000;
uf::inputs::kbm::states::Numpad2 = GetAsyncKeyState(VK_NUMPAD2) & 0x8000;
uf::inputs::kbm::states::Numpad3 = GetAsyncKeyState(VK_NUMPAD3) & 0x8000;
uf::inputs::kbm::states::Numpad4 = GetAsyncKeyState(VK_NUMPAD4) & 0x8000;
uf::inputs::kbm::states::Numpad5 = GetAsyncKeyState(VK_NUMPAD5) & 0x8000;
uf::inputs::kbm::states::Numpad6 = GetAsyncKeyState(VK_NUMPAD6) & 0x8000;
uf::inputs::kbm::states::Numpad7 = GetAsyncKeyState(VK_NUMPAD7) & 0x8000;
uf::inputs::kbm::states::Numpad8 = GetAsyncKeyState(VK_NUMPAD8) & 0x8000;
uf::inputs::kbm::states::Numpad9 = GetAsyncKeyState(VK_NUMPAD9) & 0x8000;
uf::inputs::kbm::states::Q = GetAsyncKeyState('Q') & 0x8000;
uf::inputs::kbm::states::W = GetAsyncKeyState('W') & 0x8000;
uf::inputs::kbm::states::E = GetAsyncKeyState('E') & 0x8000;
uf::inputs::kbm::states::R = GetAsyncKeyState('R') & 0x8000;
uf::inputs::kbm::states::T = GetAsyncKeyState('T') & 0x8000;
uf::inputs::kbm::states::Y = GetAsyncKeyState('Y') & 0x8000;
uf::inputs::kbm::states::U = GetAsyncKeyState('U') & 0x8000;
uf::inputs::kbm::states::I = GetAsyncKeyState('I') & 0x8000;
uf::inputs::kbm::states::O = GetAsyncKeyState('O') & 0x8000;
uf::inputs::kbm::states::P = GetAsyncKeyState('P') & 0x8000;
uf::inputs::kbm::states::A = GetAsyncKeyState('A') & 0x8000;
uf::inputs::kbm::states::S = GetAsyncKeyState('S') & 0x8000;
uf::inputs::kbm::states::D = GetAsyncKeyState('D') & 0x8000;
uf::inputs::kbm::states::F = GetAsyncKeyState('F') & 0x8000;
uf::inputs::kbm::states::G = GetAsyncKeyState('G') & 0x8000;
uf::inputs::kbm::states::H = GetAsyncKeyState('H') & 0x8000;
uf::inputs::kbm::states::J = GetAsyncKeyState('J') & 0x8000;
uf::inputs::kbm::states::K = GetAsyncKeyState('K') & 0x8000;
uf::inputs::kbm::states::L = GetAsyncKeyState('L') & 0x8000;
uf::inputs::kbm::states::Z = GetAsyncKeyState('Z') & 0x8000;
uf::inputs::kbm::states::X = GetAsyncKeyState('X') & 0x8000;
uf::inputs::kbm::states::C = GetAsyncKeyState('C') & 0x8000;
uf::inputs::kbm::states::V = GetAsyncKeyState('V') & 0x8000;
uf::inputs::kbm::states::B = GetAsyncKeyState('B') & 0x8000;
uf::inputs::kbm::states::N = GetAsyncKeyState('N') & 0x8000;
uf::inputs::kbm::states::M = GetAsyncKeyState('M') & 0x8000;
uf::inputs::kbm::states::Num1 = GetAsyncKeyState('1') & 0x8000;
uf::inputs::kbm::states::Num2 = GetAsyncKeyState('2') & 0x8000;
uf::inputs::kbm::states::Num3 = GetAsyncKeyState('3') & 0x8000;
uf::inputs::kbm::states::Num4 = GetAsyncKeyState('4') & 0x8000;
uf::inputs::kbm::states::Num5 = GetAsyncKeyState('5') & 0x8000;
uf::inputs::kbm::states::Num6 = GetAsyncKeyState('6') & 0x8000;
uf::inputs::kbm::states::Num7 = GetAsyncKeyState('7') & 0x8000;
uf::inputs::kbm::states::Num8 = GetAsyncKeyState('8') & 0x8000;
uf::inputs::kbm::states::Num9 = GetAsyncKeyState('9') & 0x8000;
uf::inputs::kbm::states::Num0 = GetAsyncKeyState('0') & 0x8000;
}
void UF_API_CALL spec::win32::Window::processEvents() {
if ( !this->m_callback ) {
MSG message;

View File

@ -0,0 +1,127 @@
#include <uf/utils/io/inputs.h>
uf::inputs::state_t uf::inputs::kbm::states::LShift = false;
uf::inputs::state_t uf::inputs::kbm::states::RShift = false;
uf::inputs::state_t uf::inputs::kbm::states::LAlt = false;
uf::inputs::state_t uf::inputs::kbm::states::RAlt = false;
uf::inputs::state_t uf::inputs::kbm::states::LControl = false;
uf::inputs::state_t uf::inputs::kbm::states::RControl = false;
uf::inputs::state_t uf::inputs::kbm::states::LSystem = false;
uf::inputs::state_t uf::inputs::kbm::states::RSystem = false;
uf::inputs::state_t uf::inputs::kbm::states::Menu = false;
uf::inputs::state_t uf::inputs::kbm::states::SemiColon = false;
uf::inputs::state_t uf::inputs::kbm::states::Slash = false;
uf::inputs::state_t uf::inputs::kbm::states::Equal = false;
uf::inputs::state_t uf::inputs::kbm::states::Dash = false;
uf::inputs::state_t uf::inputs::kbm::states::LBracket = false;
uf::inputs::state_t uf::inputs::kbm::states::RBracket = false;
uf::inputs::state_t uf::inputs::kbm::states::Comma = false;
uf::inputs::state_t uf::inputs::kbm::states::Period = false;
uf::inputs::state_t uf::inputs::kbm::states::Quote = false;
uf::inputs::state_t uf::inputs::kbm::states::BackSlash = false;
uf::inputs::state_t uf::inputs::kbm::states::Tilde = false;
uf::inputs::state_t uf::inputs::kbm::states::Escape = false;
uf::inputs::state_t uf::inputs::kbm::states::Space = false;
uf::inputs::state_t uf::inputs::kbm::states::Enter = false;
uf::inputs::state_t uf::inputs::kbm::states::BackSpace = false;
uf::inputs::state_t uf::inputs::kbm::states::Tab = false;
uf::inputs::state_t uf::inputs::kbm::states::PageUp = false;
uf::inputs::state_t uf::inputs::kbm::states::PageDown = false;
uf::inputs::state_t uf::inputs::kbm::states::End = false;
uf::inputs::state_t uf::inputs::kbm::states::Home = false;
uf::inputs::state_t uf::inputs::kbm::states::Insert = false;
uf::inputs::state_t uf::inputs::kbm::states::Delete = false;
uf::inputs::state_t uf::inputs::kbm::states::Add = false;
uf::inputs::state_t uf::inputs::kbm::states::Subtract = false;
uf::inputs::state_t uf::inputs::kbm::states::Multiply = false;
uf::inputs::state_t uf::inputs::kbm::states::Divide = false;
uf::inputs::state_t uf::inputs::kbm::states::Pause = false;
uf::inputs::state_t uf::inputs::kbm::states::F1 = false;
uf::inputs::state_t uf::inputs::kbm::states::F2 = false;
uf::inputs::state_t uf::inputs::kbm::states::F3 = false;
uf::inputs::state_t uf::inputs::kbm::states::F4 = false;
uf::inputs::state_t uf::inputs::kbm::states::F5 = false;
uf::inputs::state_t uf::inputs::kbm::states::F6 = false;
uf::inputs::state_t uf::inputs::kbm::states::F7 = false;
uf::inputs::state_t uf::inputs::kbm::states::F8 = false;
uf::inputs::state_t uf::inputs::kbm::states::F9 = false;
uf::inputs::state_t uf::inputs::kbm::states::F10 = false;
uf::inputs::state_t uf::inputs::kbm::states::F11 = false;
uf::inputs::state_t uf::inputs::kbm::states::F12 = false;
uf::inputs::state_t uf::inputs::kbm::states::F13 = false;
uf::inputs::state_t uf::inputs::kbm::states::F14 = false;
uf::inputs::state_t uf::inputs::kbm::states::F15 = false;
uf::inputs::state_t uf::inputs::kbm::states::Left = false;
uf::inputs::state_t uf::inputs::kbm::states::Right = false;
uf::inputs::state_t uf::inputs::kbm::states::Up = false;
uf::inputs::state_t uf::inputs::kbm::states::Down = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad0 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad1 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad2 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad3 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad4 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad5 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad6 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad7 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad8 = false;
uf::inputs::state_t uf::inputs::kbm::states::Numpad9 = false;
uf::inputs::state_t uf::inputs::kbm::states::Q = false;
uf::inputs::state_t uf::inputs::kbm::states::W = false;
uf::inputs::state_t uf::inputs::kbm::states::E = false;
uf::inputs::state_t uf::inputs::kbm::states::R = false;
uf::inputs::state_t uf::inputs::kbm::states::T = false;
uf::inputs::state_t uf::inputs::kbm::states::Y = false;
uf::inputs::state_t uf::inputs::kbm::states::U = false;
uf::inputs::state_t uf::inputs::kbm::states::I = false;
uf::inputs::state_t uf::inputs::kbm::states::O = false;
uf::inputs::state_t uf::inputs::kbm::states::P = false;
uf::inputs::state_t uf::inputs::kbm::states::A = false;
uf::inputs::state_t uf::inputs::kbm::states::S = false;
uf::inputs::state_t uf::inputs::kbm::states::D = false;
uf::inputs::state_t uf::inputs::kbm::states::F = false;
uf::inputs::state_t uf::inputs::kbm::states::G = false;
uf::inputs::state_t uf::inputs::kbm::states::H = false;
uf::inputs::state_t uf::inputs::kbm::states::J = false;
uf::inputs::state_t uf::inputs::kbm::states::K = false;
uf::inputs::state_t uf::inputs::kbm::states::L = false;
uf::inputs::state_t uf::inputs::kbm::states::Z = false;
uf::inputs::state_t uf::inputs::kbm::states::X = false;
uf::inputs::state_t uf::inputs::kbm::states::C = false;
uf::inputs::state_t uf::inputs::kbm::states::V = false;
uf::inputs::state_t uf::inputs::kbm::states::B = false;
uf::inputs::state_t uf::inputs::kbm::states::N = false;
uf::inputs::state_t uf::inputs::kbm::states::M = false;
uf::inputs::state_t uf::inputs::kbm::states::Num1 = false;
uf::inputs::state_t uf::inputs::kbm::states::Num2 = false;
uf::inputs::state_t uf::inputs::kbm::states::Num3 = false;
uf::inputs::state_t uf::inputs::kbm::states::Num4 = false;
uf::inputs::state_t uf::inputs::kbm::states::Num5 = false;
uf::inputs::state_t uf::inputs::kbm::states::Num6 = false;
uf::inputs::state_t uf::inputs::kbm::states::Num7 = false;
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::state_t uf::inputs::controller::states::R_DPAD_UP = false;
uf::inputs::state_t uf::inputs::controller::states::R_DPAD_DOWN = false;
uf::inputs::state_t uf::inputs::controller::states::R_DPAD_LEFT = false;
uf::inputs::state_t uf::inputs::controller::states::R_DPAD_RIGHT = false;
uf::inputs::state_t uf::inputs::controller::states::R_JOYSTICK = false;
uf::inputs::state_t uf::inputs::controller::states::R_A = false;
uf::inputs::state_t uf::inputs::controller::states::L_DPAD_UP = false;
uf::inputs::state_t uf::inputs::controller::states::L_DPAD_DOWN = false;
uf::inputs::state_t uf::inputs::controller::states::L_DPAD_LEFT = false;
uf::inputs::state_t uf::inputs::controller::states::L_DPAD_RIGHT = false;
uf::inputs::state_t uf::inputs::controller::states::L_JOYSTICK = false;
uf::inputs::state_t uf::inputs::controller::states::L_A = false;
uf::inputs::state_t uf::inputs::controller::states::DPAD_UP = false;
uf::inputs::state_t uf::inputs::controller::states::DPAD_DOWN = false;
uf::inputs::state_t uf::inputs::controller::states::DPAD_LEFT = false;
uf::inputs::state_t uf::inputs::controller::states::DPAD_RIGHT = false;
uf::inputs::state_t uf::inputs::controller::states::A = false;
uf::inputs::state_t uf::inputs::controller::states::B = false;
uf::inputs::state_t uf::inputs::controller::states::X = false;
uf::inputs::state_t uf::inputs::controller::states::Y = false;
uf::inputs::state_t uf::inputs::controller::states::L_TRIGGER = false;
uf::inputs::state_t uf::inputs::controller::states::R_TRIGGER = false;
uf::inputs::state_t uf::inputs::controller::states::START = false;

View File

@ -1,11 +1,13 @@
#include <uf/utils/thread/thread.h>
#include <uf/utils/io/iostream.h>
#include <iostream>
#include <future>
uf::thread::container_t uf::thread::threads;
double uf::thread::limiter = 1.0f / 120.0f;
float uf::thread::limiter = 1.0f / 120.0f;
uint uf::thread::workers = 1;
std::thread::id uf::thread::mainThreadId = std::this_thread::get_id();
bool uf::thread::async = false;
#define UF_THREAD_ANNOUNCE(x)\
//uf::iostream << x << "\n";
@ -57,11 +59,21 @@ pod::Thread& UF_API uf::thread::fetchWorker( const uf::stl::string& name ) {
auto& pod = exists ? uf::thread::get(thread) : uf::thread::create(thread, true);
if ( std::this_thread::get_id() != pod.thread.get_id() ) return pod;
}
bool exists = uf::thread::has("Main");
auto& pod = exists ? uf::thread::get("Main" ) : uf::thread::create("Main", true);
return pod;
return uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create("Main", true);
}
void UF_API uf::thread::batchWorker( const pod::Thread::function_t& function, const uf::stl::string& name ) {
return batchWorkers( { function }, false, name );
}
void UF_API uf::thread::batchWorkers( const uf::stl::vector<pod::Thread::function_t>& functions, bool wait, const uf::stl::string& name ) {
if ( uf::thread::async ) {
uf::stl::vector<std::future<void>> futures;
futures.reserve(functions.size());
for ( auto& function : functions ) futures.emplace_back(std::async( std::launch::async, function ));
if ( wait ) for ( auto& future : futures ) future.wait();
return;
}
uf::stl::vector<pod::Thread*> workers;
for ( auto& function : functions ) {
auto& worker = uf::thread::fetchWorker( name );

View File

@ -120,6 +120,10 @@ void UF_API_CALL uf::Window::switchToFullscreen( bool borderless ) {
this->m_window->switchToFullscreen( borderless );
}
// Update
void UF_API_CALL uf::Window::bufferInputs() {
if ( !this->m_window ) return;
this->m_window->bufferInputs();
}
void UF_API_CALL uf::Window::processEvents() {
if ( !this->m_window ) return;
this->m_window->processEvents();

View File

@ -13,6 +13,7 @@
#include <uf/ext/bullet/bullet.h>
#include <uf/utils/math/physics.h>
#include <uf/spec/controller/controller.h>
#include <uf/utils/io/inputs.h>
#include <sstream>
@ -121,6 +122,8 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
}
void ext::PlayerBehavior::tick( uf::Object& self ) {
auto& camera = this->getComponent<uf::Camera>();
auto& cameraTransform = camera.getTransform();
auto& transform = this->getComponent<pod::Transform<>>();
auto& physics = this->getComponent<pod::Physics>();
auto& scene = uf::scene::getCurrentScene();
@ -139,48 +142,50 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
bool crouch;
bool paused;
bool vee;
bool use;
} keys = {
.forward = uf::Window::isKeyPressed("W"),
.backwards = uf::Window::isKeyPressed("S"),
.left = uf::Window::isKeyPressed("A"),
.right = uf::Window::isKeyPressed("D"),
.lookLeft = uf::Window::isKeyPressed("Left"),
.lookRight = uf::Window::isKeyPressed("Right"),
.running = uf::Window::isKeyPressed("LShift"),
.walk = uf::Window::isKeyPressed("LAlt"),
.jump = uf::Window::isKeyPressed(" "),
.crouch = uf::Window::isKeyPressed("LControl"),
.paused = uf::Window::isKeyPressed("Escape"),
.vee = uf::Window::isKeyPressed("V"),
.forward = uf::inputs::kbm::states::W,
.backwards = uf::inputs::kbm::states::S,
.left = uf::inputs::kbm::states::A,
.right = uf::inputs::kbm::states::D,
.lookLeft = uf::inputs::kbm::states::Left,
.lookRight = uf::inputs::kbm::states::Right,
.running = uf::inputs::kbm::states::LShift,
.walk = uf::inputs::kbm::states::LAlt,
.jump = uf::inputs::kbm::states::Space,
.crouch = uf::inputs::kbm::states::LControl,
.paused = uf::inputs::kbm::states::Escape,
.vee = uf::inputs::kbm::states::V,
.use = uf::inputs::kbm::states::E,
};
if ( spec::controller::connected() ) {
#if UF_USE_OPENVR
if ( spec::controller::pressed( "R_DPAD_UP" ) ) keys.forward = true;
if ( spec::controller::pressed( "R_DPAD_DOWN" ) ) keys.backwards = true;
if ( spec::controller::pressed( "R_DPAD_LEFT" ) ) keys.lookLeft = true; // keys.left = true;
if ( spec::controller::pressed( "R_DPAD_RIGHT" ) ) keys.lookRight = true; // keys.right = true;
if ( spec::controller::pressed( "R_JOYSTICK" ) ) keys.running = true;
if ( spec::controller::pressed( "R_A" ) ) keys.jump = true;
if ( uf::inputs::controller::states::R_DPAD_UP ) keys.forward = true;
if ( uf::inputs::controller::states::R_DPAD_DOWN ) keys.backwards = true;
if ( uf::inputs::controller::states::R_DPAD_LEFT ) keys.lookLeft = true; // keys.left = true;
if ( uf::inputs::controller::states::R_DPAD_RIGHT ) keys.lookRight = true; // keys.right = true;
if ( uf::inputs::controller::states::R_JOYSTICK ) keys.running = true;
if ( uf::inputs::controller::states::R_A ) keys.jump = true;
if ( spec::controller::pressed( "L_DPAD_UP" ) ) keys.forward = true;
if ( spec::controller::pressed( "L_DPAD_DOWN" ) ) keys.backwards = true;
if ( spec::controller::pressed( "L_DPAD_LEFT" ) ) keys.lookLeft = true;
if ( spec::controller::pressed( "L_DPAD_RIGHT" ) ) keys.lookRight = true;
if ( spec::controller::pressed( "L_JOYSTICK" ) ) keys.crouch = true, keys.walk = true;
if ( spec::controller::pressed( "L_A" ) ) keys.paused = true;
if ( uf::inputs::controller::states::L_DPAD_UP ) keys.forward = true;
if ( uf::inputs::controller::states::L_DPAD_DOWN ) keys.backwards = true;
if ( uf::inputs::controller::states::L_DPAD_LEFT ) keys.lookLeft = true;
if ( uf::inputs::controller::states::L_DPAD_RIGHT ) keys.lookRight = true;
if ( uf::inputs::controller::states::L_JOYSTICK ) keys.crouch = true, keys.walk = true;
if ( uf::inputs::controller::states::L_A ) keys.paused = true;
#else
if ( spec::controller::pressed( "DPAD_UP" ) ) keys.forward = true;
if ( spec::controller::pressed( "DPAD_DOWN" ) ) keys.backwards = true;
if ( spec::controller::pressed( "DPAD_LEFT" ) ) keys.lookLeft = true;
if ( spec::controller::pressed( "DPAD_RIGHT" ) ) keys.lookRight = true;
if ( spec::controller::pressed( "A" ) ) keys.jump = true;
if ( spec::controller::pressed( "B" ) ) keys.running = true;
if ( spec::controller::pressed( "X" ) ) keys.crouch = true, keys.walk = true;
if ( spec::controller::pressed( "Y" ) ) keys.vee = true;
if ( spec::controller::pressed( "L_TRIGGER" ) ) keys.left = true;
if ( spec::controller::pressed( "R_TRIGGER" ) ) keys.right = true;
if ( spec::controller::pressed( "START" ) ) keys.paused = true;
if ( uf::inputs::controller::states::DPAD_UP ) keys.forward = true;
if ( uf::inputs::controller::states::DPAD_DOWN ) keys.backwards = true;
if ( uf::inputs::controller::states::DPAD_LEFT ) keys.lookLeft = true;
if ( uf::inputs::controller::states::DPAD_RIGHT ) keys.lookRight = true;
if ( uf::inputs::controller::states::A ) keys.jump = true;
if ( uf::inputs::controller::states::B ) keys.running = true;
if ( uf::inputs::controller::states::X ) keys.crouch = true, keys.walk = true;
if ( uf::inputs::controller::states::Y ) keys.vee = true;
if ( uf::inputs::controller::states::L_TRIGGER ) keys.left = true;
if ( uf::inputs::controller::states::R_TRIGGER ) keys.right = true;
if ( uf::inputs::controller::states::START ) keys.paused = true;
#endif
}
@ -207,6 +212,41 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
#endif
stats.floored |= fabs(physics.linear.velocity.y) < 0.01f;
#if UF_USE_BULLET
TIMER(0.125, keys.use && ) {
size_t uid = 0;
uf::Object* pointer = NULL;
float length = 4.0f;
pod::Vector3f pos = transform.position + cameraTransform.position;
pod::Vector3f dir = uf::vector::normalize( transform.forward + pod::Vector3f{ 0, cameraTransform.forward.y, 0 } ) * length;
float depth = ext::bullet::rayCast( pos, pos + dir, pointer );
if ( pointer ) {
uf::Serializer payload;
payload["uid"] = this->getUid();
payload["depth"] = depth;
pointer->callHook( "entity:Use.%UID%", payload );
} else {
auto& emitter = this->getComponent<uf::MappedSoundEmitter>();
uf::stl::string filename = "./ui/deny.ogg";
uf::Audio& sfx = emitter.has(filename) ? emitter.get(filename) : emitter.load(filename);
bool playing = false;
if ( !sfx.playing() ) {
#if UF_AUDIO_MAPPED_VOLUMES
sfx.setVolume(uf::audio::volumes.count("sfx") > 0 ? uf::audio::volumes.at("sfx") : 1.0);
#else
sfx.setVolume(uf::audio::volumes::sfx);
#endif
sfx.setPosition( transform.position );
sfx.setTime( 0 );
sfx.play();
}
}
}
#endif
struct {
float move = 4;
float walk = 1;
@ -268,12 +308,11 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
translator.right = uf::vector::normalize( translator.right );
} else
#endif
// un-flatted if noclipped
if ( stats.noclipped ){
auto& cameraTransform = camera.getTransform();
translator.forward.y += cameraTransform.forward.y;
translator.forward = uf::vector::normalize( translator.forward );
}
// un-flatted if noclipped
if ( stats.noclipped ){
translator.forward.y += cameraTransform.forward.y;
translator.forward = uf::vector::normalize( translator.forward );
}
if ( metadata.system.control ) {
// noclip handler
@ -310,8 +349,12 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
stats.walking = (keys.forward ^ keys.backwards) || (keys.left ^ keys.right);
if ( stats.walking ) {
float factor = stats.floored || stats.noclipped ? 1.0f : speed.air;
physics.linear.velocity += target * std::clamp( speed.move * factor - uf::vector::dot( physics.linear.velocity, target ), 0.0f, speed.move * 10 * uf::physics::time::delta );
float factor = stats.floored ? 1.0f : speed.air;
if ( stats.noclipped ) {
physics.linear.velocity += target * speed.move;
} else {
physics.linear.velocity += target * std::clamp( speed.move * factor - uf::vector::dot( physics.linear.velocity, target ), 0.0f, speed.move * 10 * uf::physics::time::delta );
}
}
if ( !stats.floored ) stats.walking = false;
}

View File

@ -15,6 +15,7 @@
#include <uf/engine/asset/asset.h>
#include <uf/engine/asset/masterdata.h>
#include <uf/utils/io/inputs.h>
#include <uf/utils/renderer/renderer.h>
#include <uf/utils/noise/noise.h>
@ -197,6 +198,9 @@ void ext::ExtSceneBehavior::initialize( uf::Object& self ) {
metadata.deserialize(self, metadataJson);
}
void ext::ExtSceneBehavior::tick( uf::Object& self ) {
auto& assetLoader = this->getComponent<uf::Asset>();
assetLoader.processQueue();
auto& metadata = this->getComponent<ext::ExtSceneBehavior::Metadata>();
auto& metadataJson = this->getComponent<uf::Serializer>();
#if 1
@ -204,7 +208,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
metadata.shader.invalidated = false;
/* Print World Tree */ {
TIMER(1, uf::Window::isKeyPressed("U") && ) {
TIMER(1, uf::inputs::kbm::states::U && ) {
std::function<void(uf::Entity*, int)> filter = []( uf::Entity* entity, int indent ) {
for ( int i = 0; i < indent; ++i ) uf::iostream << "\t";
uf::iostream << uf::string::toString(entity->as<uf::Object>()) << " ";
@ -224,7 +228,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
#endif
#if 0
/* Print World Tree */ {
TIMER(1, uf::Window::isKeyPressed("U") && false && ) {
TIMER(1, uf::inputs::kbm::states::U && false && ) {
std::function<void(uf::Entity*, int)> filter = []( uf::Entity* entity, int indent ) {
for ( int i = 0; i < indent; ++i ) uf::iostream << "\t";
uf::iostream << uf::string::toString(entity->as<uf::Object>()) << " [";
@ -255,8 +259,8 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
}
}
#endif
#if UF_USE_OPENAL
auto& assetLoader = this->getComponent<uf::Asset>();
/* check if audio needs to loop */ {
auto& audio = this->getComponent<uf::Audio>();
if ( !audio.playing() ) audio.play();

View File

@ -25,6 +25,7 @@
#include <uf/engine/entity/entity.h>
#include <uf/engine/graph/graph.h>
#include <uf/utils/io/inputs.h>
#include <sys/stat.h>
@ -61,90 +62,20 @@ namespace {
} io;
struct {
spec::Time::time_t epoch;
uf::Timer<> sys = uf::Timer<>(false);
uf::Timer<> delta = uf::Timer<>(false);
double prevTime = 0;
double curTime = 0;
double deltaTime = 0;
uf::Timer<> sys = uf::Timer<>(false);
size_t frames = 0;
double limiter = 1.0 / 144.0;
float limiter = 1.0 / 144.0;
struct {
size_t frames = 0;
double time = 0;
float time = 0;
} total;
} times;
uf::Serializer& config = ext::config;
}
namespace {
uf::stl::string getConfig() {
#if 1
return uf::io::readAsString(uf::io::root+"/config.json");
#else
struct {
bool initialized = false;
uf::Serializer file;
uf::Serializer fallback;
uf::Serializer merged;
} static config;
if ( config.initialized ) return config.merged;
struct {
bool exists = false;
uf::stl::string filename = uf::io::root+"/config.json";
} file;
/* Read from file */ {
file.exists = config.file.readFromFile(file.filename);
}
/* Initialize default configuration */ {
config.fallback["window"]["terminal"]["ncurses"] = true;
config.fallback["window"]["terminal"]["visible"] = true;
config.fallback["window"]["title"] = "Grimgram";
config.fallback["window"]["icon"] = "";
config.fallback["window"]["size"]["x"] = 0;
config.fallback["window"]["size"]["y"] = 0;
config.fallback["window"]["visible"] = true;
// config.fallback["window"]["fullscreen"] = false;
config.fallback["window"]["mode"] = "windowed";
config.fallback["window"]["cursor"]["visible"] = true;
config.fallback["window"]["cursor"]["center"] = false;
config.fallback["window"]["keyboard"]["repeat"] = true;
config.fallback["engine"]["scenes"]["start"] = "StartMenu";
config.fallback["engine"]["scenes"]["lights"]["max"] = 32;
config.fallback["engine"]["hook"]["mode"] = "Readable";
config.fallback["engine"]["limiters"]["framerate"] = 60;
config.fallback["engine"]["limiters"]["deltaTime"] = 120;
config.fallback["engine"]["threads"]["workers"] = "auto";
config.fallback["engine"]["threads"]["frame limiter"] = 144;
#if UF_ENV_DREAMCAST
config.fallback["engine"]["memory pool"]["size"] = "1 MiB";
#else
config.fallback["engine"]["memory pool"]["size"] = "512 MiB";
#endif
config.fallback["engine"]["memory pool"]["globalOverride"] = false;
config.fallback["engine"]["memory pool"]["subPools"] = true;
}
/* Merge */ if ( file.exists ){
config.merged = config.file;
config.merged.merge( config.fallback, true );
} else {
config.merged = config.fallback;
}
/* Write default to file */ if ( false ) {
config.merged.writeToFile(file.filename);
}
config.initialized = true;
return config.merged;
#endif
}
}
void EXT_API ext::load() {
ext::config = getConfig();
ext::config = uf::io::readAsString(uf::io::root+"/config.json");
}
void EXT_API ext::initialize() {
@ -178,12 +109,7 @@ void EXT_API ext::initialize() {
io.output.open(io.filenames.output);
}
/* Initialize timers */ {
times.epoch = spec::time.getTime();
times.sys.start();
times.delta.start();
times.prevTime = times.sys.elapsed().asDouble();
times.curTime = times.sys.elapsed().asDouble();
}
/* Read persistent data */ {
// #include "./inits/persistence.inl"
@ -192,104 +118,113 @@ void EXT_API ext::initialize() {
}
/* Parse config */ {
/* Set memory pool sizes */ {
// check if we are even allowed to use memory pools
bool enabled = ::config["engine"]["memory pool"]["enabled"].as(true);
auto deduceSize = [enabled]( const ext::json::Value& value )->size_t{
if ( !enabled ) return 0;
if ( value.is<size_t>() ) return value.as<size_t>();
if ( value.is<uf::stl::string>() ) {
uf::stl::string str = value.as<uf::stl::string>();
std::regex regex("^(\\d+) ?((?:K|M|G)?(?:i?B)?)$");
std::smatch match;
if ( std::regex_search( str, match, regex ) ) {
size_t requested = std::stoi( match[1].str() );
uf::stl::string prefix = match[2].str();
switch ( prefix.at(0) ) {
case 'K': return requested * 1024;
case 'M': return requested * 1024 * 1024;
case 'G': return requested * 1024 * 1024 * 1024;
}
return requested;
/* Set memory pool sizes */ {
// check if we are even allowed to use memory pools
bool enabled = ::config["engine"]["memory pool"]["enabled"].as(true);
auto deduceSize = [enabled]( const ext::json::Value& value )->size_t{
if ( !enabled ) return 0;
if ( value.is<size_t>() ) return value.as<size_t>();
if ( value.is<uf::stl::string>() ) {
uf::stl::string str = value.as<uf::stl::string>();
std::regex regex("^(\\d+) ?((?:K|M|G)?(?:i?B)?)$");
std::smatch match;
if ( std::regex_search( str, match, regex ) ) {
size_t requested = std::stoi( match[1].str() );
uf::stl::string prefix = match[2].str();
switch ( prefix.at(0) ) {
case 'K': return requested * 1024;
case 'M': return requested * 1024 * 1024;
case 'G': return requested * 1024 * 1024 * 1024;
}
}
return 0;
};
// set memory pool alignment requirements
uf::memoryPool::alignment = ::config["engine"]["memory pool"]["alignment"].as( uf::memoryPool::alignment );
// set memory pool sizes
size_t size = deduceSize( ::config["engine"]["memory pool"]["size"] );
UF_MSG_DEBUG("Requesting " << (size_t) size << " bytes for global memory pool: " << &uf::memoryPool::global);
uf::memoryPool::global.initialize( size );
uf::memoryPool::subPool = ::config["engine"]["memory pool"]["subPools"].as( uf::memoryPool::subPool );
if ( size <= 0 || uf::memoryPool::subPool ) {
{
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["component"] );
UF_MSG_DEBUG("Requesting " << (int) size << " bytes for component memory pool: " << &uf::component::memoryPool);
uf::component::memoryPool.initialize( size );
}
{
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["userdata"] );
UF_MSG_DEBUG("Requesting " << (int) size << " bytes for userdata memory pool: " << &uf::userdata::memoryPool);
uf::userdata::memoryPool.initialize( size );
}
{
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["entity"] );
UF_MSG_DEBUG("Requesting " << (int) size << " bytes for entity memory pool: " << &uf::Entity::memoryPool);
uf::Entity::memoryPool.initialize( size );
return requested;
}
}
uf::allocator::override = ::config["engine"]["memory pool"]["override"].as( uf::allocator::override );
}
{
uf::Mesh::defaultInterleaved = ::config["engine"]["scenes"]["meshes"]["interleaved"].as( uf::Mesh::defaultInterleaved );
#if 0 && UF_USE_OPENGL
uf::matrix::reverseInfiniteProjection = false;
#else
uf::matrix::reverseInfiniteProjection = ::config["engine"]["scenes"]["matrix"]["reverseInfinite"].as( uf::matrix::reverseInfiniteProjection );
#endif
return 0;
};
// set memory pool alignment requirements
uf::memoryPool::alignment = ::config["engine"]["memory pool"]["alignment"].as( uf::memoryPool::alignment );
// set memory pool sizes
size_t size = deduceSize( ::config["engine"]["memory pool"]["size"] );
UF_MSG_DEBUG("Requesting " << (size_t) size << " bytes for global memory pool: " << &uf::memoryPool::global);
uf::memoryPool::global.initialize( size );
uf::memoryPool::subPool = ::config["engine"]["memory pool"]["subPools"].as( uf::memoryPool::subPool );
if ( size <= 0 || uf::memoryPool::subPool ) {
{
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["component"] );
UF_MSG_DEBUG("Requesting " << (int) size << " bytes for component memory pool: " << &uf::component::memoryPool);
uf::component::memoryPool.initialize( size );
}
{
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["userdata"] );
UF_MSG_DEBUG("Requesting " << (int) size << " bytes for userdata memory pool: " << &uf::userdata::memoryPool);
uf::userdata::memoryPool.initialize( size );
}
{
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["entity"] );
UF_MSG_DEBUG("Requesting " << (int) size << " bytes for entity memory pool: " << &uf::Entity::memoryPool);
uf::Entity::memoryPool.initialize( size );
}
}
uf::allocator::override = ::config["engine"]["memory pool"]["override"].as( uf::allocator::override );
}
{
uf::Mesh::defaultInterleaved = ::config["engine"]["scenes"]["meshes"]["interleaved"].as( uf::Mesh::defaultInterleaved );
#if 0 && UF_USE_OPENGL
uf::matrix::reverseInfiniteProjection = false;
#else
uf::matrix::reverseInfiniteProjection = ::config["engine"]["scenes"]["matrix"]["reverseInfinite"].as( uf::matrix::reverseInfiniteProjection );
#endif
}
/* Create initial scene (kludge) */ {
uf::Scene& scene = uf::instantiator::instantiate<uf::Scene>(); //new uf::Scene;
uf::scene::scenes.emplace_back(&scene);
auto& metadata = scene.getComponent<uf::Serializer>();
metadata["system"]["config"] = ::config;
}
/* Create initial scene (kludge) */ {
uf::Scene& scene = uf::instantiator::instantiate<uf::Scene>(); //new uf::Scene;
uf::scene::scenes.emplace_back(&scene);
auto& metadata = scene.getComponent<uf::Serializer>();
metadata["system"]["config"] = ::config;
}
if ( ::config["engine"]["limiters"]["framerate"].as<uf::stl::string>() == "auto" && ::config["window"]["refresh rate"].is<size_t>() ) {
double scale = 1.0;
size_t refreshRate = ::config["window"]["refresh rate"].as<size_t>();
::config["engine"]["limiters"]["framerate"] = refreshRate * scale;
UF_MSG_DEBUG("Setting framerate cap to " << (int) refreshRate * scale);
}
if ( ::config["engine"]["threads"]["frame limiter"].as<uf::stl::string>() == "auto" && ::config["window"]["refresh rate"].is<size_t>() ) {
double scale = 2.0;
size_t refreshRate = ::config["window"]["refresh rate"].as<size_t>();
::config["engine"]["threads"]["frame limiter"] = refreshRate * scale;
UF_MSG_DEBUG("Setting thread frame limiter to " << (int) refreshRate * scale);
}
/* Frame limiter */ {
double limit = ::config["engine"]["limiters"]["framerate"].as<double>();
::times.limiter = limit != 0 ? 1.0 / limit : 0;
}
/* Thread frame limiter */ {
double limit = ::config["engine"]["threads"]["frame limiter"].as<double>();
uf::thread::limiter = limit != 0 ? 1.0 / limit : 0;
}
/* Max delta time */{
double limit = ::config["engine"]["limiters"]["deltaTime"].as<double>();
uf::physics::time::clamp = limit != 0 ? 1.0 / limit : 0;
}
{
uf::Entity::deleteChildrenOnDestroy = ::config["engine"]["debug"]["entity"]["delete children on destroy"].as( uf::Entity::deleteChildrenOnDestroy );
uf::Entity::deleteComponentsOnDestroy = ::config["engine"]["debug"]["entity"]["delete components on destroy"].as( uf::Entity::deleteComponentsOnDestroy );
}
// Set worker threads
if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "auto" ) {
auto threads = std::max( 1, (int) std::thread::hardware_concurrency() - 1 );
::config["engine"]["threads"]["workers"] = threads;
UF_MSG_DEBUG("Using " << threads << " worker threads");
}
// Mute audio
if ( ::config["engine"]["limiters"]["framerate"].as<uf::stl::string>() == "auto" && ::config["window"]["refresh rate"].is<size_t>() ) {
float scale = 1.0;
size_t refreshRate = ::config["window"]["refresh rate"].as<size_t>();
::config["engine"]["limiters"]["framerate"] = refreshRate * scale;
UF_MSG_DEBUG("Setting framerate cap to " << (int) refreshRate * scale);
}
if ( ::config["engine"]["threads"]["frame limiter"].as<uf::stl::string>() == "auto" && ::config["window"]["refresh rate"].is<size_t>() ) {
float scale = 2.0;
size_t refreshRate = ::config["window"]["refresh rate"].as<size_t>();
::config["engine"]["threads"]["frame limiter"] = refreshRate * scale;
UF_MSG_DEBUG("Setting thread frame limiter to " << (int) refreshRate * scale);
}
/* Frame limiter */ {
float limit = ::config["engine"]["limiters"]["framerate"].as<float>();
::times.limiter = limit != 0 ? 1.0 / limit : 0;
}
/* Thread frame limiter */ {
float limit = ::config["engine"]["threads"]["frame limiter"].as<float>();
uf::thread::limiter = limit != 0 ? 1.0 / limit : 0;
}
/* Max delta time */{
float limit = ::config["engine"]["limiters"]["deltaTime"].as<float>();
uf::physics::time::clamp = limit != 0 ? 1.0 / limit : 0;
}
// Set worker threads
if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "async" ) {
uf::thread::async = true;
UF_MSG_DEBUG("Using async worker threads");
} else if ( ::config["engine"]["threads"]["workers"].as<uf::stl::string>() == "auto" ) {
auto threads = std::max( 1, (int) std::thread::hardware_concurrency() - 1 );
::config["engine"]["threads"]["workers"] = threads;
uf::thread::workers = ::config["engine"]["threads"]["workers"].as<size_t>();
UF_MSG_DEBUG("Using " << threads << " worker threads");
}
// Audio settings
{
uf::audio::muted = ::config["engine"]["audio"]["mute"].as( uf::audio::muted );
uf::audio::streamsByDefault = ::config["engine"]["audio"]["streams by default"].as( uf::audio::streamsByDefault );
uf::audio::bufferSize = ::config["engine"]["audio"]["buffers"]["size"].as( uf::audio::bufferSize );
@ -304,14 +239,17 @@ void EXT_API ext::initialize() {
uf::audio::volumes::sfx = ::config["engine"]["audio"]["volumes"]["sfx"].as(uf::audio::volumes::sfx);
uf::audio::volumes::voice = ::config["engine"]["audio"]["volumes"]["voice"].as(uf::audio::volumes::voice);
#endif
#if UF_USE_OPENAL
/* Initialize OpenAL */ {
ext::al::initialize();
}
#endif
}
#if UF_USE_BULLET
// set bullet parameters
#if UF_USE_OPENAL
/* Initialize OpenAL */ {
ext::al::initialize();
}
#endif
// set bullet parameters
#if UF_USE_BULLET
{
ext::bullet::iterations = ::config["engine"]["ext"]["bullet"]["iterations"].as( ext::bullet::iterations );
ext::bullet::substeps = ::config["engine"]["ext"]["bullet"]["substeps"].as( ext::bullet::substeps );
ext::bullet::timescale = ::config["engine"]["ext"]["bullet"]["timescale"].as( ext::bullet::timescale );
@ -321,15 +259,17 @@ void EXT_API ext::initialize() {
ext::bullet::debugDrawEnabled = ::config["engine"]["ext"]["bullet"]["debug draw"]["enabled"].as( ext::bullet::debugDrawEnabled );
ext::bullet::debugDrawRate = ::config["engine"]["ext"]["bullet"]["debug draw"]["rate"].as( ext::bullet::debugDrawRate );
ext::bullet::debugDrawLayer = ::config["engine"]["ext"]["bullet"]["debug draw"]["layer"].as( ext::bullet::debugDrawLayer );
#endif
uf::thread::workers = ::config["engine"]["threads"]["workers"].as<size_t>();
}
#endif
// renderer settings
{
#if UF_USE_VULKAN
uf::stl::string RENDERER = "vulkan";
const uf::stl::string RENDERER = "vulkan";
#elif UF_USE_OPENGL
uf::stl::string RENDERER = "opengl";
const uf::stl::string RENDERER = "opengl";
#else
uf::stl::string RENDERER = "software";
const uf::stl::string RENDERER = "software";
#endif
uf::renderer::settings::validation = ::config["engine"]["ext"][RENDERER]["validation"]["enabled"].as( uf::renderer::settings::validation );
uf::renderer::settings::msaa = ::config["engine"]["ext"][RENDERER]["framebuffer"]["msaa"].as( uf::renderer::settings::msaa );
@ -345,9 +285,6 @@ void EXT_API ext::initialize() {
if ( uf::string::lowercase( filter ) == "nearest" ) uf::renderer::settings::swapchainUpscaleFilter = uf::renderer::enums::Filter::NEAREST;
else if ( uf::string::lowercase( filter ) == "linear" ) uf::renderer::settings::swapchainUpscaleFilter = uf::renderer::enums::Filter::LINEAR;
}
uf::Entity::deleteChildrenOnDestroy = ::config["engine"]["debug"]["entity"]["delete children on destroy"].as( uf::Entity::deleteChildrenOnDestroy );
uf::Entity::deleteComponentsOnDestroy = ::config["engine"]["debug"]["entity"]["delete components on destroy"].as( uf::Entity::deleteComponentsOnDestroy );
for ( int i = 0; i < ::config["engine"]["ext"][RENDERER]["validation"]["filters"].size(); ++i ) {
uf::renderer::settings::validationFilters.emplace_back( ::config["engine"]["ext"][RENDERER]["validation"]["filters"][i].as<uf::stl::string>() );
@ -376,6 +313,7 @@ void EXT_API ext::initialize() {
uf::renderer::settings::experimental::deferredSampling = ::config["engine"]["ext"][RENDERER]["experimental"]["deferred sampling"].as( uf::renderer::settings::experimental::deferredSampling );
uf::renderer::settings::experimental::culling = ::config["engine"]["ext"][RENDERER]["experimental"]["culling"].as( uf::renderer::settings::experimental::culling );
uf::renderer::settings::experimental::bloom = ::config["engine"]["ext"][RENDERER]["experimental"]["bloom"].as( uf::renderer::settings::experimental::bloom );
#define JSON_TO_VKFORMAT( key ) if ( ::config["engine"]["ext"][RENDERER]["formats"][#key].is<uf::stl::string>() ) {\
uf::stl::string format = ::config["engine"]["ext"][RENDERER]["formats"][#key].as<uf::stl::string>();\
format = uf::string::replace( uf::string::uppercase(format), " ", "_" );\
@ -403,37 +341,38 @@ void EXT_API ext::initialize() {
}
#endif
#if UF_USE_BULLET
#if UF_USE_BULLET
/* Bullet */ {
ext::bullet::initialize();
}
#endif
#if UF_USE_OPENVR
#if UF_USE_OPENVR
{
ext::openvr::enabled = ::config["engine"]["ext"]["vr"]["enable"].as( ext::openvr::enabled );
ext::openvr::swapEyes = ::config["engine"]["ext"]["vr"]["swap eyes"].as( ext::openvr::swapEyes );
if ( ::config["engine"]["ext"]["vr"]["dominant eye"].is<int>() ) {
ext::openvr::dominantEye = ::config["engine"]["ext"]["vr"]["dominant eye"].as<int>();
} else if ( ::config["engine"]["ext"]["vr"]["dominant eye"].as<uf::stl::string>() == "left" ) ext::openvr::dominantEye = 0;
else if ( ::config["engine"]["ext"]["vr"]["dominant eye"].as<uf::stl::string>() == "right" ) ext::openvr::dominantEye = 1;
ext::openvr::driver.manifest = ::config["engine"]["ext"]["vr"]["manifest"].as<uf::stl::string>();
if ( ext::openvr::enabled ) ::config["engine"]["render modes"]["stereo deferred"] = true;
#endif
}
#endif
/* Initialize Vulkan */ {
#if UF_USE_VULKAN
// setup render mode
if ( ::config["engine"]["render modes"]["gui"].as<bool>() ) {
if ( ::config["engine"]["render modes"]["gui"].as<bool>(true) ) {
auto* renderMode = new uf::renderer::RenderTargetRenderMode;
uf::renderer::addRenderMode( renderMode, "Gui" );
renderMode->blitter.descriptor.subpass = 1;
}
if ( ::config["engine"]["render modes"]["deferred"].as<bool>() ) {
if ( ::config["engine"]["render modes"]["deferred"].as<bool>(true) ) {
uf::renderer::addRenderMode( new uf::renderer::DeferredRenderMode, "" );
auto& renderMode = uf::renderer::getRenderMode("Deferred", true);
if ( ::config["engine"]["render modes"]["stereo deferred"].as<bool>() ) {
@ -458,7 +397,7 @@ void EXT_API ext::initialize() {
UF_MSG_DEBUG("Recommended VR Resolution: " << renderMode.width << ", " << renderMode.height);
if ( ::config["engine"]["ext"]["vr"]["scale"].is<double>() ) {
if ( ::config["engine"]["ext"]["vr"]["scale"].is<float>() ) {
float scale = ::config["engine"]["ext"]["vr"]["scale"].as<float>();
renderMode.width *= scale;
renderMode.height *= scale;
@ -468,15 +407,15 @@ void EXT_API ext::initialize() {
}
#endif
#if UF_USE_VULKAN
/* Callbacks for 2KHR stuffs */ if ( false ) {
/* Callbacks for 2KHR stuffs */ {
uf::hooks.addHook("vulkan:Instance.ExtensionsEnabled", []( const ext::json::Value& json ) {
// std::cout << "vulkan:Instance.ExtensionsEnabled: " << json << std::endl;
UF_MSG_DEBUG("vulkan:Instance.ExtensionsEnabled: " << json);
});
uf::hooks.addHook("vulkan:Device.ExtensionsEnabled", []( const ext::json::Value& json ) {
// std::cout << "vulkan:Device.ExtensionsEnabled: " << json << std::endl;
UF_MSG_DEBUG("vulkan:Device.ExtensionsEnabled: " << json);
});
uf::hooks.addHook("vulkan:Device.FeaturesEnabled", []( const ext::json::Value& json ) {
// std::cout << "vulkan:Device.FeaturesEnabled: " << json << std::endl;
UF_MSG_DEBUG("vulkan:Device.FeaturesEnabled: " << json);
VkPhysicalDeviceFeatures2KHR deviceFeatures2{};
VkPhysicalDeviceMultiviewFeaturesKHR extFeatures{};
@ -503,29 +442,25 @@ void EXT_API ext::initialize() {
});
}
#endif
}
{
uf::renderer::initialize();
}
/* */ {
pod::Thread& threadMain = uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false );
pod::Thread& threadPhysics = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true );
}
pod::Thread& threadMain = uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false );
#if UF_USE_DISCORD
/* Discord */ if ( ::config["engine"]["ext"]["discord"]["enabled"].as<bool>() ) {
ext::discord::initialize();
}
#endif
#if UF_USE_ULTRALIGHT
{
auto& ultralight = ::config["engine"]["ext"]["ultralight"];
/* Ultralight-UX */ if ( ultralight["enabled"].as<bool>() ) {
ext::ultralight::scale = ultralight["scale"].as<double>( ext::ultralight::scale );
ext::ultralight::log = ultralight["log"].as<size_t>( ext::ultralight::log );
ext::ultralight::initialize();
}
/* Ultralight-UX */ if ( ::config["engine"]["ext"]["ultralight"]["enabled"].as<bool>() ) {
ext::ultralight::scale = ::config["engine"]["ext"]["ultralight"]["scale"].as( ext::ultralight::scale );
ext::ultralight::log = ::config["engine"]["ext"]["ultralight"]["log"].as( ext::ultralight::log );
ext::ultralight::initialize();
}
#endif
/* Add hooks */ {
uf::hooks.addHook( "game:Scene.Load", [&](ext::json::Value& json){
auto function = [json]() -> int {
@ -545,15 +480,9 @@ void EXT_API ext::initialize() {
});
uf::hooks.addHook( "game:Scene.Cleanup", [&](ext::json::Value& json){
for ( auto* scene : uf::scene::scenes ) {
if ( scene->hasComponent<uf::Audio>() ) {
scene->getComponent<uf::Audio>().destroy();
}
}
uf::scene::unloadScene();
});
uf::hooks.addHook( "system:Quit", [&](ext::json::Value& json){
// uf::iostream << "system:Quit: " << event << "\n";
ext::ready = false;
});
}
@ -563,26 +492,22 @@ void EXT_API ext::initialize() {
payload["scene"] = ::config["engine"]["scenes"]["start"];
payload["immediate"] = true;
uf::hooks.call("game:Scene.Load", payload);
uf::thread::add( uf::thread::fetchWorker(), [&]() -> int {
auto& scene = uf::scene::getCurrentScene();
auto& assetLoader = scene.getComponent<uf::Asset>();
assetLoader.processQueue();
return 0;}, false );
}
/*
uf::thread::add( uf::thread::fetchWorker(), [&]() -> int {
auto& scene = uf::scene::getCurrentScene();
auto& assetLoader = scene.getComponent<uf::Asset>();
assetLoader.processQueue();
return 0;}, false );
*/
ext::ready = true;
UF_MSG_INFO("EXT took " << times.sys.elapsed().asDouble() << " seconds to initialize!");
}
void EXT_API ext::tick() {
/* Timer */ {
times.prevTime = times.curTime;
times.curTime = times.sys.elapsed().asDouble();
times.deltaTime = times.curTime - times.prevTime;
}
/* Tick controllers */ {
spec::controller::tick();
}
@ -592,7 +517,7 @@ void EXT_API ext::tick() {
}
#endif
/* Print Memory Pool Information */ {
TIMER(1, uf::Window::isKeyPressed("P") && ) {
TIMER(1, uf::inputs::kbm::states::P && ) {
// uf::iostream << uf::renderer::allocatorStats() << "\n";
UF_MSG_DEBUG("==== Memory Pool Information ====");
if ( uf::memoryPool::global.size() > 0 ) UF_MSG_DEBUG("Global Memory Pool: " << uf::memoryPool::global.stats());
@ -603,12 +528,12 @@ void EXT_API ext::tick() {
}
#if 0
/* Attempt to reset VR position */ {
TIMER(1, uf::Window::isKeyPressed("Z") && ) {
TIMER(1, uf::inputs::kbm::states::Z && ) {
uf::hooks.call("VR:Seat.Reset");
}
}
/* Print controller position */ if ( false ) {
TIMER(1, uf::Window::isKeyPressed("Z") && ) {
TIMER(1, uf::inputs::kbm::states::Z && ) {
auto& scene = uf::scene::getCurrentScene();
auto& controller = scene.getController();
auto& camera = controller.getComponent<uf::Camera>();
@ -637,47 +562,19 @@ void EXT_API ext::tick() {
uf::physics::tick();
}
#if UF_USE_BULLET
auto& bulletThread = uf::thread::get("Physics");
/* Update bullet */ {
#if 1
//UF_TIMER_TRACE_INIT();
ext::bullet::tick();
//UF_TIMER_TRACE("[TICK] BULLET");
#else
if ( ::config["engine"]["ext"]["bullet"]["multithreaded"].as<bool>() ) {
uf::thread::add( bulletThread, [&]() -> int { ext::bullet::tick(); return 0;}, true );
} else {
ext::bullet::tick();
}
#endif
}
#endif
//UF_TIMER_TRACE("ticking physics");
/* Update graph */ {
uf::graph::tick();
}
/* Update entities */ {
uf::scene::tick();
}
//UF_TIMER_TRACE("ticking scene");
/* Tick Main Thread Queue */ {
pod::Thread& thread = uf::thread::get("Main");
uf::thread::process( thread );
}
{
auto& gc = ::config["engine"]["debug"]["garbage collection"];
/* Garbage collection */ if ( gc["enabled"].as<bool>() ) {
double every = gc["every"].as<double>();
uint8_t mode = gc["mode"].as<uint64_t>();
bool announce = gc["announce"].as<bool>();
TIMER( every ) {
size_t collected = uf::instantiator::collect( mode );
if ( collected > 0 ) {
if ( announce ) UF_MSG_DEBUG("GC collected " << (int) collected << " unused entities");
// uf::renderer::states::rebuild = true;
}
}
}
uf::thread::process( uf::thread::get("Main") );
}
#if UF_USE_ULTRALIGHT
/* Ultralight-UX */ if ( ::config["engine"]["ext"]["ultralight"]["enabled"].as<bool>() ) {
@ -685,9 +582,7 @@ void EXT_API ext::tick() {
}
#endif
/* Update vulkan */ {
//UF_TIMER_TRACE_INIT();
uf::renderer::tick();
//UF_TIMER_TRACE("[TICK] RENDERER");
}
//UF_TIMER_TRACE("ticking renderer");
#if UF_USE_DISCORD
@ -700,13 +595,28 @@ void EXT_API ext::tick() {
/* FPS Print */ if ( fps["print"].as<bool>() ) {
++::times.frames;
++::times.total.frames;
double every = fps["every"].as<double>();
float every = fps["every"].as<float>();
TIMER( every ) {
UF_MSG_DEBUG("System: " << (every * 1000.0/::times.frames) << " ms/frame | Time: " << time << " | Frames: " << ::times.frames << " | FPS: " << ::times.frames / time);
::times.frames = 0;
}
}
}
{
auto& gc = ::config["engine"]["debug"]["garbage collection"];
/* Garbage collection */ if ( gc["enabled"].as<bool>() ) {
float every = gc["every"].as<float>();
uint8_t mode = gc["mode"].as<uint64_t>();
bool announce = gc["announce"].as<bool>();
TIMER( every ) {
size_t collected = uf::instantiator::collect( mode );
if ( collected > 0 ) {
if ( announce ) UF_MSG_DEBUG("GC collected " << (int) collected << " unused entities");
// uf::renderer::states::rebuild = true;
}
}
}
}
#if !UF_ENV_DREAMCAST
/* Frame limiter of sorts I guess */ if ( ::times.limiter > 0 ) {
static uf::Timer<long long> timer(false);
@ -720,11 +630,6 @@ void EXT_API ext::tick() {
timer.reset();
}
#endif
#if 0
if ( ::config["engine"]["ext"]["bullet"]["multithreaded"].as<bool>() ) {
uf::thread::wait( bulletThread );
}
#endif
}
void EXT_API ext::render() {
#if UF_USE_ULTRALIGHT

View File

@ -2,6 +2,6 @@ ARCH = win64
CDIR =
CC = gcc
CXX = g++
OPTIMIZATIONS = # -fstrict-aliasing # -flto
OPTIMIZATIONS = -O3 -fstrict-aliasing # -flto
WARNINGS = -g -Wall -Wno-pointer-arith -Wno-unknown-pragmas -Wno-unused-function -Wno-unused-variable -Wno-switch -Wno-reorder -Wno-sign-compare -Wno-unused-but-set-variable -Wno-ignored-attributes -Wno-narrowing -Wno-misleading-indentation
FLAGS += -std=c++17 $(OPTIMIZATIONS) $(WARNINGS) -fdiagnostics-color=always