Commit for 2020.10.21.7z
This commit is contained in:
parent
1393f1b77a
commit
7027ce2db7
24
Makefile
24
Makefile
@ -15,19 +15,19 @@ UF_LIBS =
|
||||
# EXT_LIBS = -lpng16 -lz -lassimp -lsfml-main -lsfml-system -lsfml-window -lsfml-graphics -llua52
|
||||
# EXT_LIBS = -lpng16 -lz -lassimp -ljsoncpp -lopenal32 -lalut -lvorbis -lvorbisfile -logg -lfreetype
|
||||
EXT_LIBS =
|
||||
#FLAGS = -Og -DUF_DISABLE_ALIGNAS -std=c++20 -Wno-c++11-narrowing -Wno-narrowing -g -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW
|
||||
FLAGS = -std=c++20 -Wno-c++11-narrowing -Wno-narrowing -g -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW
|
||||
#FLAGS = -std=c++0x -Wall -g -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENGL -DUF_USE_GLEW
|
||||
FLAGS = -Og -std=c++17 -g -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW
|
||||
#-march=native
|
||||
LIB_NAME = uf
|
||||
EXT_LIB_NAME = ext
|
||||
|
||||
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.101.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.108.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.114.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /cygdrive/c/VulkanSDK/1.1.101.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /cygdrive/c/VulkanSDK/1.1.108.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /cygdrive/c/VulkanSDK/1.1.114.0/
|
||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.141.2/
|
||||
VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.154.0/
|
||||
WIN64_CC = g++
|
||||
WIN64_CC = /opt/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/bin/g++
|
||||
WIN64_GLSL_VALIDATOR = $(VULKAN_WIN64_SDK_PATH)/Bin32/glslangValidator
|
||||
# Base Engine's DLL
|
||||
WIN64_INC_DIR = $(ENGINE_INC_DIR)/win64
|
||||
@ -39,8 +39,8 @@ WIN64_FLAGS = $(FLAGS) -g
|
||||
#-Wl,-subsystem,windows
|
||||
|
||||
WIN64_LIB_DIR = $(ENGINE_LIB_DIR)/win64/
|
||||
WIN64_INCS = -I$(ENGINE_INC_DIR) -I$(WIN64_INC_DIR) -I$(VULKAN_WIN64_SDK_PATH)/include
|
||||
WIN64_LIBS = -L$(ENGINE_LIB_DIR) -L$(WIN64_LIB_DIR) -L$(VULKAN_WIN64_SDK_PATH)/Lib
|
||||
WIN64_INCS = -I$(ENGINE_INC_DIR) -I$(WIN64_INC_DIR) -I$(VULKAN_WIN64_SDK_PATH)/include -I/mingw64/include
|
||||
WIN64_LIBS = -L$(ENGINE_LIB_DIR) -L$(WIN64_LIB_DIR) -L$(VULKAN_WIN64_SDK_PATH)/Lib -L/mingw64/lib
|
||||
|
||||
SRCS_WIN64_DLL = $(wildcard $(ENGINE_SRC_DIR)/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*/*.cpp)
|
||||
OBJS_WIN64_DLL = $(patsubst %.cpp,%.win64.o,$(SRCS_WIN64_DLL))
|
||||
@ -56,8 +56,8 @@ EXT_WIN64_FLAGS = $(FLAGS)
|
||||
#-Wl,-subsystem,windows
|
||||
|
||||
EXT_WIN64_LIB_DIR = $(ENGINE_LIB_DIR)/win64/
|
||||
EXT_WIN64_INCS = -I$(ENGINE_INC_DIR) -I$(EXT_WIN64_INC_DIR) -I$(VULKAN_WIN64_SDK_PATH)/include
|
||||
EXT_WIN64_LIBS = -L$(ENGINE_LIB_DIR) -L$(EXT_WIN64_LIB_DIR) -L$(VULKAN_WIN64_SDK_PATH)/Lib
|
||||
EXT_WIN64_INCS = -I$(ENGINE_INC_DIR) -I$(EXT_WIN64_INC_DIR) -I$(VULKAN_WIN64_SDK_PATH)/include -I/mingw64/include
|
||||
EXT_WIN64_LIBS = -L$(ENGINE_LIB_DIR) -L$(EXT_WIN64_LIB_DIR) -L$(VULKAN_WIN64_SDK_PATH)/Lib -L/mingw64/lib
|
||||
|
||||
SRCS_EXT_WIN64_DLL = $(wildcard $(EXT_SRC_DIR)/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*/*/*.cpp)
|
||||
OBJS_EXT_WIN64_DLL = $(patsubst %.cpp,%.win64.o,$(SRCS_EXT_WIN64_DLL))
|
||||
@ -72,10 +72,6 @@ TARGET_WIN64 = $(BIN_DIR)/$(TARGET_NAME).exe
|
||||
SRCS_SHADERS = $(wildcard bin/data/shaders/*.glsl)
|
||||
TARGET_SHADERS = $(patsubst %.glsl,%.spv,$(SRCS_SHADERS))
|
||||
|
||||
# clang-win64: WIN64_CC=clang++
|
||||
# make
|
||||
# gcc-win64: WIN64_CC=g++
|
||||
# make
|
||||
win64: $(EX_WIN64_DLL) $(EXT_EX_WIN64_DLL) $(TARGET_WIN64) $(TARGET_SHADERS)
|
||||
|
||||
rm-exe64:
|
||||
|
@ -32,6 +32,7 @@ struct Light {
|
||||
vec3 color;
|
||||
float power;
|
||||
vec2 type;
|
||||
vec2 padding;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
};
|
||||
@ -44,6 +45,7 @@ struct State {
|
||||
|
||||
struct Fog {
|
||||
vec2 range;
|
||||
vec2 padding;
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
template<typename C>
|
||||
pod::NamedTypes<C>::type_t pod::NamedTypes<C>::getType( const std::string& name ) {
|
||||
typename pod::NamedTypes<C>::type_t pod::NamedTypes<C>::getType( const std::string& name ) {
|
||||
for ( auto pair : names ) if ( pair.second == name ) return pair.first;
|
||||
return getType<void>();
|
||||
}
|
||||
template<typename C>
|
||||
template<typename T> pod::NamedTypes<C>::type_t pod::NamedTypes<C>::getType() {
|
||||
template<typename T> typename pod::NamedTypes<C>::type_t pod::NamedTypes<C>::getType() {
|
||||
return std::type_index(typeid(T));
|
||||
}
|
||||
template<typename C>
|
||||
|
@ -97,6 +97,8 @@ namespace ext {
|
||||
};
|
||||
VkQueue& getQueue( QueueEnum );
|
||||
VkCommandPool& getCommandPool( QueueEnum );
|
||||
VkQueue& getQueue( QueueEnum, std::thread::id );
|
||||
VkCommandPool& getCommandPool( QueueEnum, std::thread::id );
|
||||
|
||||
// RAII
|
||||
void initialize();
|
||||
|
@ -104,6 +104,7 @@ namespace ext {
|
||||
Pipeline& getPipeline( Descriptor& descriptor );
|
||||
|
||||
void record( VkCommandBuffer commandBuffer );
|
||||
void record( VkCommandBuffer commandBuffer, Descriptor& descriptor );
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ namespace ext {
|
||||
|
||||
struct UF_API RenderMode {
|
||||
bool execute = false;
|
||||
bool rebuild = false;
|
||||
uint32_t width = 0, height = 0;
|
||||
std::string name = "";
|
||||
|
||||
@ -16,18 +17,25 @@ namespace ext {
|
||||
|
||||
VkSemaphore renderCompleteSemaphore;
|
||||
std::vector<VkFence> fences;
|
||||
std::vector<VkCommandBuffer> commands;
|
||||
|
||||
typedef std::vector<VkCommandBuffer> commands_container_t;
|
||||
std::thread::id mostRecentCommandPoolId;
|
||||
std::unordered_map<std::thread::id, commands_container_t> commands;
|
||||
|
||||
// virtual ~RenderMode();
|
||||
// RAII
|
||||
virtual std::string getType() const;
|
||||
const std::string& getName() const;
|
||||
const std::string& getName( bool = false ) const;
|
||||
virtual RenderTarget& getRenderTarget(size_t = 0);
|
||||
virtual const RenderTarget& getRenderTarget(size_t = 0) const;
|
||||
|
||||
virtual commands_container_t& getCommands();
|
||||
virtual commands_container_t& getCommands( std::thread::id );
|
||||
|
||||
virtual void initialize( Device& device );
|
||||
virtual void createCommandBuffers();
|
||||
virtual void createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics );
|
||||
virtual void bindPipelines( const std::vector<ext::vulkan::Graphic*>& graphics );
|
||||
virtual void tick();
|
||||
virtual void render();
|
||||
virtual void destroy();
|
||||
|
@ -14,6 +14,7 @@ namespace ext {
|
||||
|
||||
// RAII
|
||||
virtual std::string getType() const;
|
||||
virtual const std::string& getName( bool ) const;
|
||||
|
||||
virtual void createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics );
|
||||
virtual void initialize( Device& device );
|
||||
|
@ -25,8 +25,11 @@ namespace uf {
|
||||
Audio( Audio&& );
|
||||
Audio( const Audio& );
|
||||
*/
|
||||
~Audio();
|
||||
|
||||
bool initialized();
|
||||
bool playing();
|
||||
void destroy();
|
||||
|
||||
void load( const std::string& = "" );
|
||||
void play();
|
||||
|
@ -10,13 +10,11 @@ namespace {
|
||||
// Sometimes uint isn't declared
|
||||
typedef unsigned int uint;
|
||||
}
|
||||
/*
|
||||
namespace uf {
|
||||
namespace math {
|
||||
template<typename T>
|
||||
T lerp( const T& from, const T& to, double delta ) {
|
||||
|
||||
T lerp( const T& a, const T& b, double f ) {
|
||||
return a + f * (b - a);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
@ -6,6 +6,7 @@
|
||||
|
||||
namespace uf {
|
||||
namespace io {
|
||||
std::string UF_API absolute( const std::string& );
|
||||
std::string UF_API filename( const std::string& );
|
||||
std::string UF_API extension( const std::string& );
|
||||
std::string UF_API directory( const std::string& );
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace pod {
|
||||
struct UF_API Thread {
|
||||
@ -22,6 +23,7 @@ namespace pod {
|
||||
bool running, terminates;
|
||||
|
||||
std::mutex* mutex;
|
||||
std::condition_variable condition;
|
||||
std::thread thread;
|
||||
|
||||
pod::Thread::queue_t temps;
|
||||
@ -45,6 +47,7 @@ namespace uf {
|
||||
// void UF_API tick( pod::Thread&, const std::function<void()>& = NULL );
|
||||
|
||||
pod::Thread& UF_API fetchWorker( const std::string& name = "Aux" );
|
||||
void UF_API batchWorkers( const std::vector<pod::Thread::function_t>&, bool = true, const std::string& name = "Aux" );
|
||||
void UF_API add( pod::Thread&, const pod::Thread::function_t&, bool = false );
|
||||
void UF_API process( pod::Thread& );
|
||||
|
||||
|
@ -31,6 +31,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
//
|
||||
{
|
||||
size_t assets = metadata["system"]["assets"].size();
|
||||
if ( metadata["system"]["load"]["ignore"].isBool() ) assets = 0;
|
||||
metadata["system"]["load"]["progress"] = 0;
|
||||
metadata["system"]["load"]["total"] = assets;
|
||||
if ( assets == 0 ) {
|
||||
@ -62,6 +63,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
std::string filename = json["filename"].asString();
|
||||
bool initialize = json["initialize"].isNull() ? true : json["initialize"].asBool();
|
||||
|
||||
if ( uf::io::extension(filename) != "json" ) return "false";
|
||||
|
||||
@ -72,7 +74,8 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
||||
json["root"] = uf::io::directory(filename);
|
||||
json["source"] = filename; // uf::io::filename(filename)
|
||||
json["hot reload"]["mtime"] = uf::io::mtime( filename ) + 10;
|
||||
if ( this->loadChildUid(json) == -1 ) return "false";
|
||||
|
||||
if ( this->loadChildUid(json, initialize) == -1 ) return "false";
|
||||
|
||||
return "true";
|
||||
});
|
||||
|
@ -87,6 +87,7 @@ void uf::LoadingBehavior::tick( uf::Object& self ) {
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity || entity->getUid() == 0 || !entity->hasComponent<uf::Serializer>() ) return;
|
||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||
if ( metadata["system"]["load"]["ignore"].isBool() ) return;
|
||||
if ( metadata["system"]["load"].isNull() ) return;
|
||||
++loading;
|
||||
if ( metadata["system"]["load"]["progress"].asInt() < metadata["system"]["load"]["total"].asInt() ) return;
|
||||
|
@ -31,9 +31,11 @@ bool UF_API_CALL ext::AL::initialize() {
|
||||
}
|
||||
return this->m_initialized = true;
|
||||
*/
|
||||
bool res = this->m_initialized = (alutInit(NULL, NULL) == AL_TRUE);
|
||||
this->m_initialized = alutInit(NULL, NULL) == AL_TRUE;
|
||||
auto error = alutGetError();
|
||||
std::cout << alutGetErrorString(error) << std::endl;
|
||||
this->checkError(__FUNCTION__, __LINE__);
|
||||
return res;
|
||||
return this->m_initialized;
|
||||
}
|
||||
bool UF_API_CALL ext::AL::terminate() {
|
||||
/*
|
||||
@ -46,7 +48,9 @@ bool UF_API_CALL ext::AL::terminate() {
|
||||
}
|
||||
void UF_API_CALL ext::AL::checkError( const std::string& function, int line, const std::string& aux ) const {
|
||||
std::string error = this->getError();
|
||||
// if ( error != "AL_NO_ERROR" ) std::cerr << "AL error @ " << function << ":" << line << ": "<<(aux!=""?"("+aux+") ":"")<< error << std::endl;
|
||||
if ( error != "AL_NO_ERROR" ) std::cerr << "AL error @ " << function << ":" << line << ": "<<(aux!=""?"("+aux+") ":"")<< error << std::endl;
|
||||
error = alutGetErrorString(alutGetError());
|
||||
if ( error != "No ALUT error found" ) std::cerr << "AL error @ " << function << ":" << line << ": "<<(aux!=""?"("+aux+") ":"")<< error << std::endl;
|
||||
}
|
||||
std::string UF_API_CALL ext::AL::getError() const {
|
||||
ALCenum error = alGetError();
|
||||
@ -58,7 +62,7 @@ std::string UF_API_CALL ext::AL::getError() const {
|
||||
case AL_INVALID_OPERATION: return "AL_INVALID_OPERATION"; // the requested operation is not valid
|
||||
case AL_OUT_OF_MEMORY: return "AL_OUT_OF_MEMORY"; // the requested operation resulted in OpenAL running out ofmemory
|
||||
}
|
||||
return "AL_UNKNOWN";
|
||||
return "AL_UNKNOWN(" + std::to_string(error) + ")";
|
||||
}
|
||||
void UF_API_CALL ext::AL::listener( ALenum name, std::vector<ALfloat> parameters ) {
|
||||
switch ( parameters.size() ) {
|
||||
@ -86,13 +90,12 @@ ext::al::Source::~Source() {
|
||||
|
||||
void UF_API_CALL ext::al::Source::generate() {
|
||||
if ( this->m_index ) this->destroy();
|
||||
alGenSources(1, &this->m_index);
|
||||
ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
alGenSources(1, &this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
}
|
||||
void UF_API_CALL ext::al::Source::destroy() {
|
||||
if ( this->m_index && alIsSource(this->m_index) ) {
|
||||
alDeleteSources(1, &this->m_index);
|
||||
ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
if ( this->playing() ) this->stop();
|
||||
alDeleteSources(1, &this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
}
|
||||
this->m_index = 0;
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
#include <uf/ext/openvr/openvr.h>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
#include <uf/utils/string/ext.h>
|
||||
#include <uf/utils/string/io.h>
|
||||
|
||||
#include <uf/ext/vulkan/vulkan.h>
|
||||
#include <uf/ext/vulkan/rendermodes/stereoscopic_deferred.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <stdlib.h>
|
||||
#define DEBUG_MARKER 0
|
||||
|
||||
vr::IVRSystem* ext::openvr::context;
|
||||
@ -156,10 +155,7 @@ bool ext::openvr::initialize( int stage ) {
|
||||
|
||||
// load manifest
|
||||
{
|
||||
std::filesystem::path p = ext::openvr::driver.manifest;
|
||||
p = std::filesystem::absolute( p );
|
||||
ext::openvr::driver.manifest = p.string();
|
||||
VR_CHECK_INPUT_RESULT( vr::VRInput()->SetActionManifestPath( ext::openvr::driver.manifest.c_str() ) );
|
||||
VR_CHECK_INPUT_RESULT( vr::VRInput()->SetActionManifestPath( uf::io::absolute(ext::openvr::driver.manifest).c_str() ) );
|
||||
// configure action handles
|
||||
{
|
||||
uf::Serializer manifest;
|
||||
|
@ -436,10 +436,15 @@ VkResult ext::vulkan::Device::createBuffer(
|
||||
return buffer.bind();
|
||||
}
|
||||
VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::Device::QueueEnum queueEnum) {
|
||||
return this->getCommandPool( queueEnum, std::this_thread::get_id() );
|
||||
}
|
||||
VkQueue& ext::vulkan::Device::getQueue( ext::vulkan::Device::QueueEnum queueEnum ) {
|
||||
return this->getQueue( queueEnum, std::this_thread::get_id() );
|
||||
}
|
||||
VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::Device::QueueEnum queueEnum, std::thread::id id ) {
|
||||
uint32_t index = 0;
|
||||
VkCommandPool* pool = NULL;
|
||||
bool exists = false;
|
||||
auto id = std::this_thread::get_id();
|
||||
switch ( queueEnum ) {
|
||||
case QueueEnum::GRAPHICS:
|
||||
index = device.queueFamilyIndices.graphics;
|
||||
@ -468,11 +473,10 @@ VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::Device::QueueEn
|
||||
}
|
||||
return *pool;
|
||||
}
|
||||
VkQueue& ext::vulkan::Device::getQueue( ext::vulkan::Device::QueueEnum queueEnum ) {
|
||||
VkQueue& ext::vulkan::Device::getQueue( ext::vulkan::Device::QueueEnum queueEnum, std::thread::id id ) {
|
||||
uint32_t index = 0;
|
||||
VkQueue* queue = NULL;
|
||||
bool exists = false;
|
||||
auto id = std::this_thread::get_id();
|
||||
switch ( queueEnum ) {
|
||||
case QueueEnum::GRAPHICS:
|
||||
index = device.queueFamilyIndices.graphics;
|
||||
|
@ -479,6 +479,9 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
// generate fallback empty texture
|
||||
auto& emptyTexture = Texture2D::empty;
|
||||
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode(graphic.descriptor.renderMode, true);
|
||||
auto& renderTarget = renderMode.getRenderTarget(graphic.descriptor.renderTarget );
|
||||
|
||||
std::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
||||
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings;
|
||||
std::vector<VkDescriptorImageInfo> inputDescriptors;
|
||||
@ -488,9 +491,6 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
descriptorSetLayoutBindings.insert( descriptorSetLayoutBindings.begin(), shader.descriptorSetLayoutBindings.begin(), shader.descriptorSetLayoutBindings.end() );
|
||||
}
|
||||
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode(graphic.descriptor.renderMode, true);
|
||||
auto& renderTarget = renderMode.getRenderTarget(graphic.descriptor.renderTarget );
|
||||
|
||||
if ( graphic.descriptor.subpass < renderTarget.passes.size() ) {
|
||||
auto& subpass = renderTarget.passes[graphic.descriptor.subpass];
|
||||
for ( auto& input : subpass.inputs ) {
|
||||
@ -563,6 +563,8 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
|
||||
if ( d.imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL )
|
||||
d.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
} else {
|
||||
// std::cout << "textures == graphic.material.textures.end()" << std::endl;
|
||||
}
|
||||
imageInfos.push_back( d );
|
||||
}
|
||||
@ -668,10 +670,11 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
for ( auto& descriptor : writeDescriptorSets ) {
|
||||
if ( descriptor.pBufferInfo ) {
|
||||
// std::cout << descriptor.pBufferInfo->offset << std::endl;
|
||||
if ( descriptor.pBufferInfo->offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
|
||||
// std::cout << "Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.pBufferInfo->offset << std::endl;
|
||||
std::cout << "Invalid descriptor for buffer: " << descriptor.pBufferInfo->buffer << " " << descriptor.pBufferInfo->offset << " " << descriptor.pBufferInfo->range << ", invalidating..." << std::endl;
|
||||
auto pointer = const_cast<VkDescriptorBufferInfo*>(descriptor.pBufferInfo);
|
||||
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
|
||||
if ( descriptor.pBufferInfo[i].offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
|
||||
// std::cout << "Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.pBufferInfo[i].offset << std::endl;
|
||||
std::cout << "Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " " << descriptor.pBufferInfo[i].offset << " " << descriptor.pBufferInfo[i].range << ", invalidating..." << std::endl;
|
||||
auto pointer = const_cast<VkDescriptorBufferInfo*>(&descriptor.pBufferInfo[i]);
|
||||
pointer->offset = 0;
|
||||
pointer->range = 0;
|
||||
pointer->buffer = VK_NULL_HANDLE;
|
||||
@ -680,7 +683,22 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render mode's command buffer is in flight, queue a rebuild
|
||||
// ext::vulkan::rebuild = true;
|
||||
// renderMode.synchronize();
|
||||
renderMode.rebuild = true;
|
||||
/*
|
||||
std::cout << this << ": " << renderMode.getName() << ": " << renderMode.getType() << " " << descriptorSet << std::endl;
|
||||
for ( auto& descriptor : writeDescriptorSets ) {
|
||||
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
|
||||
if ( descriptor.pImageInfo ) {
|
||||
std::cout << "[" << i << "]: " << descriptor.pImageInfo[i].imageView << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
vkUpdateDescriptorSets(
|
||||
*device,
|
||||
writeDescriptorSets.size(),
|
||||
@ -780,12 +798,15 @@ ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( Descriptor& descriptor
|
||||
return pipelines[descriptor.hash()];
|
||||
}
|
||||
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer ) {
|
||||
return this->record( commandBuffer, descriptor );
|
||||
}
|
||||
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, Descriptor& descriptor ) {
|
||||
if ( !this->hasPipeline( descriptor ) ) {
|
||||
std::cout << this << ": has no valid pipeline" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto& pipeline = this->getPipeline();
|
||||
auto& pipeline = this->getPipeline( descriptor );
|
||||
|
||||
assert( buffers.size() >= 2 );
|
||||
Buffer& vertexBuffer = buffers.at(0);
|
||||
|
@ -17,7 +17,7 @@ ext::vulkan::RenderMode::~RenderMode() {
|
||||
std::string ext::vulkan::RenderMode::getType() const {
|
||||
return "";
|
||||
}
|
||||
const std::string& ext::vulkan::RenderMode::getName() const {
|
||||
const std::string& ext::vulkan::RenderMode::getName( bool ) const {
|
||||
return this->name;
|
||||
}
|
||||
ext::vulkan::RenderTarget& ext::vulkan::RenderMode::getRenderTarget( size_t i ) {
|
||||
@ -52,13 +52,78 @@ void ext::vulkan::RenderMode::createCommandBuffers() {
|
||||
}
|
||||
|
||||
this->synchronize();
|
||||
//VK_CHECK_RESULT(vkWaitForFences(*device, fences.size(), fences.data(), VK_TRUE, UINT64_MAX));
|
||||
bindPipelines( graphics );
|
||||
createCommandBuffers( graphics );
|
||||
this->mostRecentCommandPoolId = std::this_thread::get_id();
|
||||
this->rebuild = false;
|
||||
}
|
||||
ext::vulkan::RenderMode::commands_container_t& ext::vulkan::RenderMode::getCommands() {
|
||||
return getCommands( std::this_thread::get_id() );
|
||||
}
|
||||
ext::vulkan::RenderMode::commands_container_t& ext::vulkan::RenderMode::getCommands( std::thread::id id ) {
|
||||
bool exists = this->commands.count(id) > 0;
|
||||
auto& commands = this->commands[id];
|
||||
if ( !exists ) {
|
||||
commands.resize( swapchain.buffers );
|
||||
|
||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = ext::vulkan::initializers::commandBufferAllocateInfo(
|
||||
this->getType() == "Compute" ? device->getCommandPool(Device::QueueEnum::COMPUTE) : device->getCommandPool(Device::QueueEnum::GRAPHICS),
|
||||
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
static_cast<uint32_t>(commands.size())
|
||||
);
|
||||
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(*device, &cmdBufAllocateInfo, commands.data()));
|
||||
}
|
||||
return commands;
|
||||
/*
|
||||
VkCommandPool* pool = NULL;
|
||||
switch ( queueEnum ) {
|
||||
case QueueEnum::GRAPHICS:
|
||||
index = device.queueFamilyIndices.graphics;
|
||||
if ( commandPool.graphics.count(id) > 0 ) exists = true;
|
||||
pool = &commandPool.graphics[id];
|
||||
break;
|
||||
case QueueEnum::COMPUTE:
|
||||
index = device.queueFamilyIndices.compute;
|
||||
if ( commandPool.compute.count(id) > 0 ) exists = true;
|
||||
pool = &commandPool.compute[id];
|
||||
break;
|
||||
case QueueEnum::TRANSFER:
|
||||
index = device.queueFamilyIndices.transfer;
|
||||
if ( commandPool.transfer.count(id) > 0 ) exists = true;
|
||||
pool = &commandPool.transfer[id];
|
||||
break;
|
||||
}
|
||||
if ( !exists ) {
|
||||
VkCommandPoolCreateFlags createFlags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
VkCommandPoolCreateInfo cmdPoolInfo = {};
|
||||
cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
cmdPoolInfo.queueFamilyIndex = index;
|
||||
cmdPoolInfo.flags = createFlags;
|
||||
if ( vkCreateCommandPool( this->logicalDevice, &cmdPoolInfo, nullptr, pool ) != VK_SUCCESS )
|
||||
throw std::runtime_error("failed to create command pool for graphics!");
|
||||
}
|
||||
return *pool;
|
||||
*/
|
||||
}
|
||||
void ext::vulkan::RenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
|
||||
}
|
||||
void ext::vulkan::RenderMode::bindPipelines( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
for ( auto* pointer : graphics ) {
|
||||
auto& graphic = *pointer;
|
||||
// copy descriptor
|
||||
ext::vulkan::Graphic::Descriptor descriptor = graphic.descriptor;
|
||||
// bind to this render mode
|
||||
descriptor.renderMode = this->getName();
|
||||
// ignore if pipeline exists for this render mode
|
||||
if ( graphic.hasPipeline( descriptor ) ) continue;
|
||||
graphic.initializePipeline( descriptor );
|
||||
}
|
||||
}
|
||||
|
||||
void ext::vulkan::RenderMode::render() {
|
||||
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||
// Get next image in the swap chain (back/front buffer)
|
||||
VK_CHECK_RESULT(swapchain.acquireNextImage(¤tBuffer, swapchain.presentCompleteSemaphore));
|
||||
|
||||
@ -101,6 +166,7 @@ void ext::vulkan::RenderMode::initialize( Device& device ) {
|
||||
}
|
||||
|
||||
// Create command buffers
|
||||
/*
|
||||
{
|
||||
commands.resize( swapchain.buffers );
|
||||
|
||||
@ -112,6 +178,7 @@ void ext::vulkan::RenderMode::initialize( Device& device ) {
|
||||
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, commands.data()));
|
||||
}
|
||||
*/
|
||||
// Set sync objects
|
||||
{
|
||||
// Fences (Used to check draw command buffer completion)
|
||||
@ -119,7 +186,7 @@ void ext::vulkan::RenderMode::initialize( Device& device ) {
|
||||
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
// Create in signaled state so we don't wait on first render of each command buffer
|
||||
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
fences.resize( commands.size() );
|
||||
fences.resize( swapchain.buffers );
|
||||
for ( auto& fence : fences ) {
|
||||
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
||||
}
|
||||
@ -143,12 +210,16 @@ void ext::vulkan::RenderMode::destroy() {
|
||||
this->synchronize();
|
||||
|
||||
renderTarget.destroy();
|
||||
|
||||
/*
|
||||
if ( commands.size() > 0 ) {
|
||||
vkFreeCommandBuffers( *device, this->getType() == "Compute" ? device->getCommandPool(Device::QueueEnum::COMPUTE) : device->getCommandPool(Device::QueueEnum::GRAPHICS), static_cast<uint32_t>(commands.size()), commands.data());
|
||||
}
|
||||
commands.clear();
|
||||
|
||||
*/
|
||||
for ( auto& pair : this->commands ) {
|
||||
vkFreeCommandBuffers( *device, device->getCommandPool(this->getType() == "Compute" ? Device::QueueEnum::COMPUTE : Device::QueueEnum::GRAPHICS, pair.first), static_cast<uint32_t>(pair.second.size()), pair.second.data());
|
||||
pair.second.clear();
|
||||
}
|
||||
if ( renderCompleteSemaphore != VK_NULL_HANDLE ) {
|
||||
vkDestroySemaphore( *device, renderCompleteSemaphore, nullptr);
|
||||
renderCompleteSemaphore = VK_NULL_HANDLE;
|
||||
|
@ -18,9 +18,6 @@ ext::vulkan::BaseRenderMode::~BaseRenderMode() {
|
||||
std::string ext::vulkan::BaseRenderMode::getType() const {
|
||||
return "Swapchain";
|
||||
}
|
||||
const std::string& ext::vulkan::BaseRenderMode::getName() const {
|
||||
return this->name;
|
||||
}
|
||||
void ext::vulkan::BaseRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||
if ( ext::vulkan::renderModes.size() > 1 ) return;
|
||||
|
||||
@ -47,6 +44,7 @@ void ext::vulkan::BaseRenderMode::createCommandBuffers( const std::vector<ext::v
|
||||
renderPassBeginInfo.renderArea.extent.height = height;
|
||||
renderPassBeginInfo.clearValueCount = 2;
|
||||
renderPassBeginInfo.pClearValues = clearValues;
|
||||
auto& commands = getCommands();
|
||||
for (size_t i = 0; i < commands.size(); ++i) {
|
||||
// Set target frame buffer
|
||||
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[i];
|
||||
|
@ -44,25 +44,18 @@ void ext::vulkan::ComputeRenderMode::initialize( Device& device ) {
|
||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||
|
||||
auto& shader = compute.material.shaders.front();
|
||||
/*
|
||||
|
||||
struct SpecializationConstant {
|
||||
int32_t eyes = 2;
|
||||
int32_t maxLights = 16;
|
||||
};
|
||||
auto& specializationConstants = shader.specializationConstants.get<SpecializationConstant>();
|
||||
specializationConstants.maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
|
||||
specializationConstants.eyes = ext::openvr::context ? 2 : 1;
|
||||
*/
|
||||
struct SpecializationConstant {
|
||||
uint32_t eyes = 2;
|
||||
uint32_t maxLights = 16;
|
||||
uint32_t eyes = 2;
|
||||
};
|
||||
auto* specializationConstants = (SpecializationConstant*) &shader.specializationConstants[0];
|
||||
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
|
||||
specializationConstants->eyes = ext::openvr::context ? 2 : 1;
|
||||
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
|
||||
if ( binding.descriptorCount > 1 )
|
||||
binding.descriptorCount = specializationConstants->maxLights;
|
||||
if ( binding.descriptorCount > 1 ) {
|
||||
binding.descriptorCount = specializationConstants->eyes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,6 +99,7 @@ void ext::vulkan::ComputeRenderMode::initialize( Device& device ) {
|
||||
void ext::vulkan::ComputeRenderMode::render() {
|
||||
if ( compute.buffers.empty() ) return;
|
||||
|
||||
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||
// Submit compute commands
|
||||
// Use a fence to ensure that compute command buffer has finished executing before using it again
|
||||
VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[currentBuffer], VK_TRUE, UINT64_MAX ));
|
||||
@ -143,13 +137,10 @@ void ext::vulkan::ComputeRenderMode::tick() {
|
||||
texture = computeTexture;
|
||||
texture.device = NULL;
|
||||
}
|
||||
auto& pipeline = blitter.getPipeline();
|
||||
pipeline.update( blitter );
|
||||
blitter.getPipeline().update( blitter );
|
||||
}
|
||||
// if ( compute.initialized ) {
|
||||
if ( !compute.buffers.empty() ) {
|
||||
auto& pipeline = compute.getPipeline();
|
||||
pipeline.update( compute );
|
||||
compute.getPipeline().update( compute );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,14 +203,16 @@ void ext::vulkan::ComputeRenderMode::createCommandBuffers( ) {
|
||||
float width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||
float height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||
|
||||
if ( compute.buffers.empty() ) return;
|
||||
|
||||
VkCommandBufferBeginInfo cmdBufInfo = ext::vulkan::initializers::commandBufferBeginInfo();
|
||||
auto& pipeline = compute.getPipeline();
|
||||
auto& commands = getCommands();
|
||||
if ( compute.buffers.empty() ) return;
|
||||
for (size_t i = 0; i < commands.size(); ++i) {
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
||||
pipeline.record(compute, commands[i]);
|
||||
vkCmdDispatch(commands[i], width / dispatchSize.x, height / dispatchSize.y, 1);
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(commands[i]));
|
||||
}
|
||||
|
||||
this->mostRecentCommandPoolId = std::this_thread::get_id();
|
||||
}
|
@ -160,9 +160,7 @@ void ext::vulkan::DeferredRenderMode::tick() {
|
||||
renderTarget.initialize( *renderTarget.device );
|
||||
// update blitter descriptor set
|
||||
if ( blitter.initialized ) {
|
||||
auto& pipeline = blitter.getPipeline();
|
||||
pipeline.update( blitter );
|
||||
ext::vulkan::rebuild = true;
|
||||
blitter.getPipeline().update( blitter );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,6 +191,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
|
||||
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes(std::vector<std::string>{"RenderTarget", "Compute"}, false);
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||
auto& commands = getCommands();
|
||||
for (size_t i = 0; i < commands.size(); ++i) {
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
||||
// Fill GBuffer
|
||||
|
@ -8,6 +8,9 @@
|
||||
std::string ext::vulkan::RenderTargetRenderMode::getType() const {
|
||||
return "RenderTarget";
|
||||
}
|
||||
const std::string& ext::vulkan::RenderTargetRenderMode::getName( bool wantsTarget ) const {
|
||||
return wantsTarget ? this->target : this->name;
|
||||
}
|
||||
|
||||
void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||
ext::vulkan::RenderMode::initialize( device );
|
||||
@ -125,6 +128,7 @@ void ext::vulkan::RenderTargetRenderMode::destroy() {
|
||||
blitter.destroy();
|
||||
}
|
||||
void ext::vulkan::RenderTargetRenderMode::render() {
|
||||
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||
// Submit commands
|
||||
// Use a fence to ensure that command buffer has finished executing before using it again
|
||||
VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[currentBuffer], VK_TRUE, UINT64_MAX ));
|
||||
@ -219,7 +223,7 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vecto
|
||||
VkCommandBufferBeginInfo cmdBufInfo = {};
|
||||
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
cmdBufInfo.pNext = nullptr;
|
||||
|
||||
auto& commands = getCommands();
|
||||
for (size_t i = 0; i < commands.size(); ++i) {
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
||||
{
|
||||
@ -265,7 +269,9 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vecto
|
||||
vkCmdSetScissor(commands[i], 0, 1, &scissor);
|
||||
for ( auto graphic : graphics ) {
|
||||
if ( graphic->descriptor.renderMode != this->target ) continue;
|
||||
graphic->record(commands[i] );
|
||||
ext::vulkan::Graphic::Descriptor descriptor = graphic->descriptor;
|
||||
descriptor.renderMode = this->name;
|
||||
graphic->record(commands[i], descriptor );
|
||||
}
|
||||
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdEndRenderPass(commands[i]);
|
||||
|
@ -196,7 +196,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
||||
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||
|
||||
auto& commands = getCommands();
|
||||
for (size_t i = 0; i < commands.size(); ++i) {
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
||||
struct EYES {
|
||||
|
@ -443,7 +443,7 @@ void ext::vulkan::Texture2D::asRenderTarget( Device& device, uint32_t width, uin
|
||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
imageCreateInfo.format = format;
|
||||
imageCreateInfo.extent = { width, height, 1 };
|
||||
imageCreateInfo.mipLevels = 1;
|
||||
imageCreateInfo.mipLevels = this->mips = 1;
|
||||
imageCreateInfo.arrayLayers = 1;
|
||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
#include <atomic>
|
||||
|
||||
uint32_t ext::vulkan::width = 1280;
|
||||
uint32_t ext::vulkan::height = 720;
|
||||
@ -302,11 +303,23 @@ void ext::vulkan::tick() {
|
||||
}
|
||||
renderMode->tick();
|
||||
}
|
||||
|
||||
std::vector<std::function<int()>> jobs;
|
||||
for ( auto& renderMode : renderModes ) {
|
||||
if ( !renderMode ) continue;
|
||||
if ( ext::vulkan::rebuild )
|
||||
if ( ext::vulkan::rebuild || renderMode->rebuild ) {
|
||||
jobs.emplace_back([&]{
|
||||
renderMode->createCommandBuffers();
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
if ( !jobs.empty() ) {
|
||||
// std::cout << "Batching " << jobs.size() << " command buffer jobs" << std::endl;
|
||||
uf::thread::batchWorkers( jobs );
|
||||
// std::cout << "Done" << std::endl;
|
||||
}
|
||||
|
||||
ext::vulkan::rebuild = false;
|
||||
ext::vulkan::resized = false;
|
||||
ext::vulkan::mutex.unlock();
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#if defined(UF_USE_OPENAL)
|
||||
#include <uf/ext/vorbis/vorbis.h>
|
||||
#include <uf/ext/oal/oal.h>
|
||||
#endif
|
||||
/*
|
||||
UF_API uf::Audio::Audio( const std::string& filename ) : m_filename(filename) {
|
||||
@ -20,11 +21,19 @@ UF_API uf::Audio::Audio( const uf::Audio& copy ) :
|
||||
{
|
||||
}
|
||||
*/
|
||||
uf::Audio::~Audio() {
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
bool UF_API uf::Audio::initialized() {
|
||||
if ( !this->m_source.getIndex() ) return false;
|
||||
if ( !this->m_buffer.getIndex() ) return false;
|
||||
return true;
|
||||
}
|
||||
void UF_API uf::Audio::destroy() {
|
||||
this->m_source.destroy();
|
||||
this->m_buffer.destroy();
|
||||
}
|
||||
bool UF_API uf::Audio::playing() {
|
||||
if ( !this->initialized() ) return false;
|
||||
if ( !this->m_source.playing() ) return false;
|
||||
@ -42,22 +51,24 @@ void UF_API uf::Audio::load( const std::string& filename ) { if ( filename != ""
|
||||
frequency = vorbis.getFrequency();
|
||||
this->m_duration = vorbis.getDuration();
|
||||
|
||||
this->m_buffer.generate();
|
||||
this->m_source.generate();
|
||||
this->m_buffer.generate(); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
this->m_source.generate(); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
|
||||
this->m_buffer.buffer( format, &buffer[0], buffer.size(), frequency );
|
||||
this->m_source.source( "BUFFER", std::vector<ALint>{ this->m_buffer.getIndex() } );
|
||||
this->m_buffer.buffer( format, &buffer[0], buffer.size(), frequency ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
this->m_source.source( "BUFFER", std::vector<ALint>{ this->m_buffer.getIndex() } ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
|
||||
this->m_source.source( "PITCH", std::vector<ALfloat>{ 1 } );
|
||||
this->m_source.source( "GAIN", std::vector<ALfloat>{ 1 } );
|
||||
this->m_source.source( "LOOPING", std::vector<ALint>{ AL_FALSE } );
|
||||
this->m_source.source( "PITCH", std::vector<ALfloat>{ 1 } ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
this->m_source.source( "GAIN", std::vector<ALfloat>{ 1 } ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
this->m_source.source( "LOOPING", std::vector<ALint>{ AL_FALSE } ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
void UF_API uf::Audio::play() {
|
||||
if ( !this->initialized() ) return;
|
||||
this->m_source.play();
|
||||
}
|
||||
void UF_API uf::Audio::stop() {
|
||||
if ( !this->initialized() ) return;
|
||||
this->m_source.stop();
|
||||
}
|
||||
const std::string& UF_API uf::Audio::getFilename() const {
|
||||
@ -66,64 +77,64 @@ const std::string& UF_API uf::Audio::getFilename() const {
|
||||
float uf::Audio::getDuration() const {
|
||||
return this->m_duration;
|
||||
}
|
||||
#include <uf/ext/oal/oal.h>
|
||||
|
||||
ALfloat UF_API uf::Audio::getTime() {
|
||||
if ( this->playing() ) return 0;
|
||||
if ( !this->playing() ) return 0;
|
||||
ALfloat pos;
|
||||
alGetSourcef(this->m_source.getIndex(), AL_SEC_OFFSET, &pos ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
return pos;
|
||||
}
|
||||
void UF_API uf::Audio::setTime( ALfloat pos ) {
|
||||
if ( this->playing() ) return;
|
||||
if ( !this->initialized() ) return;
|
||||
this->m_source.source("SEC_OFFSET", std::vector<ALfloat>{ pos } );
|
||||
}
|
||||
|
||||
ALfloat UF_API uf::Audio::getPitch() {
|
||||
if ( this->playing() ) return 0;
|
||||
if ( !this->initialized() ) return 0;
|
||||
ALfloat pitch;
|
||||
alGetSourcef(this->m_source.getIndex(), AL_PITCH, &pitch ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
return pitch;
|
||||
}
|
||||
void UF_API uf::Audio::setPitch( ALfloat pitch ) {
|
||||
if ( this->playing() ) return;
|
||||
if ( !this->initialized() ) return;
|
||||
this->m_source.source("PITCH", std::vector<ALfloat>{ pitch } );
|
||||
}
|
||||
|
||||
ALfloat UF_API uf::Audio::getGain() {
|
||||
if ( this->playing() ) return 0;
|
||||
if ( !this->initialized() ) return 0;
|
||||
ALfloat gain;
|
||||
alGetSourcef(this->m_source.getIndex(), AL_GAIN, &gain ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
return gain;
|
||||
}
|
||||
void UF_API uf::Audio::setGain( ALfloat gain ) {
|
||||
if ( this->playing() ) return;
|
||||
if ( !this->initialized() ) return;
|
||||
this->m_source.source("GAIN", std::vector<ALfloat>{ gain } );
|
||||
}
|
||||
|
||||
ALfloat UF_API uf::Audio::getRolloffFactor() {
|
||||
if ( this->playing() ) return 0;
|
||||
if ( !this->initialized() ) return 0;
|
||||
ALfloat rolloffFactor;
|
||||
alGetSourcef(this->m_source.getIndex(), AL_ROLLOFF_FACTOR, &rolloffFactor ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
return rolloffFactor;
|
||||
}
|
||||
void UF_API uf::Audio::setRolloffFactor( ALfloat rolloffFactor ) {
|
||||
if ( this->playing() ) return;
|
||||
if ( !this->initialized() ) return;
|
||||
this->m_source.source("ROLLOFF_FACTOR", std::vector<ALfloat>{ rolloffFactor } );
|
||||
}
|
||||
|
||||
ALfloat UF_API uf::Audio::getMaxDistance() {
|
||||
if ( this->playing() ) return 0;
|
||||
if ( !this->initialized() ) return 0;
|
||||
ALfloat maxDistance;
|
||||
alGetSourcef(this->m_source.getIndex(), AL_MAX_DISTANCE, &maxDistance ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||
return maxDistance;
|
||||
}
|
||||
void UF_API uf::Audio::setMaxDistance( ALfloat maxDistance ) {
|
||||
if ( this->playing() ) return;
|
||||
if ( !this->initialized() ) return;
|
||||
this->m_source.source("MAX_DISTANCE", std::vector<ALfloat>{ maxDistance } );
|
||||
}
|
||||
|
||||
void UF_API uf::Audio::setPosition( const pod::Vector3& position ) {
|
||||
if ( !this->initialized() ) return;
|
||||
this->m_source.source("POSITION", std::vector<ALfloat>{position.x, position.y, position.z} );
|
||||
}
|
||||
void UF_API uf::Audio::setOrientation( const pod::Quaternion<>& orientation ) {
|
||||
@ -164,9 +175,9 @@ const uf::SoundEmitter::container_t& UF_API uf::SoundEmitter::get() const {
|
||||
}
|
||||
|
||||
void UF_API uf::SoundEmitter::cleanup( bool purge ) {
|
||||
/*
|
||||
for ( uf::Audio& k : this->m_container ) {
|
||||
if ( !k.playing() ) this->m_container.erase(k);
|
||||
for ( auto& pair : this->m_container ) {
|
||||
if ( !pair.second.playing() ) {
|
||||
this->m_container.erase(pair.first);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
@ -7,6 +7,19 @@
|
||||
#include <fstream>
|
||||
#include <uf/utils/io/iostream.h>
|
||||
|
||||
#ifdef WINDOWS
|
||||
#include <direct.h>
|
||||
#define GetCurrentDir _getcwd
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define GetCurrentDir getcwd
|
||||
#endif
|
||||
|
||||
std::string UF_API uf::io::absolute( const std::string& path ) {
|
||||
char buff[FILENAME_MAX];
|
||||
GetCurrentDir( buff, FILENAME_MAX );
|
||||
return std::string(buff) + path;
|
||||
}
|
||||
std::string UF_API uf::io::filename( const std::string& str ) {
|
||||
return str.substr( str.find_last_of('/') + 1 );
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ pod::Thread& UF_API uf::thread::fetchWorker( const std::string& name ) {
|
||||
std::string thread = name;
|
||||
if ( current > 0 ) thread += " " + std::to_string(current);
|
||||
bool exists = uf::thread::has(thread);
|
||||
auto& pod = exists ? uf::thread::get(thread) : uf::thread::create( thread, true, false );
|
||||
auto& pod = exists ? uf::thread::get(thread) : uf::thread::create( thread, true );
|
||||
if ( !exists ) {
|
||||
/*
|
||||
pod.affinity = (current + 1) % threads;
|
||||
@ -66,7 +66,17 @@ pod::Thread& UF_API uf::thread::fetchWorker( const std::string& name ) {
|
||||
}
|
||||
return pod;
|
||||
}
|
||||
|
||||
void UF_API uf::thread::batchWorkers( const std::vector<pod::Thread::function_t>& functions, bool wait, const std::string& name ) {
|
||||
std::vector<pod::Thread*> workers;
|
||||
for ( auto& function : functions ) {
|
||||
auto& worker = uf::thread::fetchWorker( name );
|
||||
workers.emplace_back(&worker);
|
||||
uf::thread::add( worker, function, true );
|
||||
}
|
||||
if ( wait )
|
||||
for ( auto& worker : workers )
|
||||
uf::thread::wait( *worker );
|
||||
}
|
||||
/*
|
||||
void UF_API uf::thread::tick( pod::Thread& thread, const std::function<void()>& callback ) {
|
||||
while ( thread.running ) {
|
||||
@ -82,6 +92,7 @@ void UF_API uf::thread::add( pod::Thread& thread, const pod::Thread::function_t&
|
||||
if ( thread.mutex != NULL ) thread.mutex->unlock();
|
||||
}
|
||||
void UF_API uf::thread::process( pod::Thread& thread ) { if ( !uf::thread::has(uf::thread::uid(thread)) ) { if ( UF_THREAD_ANNOUNCE ) uf::iostream << "Bad Thread: " << thread.uid << " " << thread.name << "\n"; return; } //ops
|
||||
/*
|
||||
std::function<int()> temps = [&] {
|
||||
int i = 0;
|
||||
while ( !thread.temps.empty() ) {
|
||||
@ -100,17 +111,40 @@ void UF_API uf::thread::process( pod::Thread& thread ) { if ( !uf::thread::has(u
|
||||
}
|
||||
return i;
|
||||
};
|
||||
|
||||
if ( thread.mutex != NULL ) thread.mutex->lock();
|
||||
temps();
|
||||
consts();
|
||||
if ( thread.mutex != NULL ) thread.mutex->unlock();
|
||||
*/
|
||||
size_t temps = 0;
|
||||
size_t consts = 0;
|
||||
while ( !thread.temps.empty() ) {
|
||||
auto& function = thread.temps.front();
|
||||
if ( function ) function();
|
||||
thread.temps.pop();
|
||||
++temps;
|
||||
}
|
||||
for ( auto function : thread.consts ) {
|
||||
function();
|
||||
++consts;
|
||||
}
|
||||
thread.condition.notify_one();
|
||||
}
|
||||
void UF_API uf::thread::wait( pod::Thread& thread ) {
|
||||
if ( thread.mutex != NULL ) {
|
||||
std::unique_lock<std::mutex> lock(*thread.mutex);
|
||||
thread.condition.wait(lock, [&]{return thread.temps.empty();});
|
||||
return;
|
||||
}
|
||||
while ( !thread.temps.empty() );
|
||||
/*
|
||||
if ( thread.mutex != NULL ) {
|
||||
thread.mutex->lock();
|
||||
thread.mutex->unlock();
|
||||
return;
|
||||
}
|
||||
while ( !thread.temps.empty() );
|
||||
*/
|
||||
}
|
||||
|
||||
const std::string& UF_API uf::thread::name( const pod::Thread& thread ) {
|
||||
|
@ -99,7 +99,7 @@ void ext::LightBehavior::tick( uf::Object& self ) {
|
||||
float delta = metadata["light"]["fade"]["timer"].asFloat();
|
||||
delta = std::clamp( delta, 0.f, 1.f );
|
||||
if ( metadata["light"]["fade"]["power"].isNumeric() ) {
|
||||
metadata["light"]["power"] = std::lerp( metadata["light"]["backup"]["power"].asFloat(), metadata["light"]["fade"]["power"].asFloat(), delta );
|
||||
metadata["light"]["power"] = uf::math::lerp( metadata["light"]["backup"]["power"].asFloat(), metadata["light"]["fade"]["power"].asFloat(), delta );
|
||||
}
|
||||
if ( metadata["light"]["fade"]["color"].isArray() ) {
|
||||
pod::Vector3f fadeColor; {
|
||||
|
@ -271,6 +271,29 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
uint32_t maxLights = 32;
|
||||
} specializationConstants;
|
||||
|
||||
std::vector<uf::Entity*> entities;
|
||||
{
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity || entity->getName() != "Light" ) return;
|
||||
entities.push_back(entity);
|
||||
};
|
||||
for ( uf::Scene* scene : uf::renderer::scenes ) { if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
}
|
||||
{
|
||||
const pod::Vector3& position = controller.getComponent<pod::Transform<>>().position;
|
||||
std::sort( entities.begin(), entities.end(), [&]( const uf::Entity* l, const uf::Entity* r ){
|
||||
if ( !l ) return false; if ( !r ) return true;
|
||||
if ( !l->hasComponent<pod::Transform<>>() ) return false; if ( !r->hasComponent<pod::Transform<>>() ) return true;
|
||||
return uf::vector::magnitude( uf::vector::subtract( l->getComponent<pod::Transform<>>().position, position ) ) < uf::vector::magnitude( uf::vector::subtract( r->getComponent<pod::Transform<>>().position, position ) );
|
||||
} );
|
||||
}
|
||||
|
||||
{
|
||||
uf::Serializer& metadata = controller.getComponent<uf::Serializer>();
|
||||
if ( metadata["light"]["should"].asBool() ) entities.push_back(&controller);
|
||||
}
|
||||
}
|
||||
for ( size_t _ = 0; _ < blitters.size(); ++_ ) {
|
||||
auto& blitter = *blitters[_];
|
||||
|
||||
@ -284,7 +307,6 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
buffer = (uint8_t*) (void*) userdata;
|
||||
len = userdata.data().len;
|
||||
shader = &_;
|
||||
// specializationConstants = _.specializationConstants.get<SpecializationConstant>();
|
||||
specializationConstants = *((SpecializationConstant*) &_.specializationConstants[0]);
|
||||
}
|
||||
|
||||
@ -323,27 +345,6 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<uf::Entity*> entities;
|
||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||
if ( !entity || entity->getName() != "Light" ) return;
|
||||
entities.push_back(entity);
|
||||
};
|
||||
for ( uf::Scene* scene : uf::renderer::scenes ) { if ( !scene ) continue;
|
||||
scene->process(filter);
|
||||
}
|
||||
{
|
||||
const pod::Vector3& position = controller.getComponent<pod::Transform<>>().position;
|
||||
std::sort( entities.begin(), entities.end(), [&]( const uf::Entity* l, const uf::Entity* r ){
|
||||
if ( !l ) return false; if ( !r ) return true;
|
||||
if ( !l->hasComponent<pod::Transform<>>() ) return false; if ( !r->hasComponent<pod::Transform<>>() ) return true;
|
||||
return uf::vector::magnitude( uf::vector::subtract( l->getComponent<pod::Transform<>>().position, position ) ) < uf::vector::magnitude( uf::vector::subtract( r->getComponent<pod::Transform<>>().position, position ) );
|
||||
} );
|
||||
}
|
||||
|
||||
{
|
||||
uf::Serializer& metadata = controller.getComponent<uf::Serializer>();
|
||||
if ( metadata["light"]["should"].asBool() ) entities.push_back(&controller);
|
||||
}
|
||||
UniformDescriptor::Light* lights = (UniformDescriptor::Light*) &buffer[sizeof(UniformDescriptor) - sizeof(UniformDescriptor::Light)];
|
||||
for ( size_t i = 0; i < specializationConstants.maxLights; ++i ) {
|
||||
UniformDescriptor::Light& light = lights[i];
|
||||
@ -353,6 +354,10 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
light.depthBias = 0;
|
||||
}
|
||||
|
||||
std::vector<VkImage> previousTextures;
|
||||
for ( auto& texture : blitter.material.textures ) {
|
||||
previousTextures.emplace_back(texture.image);
|
||||
}
|
||||
blitter.material.textures.clear();
|
||||
|
||||
for ( size_t i = 0; i < specializationConstants.maxLights && i < entities.size(); ++i ) {
|
||||
@ -390,7 +395,6 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
uint8_t i = 0;
|
||||
for ( auto& attachment : renderTarget.attachments ) {
|
||||
if ( !(attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
// if ( (attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
||||
if ( (attachment.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) ) continue;
|
||||
auto& texture = blitter.material.textures.emplace_back();
|
||||
texture.aliasAttachment(attachment);
|
||||
@ -399,9 +403,21 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
size_t i = 0;
|
||||
bool shouldUpdate = blitter.material.textures.size() != previousTextures.size();
|
||||
while ( !shouldUpdate && i < blitter.material.textures.size() ) {
|
||||
auto& texture = blitter.material.textures[i];
|
||||
auto& previousTexture = previousTextures[i];
|
||||
if ( texture.image != previousTexture ) shouldUpdate = true;
|
||||
++i;
|
||||
}
|
||||
// check if we actually do need to update our pipeline, to avoid the command buffer rebuild cost
|
||||
if ( shouldUpdate ) {
|
||||
blitter.getPipeline().update( blitter );
|
||||
}
|
||||
}
|
||||
shader->updateBuffer( (void*) buffer, len, 0, false );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,528 +0,0 @@
|
||||
#include "behavior.h"
|
||||
|
||||
#include <uf/utils/hook/hook.h>
|
||||
#include <uf/utils/time/time.h>
|
||||
#include <uf/utils/serialize/serializer.h>
|
||||
#include <uf/utils/userdata/userdata.h>
|
||||
#include <uf/utils/graphic/mesh.h>
|
||||
#include <uf/utils/graphic/graphic.h>
|
||||
#include <uf/utils/window/window.h>
|
||||
#include <uf/utils/camera/camera.h>
|
||||
|
||||
#include <uf/utils/renderer/renderer.h>
|
||||
|
||||
#include <uf/utils/image/image.h>
|
||||
|
||||
#include <uf/engine/asset/asset.h>
|
||||
#include "../../scenes/worldscape//battle.h"
|
||||
#include "../../scenes/worldscape//.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#define PRINT_VECTOR2(v)\
|
||||
std::cout << #v << ": " << v.x << ", " << v.y << std::endl;
|
||||
|
||||
namespace {
|
||||
pod::Vector3f AXIS_OF_ROTATION = { 0, 0, 1 };
|
||||
struct Bone {
|
||||
std::string name = "";
|
||||
std::string parent = "";
|
||||
float length = 0;
|
||||
|
||||
pod::Vector2f position = { 0, 0 };
|
||||
float rotation = 0;
|
||||
};
|
||||
struct AtlasPiece {
|
||||
std::string name = "";
|
||||
struct {
|
||||
pod::Vector2f min = { 0, 0 };
|
||||
pod::Vector2f max = { 0, 0 };
|
||||
} uv;
|
||||
struct {
|
||||
pod::Vector2f topLeft = {-0.5f, 0.5f};
|
||||
pod::Vector2f topRight = { 0.5f, 0.5f};
|
||||
pod::Vector2f bottomLeft = {-0.5f, -0.5f};
|
||||
pod::Vector2f bottomRight = { 0.5f, -0.5f};
|
||||
} position;
|
||||
pod::Vector2f scale = { 1, 1 };
|
||||
pod::Vector2f size = { 0, 0 };
|
||||
pod::Quaternion<> orientation = { 0, 0, 0, 1 };
|
||||
float rotation = 0;
|
||||
};
|
||||
struct {
|
||||
uf::Serializer animation;
|
||||
uf::Serializer atlas;
|
||||
uf::Serializer overrides;
|
||||
} manifests;
|
||||
struct {
|
||||
std::unordered_map<std::string, Bone> skeleton;
|
||||
std::unordered_map<std::string, AtlasPiece> attachments;
|
||||
std::unordered_map<std::string, uf::Serializer> skins;
|
||||
std::unordered_map<std::string, uf::Serializer> slots;
|
||||
} maps;
|
||||
|
||||
float getRotation( const std::string& boneName, bool flatten = false, float start = 0 ) {
|
||||
if ( manifests.overrides[boneName]["rotation"].isNumeric() ) {
|
||||
return manifests.overrides[boneName]["rotation"].asFloat();
|
||||
}
|
||||
float rotation = start;
|
||||
if ( maps.skeleton.count(boneName) < 0 ) {
|
||||
std::cout << "Bone not in skeleton: " << boneName << std::endl;
|
||||
return rotation;
|
||||
}
|
||||
Bone* bone = &maps.skeleton[boneName];
|
||||
do {
|
||||
rotation += bone->rotation;
|
||||
if ( bone->parent == "" ) break;
|
||||
bone = &maps.skeleton[bone->parent];
|
||||
} while ( flatten );
|
||||
return rotation;
|
||||
}
|
||||
pod::Quaternion<> getOrientation( const std::string& boneName, bool flatten = false, float start = 0 ) {
|
||||
float rotation = getRotation( boneName, flatten, start );
|
||||
return uf::quaternion::axisAngle( AXIS_OF_ROTATION, rotation * 3.14159f / 180.0f );
|
||||
}
|
||||
pod::Vector3f getPosition( const std::string& boneName, bool flatten = false ) {
|
||||
if ( manifests.overrides[boneName]["position"].isArray() ) {
|
||||
return pod::Vector3f{
|
||||
manifests.overrides[boneName]["position"][0].asFloat(),
|
||||
manifests.overrides[boneName]["position"][1].asFloat(),
|
||||
0,
|
||||
};
|
||||
}
|
||||
pod::Vector3f position = { 0, 0, 0 };
|
||||
if ( maps.skeleton.count(boneName) < 0 ) {
|
||||
std::cout << "Bone not in skeleton: " << boneName << std::endl;
|
||||
return position;
|
||||
}
|
||||
Bone* bone = &maps.skeleton[boneName];
|
||||
std::vector<pod::Vector2f> positions;
|
||||
do {
|
||||
if ( bone->parent == "" ) break;
|
||||
float rotation = getRotation( bone->parent, flatten );
|
||||
pod::Quaternion<> orientation = uf::quaternion::axisAngle( AXIS_OF_ROTATION, rotation * 3.14159f / 180.0f );
|
||||
position += uf::quaternion::rotate( orientation, pod::Vector3f{ bone->position.x, bone->position.y, 0 } );
|
||||
bone = &maps.skeleton[bone->parent];
|
||||
} while ( flatten );
|
||||
return position;
|
||||
}
|
||||
pod::Matrix4f getMatrix( const std::string& boneName, bool flatten = false, float start = 0 ) {
|
||||
pod::Matrix4f matrix = uf::matrix::identity();
|
||||
if ( start > 0.0f ) {
|
||||
matrix = matrix * uf::quaternion::matrix( uf::quaternion::axisAngle( AXIS_OF_ROTATION, start ) );
|
||||
}
|
||||
if ( maps.skeleton.count(boneName) < 0 ) {
|
||||
std::cout << "Bone not in skeleton: " << boneName << std::endl;
|
||||
return matrix;
|
||||
}
|
||||
Bone* bone = &maps.skeleton[boneName];
|
||||
do {
|
||||
pod::Matrix4f translation = uf::matrix::translate( uf::matrix::identity(), {bone->position.x, bone->position.y, 0} );
|
||||
pod::Matrix4f rotation = uf::quaternion::matrix( uf::quaternion::axisAngle( AXIS_OF_ROTATION, bone->rotation ) );
|
||||
matrix = matrix * translation * rotation;
|
||||
if ( bone->parent == "" ) break;
|
||||
bone = &maps.skeleton[bone->parent];
|
||||
} while ( flatten );
|
||||
return matrix;
|
||||
}
|
||||
uf::Serializer getSkin( const uf::Serializer& slot ) {
|
||||
uf::Serializer json;
|
||||
std::string name = slot["name"].asString();
|
||||
std::string attachment = slot["attachment"].asString();
|
||||
if ( !maps.skins["default"][name][attachment].isNull() ) json = maps.skins["default"][name][attachment];
|
||||
else if ( !maps.skins["normal"][name][attachment].isNull() ) json = maps.skins["normal"][name][attachment];
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
EXT_BEHAVIOR_REGISTER_CPP(LahSpineBehavior)
|
||||
#define this (&self)
|
||||
void ext::LahSpineBehavior::initialize( uf::Object& self ) {
|
||||
uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Serializer& masterdata = scene.getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = scene.getComponent<uf::Asset>();
|
||||
|
||||
manifests.atlas.readFromFile(metadata["system"]["root"].asString() + "atlas.json");
|
||||
manifests.animation.readFromFile(metadata["system"]["root"].asString() + "animation.json");
|
||||
|
||||
this->addHook( "graphics:Assign.%UID%", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
std::string filename = json["filename"].asString();
|
||||
metadata["system"]["control"] = false;
|
||||
|
||||
if ( uf::io::extension(filename) != "png" ) return "false";
|
||||
|
||||
uf::Scene& scene = this->getRootParent<uf::Scene>();
|
||||
uf::Asset& assetLoader = scene.getComponent<uf::Asset>();
|
||||
const uf::Image* imagePointer = NULL;
|
||||
try { imagePointer = &assetLoader.get<uf::Image>(filename); } catch ( ... ) {}
|
||||
if ( !imagePointer ) return "false";
|
||||
|
||||
uf::Image image = *imagePointer;
|
||||
// test overrides
|
||||
{
|
||||
manifests.overrides = metadata["atlas"]["overrides"];
|
||||
}
|
||||
// assemble skeleton
|
||||
{
|
||||
auto& manifest = manifests.animation;
|
||||
for ( int i = 0; i < manifest["bones"].size(); ++i ) {
|
||||
auto& entry = manifest["bones"][i];
|
||||
std::string name = entry["name"].asString();
|
||||
|
||||
auto& bone = maps.skeleton[name];
|
||||
bone.name = name;
|
||||
if ( entry["parent"].isString() ) bone.parent = entry["parent"].asString();
|
||||
if ( entry["x"].isNumeric() ) bone.position.x = entry["x"].asFloat();
|
||||
if ( entry["y"].isNumeric() ) bone.position.y = entry["y"].asFloat();
|
||||
if ( entry["length"].isNumeric() ) bone.length = entry["length"].asFloat();
|
||||
if ( entry["rotation"].isNumeric() ) bone.rotation = entry["rotation"].asFloat(); // * 3.14159f / 180.0f;
|
||||
}
|
||||
}
|
||||
// create sprite attachments
|
||||
{
|
||||
auto& manifest = manifests.animation;
|
||||
for ( int i = 0; i < manifest["skins"].size(); ++i ) {
|
||||
std::string skinName = manifest["skins"][i]["name"].asString();
|
||||
if ( skinName == "damage" ) continue;
|
||||
maps.skins[skinName] = manifest["skins"][i]["attachments"];
|
||||
}
|
||||
}
|
||||
// register slots
|
||||
{
|
||||
auto& manifest = manifests.animation;
|
||||
for ( int i = 0; i < manifest["slots"].size(); ++i ) {
|
||||
std::string slotName = manifest["slots"][i]["name"].asString();
|
||||
maps.slots[slotName] = manifest["slots"][i];
|
||||
}
|
||||
}
|
||||
// parse atlas
|
||||
{
|
||||
auto& manifest = manifests.atlas;
|
||||
for ( auto it = manifest["pieces"].begin() ; it != manifest["pieces"].end() ; ++it ) {
|
||||
std::string name = it.key().asString();
|
||||
pod::Vector2f sheetSize = { manifest["size"][0].asFloat(), manifest["size"][1].asFloat() };
|
||||
pod::Vector2f xy = { manifest["pieces"][name]["xy"][0].asFloat(), manifest["pieces"][name]["xy"][1].asFloat() };
|
||||
pod::Vector2f size = { manifest["pieces"][name]["size"][0].asFloat(), manifest["pieces"][name]["size"][1].asFloat() };
|
||||
float rotation = 0.0f;
|
||||
auto& piece = maps.attachments[name];
|
||||
piece.size = size;
|
||||
if ( manifest["pieces"][name]["rotate"].isNumeric() ) {
|
||||
auto& rotation = piece.rotation;
|
||||
auto& orientation = piece.orientation;
|
||||
|
||||
rotation = manifest["pieces"][name]["rotate"].asFloat(); // * 3.14159f / 180.0f;
|
||||
orientation = uf::quaternion::axisAngle( AXIS_OF_ROTATION, rotation * 3.14159f / 180.0f );
|
||||
|
||||
pod::Vector3f rotated;
|
||||
{
|
||||
rotated = uf::quaternion::rotate( orientation, pod::Vector3f{ size.x, size.y, 0 } );
|
||||
size.x = fabs(rotated.x);
|
||||
size.y = fabs(rotated.y);
|
||||
}
|
||||
orientation = uf::quaternion::axisAngle( AXIS_OF_ROTATION, (rotation + 90) * 3.14159f / 180.0f );
|
||||
{
|
||||
rotated = uf::quaternion::rotate( orientation, pod::Vector3f{ size.x, size.y, 0 } );
|
||||
piece.size.x = fabs(rotated.x);
|
||||
piece.size.y = fabs(rotated.y);
|
||||
}
|
||||
{
|
||||
rotated = uf::quaternion::rotate( orientation, pod::Vector3f{ piece.position.topLeft.x, piece.position.topLeft.y, 0 } );
|
||||
piece.position.topLeft.x = rotated.x;
|
||||
piece.position.topLeft.y = rotated.y;
|
||||
}
|
||||
{
|
||||
rotated = uf::quaternion::rotate( orientation, pod::Vector3f{ piece.position.topRight.x, piece.position.topRight.y, 0 } );
|
||||
piece.position.topRight.x = rotated.x;
|
||||
piece.position.topRight.y = rotated.y;
|
||||
}
|
||||
{
|
||||
rotated = uf::quaternion::rotate( orientation, pod::Vector3f{ piece.position.bottomLeft.x, piece.position.bottomLeft.y, 0 } );
|
||||
piece.position.bottomLeft.x = rotated.x;
|
||||
piece.position.bottomLeft.y = rotated.y;
|
||||
}
|
||||
{
|
||||
rotated = uf::quaternion::rotate( orientation, pod::Vector3f{ piece.position.bottomRight.x, piece.position.bottomRight.y, 0 } );
|
||||
piece.position.bottomRight.x = rotated.x;
|
||||
piece.position.bottomRight.y = rotated.y;
|
||||
}
|
||||
}
|
||||
|
||||
piece.name = name;
|
||||
piece.uv.min = ( xy ) / sheetSize;
|
||||
piece.uv.max = ( xy + size ) / sheetSize;
|
||||
piece.scale = size / sheetSize;
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<std::string> whitelist = {};
|
||||
for ( int i = 0; i < metadata["atlas"]["whitelist"].size(); ++i ) {
|
||||
whitelist.emplace_back(metadata["atlas"]["whitelist"][i].asString());
|
||||
}
|
||||
auto& manifest = manifests.atlas;
|
||||
for ( auto it = manifest["pieces"].begin() ; it != manifest["pieces"].end() ; ++it ) {
|
||||
std::string name = it.key().asString();
|
||||
if ( !whitelist.empty() && std::find( whitelist.begin(), whitelist.end(), name ) == whitelist.end() ) continue;
|
||||
|
||||
auto& child = uf::instantiator::instantiate<uf::Object>();
|
||||
uf::instantiator::bind( "LahSpinePieceBehavior", child );
|
||||
this->addChild(child);
|
||||
child.initialize();
|
||||
|
||||
uf::Serializer payload;
|
||||
payload["attachment"]["name"] = name;
|
||||
payload["attachment"]["useMatrix"] = metadata["atlas"]["useMatrix"];
|
||||
payload["filename"] = json["filename"];
|
||||
child.queueHook("graphics:Assign.%UID%", payload);
|
||||
|
||||
metadata["attachments"][name] = child.getUid();
|
||||
}
|
||||
}
|
||||
|
||||
return "true";
|
||||
});
|
||||
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
|
||||
this->queueHook("graphics:Assign.%UID%", event, 0.0f);
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
void ext::LahSpineBehavior::tick( uf::Object& self ) {}
|
||||
void ext::LahSpineBehavior::render( uf::Object& self ){
|
||||
}
|
||||
void ext::LahSpineBehavior::destroy( uf::Object& self ){}
|
||||
#undef this
|
||||
|
||||
EXT_BEHAVIOR_REGISTER_CPP(LahSpinePieceBehavior)
|
||||
#define this (&self)
|
||||
void ext::LahSpinePieceBehavior::initialize( uf::Object& self ) {
|
||||
uf::Scene& scene = uf::scene::getCurrentScene();
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
uf::Serializer& masterdata = scene.getComponent<uf::Serializer>();
|
||||
uf::Asset& assetLoader = scene.getComponent<uf::Asset>();
|
||||
|
||||
this->addHook( "graphics:Assign.%UID%", [&](const std::string& event)->std::string{
|
||||
uf::Serializer json = event;
|
||||
std::string filename = json["filename"].asString();
|
||||
metadata["system"]["control"] = false;
|
||||
|
||||
if ( uf::io::extension(filename) != "png" ) return "false";
|
||||
|
||||
uf::Scene& scene = this->getRootParent<uf::Scene>();
|
||||
uf::Asset& assetLoader = scene.getComponent<uf::Asset>();
|
||||
const uf::Image* imagePointer = NULL;
|
||||
try { imagePointer = &assetLoader.get<uf::Image>(filename); } catch ( ... ) {}
|
||||
if ( !imagePointer ) return "false";
|
||||
|
||||
uf::Image image = *imagePointer;
|
||||
uf::Mesh& mesh = this->getComponent<uf::Mesh>();
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
|
||||
metadata["attachment"] = json["attachment"];
|
||||
|
||||
metadata["color"][0] = 1;
|
||||
metadata["color"][1] = 1;
|
||||
metadata["color"][2] = 1;
|
||||
metadata["color"][3] = 1;
|
||||
|
||||
std::string name = metadata["attachment"]["name"].asString();
|
||||
auto& attachment = maps.attachments[name];
|
||||
auto& slot = maps.slots[name];
|
||||
// transform.scale = { attachment.scale.x, attachment.scale.y, 1 };
|
||||
transform.scale = { 1.0f / 512.0f, 1.0f / 512.0f, 1 };
|
||||
|
||||
std::string boneName = slot["bone"].asString();
|
||||
transform.position = getPosition( boneName, true );
|
||||
transform.orientation = getOrientation( boneName, true );
|
||||
std::cout << "\"" << name << "\": {\"position\": [ " << transform.position.x << ", " << transform.position.y << " ], \"rotation\": " << getRotation( name, true ) << " }," << std::endl;
|
||||
transform.position *= transform.scale;
|
||||
struct {
|
||||
pod::Vector2f position;
|
||||
pod::Vector2f uv;
|
||||
} topLeft, topRight, bottomLeft, bottomRight;
|
||||
|
||||
{
|
||||
topLeft.position = attachment.size * attachment.position.topLeft;
|
||||
topRight.position = attachment.size * attachment.position.topRight;
|
||||
bottomLeft.position = attachment.size * attachment.position.bottomLeft;
|
||||
bottomRight.position = attachment.size * attachment.position.bottomRight;
|
||||
}
|
||||
{
|
||||
topLeft.uv = { attachment.uv.min.x, 1.0f - attachment.uv.min.y };
|
||||
topRight.uv = { attachment.uv.max.x, 1.0f - attachment.uv.min.y };
|
||||
bottomLeft.uv = { attachment.uv.min.x, 1.0f - attachment.uv.max.y };
|
||||
bottomRight.uv = { attachment.uv.max.x, 1.0f - attachment.uv.max.y };
|
||||
}
|
||||
|
||||
mesh.vertices = {
|
||||
{ { topLeft.position.x, topLeft.position.y, 0.0f }, topLeft.uv, { 0.0f, 0.0f, -1.0f } },
|
||||
{ { topRight.position.x, topRight.position.y, 0.0f }, topRight.uv,{ 0.0f, 0.0f, -1.0f } },
|
||||
{ { bottomRight.position.x, bottomRight.position.y, 0.0f }, bottomRight.uv, { 0.0f, 0.0f, -1.0f } },
|
||||
|
||||
{ { bottomRight.position.x, bottomRight.position.y, 0.0f }, bottomRight.uv, { 0.0f, 0.0f, -1.0f } },
|
||||
{ { bottomLeft.position.x, bottomLeft.position.y, 0.0f }, bottomLeft.uv, { 0.0f, 0.0f, -1.0f } },
|
||||
{ { topLeft.position.x, topLeft.position.y, 0.0f }, topLeft.uv, { 0.0f, 0.0f, -1.0f } },
|
||||
};
|
||||
{
|
||||
std::cout << name << ". Slot: " << slot << std::endl;
|
||||
auto skin = getSkin( slot );
|
||||
struct WeightedVertex {
|
||||
int boneId;
|
||||
float weight;
|
||||
pod::Vector2f position;
|
||||
};
|
||||
struct SkinnedVertex {
|
||||
std::vector<WeightedVertex> weights;
|
||||
pod::Vector2f position;
|
||||
pod::Vector2f uv;
|
||||
};
|
||||
std::vector<SkinnedVertex> skinnedVertices;
|
||||
|
||||
std::cout << name << ", Vertices?:\n";
|
||||
for ( int i = 0; i < skin["vertices"].size(); ) {
|
||||
int read = skin["vertices"][i++].asInt();
|
||||
auto& skinVertex = skinnedVertices.emplace_back();
|
||||
for ( int j = 0; j < read; ++j ) {
|
||||
auto& weightedVertex = skinVertex.weights.emplace_back();
|
||||
weightedVertex.boneId = skin["vertices"][i++].asInt();
|
||||
weightedVertex.position.x = skin["vertices"][i++].asFloat();
|
||||
weightedVertex.position.y = skin["vertices"][i++].asFloat();
|
||||
weightedVertex.weight = skin["vertices"][i++].asFloat();
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < skinnedVertices.size(); ++i ) {
|
||||
auto& skinVertex = skinnedVertices.at(i);
|
||||
skinVertex.uv.x = skin["uvs"][(i*2+0)].asFloat();
|
||||
skinVertex.uv.y = skin["uvs"][(i*2+1)].asFloat();
|
||||
|
||||
// average
|
||||
for ( auto& weightedVertex : skinVertex.weights ) {
|
||||
std::string boneName = manifests.animation["bones"][weightedVertex.boneId]["name"].asString();
|
||||
auto bonePosition = getPosition( boneName, true );
|
||||
auto boneOrientation = getOrientation( boneName, true );
|
||||
|
||||
bonePosition = uf::quaternion::rotate( boneOrientation, bonePosition );
|
||||
auto rotatedVertex = uf::quaternion::rotate( boneOrientation, pod::Vector3f{ weightedVertex.position.x, weightedVertex.position.y, 0 } );
|
||||
skinVertex.position.x += (rotatedVertex.x + bonePosition.x) * weightedVertex.weight;
|
||||
skinVertex.position.y += (rotatedVertex.y + bonePosition.y) * weightedVertex.weight;
|
||||
// wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight;
|
||||
}
|
||||
}
|
||||
for ( int i = 0; i < skinnedVertices.size(); ++i ) {
|
||||
auto& skinVertex = skinnedVertices.at(i);
|
||||
std::cout << "Index " << i << ":\n";
|
||||
for ( auto& weightedVertex : skinVertex.weights ) {
|
||||
std::string boneName = manifests.animation["bones"][weightedVertex.boneId]["name"].asString();
|
||||
std::cout << "\tPosition: " << weightedVertex.position.x << ", " << weightedVertex.position.y << " | Bone ID: " << weightedVertex.boneId << " | Bone Name: " << boneName << " | Weight: " << weightedVertex.weight << "\n";
|
||||
}
|
||||
std::cout << "\tUV: " << skinVertex.uv.x << ", " << skinVertex.uv.y << "\n";
|
||||
std::cout << "\tWeighted Position: " << skinVertex.position.x << ", " << skinVertex.position.y << "\n";
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << name << ", Triangles:\n";
|
||||
|
||||
mesh.vertices.clear();
|
||||
|
||||
for ( auto i = 0; i < skin["triangles"].size(); ) {
|
||||
std::cout << "Triangle:\n";
|
||||
for ( int j = 0; j < 3; ++j ) {
|
||||
int index = skin["triangles"][i++].asInt();
|
||||
auto& skinVertex = skinnedVertices.at(index);
|
||||
struct {
|
||||
pod::Vector2f interp;
|
||||
} position, uv;
|
||||
|
||||
uv.interp.x = std::lerp( attachment.uv.min.x, attachment.uv.max.x, skinVertex.uv.x );
|
||||
uv.interp.y = std::lerp( attachment.uv.min.y, attachment.uv.max.y, skinVertex.uv.y );
|
||||
|
||||
// uv.interp = skinVertex.uv;
|
||||
position.interp.x = (uv.interp.x - 0.5f) * attachment.size.x;
|
||||
position.interp.y = (uv.interp.y - 0.5f) * attachment.size.y;
|
||||
|
||||
std::cout << "\tIndex: " << index << "\tUV: " << uv.interp.x << ", " << uv.interp.y << "\tPosition: " << position.interp.x << ", " << position.interp.y << "\n";
|
||||
|
||||
auto& vertex = mesh.vertices.emplace_back();
|
||||
// vertex.position.x = position.interp.x;
|
||||
// vertex.position.y = position.interp.y;
|
||||
|
||||
vertex.position.x = skinVertex.position.x;
|
||||
vertex.position.y = skinVertex.position.y;
|
||||
|
||||
vertex.position.z = 0;
|
||||
vertex.uv.x = uv.interp.x;
|
||||
vertex.uv.y = 1.0f - uv.interp.y;
|
||||
vertex.normal = { 0, 0, -1 };
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
/*
|
||||
std::cout << name << ", Triangles:\n";
|
||||
for ( auto i = 0; i < skin["triangles"].size(); i += 3 ) {
|
||||
// std::cout << "\t" << skin["triangles"][i+0].asInt() << " " << skin["triangles"][i+1].asInt() << " " << skin["triangles"][i+2].asInt() << std::endl;
|
||||
std::cout << "\t" << skin["uvs"][skin["triangles"][i+0].asInt()].asFloat() << " " << skin["uvs"][skin["triangles"][i+1].asInt()].asFloat() << " " << skin["uvs"][skin["triangles"][i+2].asInt()].asFloat()
|
||||
}
|
||||
*/
|
||||
std::cout << name << ", "
|
||||
<< "UVs: " << skin["uvs"].size() << ", "
|
||||
<< "Positions: " << skin["vertices"].size() << ", "
|
||||
<< "Triangles: " << skin["triangles"].size() << ", "
|
||||
<< "Edges: " << skin["edges"].size() << ", "
|
||||
<< "Hull: " << skin["hull"]
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
graphic.initialize( "Gui" );
|
||||
graphic.initializeGeometry( mesh );
|
||||
|
||||
auto& texture = graphic.material.textures.emplace_back();
|
||||
texture.loadFromImage( image );
|
||||
|
||||
graphic.material.attachShader("./data/shaders/base.stereo.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
|
||||
graphic.material.attachShader("./data/shaders/base.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
||||
metadata["system"]["control"] = true;
|
||||
metadata["system"]["loaded"] = true;
|
||||
|
||||
return "true";
|
||||
});
|
||||
}
|
||||
void ext::LahSpinePieceBehavior::tick( uf::Object& self ) {}
|
||||
void ext::LahSpinePieceBehavior::render( uf::Object& self ){
|
||||
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
|
||||
if ( !metadata["system"]["loaded"].asBool() ) return;
|
||||
|
||||
/* Update uniforms */ if ( this->hasComponent<uf::Graphic>() ) {
|
||||
auto& mesh = this->getComponent<uf::Mesh>();
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& graphic = this->getComponent<uf::Graphic>();
|
||||
auto& transform = this->getComponent<pod::Transform<>>();
|
||||
auto& camera = scene.getController().getComponent<uf::Camera>();
|
||||
if ( !graphic.initialized ) return;
|
||||
auto& uniforms = graphic.material.shaders.front().uniforms.front().get<uf::StereoMeshDescriptor>();
|
||||
auto translation = uf::matrix::translate( uf::matrix::identity(), transform.position );
|
||||
auto rotation = uf::quaternion::matrix( transform.orientation );
|
||||
auto scale = uf::matrix::scale( uf::matrix::identity(), transform.scale );
|
||||
auto model = translation * rotation * scale;
|
||||
|
||||
std::string name = metadata["attachment"]["name"].asString();
|
||||
auto& attachment = maps.attachments[name];
|
||||
auto bone = getMatrix( name, true );
|
||||
|
||||
uniforms.matrices.model = metadata["attachment"]["useMatrix"].asBool() ? bone : model;
|
||||
|
||||
for ( std::size_t i = 0; i < 2; ++i ) {
|
||||
uniforms.matrices.view[i] = camera.getView( i );
|
||||
uniforms.matrices.projection[i] = camera.getProjection( i );
|
||||
}
|
||||
|
||||
uniforms.color[0] = metadata["color"][0].asFloat();
|
||||
uniforms.color[1] = metadata["color"][1].asFloat();
|
||||
uniforms.color[2] = metadata["color"][2].asFloat();
|
||||
uniforms.color[3] = metadata["color"][3].asFloat();
|
||||
graphic.material.shaders.front().updateBuffer( uniforms, 0, false );
|
||||
};
|
||||
}
|
||||
void ext::LahSpinePieceBehavior::destroy( uf::Object& self ){}
|
||||
#undef this
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <uf/config.h>
|
||||
#include <uf/ext/ext.h>
|
||||
#include <uf/engine/entity/entity.h>
|
||||
#include <uf/engine/scene/scene.h>
|
||||
|
||||
namespace ext {
|
||||
class EXT_API LahSpineBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
class EXT_API LahSpinePieceBehavior {
|
||||
public:
|
||||
static void attach( uf::Object& );
|
||||
static void initialize( uf::Object& );
|
||||
static void tick( uf::Object& );
|
||||
static void render( uf::Object& );
|
||||
static void destroy( uf::Object& );
|
||||
};
|
||||
}
|
@ -11,8 +11,12 @@ EXT_BEHAVIOR_REGISTER_CPP(StaticEmitterBehavior)
|
||||
#define this ((uf::Object*) &self)
|
||||
void ext::StaticEmitterBehavior::initialize( uf::Object& self ) {
|
||||
auto& metadata = this->getComponent<uf::Serializer>();
|
||||
// this->addHook( "system:Load.Finished.%UID%", [&](const std::string& event)->std::string{
|
||||
// uf::Serializer json = event;
|
||||
auto* hud = this->loadChildPointer("/hud.json", true);
|
||||
metadata["hud"]["uid"] = hud->getUid();
|
||||
// return "true";
|
||||
// });
|
||||
}
|
||||
void ext::StaticEmitterBehavior::tick( uf::Object& self ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
|
@ -825,7 +825,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
||||
// graphic.descriptor.indices = 0;
|
||||
graphic.initializeGeometry( mesh );
|
||||
graphic.getPipeline().update( graphic );
|
||||
uf::renderer::rebuild = true;
|
||||
// uf::renderer::rebuild = true;
|
||||
|
||||
/*
|
||||
graphic.destroy();
|
||||
|
@ -253,9 +253,8 @@ void EXT_API ext::initialize() {
|
||||
uf::renderer::initialize();
|
||||
}
|
||||
/* */ {
|
||||
pod::Thread& threadMain = uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false, true );
|
||||
// pod::Thread& threadAux = uf::thread::has("Aux") ? uf::thread::get("Aux") : uf::thread::create( "Aux", true, false );
|
||||
pod::Thread& threadPhysics = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true, false );
|
||||
pod::Thread& threadMain = uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false );
|
||||
pod::Thread& threadPhysics = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true );
|
||||
}
|
||||
|
||||
/* Discord */ if ( ::config["engine"]["ex"]["discord"]["enabled"].asBool() ) {
|
||||
|
@ -89,20 +89,22 @@ void ext::RayTracingSceneBehavior::tick( uf::Object& self ) {
|
||||
alignas(16) pod::Vector4f ambient;
|
||||
struct {
|
||||
alignas(8) pod::Vector2f range;
|
||||
alignas(8) pod::Vector2f padding;
|
||||
alignas(16) pod::Vector4f color;
|
||||
} fog;
|
||||
struct Light {
|
||||
alignas(16) pod::Vector4f position;
|
||||
alignas(16) pod::Vector4f color;
|
||||
alignas(8) pod::Vector2i type;
|
||||
alignas(8) pod::Vector2i padding;
|
||||
alignas(16) pod::Matrix4f view;
|
||||
alignas(16) pod::Matrix4f projection;
|
||||
} lights;
|
||||
};
|
||||
|
||||
struct SpecializationConstant {
|
||||
uint32_t eyes = 2;
|
||||
uint32_t maxLights = 16;
|
||||
uint32_t eyes = 2;
|
||||
} specializationConstants;
|
||||
|
||||
auto& shader = renderMode.compute.material.shaders.front();
|
||||
|
Loading…
Reference in New Issue
Block a user