Commit for 2020.11.12.7z
This commit is contained in:
parent
ed8eacc719
commit
71299d1284
20
Makefile
20
Makefile
@ -68,12 +68,6 @@ TARGET_SHADERS += $(patsubst %.glsl,%.spv,$(SRCS_SHADERS))
|
|||||||
|
|
||||||
$(ARCH): $(EX_DLL) $(EXT_EX_DLL) $(TARGET) $(TARGET_SHADERS)
|
$(ARCH): $(EX_DLL) $(EXT_EX_DLL) $(TARGET) $(TARGET_SHADERS)
|
||||||
|
|
||||||
rm-exe64:
|
|
||||||
-rm $(EX_DLL)
|
|
||||||
-rm $(EXT_EX_DLL)
|
|
||||||
-rm $(TARGET)
|
|
||||||
-rm $(TARGET_SHADERS)
|
|
||||||
|
|
||||||
%.$(ARCH).$(PREFIX).o: %.cpp
|
%.$(ARCH).$(PREFIX).o: %.cpp
|
||||||
$(CC) $(FLAGS) $(INCS) -c $< -o $@
|
$(CC) $(FLAGS) $(INCS) -c $< -o $@
|
||||||
|
|
||||||
@ -93,7 +87,7 @@ $(TARGET): $(OBJS)
|
|||||||
%.spv: %.glsl
|
%.spv: %.glsl
|
||||||
$(GLSL_VALIDATOR) -V $< -o $@
|
$(GLSL_VALIDATOR) -V $< -o $@
|
||||||
|
|
||||||
clean-$(ARCH):
|
clean:
|
||||||
@-rm $(EX_DLL)
|
@-rm $(EX_DLL)
|
||||||
@-rm $(EXT_EX_DLL)
|
@-rm $(EXT_EX_DLL)
|
||||||
@-rm $(TARGET)
|
@-rm $(TARGET)
|
||||||
@ -102,10 +96,16 @@ clean-$(ARCH):
|
|||||||
@-rm -f $(OBJS_EXT_DLL)
|
@-rm -f $(OBJS_EXT_DLL)
|
||||||
@-rm -f $(OBJS)
|
@-rm -f $(OBJS)
|
||||||
|
|
||||||
clean-uf-$(ARCH):
|
clean-uf:
|
||||||
@-rm $(EX_DLL)
|
@-rm $(EX_DLL)
|
||||||
@-rm -f $(OBJS_DLL)
|
@-rm -f $(OBJS_DLL)
|
||||||
|
|
||||||
clean-ext-$(ARCH):
|
clean-exf:
|
||||||
@-rm $(EXT_EX_DLL)
|
@-rm $(EXT_EX_DLL)
|
||||||
@-rm -f $(OBJS_EXT_DLL)
|
@-rm -f $(OBJS_EXT_DLL)
|
||||||
|
|
||||||
|
clean-exe:
|
||||||
|
-rm $(EX_DLL)
|
||||||
|
-rm $(EXT_EX_DLL)
|
||||||
|
-rm $(TARGET)
|
||||||
|
-rm $(TARGET_SHADERS)
|
@ -18,13 +18,16 @@ uf::Serializer client::config;
|
|||||||
void client::initialize() {
|
void client::initialize() {
|
||||||
uf::IoStream::ncurses = true;
|
uf::IoStream::ncurses = true;
|
||||||
uf::renderer::device.window = &client::window;
|
uf::renderer::device.window = &client::window;
|
||||||
|
|
||||||
|
ext::load();
|
||||||
|
|
||||||
/* Initialize config */ {
|
/* Initialize config */ {
|
||||||
struct {
|
struct {
|
||||||
uf::Serializer ext;
|
uf::Serializer ext;
|
||||||
uf::Serializer fallback;
|
uf::Serializer fallback;
|
||||||
} config;
|
} config;
|
||||||
/* Get configuration */ {
|
/* Get configuration */ {
|
||||||
config.ext = ext::getConfig();
|
config.ext = ext::config.serialize();
|
||||||
}
|
}
|
||||||
/* Merge */ {
|
/* Merge */ {
|
||||||
client::config = config.ext;
|
client::config = config.ext;
|
||||||
@ -57,6 +60,9 @@ void client::initialize() {
|
|||||||
uf::renderer::settings::height = size.y;
|
uf::renderer::settings::height = size.y;
|
||||||
client::window.create( size, title );
|
client::window.create( size, title );
|
||||||
|
|
||||||
|
// Set refresh rate
|
||||||
|
ext::config["window"]["refresh rate"] = client::window.getRefreshRate();
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
client::window.setVisible(client::config["window"]["visible"].as<bool>());
|
client::window.setVisible(client::config["window"]["visible"].as<bool>());
|
||||||
client::window.setCursorVisible(client::config["window"]["cursor"]["visible"].as<bool>());
|
client::window.setCursorVisible(client::config["window"]["cursor"]["visible"].as<bool>());
|
||||||
|
@ -38,6 +38,7 @@ int main(int argc, char** argv){
|
|||||||
std::string hook = "window:Resized";
|
std::string hook = "window:Resized";
|
||||||
json["type"] = hook;
|
json["type"] = hook;
|
||||||
json["invoker"] = "ext";
|
json["invoker"] = "ext";
|
||||||
|
|
||||||
json["window"]["size"]["x"] = client::config["window"]["size"]["x"];
|
json["window"]["size"]["x"] = client::config["window"]["size"]["x"];
|
||||||
json["window"]["size"]["y"] = client::config["window"]["size"]["y"];
|
json["window"]["size"]["y"] = client::config["window"]["size"]["y"];
|
||||||
uf::hooks.call(hook, json);
|
uf::hooks.call(hook, json);
|
||||||
|
@ -32,6 +32,7 @@ namespace uf {
|
|||||||
T loadChild( const std::string&, bool = true );
|
T loadChild( const std::string&, bool = true );
|
||||||
|
|
||||||
std::string formatHookName( const std::string& name );
|
std::string formatHookName( const std::string& name );
|
||||||
|
static std::string formatHookName( const std::string& name, size_t uid, bool fetch = true );
|
||||||
void queueHook( const std::string&, const std::string& = "", double = 0 );
|
void queueHook( const std::string&, const std::string& = "", double = 0 );
|
||||||
std::vector<std::string> callHook( const std::string&, const std::string& = "" );
|
std::vector<std::string> callHook( const std::string&, const std::string& = "" );
|
||||||
std::size_t addHook( const std::string&, const uf::HookHandler::Readable::function_t& );
|
std::size_t addHook( const std::string&, const uf::HookHandler::Readable::function_t& );
|
||||||
|
@ -37,14 +37,16 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <uf/utils/serialize/serializer.h>
|
||||||
namespace ext {
|
namespace ext {
|
||||||
extern bool EXT_API ready;
|
extern bool EXT_API ready;
|
||||||
extern std::vector<std::string> EXT_API arguments;
|
extern std::vector<std::string> EXT_API arguments;
|
||||||
|
extern uf::Serializer EXT_API config;
|
||||||
|
|
||||||
|
extern void EXT_API load();
|
||||||
extern void EXT_API initialize();
|
extern void EXT_API initialize();
|
||||||
extern bool EXT_API running();
|
extern bool EXT_API running();
|
||||||
extern void EXT_API tick();
|
extern void EXT_API tick();
|
||||||
extern void EXT_API render();
|
extern void EXT_API render();
|
||||||
extern void EXT_API terminate();
|
extern void EXT_API terminate();
|
||||||
extern std::string EXT_API getConfig();
|
|
||||||
}
|
}
|
@ -3,7 +3,7 @@
|
|||||||
#include <uf/ext/vulkan.h>
|
#include <uf/ext/vulkan.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define VK_DEFAULT_STAGE_BUFFERS 0
|
#define VK_DEFAULT_STAGE_BUFFERS 1
|
||||||
|
|
||||||
namespace ext {
|
namespace ext {
|
||||||
namespace vulkan {
|
namespace vulkan {
|
||||||
|
@ -93,6 +93,7 @@ namespace ext {
|
|||||||
Material material;
|
Material material;
|
||||||
std::unordered_map<std::string, Pipeline> pipelines;
|
std::unordered_map<std::string, Pipeline> pipelines;
|
||||||
|
|
||||||
|
~Graphic();
|
||||||
void initialize( const std::string& = "" );
|
void initialize( const std::string& = "" );
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ namespace ext {
|
|||||||
virtual void tick();
|
virtual void tick();
|
||||||
virtual void render();
|
virtual void render();
|
||||||
virtual void destroy();
|
virtual void destroy();
|
||||||
|
virtual void bindPipelines();
|
||||||
virtual void pipelineBarrier( VkCommandBuffer, uint8_t = -1 );
|
virtual void pipelineBarrier( VkCommandBuffer, uint8_t = -1 );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ namespace spec {
|
|||||||
// Gets
|
// Gets
|
||||||
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getPosition() const;/* = 0;*/
|
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getPosition() const;/* = 0;*/
|
||||||
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getSize() const;/* = 0;*/
|
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getSize() const;/* = 0;*/
|
||||||
|
/*virtual*/ size_t UF_API_CALL getRefreshRate() const;/* = 0;*/
|
||||||
// Attribute modifiers
|
// Attribute modifiers
|
||||||
/*virtual*/ void UF_API_CALL setPosition( const spec::uni::Window::vector_t& position );/* = 0;*/
|
/*virtual*/ void UF_API_CALL setPosition( const spec::uni::Window::vector_t& position );/* = 0;*/
|
||||||
/*virtual*/ void UF_API_CALL centerWindow();/* = 0;*/
|
/*virtual*/ void UF_API_CALL centerWindow();/* = 0;*/
|
||||||
|
@ -43,6 +43,7 @@ namespace spec {
|
|||||||
spec::win32::Window::handle_t UF_API_CALL getHandle() const;
|
spec::win32::Window::handle_t UF_API_CALL getHandle() const;
|
||||||
/*virtual*/ spec::win32::Window::vector_t UF_API_CALL getPosition() const;
|
/*virtual*/ spec::win32::Window::vector_t UF_API_CALL getPosition() const;
|
||||||
/*virtual*/ spec::win32::Window::vector_t UF_API_CALL getSize() const;
|
/*virtual*/ spec::win32::Window::vector_t UF_API_CALL getSize() const;
|
||||||
|
/*virtual*/ size_t UF_API_CALL getRefreshRate() const;
|
||||||
// Attribute modifiers
|
// Attribute modifiers
|
||||||
/*virtual*/ void UF_API_CALL setPosition( const spec::win32::Window::vector_t& position );
|
/*virtual*/ void UF_API_CALL setPosition( const spec::win32::Window::vector_t& position );
|
||||||
/*virtual*/ void UF_API_CALL centerWindow();
|
/*virtual*/ void UF_API_CALL centerWindow();
|
||||||
|
@ -24,6 +24,7 @@ namespace uf {
|
|||||||
// Gets
|
// Gets
|
||||||
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getPosition() const;
|
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getPosition() const;
|
||||||
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getSize() const;
|
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getSize() const;
|
||||||
|
/*virtual*/ size_t UF_API_CALL getRefreshRate() const;
|
||||||
// Attribute modifiers
|
// Attribute modifiers
|
||||||
/*virtual*/ void UF_API_CALL setPosition( const spec::uni::Window::vector_t& position );
|
/*virtual*/ void UF_API_CALL setPosition( const spec::uni::Window::vector_t& position );
|
||||||
/*virtual*/ void UF_API_CALL centerWindow();
|
/*virtual*/ void UF_API_CALL centerWindow();
|
||||||
|
@ -37,7 +37,7 @@ size_t uf::instantiator::collect( uint8_t level ) {
|
|||||||
if ( e->hasParent() ) continue;
|
if ( e->hasParent() ) continue;
|
||||||
// uninitialized
|
// uninitialized
|
||||||
if ( e->getName() == "Entity" && e->getUid() == 0 ) continue;
|
if ( e->getName() == "Entity" && e->getUid() == 0 ) continue;
|
||||||
uf::iostream << "Found orphan: " << e->getName() << ": " << e->getUid() << "\n";
|
// uf::iostream << "Found orphan: " << e->getName() << ": " << e->getUid() << "\n";
|
||||||
uf::instantiator::free( e );
|
uf::instantiator::free( e );
|
||||||
++collected;
|
++collected;
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,21 @@ void uf::Object::queueHook( const std::string& name, const std::string& payload,
|
|||||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||||
metadata["system"]["hooks"]["queue"].append(queue);
|
metadata["system"]["hooks"]["queue"].append(queue);
|
||||||
}
|
}
|
||||||
|
std::string uf::Object::formatHookName( const std::string& n, size_t uid, bool fetch ) {
|
||||||
|
if ( fetch ) {
|
||||||
|
uf::Object* object = (uf::Object*) uf::Entity::globalFindByUid( uid );
|
||||||
|
if ( object ) return object->formatHookName( n );
|
||||||
|
}
|
||||||
|
std::unordered_map<std::string, std::string> formats = {
|
||||||
|
{"%UID%", std::to_string(uid)},
|
||||||
|
};
|
||||||
|
std::string name = n;
|
||||||
|
for ( auto& pair : formats ) {
|
||||||
|
name = uf::string::replace( name, pair.first, pair.second );
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
std::string uf::Object::formatHookName( const std::string& n ) {
|
std::string uf::Object::formatHookName( const std::string& n ) {
|
||||||
if ( !this ) return n;
|
|
||||||
size_t uid = this->getUid();
|
size_t uid = this->getUid();
|
||||||
size_t parent = uid;
|
size_t parent = uid;
|
||||||
if ( this->hasParent() ) {
|
if ( this->hasParent() ) {
|
||||||
|
@ -7,6 +7,163 @@
|
|||||||
#include <uf/engine/asset/asset.h>
|
#include <uf/engine/asset/asset.h>
|
||||||
#include <uf/engine/object/behaviors/lua.h>
|
#include <uf/engine/object/behaviors/lua.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{
|
||||||
|
ext::lua::onInitialization( []{
|
||||||
|
ext::lua::state.new_usertype<uf::Object>(UF_NS_GET_LAST(uf::Object),
|
||||||
|
sol::call_constructor, sol::initializers( []( uf::Object& self, sol::object arg, bool init = true ){
|
||||||
|
if ( arg.is<std::string>() ) {
|
||||||
|
self.load( arg.as<std::string>() );
|
||||||
|
} else if ( arg.is<sol::table>() ) {
|
||||||
|
auto encoded = ext::lua::encode( arg.as<sol::table>() );
|
||||||
|
if ( encoded ) {
|
||||||
|
uf::Serializer json = encoded.value();
|
||||||
|
self.load(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( init ) {
|
||||||
|
self.initialize();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
"uid", &uf::Object::getUid ,
|
||||||
|
"name", &uf::Object::getName ,
|
||||||
|
"formatHookName", [](uf::Object& self, const std::string n ){
|
||||||
|
return self.formatHookName(n);
|
||||||
|
},
|
||||||
|
"getComponent", [](uf::Object& self, const std::string& type )->sol::object{
|
||||||
|
#define UF_LUA_RETRIEVE_COMPONENT( T )\
|
||||||
|
if ( type == UF_NS_GET_LAST(T) ) return sol::make_object( ext::lua::state, std::ref(self.getComponent<T>()) );
|
||||||
|
|
||||||
|
if ( type == "Metadata" ) {
|
||||||
|
auto& metadata = self.getComponent<uf::Serializer>();
|
||||||
|
auto decoded = ext::lua::decode( metadata );
|
||||||
|
if ( decoded ) {
|
||||||
|
sol::table table = decoded.value();
|
||||||
|
return sol::make_object( ext::lua::state, table );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UF_LUA_RETRIEVE_COMPONENT(pod::Transform<>)
|
||||||
|
UF_LUA_RETRIEVE_COMPONENT(uf::Audio)
|
||||||
|
UF_LUA_RETRIEVE_COMPONENT(uf::Asset)
|
||||||
|
UF_LUA_RETRIEVE_COMPONENT(uf::Camera)
|
||||||
|
return sol::make_object( ext::lua::state, sol::lua_nil );
|
||||||
|
},
|
||||||
|
"setComponent", [](uf::Object& self, const std::string& type, sol::object value ) {
|
||||||
|
#define UF_LUA_UPDATE_COMPONENT( T )\
|
||||||
|
else if ( type == UF_NS_GET_LAST(T) ) self.getComponent<T>() = std::move(value.as<T>());
|
||||||
|
|
||||||
|
if ( type == "Metadata" ) {
|
||||||
|
auto encoded = ext::lua::encode( value.as<sol::table>() );
|
||||||
|
if ( encoded ) {
|
||||||
|
auto& metadata = self.getComponent<uf::Serializer>();
|
||||||
|
std::string str = encoded.value();
|
||||||
|
uf::Serializer hooks = metadata["system"]["hooks"];
|
||||||
|
metadata.merge( str, false );
|
||||||
|
metadata["system"]["hooks"] = hooks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UF_LUA_UPDATE_COMPONENT(pod::Transform<>)
|
||||||
|
UF_LUA_UPDATE_COMPONENT(uf::Audio)
|
||||||
|
UF_LUA_UPDATE_COMPONENT(uf::Asset)
|
||||||
|
UF_LUA_UPDATE_COMPONENT(uf::Camera)
|
||||||
|
},
|
||||||
|
"bind", [](uf::Object& self, const std::string& type, sol::protected_function fun ) {
|
||||||
|
if ( !self.hasBehavior<uf::LuaBehavior>() ) uf::instantiator::bind( "LuaBehavior", self );
|
||||||
|
pod::Behavior* behaviorPointer = NULL;
|
||||||
|
auto& behaviors = self.getBehaviors();
|
||||||
|
for ( auto& b : behaviors ) {
|
||||||
|
if ( b.type != self.getType<uf::LuaBehavior>() ) continue;
|
||||||
|
behaviorPointer = &b;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( !behaviorPointer ) return false;
|
||||||
|
pod::Behavior& behavior = *behaviorPointer;
|
||||||
|
|
||||||
|
pod::Behavior::function_t* functionPointer = NULL;
|
||||||
|
if ( type == "initialize" ) functionPointer = &behavior.initialize;
|
||||||
|
else if ( type == "tick" ) functionPointer = &behavior.tick;
|
||||||
|
else if ( type == "render" ) functionPointer = &behavior.render;
|
||||||
|
else if ( type == "destroy" ) functionPointer = &behavior.destroy;
|
||||||
|
|
||||||
|
if ( !functionPointer ) return false;
|
||||||
|
pod::Behavior::function_t& function = *functionPointer;
|
||||||
|
|
||||||
|
function = [fun]( uf::Object& s ) {
|
||||||
|
auto result = fun(s);
|
||||||
|
if ( !result.valid() ) {
|
||||||
|
sol::error err = result;
|
||||||
|
uf::iostream << err.what() << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"findByUid", []( uf::Object& self, const size_t& index )->uf::Object&{
|
||||||
|
auto* pointer = self.findByUid( index );
|
||||||
|
if ( pointer ) return pointer->as<uf::Object>();
|
||||||
|
static uf::Object null;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"findByName", []( uf::Object& self, const std::string& index )->uf::Object&{
|
||||||
|
auto* pointer = self.findByName( index );
|
||||||
|
if ( pointer ) return pointer->as<uf::Object>();
|
||||||
|
static uf::Object null;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"addChild", []( uf::Object& self, uf::Object& child )->uf::Object&{
|
||||||
|
self.addChild( child );
|
||||||
|
return self;
|
||||||
|
},
|
||||||
|
"removeChild", []( uf::Object& self, uf::Object& child )->uf::Object&{
|
||||||
|
self.removeChild( child );
|
||||||
|
return self;
|
||||||
|
},
|
||||||
|
"loadChild", []( uf::Object& self, const std::string& filename, bool init = true )->uf::Object&{
|
||||||
|
auto* pointer = self.loadChildPointer( filename, init );
|
||||||
|
if ( pointer ) return pointer->as<uf::Object>();
|
||||||
|
static uf::Object null;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
"getChildren", []( uf::Object& self )->sol::table{
|
||||||
|
sol::table table = ext::lua::createTable();
|
||||||
|
for ( auto* child : self.getChildren() ) {
|
||||||
|
table.add(&child->as<uf::Object>());
|
||||||
|
}
|
||||||
|
return table;
|
||||||
|
},
|
||||||
|
"getParent", []( uf::Object& self )->uf::Object&{
|
||||||
|
return self.getParent().as<uf::Object>();
|
||||||
|
},
|
||||||
|
"addHook", []( uf::Object& self, const std::string& name, const sol::function& function ) {
|
||||||
|
self.addHook( name, [function]( const std::string& payload )->std::string{
|
||||||
|
auto decoded = ext::lua::decode( payload );
|
||||||
|
if ( !decoded ) return "false";
|
||||||
|
sol::table table = decoded.value();
|
||||||
|
auto result = function( table );
|
||||||
|
if ( !result.valid() ) {
|
||||||
|
sol::error err = result;
|
||||||
|
uf::iostream << err.what() << "\n";
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
return "true";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"callHook", []( uf::Object& self, const std::string& name, sol::table table = ext::lua::createTable() ) {
|
||||||
|
uf::Serializer payload = table;
|
||||||
|
self.callHook( name, payload );
|
||||||
|
},
|
||||||
|
"queueHook", []( uf::Object& self, const std::string& name, sol::table table, float delay = 0.0f ) {
|
||||||
|
uf::Serializer payload = table;
|
||||||
|
self.queueHook( name, payload, delay );
|
||||||
|
},
|
||||||
|
"__tostring", []( uf::Object& self ) {
|
||||||
|
return self.getName() + ": " + std::to_string( self.getUid() );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
UF_LUA_REGISTER_USERTYPE(uf::Object,
|
UF_LUA_REGISTER_USERTYPE(uf::Object,
|
||||||
sol::call_constructor, sol::initializers( []( uf::Object& self, sol::object arg, bool init = true ){
|
sol::call_constructor, sol::initializers( []( uf::Object& self, sol::object arg, bool init = true ){
|
||||||
if ( arg.is<std::string>() ) {
|
if ( arg.is<std::string>() ) {
|
||||||
@ -24,10 +181,12 @@ UF_LUA_REGISTER_USERTYPE(uf::Object,
|
|||||||
}),
|
}),
|
||||||
UF_LUA_REGISTER_USERTYPE_DEFINE( uid, &uf::Object::getUid ),
|
UF_LUA_REGISTER_USERTYPE_DEFINE( uid, &uf::Object::getUid ),
|
||||||
UF_LUA_REGISTER_USERTYPE_DEFINE( name, &uf::Object::getName ),
|
UF_LUA_REGISTER_USERTYPE_DEFINE( name, &uf::Object::getName ),
|
||||||
UF_LUA_REGISTER_USERTYPE_MEMBER( uf::Object::formatHookName ),
|
UF_LUA_REGISTER_USERTYPE_DEFINE( formatHookName, [](uf::Object& self, const std::string n ){
|
||||||
|
return self.formatHookName(n);
|
||||||
|
}),
|
||||||
UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, [](uf::Object& self, const std::string& type )->sol::object{
|
UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, [](uf::Object& self, const std::string& type )->sol::object{
|
||||||
#define UF_LUA_RETRIEVE_COMPONENT( T )\
|
#define UF_LUA_RETRIEVE_COMPONENT( T )\
|
||||||
if ( type == UF_NS_GET_LAST(T) ) return sol::make_object( ext::lua::state, &self.getComponent<T>() );
|
if ( type == UF_NS_GET_LAST(T) ) return sol::make_object( ext::lua::state, std::ref(self.getComponent<T>()) );
|
||||||
|
|
||||||
if ( type == "Metadata" ) {
|
if ( type == "Metadata" ) {
|
||||||
auto& metadata = self.getComponent<uf::Serializer>();
|
auto& metadata = self.getComponent<uf::Serializer>();
|
||||||
@ -61,11 +220,6 @@ UF_LUA_REGISTER_USERTYPE(uf::Object,
|
|||||||
UF_LUA_UPDATE_COMPONENT(uf::Audio)
|
UF_LUA_UPDATE_COMPONENT(uf::Audio)
|
||||||
UF_LUA_UPDATE_COMPONENT(uf::Asset)
|
UF_LUA_UPDATE_COMPONENT(uf::Asset)
|
||||||
UF_LUA_UPDATE_COMPONENT(uf::Camera)
|
UF_LUA_UPDATE_COMPONENT(uf::Camera)
|
||||||
/*
|
|
||||||
} else if ( type == "Transform" ) {
|
|
||||||
self.getComponent<pod::Transform<>>() = value.as<pod::Transform<>>();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}),
|
}),
|
||||||
UF_LUA_REGISTER_USERTYPE_DEFINE( bind, [](uf::Object& self, const std::string& type, sol::protected_function fun ) {
|
UF_LUA_REGISTER_USERTYPE_DEFINE( bind, [](uf::Object& self, const std::string& type, sol::protected_function fun ) {
|
||||||
if ( !self.hasBehavior<uf::LuaBehavior>() ) uf::instantiator::bind( "LuaBehavior", self );
|
if ( !self.hasBehavior<uf::LuaBehavior>() ) uf::instantiator::bind( "LuaBehavior", self );
|
||||||
@ -161,3 +315,4 @@ UF_LUA_REGISTER_USERTYPE(uf::Object,
|
|||||||
return self.getName() + ": " + std::to_string( self.getUid() );
|
return self.getName() + ": " + std::to_string( self.getUid() );
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
*/
|
@ -219,7 +219,6 @@ void ext::vulkan::Buffers::updateBuffer( void* data, VkDeviceSize length, Buffer
|
|||||||
length = buffer.allocationInfo.size;
|
length = buffer.allocationInfo.size;
|
||||||
VK_VALIDATION_MESSAGE("Mismatch buffer update: Requesting " << buffer.allocationInfo.size << ", got " << length << ", resetting for safety");
|
VK_VALIDATION_MESSAGE("Mismatch buffer update: Requesting " << buffer.allocationInfo.size << ", got " << length << ", resetting for safety");
|
||||||
}
|
}
|
||||||
uf::iostream << "\n";
|
|
||||||
// assert(buffer.allocationInfo.size > length);
|
// assert(buffer.allocationInfo.size > length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
|
|||||||
{
|
{
|
||||||
std::ifstream is(this->filename = filename, std::ios::binary | std::ios::in | std::ios::ate);
|
std::ifstream is(this->filename = filename, std::ios::binary | std::ios::in | std::ios::ate);
|
||||||
if ( !is.is_open() ) {
|
if ( !is.is_open() ) {
|
||||||
VK_DEBUG_MESSAGE("Error: Could not open shader file \"" << filename << "\"");
|
VK_VALIDATION_MESSAGE("Error: Could not open shader file \"" << filename << "\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
is.seekg(0, std::ios::end); spirv.reserve(is.tellg()); is.seekg(0, std::ios::beg);
|
is.seekg(0, std::ios::end); spirv.reserve(is.tellg()); is.seekg(0, std::ios::beg);
|
||||||
@ -67,12 +67,12 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
|
|||||||
size_t size = comp.get_declared_struct_size(base_type);
|
size_t size = comp.get_declared_struct_size(base_type);
|
||||||
if ( size <= 0 ) break;
|
if ( size <= 0 ) break;
|
||||||
if ( size > device.properties.limits.maxUniformBufferRange ) {
|
if ( size > device.properties.limits.maxUniformBufferRange ) {
|
||||||
VK_DEBUG_MESSAGE("Invalid uniform buffer length of " << size << " for shader " << filename);
|
VK_VALIDATION_MESSAGE("Invalid uniform buffer length of " << size << " for shader " << filename);
|
||||||
size = device.properties.limits.maxUniformBufferRange;
|
size = device.properties.limits.maxUniformBufferRange;
|
||||||
}
|
}
|
||||||
size_t misalignment = size % device.properties.limits.minStorageBufferOffsetAlignment;
|
size_t misalignment = size % device.properties.limits.minStorageBufferOffsetAlignment;
|
||||||
if ( misalignment != 0 ) {
|
if ( misalignment != 0 ) {
|
||||||
VK_DEBUG_MESSAGE("Invalid uniform buffer alignmnet of " << misalignment << " for shader " << filename << ", correcting...");
|
VK_VALIDATION_MESSAGE("Invalid uniform buffer alignmnet of " << misalignment << " for shader " << filename << ", correcting...");
|
||||||
size += misalignment;
|
size += misalignment;
|
||||||
}
|
}
|
||||||
auto& uniform = uniforms.emplace_back();
|
auto& uniform = uniforms.emplace_back();
|
||||||
@ -123,7 +123,7 @@ void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::st
|
|||||||
size_t size = comp.get_declared_struct_size(type);
|
size_t size = comp.get_declared_struct_size(type);
|
||||||
if ( size <= 0 ) continue;
|
if ( size <= 0 ) continue;
|
||||||
if ( size > device.properties.limits.maxPushConstantsSize ) {
|
if ( size > device.properties.limits.maxPushConstantsSize ) {
|
||||||
VK_DEBUG_MESSAGE("Invalid push constant length of " << size << " for shader " << filename);
|
VK_VALIDATION_MESSAGE("Invalid push constant length of " << size << " for shader " << filename);
|
||||||
size = device.properties.limits.maxPushConstantsSize;
|
size = device.properties.limits.maxPushConstantsSize;
|
||||||
}
|
}
|
||||||
auto& pushConstant = pushConstants.emplace_back();
|
auto& pushConstant = pushConstants.emplace_back();
|
||||||
@ -232,7 +232,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
|
|||||||
this->device = graphic.device;
|
this->device = graphic.device;
|
||||||
Device& device = *graphic.device;
|
Device& device = *graphic.device;
|
||||||
|
|
||||||
// VK_DEBUG_MESSAGE(&graphic << ": Shaders: " << graphic.material.shaders.size() << " Textures: " << graphic.material.textures.size());
|
// VK_VALIDATION_MESSAGE(&graphic << ": Shaders: " << graphic.material.shaders.size() << " Textures: " << graphic.material.textures.size());
|
||||||
assert( graphic.material.shaders.size() > 0 );
|
assert( graphic.material.shaders.size() > 0 );
|
||||||
|
|
||||||
RenderMode& renderMode = ext::vulkan::getRenderMode( descriptor.renderMode, true);
|
RenderMode& renderMode = ext::vulkan::getRenderMode( descriptor.renderMode, true);
|
||||||
@ -250,7 +250,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
|
|||||||
for ( auto& pushConstant : shader.pushConstants ) {
|
for ( auto& pushConstant : shader.pushConstants ) {
|
||||||
size_t len = pushConstant.data().len;
|
size_t len = pushConstant.data().len;
|
||||||
if ( len <= 0 || len > device.properties.limits.maxPushConstantsSize ) {
|
if ( len <= 0 || len > device.properties.limits.maxPushConstantsSize ) {
|
||||||
VK_DEBUG_MESSAGE("Invalid push constent length of " << len << " for shader " << shader.filename);
|
VK_VALIDATION_MESSAGE("Invalid push constent length of " << len << " for shader " << shader.filename);
|
||||||
// goto PIPELINE_INITIALIZATION_INVALID;
|
// goto PIPELINE_INITIALIZATION_INVALID;
|
||||||
len = device.properties.limits.maxPushConstantsSize;
|
len = device.properties.limits.maxPushConstantsSize;
|
||||||
}
|
}
|
||||||
@ -461,7 +461,7 @@ void ext::vulkan::Pipeline::initialize( Graphic& graphic, GraphicDescriptor& des
|
|||||||
return;
|
return;
|
||||||
PIPELINE_INITIALIZATION_INVALID:
|
PIPELINE_INITIALIZATION_INVALID:
|
||||||
graphic.process = false;
|
graphic.process = false;
|
||||||
VK_DEBUG_MESSAGE("Pipeline initialization invalid, updating next tick...");
|
VK_VALIDATION_MESSAGE("Pipeline initialization invalid, updating next tick...");
|
||||||
uf::thread::add( uf::thread::get("Main"), [&]() -> int {
|
uf::thread::add( uf::thread::get("Main"), [&]() -> int {
|
||||||
this->initialize( graphic, descriptor );
|
this->initialize( graphic, descriptor );
|
||||||
return 0;}, true );
|
return 0;}, true );
|
||||||
@ -582,12 +582,12 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
|
|||||||
auto samplerInfo = infos.sampler.begin();
|
auto samplerInfo = infos.sampler.begin();
|
||||||
auto inputInfo = infos.input.begin();
|
auto inputInfo = infos.input.begin();
|
||||||
|
|
||||||
#define BREAK_ASSERT(condition, ...) if ( condition ) { VK_DEBUG_MESSAGE(#condition << "\t" << __VA_ARGS__); break; }
|
#define BREAK_ASSERT(condition, ...) if ( condition ) { VK_VALIDATION_MESSAGE(#condition << "\t" << __VA_ARGS__); break; }
|
||||||
|
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
||||||
for ( auto& shader : graphic.material.shaders ) {
|
for ( auto& shader : graphic.material.shaders ) {
|
||||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
||||||
// VK_DEBUG_MESSAGE(shader.filename << "\tType: " << layout.descriptorType << "\tConsuming: " << layout.descriptorCount);
|
// VK_VALIDATION_MESSAGE(shader.filename << "\tType: " << layout.descriptorType << "\tConsuming: " << layout.descriptorCount);
|
||||||
switch ( layout.descriptorType ) {
|
switch ( layout.descriptorType ) {
|
||||||
// consume an texture image info
|
// consume an texture image info
|
||||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||||
@ -652,180 +652,26 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
|
||||||
std::vector<VkDescriptorImageInfo> imageInfos;
|
|
||||||
{
|
|
||||||
for ( auto& shader : graphic.material.shaders ) {
|
|
||||||
std::vector<VkDescriptorBufferInfo> buffersStorageVector;
|
|
||||||
std::vector<VkDescriptorBufferInfo> buffersUniformsVector;
|
|
||||||
|
|
||||||
#define PARSE_BUFFER( buffers ) for ( auto& buffer : buffers ) {\
|
|
||||||
if ( buffer.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT ) {\
|
|
||||||
auto& descriptor = buffersStorageVector.emplace_back(buffer.descriptor);\
|
|
||||||
if ( descriptor.offset % device->properties.limits.minStorageBufferOffsetAlignment != 0 ) {\
|
|
||||||
VK_DEBUG_MESSAGE("Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset);\
|
|
||||||
goto PIPELINE_UPDATE_INVALID;\
|
|
||||||
}\
|
|
||||||
}\
|
|
||||||
if ( buffer.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ) {\
|
|
||||||
auto& descriptor = buffersUniformsVector.emplace_back(buffer.descriptor);\
|
|
||||||
if ( descriptor.offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {\
|
|
||||||
VK_DEBUG_MESSAGE("Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.offset);\
|
|
||||||
goto PIPELINE_UPDATE_INVALID;\
|
|
||||||
}\
|
|
||||||
}\
|
|
||||||
}
|
|
||||||
|
|
||||||
PARSE_BUFFER(shader.buffers)
|
|
||||||
PARSE_BUFFER(graphic.buffers)
|
|
||||||
|
|
||||||
auto textures = graphic.material.textures.begin();
|
|
||||||
auto samplers = graphic.material.samplers.begin();
|
|
||||||
auto attachments = inputDescriptors.begin();
|
|
||||||
auto buffersStorage = buffersStorageVector.begin();
|
|
||||||
auto buffersUniforms = buffersUniformsVector.begin();
|
|
||||||
|
|
||||||
for ( auto& layout : shader.descriptorSetLayoutBindings ) {
|
|
||||||
|
|
||||||
if ( layout.descriptorCount > 1 ) {
|
|
||||||
switch ( layout.descriptorType ) {
|
|
||||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
|
|
||||||
size_t imageInfosStart = imageInfos.size();
|
|
||||||
// assume we have a texture, and fill it in the slots as defaults
|
|
||||||
size_t target = layout.descriptorCount;
|
|
||||||
for ( size_t i = 0; i < target; ++i ) {
|
|
||||||
VkDescriptorImageInfo d = emptyTexture.descriptor;
|
|
||||||
if ( textures != graphic.material.textures.end() ) {
|
|
||||||
d = (textures++)->descriptor;
|
|
||||||
if ( layout.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER && !d.sampler )
|
|
||||||
d.sampler = emptyTexture.sampler.sampler;
|
|
||||||
|
|
||||||
if ( d.imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL )
|
|
||||||
d.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
|
||||||
} else {
|
|
||||||
// VK_DEBUG_MESSAGE("textures == graphic.material.textures.end()");
|
|
||||||
}
|
|
||||||
imageInfos.push_back( d );
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t len = imageInfos.size() - imageInfosStart;
|
|
||||||
|
|
||||||
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
|
|
||||||
descriptorSet,
|
|
||||||
layout.descriptorType,
|
|
||||||
layout.binding,
|
|
||||||
&imageInfos[imageInfosStart],
|
|
||||||
len
|
|
||||||
));
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDescriptorImageInfo* imageInfo = NULL;
|
|
||||||
switch ( layout.descriptorType ) {
|
|
||||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
|
|
||||||
if ( textures == graphic.material.textures.end() ) {
|
|
||||||
imageInfo = &emptyTexture.descriptor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
imageInfo = &((textures++)->descriptor);
|
|
||||||
if ( imageInfo->imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL )
|
|
||||||
imageInfo->imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
|
||||||
} break;
|
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLER: {
|
|
||||||
if ( samplers == graphic.material.samplers.end() ) {
|
|
||||||
VK_DEBUG_MESSAGE("samplers == graphic.material.samplers.end()");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
imageInfo = &((samplers++)->descriptor.info);
|
|
||||||
} break;
|
|
||||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
|
|
||||||
if ( buffersUniforms == buffersUniformsVector.end() ) {
|
|
||||||
VK_DEBUG_MESSAGE("buffersUniforms == buffersUniformsVector.end()");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto* descriptor = &(*(buffersUniforms++));
|
|
||||||
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
|
|
||||||
descriptorSet,
|
|
||||||
layout.descriptorType,
|
|
||||||
layout.binding,
|
|
||||||
descriptor
|
|
||||||
));
|
|
||||||
} break;
|
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
|
|
||||||
if ( buffersStorage == buffersStorageVector.end() ) {
|
|
||||||
VK_DEBUG_MESSAGE("buffersStorage == buffersStorageVector.end()");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto* descriptor = &(*(buffersStorage++));
|
|
||||||
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
|
|
||||||
descriptorSet,
|
|
||||||
layout.descriptorType,
|
|
||||||
layout.binding,
|
|
||||||
descriptor
|
|
||||||
));
|
|
||||||
} break;
|
|
||||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
|
|
||||||
if ( attachments == inputDescriptors.end() ) {
|
|
||||||
VK_DEBUG_MESSAGE("attachments == inputDescriptors.end()");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
imageInfo = &(*(attachments++));
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( imageInfo ) {
|
|
||||||
if ( layout.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || layout.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ) {
|
|
||||||
if ( imageInfo->imageView == VK_NULL_HANDLE ) {
|
|
||||||
imageInfo = &emptyTexture.descriptor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( layout.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || layout.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ) {
|
|
||||||
if ( imageInfo->sampler == VK_NULL_HANDLE ) {
|
|
||||||
imageInfo->sampler = emptyTexture.sampler.sampler;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet(
|
|
||||||
descriptorSet,
|
|
||||||
layout.descriptorType,
|
|
||||||
layout.binding,
|
|
||||||
imageInfo
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
for ( auto& descriptor : writeDescriptorSets ) {
|
for ( auto& descriptor : writeDescriptorSets ) {
|
||||||
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
|
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
|
||||||
if ( descriptor.pBufferInfo ) {
|
if ( descriptor.pBufferInfo ) {
|
||||||
if ( descriptor.pBufferInfo[i].offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
|
if ( descriptor.pBufferInfo[i].offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
|
||||||
VK_DEBUG_MESSAGE("Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " (Offset: " << descriptor.pBufferInfo[i].offset << ", Range: " << descriptor.pBufferInfo[i].range << "), invalidating...");
|
VK_VALIDATION_MESSAGE("Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " (Offset: " << descriptor.pBufferInfo[i].offset << ", Range: " << descriptor.pBufferInfo[i].range << "), invalidating...");
|
||||||
goto PIPELINE_UPDATE_INVALID;
|
goto PIPELINE_UPDATE_INVALID;
|
||||||
/*
|
|
||||||
auto pointer = const_cast<VkDescriptorBufferInfo*>(&descriptor.pBufferInfo[i]);
|
|
||||||
pointer->offset = 0;
|
|
||||||
pointer->range = 0;
|
|
||||||
pointer->buffer = VK_NULL_HANDLE;
|
|
||||||
invalid = true;
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if ( descriptor.pImageInfo ) {
|
if ( descriptor.pImageInfo ) {
|
||||||
if ( descriptor.pImageInfo[i].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ) {
|
if ( descriptor.pImageInfo[i].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ) {
|
||||||
|
VK_VALIDATION_MESSAGE("Image layout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, fixing to VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL");
|
||||||
auto pointer = const_cast<VkDescriptorImageInfo*>(&descriptor.pImageInfo[i]);
|
auto pointer = const_cast<VkDescriptorImageInfo*>(&descriptor.pImageInfo[i]);
|
||||||
pointer->imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
pointer->imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||||
}
|
}
|
||||||
|
if ( descriptor.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER && !descriptor.pImageInfo[i].sampler ) {
|
||||||
|
VK_VALIDATION_MESSAGE("Image descriptor type is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, yet lacks a sampler, adding default sampler...");
|
||||||
|
auto pointer = const_cast<VkDescriptorImageInfo*>(&descriptor.pImageInfo[i]);
|
||||||
|
pointer->sampler = emptyTexture.sampler.sampler;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderMode.rebuild = true;
|
renderMode.rebuild = true;
|
||||||
@ -842,7 +688,7 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
|
|||||||
|
|
||||||
PIPELINE_UPDATE_INVALID:
|
PIPELINE_UPDATE_INVALID:
|
||||||
graphic.process = false;
|
graphic.process = false;
|
||||||
VK_DEBUG_MESSAGE("Pipeline update invalid, updating next tick...");
|
VK_VALIDATION_MESSAGE("Pipeline update invalid, updating next tick...");
|
||||||
uf::thread::add( uf::thread::get("Main"), [&]() -> int {
|
uf::thread::add( uf::thread::get("Main"), [&]() -> int {
|
||||||
this->update( graphic, descriptor );
|
this->update( graphic, descriptor );
|
||||||
return 0;}, true );
|
return 0;}, true );
|
||||||
@ -900,7 +746,9 @@ void ext::vulkan::Material::initializeShaders( const std::vector<std::pair<std::
|
|||||||
attachShader( request.first, request.second );
|
attachShader( request.first, request.second );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ext::vulkan::Graphic::~Graphic() {
|
||||||
|
this->destroy();
|
||||||
|
}
|
||||||
void ext::vulkan::Graphic::initialize( const std::string& renderModeName ) {
|
void ext::vulkan::Graphic::initialize( const std::string& renderModeName ) {
|
||||||
RenderMode& renderMode = ext::vulkan::getRenderMode(renderModeName, true);
|
RenderMode& renderMode = ext::vulkan::getRenderMode(renderModeName, true);
|
||||||
|
|
||||||
@ -949,7 +797,7 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer ) {
|
|||||||
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, GraphicDescriptor& descriptor ) {
|
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, GraphicDescriptor& descriptor ) {
|
||||||
if ( !process ) return;
|
if ( !process ) return;
|
||||||
if ( !this->hasPipeline( descriptor ) ) {
|
if ( !this->hasPipeline( descriptor ) ) {
|
||||||
VK_DEBUG_MESSAGE(this << ": has no valid pipeline");
|
VK_VALIDATION_MESSAGE(this << ": has no valid pipeline");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,4 +217,7 @@ void ext::vulkan::ComputeRenderMode::createCommandBuffers( ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->mostRecentCommandPoolId = std::this_thread::get_id();
|
this->mostRecentCommandPoolId = std::this_thread::get_id();
|
||||||
|
}
|
||||||
|
void ext::vulkan::ComputeRenderMode::bindPipelines() {
|
||||||
|
|
||||||
}
|
}
|
@ -182,6 +182,12 @@ spec::win32::Window::vector_t UF_API_CALL spec::win32::Window::getSize() const {
|
|||||||
vec.y = rectangle.bottom - rectangle.top;
|
vec.y = rectangle.bottom - rectangle.top;
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
size_t UF_API_CALL spec::win32::Window::getRefreshRate() const {
|
||||||
|
HDC screenDC = GetDC(NULL);
|
||||||
|
int refreshRate = GetDeviceCaps( screenDC, VREFRESH );
|
||||||
|
ReleaseDC(NULL, screenDC);
|
||||||
|
return refreshRate;
|
||||||
|
}
|
||||||
|
|
||||||
void UF_API_CALL spec::win32::Window::centerWindow() {
|
void UF_API_CALL spec::win32::Window::centerWindow() {
|
||||||
if ( fullscreenWindow == (void*) this ) return;
|
if ( fullscreenWindow == (void*) this ) return;
|
||||||
|
@ -34,10 +34,6 @@ bool UF_API uf::Audio::initialized() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void UF_API uf::Audio::destroy() {
|
void UF_API uf::Audio::destroy() {
|
||||||
{
|
|
||||||
auto filename = this->getFilename();
|
|
||||||
if ( filename != "" ) std::cout << "Audio::Destroy() Destroying " << filename << std::endl;
|
|
||||||
}
|
|
||||||
this->m_source.destroy();
|
this->m_source.destroy();
|
||||||
this->m_buffer.destroy();
|
this->m_buffer.destroy();
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,10 @@ spec::uni::Window::vector_t UF_API_CALL uf::Window::getSize() const {
|
|||||||
static spec::uni::Window::vector_t null = {};
|
static spec::uni::Window::vector_t null = {};
|
||||||
return this->m_window ? this->m_window->getSize() : null;
|
return this->m_window ? this->m_window->getSize() : null;
|
||||||
}
|
}
|
||||||
|
size_t UF_API_CALL uf::Window::getRefreshRate() const {
|
||||||
|
static spec::uni::Window::vector_t null = {};
|
||||||
|
return this->m_window ? this->m_window->getRefreshRate() : 0;
|
||||||
|
}
|
||||||
// Attribute modifiers
|
// Attribute modifiers
|
||||||
void UF_API_CALL uf::Window::setPosition( const spec::uni::Window::vector_t& position ) {
|
void UF_API_CALL uf::Window::setPosition( const spec::uni::Window::vector_t& position ) {
|
||||||
if ( this->m_window ) this->m_window->setPosition(position);
|
if ( this->m_window ) this->m_window->setPosition(position);
|
||||||
|
@ -289,7 +289,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
|||||||
if ( !entity || entity->getName() != "Light" ) return;
|
if ( !entity || entity->getName() != "Light" ) return;
|
||||||
entities.push_back(entity);
|
entities.push_back(entity);
|
||||||
};
|
};
|
||||||
for ( uf::Scene* scene : uf::renderer::scenes ) { if ( !scene ) continue;
|
for ( uf::Scene* scene : uf::scene::scenes ) { if ( !scene ) continue;
|
||||||
scene->process(filter);
|
scene->process(filter);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -26,7 +26,7 @@ UF_BEHAVIOR_REGISTER_CPP(ext::SceneCollisionBehavior)
|
|||||||
#define this ((uf::Scene*) &self)
|
#define this ((uf::Scene*) &self)
|
||||||
|
|
||||||
void ext::SceneCollisionBehavior::initialize( uf::Object& self ) {
|
void ext::SceneCollisionBehavior::initialize( uf::Object& self ) {
|
||||||
{
|
if ( false ) {
|
||||||
auto& mutexPointer = this->getComponent<std::mutex*>();
|
auto& mutexPointer = this->getComponent<std::mutex*>();
|
||||||
mutexPointer = new std::mutex;
|
mutexPointer = new std::mutex;
|
||||||
}
|
}
|
||||||
@ -36,8 +36,9 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
|
|||||||
auto& metadata = this->getComponent<uf::Serializer>();
|
auto& metadata = this->getComponent<uf::Serializer>();
|
||||||
|
|
||||||
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) return;
|
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) return;
|
||||||
auto& mutex = *(this->getComponent<std::mutex*>());
|
if ( this->hasComponent<std::mutex*>() ) {
|
||||||
mutex.lock();
|
this->getComponent<std::mutex*>()->lock();
|
||||||
|
}
|
||||||
|
|
||||||
bool threaded = !metadata["system"]["physics"]["single threaded"].as<bool>();
|
bool threaded = !metadata["system"]["physics"]["single threaded"].as<bool>();
|
||||||
bool sort = metadata["system"]["physics"]["sort"].as<bool>();
|
bool sort = metadata["system"]["physics"]["sort"].as<bool>();
|
||||||
@ -47,12 +48,12 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
|
|||||||
bool ignoreStaticEntities = metadata["system"]["physics"]["optimizations"]["ignore static entities"].as<bool>();
|
bool ignoreStaticEntities = metadata["system"]["physics"]["optimizations"]["ignore static entities"].as<bool>();
|
||||||
bool ignoreDuplicateTests = metadata["system"]["physics"]["optimizations"]["ignore duplicate tests"].as<bool>();
|
bool ignoreDuplicateTests = metadata["system"]["physics"]["optimizations"]["ignore duplicate tests"].as<bool>();
|
||||||
bool useWorkers = metadata["system"]["physics"]["use"]["worker"].as<bool>();
|
bool useWorkers = metadata["system"]["physics"]["use"]["worker"].as<bool>();
|
||||||
pod::Thread& thread = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true, false );
|
|
||||||
auto function = [&]() -> int {
|
std::vector<std::function<int()>> jobs;
|
||||||
std::vector<uf::Object*> entities;
|
std::vector<uf::Object*> entities; {
|
||||||
// update physics
|
// update physics
|
||||||
if ( updatePhysics ) {
|
if ( updatePhysics ) {
|
||||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
this->process([&]( uf::Entity* entity ) {
|
||||||
if ( !entity->hasComponent<pod::Physics>() ) return;
|
if ( !entity->hasComponent<pod::Physics>() ) return;
|
||||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||||
auto& transform = entity->getComponent<pod::Transform<>>();
|
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||||
@ -68,46 +69,164 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
|
|||||||
physics.linear.acceleration.z = 0;
|
physics.linear.acceleration.z = 0;
|
||||||
}
|
}
|
||||||
transform = uf::physics::update( transform, physics );
|
transform = uf::physics::update( transform, physics );
|
||||||
};
|
});
|
||||||
this->process(filter);
|
|
||||||
}
|
}
|
||||||
{
|
this->process([&]( uf::Entity* entity ) {
|
||||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
if ( !entity ) return;
|
||||||
if ( !entity ) return;
|
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
if ( !ext::json::isNull( metadata["system"]["physics"]["collision"] ) && !metadata["system"]["physics"]["collision"].as<bool>() ) return;
|
||||||
if ( !ext::json::isNull( metadata["system"]["physics"]["collision"] ) && !metadata["system"]["physics"]["collision"].as<bool>() ) return;
|
if ( entity->hasComponent<uf::Collider>() )
|
||||||
if ( entity->hasComponent<uf::Collider>() )
|
entities.push_back((uf::Object*) entity);
|
||||||
entities.push_back((uf::Object*) entity);
|
});
|
||||||
};
|
auto onCollision = []( pod::Collider::Manifold& manifold, size_t uidA, size_t uidB, bool queued ){
|
||||||
this->process(filter);
|
|
||||||
}
|
|
||||||
auto onCollision = []( pod::Collider::Manifold& manifold, uf::Object* a, uf::Object* b, bool queued ){
|
|
||||||
if ( !a || !b ) return;
|
|
||||||
|
|
||||||
uf::Serializer payload;
|
uf::Serializer payload;
|
||||||
payload["normal"][0] = manifold.normal.x;
|
payload["normal"][0] = manifold.normal.x;
|
||||||
payload["normal"][1] = manifold.normal.y;
|
payload["normal"][1] = manifold.normal.y;
|
||||||
payload["normal"][2] = manifold.normal.z;
|
payload["normal"][2] = manifold.normal.z;
|
||||||
payload["entity"] = b->getUid();
|
payload["entity"] = uidB;
|
||||||
payload["depth"] = -manifold.depth;
|
payload["depth"] = -manifold.depth;
|
||||||
if ( queued ) a->queueHook("world:Collision.%UID%", payload);
|
|
||||||
else a->callHook("world:Collision.%UID%", payload);
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
|
if ( queued ) scene.queueHook(uf::Object::formatHookName("world:Collision.%UID%",uidA), payload);
|
||||||
|
else scene.callHook(uf::Object::formatHookName("world:Collision.%UID%",uidA), payload);
|
||||||
|
|
||||||
payload["entity"] = a->getUid();
|
payload["entity"] = uidA;
|
||||||
payload["depth"] = manifold.depth;
|
payload["depth"] = manifold.depth;
|
||||||
if ( queued ) b->queueHook("world:Collision.%UID%", payload);
|
if ( queued ) scene.queueHook(uf::Object::formatHookName("world:Collision.%UID%",uidB), payload);
|
||||||
else b->callHook("world:Collision.%UID%", payload);
|
else scene.callHook(uf::Object::formatHookName("world:Collision.%UID%",uidB), payload);
|
||||||
};
|
};
|
||||||
auto testColliders = [&]( uf::Collider& colliderA, uf::Collider& colliderB, uf::Object* a, uf::Object* b, bool useStrongest ){
|
auto testColliders = [&]( uf::Collider& colliderA, uf::Collider& colliderB, size_t uidA, size_t uidB, bool useStrongest ){
|
||||||
pod::Collider::Manifold strongest;
|
pod::Collider::Manifold strongest;
|
||||||
auto manifolds = colliderA.intersects(colliderB);
|
auto manifolds = colliderA.intersects(colliderB);
|
||||||
for ( auto manifold : manifolds ) {
|
for ( auto manifold : manifolds ) {
|
||||||
if ( manifold.colliding && manifold.depth > 0 ) {
|
if ( manifold.colliding && manifold.depth > 0 ) {
|
||||||
if ( !useStrongest ) onCollision(manifold, a, b, queued);
|
if ( !useStrongest ) onCollision(manifold, uidA, uidB, queued);
|
||||||
else if ( strongest.depth < manifold.depth ) strongest = manifold;
|
else if ( strongest.depth < manifold.depth ) strongest = manifold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( useStrongest && strongest.colliding ) onCollision(strongest, a, b, queued);
|
if ( useStrongest && strongest.colliding ) onCollision(strongest, uidA, uidB, queued);
|
||||||
|
};
|
||||||
|
// collide with others
|
||||||
|
if ( ignoreDuplicateTests ) {
|
||||||
|
struct Pair {
|
||||||
|
uf::Object* a = NULL;
|
||||||
|
uf::Object* b = NULL;
|
||||||
|
};
|
||||||
|
std::unordered_map<std::string, Pair> queued;
|
||||||
|
for ( auto* _a : entities ) {
|
||||||
|
uf::Object& entityA = *_a;
|
||||||
|
if ( ignoreStaticEntities && !entityA.hasComponent<pod::Physics>() ) continue;
|
||||||
|
for ( auto* _b : entities ) { if ( _a == _b ) continue;
|
||||||
|
uf::Object& entityB = *_b;
|
||||||
|
|
||||||
|
std::string hash = std::to_string(std::min( entityA.getUid(), entityB.getUid() )) + ":" + std::to_string(std::max( entityA.getUid(), entityB.getUid() ));
|
||||||
|
if ( queued.count(hash) > 0 ) continue;
|
||||||
|
|
||||||
|
queued[hash] = {
|
||||||
|
.a = _a,
|
||||||
|
.b = _b,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( auto& pair : queued ) {
|
||||||
|
auto* entityA = pair.second.a;
|
||||||
|
auto* entityB = pair.second.b;
|
||||||
|
auto& colliderA = entityA->getComponent<uf::Collider>();
|
||||||
|
auto& colliderB = entityB->getComponent<uf::Collider>();
|
||||||
|
size_t uidA = entityA->getUid();
|
||||||
|
size_t uidB = entityB->getUid();
|
||||||
|
auto function = [&, uidA, uidB]() -> int {
|
||||||
|
testColliders( colliderA, colliderB, uidA, uidB, useStrongest );
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
if ( threaded && useWorkers ) jobs.emplace_back(function); else function();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for ( auto* _a : entities ) {
|
||||||
|
uf::Object& entityA = *_a;
|
||||||
|
size_t uidA = entityA.getUid();
|
||||||
|
if ( ignoreStaticEntities && !entityA.hasComponent<pod::Physics>() ) continue;
|
||||||
|
for ( auto* _b : entities ) { if ( _a == _b ) continue;
|
||||||
|
uf::Object& entityB = *_b;
|
||||||
|
auto& colliderA = entityA.getComponent<uf::Collider>();
|
||||||
|
auto& colliderB = entityB.getComponent<uf::Collider>();
|
||||||
|
size_t uidB = entityB.getUid();
|
||||||
|
auto function = [&, uidA, uidB]() -> int {
|
||||||
|
testColliders( colliderA, colliderB, uidA, uidB, useStrongest );
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
if ( threaded && useWorkers ) jobs.emplace_back(function); else function();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !jobs.empty() ) {
|
||||||
|
if ( threaded ) uf::thread::batchWorkers( jobs );
|
||||||
|
else {
|
||||||
|
for ( auto& fun : jobs ) fun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( this->hasComponent<std::mutex*>() ) {
|
||||||
|
this->getComponent<std::mutex*>()->lock();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
pod::Thread& thread = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true, false );
|
||||||
|
auto function = [&]() -> int {
|
||||||
|
std::vector<uf::Object*> entities;
|
||||||
|
// update physics
|
||||||
|
if ( updatePhysics ) {
|
||||||
|
this->process([&]( uf::Entity* entity ) {
|
||||||
|
if ( !entity->hasComponent<pod::Physics>() ) return;
|
||||||
|
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||||
|
auto& transform = entity->getComponent<pod::Transform<>>();
|
||||||
|
auto& physics = entity->getComponent<pod::Physics>();
|
||||||
|
if ( metadata["system"]["physics"]["gravity"] != Json::nullValue ) {
|
||||||
|
physics.linear.acceleration.x = metadata["system"]["physics"]["gravity"][0].as<float>();
|
||||||
|
physics.linear.acceleration.y = metadata["system"]["physics"]["gravity"][1].as<float>();
|
||||||
|
physics.linear.acceleration.z = metadata["system"]["physics"]["gravity"][2].as<float>();
|
||||||
|
}
|
||||||
|
if ( !metadata["system"]["physics"]["collision"].as<bool>() ) {
|
||||||
|
physics.linear.acceleration.x = 0;
|
||||||
|
physics.linear.acceleration.y = 0;
|
||||||
|
physics.linear.acceleration.z = 0;
|
||||||
|
}
|
||||||
|
transform = uf::physics::update( transform, physics );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this->process([&]( uf::Entity* entity ) {
|
||||||
|
if ( !entity ) return;
|
||||||
|
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||||
|
if ( !ext::json::isNull( metadata["system"]["physics"]["collision"] ) && !metadata["system"]["physics"]["collision"].as<bool>() ) return;
|
||||||
|
if ( entity->hasComponent<uf::Collider>() )
|
||||||
|
entities.push_back((uf::Object*) entity);
|
||||||
|
});
|
||||||
|
auto onCollision = []( pod::Collider::Manifold& manifold, size_t uidA, size_t uidB, bool queued ){
|
||||||
|
uf::Serializer payload;
|
||||||
|
payload["normal"][0] = manifold.normal.x;
|
||||||
|
payload["normal"][1] = manifold.normal.y;
|
||||||
|
payload["normal"][2] = manifold.normal.z;
|
||||||
|
payload["entity"] = uidB;
|
||||||
|
payload["depth"] = -manifold.depth;
|
||||||
|
|
||||||
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
|
if ( queued ) scene.queueHook(uf::Object::formatHookName("world:Collision.%UID%",uidA), payload);
|
||||||
|
else scene.callHook(uf::Object::formatHookName("world:Collision.%UID%",uidA), payload);
|
||||||
|
|
||||||
|
payload["entity"] = uidA;
|
||||||
|
payload["depth"] = manifold.depth;
|
||||||
|
if ( queued ) scene.queueHook(uf::Object::formatHookName("world:Collision.%UID%",uidB), payload);
|
||||||
|
else scene.callHook(uf::Object::formatHookName("world:Collision.%UID%",uidB), payload);
|
||||||
|
};
|
||||||
|
auto testColliders = [&]( uf::Collider& colliderA, uf::Collider& colliderB, size_t uidA, size_t uidB, bool useStrongest ){
|
||||||
|
pod::Collider::Manifold strongest;
|
||||||
|
auto manifolds = colliderA.intersects(colliderB);
|
||||||
|
for ( auto manifold : manifolds ) {
|
||||||
|
if ( manifold.colliding && manifold.depth > 0 ) {
|
||||||
|
if ( !useStrongest ) onCollision(manifold, uidA, uidB, queued);
|
||||||
|
else if ( strongest.depth < manifold.depth ) strongest = manifold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( useStrongest && strongest.colliding ) onCollision(strongest, uidA, uidB, queued);
|
||||||
};
|
};
|
||||||
// collide with others
|
// collide with others
|
||||||
if ( ignoreDuplicateTests ) {
|
if ( ignoreDuplicateTests ) {
|
||||||
@ -137,7 +256,7 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
|
|||||||
auto& colliderA = entityA->getComponent<uf::Collider>();
|
auto& colliderA = entityA->getComponent<uf::Collider>();
|
||||||
auto& colliderB = entityB->getComponent<uf::Collider>();
|
auto& colliderB = entityB->getComponent<uf::Collider>();
|
||||||
auto function = [&]() -> int {
|
auto function = [&]() -> int {
|
||||||
testColliders( colliderA, colliderB, entityA, entityB, useStrongest );
|
testColliders( colliderA, colliderB, entityA->getUid(), entityB->getUid(), useStrongest );
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
if ( threaded && useWorkers ) uf::thread::add( uf::thread::fetchWorker(), function, true ); else function();
|
if ( threaded && useWorkers ) uf::thread::add( uf::thread::fetchWorker(), function, true ); else function();
|
||||||
@ -151,7 +270,7 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
|
|||||||
auto& colliderA = entityA.getComponent<uf::Collider>();
|
auto& colliderA = entityA.getComponent<uf::Collider>();
|
||||||
auto& colliderB = entityB.getComponent<uf::Collider>();
|
auto& colliderB = entityB.getComponent<uf::Collider>();
|
||||||
auto function = [&]() -> int {
|
auto function = [&]() -> int {
|
||||||
testColliders( colliderA, colliderB, &entityA, &entityB, useStrongest );
|
testColliders( colliderA, colliderB, entityA.getUid(), entityB.getUid(), useStrongest );
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
if ( threaded && useWorkers ) uf::thread::add( uf::thread::fetchWorker(), function, true ); else function();
|
if ( threaded && useWorkers ) uf::thread::add( uf::thread::fetchWorker(), function, true ); else function();
|
||||||
@ -162,6 +281,7 @@ void ext::SceneCollisionBehavior::tick( uf::Object& self ) {
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
if ( threaded ) uf::thread::add( thread, function, true ); else function();
|
if ( threaded ) uf::thread::add( thread, function, true ); else function();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void ext::SceneCollisionBehavior::render( uf::Object& self ){}
|
void ext::SceneCollisionBehavior::render( uf::Object& self ){}
|
||||||
|
@ -16,7 +16,7 @@ void ext::SoundEmitterBehavior::initialize( uf::Object& self ) {
|
|||||||
auto& metadata = this->getComponent<uf::Serializer>();
|
auto& metadata = this->getComponent<uf::Serializer>();
|
||||||
|
|
||||||
auto& scene = uf::scene::getCurrentScene();
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
auto& sMetadata = this->getComponent<uf::Serializer>();
|
auto& sMetadata = scene.getComponent<uf::Serializer>();
|
||||||
auto& assetLoader = scene.getComponent<uf::Asset>();
|
auto& assetLoader = scene.getComponent<uf::Asset>();
|
||||||
|
|
||||||
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
|
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
|
||||||
@ -31,7 +31,15 @@ void ext::SoundEmitterBehavior::initialize( uf::Object& self ) {
|
|||||||
uf::Audio& audio = this->getComponent<uf::Audio>(); //emitter.add(filename);
|
uf::Audio& audio = this->getComponent<uf::Audio>(); //emitter.add(filename);
|
||||||
audio.load(filename);
|
audio.load(filename);
|
||||||
{
|
{
|
||||||
float volume = metadata["audio"]["volume"].is<double>() ? metadata["audio"]["volume"].as<float>() : sMetadata["volumes"]["sfx"].as<float>();
|
float volume = 1.0f;
|
||||||
|
if ( metadata["audio"]["volume"].is<double>() ) {
|
||||||
|
volume = metadata["audio"]["volume"].as<float>();
|
||||||
|
} else if ( metadata["audio"]["volume"].is<std::string>() ) {
|
||||||
|
std::string key = metadata["audio"]["volume"].as<std::string>();
|
||||||
|
if ( sMetadata["volumes"][key].is<double>() ) {
|
||||||
|
volume = sMetadata["volumes"][key].as<float>();
|
||||||
|
}
|
||||||
|
}
|
||||||
audio.setVolume(volume);
|
audio.setVolume(volume);
|
||||||
}
|
}
|
||||||
if ( metadata["audio"]["pitch"].is<double>() ) {
|
if ( metadata["audio"]["pitch"].is<double>() ) {
|
||||||
@ -60,8 +68,10 @@ void ext::SoundEmitterBehavior::tick( uf::Object& self ) {
|
|||||||
// uf::Audio& audio = pair.second;
|
// uf::Audio& audio = pair.second;
|
||||||
{
|
{
|
||||||
uf::Audio& audio = this->getComponent<uf::Audio>();
|
uf::Audio& audio = this->getComponent<uf::Audio>();
|
||||||
audio.setPosition( transform.position );
|
if ( metadata["audio"]["spatial"].as<bool>() ) {
|
||||||
audio.setOrientation( transform.orientation );
|
audio.setPosition( transform.position );
|
||||||
|
audio.setOrientation( transform.orientation );
|
||||||
|
}
|
||||||
|
|
||||||
if ( metadata["audio"]["loop"].as<bool>() ) {
|
if ( metadata["audio"]["loop"].as<bool>() ) {
|
||||||
float current = audio.getTime();
|
float current = audio.getTime();
|
||||||
|
201
ext/main.cpp
201
ext/main.cpp
@ -44,6 +44,10 @@
|
|||||||
#include <uf/ext/openvr/openvr.h>
|
#include <uf/ext/openvr/openvr.h>
|
||||||
#include <uf/ext/lua/lua.h>
|
#include <uf/ext/lua/lua.h>
|
||||||
|
|
||||||
|
bool ext::ready = false;
|
||||||
|
std::vector<std::string> ext::arguments;
|
||||||
|
uf::Serializer ext::config;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct {
|
struct {
|
||||||
uf::String input;
|
uf::String input;
|
||||||
@ -65,13 +69,70 @@ namespace {
|
|||||||
double limiter = 1.0 / 144.0;
|
double limiter = 1.0 / 144.0;
|
||||||
} times;
|
} times;
|
||||||
|
|
||||||
uf::Serializer config;
|
uf::Serializer& config = ext::config;
|
||||||
}
|
}
|
||||||
bool ext::ready = false;
|
|
||||||
std::vector<std::string> ext::arguments;
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::string getConfig() {
|
||||||
|
struct {
|
||||||
|
bool initialized = false;
|
||||||
|
uf::Serializer file;
|
||||||
|
uf::Serializer fallback;
|
||||||
|
uf::Serializer merged;
|
||||||
|
} static config;
|
||||||
|
if ( config.initialized ) return config.merged;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool exists = false;
|
||||||
|
std::string filename = "./data/config.json";
|
||||||
|
} file;
|
||||||
|
/* Read from file */ {
|
||||||
|
file.exists = config.file.readFromFile(file.filename);
|
||||||
|
}
|
||||||
|
/* Initialize default configuration */ {
|
||||||
|
config.fallback["window"]["terminal"]["ncurses"] = true;
|
||||||
|
config.fallback["window"]["terminal"]["visible"] = true;
|
||||||
|
config.fallback["window"]["title"] = "Grimgram";
|
||||||
|
config.fallback["window"]["icon"] = "";
|
||||||
|
config.fallback["window"]["size"]["x"] = 0;
|
||||||
|
config.fallback["window"]["size"]["y"] = 0;
|
||||||
|
config.fallback["window"]["visible"] = true;
|
||||||
|
// config.fallback["window"]["fullscreen"] = false;
|
||||||
|
config.fallback["window"]["mode"] = "windowed";
|
||||||
|
config.fallback["window"]["cursor"]["visible"] = true;
|
||||||
|
config.fallback["window"]["cursor"]["center"] = false;
|
||||||
|
config.fallback["window"]["keyboard"]["repeat"] = true;
|
||||||
|
|
||||||
|
config.fallback["engine"]["scenes"]["start"] = "StartMenu";
|
||||||
|
config.fallback["engine"]["scenes"]["max lights"] = 32;
|
||||||
|
config.fallback["engine"]["hook"]["mode"] = "Readable";
|
||||||
|
config.fallback["engine"]["limiters"]["framerate"] = 60;
|
||||||
|
config.fallback["engine"]["limiters"]["deltaTime"] = 120;
|
||||||
|
config.fallback["engine"]["threads"]["workers"] = "auto";
|
||||||
|
config.fallback["engine"]["threads"]["frame limiter"] = 144;
|
||||||
|
config.fallback["engine"]["memory pool"]["size"] = "512 MiB";
|
||||||
|
config.fallback["engine"]["memory pool"]["globalOverride"] = false;
|
||||||
|
config.fallback["engine"]["memory pool"]["subPools"] = true;
|
||||||
|
}
|
||||||
|
/* Merge */ if ( file.exists ){
|
||||||
|
config.merged = config.file;
|
||||||
|
config.merged.merge( config.fallback, true );
|
||||||
|
} else {
|
||||||
|
config.merged = config.fallback;
|
||||||
|
}
|
||||||
|
/* Write default to file */ if ( false ) {
|
||||||
|
config.merged.writeToFile(file.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
config.initialized = true;
|
||||||
|
return config.merged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EXT_API ext::load() {
|
||||||
|
ext::config = getConfig();
|
||||||
|
}
|
||||||
void EXT_API ext::initialize() {
|
void EXT_API ext::initialize() {
|
||||||
::config = ext::getConfig();
|
|
||||||
/* Arguments */ {
|
/* Arguments */ {
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
auto& arguments = ::config["arguments"];
|
auto& arguments = ::config["arguments"];
|
||||||
@ -128,64 +189,69 @@ void EXT_API ext::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse config */ {
|
/* Parse config */ {
|
||||||
// Set memory pool sizes
|
/* Set memory pool sizes */ {
|
||||||
{
|
auto deduceSize = []( const Json::Value& value )->size_t{
|
||||||
auto deduceSize = []( const Json::Value& value )->size_t{
|
if ( value.is<double>() ) return value.as<size_t>();
|
||||||
if ( value.is<double>() ) return value.as<size_t>();
|
if ( value.is<std::string>() ) {
|
||||||
if ( value.is<std::string>() ) {
|
std::string str = value.as<std::string>();
|
||||||
std::string str = value.as<std::string>();
|
std::regex regex("^(\\d+) ?((?:K|M|G)?(?:i?B)?)$");
|
||||||
std::regex regex("^(\\d+) ?((?:K|M|G)?(?:i?B)?)$");
|
std::smatch match;
|
||||||
std::smatch match;
|
if ( std::regex_search( str, match, regex ) ) {
|
||||||
if ( std::regex_search( str, match, regex ) ) {
|
size_t requested = std::stoi( match[1].str() );
|
||||||
size_t requested = std::stoi( match[1].str() );
|
std::string prefix = match[2].str();
|
||||||
std::string prefix = match[2].str();
|
switch ( prefix.at(0) ) {
|
||||||
switch ( prefix.at(0) ) {
|
case 'K': return requested * 1024;
|
||||||
case 'K': return requested * 1024;
|
case 'M': return requested * 1024 * 1024;
|
||||||
case 'M': return requested * 1024 * 1024;
|
case 'G': return requested * 1024 * 1024 * 1024;
|
||||||
case 'G': return requested * 1024 * 1024 * 1024;
|
|
||||||
}
|
|
||||||
return requested;
|
|
||||||
}
|
}
|
||||||
|
return requested;
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
};
|
return 0;
|
||||||
{
|
};
|
||||||
size_t size = deduceSize( ::config["engine"]["memory pool"]["size"] );
|
{
|
||||||
uf::MemoryPool::globalOverride = ::config["engine"]["memory pool"]["globalOverride"].as<bool>();
|
size_t size = deduceSize( ::config["engine"]["memory pool"]["size"] );
|
||||||
uf::iostream << "Requesting " << (int) size << " bytes for global memory pool: " << &uf::MemoryPool::global << "\n";
|
uf::MemoryPool::globalOverride = ::config["engine"]["memory pool"]["globalOverride"].as<bool>();
|
||||||
uf::MemoryPool::global.initialize( size );
|
uf::iostream << "Requesting " << (int) size << " bytes for global memory pool: " << &uf::MemoryPool::global << "\n";
|
||||||
uf::MemoryPool::subPool = ::config["engine"]["memory pool"]["subPools"].as<bool>();
|
uf::MemoryPool::global.initialize( size );
|
||||||
if ( size <= 0 || uf::MemoryPool::subPool ) {
|
uf::MemoryPool::subPool = ::config["engine"]["memory pool"]["subPools"].as<bool>();
|
||||||
{
|
if ( size <= 0 || uf::MemoryPool::subPool ) {
|
||||||
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["component"] );
|
{
|
||||||
uf::iostream << "Requesting " << (int) size << " bytes for component memory pool: " << &uf::component::memoryPool << "\n";
|
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["component"] );
|
||||||
uf::component::memoryPool.initialize( size );
|
uf::iostream << "Requesting " << (int) size << " bytes for component memory pool: " << &uf::component::memoryPool << "\n";
|
||||||
}
|
uf::component::memoryPool.initialize( size );
|
||||||
{
|
}
|
||||||
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["userdata"] );
|
{
|
||||||
uf::iostream << "Requesting " << (int) size << " bytes for userdata memory pool: " << &uf::userdata::memoryPool << "\n";
|
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["userdata"] );
|
||||||
uf::userdata::memoryPool.initialize( size );
|
uf::iostream << "Requesting " << (int) size << " bytes for userdata memory pool: " << &uf::userdata::memoryPool << "\n";
|
||||||
}
|
uf::userdata::memoryPool.initialize( size );
|
||||||
{
|
}
|
||||||
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["entity"] );
|
{
|
||||||
uf::iostream << "Requesting " << (int) size << " bytes for entity memory pool: " << &uf::Entity::memoryPool << "\n";
|
size_t size = deduceSize( ::config["engine"]["memory pool"]["pools"]["entity"] );
|
||||||
uf::Entity::memoryPool.initialize( size );
|
uf::iostream << "Requesting " << (int) size << " bytes for entity memory pool: " << &uf::Entity::memoryPool << "\n";
|
||||||
}
|
uf::Entity::memoryPool.initialize( size );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if ( ::config["engine"]["limiters"]["framerate"].as<std::string>() == "auto" && ::config["window"]["refresh rate"].is<size_t>() ) {
|
||||||
|
double scale = 1.0;
|
||||||
|
size_t refreshRate = ::config["window"]["refresh rate"].as<size_t>();
|
||||||
|
::config["engine"]["limiters"]["framerate"] = refreshRate * scale;
|
||||||
|
uf::iostream << "Setting framerate cap to " << (int) refreshRate * scale << "\n";
|
||||||
|
}
|
||||||
|
if ( ::config["engine"]["threads"]["frame limiter"].as<std::string>() == "auto" && ::config["window"]["refresh rate"].is<size_t>() ) {
|
||||||
|
double scale = 2.0;
|
||||||
|
size_t refreshRate = ::config["window"]["refresh rate"].as<size_t>();
|
||||||
|
::config["engine"]["threads"]["frame limiter"] = refreshRate * scale;
|
||||||
|
uf::iostream << "Setting thread frame limiter to " << (int) refreshRate * scale << "\n";
|
||||||
|
}
|
||||||
/* Frame limiter */ {
|
/* Frame limiter */ {
|
||||||
double limit = ::config["engine"]["limiters"]["framerate"].as<double>();
|
double limit = ::config["engine"]["limiters"]["framerate"].as<double>();
|
||||||
if ( limit != 0 )
|
if ( limit != 0 )
|
||||||
::times.limiter = 1.0 / ::config["engine"]["limiters"]["framerate"].as<double>();
|
::times.limiter = 1.0 / ::config["engine"]["limiters"]["framerate"].as<double>();
|
||||||
else ::times.limiter = 0;
|
else ::times.limiter = 0;
|
||||||
}
|
}
|
||||||
/* Max delta time */{
|
|
||||||
double limit = ::config["engine"]["limiters"]["deltaTime"].as<double>();
|
|
||||||
if ( limit != 0 )
|
|
||||||
uf::physics::time::clamp = 1.0 / ::config["engine"]["limiters"]["deltaTime"].as<double>();
|
|
||||||
else uf::physics::time::clamp = 0;
|
|
||||||
}
|
|
||||||
/* Thread frame limiter */ {
|
/* Thread frame limiter */ {
|
||||||
double limit = ::config["engine"]["threads"]["frame limiter"].as<double>();
|
double limit = ::config["engine"]["threads"]["frame limiter"].as<double>();
|
||||||
if ( limit != 0 )
|
if ( limit != 0 )
|
||||||
@ -193,6 +259,12 @@ void EXT_API ext::initialize() {
|
|||||||
else
|
else
|
||||||
uf::thread::limiter = 0;
|
uf::thread::limiter = 0;
|
||||||
}
|
}
|
||||||
|
/* Max delta time */{
|
||||||
|
double limit = ::config["engine"]["limiters"]["deltaTime"].as<double>();
|
||||||
|
if ( limit != 0 )
|
||||||
|
uf::physics::time::clamp = 1.0 / ::config["engine"]["limiters"]["deltaTime"].as<double>();
|
||||||
|
else uf::physics::time::clamp = 0;
|
||||||
|
}
|
||||||
// Mute audio
|
// Mute audio
|
||||||
if ( ::config["engine"]["audio"]["mute"].is<bool>() )
|
if ( ::config["engine"]["audio"]["mute"].is<bool>() )
|
||||||
uf::Audio::mute = ::config["engine"]["audio"]["mute"].as<bool>();
|
uf::Audio::mute = ::config["engine"]["audio"]["mute"].as<bool>();
|
||||||
@ -320,8 +392,8 @@ void EXT_API ext::initialize() {
|
|||||||
uf::Serializer json = event;
|
uf::Serializer json = event;
|
||||||
uf::renderer::synchronize();
|
uf::renderer::synchronize();
|
||||||
|
|
||||||
// uf::hooks.call("game:Scene.Cleanup");
|
uf::hooks.call("game:Scene.Cleanup");
|
||||||
uf::scene::unloadScene();
|
// uf::scene::unloadScene();
|
||||||
|
|
||||||
auto& scene = uf::scene::loadScene( json["scene"].as<std::string>() );
|
auto& scene = uf::scene::loadScene( json["scene"].as<std::string>() );
|
||||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||||
@ -339,15 +411,23 @@ void EXT_API ext::initialize() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
uf::hooks.addHook( "game:Scene.Cleanup", [&](const std::string& event)->std::string{
|
uf::hooks.addHook( "game:Scene.Cleanup", [&](const std::string& event)->std::string{
|
||||||
|
for ( auto* scene : uf::scene::scenes ) {
|
||||||
|
if ( scene->hasComponent<uf::Audio>() ) {
|
||||||
|
scene->getComponent<uf::Audio>().destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uf::scene::unloadScene();
|
||||||
|
/*
|
||||||
for ( auto* scene : uf::scene::scenes ) {
|
for ( auto* scene : uf::scene::scenes ) {
|
||||||
scene->destroy();
|
scene->destroy();
|
||||||
delete scene;
|
delete scene;
|
||||||
}
|
}
|
||||||
uf::scene::scenes.clear();
|
uf::scene::scenes.clear();
|
||||||
|
*/
|
||||||
return "true";
|
return "true";
|
||||||
});
|
});
|
||||||
uf::hooks.addHook( "system:Quit", [&](const std::string& event)->std::string{
|
uf::hooks.addHook( "system:Quit", [&](const std::string& event)->std::string{
|
||||||
uf::iostream << "system:Quit: " << event << "\n";
|
// uf::iostream << "system:Quit: " << event << "\n";
|
||||||
ext::ready = false;
|
ext::ready = false;
|
||||||
return "true";
|
return "true";
|
||||||
});
|
});
|
||||||
@ -498,11 +578,12 @@ void EXT_API ext::tick() {
|
|||||||
/* Garbage collection */ if ( ::config["engine"]["debug"]["garbage collection"]["enabled"].as<bool>() ) {
|
/* Garbage collection */ if ( ::config["engine"]["debug"]["garbage collection"]["enabled"].as<bool>() ) {
|
||||||
static uf::Timer<long long> timer(false);
|
static uf::Timer<long long> timer(false);
|
||||||
if ( !timer.running() ) timer.start();
|
if ( !timer.running() ) timer.start();
|
||||||
double every = ::config["engine"]["debug"]["framerate"]["every"].as<double>();
|
double every = ::config["engine"]["debug"]["garbage collection"]["every"].as<double>();
|
||||||
uint8_t mode = ::config["engine"]["debug"]["framerate"]["mode"].as<uint64_t>();
|
uint8_t mode = ::config["engine"]["debug"]["garbage collection"]["mode"].as<uint64_t>();
|
||||||
|
bool announce = ::config["engine"]["debug"]["garbage collection"]["announce"].as<bool>();
|
||||||
if ( timer.elapsed().asDouble() >= every ) { timer.reset();
|
if ( timer.elapsed().asDouble() >= every ) { timer.reset();
|
||||||
size_t collected = uf::instantiator::collect( mode );
|
size_t collected = uf::instantiator::collect( mode );
|
||||||
if ( collected > 0 ) {
|
if ( announce && collected > 0 ) {
|
||||||
uf::iostream << "GC collected " << (int) collected << " unused entities" << "\n";
|
uf::iostream << "GC collected " << (int) collected << " unused entities" << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -593,6 +674,7 @@ void EXT_API ext::terminate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
std::string EXT_API ext::getConfig() {
|
std::string EXT_API ext::getConfig() {
|
||||||
struct {
|
struct {
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
@ -646,4 +728,5 @@ std::string EXT_API ext::getConfig() {
|
|||||||
|
|
||||||
config.initialized = true;
|
config.initialized = true;
|
||||||
return config.merged;
|
return config.merged;
|
||||||
}
|
}
|
||||||
|
#endif
|
@ -157,7 +157,7 @@ void ext::RayTracingSceneBehavior::tick( uf::Object& self ) {
|
|||||||
if ( !entity || entity->getName() != "Light" ) return;
|
if ( !entity || entity->getName() != "Light" ) return;
|
||||||
entities.push_back(entity);
|
entities.push_back(entity);
|
||||||
};
|
};
|
||||||
for ( uf::Scene* scene : uf::renderer::scenes ) { if ( !scene ) continue;
|
for ( uf::Scene* scene : uf::scene::scenes ) { if ( !scene ) continue;
|
||||||
scene->process(filter);
|
scene->process(filter);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
ARCH = win64
|
ARCH = win64
|
||||||
PREFIX = gcc
|
PREFIX = gcc
|
||||||
CC = /opt/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/bin/g++
|
CC = /opt/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/bin/g++
|
||||||
FLAGS = -fdiagnostics-color=always -Wall -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 = -Og -fdiagnostics-color=always -Wall -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
|
Loading…
Reference in New Issue
Block a user