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 -lsfml-main -lsfml-system -lsfml-window -lsfml-graphics -llua52
|
||||||
# EXT_LIBS = -lpng16 -lz -lassimp -ljsoncpp -lopenal32 -lalut -lvorbis -lvorbisfile -logg -lfreetype
|
# EXT_LIBS = -lpng16 -lz -lassimp -ljsoncpp -lopenal32 -lalut -lvorbis -lvorbisfile -logg -lfreetype
|
||||||
EXT_LIBS =
|
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++0x -Wall -g -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENGL -DUF_USE_GLEW
|
||||||
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 = -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
|
#-march=native
|
||||||
LIB_NAME = uf
|
LIB_NAME = uf
|
||||||
EXT_LIB_NAME = ext
|
EXT_LIB_NAME = ext
|
||||||
|
|
||||||
|
|
||||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.101.0/
|
#VULKAN_WIN64_SDK_PATH = /cygdrive/c/VulkanSDK/1.1.101.0/
|
||||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.108.0/
|
#VULKAN_WIN64_SDK_PATH = /cygdrive/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.114.0/
|
||||||
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.141.2/
|
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.141.2/
|
||||||
VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.154.0/
|
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
|
WIN64_GLSL_VALIDATOR = $(VULKAN_WIN64_SDK_PATH)/Bin32/glslangValidator
|
||||||
# Base Engine's DLL
|
# Base Engine's DLL
|
||||||
WIN64_INC_DIR = $(ENGINE_INC_DIR)/win64
|
WIN64_INC_DIR = $(ENGINE_INC_DIR)/win64
|
||||||
@ -39,8 +39,8 @@ WIN64_FLAGS = $(FLAGS) -g
|
|||||||
#-Wl,-subsystem,windows
|
#-Wl,-subsystem,windows
|
||||||
|
|
||||||
WIN64_LIB_DIR = $(ENGINE_LIB_DIR)/win64/
|
WIN64_LIB_DIR = $(ENGINE_LIB_DIR)/win64/
|
||||||
WIN64_INCS = -I$(ENGINE_INC_DIR) -I$(WIN64_INC_DIR) -I$(VULKAN_WIN64_SDK_PATH)/include
|
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
|
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)
|
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))
|
OBJS_WIN64_DLL = $(patsubst %.cpp,%.win64.o,$(SRCS_WIN64_DLL))
|
||||||
@ -56,8 +56,8 @@ EXT_WIN64_FLAGS = $(FLAGS)
|
|||||||
#-Wl,-subsystem,windows
|
#-Wl,-subsystem,windows
|
||||||
|
|
||||||
EXT_WIN64_LIB_DIR = $(ENGINE_LIB_DIR)/win64/
|
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_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
|
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)
|
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))
|
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)
|
SRCS_SHADERS = $(wildcard bin/data/shaders/*.glsl)
|
||||||
TARGET_SHADERS = $(patsubst %.glsl,%.spv,$(SRCS_SHADERS))
|
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)
|
win64: $(EX_WIN64_DLL) $(EXT_EX_WIN64_DLL) $(TARGET_WIN64) $(TARGET_SHADERS)
|
||||||
|
|
||||||
rm-exe64:
|
rm-exe64:
|
||||||
|
@ -32,6 +32,7 @@ struct Light {
|
|||||||
vec3 color;
|
vec3 color;
|
||||||
float power;
|
float power;
|
||||||
vec2 type;
|
vec2 type;
|
||||||
|
vec2 padding;
|
||||||
mat4 view;
|
mat4 view;
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
};
|
};
|
||||||
@ -44,6 +45,7 @@ struct State {
|
|||||||
|
|
||||||
struct Fog {
|
struct Fog {
|
||||||
vec2 range;
|
vec2 range;
|
||||||
|
vec2 padding;
|
||||||
vec4 color;
|
vec4 color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
template<typename C>
|
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;
|
for ( auto pair : names ) if ( pair.second == name ) return pair.first;
|
||||||
return getType<void>();
|
return getType<void>();
|
||||||
}
|
}
|
||||||
template<typename C>
|
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));
|
return std::type_index(typeid(T));
|
||||||
}
|
}
|
||||||
template<typename C>
|
template<typename C>
|
||||||
|
@ -97,6 +97,8 @@ namespace ext {
|
|||||||
};
|
};
|
||||||
VkQueue& getQueue( QueueEnum );
|
VkQueue& getQueue( QueueEnum );
|
||||||
VkCommandPool& getCommandPool( QueueEnum );
|
VkCommandPool& getCommandPool( QueueEnum );
|
||||||
|
VkQueue& getQueue( QueueEnum, std::thread::id );
|
||||||
|
VkCommandPool& getCommandPool( QueueEnum, std::thread::id );
|
||||||
|
|
||||||
// RAII
|
// RAII
|
||||||
void initialize();
|
void initialize();
|
||||||
|
@ -104,6 +104,7 @@ namespace ext {
|
|||||||
Pipeline& getPipeline( Descriptor& descriptor );
|
Pipeline& getPipeline( Descriptor& descriptor );
|
||||||
|
|
||||||
void record( VkCommandBuffer commandBuffer );
|
void record( VkCommandBuffer commandBuffer );
|
||||||
|
void record( VkCommandBuffer commandBuffer, Descriptor& descriptor );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ namespace ext {
|
|||||||
|
|
||||||
struct UF_API RenderMode {
|
struct UF_API RenderMode {
|
||||||
bool execute = false;
|
bool execute = false;
|
||||||
|
bool rebuild = false;
|
||||||
uint32_t width = 0, height = 0;
|
uint32_t width = 0, height = 0;
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
|
|
||||||
@ -16,18 +17,25 @@ namespace ext {
|
|||||||
|
|
||||||
VkSemaphore renderCompleteSemaphore;
|
VkSemaphore renderCompleteSemaphore;
|
||||||
std::vector<VkFence> fences;
|
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();
|
// virtual ~RenderMode();
|
||||||
// RAII
|
// RAII
|
||||||
virtual std::string getType() const;
|
virtual std::string getType() const;
|
||||||
const std::string& getName() const;
|
const std::string& getName( bool = false ) const;
|
||||||
virtual RenderTarget& getRenderTarget(size_t = 0);
|
virtual RenderTarget& getRenderTarget(size_t = 0);
|
||||||
virtual const RenderTarget& getRenderTarget(size_t = 0) const;
|
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 initialize( Device& device );
|
||||||
virtual void createCommandBuffers();
|
virtual void createCommandBuffers();
|
||||||
virtual void createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics );
|
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 tick();
|
||||||
virtual void render();
|
virtual void render();
|
||||||
virtual void destroy();
|
virtual void destroy();
|
||||||
|
@ -14,6 +14,7 @@ namespace ext {
|
|||||||
|
|
||||||
// RAII
|
// RAII
|
||||||
virtual std::string getType() const;
|
virtual std::string getType() const;
|
||||||
|
virtual const std::string& getName( bool ) const;
|
||||||
|
|
||||||
virtual void createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics );
|
virtual void createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics );
|
||||||
virtual void initialize( Device& device );
|
virtual void initialize( Device& device );
|
||||||
|
@ -25,8 +25,11 @@ namespace uf {
|
|||||||
Audio( Audio&& );
|
Audio( Audio&& );
|
||||||
Audio( const Audio& );
|
Audio( const Audio& );
|
||||||
*/
|
*/
|
||||||
|
~Audio();
|
||||||
|
|
||||||
bool initialized();
|
bool initialized();
|
||||||
bool playing();
|
bool playing();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
void load( const std::string& = "" );
|
void load( const std::string& = "" );
|
||||||
void play();
|
void play();
|
||||||
|
@ -10,13 +10,11 @@ namespace {
|
|||||||
// Sometimes uint isn't declared
|
// Sometimes uint isn't declared
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
namespace uf {
|
namespace uf {
|
||||||
namespace math {
|
namespace math {
|
||||||
template<typename T>
|
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 uf {
|
||||||
namespace io {
|
namespace io {
|
||||||
|
std::string UF_API absolute( const std::string& );
|
||||||
std::string UF_API filename( const std::string& );
|
std::string UF_API filename( const std::string& );
|
||||||
std::string UF_API extension( const std::string& );
|
std::string UF_API extension( const std::string& );
|
||||||
std::string UF_API directory( const std::string& );
|
std::string UF_API directory( const std::string& );
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
namespace pod {
|
namespace pod {
|
||||||
struct UF_API Thread {
|
struct UF_API Thread {
|
||||||
@ -22,6 +23,7 @@ namespace pod {
|
|||||||
bool running, terminates;
|
bool running, terminates;
|
||||||
|
|
||||||
std::mutex* mutex;
|
std::mutex* mutex;
|
||||||
|
std::condition_variable condition;
|
||||||
std::thread thread;
|
std::thread thread;
|
||||||
|
|
||||||
pod::Thread::queue_t temps;
|
pod::Thread::queue_t temps;
|
||||||
@ -45,6 +47,7 @@ namespace uf {
|
|||||||
// void UF_API tick( pod::Thread&, const std::function<void()>& = NULL );
|
// void UF_API tick( pod::Thread&, const std::function<void()>& = NULL );
|
||||||
|
|
||||||
pod::Thread& UF_API fetchWorker( const std::string& name = "Aux" );
|
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 add( pod::Thread&, const pod::Thread::function_t&, bool = false );
|
||||||
void UF_API process( pod::Thread& );
|
void UF_API process( pod::Thread& );
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
|
|||||||
//
|
//
|
||||||
{
|
{
|
||||||
size_t assets = metadata["system"]["assets"].size();
|
size_t assets = metadata["system"]["assets"].size();
|
||||||
|
if ( metadata["system"]["load"]["ignore"].isBool() ) assets = 0;
|
||||||
metadata["system"]["load"]["progress"] = 0;
|
metadata["system"]["load"]["progress"] = 0;
|
||||||
metadata["system"]["load"]["total"] = assets;
|
metadata["system"]["load"]["total"] = assets;
|
||||||
if ( assets == 0 ) {
|
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{
|
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
|
||||||
uf::Serializer json = event;
|
uf::Serializer json = event;
|
||||||
std::string filename = json["filename"].asString();
|
std::string filename = json["filename"].asString();
|
||||||
|
bool initialize = json["initialize"].isNull() ? true : json["initialize"].asBool();
|
||||||
|
|
||||||
if ( uf::io::extension(filename) != "json" ) return "false";
|
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["root"] = uf::io::directory(filename);
|
||||||
json["source"] = filename; // uf::io::filename(filename)
|
json["source"] = filename; // uf::io::filename(filename)
|
||||||
json["hot reload"]["mtime"] = uf::io::mtime( filename ) + 10;
|
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";
|
return "true";
|
||||||
});
|
});
|
||||||
|
@ -87,6 +87,7 @@ void uf::LoadingBehavior::tick( uf::Object& self ) {
|
|||||||
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
std::function<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
|
||||||
if ( !entity || entity->getUid() == 0 || !entity->hasComponent<uf::Serializer>() ) return;
|
if ( !entity || entity->getUid() == 0 || !entity->hasComponent<uf::Serializer>() ) return;
|
||||||
auto& metadata = entity->getComponent<uf::Serializer>();
|
auto& metadata = entity->getComponent<uf::Serializer>();
|
||||||
|
if ( metadata["system"]["load"]["ignore"].isBool() ) return;
|
||||||
if ( metadata["system"]["load"].isNull() ) return;
|
if ( metadata["system"]["load"].isNull() ) return;
|
||||||
++loading;
|
++loading;
|
||||||
if ( metadata["system"]["load"]["progress"].asInt() < metadata["system"]["load"]["total"].asInt() ) return;
|
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;
|
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__);
|
this->checkError(__FUNCTION__, __LINE__);
|
||||||
return res;
|
return this->m_initialized;
|
||||||
}
|
}
|
||||||
bool UF_API_CALL ext::AL::terminate() {
|
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 {
|
void UF_API_CALL ext::AL::checkError( const std::string& function, int line, const std::string& aux ) const {
|
||||||
std::string error = this->getError();
|
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 {
|
std::string UF_API_CALL ext::AL::getError() const {
|
||||||
ALCenum error = alGetError();
|
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_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
|
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 ) {
|
void UF_API_CALL ext::AL::listener( ALenum name, std::vector<ALfloat> parameters ) {
|
||||||
switch ( parameters.size() ) {
|
switch ( parameters.size() ) {
|
||||||
@ -86,13 +90,12 @@ ext::al::Source::~Source() {
|
|||||||
|
|
||||||
void UF_API_CALL ext::al::Source::generate() {
|
void UF_API_CALL ext::al::Source::generate() {
|
||||||
if ( this->m_index ) this->destroy();
|
if ( this->m_index ) this->destroy();
|
||||||
alGenSources(1, &this->m_index);
|
alGenSources(1, &this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
ext::oal.checkError(__FUNCTION__, __LINE__);
|
|
||||||
}
|
}
|
||||||
void UF_API_CALL ext::al::Source::destroy() {
|
void UF_API_CALL ext::al::Source::destroy() {
|
||||||
if ( this->m_index && alIsSource(this->m_index) ) {
|
if ( this->m_index && alIsSource(this->m_index) ) {
|
||||||
alDeleteSources(1, &this->m_index);
|
if ( this->playing() ) this->stop();
|
||||||
ext::oal.checkError(__FUNCTION__, __LINE__);
|
alDeleteSources(1, &this->m_index); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
this->m_index = 0;
|
this->m_index = 0;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#include <uf/ext/openvr/openvr.h>
|
#include <uf/ext/openvr/openvr.h>
|
||||||
#include <uf/utils/io/iostream.h>
|
#include <uf/utils/io/iostream.h>
|
||||||
#include <uf/utils/string/ext.h>
|
#include <uf/utils/string/ext.h>
|
||||||
|
#include <uf/utils/string/io.h>
|
||||||
|
|
||||||
#include <uf/ext/vulkan/vulkan.h>
|
#include <uf/ext/vulkan/vulkan.h>
|
||||||
#include <uf/ext/vulkan/rendermodes/stereoscopic_deferred.h>
|
#include <uf/ext/vulkan/rendermodes/stereoscopic_deferred.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#define DEBUG_MARKER 0
|
#define DEBUG_MARKER 0
|
||||||
|
|
||||||
vr::IVRSystem* ext::openvr::context;
|
vr::IVRSystem* ext::openvr::context;
|
||||||
@ -156,10 +155,7 @@ bool ext::openvr::initialize( int stage ) {
|
|||||||
|
|
||||||
// load manifest
|
// load manifest
|
||||||
{
|
{
|
||||||
std::filesystem::path p = ext::openvr::driver.manifest;
|
VR_CHECK_INPUT_RESULT( vr::VRInput()->SetActionManifestPath( uf::io::absolute(ext::openvr::driver.manifest).c_str() ) );
|
||||||
p = std::filesystem::absolute( p );
|
|
||||||
ext::openvr::driver.manifest = p.string();
|
|
||||||
VR_CHECK_INPUT_RESULT( vr::VRInput()->SetActionManifestPath( ext::openvr::driver.manifest.c_str() ) );
|
|
||||||
// configure action handles
|
// configure action handles
|
||||||
{
|
{
|
||||||
uf::Serializer manifest;
|
uf::Serializer manifest;
|
||||||
|
@ -436,10 +436,15 @@ VkResult ext::vulkan::Device::createBuffer(
|
|||||||
return buffer.bind();
|
return buffer.bind();
|
||||||
}
|
}
|
||||||
VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::Device::QueueEnum queueEnum) {
|
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;
|
uint32_t index = 0;
|
||||||
VkCommandPool* pool = NULL;
|
VkCommandPool* pool = NULL;
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
auto id = std::this_thread::get_id();
|
|
||||||
switch ( queueEnum ) {
|
switch ( queueEnum ) {
|
||||||
case QueueEnum::GRAPHICS:
|
case QueueEnum::GRAPHICS:
|
||||||
index = device.queueFamilyIndices.graphics;
|
index = device.queueFamilyIndices.graphics;
|
||||||
@ -468,11 +473,10 @@ VkCommandPool& ext::vulkan::Device::getCommandPool( ext::vulkan::Device::QueueEn
|
|||||||
}
|
}
|
||||||
return *pool;
|
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;
|
uint32_t index = 0;
|
||||||
VkQueue* queue = NULL;
|
VkQueue* queue = NULL;
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
auto id = std::this_thread::get_id();
|
|
||||||
switch ( queueEnum ) {
|
switch ( queueEnum ) {
|
||||||
case QueueEnum::GRAPHICS:
|
case QueueEnum::GRAPHICS:
|
||||||
index = device.queueFamilyIndices.graphics;
|
index = device.queueFamilyIndices.graphics;
|
||||||
|
@ -479,6 +479,9 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
|||||||
// generate fallback empty texture
|
// generate fallback empty texture
|
||||||
auto& emptyTexture = Texture2D::empty;
|
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<VkWriteDescriptorSet> writeDescriptorSets;
|
||||||
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings;
|
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings;
|
||||||
std::vector<VkDescriptorImageInfo> inputDescriptors;
|
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() );
|
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() ) {
|
if ( graphic.descriptor.subpass < renderTarget.passes.size() ) {
|
||||||
auto& subpass = renderTarget.passes[graphic.descriptor.subpass];
|
auto& subpass = renderTarget.passes[graphic.descriptor.subpass];
|
||||||
for ( auto& input : subpass.inputs ) {
|
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 )
|
if ( d.imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL )
|
||||||
d.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_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 );
|
imageInfos.push_back( d );
|
||||||
}
|
}
|
||||||
@ -668,10 +670,11 @@ void ext::vulkan::Pipeline::update( Graphic& graphic ) {
|
|||||||
for ( auto& descriptor : writeDescriptorSets ) {
|
for ( auto& descriptor : writeDescriptorSets ) {
|
||||||
if ( descriptor.pBufferInfo ) {
|
if ( descriptor.pBufferInfo ) {
|
||||||
// std::cout << descriptor.pBufferInfo->offset << std::endl;
|
// std::cout << descriptor.pBufferInfo->offset << std::endl;
|
||||||
if ( descriptor.pBufferInfo->offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
|
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
|
||||||
// std::cout << "Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.pBufferInfo->offset << std::endl;
|
if ( descriptor.pBufferInfo[i].offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
|
||||||
std::cout << "Invalid descriptor for buffer: " << descriptor.pBufferInfo->buffer << " " << descriptor.pBufferInfo->offset << " " << descriptor.pBufferInfo->range << ", invalidating..." << std::endl;
|
// std::cout << "Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.pBufferInfo[i].offset << std::endl;
|
||||||
auto pointer = const_cast<VkDescriptorBufferInfo*>(descriptor.pBufferInfo);
|
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->offset = 0;
|
||||||
pointer->range = 0;
|
pointer->range = 0;
|
||||||
pointer->buffer = VK_NULL_HANDLE;
|
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(
|
vkUpdateDescriptorSets(
|
||||||
*device,
|
*device,
|
||||||
writeDescriptorSets.size(),
|
writeDescriptorSets.size(),
|
||||||
@ -780,12 +798,15 @@ ext::vulkan::Pipeline& ext::vulkan::Graphic::getPipeline( Descriptor& descriptor
|
|||||||
return pipelines[descriptor.hash()];
|
return pipelines[descriptor.hash()];
|
||||||
}
|
}
|
||||||
void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer ) {
|
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 ) ) {
|
if ( !this->hasPipeline( descriptor ) ) {
|
||||||
std::cout << this << ": has no valid pipeline" << std::endl;
|
std::cout << this << ": has no valid pipeline" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& pipeline = this->getPipeline();
|
auto& pipeline = this->getPipeline( descriptor );
|
||||||
|
|
||||||
assert( buffers.size() >= 2 );
|
assert( buffers.size() >= 2 );
|
||||||
Buffer& vertexBuffer = buffers.at(0);
|
Buffer& vertexBuffer = buffers.at(0);
|
||||||
|
@ -17,7 +17,7 @@ ext::vulkan::RenderMode::~RenderMode() {
|
|||||||
std::string ext::vulkan::RenderMode::getType() const {
|
std::string ext::vulkan::RenderMode::getType() const {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const std::string& ext::vulkan::RenderMode::getName() const {
|
const std::string& ext::vulkan::RenderMode::getName( bool ) const {
|
||||||
return this->name;
|
return this->name;
|
||||||
}
|
}
|
||||||
ext::vulkan::RenderTarget& ext::vulkan::RenderMode::getRenderTarget( size_t i ) {
|
ext::vulkan::RenderTarget& ext::vulkan::RenderMode::getRenderTarget( size_t i ) {
|
||||||
@ -52,13 +52,78 @@ void ext::vulkan::RenderMode::createCommandBuffers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->synchronize();
|
this->synchronize();
|
||||||
//VK_CHECK_RESULT(vkWaitForFences(*device, fences.size(), fences.data(), VK_TRUE, UINT64_MAX));
|
bindPipelines( graphics );
|
||||||
createCommandBuffers( 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::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() {
|
void ext::vulkan::RenderMode::render() {
|
||||||
|
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||||
// Get next image in the swap chain (back/front buffer)
|
// Get next image in the swap chain (back/front buffer)
|
||||||
VK_CHECK_RESULT(swapchain.acquireNextImage(¤tBuffer, swapchain.presentCompleteSemaphore));
|
VK_CHECK_RESULT(swapchain.acquireNextImage(¤tBuffer, swapchain.presentCompleteSemaphore));
|
||||||
|
|
||||||
@ -101,6 +166,7 @@ void ext::vulkan::RenderMode::initialize( Device& device ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create command buffers
|
// Create command buffers
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
commands.resize( swapchain.buffers );
|
commands.resize( swapchain.buffers );
|
||||||
|
|
||||||
@ -112,6 +178,7 @@ void ext::vulkan::RenderMode::initialize( Device& device ) {
|
|||||||
|
|
||||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, commands.data()));
|
VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, commands.data()));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// Set sync objects
|
// Set sync objects
|
||||||
{
|
{
|
||||||
// Fences (Used to check draw command buffer completion)
|
// 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;
|
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
// Create in signaled state so we don't wait on first render of each command buffer
|
// Create in signaled state so we don't wait on first render of each command buffer
|
||||||
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
fences.resize( commands.size() );
|
fences.resize( swapchain.buffers );
|
||||||
for ( auto& fence : fences ) {
|
for ( auto& fence : fences ) {
|
||||||
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
||||||
}
|
}
|
||||||
@ -143,12 +210,16 @@ void ext::vulkan::RenderMode::destroy() {
|
|||||||
this->synchronize();
|
this->synchronize();
|
||||||
|
|
||||||
renderTarget.destroy();
|
renderTarget.destroy();
|
||||||
|
/*
|
||||||
if ( commands.size() > 0 ) {
|
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());
|
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();
|
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 ) {
|
if ( renderCompleteSemaphore != VK_NULL_HANDLE ) {
|
||||||
vkDestroySemaphore( *device, renderCompleteSemaphore, nullptr);
|
vkDestroySemaphore( *device, renderCompleteSemaphore, nullptr);
|
||||||
renderCompleteSemaphore = VK_NULL_HANDLE;
|
renderCompleteSemaphore = VK_NULL_HANDLE;
|
||||||
|
@ -18,9 +18,6 @@ ext::vulkan::BaseRenderMode::~BaseRenderMode() {
|
|||||||
std::string ext::vulkan::BaseRenderMode::getType() const {
|
std::string ext::vulkan::BaseRenderMode::getType() const {
|
||||||
return "Swapchain";
|
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 ) {
|
void ext::vulkan::BaseRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
|
||||||
if ( ext::vulkan::renderModes.size() > 1 ) return;
|
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.renderArea.extent.height = height;
|
||||||
renderPassBeginInfo.clearValueCount = 2;
|
renderPassBeginInfo.clearValueCount = 2;
|
||||||
renderPassBeginInfo.pClearValues = clearValues;
|
renderPassBeginInfo.pClearValues = clearValues;
|
||||||
|
auto& commands = getCommands();
|
||||||
for (size_t i = 0; i < commands.size(); ++i) {
|
for (size_t i = 0; i < commands.size(); ++i) {
|
||||||
// Set target frame buffer
|
// Set target frame buffer
|
||||||
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[i];
|
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[i];
|
||||||
|
@ -44,25 +44,18 @@ void ext::vulkan::ComputeRenderMode::initialize( Device& device ) {
|
|||||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||||
|
|
||||||
auto& shader = compute.material.shaders.front();
|
auto& shader = compute.material.shaders.front();
|
||||||
/*
|
|
||||||
struct SpecializationConstant {
|
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 maxLights = 16;
|
||||||
|
uint32_t eyes = 2;
|
||||||
};
|
};
|
||||||
auto* specializationConstants = (SpecializationConstant*) &shader.specializationConstants[0];
|
auto* specializationConstants = (SpecializationConstant*) &shader.specializationConstants[0];
|
||||||
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
|
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
|
||||||
specializationConstants->eyes = ext::openvr::context ? 2 : 1;
|
specializationConstants->eyes = ext::openvr::context ? 2 : 1;
|
||||||
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
|
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
|
||||||
if ( binding.descriptorCount > 1 )
|
if ( binding.descriptorCount > 1 ) {
|
||||||
binding.descriptorCount = specializationConstants->maxLights;
|
binding.descriptorCount = specializationConstants->eyes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +99,7 @@ void ext::vulkan::ComputeRenderMode::initialize( Device& device ) {
|
|||||||
void ext::vulkan::ComputeRenderMode::render() {
|
void ext::vulkan::ComputeRenderMode::render() {
|
||||||
if ( compute.buffers.empty() ) return;
|
if ( compute.buffers.empty() ) return;
|
||||||
|
|
||||||
|
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||||
// Submit compute commands
|
// Submit compute commands
|
||||||
// Use a fence to ensure that compute command buffer has finished executing before using it again
|
// 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 ));
|
VK_CHECK_RESULT(vkWaitForFences( *device, 1, &fences[currentBuffer], VK_TRUE, UINT64_MAX ));
|
||||||
@ -143,13 +137,10 @@ void ext::vulkan::ComputeRenderMode::tick() {
|
|||||||
texture = computeTexture;
|
texture = computeTexture;
|
||||||
texture.device = NULL;
|
texture.device = NULL;
|
||||||
}
|
}
|
||||||
auto& pipeline = blitter.getPipeline();
|
blitter.getPipeline().update( blitter );
|
||||||
pipeline.update( blitter );
|
|
||||||
}
|
}
|
||||||
// if ( compute.initialized ) {
|
|
||||||
if ( !compute.buffers.empty() ) {
|
if ( !compute.buffers.empty() ) {
|
||||||
auto& pipeline = compute.getPipeline();
|
compute.getPipeline().update( compute );
|
||||||
pipeline.update( compute );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,14 +203,16 @@ void ext::vulkan::ComputeRenderMode::createCommandBuffers( ) {
|
|||||||
float width = this->width > 0 ? this->width : ext::vulkan::width;
|
float width = this->width > 0 ? this->width : ext::vulkan::width;
|
||||||
float height = this->height > 0 ? this->height : ext::vulkan::height;
|
float height = this->height > 0 ? this->height : ext::vulkan::height;
|
||||||
|
|
||||||
if ( compute.buffers.empty() ) return;
|
|
||||||
|
|
||||||
VkCommandBufferBeginInfo cmdBufInfo = ext::vulkan::initializers::commandBufferBeginInfo();
|
VkCommandBufferBeginInfo cmdBufInfo = ext::vulkan::initializers::commandBufferBeginInfo();
|
||||||
auto& pipeline = compute.getPipeline();
|
auto& pipeline = compute.getPipeline();
|
||||||
|
auto& commands = getCommands();
|
||||||
|
if ( compute.buffers.empty() ) return;
|
||||||
for (size_t i = 0; i < commands.size(); ++i) {
|
for (size_t i = 0; i < commands.size(); ++i) {
|
||||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
||||||
pipeline.record(compute, commands[i]);
|
pipeline.record(compute, commands[i]);
|
||||||
vkCmdDispatch(commands[i], width / dispatchSize.x, height / dispatchSize.y, 1);
|
vkCmdDispatch(commands[i], width / dispatchSize.x, height / dispatchSize.y, 1);
|
||||||
VK_CHECK_RESULT(vkEndCommandBuffer(commands[i]));
|
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 );
|
renderTarget.initialize( *renderTarget.device );
|
||||||
// update blitter descriptor set
|
// update blitter descriptor set
|
||||||
if ( blitter.initialized ) {
|
if ( blitter.initialized ) {
|
||||||
auto& pipeline = blitter.getPipeline();
|
blitter.getPipeline().update( blitter );
|
||||||
pipeline.update( blitter );
|
|
||||||
ext::vulkan::rebuild = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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);
|
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes(std::vector<std::string>{"RenderTarget", "Compute"}, false);
|
||||||
auto& scene = uf::scene::getCurrentScene();
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||||
|
auto& commands = getCommands();
|
||||||
for (size_t i = 0; i < commands.size(); ++i) {
|
for (size_t i = 0; i < commands.size(); ++i) {
|
||||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
||||||
// Fill GBuffer
|
// Fill GBuffer
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
std::string ext::vulkan::RenderTargetRenderMode::getType() const {
|
std::string ext::vulkan::RenderTargetRenderMode::getType() const {
|
||||||
return "RenderTarget";
|
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 ) {
|
void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
|
||||||
ext::vulkan::RenderMode::initialize( device );
|
ext::vulkan::RenderMode::initialize( device );
|
||||||
@ -125,6 +128,7 @@ void ext::vulkan::RenderTargetRenderMode::destroy() {
|
|||||||
blitter.destroy();
|
blitter.destroy();
|
||||||
}
|
}
|
||||||
void ext::vulkan::RenderTargetRenderMode::render() {
|
void ext::vulkan::RenderTargetRenderMode::render() {
|
||||||
|
auto& commands = getCommands( this->mostRecentCommandPoolId );
|
||||||
// Submit commands
|
// Submit commands
|
||||||
// Use a fence to ensure that command buffer has finished executing before using it again
|
// 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 ));
|
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 = {};
|
VkCommandBufferBeginInfo cmdBufInfo = {};
|
||||||
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
cmdBufInfo.pNext = nullptr;
|
cmdBufInfo.pNext = nullptr;
|
||||||
|
auto& commands = getCommands();
|
||||||
for (size_t i = 0; i < commands.size(); ++i) {
|
for (size_t i = 0; i < commands.size(); ++i) {
|
||||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
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);
|
vkCmdSetScissor(commands[i], 0, 1, &scissor);
|
||||||
for ( auto graphic : graphics ) {
|
for ( auto graphic : graphics ) {
|
||||||
if ( graphic->descriptor.renderMode != this->target ) continue;
|
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);
|
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
|
||||||
vkCmdEndRenderPass(commands[i]);
|
vkCmdEndRenderPass(commands[i]);
|
||||||
|
@ -196,7 +196,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
|
|||||||
|
|
||||||
auto& scene = uf::scene::getCurrentScene();
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
auto& metadata = scene.getComponent<uf::Serializer>();
|
auto& metadata = scene.getComponent<uf::Serializer>();
|
||||||
|
auto& commands = getCommands();
|
||||||
for (size_t i = 0; i < commands.size(); ++i) {
|
for (size_t i = 0; i < commands.size(); ++i) {
|
||||||
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
|
||||||
struct EYES {
|
struct EYES {
|
||||||
|
@ -443,7 +443,7 @@ void ext::vulkan::Texture2D::asRenderTarget( Device& device, uint32_t width, uin
|
|||||||
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||||
imageCreateInfo.format = format;
|
imageCreateInfo.format = format;
|
||||||
imageCreateInfo.extent = { width, height, 1 };
|
imageCreateInfo.extent = { width, height, 1 };
|
||||||
imageCreateInfo.mipLevels = 1;
|
imageCreateInfo.mipLevels = this->mips = 1;
|
||||||
imageCreateInfo.arrayLayers = 1;
|
imageCreateInfo.arrayLayers = 1;
|
||||||
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
uint32_t ext::vulkan::width = 1280;
|
uint32_t ext::vulkan::width = 1280;
|
||||||
uint32_t ext::vulkan::height = 720;
|
uint32_t ext::vulkan::height = 720;
|
||||||
@ -302,11 +303,23 @@ void ext::vulkan::tick() {
|
|||||||
}
|
}
|
||||||
renderMode->tick();
|
renderMode->tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::function<int()>> jobs;
|
||||||
for ( auto& renderMode : renderModes ) {
|
for ( auto& renderMode : renderModes ) {
|
||||||
if ( !renderMode ) continue;
|
if ( !renderMode ) continue;
|
||||||
if ( ext::vulkan::rebuild )
|
if ( ext::vulkan::rebuild || renderMode->rebuild ) {
|
||||||
|
jobs.emplace_back([&]{
|
||||||
renderMode->createCommandBuffers();
|
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::rebuild = false;
|
||||||
ext::vulkan::resized = false;
|
ext::vulkan::resized = false;
|
||||||
ext::vulkan::mutex.unlock();
|
ext::vulkan::mutex.unlock();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#if defined(UF_USE_OPENAL)
|
#if defined(UF_USE_OPENAL)
|
||||||
#include <uf/ext/vorbis/vorbis.h>
|
#include <uf/ext/vorbis/vorbis.h>
|
||||||
|
#include <uf/ext/oal/oal.h>
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
UF_API uf::Audio::Audio( const std::string& filename ) : m_filename(filename) {
|
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() {
|
bool UF_API uf::Audio::initialized() {
|
||||||
if ( !this->m_source.getIndex() ) return false;
|
if ( !this->m_source.getIndex() ) return false;
|
||||||
if ( !this->m_buffer.getIndex() ) return false;
|
if ( !this->m_buffer.getIndex() ) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
void UF_API uf::Audio::destroy() {
|
||||||
|
this->m_source.destroy();
|
||||||
|
this->m_buffer.destroy();
|
||||||
|
}
|
||||||
bool UF_API uf::Audio::playing() {
|
bool UF_API uf::Audio::playing() {
|
||||||
if ( !this->initialized() ) return false;
|
if ( !this->initialized() ) return false;
|
||||||
if ( !this->m_source.playing() ) 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();
|
frequency = vorbis.getFrequency();
|
||||||
this->m_duration = vorbis.getDuration();
|
this->m_duration = vorbis.getDuration();
|
||||||
|
|
||||||
this->m_buffer.generate();
|
this->m_buffer.generate(); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
this->m_source.generate();
|
this->m_source.generate(); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
|
|
||||||
this->m_buffer.buffer( format, &buffer[0], buffer.size(), frequency );
|
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() } );
|
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( "PITCH", std::vector<ALfloat>{ 1 } ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
this->m_source.source( "GAIN", std::vector<ALfloat>{ 1 } );
|
this->m_source.source( "GAIN", std::vector<ALfloat>{ 1 } ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
this->m_source.source( "LOOPING", std::vector<ALint>{ AL_FALSE } );
|
this->m_source.source( "LOOPING", std::vector<ALint>{ AL_FALSE } ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UF_API uf::Audio::play() {
|
void UF_API uf::Audio::play() {
|
||||||
|
if ( !this->initialized() ) return;
|
||||||
this->m_source.play();
|
this->m_source.play();
|
||||||
}
|
}
|
||||||
void UF_API uf::Audio::stop() {
|
void UF_API uf::Audio::stop() {
|
||||||
|
if ( !this->initialized() ) return;
|
||||||
this->m_source.stop();
|
this->m_source.stop();
|
||||||
}
|
}
|
||||||
const std::string& UF_API uf::Audio::getFilename() const {
|
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 {
|
float uf::Audio::getDuration() const {
|
||||||
return this->m_duration;
|
return this->m_duration;
|
||||||
}
|
}
|
||||||
#include <uf/ext/oal/oal.h>
|
|
||||||
|
|
||||||
ALfloat UF_API uf::Audio::getTime() {
|
ALfloat UF_API uf::Audio::getTime() {
|
||||||
if ( this->playing() ) return 0;
|
if ( !this->playing() ) return 0;
|
||||||
ALfloat pos;
|
ALfloat pos;
|
||||||
alGetSourcef(this->m_source.getIndex(), AL_SEC_OFFSET, &pos ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
alGetSourcef(this->m_source.getIndex(), AL_SEC_OFFSET, &pos ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
void UF_API uf::Audio::setTime( ALfloat 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 } );
|
this->m_source.source("SEC_OFFSET", std::vector<ALfloat>{ pos } );
|
||||||
}
|
}
|
||||||
|
|
||||||
ALfloat UF_API uf::Audio::getPitch() {
|
ALfloat UF_API uf::Audio::getPitch() {
|
||||||
if ( this->playing() ) return 0;
|
if ( !this->initialized() ) return 0;
|
||||||
ALfloat pitch;
|
ALfloat pitch;
|
||||||
alGetSourcef(this->m_source.getIndex(), AL_PITCH, &pitch ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
alGetSourcef(this->m_source.getIndex(), AL_PITCH, &pitch ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
return pitch;
|
return pitch;
|
||||||
}
|
}
|
||||||
void UF_API uf::Audio::setPitch( ALfloat 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 } );
|
this->m_source.source("PITCH", std::vector<ALfloat>{ pitch } );
|
||||||
}
|
}
|
||||||
|
|
||||||
ALfloat UF_API uf::Audio::getGain() {
|
ALfloat UF_API uf::Audio::getGain() {
|
||||||
if ( this->playing() ) return 0;
|
if ( !this->initialized() ) return 0;
|
||||||
ALfloat gain;
|
ALfloat gain;
|
||||||
alGetSourcef(this->m_source.getIndex(), AL_GAIN, &gain ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
alGetSourcef(this->m_source.getIndex(), AL_GAIN, &gain ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
return gain;
|
return gain;
|
||||||
}
|
}
|
||||||
void UF_API uf::Audio::setGain( ALfloat 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 } );
|
this->m_source.source("GAIN", std::vector<ALfloat>{ gain } );
|
||||||
}
|
}
|
||||||
|
|
||||||
ALfloat UF_API uf::Audio::getRolloffFactor() {
|
ALfloat UF_API uf::Audio::getRolloffFactor() {
|
||||||
if ( this->playing() ) return 0;
|
if ( !this->initialized() ) return 0;
|
||||||
ALfloat rolloffFactor;
|
ALfloat rolloffFactor;
|
||||||
alGetSourcef(this->m_source.getIndex(), AL_ROLLOFF_FACTOR, &rolloffFactor ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
alGetSourcef(this->m_source.getIndex(), AL_ROLLOFF_FACTOR, &rolloffFactor ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
return rolloffFactor;
|
return rolloffFactor;
|
||||||
}
|
}
|
||||||
void UF_API uf::Audio::setRolloffFactor( ALfloat 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 } );
|
this->m_source.source("ROLLOFF_FACTOR", std::vector<ALfloat>{ rolloffFactor } );
|
||||||
}
|
}
|
||||||
|
|
||||||
ALfloat UF_API uf::Audio::getMaxDistance() {
|
ALfloat UF_API uf::Audio::getMaxDistance() {
|
||||||
if ( this->playing() ) return 0;
|
if ( !this->initialized() ) return 0;
|
||||||
ALfloat maxDistance;
|
ALfloat maxDistance;
|
||||||
alGetSourcef(this->m_source.getIndex(), AL_MAX_DISTANCE, &maxDistance ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
alGetSourcef(this->m_source.getIndex(), AL_MAX_DISTANCE, &maxDistance ); ext::oal.checkError(__FUNCTION__, __LINE__);
|
||||||
return maxDistance;
|
return maxDistance;
|
||||||
}
|
}
|
||||||
void UF_API uf::Audio::setMaxDistance( ALfloat 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 } );
|
this->m_source.source("MAX_DISTANCE", std::vector<ALfloat>{ maxDistance } );
|
||||||
}
|
}
|
||||||
|
|
||||||
void UF_API uf::Audio::setPosition( const pod::Vector3& position ) {
|
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} );
|
this->m_source.source("POSITION", std::vector<ALfloat>{position.x, position.y, position.z} );
|
||||||
}
|
}
|
||||||
void UF_API uf::Audio::setOrientation( const pod::Quaternion<>& orientation ) {
|
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 ) {
|
void UF_API uf::SoundEmitter::cleanup( bool purge ) {
|
||||||
/*
|
for ( auto& pair : this->m_container ) {
|
||||||
for ( uf::Audio& k : this->m_container ) {
|
if ( !pair.second.playing() ) {
|
||||||
if ( !k.playing() ) this->m_container.erase(k);
|
this->m_container.erase(pair.first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
@ -7,6 +7,19 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <uf/utils/io/iostream.h>
|
#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 ) {
|
std::string UF_API uf::io::filename( const std::string& str ) {
|
||||||
return str.substr( str.find_last_of('/') + 1 );
|
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;
|
std::string thread = name;
|
||||||
if ( current > 0 ) thread += " " + std::to_string(current);
|
if ( current > 0 ) thread += " " + std::to_string(current);
|
||||||
bool exists = uf::thread::has(thread);
|
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 ) {
|
if ( !exists ) {
|
||||||
/*
|
/*
|
||||||
pod.affinity = (current + 1) % threads;
|
pod.affinity = (current + 1) % threads;
|
||||||
@ -66,7 +66,17 @@ pod::Thread& UF_API uf::thread::fetchWorker( const std::string& name ) {
|
|||||||
}
|
}
|
||||||
return pod;
|
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 ) {
|
void UF_API uf::thread::tick( pod::Thread& thread, const std::function<void()>& callback ) {
|
||||||
while ( thread.running ) {
|
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();
|
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
|
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 = [&] {
|
std::function<int()> temps = [&] {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while ( !thread.temps.empty() ) {
|
while ( !thread.temps.empty() ) {
|
||||||
@ -100,17 +111,40 @@ void UF_API uf::thread::process( pod::Thread& thread ) { if ( !uf::thread::has(u
|
|||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( thread.mutex != NULL ) thread.mutex->lock();
|
if ( thread.mutex != NULL ) thread.mutex->lock();
|
||||||
temps();
|
temps();
|
||||||
consts();
|
consts();
|
||||||
if ( thread.mutex != NULL ) thread.mutex->unlock();
|
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 ) {
|
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 ) {
|
if ( thread.mutex != NULL ) {
|
||||||
thread.mutex->lock();
|
thread.mutex->lock();
|
||||||
thread.mutex->unlock();
|
thread.mutex->unlock();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
while ( !thread.temps.empty() );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& UF_API uf::thread::name( const pod::Thread& thread ) {
|
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();
|
float delta = metadata["light"]["fade"]["timer"].asFloat();
|
||||||
delta = std::clamp( delta, 0.f, 1.f );
|
delta = std::clamp( delta, 0.f, 1.f );
|
||||||
if ( metadata["light"]["fade"]["power"].isNumeric() ) {
|
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() ) {
|
if ( metadata["light"]["fade"]["color"].isArray() ) {
|
||||||
pod::Vector3f fadeColor; {
|
pod::Vector3f fadeColor; {
|
||||||
|
@ -271,6 +271,29 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
|||||||
uint32_t maxLights = 32;
|
uint32_t maxLights = 32;
|
||||||
} specializationConstants;
|
} 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(); ++_ ) {
|
for ( size_t _ = 0; _ < blitters.size(); ++_ ) {
|
||||||
auto& blitter = *blitters[_];
|
auto& blitter = *blitters[_];
|
||||||
|
|
||||||
@ -284,7 +307,6 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
|||||||
buffer = (uint8_t*) (void*) userdata;
|
buffer = (uint8_t*) (void*) userdata;
|
||||||
len = userdata.data().len;
|
len = userdata.data().len;
|
||||||
shader = &_;
|
shader = &_;
|
||||||
// specializationConstants = _.specializationConstants.get<SpecializationConstant>();
|
|
||||||
specializationConstants = *((SpecializationConstant*) &_.specializationConstants[0]);
|
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)];
|
UniformDescriptor::Light* lights = (UniformDescriptor::Light*) &buffer[sizeof(UniformDescriptor) - sizeof(UniformDescriptor::Light)];
|
||||||
for ( size_t i = 0; i < specializationConstants.maxLights; ++i ) {
|
for ( size_t i = 0; i < specializationConstants.maxLights; ++i ) {
|
||||||
UniformDescriptor::Light& light = lights[i];
|
UniformDescriptor::Light& light = lights[i];
|
||||||
@ -353,6 +354,10 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
|
|||||||
light.depthBias = 0;
|
light.depthBias = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<VkImage> previousTextures;
|
||||||
|
for ( auto& texture : blitter.material.textures ) {
|
||||||
|
previousTextures.emplace_back(texture.image);
|
||||||
|
}
|
||||||
blitter.material.textures.clear();
|
blitter.material.textures.clear();
|
||||||
|
|
||||||
for ( size_t i = 0; i < specializationConstants.maxLights && i < entities.size(); ++i ) {
|
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;
|
uint8_t i = 0;
|
||||||
for ( auto& attachment : renderTarget.attachments ) {
|
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.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
|
|
||||||
if ( (attachment.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) ) continue;
|
if ( (attachment.layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) ) continue;
|
||||||
auto& texture = blitter.material.textures.emplace_back();
|
auto& texture = blitter.material.textures.emplace_back();
|
||||||
texture.aliasAttachment(attachment);
|
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 );
|
blitter.getPipeline().update( blitter );
|
||||||
|
}
|
||||||
|
}
|
||||||
shader->updateBuffer( (void*) buffer, len, 0, false );
|
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)
|
#define this ((uf::Object*) &self)
|
||||||
void ext::StaticEmitterBehavior::initialize( uf::Object& self ) {
|
void ext::StaticEmitterBehavior::initialize( uf::Object& self ) {
|
||||||
auto& metadata = this->getComponent<uf::Serializer>();
|
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);
|
auto* hud = this->loadChildPointer("/hud.json", true);
|
||||||
metadata["hud"]["uid"] = hud->getUid();
|
metadata["hud"]["uid"] = hud->getUid();
|
||||||
|
// return "true";
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
void ext::StaticEmitterBehavior::tick( uf::Object& self ) {
|
void ext::StaticEmitterBehavior::tick( uf::Object& self ) {
|
||||||
auto& scene = uf::scene::getCurrentScene();
|
auto& scene = uf::scene::getCurrentScene();
|
||||||
|
@ -825,7 +825,7 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
|
|||||||
// graphic.descriptor.indices = 0;
|
// graphic.descriptor.indices = 0;
|
||||||
graphic.initializeGeometry( mesh );
|
graphic.initializeGeometry( mesh );
|
||||||
graphic.getPipeline().update( graphic );
|
graphic.getPipeline().update( graphic );
|
||||||
uf::renderer::rebuild = true;
|
// uf::renderer::rebuild = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
graphic.destroy();
|
graphic.destroy();
|
||||||
|
@ -253,9 +253,8 @@ void EXT_API ext::initialize() {
|
|||||||
uf::renderer::initialize();
|
uf::renderer::initialize();
|
||||||
}
|
}
|
||||||
/* */ {
|
/* */ {
|
||||||
pod::Thread& threadMain = uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false, true );
|
pod::Thread& threadMain = uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false );
|
||||||
// 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 );
|
||||||
pod::Thread& threadPhysics = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true, false );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Discord */ if ( ::config["engine"]["ex"]["discord"]["enabled"].asBool() ) {
|
/* Discord */ if ( ::config["engine"]["ex"]["discord"]["enabled"].asBool() ) {
|
||||||
|
@ -89,20 +89,22 @@ void ext::RayTracingSceneBehavior::tick( uf::Object& self ) {
|
|||||||
alignas(16) pod::Vector4f ambient;
|
alignas(16) pod::Vector4f ambient;
|
||||||
struct {
|
struct {
|
||||||
alignas(8) pod::Vector2f range;
|
alignas(8) pod::Vector2f range;
|
||||||
|
alignas(8) pod::Vector2f padding;
|
||||||
alignas(16) pod::Vector4f color;
|
alignas(16) pod::Vector4f color;
|
||||||
} fog;
|
} fog;
|
||||||
struct Light {
|
struct Light {
|
||||||
alignas(16) pod::Vector4f position;
|
alignas(16) pod::Vector4f position;
|
||||||
alignas(16) pod::Vector4f color;
|
alignas(16) pod::Vector4f color;
|
||||||
alignas(8) pod::Vector2i type;
|
alignas(8) pod::Vector2i type;
|
||||||
|
alignas(8) pod::Vector2i padding;
|
||||||
alignas(16) pod::Matrix4f view;
|
alignas(16) pod::Matrix4f view;
|
||||||
alignas(16) pod::Matrix4f projection;
|
alignas(16) pod::Matrix4f projection;
|
||||||
} lights;
|
} lights;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SpecializationConstant {
|
struct SpecializationConstant {
|
||||||
uint32_t eyes = 2;
|
|
||||||
uint32_t maxLights = 16;
|
uint32_t maxLights = 16;
|
||||||
|
uint32_t eyes = 2;
|
||||||
} specializationConstants;
|
} specializationConstants;
|
||||||
|
|
||||||
auto& shader = renderMode.compute.material.shaders.front();
|
auto& shader = renderMode.compute.material.shaders.front();
|
||||||
|
Loading…
Reference in New Issue
Block a user