Commit for 2022.07.21 23-48-52.7z

This commit is contained in:
mrq 2022-07-21 23:48:00 -05:00
parent 64dd96692c
commit 928945e727
38 changed files with 618 additions and 1027 deletions

View File

@ -59,9 +59,9 @@ DEPS +=
ifneq (,$(findstring win64,$(ARCH)))
ifneq (,$(findstring zig,$(CC)))
REQ_DEPS += $(RENDERER) json:nlohmann toml png zlib luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt curl freetype openal ogg # ncurses openvr draco discord bullet ultralight-ux
REQ_DEPS += $(RENDERER) json:nlohmann toml png zlib luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt curl freetype openal ogg ffx:fsr # ncurses openvr draco discord bullet ultralight-ux
else
REQ_DEPS += $(RENDERER) json:nlohmann toml png zlib luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt curl freetype openal ogg # ncurses openvr draco discord bullet ultralight-ux
REQ_DEPS += $(RENDERER) json:nlohmann toml png zlib luajit reactphysics meshoptimizer xatlas simd ctti gltf imgui fmt curl freetype openal ogg ffx:fsr # ncurses openvr draco discord bullet ultralight-ux
endif
FLAGS += -DUF_ENV_WINDOWS -DUF_ENV_WIN64 -DWIN32_LEAN_AND_MEAN
DEPS += -lgdi32 -ldwmapi
@ -104,6 +104,11 @@ ifneq (,$(findstring fmt,$(REQ_DEPS)))
DEPS += -lfmt
endif
endif
ifneq (,$(findstring ffx:fsr,$(REQ_DEPS)))
FLAGS += -DUF_USE_FFX_FSR
#INCS += -I./dep/include/ffx_fsr2/
DEPS += -lffx_fsr2_api_x64 -lffx_fsr2_api_vk_x64
endif
ifneq (,$(findstring imgui,$(REQ_DEPS)))
FLAGS += -DUF_USE_IMGUI
INCS += -I./dep/include/imgui/

View File

@ -11,7 +11,7 @@
"enabled": true,
"update": 4,
"max": 24,
"samples": 1
"samples": 16
},
"bloom": {
"scale": 1.0,
@ -83,9 +83,9 @@
},
"framebuffer": {
"msaa": 1,
// "size": 0.5
"size": 0.25
// "size": 0.75
"size": 1
// "size": 1
// "size": [ 640, 480, "NEAREST" ]
// "size": [ 1280, 720 ]
// "size": [ 960, 540 ]
@ -104,8 +104,9 @@
"hdr": true,
"vxgi": true,
"culling": true,
"occlusion": true,
"bloom": false,
"rt": true
"rt": false
},
"formats": {
"depth": "D32_SFLOAT",
@ -205,27 +206,19 @@
"imgui": {
"enabled": false
},
"fsr": {
"enabled": true
},
"reactphysics": {
"timescale": 0.01666666666,
"interpolate": false,
"debug draw": {
"enabled": false,
"line width": 8,
// "layer": "Gui",
"rate": 0.0125
}
},
"bullet": {
"iterations": 1,
"substeps": 4,
"timescale": 1,
"multithreaded": false,
"pool size": {
"max collision algorithm": 65535,
"max persistent manifold": 65535
"gravity": {
"mode": "universal",
"constant": 6.67408e-11
},
"debug draw": {
"enabled": false,
"line width": 8,
// "layer": "Gui",
"rate": 0.0125
}
@ -317,9 +310,9 @@
},
"mode" : "windowed", // fullscreen, borderless, windowed
"icon" : "./data/textures/icon.png",
// "size" : [ 1920, 1080 ],
"size" : [ 1920, 1080 ],
// "size" : [ 1280, 720 ],
"size" : [ 960, 540 ],
// "size" : [ 960, 540 ],
// "size" : [ 640, 480 ],
// "size" : [ 256, 224 ],
"title" : "Grimgram",

View File

@ -62,7 +62,7 @@
"air": 0.1,
"crouch": 1,
"jump": [ 0, 4, 0 ],
"jump": [ 0, 3, 0 ],
"look": 1,
"floored": {
"feet": [ 0, -1.5, 0 ],

View File

@ -14,7 +14,7 @@
},
"info_player_spawn": { "action": "attach", "filename": "./player.json", "transform": { "orientation": [ 0, 1, 0, 0 ] } },
"light_environment": { "transform": { "orientation": [0,0,0,1] }, "light": {
"power": 1,
"power": 100000,
"global": true,
"bias": {
"constant": 1.25,
@ -22,7 +22,7 @@
"shader": 0.0000025
},
"radius": [0.95, 0],
"resolution": 1536
"resolution": 8196
} },
// regexp matches

View File

@ -11,12 +11,20 @@
],
"tags": {
// exact matches
"worldspawn_skybox": { "ignore": true },
// "worldspawn_skybox": { "ignore": true },
"worldspawn_skybox": {
"grid": { "size": [3,1,3], "epsilon": 1.0, "cleanup": true, "print": true },
"unwrap mesh": true,
"optimize mesh": { "simplify": 0 }
},
"worldspawn_water": {},
// regex matches
"/^gm_construct\\/water/": { "material": {
"base": [ 0.027, 0.227, 0.259, 0.5 ],
"fRoughness": 0.3
"fRoughness": 0.3,
"fAlphaCutoff": 0.5,
"modeAlpha": "blend"
} }
}
}

View File

@ -6,28 +6,30 @@
],
"metadata": {
"light": {
"ambient": [ 0, 0, 0 ],
// "ambient": [ 0, 0, 0 ],
// "ambient": [ 0.05, 0.05, 0.05 ],
// "ambient": [ 0.15, 0.15, 0.15 ],
"ambient": [ 0.15, 0.15, 0.15 ],
// "ambient": [ 0.5, 0.5, 0.5 ],
// "ambient": [ 0.8, 0.8, 0.8 ],
// "ambient": [ 0.1, 0.1, 0.2 ],
"exposure": 0.25,
"exposure": 0.125,
"gamma": 2.2,
"brightnessThreshold": 1.2,
"fog": {
"color": [ 0.1, 0.1, 0.1 ],
// "color": [ 0.1, 0.1, 0.1 ],
// "color": [ 0.2, 0.2, 0.2 ],
"color": [ 0.3, 0.3, 0.3 ],
"range": [ 64, 256 ],
"step scale": 2,
"step scale": 4,
"absorbtion": 0.0125,
"density": {
"threshold": 0.35,
"multiplier": 5.0,
"multiplier": 2.0,
"scale": 25.0,
"offset": [0.2, 0, 1],
"timescale": 8
"timescale": 32
}
}
}

View File

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

View File

@ -38,15 +38,14 @@ float stripes(vec2 uv) {
return ramp(mod(uv.y*4. + iTime/2.+sin(iTime + sin(iTime*0.63)),1.),0.5,0.6)*noi;
}
vec3 getVideo(vec2 uv) {
vec4 getVideo(vec2 uv) {
vec2 look = uv;
float window = 1./(1.+20.*(look.y-mod(iTime/4.,1.))*(look.y-mod(iTime/4.,1.)));
look.x = look.x + sin(look.y*10. + iTime)/50.*onOff(4.,4.,.3)*(1.+cos(iTime*80.))*window;
float vShift = 0.4*onOff(2.,3.,.9)*(sin(iTime)*sin(iTime*20.) +
(0.5 + 0.1*sin(iTime*200.)*cos(iTime)));
look.y = mod(look.y + vShift, 1.);
vec3 video = vec3(texture(samplerAlbedo,look));
return video;
return texture(samplerAlbedo,look);
}
vec2 screenDistort(vec2 uv) {
@ -61,16 +60,16 @@ void main() {
iTime = ubo.curTime;
uv = screenDistort(uv);
vec3 video = getVideo(uv);
vec4 video = getVideo(uv);
float vigAmt = 3.+.3*sin(iTime + 5.*cos(iTime*5.));
float vignette = (1.-vigAmt*(uv.y-.5)*(uv.y-.5))*(1.-vigAmt*(uv.x-.5)*(uv.x-.5));
video += stripes(uv);
video += noise(uv*2.)/2.;
video *= vignette;
video *= (12.+mod(uv.y*30.+iTime,1.))/13.;
video.rgb += stripes(uv);
video.rgb += noise(uv*2.)/4.;
video.rgb *= vignette;
video.rgb *= (12.+mod(uv.y*30.+iTime,1.))/13.;
fragColor = vec4(video,1.0);
fragColor = video;
}
#endif
#if 1
@ -94,28 +93,28 @@ vec4 vignetteIntensity(vec2 uv, vec2 resolution, float opacity, float roundness)
}
void main(void) {
const vec2 screenResolution = textureSize( samplerAlbedo, 0 ) * 0.75;
const vec2 scanLineOpacity = vec2(1,1);
const float brightness = 1;
const float vignetteOpacity = 1;
const float vignetteRoundness = 1;
const vec2 curvature = vec2(3.0, 3.0);
const vec2 screenResolution = textureSize( samplerAlbedo, 0 );
const vec2 scanLineOpacity = vec2(0.5);
const float brightness = 2;
const float vignetteOpacity = 0.5;
const float vignetteRoundness = 0.5;
const vec2 curvature = vec2(8);
const vec2 remappedUV = curveRemapUV(vec2(inUv.x, inUv.y), curvature);
vec4 baseColor = texture(samplerAlbedo, remappedUV);
const vec2 remappedUV = curveRemapUV(vec2(inUv.x, inUv.y), curvature);
vec4 baseColor = texture(samplerAlbedo, remappedUV);
baseColor *= vignetteIntensity(remappedUV, screenResolution, vignetteOpacity, vignetteRoundness);
baseColor *= vignetteIntensity(remappedUV, screenResolution, vignetteOpacity, vignetteRoundness);
baseColor *= scanLineIntensity(remappedUV.x, screenResolution.y, scanLineOpacity.x);
baseColor *= scanLineIntensity(remappedUV.y, screenResolution.x, scanLineOpacity.y);
baseColor *= scanLineIntensity(remappedUV.x, screenResolution.y, scanLineOpacity.x);
baseColor *= scanLineIntensity(remappedUV.y, screenResolution.x, scanLineOpacity.y);
baseColor *= vec4(vec3(brightness), 1.0);
baseColor *= vec4(vec3(brightness), 1.0);
if (remappedUV.x < 0.0 || remappedUV.y < 0.0 || remappedUV.x > 1.0 || remappedUV.y > 1.0){
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
} else {
fragColor = baseColor;
}
if (remappedUV.x < 0.0 || remappedUV.y < 0.0 || remappedUV.x > 1.0 || remappedUV.y > 1.0){
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
} else {
fragColor = baseColor;
}
}
#endif
#if 0

View File

@ -101,7 +101,7 @@ layout(buffer_reference, scalar) buffer VID { uint v[]; };
void postProcess() {
float brightness = dot(surface.fragment.rgb, vec3(0.2126, 0.7152, 0.0722));
outFragBright = brightness > ubo.settings.bloom.brightnessThreshold ? vec4(surface.fragment.rgb, 1.0) : vec4(0, 0, 0, 1);
// outFragBright = brightness > ubo.settings.bloom.brightnessThreshold ? vec4(surface.fragment.rgb, 1.0) : vec4(0, 0, 0, 1);
#if FOG
fog( surface.ray, surface.fragment.rgb, surface.fragment.a );

View File

@ -0,0 +1,52 @@
#version 450
#pragma shader_stage(compute)
//#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;
#define COMPUTE 1
#include "../common/macros.h"
#include "../common/structs.h"
layout( push_constant ) uniform PushBlock {
uint pass;
uint passes;
} PushConstant;
layout (binding = 0) uniform Camera {
Viewport viewport[PASSES];
} camera;
layout (std140, binding = 1) buffer DrawCommands {
DrawCommand drawCommands[];
};
layout (std140, binding = 2) buffer Instances {
Instance instances[];
};
layout (binding = 3) uniform sampler2D samplerID;
layout (binding = 4) uniform sampler2D samplerDepth;
bool frustumCull( uint id ) {
if ( PushConstant.passes == 0 ) return true;
const DrawCommand drawCommand = drawCommands[id];
const Instance instance = instances[drawCommand.instanceID];
bool visible = true;
for ( uint pass = 0; pass < PushConstant.passes; ++pass ) {
mat4 mat = camera.viewport[pass].projection * camera.viewport[pass].view * instance.model;
}
return visible;
}
void main() {
const uint gID = gl_GlobalInvocationID.x;
if ( !(0 <= gID && gID < drawCommands.length()) ) return;
if ( drawCommands[gID].instances == 0 ) return;
// drawCommands[gID].instances = frustumCull( gID ) ? 1 : 0;
}

View File

@ -1,110 +0,0 @@
#pragma once
#include <uf/config.h>
#include <uf/engine/object/object.h>
#include <uf/utils/math/transform.h>
#include <uf/utils/mesh/mesh.h>
#include <uf/utils/math/collision.h>
#include <uf/engine/graph/graph.h>
#if UF_USE_BULLET
#include <btBulletDynamicsCommon.h>
#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h"
#endif
namespace pod {
struct UF_API Physics {
size_t uid = 0;
uf::Object* pointer = NULL;
pod::Transform<> transform;
pod::Transform<> previous;
bool shared = false; // share control of the transform both in-engine and bullet, set to true if you're directly modifying the transform
btRigidBody* body = NULL;
btCollisionShape* shape = NULL;
struct {
pod::Vector3 velocity;
pod::Vector3 acceleration;
} linear;
struct {
pod::Quaternion<> velocity;
pod::Quaternion<> acceleration;
} rotational;
struct {
uint32_t flags = 0;
float mass = 0.0f;
float friction = 0.8f;
float restitution = 0.0f;
pod::Vector3f inertia = {0, 0, 0};
pod::Vector3f gravity = {0, 0, 0};
} stats;
};
typedef Physics PhysicsState;
}
#if UF_USE_BULLET
namespace ext {
namespace bullet {
extern UF_API size_t iterations;
extern UF_API size_t substeps;
extern UF_API float timescale;
extern UF_API size_t defaultMaxCollisionAlgorithmPoolSize;
extern UF_API size_t defaultMaxPersistentManifoldPoolSize;
namespace debugDraw {
extern UF_API bool enabled;
extern UF_API float rate;
extern UF_API uf::stl::string layer;
extern UF_API float lineWidth;
}
void UF_API initialize();
void UF_API tick( float = 0 );
void UF_API terminate();
// base collider creation
pod::PhysicsState& UF_API create( uf::Object& );
void UF_API destroy( uf::Object& );
void UF_API destroy( pod::PhysicsState& );
void UF_API attach( pod::PhysicsState& );
void UF_API detach( pod::PhysicsState& );
// collider for mesh (static or dynamic)
pod::PhysicsState& create( uf::Object&, const uf::Mesh&, bool );
// collider for boundingbox
pod::PhysicsState& UF_API create( uf::Object&, const pod::Vector3f& );
// collider for capsule
pod::PhysicsState& UF_API create( uf::Object&, float, float );
// synchronize engine transforms to bullet transforms
void UF_API syncTo();
// synchronize bullet transforms to engine transforms
void UF_API syncFrom( float = 1 );
// apply impulse
void UF_API applyImpulse( pod::PhysicsState&, const pod::Vector3f& );
// directly move a transform
void UF_API applyMovement( pod::PhysicsState&, const pod::Vector3f& );
// directly apply a velocity
void UF_API setVelocity( pod::PhysicsState&, const pod::Vector3f& );
void UF_API applyVelocity( pod::PhysicsState&, const pod::Vector3f& );
// directly rotate a transform
void UF_API applyRotation( pod::PhysicsState&, const pod::Quaternion<>& );
void UF_API applyRotation( pod::PhysicsState&, const pod::Vector3f&, float );
// 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::PhysicsState&, bool = true );
}
}
#endif

View File

@ -0,0 +1,15 @@
#pragma once
#include <uf/config.h>
#if UF_USE_FFX_FSR
namespace ext {
namespace fsr {
extern bool UF_API initialized;
void UF_API initialize();
void UF_API tick();
void UF_API terminate();
}
}
#endif

View File

@ -16,6 +16,8 @@ namespace ext {
extern UF_API uint8_t msaa;
extern UF_API bool validation;
extern UF_API bool defaultStageBuffers;
extern UF_API bool defaultDeferBufferDestroy;
extern UF_API bool defaultCommandBufferWait;
extern UF_API size_t viewCount;
extern UF_API size_t scratchBufferAlignment;
extern UF_API size_t scratchBufferInitialSize;
@ -42,8 +44,6 @@ namespace ext {
extern UF_API bool multithreadedRecording;
extern UF_API uf::stl::string deferredMode;
extern UF_API bool deferredAliasOutputToSwapchain;
extern UF_API bool deferredSampling;
extern UF_API bool multiview;
}
@ -53,6 +53,7 @@ namespace ext {
extern UF_API bool hdr;
extern UF_API bool vxgi;
extern UF_API bool culling;
extern UF_API bool occlusion;
extern UF_API bool bloom;
extern UF_API bool rt;
@ -62,6 +63,7 @@ namespace ext {
extern UF_API uf::stl::string hdr;
extern UF_API uf::stl::string vxgi;
extern UF_API uf::stl::string culling;
extern UF_API uf::stl::string occlusion;
extern UF_API uf::stl::string bloom;
extern UF_API uf::stl::string rt;
}

View File

@ -64,6 +64,17 @@ namespace ext {
extern UF_API bool interpolate;
extern UF_API bool shared;
namespace gravity {
enum Mode {
DEFAULT,
PER_OBJECT,
UNIVERSAL
};
extern UF_API Mode mode;
extern UF_API float constant;
}
namespace debugDraw {
extern UF_API bool enabled;
extern UF_API float rate;
@ -118,4 +129,9 @@ namespace ext {
void UF_API setMass( pod::PhysicsState&, float );
}
}
namespace uf {
namespace physics {
namespace impl = ext::reactphysics;
}
}
#endif

View File

@ -25,6 +25,7 @@ namespace ext {
uf::stl::string pipeline = "";
uf::stl::vector<uf::stl::string> pipelines;
uf::stl::vector<uint8_t> outputs;
uf::stl::unordered_map<uf::stl::string, uint8_t> attachments;
struct {
float frequency = 0.0f;
@ -54,7 +55,7 @@ namespace ext {
constexpr static int32_t EXECUTE_BEGIN = -3;
constexpr static int32_t EXECUTE_END = -4;
typedef std::function<void(VkCommandBuffer)> callback_t;
typedef std::function<void(VkCommandBuffer, size_t)> callback_t;
uf::stl::unordered_map<int32_t, callback_t> commandBufferCallbacks;
void bindCallback( int32_t, const callback_t& );
@ -77,6 +78,9 @@ namespace ext {
virtual RenderTarget& getRenderTarget(size_t = 0);
virtual const RenderTarget& getRenderTarget(size_t = 0) const;
virtual const RenderTarget::Attachment& getAttachment( const uf::stl::string& ) const;
virtual size_t getAttachmentIndex( const uf::stl::string& ) const;
virtual const size_t blitters() const;
virtual ext::vulkan::Graphic* getBlitter(size_t = 0);
virtual uf::stl::vector<ext::vulkan::Graphic*> getBlitters();

View File

@ -81,8 +81,6 @@ namespace ext {
extern UF_API bool multithreadedRecording;
extern UF_API uf::stl::string deferredMode;
extern UF_API bool deferredAliasOutputToSwapchain;
extern UF_API bool deferredSampling;
extern UF_API bool multiview;
}
@ -92,6 +90,7 @@ namespace ext {
extern UF_API bool hdr;
extern UF_API bool vxgi;
extern UF_API bool culling;
extern UF_API bool occlusion;
extern UF_API bool bloom;
extern UF_API bool rt;
@ -101,6 +100,7 @@ namespace ext {
extern UF_API uf::stl::string hdr;
extern UF_API uf::stl::string vxgi;
extern UF_API uf::stl::string culling;
extern UF_API uf::stl::string occlusion;
extern UF_API uf::stl::string bloom;
extern UF_API uf::stl::string rt;
}

View File

@ -45,9 +45,9 @@
#define UF_ASSERT_BREAK(condition, ...) if ( !(condition) ) { UF_MSG_ERROR("Assert failed: {}", #condition); break; }
#define UF_ASSERT_SAFE(condition) if ( !(condition) ) { UF_MSG_ERROR("Assertion failed: {}", #condition); }
#define UF_ASSERT_MSG(condition, ...) if ( !(condition) ) { UF_EXCEPTION("Assert failed: {} {}", #condition, __VA_ARGS__); }
#define UF_ASSERT_BREAK_MSG(condition, ...) if ( !(condition) ) { UF_MSG_ERROR("Assert failed: {} {}", #condition, __VA_ARGS__); break; }
#define UF_ASSERT_SAFE_MSG(condition, ...) if ( !(condition) ) { UF_MSG_ERROR("Assertion failed: {} {}", #condition, __VA_ARGS__); }
#define UF_ASSERT_MSG(condition, ...) if ( !(condition) ) { UF_EXCEPTION("Assert failed: {} {}", #condition, ::fmt::format(__VA_ARGS__)); }
#define UF_ASSERT_BREAK_MSG(condition, ...) if ( !(condition) ) { UF_MSG_ERROR("Assert failed: {} {}", #condition, ::fmt::format(__VA_ARGS__)); break; }
#define UF_ASSERT_SAFE_MSG(condition, ...) if ( !(condition) ) { UF_MSG_ERROR("Assertion failed: {} {}", #condition, ::fmt::format(__VA_ARGS__)); }
#define UF_TIMER_TRACE_INIT() uf::Timer<long long> TIMER_TRACE;

View File

@ -22,50 +22,8 @@ namespace spec {
pod::Hook::userdata_t payload;
};
protected:
// Window::Events m_events;
std::queue<Event> m_events;
public:
#if 0
// C-tors
void create( const spec::uni::Window::vector_t& size, const spec::uni::Window::title_t& title = L"Window" ) {} ;// = 0;
// D-tors
void terminate();/* = 0;*/
// Gets
spec::uni::Window::vector_t getPosition() const;/* = 0;*/
spec::uni::Window::vector_t getSize() const;/* = 0;*/
size_t getRefreshRate() const;/* = 0;*/
// Attribute modifiers
void setPosition( const spec::uni::Window::vector_t& position );/* = 0;*/
void centerWindow();/* = 0;*/
void setMousePosition( const spec::uni::Window::vector_t& position );/* = 0;*/
void setSize( const spec::uni::Window::vector_t& size );/* = 0;*/
void setTitle( const spec::uni::Window::title_t& title );/* = 0;*/
void setIcon( const spec::uni::Window::vector_t& size, uint8_t* pixels );/* = 0;*/
void setVisible( bool visibility );/* = 0;*/
void setCursorVisible( bool visibility );/* = 0;*/
void setKeyRepeatEnabled( bool state );/* = 0;*/
void setMouseGrabbed( bool state );/* = 0;*/
void requestFocus();/* = 0;*/
bool hasFocus() const;/* = 0;*/
// Update
void bufferInputs();/* = 0;*/
static bool isKeyPressed( const uf::stl::string& );
#endif
#if 0
void processEvents();
void pushEvent( const uf::Hooks::name_t& name, const uf::stl::string& payload );
void pushEvent( const uf::Hooks::name_t& name, const ext::json::Value& payload );
void pushEvent( const uf::Hooks::name_t& name, const uf::Serializer& payload );
void pushEvent( const uf::Hooks::name_t& name, const pod::Hook::userdata_t& payload );
void pushEvent( const pod::Hook::userdata_t& payload );
template<typename T> void pushEvent( const uf::Hooks::name_t& name, const T& payload );
bool pollEvents( bool block = false );
#endif
void pushEvent( const uf::Hooks::name_t& name, const pod::Hook::userdata_t& payload );
template<typename T> void pushEvent( const uf::Hooks::name_t& name, const T& payload );
static bool focused;

View File

@ -12,12 +12,6 @@
namespace uf {
namespace physics {
#if UF_USE_BULLET
namespace impl = ext::bullet;
#elif UF_USE_REACTPHYSICS
namespace impl = ext::reactphysics;
#endif
typedef pod::Math::num_t num_t;
namespace time = uf::time;

View File

@ -55,9 +55,9 @@ bool uf::Asset::assertionLoad = true;
void uf::Asset::processQueue() {
#if UF_ASSET_MULTITHREAD
auto tasks = uf::thread::schedule(true, true);
auto tasks = uf::thread::schedule(true, false);
#else
auto tasks = uf::thread::schedule(false, true);
auto tasks = uf::thread::schedule(false);
#endif
mutex.lock();

View File

@ -234,7 +234,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
UF_ASSERT( indirect );
if ( indirect ) {
uf::stl::string compShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/cull.comp.spv");
uf::stl::string compShaderFilename = graph.metadata["shaders"][uf::renderer::settings::pipelines::names::culling]["compute"].as<uf::stl::string>("/graph/cull.comp.spv");
{
graphic.material.metadata.autoInitializeUniformBuffers = false;
compShaderFilename = entity.resolveURI( compShaderFilename, root );
@ -246,12 +246,36 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
auto& shader = graphic.material.getShader("compute", uf::renderer::settings::pipelines::names::culling);
shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
#if UF_USE_VULKAN
shader.buffers.emplace_back( indirect->alias() );
#endif
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
}
}
if ( uf::renderer::settings::pipelines::occlusion ) {
uf::renderer::Buffer* indirect = NULL;
for ( auto& buffer : graphic.buffers ) if ( !indirect && buffer.usage & uf::renderer::enums::Buffer::INDIRECT ) indirect = &buffer;
UF_ASSERT( indirect );
if ( indirect ) {
uf::stl::string compShaderFilename = graph.metadata["shaders"][uf::renderer::settings::pipelines::names::occlusion]["compute"].as<uf::stl::string>("/graph/occlusion.comp.spv");
{
graphic.material.metadata.autoInitializeUniformBuffers = false;
compShaderFilename = entity.resolveURI( compShaderFilename, root );
graphic.material.attachShader(compShaderFilename, uf::renderer::enums::Shader::COMPUTE, uf::renderer::settings::pipelines::names::occlusion);
graphic.material.metadata.autoInitializeUniformBuffers = true;
}
graphic.descriptor.inputs.dispatch = { graphic.descriptor.inputs.indirect.count, 1, 1 };
auto& shader = graphic.material.getShader("compute", uf::renderer::settings::pipelines::names::occlusion);
auto& renderMode = uf::renderer::getRenderMode( graphic.descriptor.renderMode, true );
auto& renderTarget = renderMode.getRenderTarget( graphic.descriptor.renderTarget );
shader.buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
shader.buffers.emplace_back( indirect->alias() );
shader.buffers.emplace_back( uf::graph::storage.buffers.instance.alias() );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[0] ); // alias ID buffer
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[5] ); // alias depth buffer
}
}
if ( geometryShaderFilename != "" && uf::renderer::device.enabledFeatures.geometryShader ) {
geometryShaderFilename = entity.resolveURI( geometryShaderFilename, root );
graphic.material.attachShader(geometryShaderFilename, uf::renderer::enums::Shader::GEOMETRY);
@ -259,7 +283,7 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
// depth only pipeline
{
graphic.material.metadata.autoInitializeUniformBuffers = false;
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/depth.frag.spv");
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["depth"]["fragmment"].as<uf::stl::string>("/graph/depth.frag.spv");
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );
graphic.material.attachShader(fragmentShaderFilename, uf::renderer::enums::Shader::FRAGMENT, "depth");
graphic.material.metadata.autoInitializeUniformBuffers = true;
@ -290,9 +314,9 @@ void uf::graph::initializeGraphics( pod::Graph& graph, uf::Object& entity, uf::M
}
// vxgi pipeline
if ( uf::renderer::settings::pipelines::vxgi ) {
uf::stl::string vertexShaderFilename = graph.metadata["shaders"]["vertex"].as<uf::stl::string>("/graph/base.vert.spv");
uf::stl::string geometryShaderFilename = graph.metadata["shaders"]["geometry"].as<uf::stl::string>("/graph/voxelize.geom.spv");
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"]["fragment"].as<uf::stl::string>("/graph/voxelize.frag.spv");
uf::stl::string vertexShaderFilename = graph.metadata["shaders"][uf::renderer::settings::pipelines::names::vxgi]["vertex"].as<uf::stl::string>("/graph/base.vert.spv");
uf::stl::string geometryShaderFilename = graph.metadata["shaders"][uf::renderer::settings::pipelines::names::vxgi]["geometry"].as<uf::stl::string>("/graph/voxelize.geom.spv");
uf::stl::string fragmentShaderFilename = graph.metadata["shaders"][uf::renderer::settings::pipelines::names::vxgi]["fragment"].as<uf::stl::string>("/graph/voxelize.frag.spv");
{
fragmentShaderFilename = entity.resolveURI( fragmentShaderFilename, root );

View File

@ -1,588 +0,0 @@
#if UF_USE_BULLET
#include <uf/ext/bullet/bullet.h>
#include <uf/utils/math/physics.h>
#include <uf/utils/renderer/renderer.h>
#include <uf/utils/graphic/graphic.h>
#include <uf/engine/scene/scene.h>
#include <uf/engine/graph/graph.h>
#include <BulletCollision/CollisionShapes/btTriangleShape.h>
namespace {
struct VertexLine {
pod::Vector3f position;
pod::Vector3f color;
static UF_API uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
};
UF_VERTEX_DESCRIPTOR(VertexLine,
UF_VERTEX_DESCRIPTION(VertexLine, R32G32B32_SFLOAT, position)
UF_VERTEX_DESCRIPTION(VertexLine, R32G32B32_SFLOAT, color)
);
class BulletDebugDrawer : public btIDebugDraw {
protected:
int m;
uf::Mesh mesh;
public:
virtual void drawLine( const btVector3& from, const btVector3& to, const btVector3& color ) {
drawLine( from, to, color, color );
}
virtual void drawLine( const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor ) {
uf::stl::vector<VertexLine> vertices;
{
auto& vertex = vertices.emplace_back();
vertex.position = { from.getX(), from.getY(), from.getZ() };
vertex.color = { fromColor.getX(), fromColor.getY(), fromColor.getZ() };
}
{
auto& vertex = vertices.emplace_back();
vertex.position = { to.getX(), to.getY(), to.getZ() };
vertex.color = { toColor.getX(), toColor.getY(), toColor.getZ() };
}
if ( !mesh.hasVertex<VertexLine>() ) mesh.bind<VertexLine>();
mesh.insertVertices(vertices);
}
virtual void drawContactPoint(const btVector3&, const btVector3&, btScalar, int, const btVector3&) {
}
virtual void reportErrorWarning(const char* str ) {
UF_MSG_WARNING("[Bullet] {}", str);
}
virtual void draw3dText(const btVector3& , const char* str ) {
}
virtual void setDebugMode(int p) {
m = p;
}
virtual void clearLines() {
for ( auto& buffer : mesh.buffers ) buffer.clear();
mesh.vertex.count = 0;
mesh.index.count = 0;
}
virtual void flushLines() {
auto& scene = uf::scene::getCurrentScene();
ext::bullet::debugDraw( scene );
}
int getDebugMode(void) const { return m; }
uf::Mesh& getMesh() { return mesh; }
const uf::Mesh& getMesh() const { return mesh; }
};
void UF_API ext::bullet::debugDraw( uf::Object& object ) {
auto& mesh = ext::bullet::debugDrawer.getMesh();
if ( !mesh.vertex.count ) return;
bool create = !object.hasComponent<uf::Graphic>();
auto& graphic = object.getComponent<uf::Graphic>();
graphic.process = false;
if ( create ) {
graphic.device = &uf::renderer::device;
graphic.material.device = &uf::renderer::device;
graphic.descriptor.cullMode = uf::renderer::enums::CullMode::NONE;
graphic.material.metadata.autoInitializeUniformBuffers = false;
graphic.material.attachShader(uf::io::root + "/shaders/bullet/base.vert.spv", uf::renderer::enums::Shader::VERTEX);
graphic.material.attachShader(uf::io::root + "/shaders/bullet/base.frag.spv", uf::renderer::enums::Shader::FRAGMENT);
graphic.material.metadata.autoInitializeUniformBuffers = true;
graphic.material.getShader("vertex").buffers.emplace_back( uf::graph::storage.buffers.camera.alias() );
graphic.initialize(ext::bullet::debugDrawLayer);
graphic.initializeMesh( mesh );
graphic.descriptor.topology = uf::renderer::enums::PrimitiveTopology::LINE_LIST;
graphic.descriptor.fill = uf::renderer::enums::PolygonMode::LINE;
graphic.descriptor.lineWidth = ext::bullet::debugDrawLineWidth;
} else {
if ( graphic.updateMesh( mesh ) ) {
graphic.getPipeline().update( graphic );
}
}
graphic.process = true;
}
}
size_t ext::bullet::iterations = 1;
size_t ext::bullet::substeps = 12;
float ext::bullet::timescale = 1.0f;
size_t ext::bullet::defaultMaxCollisionAlgorithmPoolSize = 65535;
size_t ext::bullet::defaultMaxPersistentManifoldPoolSize = 65535;
bool ext::bullet::debugDrawEnabled = false;
float ext::bullet::debugDrawRate = 1.0f;
uf::stl::string ext::bullet::debugDrawLayer = "";
float ext::bullet::debugDrawLineWidth = 1.0f;
namespace ext {
namespace bullet {
btDefaultCollisionConstructionInfo constructionInfo;
btDefaultCollisionConfiguration* collisionConfiguration = NULL;
btCollisionDispatcher* dispatcher = NULL;
btBroadphaseInterface* overlappingPairCache = NULL;
btSequentialImpulseConstraintSolver* solver = NULL;
btDiscreteDynamicsWorld* dynamicsWorld = NULL;
btAlignedObjectArray<btCollisionShape*> collisionShapes;
uf::stl::unordered_map<btRigidBody*, size_t> rigidBodyMap;
BulletDebugDrawer debugDrawer;
}
}
#if !UF_ENV_DREAMCAST
static bool contactCallback(btManifoldPoint &ManifoldPoint, const btCollisionObjectWrapper *Object0, int PartID0, int Index0, const btCollisionObjectWrapper *Object1, int PartID1, int Index1) {
if( Object1->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE ) return false;
/*
pod::Vector3f Before = {
ManifoldPoint.m_normalWorldOnB.getX(),
ManifoldPoint.m_normalWorldOnB.getY(),
ManifoldPoint.m_normalWorldOnB.getZ(),
};
*/
btAdjustInternalEdgeContacts(ManifoldPoint, Object1, Object0, PartID1, Index1);
btAdjustInternalEdgeContacts(ManifoldPoint, Object0, Object1, PartID0, Index0);
/*
pod::Vector3f After = {
ManifoldPoint.m_normalWorldOnB.getX(),
ManifoldPoint.m_normalWorldOnB.getY(),
ManifoldPoint.m_normalWorldOnB.getZ(),
};
*/
return false;
}
#endif
void ext::bullet::initialize() {
ext::bullet::constructionInfo = btDefaultCollisionConstructionInfo();
ext::bullet::constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize = ext::bullet::defaultMaxCollisionAlgorithmPoolSize;
ext::bullet::constructionInfo.m_defaultMaxPersistentManifoldPoolSize = ext::bullet::defaultMaxPersistentManifoldPoolSize;
ext::bullet::collisionConfiguration = new btDefaultCollisionConfiguration(ext::bullet::constructionInfo);
ext::bullet::dispatcher = new btCollisionDispatcher(ext::bullet::collisionConfiguration);
ext::bullet::overlappingPairCache = new btDbvtBroadphase(); // new btAxis3Sweep();
ext::bullet::solver = new btSequentialImpulseConstraintSolver;
ext::bullet::dynamicsWorld = new btDiscreteDynamicsWorld(ext::bullet::dispatcher, ext::bullet::overlappingPairCache, ext::bullet::solver, ext::bullet::collisionConfiguration);
ext::bullet::dynamicsWorld->setGravity(btVector3(0, -9.81, 0));
ext::bullet::debugDrawer.setDebugMode(btIDebugDraw::DBG_DrawWireframe);
ext::bullet::dynamicsWorld->setDebugDrawer(&ext::bullet::debugDrawer);
auto& mesh = ext::bullet::debugDrawer.getMesh();
mesh.bind<VertexLine>();
#if !UF_ENV_DREAMCAST
gContactAddedCallback = contactCallback;
#endif
}
void ext::bullet::tick( float delta ) { if ( delta == 0.0f ) delta = uf::physics::time::delta;
ext::bullet::syncTo();
static float accumulator = 0;
static const float timeStep = 1.0f / 60.0f;
accumulator += uf::physics::time::delta;
while ( accumulator >= timeStep ) {
ext::bullet::dynamicsWorld->stepSimulation( delta, ext::bullet::substeps, timeStep );
accumulator -= timeStep;
}
/*
delta = delta * ext::bullet::timescale / ext::bullet::iterations;
for ( size_t i = 0; i < ext::bullet::iterations; ++i ) {
ext::bullet::dynamicsWorld->stepSimulation(delta, ext::bullet::substeps, delta / ext::bullet::substeps);
}
*/
ext::bullet::syncFrom();
TIMER(ext::bullet::debugDrawRate, ext::bullet::debugDrawEnabled ) {
ext::bullet::dynamicsWorld->debugDrawWorld();
}
}
void ext::bullet::terminate() {
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) {
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState()) delete body->getMotionState();
ext::bullet::dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
for ( size_t i = 0; i < ext::bullet::collisionShapes.size(); ++i ) {
btCollisionShape* shape = ext::bullet::collisionShapes[i];
ext::bullet::collisionShapes[i] = NULL;
delete shape;
}
if ( ext::bullet::dynamicsWorld ) delete ext::bullet::dynamicsWorld;
if ( ext::bullet::solver ) delete ext::bullet::solver;
if ( ext::bullet::overlappingPairCache ) delete ext::bullet::overlappingPairCache;
if ( ext::bullet::dispatcher ) delete ext::bullet::dispatcher;
if ( ext::bullet::collisionConfiguration ) delete ext::bullet::collisionConfiguration;
ext::bullet::collisionShapes.clear();
}
void ext::bullet::syncTo() {
// update bullet transforms
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if ( !body || !body->getMotionState() ) return;
uf::Object* entity = (uf::Object*) body->getUserPointer();
if ( !entity || !entity->isValid() || !entity->hasComponent<pod::PhysicsState>() ) continue;
auto& state = entity->getComponent<pod::PhysicsState>();
if ( !state.shared ) continue;
auto& physics = entity->getComponent<pod::Physics>();
auto model = uf::transform::model( state.transform );
btTransform t = body->getWorldTransform();
t.setFromOpenGLMatrix(&model[0]);
// t.setOrigin( btVector3( transform.position.x, transform.position.y, transform.position.z ) );
// t.setRotation( btQuaternion( transform.orientation.x, transform.orientation.y, transform.orientation.z, transform.orientation.w ) );
body->setWorldTransform(t);
body->setCenterOfMassTransform(t);
body->setLinearVelocity( btVector3( physics.linear.velocity.x, physics.linear.velocity.y, physics.linear.velocity.z ) );
}
}
void ext::bullet::syncFrom() {
for ( int i = ext::bullet::dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {
btCollisionObject* obj = ext::bullet::dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if ( !body || !body->getMotionState() ) return;
btTransform t = body->getWorldTransform();
// body->getMotionState()->getWorldTransform(t);
uf::Object* object = (uf::Object*) body->getUserPointer();
if ( !object || !object->isValid() || !object->hasComponent<pod::PhysicsState>() ) continue;
auto& state = object->getComponent<pod::PhysicsState>();;
auto& transform = object->getComponent<pod::Transform<>>();
auto& physics = object->getComponent<pod::Physics>();
/*state.*/transform.position.x = t.getOrigin().getX();
/*state.*/transform.position.y = t.getOrigin().getY();
/*state.*/transform.position.z = t.getOrigin().getZ();
// state transform is an offset, un-offset
if ( state.transform.reference ) {
transform.position -= state.transform.position;
}
/*state.*/transform.orientation.x = t.getRotation().getX();
/*state.*/transform.orientation.y = t.getRotation().getY();
/*state.*/transform.orientation.z = t.getRotation().getZ();
/*state.*/transform.orientation.w = t.getRotation().getW();
physics.linear.velocity.x = body->getLinearVelocity().getX();
physics.linear.velocity.y = body->getLinearVelocity().getY();
physics.linear.velocity.z = body->getLinearVelocity().getZ();
physics.rotational.velocity.x = body->getAngularVelocity().getX();
physics.rotational.velocity.y = body->getAngularVelocity().getY();
physics.rotational.velocity.z = body->getAngularVelocity().getZ();
transform = uf::transform::reorient( transform );
}
}
pod::PhysicsState& ext::bullet::create( uf::Object& object ) {
auto& collider = object.getComponent<pod::PhysicsState>();
collider.uid = object.getUid();
collider.pointer = &object;
collider.transform.reference = &object.getComponent<pod::Transform<>>();
collider.shared = true;
return collider;
}
void ext::bullet::attach( pod::PhysicsState& collider ) {
if ( !collider.shape ) return;
auto model = uf::transform::model( collider.transform );
btTransform t;
t.setFromOpenGLMatrix(&model[0]);
// t.setIdentity();
// t.setOrigin(btVector3(collider.transform->position.x, collider.transform->position.y, collider.transform->position.z));
// t.setRotation(btQuaternion(collider.transform->orientation.x, collider.transform->orientation.y, collider.transform->orientation.z, collider.transform->orientation.w));
btVector3 inertia(collider.stats.inertia.x, collider.stats.inertia.y, collider.stats.inertia.z);
btDefaultMotionState* motion = new btDefaultMotionState(t);
if ( collider.stats.mass != 0.0f ) collider.shape->calculateLocalInertia(collider.stats.mass, inertia);
btRigidBody::btRigidBodyConstructionInfo info(collider.stats.mass, motion, collider.shape, inertia);
collider.body = new btRigidBody(info);
collider.body->setUserPointer((void*) collider.pointer);
collider.body->setRestitution(collider.stats.restitution);
collider.body->setFriction(collider.stats.friction);
collider.body->setGravity( btVector3( collider.stats.gravity.x, collider.stats.gravity.y, collider.stats.gravity.z ) );
/*
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | collider.stats.flags);
if ( collider.stats.mass != 0.0f ) {
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | ~btCollisionObject::CF_STATIC_OBJECT);
} else {
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
}
collider.body->activate(true);
collider.body->setActivationState(DISABLE_DEACTIVATION);
*/
ext::bullet::dynamicsWorld->addRigidBody(collider.body);
ext::bullet::collisionShapes.push_back(collider.shape);
}
void ext::bullet::detach( pod::PhysicsState& collider ) {
if ( !collider.body || !collider.shape ) return;
ext::bullet::dynamicsWorld->removeCollisionObject( collider.body );
}
pod::PhysicsState& ext::bullet::create( uf::Object& object, const uf::Mesh& mesh, bool dynamic ) {
btTriangleIndexVertexArray* bMesh = new btTriangleIndexVertexArray();
if ( mesh.index.count ) {
uf::Mesh::Attribute vertexAttribute;
for ( auto& attribute : mesh.vertex.attributes ) if ( attribute.descriptor.name == "position" ) { vertexAttribute = attribute; break; }
UF_ASSERT( vertexAttribute.descriptor.name == "position" );
auto& indexAttribute = mesh.index.attributes.front();
PHY_ScalarType indexType = PHY_INTEGER;
PHY_ScalarType vertexType = PHY_FLOAT;
switch ( mesh.index.size ) {
case sizeof(uint8_t): indexType = PHY_UCHAR; break;
case sizeof(uint16_t): indexType = PHY_SHORT; break;
case sizeof(uint32_t): indexType = PHY_INTEGER; break;
default: UF_EXCEPTION("unsupported index type"); break;
}
btIndexedMesh iMesh;
if ( mesh.indirect.count ) {
uf::Mesh::Attribute remappedVertexAttribute = vertexAttribute;
uf::Mesh::Attribute remappedIndexAttribute = indexAttribute;
uf::Mesh::Input remappedVertexInput;
uf::Mesh::Input remappedIndexInput;
for ( auto i = 0; i < mesh.indirect.count; ++i ) {
remappedVertexInput = mesh.remapVertexInput( i );
remappedIndexInput = mesh.remapIndexInput( i );
// remappedVertexAttribute = mesh.remapVertexAttribute( vertexAttribute, i );
// remappedIndexAttribute = mesh.remapIndexAttribute( indexAttribute, i );
iMesh.m_numTriangles = remappedIndexInput.count / 3;
iMesh.m_triangleIndexBase = (const uint8_t*) remappedIndexAttribute.pointer + remappedIndexAttribute.stride * remappedIndexInput.first;
iMesh.m_triangleIndexStride = remappedIndexAttribute.stride * 3;
iMesh.m_numVertices = remappedVertexInput.count;
iMesh.m_vertexBase = (const uint8_t*) remappedVertexAttribute.pointer + remappedVertexAttribute.stride * remappedVertexInput.first;
iMesh.m_vertexStride = remappedVertexAttribute.stride;
iMesh.m_indexType = indexType;
iMesh.m_vertexType = vertexType;
bMesh->addIndexedMesh( iMesh, indexType );
}
} else {
iMesh.m_numTriangles = mesh.index.count / 3;
iMesh.m_triangleIndexBase = (const uint8_t*) indexAttribute.pointer + indexAttribute.stride * mesh.index.count;
iMesh.m_triangleIndexStride = indexAttribute.stride * 3;
iMesh.m_numVertices = mesh.vertex.count;
iMesh.m_vertexBase = (const uint8_t*) vertexAttribute.pointer + vertexAttribute.stride * mesh.vertex.count;
iMesh.m_vertexStride = vertexAttribute.stride;
iMesh.m_indexType = indexType;
iMesh.m_vertexType = vertexType;
bMesh->addIndexedMesh( iMesh, indexType );
}
} else UF_EXCEPTION("to-do: not require indices for meshes");
auto& collider = ext::bullet::create( object );
collider.shape = new btBvhTriangleMeshShape( bMesh, true, true );
collider.stats.mass = 0;
ext::bullet::attach( collider );
auto& transform = object.getComponent<pod::Transform<>>();
auto model = uf::transform::model( collider.transform );
btTransform t = collider.body->getWorldTransform();
t.setFromOpenGLMatrix(&model[0]);
collider.body->setWorldTransform(t);
collider.body->setCenterOfMassTransform(t);
/*
btBvhTriangleMeshShape* triangleMeshShape = (btBvhTriangleMeshShape*) collider.shape;
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
triangleInfoMap->m_edgeDistanceThreshold = 0.01f;
triangleInfoMap->m_maxEdgeAngleThreshold = SIMD_HALF_PI*0.25;
if ( !false ) {
btGenerateInternalEdgeInfo( triangleMeshShape, triangleInfoMap );
collider.body->setCollisionFlags(collider.body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
}
*/
return collider;
}
pod::PhysicsState& ext::bullet::create( uf::Object& object, const pod::Vector3f& extent ) {
auto& collider = ext::bullet::create( object );
collider.shape = new btBoxShape(btVector3(abs(extent.x), abs(extent.y), abs(extent.z)));
ext::bullet::attach( collider );
auto& transform = object.getComponent<pod::Transform<>>();
auto model = uf::transform::model( collider.transform );
// collider.body->setContactProcessingThreshold(0.0);
// collider.body->setAngularFactor(0.0);
// collider.body->setCcdMotionThreshold(1e-7);
// collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
return collider;
}
uf::stl::vector<pod::PhysicsState>& ext::bullet::create( uf::Object& object, const uf::stl::vector<pod::Instance::Bounds>& bounds ) {
auto& colliders = object.getComponent<uf::stl::vector<pod::PhysicsState>>();
colliders.reserve(colliders.size() + bounds.size());
auto& transform = object.getComponent<pod::Transform<>>();
auto flatten = uf::transform::flatten( transform );
auto model = uf::transform::model( transform );
for ( auto bound : bounds ) {
pod::Vector3f center = (bound.max + bound.min) * 0.5f;
pod::Vector3f corner = (bound.max - bound.min) * 0.5f;
center.x = -center.x;
center = uf::matrix::multiply<float>( model, center, 1.0f );
corner = uf::matrix::multiply<float>( model, corner, 0.0f );
auto& collider = colliders.emplace_back();
collider.transform = flatten;
collider.transform.position = center;
collider.transform.reference = NULL;
collider.shape = new btBoxShape(btVector3(corner.x, corner.y, corner.z));
ext::bullet::attach( collider );
// collider.body->setContactProcessingThreshold(0.0);
// collider.body->setAngularFactor(0.0);
// collider.body->setCcdMotionThreshold(1e-7);
// collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
}
return colliders;
}
pod::PhysicsState& ext::bullet::create( uf::Object& object, float radius, float height ) {
auto& collider = ext::bullet::create( object );
collider.shape = new btCapsuleShape(radius, height);
ext::bullet::attach( collider );
auto& transform = object.getComponent<pod::Transform<>>();
auto model = uf::transform::model( collider.transform );
collider.body->setContactProcessingThreshold(0.0);
collider.body->setAngularFactor(0.0);
collider.body->setCcdMotionThreshold(1e-7);
collider.body->setCcdSweptSphereRadius(0.25 * 0.2);
return collider;
}
void UF_API ext::bullet::setVelocity( pod::PhysicsState& collider, const pod::Vector3f& v ) {
if ( !collider.body ) return;
collider.body->activate(true);
if ( collider.shared ) {
auto& physics = collider.pointer->getComponent<pod::Physics>();
physics.linear.velocity = v;
} else {
collider.body->setLinearVelocity( btVector3( v.x, v.y, v.z ) );
}
}
void UF_API ext::bullet::applyImpulse( pod::PhysicsState& collider, const pod::Vector3f& v ) {
if ( !collider.body ) return;
collider.body->activate(true);
collider.body->applyCentralImpulse( btVector3( v.x, v.y, v.z ) /** uf::physics::time::delta*/ );
}
void UF_API ext::bullet::applyMovement( pod::PhysicsState& collider, const pod::Vector3f& v ) {
if ( !collider.body ) return;
collider.body->activate(true);
btTransform transform = collider.body->getWorldTransform();
// collider.body->getMotionState()->getWorldTransform(transform);
transform.setOrigin( transform.getOrigin() + btVector3( v.x, v.y, v.z ) * uf::physics::time::delta );
// collider.body->getMotionState()->setWorldTransform(transform);
collider.body->setWorldTransform(transform);
collider.body->setCenterOfMassTransform(transform);
}
void UF_API ext::bullet::applyVelocity( pod::PhysicsState& collider, const pod::Vector3f& v ) {
if ( !collider.body ) return;
collider.body->activate(true);
if ( collider.shared ) {
auto& physics = collider.pointer->getComponent<pod::Physics>();
physics.linear.velocity += v;
} else {
collider.body->setLinearVelocity( collider.body->getLinearVelocity() + btVector3( v.x, v.y, v.z ) );
}
}
void UF_API ext::bullet::applyRotation( pod::PhysicsState& collider, const pod::Vector3f& axis, float delta ) {
ext::bullet::applyRotation( collider, uf::quaternion::axisAngle( axis, delta ) );
}
void UF_API ext::bullet::applyRotation( pod::PhysicsState& collider, const pod::Quaternion<>& q ) {
if ( !collider.body ) return;
collider.body->activate(true);
if ( collider.shared ) {
auto& transform = collider.pointer->getComponent<pod::Transform<>>();
uf::transform::rotate( transform, q );
return;
}
btTransform transform = collider.body->getWorldTransform();
// collider.body->getMotionState()->getWorldTransform(transform);
pod::Quaternion<> orientation = uf::vector::normalize(uf::quaternion::multiply({
transform.getRotation().getX(),
transform.getRotation().getY(),
transform.getRotation().getZ(),
transform.getRotation().getW(),
}, q));
transform.setRotation( btQuaternion( orientation.x, orientation.y, orientation.z, orientation.w ) );
// collider.body->getMotionState()->setWorldTransform(transform);
collider.body->setWorldTransform(transform);
collider.body->setCenterOfMassTransform(transform);
}
void UF_API ext::bullet::activateCollision( pod::PhysicsState& collider, bool enabled ) {
if ( !collider.body ) return;
collider.body->activate(enabled);
}
float UF_API ext::bullet::rayCast( const pod::Vector3f& from, const pod::Vector3f& to ) {
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 -1.0;
/*
float length = uf::vector::distanceSquared( from, to );
float depth = uf::vector::distanceSquared( from, pod::Vector3f{ res.m_hitPointWorld.getX(), res.m_hitPointWorld.getY(), res.m_hitPointWorld.getZ() } );
return depth / length;
*/
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;
}
#endif

200
engine/src/ext/ffx/fsr.cpp Normal file
View File

@ -0,0 +1,200 @@
#include <uf/ext/ffx/fsr.h>
#if UF_USE_FFX_FSR
#include <ffx_fsr2/ffx_fsr2.h>
#include <ffx_fsr2/vk/ffx_fsr2_vk.h>
#include <uf/utils/renderer/renderer.h>
#include <cfloat>
namespace {
uf::stl::vector<uint8_t> scratchBuffer;
FfxFsr2Context context;
FfxFsr2ContextDescription contextDescription;
uf::stl::string FFX_ERROR_TO_STRING( FfxErrorCode code ) {
switch ( code ) {
case FFX_OK: return "OK"; break;
case FFX_ERROR_INVALID_POINTER: return "ERROR_INVALID_POINTER"; break;
case FFX_ERROR_INVALID_ALIGNMENT: return "ERROR_INVALID_ALIGNMENT"; break;
case FFX_ERROR_INVALID_SIZE: return "ERROR_INVALID_SIZE"; break;
case FFX_EOF: return "EOF"; break;
case FFX_ERROR_INVALID_PATH: return "ERROR_INVALID_PATH"; break;
case FFX_ERROR_EOF: return "ERROR_EOF"; break;
case FFX_ERROR_MALFORMED_DATA: return "ERROR_MALFORMED_DATA"; break;
case FFX_ERROR_OUT_OF_MEMORY: return "ERROR_OUT_OF_MEMORY"; break;
case FFX_ERROR_INCOMPLETE_INTERFACE: return "ERROR_INCOMPLETE_INTERFACE"; break;
case FFX_ERROR_INVALID_ENUM: return "ERROR_INVALID_ENUM"; break;
case FFX_ERROR_INVALID_ARGUMENT: return "ERROR_INVALID_ARGUMENT"; break;
case FFX_ERROR_OUT_OF_RANGE: return "ERROR_OUT_OF_RANGE"; break;
case FFX_ERROR_NULL_DEVICE: return "ERROR_NULL_DEVICE"; break;
case FFX_ERROR_BACKEND_API_ERROR: return "ERROR_BACKEND_API_ERROR"; break;
case FFX_ERROR_INSUFFICIENT_MEMORY: return "ERROR_INSUFFICIENT_MEMORY"; break;
}
return ::fmt::format("{}", (void*) code);
}
#define FFX_ERROR_CHECK(f) { auto error = f; if ( error != FFX_OK) UF_MSG_ERROR("FFXFSR2 Error {}: {}", #f, FFX_ERROR_TO_STRING(error)); }
void draw(VkCommandBuffer commandBuffer, size_t swapchainIndex) {
auto& deferredRenderMode = uf::renderer::getRenderMode("", true);
auto& swapchainRenderMode = uf::renderer::getRenderMode("Swapchain", true);
#if 0
// reactive mask
FfxFsr2GenerateReactiveDescription generateReactiveParameters;
generateReactiveParameters.commandList = ffxGetCommandListVK(pCommandList);
generateReactiveParameters.colorOpaqueOnly = ffxGetTextureResourceVK(&::context, cameraSetup.opaqueOnlyColorResource->Resource(), cameraSetup.opaqueOnlyColorResourceView, cameraSetup.opaqueOnlyColorResource->GetWidth(), cameraSetup.opaqueOnlyColorResource->GetHeight(), cameraSetup.opaqueOnlyColorResource->GetFormat(), L"FSR2_OpaqueOnlyColorResource");
generateReactiveParameters.colorPreUpscale = ffxGetTextureResourceVK(&::context, cameraSetup.unresolvedColorResource->Resource(), cameraSetup.unresolvedColorResourceView, cameraSetup.unresolvedColorResource->GetWidth(), cameraSetup.unresolvedColorResource->GetHeight(), cameraSetup.unresolvedColorResource->GetFormat(), L"FSR2_UnresolvedColorResource");
generateReactiveParameters.outReactive = ffxGetTextureResourceVK(&::context, cameraSetup.reactiveMapResource->Resource(), cameraSetup.reactiveMapResourceView, cameraSetup.reactiveMapResource->GetWidth(), cameraSetup.reactiveMapResource->GetHeight(), cameraSetup.reactiveMapResource->GetFormat(), L"FSR2_InputReactiveMap", FFX_RESOURCE_STATE_GENERIC_READ);
generateReactiveParameters.renderSize.width = pState->renderWidth;
generateReactiveParameters.renderSize.height = pState->renderHeight;
generateReactiveParameters.scale = pState->fFsr2AutoReactiveScale;
generateReactiveParameters.cutoffThreshold = pState->fFsr2AutoReactiveThreshold;
generateReactiveParameters.flags = (pState->bFsr2AutoReactiveTonemap ? FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_TONEMAP : 0) |
(pState->bFsr2AutoReactiveInverseTonemap ? FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_INVERSETONEMAP : 0) |
(pState->bFsr2AutoReactiveThreshold ? FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_THRESHOLD : 0) |
(pState->bFsr2AutoReactiveUseMax ? FFX_FSR2_AUTOREACTIVEFLAGS_USE_COMPONENTS_MAX : 0);
ffxFsr2ContextGenerateReactiveMask(&::context, &generateReactiveParameters);
#endif
#if 1
FfxFsr2DispatchDescription dispatchParameters = {};
dispatchParameters.commandList = ffxGetCommandListVK(commandBuffer);
auto& attachmentColor = deferredRenderMode.getAttachment("color");
auto& attachmentDepth = deferredRenderMode.getAttachment("depth");
auto& attachmentOutput = deferredRenderMode.getAttachment("scratch"); // swapchainRenderMode.getAttachment("color["+std::to_string(swapchainIndex)+"]");
pod::Vector2ui renderSize = {
deferredRenderMode.width > 0 ? deferredRenderMode.width : uf::renderer::settings::width,
deferredRenderMode.height > 0 ? deferredRenderMode.height : uf::renderer::settings::height,
};
pod::Vector2ui displaySize = {
swapchainRenderMode.width,
swapchainRenderMode.height,
};
dispatchParameters.color = ffxGetTextureResourceVK(&::context,
attachmentColor.image,
attachmentColor.view,
renderSize.x,
renderSize.y,
attachmentColor.descriptor.format,
L"FSR2_InputColor"
);
dispatchParameters.depth = ffxGetTextureResourceVK(&::context,
attachmentDepth.image,
attachmentDepth.view,
renderSize.x,
renderSize.y,
attachmentDepth.descriptor.format,
L"FSR2_InputDepth"
);
dispatchParameters.motionVectors = ffxGetTextureResourceVK(&::context,
nullptr,
nullptr,
1,
1,
VK_FORMAT_UNDEFINED,
L"FSR2_InputMotionVectors"
);
dispatchParameters.exposure = ffxGetTextureResourceVK(&::context,
nullptr,
nullptr,
1,
1,
VK_FORMAT_UNDEFINED,
L"FSR2_InputExposure"
);
dispatchParameters.reactive = ffxGetTextureResourceVK(&::context,
nullptr,
nullptr,
1,
1,
VK_FORMAT_UNDEFINED,
L"FSR2_InputReactiveMap"
);
dispatchParameters.transparencyAndComposition = ffxGetTextureResourceVK(&::context,
nullptr,
nullptr,
1,
1,
VK_FORMAT_UNDEFINED,
L"FSR2_TransparencyAndCompositionMap"
);
dispatchParameters.output = ffxGetTextureResourceVK(&::context,
attachmentOutput.image,
attachmentOutput.view,
displaySize.x,
displaySize.y,
attachmentOutput.descriptor.format,
L"FSR2_OutputUpscaledColor", FFX_RESOURCE_STATE_UNORDERED_ACCESS
);
dispatchParameters.jitterOffset.x = 0; // m_JitterX;
dispatchParameters.jitterOffset.y = 0; // m_JitterY;
dispatchParameters.motionVectorScale.x = 1; // (float)pState->renderWidth;
dispatchParameters.motionVectorScale.y = 1; // (float)pState->renderHeight;
dispatchParameters.reset = true; // pState->bReset;
dispatchParameters.enableSharpening = true; // pState->bUseRcas;
dispatchParameters.sharpness = 1.0f; // pState->sharpening;
dispatchParameters.frameTimeDelta = uf::time::delta;
dispatchParameters.preExposure = 1.0f;
dispatchParameters.renderSize.width = renderSize.x;
dispatchParameters.renderSize.height = renderSize.y;
dispatchParameters.cameraFar = FLT_MAX; // pState->camera.GetFarPlane();
dispatchParameters.cameraNear = 0.01f; // pState->camera.GetNearPlane();
dispatchParameters.cameraFovAngleVertical = 1.5708f; // pState->camera.GetFovV();
// pState->bReset = false;
FFX_ERROR_CHECK(ffxFsr2ContextDispatch(&::context, &dispatchParameters));
#endif
}
}
bool ext::fsr::initialized = false;
void UF_API ext::fsr::initialize() {
ffxFsr2SetInstanceFunctions( uf::renderer::device.instance, vkGetInstanceProcAddr );
scratchBuffer.resize(ffxFsr2GetScratchMemorySizeVK(uf::renderer::device.physicalDevice, uf::renderer::device.extensionProperties.device.size()));
::contextDescription.device = ffxGetDeviceVK(uf::renderer::device.logicalDevice);
::contextDescription.maxRenderSize.width = 3840; // uf::renderer::settings::width;
::contextDescription.maxRenderSize.height = 2160; // uf::renderer::settings::height;
::contextDescription.displaySize.width = uf::renderer::settings::width;
::contextDescription.displaySize.height = uf::renderer::settings::height;
::contextDescription.flags = FFX_FSR2_ENABLE_DEPTH_INVERTED |
FFX_FSR2_ENABLE_DEPTH_INFINITE |
FFX_FSR2_ENABLE_AUTO_EXPOSURE |
FFX_FSR2_ENABLE_DYNAMIC_RESOLUTION; // | FFX_FSR2_ENABLE_TEXTURE1D_USAGE;
if ( uf::renderer::settings::pipelines::hdr ) ::contextDescription.flags |= FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE;
FFX_ERROR_CHECK(ffxFsr2GetInterfaceVK( &::contextDescription.callbacks, ::scratchBuffer.data(), ::scratchBuffer.size(), uf::renderer::device.physicalDevice, &vkGetDeviceProcAddr ));
FFX_ERROR_CHECK(ffxFsr2ContextCreate( &::context, &::contextDescription ));
ext::fsr::initialized = true;
UF_MSG_DEBUG("{} x {}", ::contextDescription.maxRenderSize.width, ::contextDescription.maxRenderSize.height);
#if 0
swapchainRenderMode.bindCallback( swapchainRenderMode.CALLBACK_BEGIN, draw);
#endif
}
void UF_API ext::fsr::tick() {
if ( !ext::fsr::initialized ) return;
auto commandBuffer = uf::renderer::device.fetchCommandBuffer(uf::renderer::QueueEnum::GRAPHICS);
draw(commandBuffer, uf::renderer::states::currentBuffer);
uf::renderer::device.flushCommandBuffer(commandBuffer);
}
void UF_API ext::fsr::terminate() {
if ( !ext::fsr::initialized ) return;
FFX_ERROR_CHECK(ffxFsr2ContextDestroy( &::context ));
}
#endif

View File

@ -470,7 +470,7 @@ void ext::imgui::initialize() {
}
{
renderMode.bindCallback( 0, [&]( VkCommandBuffer commandBuffer ){
renderMode.bindCallback( 0, [&]( VkCommandBuffer commandBuffer, size_t _ ){
ImDrawData* drawData = ImGui::GetDrawData();
ImGui_ImplVulkan_RenderDrawData(drawData, commandBuffer);
});

View File

@ -21,7 +21,9 @@ uint32_t ext::opengl::settings::width = 640;
uint32_t ext::opengl::settings::height = 480;
uint8_t ext::opengl::settings::msaa = 1;
bool ext::opengl::settings::validation = false;
bool ext::opengl::settings::defaultStageBuffers = false;
bool ext::opengl::settings::defaultStageBuffers = true;
bool ext::opengl::settings::defaultDeferBufferDestroy = true;
bool ext::opengl::settings::defaultCommandBufferWait = true;
// constexpr size_t ext::opengl::settings::maxViews = 6;
size_t ext::opengl::settings::viewCount = 1;
@ -51,8 +53,6 @@ bool ext::opengl::settings::invariant::individualPipelines = true;
bool ext::opengl::settings::invariant::multithreadedRecording = true;
uf::stl::string ext::opengl::settings::invariant::deferredMode = "";
bool ext::opengl::settings::invariant::deferredAliasOutputToSwapchain = false;
bool ext::opengl::settings::invariant::deferredSampling = false;
bool ext::opengl::settings::invariant::multiview = false;
// pipelines
@ -61,6 +61,7 @@ bool ext::opengl::settings::pipelines::vsync = true;
bool ext::opengl::settings::pipelines::hdr = false;
bool ext::opengl::settings::pipelines::vxgi = false;
bool ext::opengl::settings::pipelines::culling = false;
bool ext::opengl::settings::pipelines::occlusion = false;
bool ext::opengl::settings::pipelines::bloom = false;
bool ext::opengl::settings::pipelines::rt = false;
@ -69,6 +70,7 @@ uf::stl::string ext::opengl::settings::pipelines::names::vsync = "vsync";
uf::stl::string ext::opengl::settings::pipelines::names::hdr = "hdr";
uf::stl::string ext::opengl::settings::pipelines::names::vxgi = "vxgi";
uf::stl::string ext::opengl::settings::pipelines::names::culling = "culling";
uf::stl::string ext::opengl::settings::pipelines::names::occlusion = "occlusion";
uf::stl::string ext::opengl::settings::pipelines::names::bloom = "bloom";
uf::stl::string ext::opengl::settings::pipelines::names::rt = "rt";

View File

@ -118,7 +118,7 @@ namespace {
size_t triCount = debugRenderer.getNbTriangles();
if ( !lineCount || !triCount ) return;
if ( oldCount == lineCount * 2 + triCount * 3 ) return;
// if ( oldCount == lineCount * 2 + triCount * 3 ) return;
oldCount = lineCount * 2 + triCount * 3;
auto* lines = debugRenderer.getLinesArray();
@ -191,6 +191,9 @@ float ext::reactphysics::timescale = 1.0f / 60.0f;
bool ext::reactphysics::shared = true;
bool ext::reactphysics::interpolate = true;
ext::reactphysics::gravity::Mode ext::reactphysics::gravity::mode = ext::reactphysics::gravity::Mode::UNIVERSAL;
float ext::reactphysics::gravity::constant = 6.67408e-11;
bool ext::reactphysics::debugDraw::enabled = false;
float ext::reactphysics::debugDraw::rate = 1.0f;
uf::stl::string ext::reactphysics::debugDraw::layer = "";
@ -198,7 +201,11 @@ float ext::reactphysics::debugDraw::lineWidth = 1.0f;
void ext::reactphysics::initialize() {
rp3d::PhysicsWorld::WorldSettings settings;
settings.gravity = rp3d::Vector3( 0, -9.81, 0 );
if ( ext::reactphysics::gravity::mode == ext::reactphysics::gravity::Mode::DEFAULT ) {
settings.gravity = rp3d::Vector3( 0, -9.81, 0 );
} else {
settings.gravity = rp3d::Vector3( 0, 0, 0 );
}
// ::logger = ::common.createDefaultLogger();
// size_t logLevel = static_cast<uint>(rp3d::Logger::Level::Warning) | static_cast<uint>(rp3d::Logger::Level::Error); // | static_cast<uint>(rp3d::Logger::Level::Information);
@ -222,21 +229,11 @@ void ext::reactphysics::tick( float delta ) {
ext::reactphysics::syncTo();
static float accumulator = 0;
accumulator += uf::physics::time::delta;
#if 0
delta = delta * ext::reactphysics::timescale / 12;
for ( size_t i = 0; i < 12; ++i ) {
::world->update(ext::reactphysics::timescale);
accumulator -= delta;
}
#else
while ( accumulator >= ext::reactphysics::timescale ) {
::world->update(ext::reactphysics::timescale);
accumulator -= ext::reactphysics::timescale;
}
#endif
TIMER(ext::reactphysics::debugDraw::rate, ext::reactphysics::debugDraw::enabled ) {
auto& scene = uf::scene::getCurrentScene();
@ -298,9 +295,7 @@ void ext::reactphysics::attach( pod::PhysicsState& state ) {
state.body->setType(rp3d::BodyType::STATIC);
}
if ( state.stats.gravity == pod::Vector3f{0,0,0} ) {
state.body->enableGravity(false);
}
state.body->enableGravity(state.stats.gravity != pod::Vector3f{0,0,0});
// affects air speed, bad
// state.body->setLinearDamping(state.stats.friction);
@ -442,6 +437,19 @@ pod::PhysicsState& ext::reactphysics::create( uf::Object& object, float radius,
// synchronize engine transforms to bullet transforms
void ext::reactphysics::syncTo() {
size_t count = ::world->getNbRigidBodies();
struct Body {
rp3d::RigidBody* body{};
float mass{};
pod::Vector3f position{};
};
uf::stl::vector<Body> bodies; bodies.reserve(count);
bodies.emplace_back(Body{
.body = NULL,
.mass = 5.97219e24,
.position = pod::Vector3f{ 0, -6.371e6, 0 },
});
for ( size_t i = 0; i < count; ++i ) {
auto* body = ::world->getRigidBody(i); if ( !body ) continue;
uf::Object* object = (uf::Object*) body->getUserData(); if ( !object || !object->isValid() ) continue;
@ -449,12 +457,46 @@ void ext::reactphysics::syncTo() {
if ( state.shared ) {
if ( !ext::reactphysics::interpolate ) body->setTransform(::convert(state.transform));
// body->setTransform(::convert(state.transform));
body->setLinearVelocity( ::convert(state.linear.velocity) );
body->setAngularVelocity( ::convertQ(state.rotational.velocity) );
}
// apply per-object gravities
float mass = body->getMass();
switch ( ext::reactphysics::gravity::mode ) {
case ext::reactphysics::gravity::Mode::PER_OBJECT: if ( body->isGravityEnabled() ) {
body->applyLocalForceAtCenterOfMass( ::convert(state.stats.gravity * mass) );
} break;
case ext::reactphysics::gravity::Mode::UNIVERSAL: if ( mass > 0 ) {
auto transform = ::convert( body->getTransform() );
bodies.emplace_back(Body{
.body = body,
.mass = mass,
.position = transform.position,
});
} break;
}
state.internal.previous = state.internal.current;
}
if ( ext::reactphysics::gravity::mode == ext::reactphysics::gravity::Mode::UNIVERSAL ) {
for ( auto i1 = 0; i1 < bodies.size(); ++i1 ) {
for ( auto i2 = 0; i2 < bodies.size(); ++i2 ) {
if ( i1 == i2 ) continue;
const auto& b1 = bodies[i1];
const auto& b2 = bodies[i2];
const auto direction = ::convert(uf::vector::normalize( b2.position - b1.position ));
const float G = ext::reactphysics::gravity::constant;
const float m1 = b1.mass;
const float m2 = b2.mass;
const float r2 = uf::vector::distanceSquared( b1.position, b2.position );
const float F = G * m1 * m2 / r2;
if ( b1.body ) b1.body->applyLocalForceAtCenterOfMass(direction * F);
if ( b2.body ) b2.body->applyLocalForceAtCenterOfMass(direction * -F);
}
}
}
}
// synchronize bullet transforms to engine transforms
void ext::reactphysics::syncFrom( float interp ) {
@ -523,7 +565,7 @@ void ext::reactphysics::setImpulse( pod::PhysicsState& state, const pod::Vector3
void ext::reactphysics::applyImpulse( pod::PhysicsState& state, const pod::Vector3f& v ) {
if ( !state.body ) return;
state.body->applyWorldForceAtCenterOfMass( ::convert(v) );
state.body->applyLocalForceAtCenterOfMass( ::convert(v) );
}
// directly move a transform
void ext::reactphysics::applyMovement( pod::PhysicsState& state, const pod::Vector3f& v ) {

View File

@ -107,9 +107,8 @@ size_t ext::vulkan::Buffer::getAddress() const {
return vkGetBufferDeviceAddressKHR(this->device ? *this->device : ext::vulkan::device, &info);
}
// RAII
ext::vulkan::Buffer::~Buffer() {
// this->destroy();
// this->destroy(); // bad, will get called every time a vector gets resized, buffer owners will clean it up in their own destructors
}
void ext::vulkan::Buffer::initialize( ext::vulkan::Device& device, size_t alignment ) {
this->device = &device;
@ -119,16 +118,20 @@ void ext::vulkan::Buffer::destroy(bool defer) {
if ( !device || aliased ) return;
if ( defer ) {
device->transient.buffers.emplace_back(*this);
this->aliased = true;
return;
}
if ( buffer ) {
} else if ( buffer ) {
vmaDestroyBuffer( allocator, buffer, allocation );
}
buffer = nullptr;
memory = nullptr;
this->buffer = {};
this->memory = {};
this->descriptor = {};
this->alignment = {};
this->address = {};
this->mapped = {};
this->usage = {};
this->memoryProperties = {};
this->allocation = {};
this->allocationInfo = {};
}
void ext::vulkan::Buffer::initialize( const void* data, VkDeviceSize length, VkBufferUsageFlags usage, VkMemoryPropertyFlags memoryProperties, bool stage ) {
if ( !device ) device = &ext::vulkan::device;
@ -150,7 +153,7 @@ bool ext::vulkan::Buffer::update( const void* data, VkDeviceSize length, bool st
UF_MSG_WARNING("Buffer update of {} exceeds buffer size of {}", length, allocationInfo.size );
Buffer& b = *const_cast<Buffer*>(this);
b.destroy();
b.destroy(true);
b.initialize( data, length, usage, memoryProperties, stage );
return true;
}
@ -190,7 +193,7 @@ ext::vulkan::Buffers::~Buffers() {
}
*/
void ext::vulkan::Buffers::destroy() {
for ( auto& buffer : buffers ) if ( buffer.device ) buffer.destroy();
for ( auto& buffer : buffers ) if ( buffer.device ) buffer.destroy(true);
buffers.clear();
}

View File

@ -44,6 +44,14 @@ ext::vulkan::Graphic* ext::vulkan::RenderMode::getBlitter( size_t i ) {
uf::stl::vector<ext::vulkan::Graphic*> ext::vulkan::RenderMode::getBlitters() {
return {};
}
const ext::vulkan::RenderTarget::Attachment& ext::vulkan::RenderMode::getAttachment( const uf::stl::string& name ) const {
UF_ASSERT_MSG( metadata.attachments.count(name) > 0, "attachment in `{}`: {} not found: {}", this->getName(), this->getType(), name );
return renderTarget.attachments[metadata.attachments.at(name)];
}
size_t ext::vulkan::RenderMode::getAttachmentIndex( const uf::stl::string& name ) const {
if ( metadata.attachments.count(name) == 0 ) return SIZE_MAX;
return metadata.attachments.at(name);
}
uf::Image ext::vulkan::RenderMode::screenshot( size_t attachmentID, size_t layerID ) {
uf::Image image;

View File

@ -142,7 +142,7 @@ void ext::vulkan::BaseRenderMode::createCommandBuffers( const uf::stl::vector<ex
}
// pre-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i] );
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i], i );
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
@ -165,7 +165,7 @@ void ext::vulkan::BaseRenderMode::createCommandBuffers( const uf::stl::vector<ex
vkCmdEndRenderPass(commands[i]);
// post-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i] );
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i], i );
// need to transfer it back, if they differ
if ( ext::vulkan::device.queueFamilyIndices.graphics != ext::vulkan::device.queueFamilyIndices.present ) {
@ -278,6 +278,7 @@ void ext::vulkan::BaseRenderMode::initialize( Device& device ) {
// uint32_t width = windowSize.x; //this->width > 0 ? this->width : windowSize.x;
// uint32_t height = windowSize.y; //this->height > 0 ? this->height : windowSize.y;
size_t attachmentIndex = 0;
for ( size_t i = 0; i < images.size(); ++i ) {
VkImageViewCreateInfo colorAttachmentView = {};
colorAttachmentView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
@ -306,9 +307,12 @@ void ext::vulkan::BaseRenderMode::initialize( Device& device ) {
renderTarget.attachments[i].descriptor.aliased = true;
renderTarget.attachments[i].image = images[i];
renderTarget.attachments[i].mem = VK_NULL_HANDLE;
metadata.attachments["color["+std::to_string((int) i)+"]"] = attachmentIndex++;
}
// Create depth
auto& depthAttachment = renderTarget.attachments.back();
metadata.attachments["depth"] = attachmentIndex++;
{
// Create an optimal image used as the depth stencil attachment
VkImageCreateInfo imageCreateInfo = {};

View File

@ -190,7 +190,7 @@ void ext::vulkan::ComputeRenderMode::destroy() {
}
void ext::vulkan::ComputeRenderMode::render() {
if ( commandBufferCallbacks.count(EXECUTE_BEGIN) > 0 ) commandBufferCallbacks[EXECUTE_BEGIN]( VkCommandBuffer{} );
if ( commandBufferCallbacks.count(EXECUTE_BEGIN) > 0 ) commandBufferCallbacks[EXECUTE_BEGIN]( VkCommandBuffer{}, 0 );
//lockMutex( this->mostRecentCommandPoolId );
auto& commands = getCommands( this->mostRecentCommandPoolId );
@ -212,7 +212,7 @@ void ext::vulkan::ComputeRenderMode::render() {
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( uf::renderer::QueueEnum::COMPUTE ), 1, &submitInfo, fences[states::currentBuffer]));
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{} );
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{}, 0 );
this->executed = true;
//unlockMutex( this->mostRecentCommandPoolId );
@ -234,7 +234,7 @@ void ext::vulkan::ComputeRenderMode::createCommandBuffers( const uf::stl::vector
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
// pre-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i] );
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i], i );
// if ( blitter.process ) blitter.getPipeline().record( blitter, blitter.descriptor, commands[i] );
/*
@ -245,13 +245,13 @@ void ext::vulkan::ComputeRenderMode::createCommandBuffers( const uf::stl::vector
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentPass);
graphic->record( commands[i], descriptor, currentPass, currentDraw++ );
}
if ( commandBufferCallbacks.count( currentPass ) > 0 ) commandBufferCallbacks[currentPass]( commands[i] );
if ( commandBufferCallbacks.count( currentPass ) > 0 ) commandBufferCallbacks[currentPass]( commands[i], i );
if ( currentPass + 1 < subpasses ) vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
}
*/
// post-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i] );
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i], i );
VK_CHECK_RESULT(vkEndCommandBuffer(commands[i]));
}

View File

@ -28,6 +28,7 @@ uf::stl::vector<ext::vulkan::Graphic*> ext::vulkan::DeferredRenderMode::getBlitt
}
void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
#if 0
if ( metadata.eyes == 0 ) metadata.eyes = 1;
{
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
@ -37,10 +38,11 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
settings::invariant::deferredAliasOutputToSwapchain = false;
}
}
if ( settings::pipelines::bloom ) settings::invariant::deferredAliasOutputToSwapchain = false;
#endif
// buffers.emplace_back().initialize( NULL, sizeof(pod::Camera::Viewports), uf::renderer::enums::Buffer::UNIFORM );
if ( settings::pipelines::bloom ) settings::invariant::deferredAliasOutputToSwapchain = false;
auto HDR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
auto SDR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
@ -233,6 +235,17 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
/*.blend =*/ blend,
/*.samples =*/ 1,
});
metadata.attachments["id"] = attachments.id;
metadata.attachments["bary"] = attachments.bary;
metadata.attachments["mips"] = attachments.mips;
metadata.attachments["normals"] = attachments.normals;
metadata.attachments["uvs"] = attachments.uvs;
metadata.attachments["depth"] = attachments.depth;
metadata.attachments["color"] = attachments.color;
metadata.attachments["bright"] = attachments.bright;
metadata.attachments["scratch"] = attachments.scratch;
for ( size_t eye = 0; eye < metadata.eyes; ++eye ) {
// First pass: fill the G-Buffer
{
@ -307,10 +320,10 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
}
{
size_t index = uf::renderer::settings::pipelines::deferred ? metadata.outputs[0] : metadata.outputs[0] - 2; // deferred ? attachments.color : attachments.albedo;
size_t index = metadata.attachments["color"]; // uf::renderer::settings::pipelines::deferred ? metadata.attachments["color"] : metadata.attachments["albedo"]; // deferred ? attachments.color : attachments.albedo;
auto& shader = blitter.material.getShader("fragment");
shader.textures.clear();
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[index], (size_t) 0 ); // attachments.color
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[index] ); // attachments.color
}
if ( settings::pipelines::deferred ) {
@ -348,9 +361,9 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
auto& shader = blitter.material.getShader("compute", "bloom");
shader.textures.clear();
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[attachments.color], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[attachments.bright], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[attachments.scratch], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["color"]/*attachments.color*/], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["bright"]/*attachments.bright*/], (size_t) 0 );
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["scratch"]/*attachments.scratch*/], (size_t) 0 );
for ( auto& texture : shader.textures ) {
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
@ -476,9 +489,9 @@ void ext::vulkan::DeferredRenderMode::tick() {
if ( settings::pipelines::bloom ) {
auto& shader = blitter.material.getShader("compute", "bloom");
shader.textures.clear();
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.outputs[0]+0], (size_t) 0 ); // attachments.color
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.outputs[0]+1], (size_t) 0 ); // attachments.bright
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.outputs[0]+2], (size_t) 0 ); // attachments.scratch
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["color"]/*metadata.outputs[0]+0*/], (size_t) 0 ); // attachments.color
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["bright"]/*metadata.outputs[0]+1*/], (size_t) 0 ); // attachments.bright
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[metadata.attachments["scratch"]/*metadata.outputs[0]+2*/], (size_t) 0 ); // attachments.scratch
for ( auto& texture : shader.textures ) {
texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
texture.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
@ -488,7 +501,11 @@ void ext::vulkan::DeferredRenderMode::tick() {
// update blitter descriptor set
if ( rebuild && blitter.initialized ) {
{
size_t index = uf::renderer::settings::pipelines::deferred ? metadata.outputs[0] : metadata.outputs[0] - 2; // deferred ? attachments.color : attachments.albedo;
#if UF_USE_FFX_FSR
size_t index = metadata.attachments["scratch"];
#else
size_t index = metadata.attachments["color"]; // uf::renderer::settings::pipelines::deferred ? metadata.outputs[0] : metadata.outputs[0] - 2; // deferred ? attachments.color : attachments.albedo;
#endif
auto& shader = blitter.material.getShader("fragment");
shader.textures.clear();
shader.textures.emplace_back().aliasAttachment( renderTarget.attachments[index], (size_t) 0 ); // attachments.color
@ -551,7 +568,7 @@ VkSubmitInfo ext::vulkan::DeferredRenderMode::queue() {
return submitInfo;
}
void ext::vulkan::DeferredRenderMode::render() {
if ( commandBufferCallbacks.count(EXECUTE_BEGIN) > 0 ) commandBufferCallbacks[EXECUTE_BEGIN]( VkCommandBuffer{} );
if ( commandBufferCallbacks.count(EXECUTE_BEGIN) > 0 ) commandBufferCallbacks[EXECUTE_BEGIN]( VkCommandBuffer{}, 0 );
//lockMutex( this->mostRecentCommandPoolId );
auto& commands = getCommands( this->mostRecentCommandPoolId );
@ -572,7 +589,7 @@ void ext::vulkan::DeferredRenderMode::render() {
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{} );
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{}, 0 );
this->executed = true;
//unlockMutex( this->mostRecentCommandPoolId );
@ -688,7 +705,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
*/
// pre-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i] );
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i], i );
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
@ -746,7 +763,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
#endif
// post-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i] );
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i], i );
#if 1
if ( settings::pipelines::bloom ) {
@ -827,98 +844,6 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const uf::stl::vecto
for ( auto layer : layers ) {
layer->pipelineBarrier( commands[i], 1 );
}
#if 0
if ( !settings::invariant::deferredAliasOutputToSwapchain ) {
{
auto& renderTarget = swapchainRender.renderTarget;
float width = renderTarget.width;
float height = renderTarget.height;
uf::stl::vector<VkClearValue> clearValues; clearValues.resize(2);
clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
clearValues[1].depthStencil = { 1.0f, 0 };
VkRenderPassBeginInfo renderPassBeginInfo = {};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.pNext = nullptr;
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent.width = width;
renderPassBeginInfo.renderArea.extent.height = height;
renderPassBeginInfo.clearValueCount = clearValues.size();
renderPassBeginInfo.pClearValues = &clearValues[0];
renderPassBeginInfo.renderPass = renderTarget.renderPass;
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[i];
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdEndRenderPass(commands[i]);
}
{
VkImageBlit imageBlitRegion{};
imageBlitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlitRegion.srcSubresource.layerCount = 1;
imageBlitRegion.srcOffsets[1] = { width, height, 1 };
imageBlitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlitRegion.dstSubresource.layerCount = 1;
imageBlitRegion.dstOffsets[1] = {
swapchainRender.width > 0 ? swapchainRender.width : ext::vulkan::settings::width,
swapchainRender.height > 0 ? swapchainRender.height : ext::vulkan::settings::height,
1
};
auto& outputAttachment = renderTarget.attachments[metadata.outputs.front()];
// Transition to KHR
{
imageMemoryBarrier.image = outputAttachment.image;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.oldLayout = outputAttachment.descriptor.layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
// outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
}
{
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].descriptor.layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
swapchainRender.renderTarget.attachments[i].descriptor.layout = imageMemoryBarrier.newLayout;
}
vkCmdBlitImage(
commands[i],
outputAttachment.image,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
swapchainRender.renderTarget.attachments[i].image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&imageBlitRegion,
settings::swapchainUpscaleFilter
);
{
imageMemoryBarrier.image = outputAttachment.image;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; //outputAttachment.descriptor.layout;
imageMemoryBarrier.newLayout = outputAttachment.descriptor.layout; //VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
// outputAttachment.descriptor.layout = imageMemoryBarrier.newLayout;
}
{
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].descriptor.layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
swapchainRender.renderTarget.attachments[i].descriptor.layout = imageMemoryBarrier.newLayout;
}
}
}
#endif
}
VK_CHECK_RESULT(vkEndCommandBuffer(commands[i]));

View File

@ -82,6 +82,8 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
/*.blend = */ false,
/*.samples = */ 1,
});
metadata.attachments["depth"] = attachments.depth;
for ( size_t currentPass = 0; currentPass < metadata.subpasses; ++currentPass ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
@ -122,6 +124,9 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
0,
true
);
metadata.attachments["albedo"] = attachments.albedo;
metadata.attachments["depth"] = attachments.depth;
#if 0
if ( metadata.type == "single" ) {
} else {
@ -304,7 +309,8 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
uf::stl::string vertexShaderFilename = uf::io::root+"/shaders/display/renderTarget.vert.spv";
uf::stl::string fragmentShaderFilename = uf::io::root+"/shaders/display/renderTarget.frag.spv"; {
std::pair<bool, uf::stl::string> settings[] = {
{ msaa > 1, "msaa.frag" },
{ true, "postProcess.frag" },
// { msaa > 1, "msaa.frag" },
};
FOR_ARRAY( settings ) if ( settings[i].first ) fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", settings[i].second );
}
@ -448,7 +454,7 @@ void ext::vulkan::RenderTargetRenderMode::destroy() {
}
void ext::vulkan::RenderTargetRenderMode::render() {
if ( commandBufferCallbacks.count(EXECUTE_BEGIN) > 0 ) commandBufferCallbacks[EXECUTE_BEGIN]( VkCommandBuffer{} );
if ( commandBufferCallbacks.count(EXECUTE_BEGIN) > 0 ) commandBufferCallbacks[EXECUTE_BEGIN]( VkCommandBuffer{}, 0 );
//lockMutex( this->mostRecentCommandPoolId );
auto& commands = getCommands( this->mostRecentCommandPoolId );
@ -469,7 +475,7 @@ void ext::vulkan::RenderTargetRenderMode::render() {
VK_CHECK_RESULT(vkQueueSubmit(device->getQueue( QueueEnum::GRAPHICS ), 1, &submitInfo, fences[states::currentBuffer]));
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{} );
if ( commandBufferCallbacks.count(EXECUTE_END) > 0 ) commandBufferCallbacks[EXECUTE_END]( VkCommandBuffer{}, 0 );
this->executed = true;
//unlockMutex( this->mostRecentCommandPoolId );
@ -539,7 +545,7 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const uf::stl::v
size_t subpasses = renderTarget.passes.size();
size_t currentPass = 0;
// pre-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i] );
if ( commandBufferCallbacks.count(CALLBACK_BEGIN) > 0 ) commandBufferCallbacks[CALLBACK_BEGIN]( commands[i], i );
if ( this->getName() == "Compute" ) {
for ( auto graphic : graphics ) {
@ -568,14 +574,14 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const uf::stl::v
ext::vulkan::GraphicDescriptor descriptor = bindGraphicDescriptor(graphic->descriptor, currentPass);
graphic->record( commands[i], descriptor, currentPass, currentDraw++ );
}
if ( commandBufferCallbacks.count( currentPass ) > 0 ) commandBufferCallbacks[currentPass]( commands[i] );
if ( commandBufferCallbacks.count( currentPass ) > 0 ) commandBufferCallbacks[currentPass]( commands[i], i );
if ( currentPass + 1 < subpasses ) vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
}
vkCmdEndRenderPass(commands[i]);
}
// post-renderpass commands
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i] );
if ( commandBufferCallbacks.count(CALLBACK_END) > 0 ) commandBufferCallbacks[CALLBACK_END]( commands[i], i );
}
VK_CHECK_RESULT(vkEndCommandBuffer(commands[i]));

View File

@ -8,6 +8,7 @@
#include <uf/engine/graph/graph.h>
#include <uf/ext/openvr/openvr.h>
#include <uf/ext/ffx/fsr.h>
#include <ostream>
#include <fstream>
@ -25,7 +26,7 @@ bool ext::vulkan::settings::validation = true;
bool ext::vulkan::settings::defaultStageBuffers = true;
bool ext::vulkan::settings::defaultDeferBufferDestroy = true;
bool ext::vulkan::settings::defaultCommandBufferWait = true;
// constexpr size_t ext::vulkan::settings::maxViews = 6;
size_t ext::vulkan::settings::viewCount = 2;
size_t ext::vulkan::settings::gpuID = -1;
size_t ext::vulkan::settings::scratchBufferAlignment = 256;
@ -51,8 +52,6 @@ bool ext::vulkan::settings::invariant::individualPipelines = true;
bool ext::vulkan::settings::invariant::multithreadedRecording = true;
uf::stl::string ext::vulkan::settings::invariant::deferredMode = "";
bool ext::vulkan::settings::invariant::deferredAliasOutputToSwapchain = false;
bool ext::vulkan::settings::invariant::deferredSampling = true;
bool ext::vulkan::settings::invariant::multiview = true;
// pipelines
@ -61,6 +60,7 @@ bool ext::vulkan::settings::pipelines::vsync = true;
bool ext::vulkan::settings::pipelines::hdr = true;
bool ext::vulkan::settings::pipelines::vxgi = true;
bool ext::vulkan::settings::pipelines::culling = false;
bool ext::vulkan::settings::pipelines::occlusion = false;
bool ext::vulkan::settings::pipelines::bloom = false;
bool ext::vulkan::settings::pipelines::rt = false;
@ -69,6 +69,7 @@ uf::stl::string ext::vulkan::settings::pipelines::names::vsync = "vsync";
uf::stl::string ext::vulkan::settings::pipelines::names::hdr = "hdr";
uf::stl::string ext::vulkan::settings::pipelines::names::vxgi = "vxgi";
uf::stl::string ext::vulkan::settings::pipelines::names::culling = "culling";
uf::stl::string ext::vulkan::settings::pipelines::names::occlusion = "occlusion";
uf::stl::string ext::vulkan::settings::pipelines::names::bloom = "bloom";
uf::stl::string ext::vulkan::settings::pipelines::names::rt = "rt";
@ -428,6 +429,12 @@ void ext::vulkan::tick() {
}
uf::thread::execute( tasks );
}
#if UF_USE_FFX_FSR
if ( !ext::fsr::initialized ) {
ext::fsr::initialize();
}
#endif
ext::vulkan::states::rebuild = false;
ext::vulkan::states::resized = false;
@ -474,7 +481,7 @@ void ext::vulkan::render() {
for ( auto renderMode : renderModes ) {
if ( !renderMode || !renderMode->execute || !renderMode->metadata.limiter.execute ) continue;
// renderMode->lockMutex( renderMode->mostRecentCommandPoolId );
if ( renderMode->commandBufferCallbacks.count(RenderMode::EXECUTE_BEGIN) > 0 ) renderMode->commandBufferCallbacks[RenderMode::EXECUTE_BEGIN]( VkCommandBuffer{} );
if ( renderMode->commandBufferCallbacks.count(RenderMode::EXECUTE_BEGIN) > 0 ) renderMode->commandBufferCallbacks[RenderMode::EXECUTE_BEGIN]( VkCommandBuffer{}, 0 );
if ( renderMode->getName() == "Gui" || renderMode->getName() == "" || renderMode->getName() == "Swapchain" )
specialRenderModes.emplace_back(renderMode);
@ -525,9 +532,14 @@ void ext::vulkan::render() {
ext::vulkan::setCurrentRenderMode(NULL);
}
}
#if UF_USE_FFX_FSR
if ( ext::fsr::initialized ) {
ext::fsr::tick();
}
#endif
for ( auto renderMode : renderModes ) {
if ( renderMode->commandBufferCallbacks.count(RenderMode::EXECUTE_END) > 0 ) renderMode->commandBufferCallbacks[RenderMode::EXECUTE_END]( VkCommandBuffer{} );
if ( renderMode->commandBufferCallbacks.count(RenderMode::EXECUTE_END) > 0 ) renderMode->commandBufferCallbacks[RenderMode::EXECUTE_END]( VkCommandBuffer{}, 0 );
// renderMode->cleanupCommands( renderMode->mostRecentCommandPoolId );
// renderMode->unlockMutex( renderMode->mostRecentCommandPoolId );
}

View File

@ -367,16 +367,12 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
}
if ( !stats.floored ) stats.walking = false;
}
TIMER(0.0625, stats.floored && keys.jump ) {
TIMER(0.0625, stats.floored && keys.jump && !stats.noclipped ) {
physics.linear.velocity += translator.up * metadata.movement.jump;
}
/*
if ( stats.floored && keys.jump ) {
physics.linear.velocity += translator.up * metadata.movement.jump;
}
*/
if ( stats.floored && keys.jump && stats.noclipped ) transform.position += translator.up * metadata.movement.jump * uf::physics::time::delta * 4.0f;
if ( keys.crouch ) {
if ( stats.noclipped ) physics.linear.velocity -= translator.up * metadata.movement.jump;
if ( stats.noclipped ) transform.position -= translator.up * metadata.movement.jump * uf::physics::time::delta * 4.0f;
else {
if ( !metadata.system.crouching ) stats.deltaCrouch = true;
metadata.system.crouching = true;
@ -435,12 +431,12 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
if ( stats.deltaCrouch ) {
float delta = metadata.movement.crouch;
if ( metadata.system.crouching ) camera.getTransform().position.y -= delta;
else camera.getTransform().position.y += delta;
if ( metadata.system.crouching ) cameraTransform.position.y -= delta;
else cameraTransform.position.y += delta;
}
#if UF_USE_OPENAL
if ( stats.floored ) {
if ( stats.floored && !stats.noclipped ) {
if ( stats.walking ) {
auto& emitter = this->getComponent<uf::MappedSoundEmitter>();
int cycle = rand() % metadata.audio.footstep.list.size();
@ -462,7 +458,7 @@ void ext::PlayerBehavior::tick( uf::Object& self ) {
modulation -= 0.05f;
if ( keys.running ) modulation += 0.5f;
footstep.setPitch( 1 + modulation );
footstep.setVolume( metadata.audio.footstep.volume );
footstep.setVolume( metadata.audio.footstep.volume * (metadata.system.crouching ? 0.5 : 1) );
footstep.setPosition( transform.position );
footstep.setTime( 0 );

View File

@ -561,6 +561,15 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
}
}
}
for ( auto& texture : uf::graph::storage.shadowCubes ) {
texture.sampler.descriptor.filter.min = uf::renderer::enums::Filter::LINEAR;
texture.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::LINEAR;
}
for ( auto& texture : uf::graph::storage.shadow2Ds ) {
texture.sampler.descriptor.filter.min = uf::renderer::enums::Filter::LINEAR;
texture.sampler.descriptor.filter.mag = uf::renderer::enums::Filter::LINEAR;
}
uf::graph::storage.buffers.light.update( (const void*) uf::graph::storage.lights.data(), uf::graph::storage.lights.size() * sizeof(pod::Light) );
}

View File

@ -118,9 +118,9 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
if ( renderMode.metadata.samples > 1 ) {
computeShaderFilename = uf::string::replace( computeShaderFilename, "frag", "msaa.frag" );
}
if ( uf::renderer::settings::invariant::deferredSampling ) {
computeShaderFilename = uf::string::replace( computeShaderFilename, "frag", "deferredSampling.frag" );
}
// if ( uf::renderer::settings::invariant::deferredSampling ) {
// computeShaderFilename = uf::string::replace( computeShaderFilename, "frag", "deferredSampling.frag" );
// }
renderMode.metadata.json["shaders"]["compute"] = computeShaderFilename;
renderMode.blitter.descriptor.renderMode = metadata.renderModeName;
renderMode.blitter.descriptor.subpass = -1;
@ -145,7 +145,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
for ( auto& t : sceneTextures.voxels.radiance ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
for ( auto& t : sceneTextures.voxels.depth ) renderMode.blitter.material.textures.emplace_back().aliasTexture(t);
renderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer ){
renderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer, size_t _ ){
// clear textures
VkImageSubresourceRange subresourceRange = {};
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -161,7 +161,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
for ( auto& t : sceneTextures.voxels.radiance ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
for ( auto& t : sceneTextures.voxels.depth ) vkCmdClearColorImage( commandBuffer, t.image, t.imageLayout, &clearColor, 1, &subresourceRange );
});
renderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer ){
renderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer, size_t _ ){
// parse voxel lighting
if ( renderMode.blitter.initialized ) {
auto& pipeline = renderMode.blitter.getPipeline();
@ -194,7 +194,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
}
});
#if 0
renderMode.bindCallback( renderMode.EXECUTE_BEGIN, [&]( VkCommandBuffer _ ) {
renderMode.bindCallback( renderMode.EXECUTE_BEGIN, [&]( VkCommandBuffer _, size_t __ ) {
auto& controller = scene.getController();
auto controllerTransform = uf::transform::flatten( controller.getComponent<uf::Camera>().getTransform() );
pod::Vector3f controllerPosition = controllerTransform.position - metadata.extents.min;
@ -246,7 +246,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
#endif
#if 0
auto& deferredRenderMode = uf::renderer::getRenderMode("", true);
deferredRenderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer ){
deferredRenderMode.bindCallback( renderMode.CALLBACK_BEGIN, [&]( VkCommandBuffer commandBuffer, size_t _ ){
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
@ -285,7 +285,7 @@ void ext::VoxelizerSceneBehavior::initialize( uf::Object& self ) {
);
}
});
deferredRenderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer ){
deferredRenderMode.bindCallback( renderMode.CALLBACK_END, [&]( VkCommandBuffer commandBuffer, size_t _ ){
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED

View File

@ -46,6 +46,7 @@
#include <uf/ext/lua/lua.h>
#include <uf/ext/ultralight/ultralight.h>
#include <uf/ext/imgui/imgui.h>
#include <uf/ext/ffx/fsr.h>
bool ext::ready = false;
uf::stl::vector<uf::stl::string> ext::arguments;
@ -84,7 +85,7 @@ namespace {
struct {
struct {
bool enabled;
} ultralight, discord, imgui;
} ultralight, discord, imgui, fsr;
} ext;
struct {
@ -207,6 +208,7 @@ void EXT_API ext::initialize() {
::config.engine.ext.ultralight.enabled = ::json["engine"]["ext"]["ultralight"]["enabled"].as(::config.engine.ext.ultralight.enabled);
::config.engine.ext.discord.enabled = ::json["engine"]["ext"]["discord"]["enabled"].as(::config.engine.ext.discord.enabled);
::config.engine.ext.imgui.enabled = ::json["engine"]["ext"]["imgui"]["enabled"].as(::config.engine.ext.imgui.enabled);
::config.engine.ext.fsr.enabled = ::json["engine"]["ext"]["fsr"]["enabled"].as(::config.engine.ext.fsr.enabled);
::config.engine.limiter.print = ::json["engine"]["debug"]["framerate"]["print"].as(::config.engine.limiter.print);
@ -320,29 +322,23 @@ void EXT_API ext::initialize() {
}
#endif
// set bullet parameters
#if UF_USE_BULLET
{
auto& configEngineBulletJson = ::json["engine"]["ext"]["bullet"];
ext::bullet::iterations = configEngineBulletJson["iterations"].as( ext::bullet::iterations );
ext::bullet::substeps = configEngineBulletJson["substeps"].as( ext::bullet::substeps );
ext::bullet::timescale = configEngineBulletJson["timescale"].as( ext::bullet::timescale );
ext::bullet::defaultMaxCollisionAlgorithmPoolSize = configEngineBulletJson["pool size"]["max collision algorithm"].as( ext::bullet::defaultMaxCollisionAlgorithmPoolSize );
ext::bullet::defaultMaxPersistentManifoldPoolSize = configEngineBulletJson["pool size"]["max persistent manifold"].as( ext::bullet::defaultMaxPersistentManifoldPoolSize );
ext::bullet::debugDraw::enabled = configEngineBulletJson["debug draw"]["enabled"].as( ext::bullet::debugDraw::enabled );
ext::bullet::debugDraw::rate = configEngineBulletJson["debug draw"]["rate"].as( ext::bullet::debugDraw::rate );
ext::bullet::debugDraw::layer = configEngineBulletJson["debug draw"]["layer"].as( ext::bullet::debugDraw::layer );
ext::bullet::debugDraw::lineWidth = configEngineBulletJson["debug draw"]["line width"].as( ext::bullet::debugDraw::lineWidth );
}
#elif UF_USE_REACTPHYSICS
// set physics parameters
#if UF_USE_REACTPHYSICS
{
auto& configEngineReactJson = ::json["engine"]["ext"]["reactphysics"];
ext::reactphysics::timescale = configEngineReactJson["timescale"].as( ext::reactphysics::timescale );
ext::reactphysics::interpolate = configEngineReactJson["interpolate"].as( ext::reactphysics::interpolate );
ext::reactphysics::shared = configEngineReactJson["shared"].as( ext::reactphysics::shared );
if ( configEngineReactJson["gravity"]["mode"].is<uf::stl::string>() ) {
const auto mode = uf::string::lowercase( configEngineReactJson["gravity"]["mode"].as<uf::stl::string>() );
if ( mode == "default" ) ext::reactphysics::gravity::mode = ext::reactphysics::gravity::Mode::DEFAULT;
else if ( mode == "per-object" ) ext::reactphysics::gravity::mode = ext::reactphysics::gravity::Mode::PER_OBJECT;
else if ( mode == "universal" ) ext::reactphysics::gravity::mode = ext::reactphysics::gravity::Mode::UNIVERSAL;
else UF_MSG_WARNING("Invalid Gravity::Mode enum string specified: {}", mode);
}
ext::reactphysics::gravity::constant = configEngineReactJson["gravity"]["constant"].as( ext::reactphysics::gravity::constant );
ext::reactphysics::debugDraw::enabled = configEngineReactJson["debug draw"]["enabled"].as( ext::reactphysics::debugDraw::enabled );
ext::reactphysics::debugDraw::rate = configEngineReactJson["debug draw"]["rate"].as( ext::reactphysics::debugDraw::rate );
@ -424,24 +420,20 @@ void EXT_API ext::initialize() {
uf::renderer::settings::invariant::waitOnRenderEnd = configRenderInvariantJson["wait on render end"].as( uf::renderer::settings::invariant::waitOnRenderEnd );
uf::renderer::settings::invariant::individualPipelines = configRenderInvariantJson["individual pipelines"].as( uf::renderer::settings::invariant::individualPipelines );
uf::renderer::settings::invariant::deferredMode = configRenderInvariantJson["deferred mode"].as( uf::renderer::settings::invariant::deferredMode );
uf::renderer::settings::invariant::deferredAliasOutputToSwapchain = configRenderInvariantJson["deferred alias output to swapchain"].as( uf::renderer::settings::invariant::deferredAliasOutputToSwapchain );
uf::renderer::settings::invariant::deferredSampling = true; // configRenderInvariantJson["deferred sampling"].as( uf::renderer::settings::invariant::deferredSampling );
uf::renderer::settings::pipelines::deferred = configRenderPipelinesJson["deferred"].as( uf::renderer::settings::pipelines::deferred );
uf::renderer::settings::pipelines::vsync = configRenderPipelinesJson["vsync"].as( uf::renderer::settings::pipelines::vsync );
uf::renderer::settings::pipelines::hdr = configRenderPipelinesJson["hdr"].as( uf::renderer::settings::pipelines::hdr );
uf::renderer::settings::pipelines::vxgi = configRenderPipelinesJson["vxgi"].as( uf::renderer::settings::pipelines::vxgi );
uf::renderer::settings::pipelines::culling = configRenderPipelinesJson["culling"].as( uf::renderer::settings::pipelines::culling );
uf::renderer::settings::pipelines::occlusion = configRenderPipelinesJson["occlusion"].as( uf::renderer::settings::pipelines::occlusion );
uf::renderer::settings::pipelines::bloom = configRenderPipelinesJson["bloom"].as( uf::renderer::settings::pipelines::bloom );
uf::renderer::settings::pipelines::rt = configRenderPipelinesJson["rt"].as( uf::renderer::settings::pipelines::rt );
if ( !uf::renderer::settings::pipelines::deferred /*&& !uf::renderer::settings::pipelines::rt*/ ) {
uf::renderer::settings::invariant::deferredSampling = false;
}
if ( uf::renderer::settings::pipelines::rt ) {
uf::renderer::settings::pipelines::vxgi = false;
uf::renderer::settings::pipelines::culling = false;
uf::renderer::settings::pipelines::occlusion = false;
::json["engine"]["scenes"]["lights"]["shadows"]["enabled"] = false;
}
@ -521,6 +513,9 @@ void EXT_API ext::initialize() {
if ( uf::renderer::settings::pipelines::culling ) {
renderMode->metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::culling);
}
if ( uf::renderer::settings::pipelines::occlusion ) {
renderMode->metadata.pipelines.emplace_back(uf::renderer::settings::pipelines::names::occlusion);
}
uf::renderer::addRenderMode( renderMode, "" );
}
@ -606,6 +601,11 @@ void EXT_API ext::initialize() {
if ( ::config.engine.ext.imgui.enabled ) {
ext::imgui::initialize();
}
#endif
#if UF_USE_FFX_FSR
if ( ::config.engine.ext.fsr.enabled ) {
// ext::fsr::initialize();
}
#endif
/* Add hooks */ {
uf::hooks.addHook( "game:Scene.Load", [&](ext::json::Value& json){
@ -776,6 +776,11 @@ void EXT_API ext::tick() {
if ( ::config.engine.ext.imgui.enabled ) {
ext::imgui::tick();
}
#endif
#if UF_USE_FFX_FSR
if ( ::config.engine.ext.fsr.enabled ) {
ext::fsr::tick();
}
#endif
/* FPS Print */ if ( ::config.engine.fps.print ) {
++::times.frames;
@ -849,6 +854,11 @@ void EXT_API ext::terminate() {
/* Terminate controllers */ {
spec::controller::terminate();
}
#if UF_USE_FFX_FSR
if ( ::config.engine.ext.fsr.enabled ) {
ext::fsr::terminate();
}
#endif
#if UF_USE_IMGUI
if ( ::config.engine.ext.imgui.enabled ) {
ext::imgui::terminate();

View File

@ -2,6 +2,6 @@ ARCH = win64
CDIR =
CC = gcc
CXX = g++
OPTIMIZATIONS = -O3 -g -fstrict-aliasing -DUF_NO_EXCEPTIONS -march=native # -flto
OPTIMIZATIONS = -g -fstrict-aliasing -DUF_NO_EXCEPTIONS -march=native # -flto
WARNINGS = -Wall -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++20 $(OPTIMIZATIONS) $(WARNINGS) -fdiagnostics-color=always