Commit for 2020.11.04.7z

This commit is contained in:
mrq 2020-11-04 00:00:00 -06:00
parent 360e921722
commit 2b56261e73
64 changed files with 28965 additions and 325 deletions

169
Makefile
View File

@ -1,117 +1,112 @@
.PHONY: win64
DEFAULT_PREFIX = gcc
include makefiles/win64.$(DEFAULT_PREFIX).make
TARGET_NAME = program
BIN_DIR = ./bin
.PHONY: $(ARCH)-$(PREFIX)
ENGINE_SRC_DIR = ./engine/src
ENGINE_INC_DIR = ./engine/inc
ENGINE_LIB_DIR = ./engine/lib
TARGET_NAME += program
BIN_DIR += ./bin
EXT_SRC_DIR = ./ext
CLIENT_SRC_DIR = ./client
ENGINE_SRC_DIR += ./engine/src
ENGINE_INC_DIR += ./engine/inc
ENGINE_LIB_DIR += ./engine/lib
UF_LIBS =
# EXT_LIBS = -lpng16 -lz -lsfml-main -lsfml-system -lsfml-window -lsfml-graphics
# EXT_LIBS = -lpng16 -lz -lassimp -lsfml-main -lsfml-system -lsfml-window -lsfml-graphics -llua52
# EXT_LIBS = -lpng16 -lz -lassimp -ljsoncpp -lopenal32 -lalut -lvorbis -lvorbisfile -logg -lfreetype
EXT_LIBS =
#FLAGS = -std=c++0x -Wall -g -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENGL -DUF_USE_GLEW -DUF_USE_DISCORD
FLAGS = -fdiagnostics-color=always -Og -std=c++17 -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
#-march=native
LIB_NAME = uf
EXT_LIB_NAME = ext
EXT_SRC_DIR += ./ext
CLIENT_SRC_DIR += ./client
UF_LIBS +=
EXT_LIBS +=
FLAGS += -std=c++17 -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
LIB_NAME += uf
EXT_LIB_NAME += ext
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.101.0/
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.108.0/
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.1.114.0/
VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.141.2/
#VULKAN_WIN64_SDK_PATH = /c/VulkanSDK/1.2.154.0/
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
#VULKAN_SDK_PATH += /c/VulkanSDK/1.1.101.0/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.1.108.0/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.1.114.0/
VULKAN_SDK_PATH += /c/VulkanSDK/1.2.141.2/
#VULKAN_SDK_PATH += /c/VulkanSDK/1.2.154.0/
GLSL_VALIDATOR += $(VULKAN_SDK_PATH)/Bin32/glslangValidator
# Base Engine's DLL
WIN64_INC_DIR = $(ENGINE_INC_DIR)/win64
WIN64_LB_FLAGS = $(ENGINE_LIB_DIR)/win64
WIN64_DEPS = -lgdi32 -lvulkan -lspirv-cross -lpng -lz -ljsoncpp -lopenal -lalut -lvorbis -lvorbisfile -logg -lfreetype -lncursesw -lcurl -ldiscord_game_sdk -lopenvr_api
#WIN64_DEPS = -lvulkan -lncursesw
WIN64_LINKS = $(UF_LIBS) $(EXT_LIBS) $(WIN64_DEPS)
WIN64_FLAGS = $(FLAGS)
INC_DIR += $(ENGINE_INC_DIR)/$(ARCH)/$(PREFIX)
LB_FLAGS += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)
DEPS += -lgdi32 -lvulkan -lspirv-cross -lpng -lz -ljsoncpp -lopenal -lalut -lvorbis -lvorbisfile -logg -lfreetype -lncursesw -lcurl -ldiscord_game_sdk -lopenvr_api -lluajit-5.1
#DEPS += -lvulkan -lncursesw
LINKS += $(UF_LIBS) $(EXT_LIBS) $(DEPS)
#-Wl,-subsystem,windows
WIN64_LIB_DIR = $(ENGINE_LIB_DIR)/win64/
WIN64_INCS = -I$(ENGINE_INC_DIR) -I$(WIN64_INC_DIR) -I$(VULKAN_WIN64_SDK_PATH)/include -I/mingw64/include
WIN64_LIBS = -L$(ENGINE_LIB_DIR) -L$(WIN64_LIB_DIR) -L$(VULKAN_WIN64_SDK_PATH)/Lib -L/mingw64/lib
LIB_DIR += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)
INCS += -I$(ENGINE_INC_DIR) -I$(INC_DIR) -I$(VULKAN_SDK_PATH)/include -I/mingw64/include -I/mingw64/include/luajit-2.1
LIBS += -L$(ENGINE_LIB_DIR) -L$(LIB_DIR) -L$(VULKAN_SDK_PATH)/Lib -L/mingw64/lib
SRCS_WIN64_DLL = $(wildcard $(ENGINE_SRC_DIR)/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(ENGINE_SRC_DIR)/*/*/*/*/*.cpp)
OBJS_WIN64_DLL = $(patsubst %.cpp,%.win64.o,$(SRCS_WIN64_DLL))
BASE_WIN64_DLL = lib$(LIB_NAME)
IM_WIN64_DLL = $(ENGINE_LIB_DIR)/win64/$(BASE_WIN64_DLL).dll.a
EX_WIN64_DLL = $(BIN_DIR)/lib/win64/$(BASE_WIN64_DLL).dll
SRCS_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_DLL += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_DLL))
BASE_DLL += lib$(LIB_NAME)
IM_DLL += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).dll.a
EX_DLL += $(BIN_DIR)/lib/$(ARCH)/$(PREFIX)/$(BASE_DLL).dll
# External Engine's DLL
EXT_WIN64_INC_DIR = $(WIN64_INC_DIR)
EXT_WIN64_LB_FLAGS = $(WIN64_LIB_DIR)
EXT_WIN64_DEPS = -l$(LIB_NAME) $(WIN64_DEPS)
EXT_WIN64_LINKS = $(UF_LIBS) $(EXT_LIBS) $(EXT_WIN64_DEPS)
EXT_WIN64_FLAGS = $(FLAGS)
EXT_INC_DIR += $(INC_DIR)
EXT_LB_FLAGS += $(LIB_DIR)
EXT_DEPS += -l$(LIB_NAME) $(DEPS)
EXT_LINKS += $(UF_LIBS) $(EXT_LIBS) $(EXT_DEPS)
EXT_FLAGS += $(FLAGS)
#-Wl,-subsystem,windows
EXT_WIN64_LIB_DIR = $(ENGINE_LIB_DIR)/win64/
EXT_WIN64_INCS = -I$(ENGINE_INC_DIR) -I$(EXT_WIN64_INC_DIR) -I$(VULKAN_WIN64_SDK_PATH)/include -I/mingw64/include
EXT_WIN64_LIBS = -L$(ENGINE_LIB_DIR) -L$(EXT_WIN64_LIB_DIR) -L$(VULKAN_WIN64_SDK_PATH)/Lib -L/mingw64/lib
EXT_LIB_DIR += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/
EXT_INCS += -I$(ENGINE_INC_DIR) -I$(EXT_INC_DIR) -I$(VULKAN_SDK_PATH)/include -I/mingw64/include
EXT_LIBS += -L$(ENGINE_LIB_DIR) -L$(EXT_LIB_DIR) -L$(VULKAN_SDK_PATH)/Lib -L/mingw64/lib
SRCS_EXT_WIN64_DLL = $(wildcard $(EXT_SRC_DIR)/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*/*.cpp) $(wildcard $(EXT_SRC_DIR)/*/*/*/*/*.cpp)
OBJS_EXT_WIN64_DLL = $(patsubst %.cpp,%.win64.o,$(SRCS_EXT_WIN64_DLL))
BASE_EXT_WIN64_DLL = lib$(EXT_LIB_NAME)
EXT_IM_WIN64_DLL = $(ENGINE_LIB_DIR)/win64/$(BASE_EXT_WIN64_DLL).dll.a
EXT_EX_WIN64_DLL = $(BIN_DIR)/lib/win64/$(BASE_EXT_WIN64_DLL).dll
SRCS_EXT_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_DLL += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS_EXT_DLL))
BASE_EXT_DLL += lib$(EXT_LIB_NAME)
EXT_IM_DLL += $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).dll.a
EXT_EX_DLL += $(BIN_DIR)/lib/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).dll
# Client EXE
SRCS_WIN64 = $(wildcard $(CLIENT_SRC_DIR)/*.cpp) $(wildcard $(CLIENT_SRC_DIR)/*/*.cpp)
OBJS_WIN64 = $(patsubst %.cpp,%.win64.o,$(SRCS_WIN64))
TARGET_WIN64 = $(BIN_DIR)/$(TARGET_NAME).exe
SRCS += $(wildcard $(CLIENT_SRC_DIR)/*.cpp) $(wildcard $(CLIENT_SRC_DIR)/*/*.cpp)
OBJS += $(patsubst %.cpp,%.$(ARCH).$(PREFIX).o,$(SRCS))
TARGET += $(BIN_DIR)/$(TARGET_NAME).$(PREFIX).exe
# Shaders
SRCS_SHADERS = $(wildcard bin/data/shaders/*.glsl)
TARGET_SHADERS = $(patsubst %.glsl,%.spv,$(SRCS_SHADERS))
SRCS_SHADERS += $(wildcard bin/data/shaders/*.glsl)
TARGET_SHADERS += $(patsubst %.glsl,%.spv,$(SRCS_SHADERS))
win64: $(EX_WIN64_DLL) $(EXT_EX_WIN64_DLL) $(TARGET_WIN64) $(TARGET_SHADERS)
$(ARCH): $(EX_DLL) $(EXT_EX_DLL) $(TARGET) $(TARGET_SHADERS)
rm-exe64:
-rm $(EX_WIN64_DLL)
-rm $(EXT_EX_WIN64_DLL)
-rm $(TARGET_WIN64)
-rm $(EX_DLL)
-rm $(EXT_EX_DLL)
-rm $(TARGET)
-rm $(TARGET_SHADERS)
%.win64.o: %.cpp
$(WIN64_CC) $(WIN64_FLAGS) $(WIN64_INCS) -c $< -o $@
%.$(ARCH).$(PREFIX).o: %.cpp
$(CC) $(FLAGS) $(INCS) -c $< -o $@
$(EX_WIN64_DLL): WIN64_FLAGS += -DUF_EXPORTS
$(EX_WIN64_DLL): $(OBJS_WIN64_DLL)
$(WIN64_CC) -shared -o $(EX_WIN64_DLL) -g -Wl,--out-implib=$(IM_WIN64_DLL) $(OBJS_WIN64_DLL) $(WIN64_LIBS) $(WIN64_INCS) $(WIN64_LINKS)
cp $(ENGINE_LIB_DIR)/win64/$(BASE_WIN64_DLL).dll.a $(ENGINE_LIB_DIR)/win64/$(BASE_WIN64_DLL).a
$(EX_DLL): FLAGS += -DUF_EXPORTS
$(EX_DLL): $(OBJS_DLL)
$(CC) -shared -o $(EX_DLL) -g -Wl,--out-implib=$(IM_DLL) $(OBJS_DLL) $(LIBS) $(INCS) $(LINKS)
cp $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).dll.a $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_DLL).a
$(EXT_EX_WIN64_DLL): WIN64_FLAGS += -DEXT_EXPORTS
$(EXT_EX_WIN64_DLL): $(OBJS_EXT_WIN64_DLL)
$(WIN64_CC) -shared -o $(EXT_EX_WIN64_DLL) -g -Wl,--out-implib=$(EXT_IM_WIN64_DLL) $(OBJS_EXT_WIN64_DLL) $(EXT_WIN64_LIBS) $(EXT_WIN64_INCS) $(EXT_WIN64_LINKS)
cp $(ENGINE_LIB_DIR)/win64/$(BASE_EXT_WIN64_DLL).dll.a $(ENGINE_LIB_DIR)/win64/$(BASE_EXT_WIN64_DLL).a
$(EXT_EX_DLL): FLAGS += -DEXT_EXPORTS
$(EXT_EX_DLL): $(OBJS_EXT_DLL)
$(CC) -shared -o $(EXT_EX_DLL) -g -Wl,--out-implib=$(EXT_IM_DLL) $(OBJS_EXT_DLL) $(EXT_LIBS) $(EXT_INCS) $(EXT_LINKS)
cp $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).dll.a $(ENGINE_LIB_DIR)/$(ARCH)/$(PREFIX)/$(BASE_EXT_DLL).a
$(TARGET_WIN64): $(OBJS_WIN64)
$(WIN64_CC) $(WIN64_FLAGS) $(OBJS_WIN64) $(WIN64_LIBS) $(WIN64_INCS) $(WIN64_LINKS) -l$(LIB_NAME) -l$(EXT_LIB_NAME) -o $(TARGET_WIN64)
$(TARGET): $(OBJS)
$(CC) $(FLAGS) $(OBJS) $(LIBS) $(INCS) $(LINKS) -l$(LIB_NAME) -l$(EXT_LIB_NAME) -o $(TARGET)
%.spv: %.glsl
$(WIN64_GLSL_VALIDATOR) -V $< -o $@
$(GLSL_VALIDATOR) -V $< -o $@
clean-win64:
@-rm $(EX_WIN64_DLL)
@-rm $(EXT_EX_WIN64_DLL)
@-rm $(TARGET_WIN64)
clean-$(ARCH):
@-rm $(EX_DLL)
@-rm $(EXT_EX_DLL)
@-rm $(TARGET)
@-rm -f $(OBJS_WIN64_DLL)
@-rm -f $(OBJS_EXT_WIN64_DLL)
@-rm -f $(OBJS_WIN64)
@-rm -f $(OBJS_DLL)
@-rm -f $(OBJS_EXT_DLL)
@-rm -f $(OBJS)
clean-uf-win64:
@-rm $(EX_WIN64_DLL)
@-rm -f $(OBJS_WIN64_DLL)
clean-uf-$(ARCH):
@-rm $(EX_DLL)
@-rm -f $(OBJS_DLL)
clean-ext-win64:
@-rm $(EXT_EX_WIN64_DLL)
@-rm -f $(OBJS_EXT_WIN64_DLL)
clean-ext-$(ARCH):
@-rm $(EXT_EX_DLL)
@-rm -f $(OBJS_EXT_DLL)

View File

@ -164,10 +164,12 @@ float shadowFactor( Light light, uint shadowMap ) {
vec2 uv = positionClip.xy * 0.5 + 0.5;
float bias = light.depthBias;
if ( false ) {
if ( !true ) {
float cosTheta = clamp(dot(normal.eye, normalize(light.position.xyz - position.eye)), 0, 1);
bias = clamp(bias * tan(acos(cosTheta)), 0, 0.01);
}
} else if ( true ) {
bias = max(bias * 10 * (1.0 - dot(normal.eye, normalize(light.position.xyz - position.eye))), bias);
}
float eyeDepth = positionClip.z;
int samples = poissonDisk.length();
@ -212,9 +214,9 @@ float hueDistance(float h1, float h2) {
float diff = abs((h1 - h2));
return min(abs((1.0 - diff)), diff);
}
const float lightnessSteps = 4.0;
const float lightnessSteps = 16.0;
float lightnessStep(float l) {
return floor((0.5 + l * lightnessSteps)) / lightnessSteps;
return floor((0.5 + l * lightnessSteps)) / lightnessSteps;
}
const int indexMatrix16x16[256] = int[](0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255,
128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127,
@ -286,12 +288,13 @@ float dither(float color) {
float closestColor = (color < 0.5) ? 0 : 1;
float secondClosestColor = 1 - closestColor;
float d = 1; // -0.5 - fract(ubo.mode.parameters.w / 8.0);
float scale = 1;
if ( ubo.mode.scalar == 16 ) {
d = indexValue16x16(1);
d = indexValue16x16(scale);
} else if ( ubo.mode.scalar == 8 ) {
d = indexValue8x8(1);
d = indexValue8x8(scale);
} else if ( ubo.mode.scalar == 4 ) {
d = indexValue4x4(1);
d = indexValue4x4(scale);
}
float distance = abs(closestColor - color);
return (distance < d) ? closestColor : secondClosestColor;
@ -314,21 +317,45 @@ void dither1(inout vec3 color) {
} else if ( ubo.mode.scalar == 4 ) {
d = indexValue4x4(scale);
}
float hueDiff = hueDistance(hsl.x, cs[0].x) / hueDistance(cs[1].x, cs[0].x);
float l1 = lightnessStep(max((hsl.z - 0.125), 0.0));
float l2 = lightnessStep(min((hsl.z + 0.124), 1.0));
float lightnessDiff = (hsl.z - l1) / (l2 - l1);
float hueDiff = hueDistance(hsl.x, cs[0].x) / hueDistance(cs[1].x, cs[0].x);
float l1 = lightnessStep(max((hsl.z - 0.125), 0.0));
float l2 = lightnessStep(min((hsl.z + 0.124), 1.0));
float lightnessDiff = (hsl.z - l1) / (l2 - l1);
vec3 resultColor = (hueDiff < d) ? cs[0] : cs[1];
resultColor.z = (lightnessDiff < d) ? l1 : l2;
color = hslToRgb(resultColor);
vec3 resultColor = (hueDiff < d) ? cs[0] : cs[1];
resultColor.z = (lightnessDiff < d) ? l1 : l2;
color = hslToRgb(resultColor);
}
void dither2(inout vec3 color) {
vec3 hsl = rgbToHsl(color);
float d = 1;
float scale = 1;
if ( ubo.mode.scalar == 16 ) {
d = indexValue16x16(scale);
} else if ( ubo.mode.scalar == 8 ) {
d = indexValue8x8(scale);
} else if ( ubo.mode.scalar == 4 ) {
d = indexValue4x4(scale);
}
hsl.z *= d;
/*
float l1 = lightnessStep(max((hsl.z - 0.125), 0.0));
float l2 = lightnessStep(min((hsl.z + 0.124), 1.0));
float lightnessDiff = (hsl.z - l1) / (l2 - l1);
hsl.z = (lightnessDiff < d) ? l1 : l2;
*/
color = hslToRgb(hsl);
}
vec3 dither3() {
vec3 vDither = dot( vec2( 171.0, 231.0 ), inUv.xy + ubo.mode.parameters.w ).xxx;
vDither.rgb = fract( vDither.rgb / vec3( 103.0, 71.0, 97.0 ) ) - vec3( 0.5, 0.5, 0.5 );
return ( vDither.rgb / 255.0 ) * 0.375;
}
float rand2(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453);
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453);
}
float rand3(vec3 co){
return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453);
return fract(sin(dot(co.xyz ,vec3(12.9898,78.233, 37.719))) * 143758.5453);
}
void whitenoise(inout vec3 color) {
float flicker = ubo.mode.parameters.x;
@ -345,27 +372,13 @@ void whitenoise(inout vec3 color) {
void main() {
vec4 albedoSpecular = subpassLoad(samplerAlbedo);
vec3 fragColor = albedoSpecular.rgb * ubo.ambient.rgb;
normal.eye = subpassLoad(samplerNormal).rgb;
/*
position.eye = subpassLoad(samplerPosition).rgb; {
mat4 iView = inverse( ubo.matrices.view[inPushConstantPass] );
vec4 positionWorld = iView * vec4(position.eye, 1);
position.world = positionWorld.xyz;
}
*/
{
mat4 iProj = inverse( ubo.matrices.projection[inPushConstantPass] );
mat4 iView = inverse( ubo.matrices.view[inPushConstantPass] );
float depth = subpassLoad(samplerDepth).r;
if ( false ) {
depth /= 0.00526;
outFragColor.rgb = vec3( 1 - depth );
outFragColor.a = 1;
return;
}
float depth = subpassLoad(samplerDepth).r;
vec4 positionClip = vec4(inUv * 2.0 - 1.0, depth, 1.0);
vec4 positionEye = iProj * positionClip;
positionEye /= positionEye.w;
@ -389,12 +402,14 @@ void main() {
}
phong( light, albedoSpecular, fragColor );
}
fog(fragColor, litFactor);
if ( (ubo.mode.type & (0x1 << 0)) == (0x1 << 0) ) {
dither1(fragColor);
// dither2(fragColor);
fragColor += dither3();
}
if ( (ubo.mode.type & (0x1 << 1)) == (0x1 << 1) ) {
whitenoise(fragColor);
}

View File

@ -164,10 +164,12 @@ float shadowFactor( Light light, uint shadowMap ) {
vec2 uv = positionClip.xy * 0.5 + 0.5;
float bias = light.depthBias;
if ( false ) {
if ( !true ) {
float cosTheta = clamp(dot(normal.eye, normalize(light.position.xyz - position.eye)), 0, 1);
bias = clamp(bias * tan(acos(cosTheta)), 0, 0.01);
}
} else if ( true ) {
bias = max(bias * 10 * (1.0 - dot(normal.eye, normalize(light.position.xyz - position.eye))), bias);
}
float eyeDepth = positionClip.z;
int samples = poissonDisk.length();
@ -323,6 +325,11 @@ void dither1(inout vec3 color) {
resultColor.z = (lightnessDiff < d) ? l1 : l2;
color = hslToRgb(resultColor);
}
vec3 dither2() {
vec3 vDither = dot( vec2( 171.0, 231.0 ), inUv.xy + ubo.mode.parameters.w ).xxx;
vDither.rgb = fract( vDither.rgb / vec3( 103.0, 71.0, 97.0 ) ) - vec3( 0.5, 0.5, 0.5 );
return ( vDither.rgb / 255.0 ) * 0.375;
}
float rand2(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 143758.5453);
@ -370,7 +377,8 @@ void main() {
fog(fragColor, litFactor);
if ( (ubo.mode.type & (0x1 << 0)) == (0x1 << 0) ) {
dither1(fragColor);
//dither1(fragColor);
fragColor += dither2();
}
if ( (ubo.mode.type & (0x1 << 1)) == (0x1 << 1) ) {
whitenoise(fragColor);

View File

@ -20,16 +20,24 @@ layout (binding = 0) uniform UBO {
vec4 color;
} ubo;
layout (location = 0) out vec2 outUv;
layout (location = 0) noperspective out vec2 outUv;
layout (location = 1) out vec4 outColor;
layout (location = 2) out vec3 outNormal;
layout (location = 3) out vec3 outPosition;
layout (location = 4) flat out uint outId;
layout (location = 5) out float affine;
out gl_PerVertex {
vec4 gl_Position;
};
vec4 snap(vec4 vertex, vec2 resolution) {
vec4 snappedPos = vertex;
snappedPos.xyz = vertex.xyz / vertex.w;
snappedPos.xy = floor(resolution * snappedPos.xy) / resolution;
snappedPos.xyz *= vertex.w;
return snappedPos;
}
void main() {
outUv = inUv;
@ -42,4 +50,9 @@ void main() {
outId = inId;
gl_Position = ubo.matrices.projection[PushConstant.pass] * ubo.matrices.view[PushConstant.pass] * ubo.matrices.model * vec4(inPos.xyz, 1.0);
// gl_Position = snap( gl_Position, vec2(320.0, 240.0) );
// gl_Position = snap( gl_Position, vec2(480.0, 270.0) );
// gl_Position = snap( gl_Position, vec2(640.0, 480.0) );
affine = 1;
}

View File

@ -15,6 +15,7 @@ layout (location = 1) in vec4 inColor;
layout (location = 2) in vec3 inNormal;
layout (location = 3) in vec3 inPosition;
layout (location = 4) flat in uint inId;
layout (location = 5) in float inAffine;
layout (location = 0) out vec4 outAlbedoSpecular;
layout (location = 1) out vec4 outNormal;
@ -22,12 +23,12 @@ layout (location = 2) out vec4 outPosition;
void main() {
uint offset = inId;
outAlbedoSpecular = texture(samplerTextures[offset], inUv.xy);
outAlbedoSpecular = texture(samplerTextures[offset], inUv.xy / inAffine);
Map mapped = ubo.map[offset];
if ( offset != mapped.target ) {
outAlbedoSpecular = mix(texture(samplerTextures[offset], inUv.xy), texture(samplerTextures[mapped.target], inUv.xy), mapped.blend);
outAlbedoSpecular = mix(texture(samplerTextures[offset], inUv.xy / inAffine), texture(samplerTextures[mapped.target], inUv.xy / inAffine), mapped.blend);
} else {
outAlbedoSpecular = texture(samplerTextures[offset], inUv.xy);
outAlbedoSpecular = texture(samplerTextures[offset], inUv.xy / inAffine);
}
if ( outAlbedoSpecular.a < 0.001 ) discard;

View File

@ -131,8 +131,11 @@ void client::initialize() {
client::window.setSize(size);
}
// Update viewport
uf::renderer::settings::width = size.x;
uf::renderer::settings::height = size.y;
if ( !client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].isArray() ) {
float scale = client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].isNumeric() ? client::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].asFloat() : 1;
uf::renderer::settings::width = size.x * scale;
uf::renderer::settings::height = size.y * scale;
}
uf::renderer::states::resized = true;
return "true";

View File

@ -1,6 +1,8 @@
#!/bin/bash
PREFIX=gcc
cd bin
cp lib/win64/*.dll .
gdb program.exe
cp lib/win64/$PREFIX/*.dll .
gdb program.$PREFIX.exe
rm *.dll

53
engine/inc/sol/config.hpp Normal file
View File

@ -0,0 +1,53 @@
// The MIT License (MIT)
// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script.
// Generated 2020-10-03 21:34:25.034794 UTC
// This header was generated with sol v3.2.1 (revision 48eea7b5)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_CONFIG_HPP
#define SOL_SINGLE_CONFIG_HPP
// beginning of sol/config.hpp
/* Base, empty configuration file!
To override, place a file in your include paths of the form:
. (your include path here)
| sol (directory, or equivalent)
| config.hpp (your config.hpp file)
So that when sol2 includes the file
#include <sol/config.hpp>
it gives you the configuration values you desire. Configuration values can be
seen in the safety.rst of the doc/src, or at
https://sol2.readthedocs.io/en/latest/safety.html ! You can also pass them through
the build system, or the command line options of your compiler.
*/
// end of sol/config.hpp
#endif // SOL_SINGLE_CONFIG_HPP

828
engine/inc/sol/forward.hpp Normal file
View File

@ -0,0 +1,828 @@
// The MIT License (MIT)
// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script.
// Generated 2020-10-03 21:34:25.022965 UTC
// This header was generated with sol v3.2.1 (revision 48eea7b5)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
#define SOL_SINGLE_INCLUDE_FORWARD_HPP
// beginning of sol/forward.hpp
#ifndef SOL_FORWARD_HPP
#define SOL_FORWARD_HPP
// beginning of sol/version.hpp
#include <sol/config.hpp>
#include <cstdint>
#define SOL_VERSION_MAJOR 3
#define SOL_VERSION_MINOR 5
#define SOL_VERSION_PATCH 0
#define SOL_VERSION_STRING "3.5.0"
#define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH))
#define SOL_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0)
#define SOL_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0)
#define SOL_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3)
#define SOL_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0)
#define SOL_ON |
#define SOL_OFF ^
#define SOL_DEFAULT_ON +
#define SOL_DEFAULT_OFF -
#if defined(_MSC_VER)
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_ON
#elif defined(__clang__)
#define SOL_COMPILER_CLANG_I_ SOL_ON
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#elif defined(__GNUC__)
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_ON
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#else
#define SOL_COMPILER_CLANG_I_ SOL_OFF
#define SOL_COMPILER_GCC_I_ SOL_OFF
#define SOL_COMPILER_EDG_I_ SOL_OFF
#define SOL_COMPILER_VCXX_I_ SOL_OFF
#endif
#if defined(__MINGW32__)
#define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_ON
#else
#define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_OFF
#endif
#if SIZE_MAX <= 0xFFFFULL
#define SOL_PLATFORM_X16_I_ SOL_ON
#define SOL_PLATFORM_X86_I_ SOL_OFF
#define SOL_PLATFORM_X64_I_ SOL_OFF
#elif SIZE_MAX <= 0xFFFFFFFFULL
#define SOL_PLATFORM_X16_I_ SOL_OFF
#define SOL_PLATFORM_X86_I_ SOL_ON
#define SOL_PLATFORM_X64_I_ SOL_OFF
#else
#define SOL_PLATFORM_X16_I_ SOL_OFF
#define SOL_PLATFORM_X86_I_ SOL_OFF
#define SOL_PLATFORM_X64_I_ SOL_ON
#endif
#define SOL_PLATFORM_ARM32_I_ SOL_OFF
#define SOL_PLATFORM_ARM64_I_ SOL_OFF
#if defined(_WIN32)
#define SOL_PLATFORM_WINDOWS_I_ SOL_ON
#else
#define SOL_PLATFORM_WINDOWS_I_ SOL_OFF
#endif
#if defined(__APPLE__)
#define SOL_PLATFORM_APPLE_I_ SOL_ON
#else
#define SOL_PLATFORM_APPLE_I_ SOL_OFF
#endif
#if defined(__unix__)
#define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON
#else
#define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF
#endif
#if defined(__linux__)
#define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON
#else
#define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF
#endif
#define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF
#define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF
#if defined(SOL_IN_DEBUG_DETECTED)
#if SOL_IN_DEBUG_DETECTED != 0
#define SOL_DEBUG_BUILD_I_ SOL_ON
#else
#define SOL_DEBUG_BUILD_I_ SOL_OFF
#endif
#elif !defined(NDEBUG)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && defined(_DEBUG)
#define SOL_DEBUG_BUILD_I_ SOL_ON
#elif (SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)) && !defined(__OPTIMIZE__)
#define SOL_DEBUG_BUILD_I_ SOL_ON
#else
#define SOL_DEBUG_BUILD_I_ SOL_OFF
#endif
#else
#define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF
#endif // We are in a debug mode of some sort
#if defined(SOL_NO_EXCEPTIONS)
#if (SOL_NO_EXCEPTIONS != 0)
#define SOL_EXCEPTIONS_I_ SOL_OFF
#else
#define SOL_EXCEPTIONS_I_ SOL_ON
#endif
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if !defined(_CPPUNWIND)
#define SOL_EXCEPTIONS_I_ SOL_OFF
#else
#define SOL_EXCEPTIONS_I_ SOL_ON
#endif
#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)
#if !defined(__EXCEPTIONS)
#define SOL_EXCEPTIONS_I_ SOL_OFF
#else
#define SOL_EXCEPTIONS_I_ SOL_ON
#endif
#else
#define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON
#endif
#if defined(SOL_NO_RTTI)
#if (SOL_NO_RTTI != 0)
#define SOL_RTTI_I_ SOL_OFF
#else
#define SOL_RTTI_I_ SOL_ON
#endif
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if !defined(_CPPRTTI)
#define SOL_RTTI_I_ SOL_OFF
#else
#define SOL_RTTI_I_ SOL_ON
#endif
#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)
#if !defined(__GXX_RTTI)
#define SOL_RTTI_I_ SOL_OFF
#else
#define SOL_RTTI_I_ SOL_ON
#endif
#else
#define SOL_RTTI_I_ SOL_DEFAULT_ON
#endif
#if defined(SOL_NO_THREAD_LOCAL) && (SOL_NO_THREAD_LOCAL != 0)
#define SOL_USE_THREAD_LOCAL_I_ SOL_OFF
#else
#define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON
#endif // thread_local keyword is bjorked on some platforms
#if defined(SOL_ALL_SAFETIES_ON) && (SOL_ALL_SAFETIES_ON != 0)
#define SOL_ALL_SAFETIES_ON_I_ SOL_ON
#else
#define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF
#endif
#if defined(SOL_SAFE_GETTER) && (SOL_SAFE_GETTER != 0)
#define SOL_SAFE_GETTER_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_SAFE_GETTER_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON
#else
#define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF
#endif
#endif
#if defined(SOL_SAFE_USERTYPE) && (SOL_SAFE_USERTYPE != 0)
#define SOL_SAFE_USERTYPE_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_SAFE_USERTYPE_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON
#else
#define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF
#endif
#endif
#if defined(SOL_SAFE_REFERENCES) && (SOL_SAFE_REFERENCES != 0)
#define SOL_SAFE_REFERENCES_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_SAFE_REFERENCES_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON
#else
#define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF
#endif
#endif
#if (defined(SOL_SAFE_FUNCTIONS) && (SOL_SAFE_FUNCTIONS != 0)) \
|| (defined(SOL_SAFE_FUNCTION_OBJECTS) && (SOL_SAFE_FUNCTION_OBJECTS != 0))
#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON
#else
#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF
#endif
#endif
#if defined(SOL_SAFE_FUNCTION_CALLS) && (SOL_SAFE_FUNCTION_CALLS != 0)
#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON
#else
#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF
#endif
#endif
#if defined(SOL_SAFE_PROXIES) && (SOL_SAFE_PROXIES != 0)
#define SOL_SAFE_PROXIES_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_SAFE_PROXIES_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON
#else
#define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF
#endif
#endif
#if defined(SOL_SAFE_NUMERICS) && (SOL_SAFE_NUMERICS != 0)
#define SOL_SAFE_NUMERICS_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_SAFE_NUMERICS_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON
#else
#define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF
#endif
#endif
#if defined(SOL_SAFE_STACK_CHECK) && (SOL_SAFE_STACK_CHECK != 0)
#define SOL_SAFE_STACK_CHECK_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_SAFE_STACK_CHECK_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON
#else
#define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF
#endif
#endif
#if (defined(SOL_NO_CHECK_NUMBER_PRECISION) && (SOL_NO_CHECK_NUMBER_PRECISION != 0)) \
|| (defined(SOL_NO_CHECKING_NUMBER_PRECISION) && (SOL_NO_CHECKING_NUMBER_PRECISION != 0))
#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
#elif SOL_IS_ON(SOL_SAFE_NUMERICS_I_)
#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON
#else
#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF
#endif
#endif
#if defined(SOL_STRINGS_ARE_NUMBERS)
#if (SOL_STRINGS_ARE_NUMBERS != 0)
#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON
#else
#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF
#endif
#else
#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF
#endif
#if defined(SOL_ENABLE_INTEROP) && (SOL_ENABLE_INTEROP != 0) \
|| defined(SOL_USE_INTEROP) && (SOL_USE_INTEROP != 0)
#define SOL_USE_INTEROP_I_ SOL_ON
#else
#define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF
#endif
#if defined(SOL_NO_NIL)
#if (SOL_NO_NIL != 0)
#define SOL_NIL_I_ SOL_OFF
#else
#define SOL_NIL_I_ SOL_ON
#endif
#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil)
#define SOL_NIL_I_ SOL_DEFAULT_OFF
#else
#define SOL_NIL_I_ SOL_DEFAULT_ON
#endif
#if defined(SOL_USERTYPE_TYPE_BINDING_INFO)
#if (SOL_USERTYPE_TYPE_BINDING_INFO != 0)
#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON
#else
#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF
#endif
#else
#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON
#endif // We should generate a my_type.__type table with lots of class information for usertypes
#if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT)
#if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0)
#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON
#else
#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF
#endif
#elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES)
#if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0)
#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON
#else
#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF
#endif
#else
#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON
#endif // make is_automagical on/off by default
#if defined(SOL_STD_VARIANT)
#if (SOL_STD_VARIANT != 0)
#define SOL_STD_VARIANT_I_ SOL_ON
#else
#define SOL_STD_VARIANT_I_ SOL_OFF
#endif
#else
#if SOL_IS_ON(SOL_COMPILER_CLANG_I_) && SOL_IS_ON(SOL_PLATFORM_APPLE_I_)
#if defined(__has_include)
#if __has_include(<variant>)
#define SOL_STD_VARIANT_I_ SOL_ON
#else
#define SOL_STD_VARIANT_I_ SOL_OFF
#endif
#else
#define SOL_STD_VARIANT_I_ SOL_OFF
#endif
#else
#define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON
#endif
#endif // make is_automagical on/off by default
#if defined(SOL_NOEXCEPT_FUNCTION_TYPE)
#if (SOL_NOEXCEPT_FUNCTION_TYPE != 0)
#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON
#else
#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF
#endif
#else
#if defined(__cpp_noexcept_function_type)
#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L))
// There is a bug in the VC++ compiler??
// on /std:c++latest under x86 conditions (VS 15.5.2),
// compiler errors are tossed for noexcept markings being on function types
// that are identical in every other way to their non-noexcept marked types function types...
// VS 2019: There is absolutely a bug.
#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF
#else
#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON
#endif
#endif // noexcept is part of a function's type
#if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && SOL_STACK_STRING_OPTIMIZATION_SIZE > 0
#define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE
#else
#define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024
#endif
#if defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0
#define SOL_ID_SIZE_I_ SOL_ID_SIZE
#else
#define SOL_ID_SIZE_I_ 512
#endif
#if defined(LUA_IDSIZE) && LUA_IDSIZE > 0
#define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE
#elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0
#define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE
#else
#define SOL_FILE_ID_SIZE_I_ 2048
#endif
#if defined(SOL_PRINT_ERRORS)
#if (SOL_PRINT_ERRORS != 0)
#define SOL_PRINT_ERRORS_I_ SOL_ON
#else
#define SOL_PRINT_ERRORS_I_ SOL_OFF
#endif
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_PRINT_ERRORS_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON
#else
#define SOL_PRINT_ERRORS_I_ SOL_OFF
#endif
#endif
#if defined(SOL_DEFAULT_PASS_ON_ERROR) && (SOL_DEFAULT_PASS_ON_ERROR != 0)
#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON
#else
#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_)
#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON
#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_ON
#else
#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF
#endif
#endif
#if defined(SOL_USING_CXX_LUA)
#if (SOL_USING_CXX_LUA != 0)
#define SOL_USE_CXX_LUA_I_ SOL_ON
#else
#define SOL_USE_CXX_LUA_I_ SOL_OFF
#endif
#elif defined(SOL_USE_CXX_LUA)
#if (SOL_USE_CXX_LUA != 0)
#define SOL_USE_CXX_LUA_I_ SOL_ON
#else
#define SOL_USE_CXX_LUA_I_ SOL_OFF
#endif
#else
#define SOL_USE_CXX_LUA_I_ SOL_OFF
#endif
#if defined(SOL_USING_CXX_LUAJIT)
#if (SOL_USING_CXX_LUA != 0)
#define SOL_USE_CXX_LUAJIT_I_ SOL_ON
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
#endif
#elif defined(SOL_USE_CXX_LUAJIT)
#if (SOL_USE_CXX_LUA != 0)
#define SOL_USE_CXX_LUAJIT_I_ SOL_ON
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
#endif
#else
#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF
#endif
#if defined(SOL_NO_LUA_HPP)
#if (SOL_NO_LUA_HPP != 0)
#define SOL_USE_LUA_HPP_I_ SOL_OFF
#else
#define SOL_USE_LUA_HPP_I_ SOL_ON
#endif
#elif defined(SOL_USING_CXX_LUA)
#define SOL_USE_LUA_HPP_I_ SOL_OFF
#elif defined(__has_include)
#if __has_include(<lua.hpp>)
#define SOL_USE_LUA_HPP_I_ SOL_ON
#else
#define SOL_USE_LUA_HPP_I_ SOL_OFF
#endif
#else
#define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON
#endif
#if defined(SOL_CONTAINERS_START)
#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START
#elif defined(SOL_CONTAINERS_START_INDEX)
#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX
#elif defined(SOL_CONTAINER_START_INDEX)
#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX
#else
#define SOL_CONTAINER_START_INDEX_I_ 1
#endif
#if defined (SOL_NO_MEMORY_ALIGNMENT)
#if (SOL_NO_MEMORY_ALIGNMENT != 0)
#define SOL_ALIGN_MEMORY_I_ SOL_OFF
#else
#define SOL_ALIGN_MEMORY_I_ SOL_ON
#endif
#else
#define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON
#endif
#if defined(SOL_USE_BOOST)
#if (SOL_USE_BOOST != 0)
#define SOL_USE_BOOST_I_ SOL_ON
#else
#define SOL_USE_BOOST_I_ SOL_OFF
#endif
#else
#define SOL_USE_BOOST_I_ SOL_OFF
#endif
#if defined(SOL_USE_UNSAFE_BASE_LOOKUP)
#if (SOL_USE_UNSAFE_BASE_LOOKUP != 0)
#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON
#else
#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF
#endif
#else
#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF
#endif
#if defined(SOL_INSIDE_UNREAL)
#if (SOL_INSIDE_UNREAL != 0)
#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON
#else
#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF
#endif
#else
#if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER)
#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON
#else
#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF
#endif
#endif
#if defined(SOL_NO_COMPAT)
#if (SOL_NO_COMPAT != 0)
#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF
#else
#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON
#endif
#else
#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON
#endif
#if defined(SOL_GET_FUNCTION_POINTER_UNSAFE)
#if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0)
#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON
#else
#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF
#endif
#else
#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF
#endif
#if SOL_IS_ON(SOL_COMPILER_FRONTEND_MINGW_I_) && defined(__GNUC__) && (__GNUC__ < 6)
// MinGW is off its rocker in some places...
#define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON
#else
#define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF
#endif
// end of sol/version.hpp
#include <utility>
#include <type_traits>
#include <string_view>
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
struct lua_State;
#else
extern "C" {
struct lua_State;
}
#endif // C++ Mangling for Lua vs. Not
namespace sol {
enum class type;
class stateless_reference;
template <bool b>
class basic_reference;
using reference = basic_reference<false>;
using main_reference = basic_reference<true>;
class stateless_stack_reference;
class stack_reference;
template <typename A>
class basic_bytecode;
struct lua_value;
struct proxy_base_tag;
template <typename>
struct proxy_base;
template <typename, typename>
struct table_proxy;
template <bool, typename>
class basic_table_core;
template <bool b>
using table_core = basic_table_core<b, reference>;
template <bool b>
using main_table_core = basic_table_core<b, main_reference>;
template <bool b>
using stack_table_core = basic_table_core<b, stack_reference>;
template <typename base_type>
using basic_table = basic_table_core<false, base_type>;
using table = table_core<false>;
using global_table = table_core<true>;
using main_table = main_table_core<false>;
using main_global_table = main_table_core<true>;
using stack_table = stack_table_core<false>;
using stack_global_table = stack_table_core<true>;
template <typename>
struct basic_lua_table;
using lua_table = basic_lua_table<reference>;
using stack_lua_table = basic_lua_table<stack_reference>;
template <typename T, typename base_type>
class basic_usertype;
template <typename T>
using usertype = basic_usertype<T, reference>;
template <typename T>
using stack_usertype = basic_usertype<T, stack_reference>;
template <typename base_type>
class basic_metatable;
using metatable = basic_metatable<reference>;
using stack_metatable = basic_metatable<stack_reference>;
template <typename base_t>
struct basic_environment;
using environment = basic_environment<reference>;
using main_environment = basic_environment<main_reference>;
using stack_environment = basic_environment<stack_reference>;
template <typename T, bool>
class basic_function;
template <typename T, bool, typename H>
class basic_protected_function;
using unsafe_function = basic_function<reference, false>;
using safe_function = basic_protected_function<reference, false, reference>;
using main_unsafe_function = basic_function<main_reference, false>;
using main_safe_function = basic_protected_function<main_reference, false, reference>;
using stack_unsafe_function = basic_function<stack_reference, false>;
using stack_safe_function = basic_protected_function<stack_reference, false, reference>;
using stack_aligned_unsafe_function = basic_function<stack_reference, true>;
using stack_aligned_safe_function = basic_protected_function<stack_reference, true, reference>;
using protected_function = safe_function;
using main_protected_function = main_safe_function;
using stack_protected_function = stack_safe_function;
using stack_aligned_protected_function = stack_aligned_safe_function;
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_)
using function = protected_function;
using main_function = main_protected_function;
using stack_function = stack_protected_function;
using stack_aligned_function = stack_aligned_safe_function;
#else
using function = unsafe_function;
using main_function = main_unsafe_function;
using stack_function = stack_unsafe_function;
using stack_aligned_function = stack_aligned_unsafe_function;
#endif
using stack_aligned_stack_handler_function = basic_protected_function<stack_reference, true, stack_reference>;
struct unsafe_function_result;
struct protected_function_result;
using safe_function_result = protected_function_result;
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_)
using function_result = safe_function_result;
#else
using function_result = unsafe_function_result;
#endif
template <typename base_t>
class basic_object_base;
template <typename base_t>
class basic_object;
template <typename base_t>
class basic_userdata;
template <typename base_t>
class basic_lightuserdata;
template <typename base_t>
class basic_coroutine;
template <typename base_t>
class basic_thread;
using object = basic_object<reference>;
using userdata = basic_userdata<reference>;
using lightuserdata = basic_lightuserdata<reference>;
using thread = basic_thread<reference>;
using coroutine = basic_coroutine<reference>;
using main_object = basic_object<main_reference>;
using main_userdata = basic_userdata<main_reference>;
using main_lightuserdata = basic_lightuserdata<main_reference>;
using main_coroutine = basic_coroutine<main_reference>;
using stack_object = basic_object<stack_reference>;
using stack_userdata = basic_userdata<stack_reference>;
using stack_lightuserdata = basic_lightuserdata<stack_reference>;
using stack_thread = basic_thread<stack_reference>;
using stack_coroutine = basic_coroutine<stack_reference>;
struct stack_proxy_base;
struct stack_proxy;
struct variadic_args;
struct variadic_results;
struct stack_count;
struct this_state;
struct this_main_state;
struct this_environment;
class state_view;
class state;
template <typename T>
struct as_table_t;
template <typename T>
struct as_container_t;
template <typename T>
struct nested;
template <typename T>
struct light;
template <typename T>
struct user;
template <typename T>
struct as_args_t;
template <typename T>
struct protect_t;
template <typename F, typename... Policies>
struct policy_wrapper;
template <typename T>
struct usertype_traits;
template <typename T>
struct unique_usertype_traits;
template <typename... Args>
struct types {
typedef std::make_index_sequence<sizeof...(Args)> indices;
static constexpr std::size_t size() {
return sizeof...(Args);
}
};
template <typename T>
struct derive : std::false_type {
typedef types<> type;
};
template <typename T>
struct base : std::false_type {
typedef types<> type;
};
template <typename T>
struct weak_derive {
static bool value;
};
template <typename T>
bool weak_derive<T>::value = false;
namespace stack {
struct record;
}
#if SOL_IS_OFF(SOL_USE_BOOST_I_)
template <class T>
class optional;
template <class T>
class optional<T&>;
#endif
using check_handler_type = int(lua_State*, int, type, type, const char*);
} // namespace sol
#define SOL_BASE_CLASSES(T, ...) \
namespace sol { \
template <> \
struct base<T> : std::true_type { \
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
#define SOL_DERIVED_CLASSES(T, ...) \
namespace sol { \
template <> \
struct derive<T> : std::true_type { \
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
#endif // SOL_FORWARD_HPP
// end of sol/forward.hpp
#endif // SOL_SINGLE_INCLUDE_FORWARD_HPP

26674
engine/inc/sol/sol.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -70,14 +70,6 @@ namespace uf {
this->removeBehavior(pod::Behavior{
.type = getType<T>()
});
/*
auto it = this->m_behaviors.begin();
while ( it != this->m_behaviors.end() ) {
if ( (it++)->type == getType<T>() ) break;
}
if ( it != this->m_behaviors.end() )
this->m_behaviors.erase(it);
*/
}
};

View File

@ -1,7 +1,7 @@
template<typename T=uf::Object> T& uf::Entity::as() {
template<typename T> T& uf::Entity::as() {
return *((T*) this);
}
template<typename T=uf::Object> const T& uf::Entity::as() const {
template<typename T> const T& uf::Entity::as() const {
return *((T*) this);
}
template<typename T> T& uf::Entity::getParent() {

View File

@ -0,0 +1,16 @@
#pragma once
#include <uf/config.h>
#include <uf/engine/entity/entity.h>
#include <uf/engine/scene/scene.h>
namespace uf {
class UF_API LuaBehavior {
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& );
};
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <uf/config.h>
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
namespace pod {
struct UF_API LuaScript {
std::string filename;
std::string header;
sol::environment env;
};
}
namespace ext {
namespace lua {
extern UF_API sol::state state;
extern UF_API std::string main;
void UF_API initialize();
void UF_API terminate();
bool UF_API run( const std::string&, bool = true );
pod::LuaScript UF_API script( const std::string& );
bool UF_API run( const pod::LuaScript& );
}
}
#include "lua.inl"

View File

@ -0,0 +1,14 @@
#define POD_LUA_REGISTER_USERTYPE_BEGIN(x)\
state.new_usertype<pod::x>(#x,
#define UF_LUA_REGISTER_USERTYPE_BEGIN(x)\
state.new_usertype<uf::x>(#x,
#define EXT_LUA_REGISTER_USERTYPE_BEGIN(x)\
state.new_usertype<ext::x>(#x,
#define POD_LUA_REGISTER_USERTYPE_MEMBER(x, y) #y, &pod::x::y
#define UF_LUA_REGISTER_USERTYPE_MEMBER(x, y) #y, &uf::x::y
#define EXT_LUA_REGISTER_USERTYPE_MEMBER(x, y) #y, &ext::x::y
#define UF_LUA_REGISTER_USERTYPE_END(x) );
#define POD_LUA_REGISTER_USERTYPE_END(x) UF_LUA_REGISTER_USERTYPE_END(x)
#define EXT_LUA_REGISTER_USERTYPE_END(x) UF_LUA_REGISTER_USERTYPE_END(x)

View File

@ -22,7 +22,7 @@ namespace ext {
std::thread::id mostRecentCommandPoolId;
std::unordered_map<std::thread::id, commands_container_t> commands;
// virtual ~RenderMode();
virtual ~RenderMode();
// RAII
virtual std::string getType() const;
const std::string& getName( bool = false ) const;

View File

@ -0,0 +1,20 @@
#pragma once
#include <uf/ext/vulkan/rendermode.h>
#include <uf/ext/vulkan/graphic.h>
namespace ext {
namespace vulkan {
struct UF_API MultiviewStereoscopicDeferredRenderMode : public ext::vulkan::RenderMode {
ext::vulkan::Graphic blitter;
// RAII
virtual std::string getType() const;
virtual void createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics );
virtual void initialize( Device& device );
virtual void tick();
virtual void destroy();
};
}
}

View File

@ -36,6 +36,7 @@ namespace ext {
VkRenderPass renderPass = VK_NULL_HANDLE;
std::vector<VkFramebuffer> framebuffers;
uint32_t width = 0, height = 0;
uint8_t multiviews = 1;
// RAII
void initialize( Device& device );
void destroy();

View File

@ -47,11 +47,16 @@ namespace ext {
extern UF_API std::vector<std::string> requestedDeviceExtensions;
extern UF_API std::vector<std::string> requestedInstanceExtensions;
extern UF_API VkFilter swapchainUpscaleFilter;
namespace experimental {
extern UF_API bool rebuildOnTickBegin;
extern UF_API bool waitOnRenderEnd;
extern UF_API bool individualPipelines;
extern UF_API bool multithreadedCommandRecording;
extern UF_API bool deferredReconstructPosition;
extern UF_API bool deferredAliasOutputToSwapchain;
extern UF_API bool multiview;
}
}
namespace states {

View File

@ -6,6 +6,7 @@
#include <uf/ext/vulkan/rendermodes/deferred.h>
#include <uf/ext/vulkan/rendermodes/compute.h>
#include <uf/ext/vulkan/rendermodes/stereoscopic_deferred.h>
#include <uf/ext/vulkan/rendermodes/multiview_stereoscopic_deferred.h>
#include <uf/ext/vulkan/rendertarget.h>
namespace spec {

View File

@ -22,6 +22,6 @@ namespace uf {
virtual std::string type() const;
virtual pod::Vector3* expand() const;
virtual pod::Vector3 support( const pod::Vector3& ) const;
virtual pod::Collider::Manifold intersects( const uf::BoundingBox& ) const;
pod::Collider::Manifold intersects( const uf::BoundingBox& ) const;
};
}

View File

@ -78,7 +78,7 @@ namespace pod {
virtual std::string type() const;
virtual pod::Vector3* expand() const = 0;
virtual pod::Vector3 support( const pod::Vector3& ) const = 0;
virtual pod::Collider::Manifold intersects( const pod::Collider& ) const;
pod::Collider::Manifold intersects( const pod::Collider& ) const;
pod::Vector3f getPosition() const;
pod::Transform<>& getTransform();

View File

@ -19,6 +19,6 @@ namespace uf {
virtual std::string type() const;
virtual pod::Vector3* expand() const;
virtual pod::Vector3 support( const pod::Vector3& ) const;
virtual pod::Collider::Manifold intersects( const uf::SphereCollider& ) const;
pod::Collider::Manifold intersects( const uf::SphereCollider& ) const;
};
}

View File

@ -3,6 +3,8 @@
// Equality checking
template<typename T>
pod::Vector1t<T> /*UF_API*/ uf::vector::create( T x ) { pod::Vector1t<T> vec; vec.x = x; return vec; }
template<typename T>
pod::Vector2t<T> /*UF_API*/ uf::vector::create( T x, T y ) { pod::Vector2t<T> vec; vec.x = x, vec.y = y; return vec; }
template<typename T>
pod::Vector3t<T> /*UF_API*/ uf::vector::create( T x, T y, T z ) { pod::Vector3t<T> vec; vec.x = x, vec.y = y, vec.z = z; return vec; }

View File

@ -163,7 +163,7 @@ const T& pod::Vector<T,1>::operator[](std::size_t i) const {
// Arithmetic
template<typename T> // Negation
inline pod::Vector<T,1> pod::Vector<T,1>::operator()() const {
return uf::vector::create(0,0);
return uf::vector::create<T>(0);
}
template<typename T> // Negation
inline pod::Vector<T,1> pod::Vector<T,1>::operator-() const {
@ -254,7 +254,7 @@ const T& pod::Vector<T,2>::operator[](std::size_t i) const {
// Arithmetic
template<typename T> // Negation
inline pod::Vector<T,2> pod::Vector<T,2>::operator()() const {
return uf::vector::create(0,0);
return uf::vector::create<T>(0,0);
}
template<typename T> // Negation
inline pod::Vector<T,2> pod::Vector<T,2>::operator-() const {
@ -346,7 +346,7 @@ const T& pod::Vector<T,3>::operator[](std::size_t i) const {
// Arithmetic
template<typename T> // Negation
inline pod::Vector<T,3> pod::Vector<T,3>::operator()() const {
return uf::vector::create(0,0,0);
return uf::vector::create<T>(0,0,0);
}
template<typename T> // Negation
inline pod::Vector<T,3> pod::Vector<T,3>::operator-() const {
@ -410,19 +410,19 @@ inline bool pod::Vector<T,3>::operator!=( const pod::Vector<T,3>& vector ) const
}
template<typename T> // Equality check between two vectors (less than)
inline bool pod::Vector<T,3>::operator<( const pod::Vector<T,3>& vector ) const {
return uf::vector::compareTo(vector) < 0;
return uf::vector::compareTo(*this, vector) < 0;
}
template<typename T> // Equality check between two vectors (less than or equals)
inline bool pod::Vector<T,3>::operator<=( const pod::Vector<T,3>& vector ) const {
return uf::vector::compareTo(vector) <= 0;
return uf::vector::compareTo(*this, vector) <= 0;
}
template<typename T> // Equality check between two vectors (greater than)
inline bool pod::Vector<T,3>::operator>( const pod::Vector<T,3>& vector ) const {
return uf::vector::compareTo(vector) > 0;
return uf::vector::compareTo(*this, vector) > 0;
}
template<typename T> // Equality check between two vectors (greater than or equals)
inline bool pod::Vector<T,3>::operator>=( const pod::Vector<T,3>& vector ) const {
return uf::vector::compareTo(vector) >= 0;
return uf::vector::compareTo(*this, vector) >= 0;
}
//
template<typename T>
@ -438,7 +438,7 @@ const T& pod::Vector<T,4>::operator[](std::size_t i) const {
// Arithmetic
template<typename T> // Negation
inline pod::Vector<T,4> pod::Vector<T,4>::operator()() const {
return uf::vector::create(0,0,0,1);
return uf::vector::create<T>(0,0,0,1);
}
template<typename T> // Negation
inline pod::Vector<T,4> pod::Vector<T,4>::operator-() const {
@ -502,19 +502,19 @@ inline bool pod::Vector<T,4>::operator!=( const pod::Vector<T,4>& vector ) const
}
template<typename T> // Equality check between two vectors (less than)
inline bool pod::Vector<T,4>::operator<( const pod::Vector<T,4>& vector ) const {
return uf::vector::compareTo(vector) < 0;
return uf::vector::compareTo(*this, vector) < 0;
}
template<typename T> // Equality check between two vectors (less than or equals)
inline bool pod::Vector<T,4>::operator<=( const pod::Vector<T,4>& vector ) const {
return uf::vector::compareTo(vector) <= 0;
return uf::vector::compareTo(*this, vector) <= 0;
}
template<typename T> // Equality check between two vectors (greater than)
inline bool pod::Vector<T,4>::operator>( const pod::Vector<T,4>& vector ) const {
return uf::vector::compareTo(vector) > 0;
return uf::vector::compareTo(*this, vector) > 0;
}
template<typename T> // Equality check between two vectors (greater than or equals)
inline bool pod::Vector<T,4>::operator>=( const pod::Vector<T,4>& vector ) const {
return uf::vector::compareTo(vector) >= 0;
return uf::vector::compareTo(*this, vector) >= 0;
}
//
namespace uf {

View File

@ -6,6 +6,7 @@
#include <uf/ext/vulkan/rendermodes/deferred.h>
#include <uf/ext/vulkan/rendermodes/compute.h>
#include <uf/ext/vulkan/rendermodes/stereoscopic_deferred.h>
#include <uf/ext/vulkan/rendermodes/multiview_stereoscopic_deferred.h>
#include <uf/ext/vulkan/rendermodes/rendertarget.h>
namespace uf {

View File

@ -15,5 +15,6 @@ namespace uf {
std::vector<uint8_t> UF_API readAsBuffer( const std::string& );
bool UF_API exists( const std::string& );
size_t UF_API mtime( const std::string& );
std::string UF_API resolveURI( const std::string&, const std::string& = "" );
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -11,6 +11,7 @@
#include <uf/utils/serialize/serializer.h>
#include <uf/utils/string/ext.h>
#include <uf/utils/thread/thread.h>
#include <uf/ext/lua/lua.h>
#include <uf/ext/gltf/gltf.h>
#include <mutex>
@ -43,34 +44,6 @@ namespace {
std::string type;
};
std::queue<Job> jobs;
/*
uint64_t queueJob( const std::string& uri, const std::string& callback ) {
mutex.lock();
uint64_t id = ++uid;
jobs.push({
id, uri, callback
});
mutex.unlock();
return id;
}
std::unordered_map<uint64_t, Job> jobs;
Job getJob( uint64_t id ){
mutex.lock();
Job job = jobs[id];
jobs.erase(id);
mutex.unlock();
return job;
}
uint64_t queueJob( const std::string& uri, const std::string& callback ) {
mutex.lock();
uint64_t id = ++uid;
jobs[id] = {
id, uri, callback
};
mutex.unlock();
return id;
}
*/
}
uf::Entity uf::Asset::masterAssetLoader;
@ -87,7 +60,6 @@ void uf::Asset::processQueue() {
continue;
}
std::string filename = type == "cache" ? this->cache(uri) : this->load(uri);
// uf::iostream << "Parsed `" + filename + "` (" + type + "). Callback: " + callback << "\n";
if ( callback != "" ) {
uf::Serializer payload;
payload["filename"] = filename;
@ -100,47 +72,11 @@ void uf::Asset::cache( const std::string& uri, const std::string& callback ) {
mutex.lock();
jobs.push({ uri, callback, "cache" });
mutex.unlock();
/*
uint64_t id = queueJob(uri, callback);
std::cout << "Queued job: " + std::to_string(id) + ": " + callback + " " + uri << std::endl;
uf::thread::add( uf::thread::get("Aux"), [&]() -> int {
auto job = getJob(id);
std::string uri = job.uri;
std::string callback = job.callback;
if ( uri == "" || callback == "" || id == 0 ) {
std::cout << "Failed job: " << id << std::endl;
return 0;
}
std::string filename = this->cache(uri);
if ( callback != "" ) {
uf::Serializer payload;
payload["filename"] = filename;
uf::hooks.call(callback, payload);
}
return 0;}, true );
*/
}
void uf::Asset::load( const std::string& uri, const std::string& callback ) {
mutex.lock();
jobs.push({ uri, callback, "load" });
mutex.unlock();
/*
uf::thread::add( uf::thread::get("Aux"), [&]() -> int {
auto job = getJob(id);
std::string uri = job.uri;
std::string callback = job.callback;
if ( uri == "" || callback == "" || id == 0 ) {
std::cout << "Failed job: " << id << std::endl;
return 0;
}
std::string filename = this->load(uri);
if ( callback != "" ) {
uf::Serializer payload;
payload["filename"] = filename;
uf::hooks.call(callback, payload);
}
return 0;}, true );
*/
}
std::string uf::Asset::cache( const std::string& uri ) {
std::string filename = uri;
@ -195,6 +131,9 @@ std::string uf::Asset::load( const std::string& uri ) {
} else if ( extension == "json" ) {
UF_ASSET_REGISTER(uf::Serializer)
asset.readFromFile(filename);
} else if ( extension == "lua" ) {
UF_ASSET_REGISTER(pod::LuaScript)
asset = ext::lua::script( filename );
} else if ( extension == "gltf" || extension == "glb" ) {
UF_ASSET_REGISTER(uf::Object*)
uint8_t LOAD_FLAGS = 0;

View File

@ -45,7 +45,7 @@ void uf::ObjectBehavior::initialize( uf::Object& self ) {
this->addHook( "asset:QueueLoad.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
std::string callback = "asset:FinishedLoad." + std::to_string(this->getUid());
std::string callback = this->formatHookName("asset:FinishedLoad.%UID%");
if ( json["single threaded"].asBool() ) {
assetLoader.load( filename );
this->queueHook( callback, event );

View File

@ -0,0 +1,46 @@
#include <uf/engine/object/behaviors/lua.h>
#include <uf/engine/object/object.h>
#include <uf/engine/asset/asset.h>
#include <uf/engine/scene/scene.h>
#include <uf/utils/time/time.h>
#include <uf/utils/math/transform.h>
#include <uf/utils/math/physics.h>
#include <uf/utils/graphic/graphic.h>
#include <uf/utils/camera/camera.h>
#include <uf/utils/graphic/mesh.h>
#include <uf/engine/asset/asset.h>
#include <uf/ext/lua/lua.h>
UF_BEHAVIOR_REGISTER_CPP(LuaBehavior)
#define this (&self)
void uf::LuaBehavior::initialize( uf::Object& self ) {
this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
if ( uf::io::extension(filename) != "lua" ) return "false";
uf::Scene& scene = uf::scene::getCurrentScene();
uf::Asset& assetLoader = scene.getComponent<uf::Asset>();
const pod::LuaScript* assetPointer = NULL;
try { assetPointer = &assetLoader.get<pod::LuaScript>(filename); } catch ( ... ) {}
if ( !assetPointer ) return "false";
pod::LuaScript script = *assetPointer;
script.header = "local ent = entities.get("+ std::to_string((uint) this->getUid()) +")";
ext::lua::run( script );
return "true";
});
}
void uf::LuaBehavior::destroy( uf::Object& self ) {
}
void uf::LuaBehavior::tick( uf::Object& self ) {
}
void uf::LuaBehavior::render( uf::Object& self ) {
}
#undef this

View File

@ -198,11 +198,12 @@ bool uf::Object::load( const uf::Serializer& _json ) {
payload["filename"] = filename;\
payload["single threaded"] = singleThreaded;\
this->queueHook( "asset:QueueLoad.%UID%", payload, delay );\
addBehavior = true;
// Audio (singular)
// Audio
{
// find first valid texture in asset list
bool addBehavior = false;
uf::Serializer target;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
@ -216,9 +217,10 @@ bool uf::Object::load( const uf::Serializer& _json ) {
}
}
// Texture (singular)
// Texture
{
// find first valid texture in asset list
bool addBehavior = false;
uf::Serializer target;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
@ -232,9 +234,10 @@ bool uf::Object::load( const uf::Serializer& _json ) {
}
}
// gltf (singular)
// gltf
{
// find first valid texture in asset list
bool addBehavior = false;
uf::Serializer target;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
@ -249,6 +252,24 @@ bool uf::Object::load( const uf::Serializer& _json ) {
auto& aMetadata = assetLoader.getComponent<uf::Serializer>();
aMetadata[filename] = json["metadata"]["model"];
}
if ( addBehavior ) uf::instantiator::bind( "GltfBehavior", *this );
}
// lua
{
// find first valid texture in asset list
uf::Serializer target;
bool addBehavior = false;
if ( metadata["system"]["assets"].isArray() ) {
target = metadata["system"]["assets"];
} else if ( json["assets"].isArray() ) {
target = json["assets"];
} else if ( json["assets"].isObject() && !json["assets"]["scripts"].isNull() ) {
target = json["assets"]["scripts"];
}
for ( uint i = 0; i < target.size(); ++i ) {
UF_OBJECT_LOAD_ASSET("lua")
}
if ( addBehavior ) uf::instantiator::bind( "LuaBehavior", *this );
}
uf::Serializer hooks = metadata["system"]["hooks"];
@ -416,18 +437,6 @@ std::size_t uf::Object::loadChildUid( const uf::Serializer& json, bool initializ
return pointer ? pointer->getUid() : -1;
}
std::string uf::Object::grabURI( const std::string& filename, const std::string& _root ) {
std::string root = _root;
if ( filename.substr(0,8) == "https://" ) return filename;
std::string extension = uf::io::extension(filename);
if ( filename[0] == '/' || root == "" ) {
if ( filename.substr(0,9) == "/smtsamo/" ) root = "./data/";
else if ( extension == "json" ) root = "./data/entities/";
else if ( extension == "png" ) root = "./data/textures/";
else if ( extension == "glb" ) root = "./data/models/";
else if ( extension == "gltf" ) root = "./data/models/";
else if ( extension == "ogg" ) root = "./data/audio/";
else if ( extension == "spv" ) root = "./data/shaders/";
}
return uf::io::sanitize(filename, root);
std::string uf::Object::grabURI( const std::string& filename, const std::string& root ) {
return uf::io::resolveURI( filename, root );
}

244
engine/src/ext/lua/lua.cpp Normal file
View File

@ -0,0 +1,244 @@
#include <uf/ext/lua/lua.h>
sol::state ext::lua::state;
std::string ext::lua::main = "./data/scripts/main.lua";
#include <uf/utils/math/transform.h>
#include <uf/utils/math/physics.h>
#include <uf/utils/serialize/serializer.h>
#include <uf/engine/object/object.h>
#include <uf/engine/object/behaviors/lua.h>
#include <uf/utils/string/io.h>
#include <uf/utils/window/window.h>
void ext::lua::initialize() {
state.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::math, sol::lib::string);
POD_LUA_REGISTER_USERTYPE_BEGIN(Matrix4f)
"value", []( pod::Matrix4f& self, const size_t& index ) {
return self[index];
}
POD_LUA_REGISTER_USERTYPE_END()
POD_LUA_REGISTER_USERTYPE_BEGIN(Vector3f)
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector3f, x),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector3f, y),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector3f, z)
POD_LUA_REGISTER_USERTYPE_END()
POD_LUA_REGISTER_USERTYPE_BEGIN(Vector4f)
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector4f, x),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector4f, y),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector4f, z),
POD_LUA_REGISTER_USERTYPE_MEMBER(Vector4f, w)
POD_LUA_REGISTER_USERTYPE_END()
POD_LUA_REGISTER_USERTYPE_BEGIN(Quaternion<>)
POD_LUA_REGISTER_USERTYPE_MEMBER(Quaternion<>, x),
POD_LUA_REGISTER_USERTYPE_MEMBER(Quaternion<>, y),
POD_LUA_REGISTER_USERTYPE_MEMBER(Quaternion<>, z),
POD_LUA_REGISTER_USERTYPE_MEMBER(Quaternion<>, w)
POD_LUA_REGISTER_USERTYPE_END()
POD_LUA_REGISTER_USERTYPE_BEGIN(Transform<>)
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, position),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, scale),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, up),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, right),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, forward),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, orientation),
POD_LUA_REGISTER_USERTYPE_MEMBER(Transform<>, model),
"move", []( pod::Transform<>& self, sol::variadic_args va ) {
auto it = va.begin();
if ( va.size() == 1 ) {
pod::Vector3f delta = *it++;
self = uf::transform::move( self, delta );
} else if ( va.size() == 2 ) {
pod::Vector3f axis = *it++;
double delta = *it++;
self = uf::transform::move( self, axis, delta );
}
},
"rotate", []( pod::Transform<>& self, sol::variadic_args va ) {
auto it = va.begin();
if ( va.size() == 1 ) {
pod::Quaternion<> delta = *it++;
self = uf::transform::rotate( self, delta );
} else if ( va.size() == 2 ) {
pod::Vector3f axis = *it++;
double delta = *it++;
self = uf::transform::rotate( self, axis, delta );
}
}
POD_LUA_REGISTER_USERTYPE_END()
UF_LUA_REGISTER_USERTYPE_BEGIN(Object)
"uid", &uf::Object::getUid,
"name", &uf::Object::getName,
"getComponent", [](uf::Object& self, const std::string& type, sol::this_state L ) {
sol::variadic_results values;
if ( type == "Metadata" ) {
std::string serialized = self.getComponent<uf::Serializer>();
sol::table table = state["json"]["decode"]( serialized );
values.push_back( { L, sol::in_place, table } );
} else if ( type == "Transform" ) {
values.push_back( { L, sol::in_place, &self.getComponent<pod::Transform<>>() } );
}
return values;
},
"setComponent", [](uf::Object& self, const std::string& type, sol::variadic_args va ) {
auto value = *va.begin();
if ( type == "Metadata" ) {
std::string encoded = state["json"]["encode"]( value.as<sol::table>() );
self.getComponent<uf::Serializer>().merge(encoded);
} else if ( type == "Transform" ) {
self.getComponent<pod::Transform<>>() = value.as<pod::Transform<>>();
}
},
"bind", [](uf::Object& self, const std::string& type, const sol::function& fun ) {
if ( !self.hasBehavior<uf::LuaBehavior>() ) uf::instantiator::bind( "LuaBehavior", self );
pod::Behavior* behaviorPointer = NULL;
auto& behaviors = self.getBehaviors();
for ( auto& b : behaviors ) {
if ( b.type != self.getType<uf::LuaBehavior>() ) continue;
behaviorPointer = &b;
break;
}
if ( !behaviorPointer ) return false;
pod::Behavior& behavior = *behaviorPointer;
pod::Behavior::function_t* functionPointer = NULL;
if ( type == "initialize" ) functionPointer = &behavior.initialize;
else if ( type == "tick" ) functionPointer = &behavior.tick;
else if ( type == "render" ) functionPointer = &behavior.render;
else if ( type == "destroy" ) functionPointer = &behavior.destroy;
if ( !functionPointer ) return false;
pod::Behavior::function_t& function = *functionPointer;
function = [fun]( uf::Object& s ) {
fun(s);
};
return true;
},
"findByUid", []( uf::Object& self, const size_t& index )->uf::Object&{
auto* pointer = self.findByUid( index );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
},
"findByName", []( uf::Object& self, const std::string& index )->uf::Object&{
auto* pointer = self.findByName( index );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
},
"loadChild", []( uf::Object& self, const std::string& filename )->uf::Object&{
auto* pointer = self.loadChildPointer( filename );
if ( pointer ) return pointer->as<uf::Object>();
static uf::Object null;
return null;
},
"getChildren", []( uf::Object& self )->sol::table{
sol::table table(ext::lua::state, sol::create);
for ( auto* child : self.getChildren() ) {
table.add(&child->as<uf::Object>());
}
return table;
},
"getParent", []( uf::Object& self )->uf::Object&{
return self.getParent().as<uf::Object>();
}
UF_LUA_REGISTER_USERTYPE_END()
// `hooks` table
{
auto hooks = state["hooks"].get_or_create<sol::table>();
hooks["add"] = []( const std::string& name, const sol::function& function ) {
uf::hooks.addHook( name, [function]( const std::string& payload )->std::string{
return function( payload );
});
};
hooks["call"] = []( const std::string& name, const std::string& payload ) {
return uf::hooks.call( name, payload );
};
}
// `entities` table
{
auto entities = state["entities"].get_or_create<sol::table>();
entities["get"] = [](const uint& uid)->uf::Object&{
auto* p = uf::Entity::globalFindByUid(uid);
if ( p ) return p->as<uf::Object>();
static uf::Object null;
return null;
};
}
// `time` table
{
auto time = state["time"].get_or_create<sol::table>();
time["current"] = []()->double{ return uf::physics::time::current; };
time["previous"] = []()->double{ return uf::physics::time::previous; };
time["delta"] = []()->double{ return uf::physics::time::delta; };
}
// `json` table
{
auto json = state.require_file("json", "./data/scripts/json.lua", true);
state["json"]["pretty"] = []( const std::string& json )->std::string{
uf::Serializer serializer = json;
return serializer.serialize();
};
}
// `window` table
{
auto window = state["window"].get_or_create<sol::table>();
window["keyPressed"] = [](const std::string& name)->bool{
return uf::Window::isKeyPressed(name);
};
}
run(main);
}
bool ext::lua::run( const std::string& s, bool safe ) {
// is file
if ( uf::io::extension(s) == "lua" ) {
if ( safe ) {
auto result = state.safe_script_file( s, sol::script_pass_on_error );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << "Invalid call to Lua script: " << err.what() << "\n";
return false;
}
} else {
state.script_file( s );
}
// is string with lua
} else {
if ( safe ) {
auto result = state.safe_script( s, sol::script_pass_on_error );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << "Invalid call to Lua script: " << err.what() << "\n";
return false;
}
} else {
state.script( s );
}
}
return true;
}
pod::LuaScript ext::lua::script( const std::string& filename ) {
pod::LuaScript script;
script.filename = filename;
script.env = sol::environment( ext::lua::state, sol::create, ext::lua::state.globals() );
return script;
}
bool ext::lua::run( const pod::LuaScript& s ) {
std::string script = s.header + "\n" + uf::io::readAsString( s.filename );
auto result = state.safe_script( script, s.env, sol::script_pass_on_error );
if ( !result.valid() ) {
sol::error err = result;
uf::iostream << "Invalid call to Lua script: " << err.what() << "\n";
return false;
}
return true;
}
void ext::lua::terminate() {
}

View File

@ -15,8 +15,7 @@ ext::vulkan::Shader::~Shader() {
if ( !aliased ) destroy();
}
*/
void ext::vulkan::Shader::initialize( ext::vulkan::Device& _device, const std::string& filename, VkShaderStageFlagBits stage ) {
auto& device = &_device ? _device : ext::vulkan::device;
void ext::vulkan::Shader::initialize( ext::vulkan::Device& device, const std::string& filename, VkShaderStageFlagBits stage ) {
this->device = &device;
ext::vulkan::Buffers::initialize( device );
aliased = false;
@ -599,6 +598,8 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
break;
}
imageInfo = &((textures++)->descriptor);
if ( imageInfo->imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL )
imageInfo->imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
} break;
case VK_DESCRIPTOR_TYPE_SAMPLER: {
if ( samplers == graphic.material.samplers.end() ) {
@ -673,38 +674,41 @@ void ext::vulkan::Pipeline::update( Graphic& graphic, GraphicDescriptor& descrip
}
}
bool invalid = false;
for ( auto& descriptor : writeDescriptorSets ) {
if ( descriptor.pBufferInfo ) {
// std::cout << descriptor.pBufferInfo->offset << std::endl;
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
for ( size_t i = 0; i < descriptor.descriptorCount; ++i ) {
if ( descriptor.pBufferInfo ) {
if ( descriptor.pBufferInfo[i].offset % device->properties.limits.minUniformBufferOffsetAlignment != 0 ) {
// std::cout << "Unaligned offset! Expecting " << device->properties.limits.minUniformBufferOffsetAlignment << ", got " << descriptor.pBufferInfo[i].offset << std::endl;
std::cout << "[" << __LINE__ << "] Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " " << descriptor.pBufferInfo[i].offset << " " << descriptor.pBufferInfo[i].range << ", invalidating..." << std::endl;
std::cout << "[" << __LINE__ << "] Invalid descriptor for buffer: " << descriptor.pBufferInfo[i].buffer << " (Offset: " << descriptor.pBufferInfo[i].offset << ", Range: " << descriptor.pBufferInfo[i].range << "), invalidating..." << std::endl;
auto pointer = const_cast<VkDescriptorBufferInfo*>(&descriptor.pBufferInfo[i]);
pointer->offset = 0;
pointer->range = 0;
pointer->buffer = VK_NULL_HANDLE;
// const_cast<VkDescriptorBufferInfo*>(descriptor.pBufferInfo)->offset = 0;
invalid = true;
break;
}
}
if ( descriptor.pImageInfo ) {
if ( descriptor.pImageInfo[i].imageLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ) {
// auto pointer = const_cast<VkDescriptorImageInfo*>(&descriptor.pImageInfo[i]);
// pointer->imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
}
}
}
}
// 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;
}
}
if ( invalid ) {
graphic.process = false;
std::cout << "[" << __LINE__ << "] Pipeline invalid, updating next tick..." << std::endl;
uf::thread::add( uf::thread::has("Main") ? uf::thread::get("Main") : uf::thread::create( "Main", false, true ), [&]() -> int {
this->update( graphic, descriptor );
return 0;}, true );
return;
}
*/
graphic.process = true;
vkUpdateDescriptorSets(
*device,
writeDescriptorSets.size(),

View File

@ -9,11 +9,9 @@
#include <uf/utils/serialize/serializer.h>
#include <uf/engine/scene/scene.h>
/*
ext::vulkan::RenderMode::~RenderMode() {
this->destroy();
}
*/
std::string ext::vulkan::RenderMode::getType() const {
return "";
}

View File

@ -21,8 +21,9 @@ std::string ext::vulkan::BaseRenderMode::getType() const {
void ext::vulkan::BaseRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
if ( ext::vulkan::renderModes.size() > 1 ) return;
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
auto windowSize = device->window->getSize();
float width = windowSize.x; //this->width > 0 ? this->width : windowSize.x;
float height = windowSize.y; //this->height > 0 ? this->height : windowSize.y;
VkCommandBufferBeginInfo commandBufferInfo = {};
commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@ -95,6 +96,10 @@ void ext::vulkan::BaseRenderMode::render() {
void ext::vulkan::BaseRenderMode::initialize( Device& device ) {
this->name = "Swapchain";
auto windowSize = device.window->getSize();
this->width = windowSize.x;
this->height = windowSize.y;
ext::vulkan::RenderMode::initialize( device );
// manual initialization
// recreate swapchain
@ -110,8 +115,8 @@ void ext::vulkan::BaseRenderMode::initialize( Device& device ) {
renderTarget.attachments.clear();
renderTarget.attachments.resize( ext::vulkan::swapchain.buffers + 1 );
uint32_t width = this->width > 0 ? this->width : ext::vulkan::settings::width;
uint32_t height = this->height > 0 ? this->height : ext::vulkan::settings::height;
// uint32_t width = windowSize.x; //this->width > 0 ? this->width : windowSize.x;
// uint32_t height = windowSize.y; //this->height > 0 ? this->height : windowSize.y;
for ( size_t i = 0; i < images.size(); ++i ) {
VkImageViewCreateInfo colorAttachmentView = {};

View File

@ -16,6 +16,15 @@ std::string ext::vulkan::DeferredRenderMode::getType( ) const {
}
void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
{
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
auto& swapchainRender = ext::vulkan::getRenderMode("Swapchain");
if ( swapchainRender.renderTarget.width != width || swapchainRender.renderTarget.height != height ) {
settings::experimental::deferredAliasOutputToSwapchain = false;
}
}
ext::vulkan::RenderMode::initialize( device );
{
renderTarget.device = &device;
@ -26,12 +35,15 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
attachments.albedo = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // normals
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // position
if ( !settings::experimental::deferredReconstructPosition )
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // position
attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true ); // depth
// attachments.ping = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
// attachments.pong = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
// Attach swapchain's image as output
{
if ( settings::experimental::deferredAliasOutputToSwapchain ) {
attachments.output = renderTarget.attachments.size();
RenderTarget::Attachment swapchainAttachment;
swapchainAttachment.format = device.formats.color;
@ -56,10 +68,19 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
swapchainAttachment.blendState = blendAttachmentState;
}
renderTarget.attachments.push_back(swapchainAttachment);
} else {
attachments.output = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
}
// First pass: fill the G-Buffer
{
if ( settings::experimental::deferredReconstructPosition ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.albedo, attachments.normals },
{},
attachments.depth
);
} else {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.albedo, attachments.normals, attachments.position },
@ -68,7 +89,14 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
);
}
// Second pass: write to output
{
if ( settings::experimental::deferredReconstructPosition ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.albedo, attachments.normals, attachments.depth },
attachments.depth
);
} else {
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
@ -96,10 +124,17 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) {
blitter.initialize( this->getName() );
blitter.initializeGeometry( mesh );
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
if ( settings::experimental::deferredReconstructPosition ) {
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
} else {
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
}
{
auto& scene = uf::scene::getCurrentScene();
auto& metadata = scene.getComponent<uf::Serializer>();
@ -177,10 +212,20 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdBufInfo.pNext = nullptr;
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.levelCount = 1;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes(std::vector<std::string>{"RenderTarget", "Compute"}, false);
auto& scene = uf::scene::getCurrentScene();
auto& metadata = scene.getComponent<uf::Serializer>();
auto& commands = getCommands();
auto& swapchainRender = ext::vulkan::getRenderMode("Swapchain");
for (size_t i = 0; i < commands.size(); ++i) {
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
// Fill GBuffer
@ -236,7 +281,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
for ( auto layer : layers ) {
layer->pipelineBarrier( commands[i], 0 );
}
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
@ -268,10 +313,190 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
}
}
vkCmdEndRenderPass(commands[i]);
/*
bool matching = !settings::experimental::deferredAliasOutputToSwapchain ? true : swapchainRender.renderTarget.width == width && swapchainRender.renderTarget.height == height;
std::cout << (matching ? "framebuffer matches swapchain" : "framebuffer mismatches swapchain") << std::endl;
if ( true || matching ) {
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
for ( auto graphic : graphics ) {
// only draw graphics that are assigned to this type of render mode
if ( graphic->descriptor.renderMode != this->getName() ) continue;
graphic->record( commands[i] );
}
// blit any RT's
{
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 0 ) continue;
blitter.record(commands[i]);
}
}
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
viewport.width = (float) swapchainRender.renderTarget.width;
viewport.height = (float) swapchainRender.renderTarget.height;
scissor.extent.width = swapchainRender.renderTarget.width;
scissor.extent.height = swapchainRender.renderTarget.height;
// vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
{
blitter.record(commands[i]);
}
// blit any RT's
{
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 1 ) continue;
blitter.record(commands[i]);
}
}
vkCmdEndRenderPass(commands[i]);
} else {
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
for ( auto graphic : graphics ) {
// only draw graphics that are assigned to this type of render mode
if ( graphic->descriptor.renderMode != this->getName() ) continue;
graphic->record( commands[i] );
}
// blit any RT's
{
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 0 ) continue;
blitter.record(commands[i]);
}
}
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
vkCmdEndRenderPass(commands[i]);
renderPassBeginInfo.renderArea.extent.width = swapchainRender.renderTarget.width;
renderPassBeginInfo.renderArea.extent.height = swapchainRender.renderTarget.height;
viewport.width = (float) swapchainRender.renderTarget.width;
viewport.height = (float) swapchainRender.renderTarget.height;
scissor.extent.width = swapchainRender.renderTarget.width;
scissor.extent.height = swapchainRender.renderTarget.height;
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
{
blitter.record(commands[i]);
}
// blit any RT's
{
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 1 ) continue;
blitter.record(commands[i]);
}
}
vkCmdEndRenderPass(commands[i]);
}
*/
for ( auto layer : layers ) {
layer->pipelineBarrier( commands[i], 1 );
}
if ( !settings::experimental::deferredAliasOutputToSwapchain ) {
{
auto& renderTarget = swapchainRender.renderTarget;
float width = renderTarget.width;
float height = renderTarget.height;
std::vector<VkClearValue> clearValues; clearValues.resize(2);
clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
clearValues[1].depthStencil = { 1.0f, 0 };
VkRenderPassBeginInfo renderPassBeginInfo = {};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.pNext = nullptr;
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent.width = width;
renderPassBeginInfo.renderArea.extent.height = height;
renderPassBeginInfo.clearValueCount = clearValues.size();
renderPassBeginInfo.pClearValues = &clearValues[0];
renderPassBeginInfo.renderPass = renderTarget.renderPass;
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[i];
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdEndRenderPass(commands[i]);
}
{
VkImageBlit imageBlitRegion{};
imageBlitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlitRegion.srcSubresource.layerCount = 1;
imageBlitRegion.srcOffsets[1] = { width, height, 1 };
imageBlitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlitRegion.dstSubresource.layerCount = 1;
imageBlitRegion.dstOffsets[1] = {
swapchainRender.width > 0 ? swapchainRender.width : ext::vulkan::settings::width,
swapchainRender.height > 0 ? swapchainRender.height : ext::vulkan::settings::height,
1
};
auto& outputAttachment = renderTarget.attachments[renderTarget.attachments.size()-1];
// Transition to KHR
{
imageMemoryBarrier.image = outputAttachment.image;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.oldLayout = outputAttachment.layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
outputAttachment.layout = imageMemoryBarrier.newLayout;
}
{
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
}
vkCmdBlitImage(
commands[i],
outputAttachment.image,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
swapchainRender.renderTarget.attachments[i].image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&imageBlitRegion,
settings::swapchainUpscaleFilter
);
{
imageMemoryBarrier.image = outputAttachment.image;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.oldLayout = outputAttachment.layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
outputAttachment.layout = imageMemoryBarrier.newLayout;
}
{
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
}
}
}
}
VK_CHECK_RESULT(vkEndCommandBuffer(commands[i]));

View File

@ -0,0 +1,366 @@
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/vulkan/rendermodes/deferred.h>
#include <uf/ext/vulkan/rendermodes/multiview_stereoscopic_deferred.h>
#include <uf/ext/vulkan/rendermodes/rendertarget.h>
#include <uf/ext/vulkan/initializers.h>
#include <uf/utils/window/window.h>
#include <uf/utils/graphic/graphic.h>
#include <uf/ext/vulkan/graphic.h>
#include <uf/engine/scene/scene.h>
#include <uf/utils/camera/camera.h>
#include <uf/utils/math/transform.h>
#include <uf/ext/openvr/openvr.h>
std::string ext::vulkan::MultiviewStereoscopicDeferredRenderMode::getType() const {
return "Deferred (Stereoscopic, Multiview)";
}
void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::initialize( Device& device ) {
ext::vulkan::RenderMode::initialize( device );
renderTarget.device = &device;
renderTarget.width = this->width;
renderTarget.height = this->height;
renderTarget.multiviews = 2;
// attach targets
struct {
size_t albedo, normals, position, depth, output;
} attachments;
attachments.albedo = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
if ( !settings::experimental::deferredReconstructPosition ) {
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // position
}
attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
attachments.output = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
// attachments.ping = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
// attachments.pong = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
/*
// Attach swapchain's image as output
if ( !true ) {
attachments.swapchain = renderTarget.attachments.size();
RenderTarget::Attachment swapchainAttachment;
swapchainAttachment.format = device.formats.color;
swapchainAttachment.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
swapchainAttachment.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
swapchainAttachment.aliased = true;
renderTarget.attachments.push_back(swapchainAttachment);
}
*/
// First pass: fill the G-Buffer
if ( settings::experimental::deferredReconstructPosition ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.albedo, attachments.normals },
{},
attachments.depth
);
} else {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.albedo, attachments.normals, attachments.position },
{},
attachments.depth
);
}
// Second pass: write to output
if ( settings::experimental::deferredReconstructPosition ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.albedo, attachments.normals, attachments.depth },
attachments.depth
);
} else {
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.albedo, attachments.normals, attachments.position },
attachments.depth
);
}
renderTarget.initialize( device );
{
uf::BaseMesh<pod::Vertex_2F2F, uint16_t> mesh;
mesh.vertices = {
{ {-1.0f, 1.0f}, {0.0f, 1.0f}, },
{ {-1.0f, -1.0f}, {0.0f, 0.0f}, },
{ {1.0f, -1.0f}, {1.0f, 0.0f}, },
{ {1.0f, 1.0f}, {1.0f, 1.0f}, }
};
mesh.indices = {
0, 1, 2, 0, 2, 3
};
blitter.descriptor.subpass = 1;
blitter.descriptor.renderTarget = 0;
blitter.descriptor.depthTest.test = false;
blitter.descriptor.depthTest.write = false;
blitter.initialize( this->getName() );
blitter.initializeGeometry( mesh );
if ( settings::experimental::deferredReconstructPosition ) {
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
} else {
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
}
{
auto& scene = uf::scene::getCurrentScene();
auto& metadata = scene.getComponent<uf::Serializer>();
auto& shader = blitter.material.shaders.back();
struct SpecializationConstant {
uint32_t maxLights = 16;
};
auto* specializationConstants = (SpecializationConstant*) &shader.specializationConstants[0];
specializationConstants->maxLights = metadata["system"]["config"]["engine"]["scenes"]["max lights"].asUInt64();
for ( auto& binding : shader.descriptorSetLayoutBindings ) {
if ( binding.descriptorCount > 1 )
binding.descriptorCount = specializationConstants->maxLights;
}
}
blitter.initializePipeline();
}
}
void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::tick() {
ext::vulkan::RenderMode::tick();
if ( ext::vulkan::states::resized ) {
renderTarget.initialize( *renderTarget.device );
// update blitter descriptor set
if ( blitter.initialized ) {
blitter.getPipeline().update( blitter );
// blitter.updatePipelines();
}
}
}
void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::destroy() {
ext::vulkan::RenderMode::destroy();
blitter.destroy();
}
void ext::vulkan::MultiviewStereoscopicDeferredRenderMode::createCommandBuffers( const std::vector<ext::vulkan::Graphic*>& graphics ) {
// destroy if exists
// ext::vulkan::RenderMode& swapchain =
float width = this->width > 0 ? this->width : ext::vulkan::settings::width;
float height = this->height > 0 ? this->height : ext::vulkan::settings::height;
VkCommandBufferBeginInfo cmdBufInfo = {};
cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
cmdBufInfo.pNext = nullptr;
VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // ext::vulkan::device.queueFamilyIndices.graphics; //VK_QUEUE_FAMILY_IGNORED
imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
imageMemoryBarrier.subresourceRange.levelCount = 1;
imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
std::vector<RenderMode*> layers = ext::vulkan::getRenderModes(std::vector<std::string>{"RenderTarget", "Compute"}, false);
auto& scene = uf::scene::getCurrentScene();
auto& metadata = scene.getComponent<uf::Serializer>();
auto& commands = getCommands();
for (size_t i = 0; i < commands.size(); ++i) {
VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo));
// Fill GBuffer
{
std::vector<VkClearValue> clearValues;
for ( auto& attachment : renderTarget.attachments ) {
VkClearValue clearValue;
if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) {
if ( !metadata["system"]["renderer"]["clear values"][(int) clearValues.size()].isNull() ) {
auto& v = metadata["system"]["renderer"]["clear values"][(int) clearValues.size()];
clearValue.color = { {
v[0].asFloat(),
v[1].asFloat(),
v[2].asFloat(),
v[3].asFloat(),
} };
} else {
clearValue.color = { { 0, 0, 0, 0 } };
}
} else if ( attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) {
clearValue.depthStencil = { 0.0f, 0 };
}
clearValues.push_back(clearValue);
}
VkRenderPassBeginInfo renderPassBeginInfo = {};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.pNext = nullptr;
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent.width = width;
renderPassBeginInfo.renderArea.extent.height = height;
renderPassBeginInfo.clearValueCount = clearValues.size();
renderPassBeginInfo.pClearValues = &clearValues[0];
renderPassBeginInfo.renderPass = renderTarget.renderPass;
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[i];
// Update dynamic viewport state
VkViewport viewport = {};
viewport.width = (float) width;
viewport.height = (float) height;
viewport.minDepth = (float) 0.0f;
viewport.maxDepth = (float) 1.0f;
// Update dynamic scissor state
VkRect2D scissor = {};
scissor.extent.width = width;
scissor.extent.height = height;
scissor.offset.x = 0;
scissor.offset.y = 0;
// transition layers for read
for ( auto layer : layers ) {
layer->pipelineBarrier( commands[i], 0 );
}
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(commands[i], 0, 1, &viewport);
vkCmdSetScissor(commands[i], 0, 1, &scissor);
for ( auto graphic : graphics ) {
// only draw graphics that are assigned to this type of render mode
if ( graphic->descriptor.renderMode != this->getName() ) continue;
graphic->record(commands[i] );
}
// render gui layer
{
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 0 ) continue;
blitter.record(commands[i]);
}
}
vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE);
{
blitter.record(commands[i]);
}
// render gui layer
{
for ( auto _ : layers ) {
RenderTargetRenderMode* layer = (RenderTargetRenderMode*) _;
auto& blitter = layer->blitter;
if ( !blitter.initialized || !blitter.process || blitter.descriptor.subpass != 1 ) continue;
blitter.record(commands[i]);
}
}
vkCmdEndRenderPass(commands[i]);
for ( auto layer : layers ) {
layer->pipelineBarrier( commands[i], 1 );
}
}
// Blit eye to swapchain
{
// if ( false ) {
// transition swapchain to proper layout
auto& swapchainRender = ext::vulkan::getRenderMode("Swapchain");
{
auto& renderTarget = swapchainRender.renderTarget;
float width = renderTarget.width;
float height = renderTarget.height;
std::vector<VkClearValue> clearValues; clearValues.resize(2);
clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
clearValues[1].depthStencil = { 1.0f, 0 };
VkRenderPassBeginInfo renderPassBeginInfo = {};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.pNext = nullptr;
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
renderPassBeginInfo.renderArea.extent.width = width;
renderPassBeginInfo.renderArea.extent.height = height;
renderPassBeginInfo.clearValueCount = clearValues.size();
renderPassBeginInfo.pClearValues = &clearValues[0];
renderPassBeginInfo.renderPass = renderTarget.renderPass;
renderPassBeginInfo.framebuffer = renderTarget.framebuffers[i];
vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdEndRenderPass(commands[i]);
}
{
VkImageBlit imageBlitRegion{};
imageBlitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlitRegion.srcSubresource.layerCount = 1;
imageBlitRegion.srcSubresource.baseArrayLayer = ext::openvr::dominantEye;
imageBlitRegion.srcOffsets[1] = { width, height, 1 };
imageBlitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlitRegion.dstSubresource.layerCount = 1;
imageBlitRegion.dstOffsets[1] = {
swapchainRender.width > 0 ? swapchainRender.width : ext::vulkan::settings::width,
swapchainRender.height > 0 ? swapchainRender.height : ext::vulkan::settings::height,
1
};
auto& outputAttachment = renderTarget.attachments[renderTarget.attachments.size()-1];
// Transition to KHR
{
imageMemoryBarrier.image = outputAttachment.image;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.oldLayout = outputAttachment.layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
outputAttachment.layout = imageMemoryBarrier.newLayout;
}
{
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
imageMemoryBarrier.srcAccessMask = 0;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
}
vkCmdBlitImage(
commands[i],
outputAttachment.image,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
swapchainRender.renderTarget.attachments[i].image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&imageBlitRegion,
settings::swapchainUpscaleFilter
);
{
imageMemoryBarrier.image = outputAttachment.image;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.oldLayout = outputAttachment.layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
outputAttachment.layout = imageMemoryBarrier.newLayout;
}
{
imageMemoryBarrier.image = swapchainRender.renderTarget.attachments[i].image;
imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imageMemoryBarrier.oldLayout = swapchainRender.renderTarget.attachments[i].layout;
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, NULL, 0, NULL, 1, &imageMemoryBarrier );
swapchainRender.renderTarget.attachments[i].layout = imageMemoryBarrier.newLayout;
}
}
}
VK_CHECK_RESULT(vkEndCommandBuffer(commands[i]));
}
ext::openvr::renderPass = 0;
}

View File

@ -25,7 +25,8 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
attachments.albedo = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // normals
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // position
if ( !settings::experimental::deferredReconstructPosition )
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // position
attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true ); // depth
// Attach swapchain's image as output
if ( !false ) {
@ -58,7 +59,14 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
}
// First pass: write to target
{
if ( settings::experimental::deferredReconstructPosition ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.albedo, attachments.normals },
{},
attachments.depth
);
} else {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.albedo, attachments.normals, attachments.position },
@ -67,11 +75,18 @@ void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) {
);
}
// NOP
if ( !false ) {
if ( settings::experimental::deferredReconstructPosition ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.albedo, attachments.normals, attachments.position/*, attachments.depth*/ },
{ attachments.albedo, attachments.normals, attachments.depth },
attachments.depth
);
} else {
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.albedo, attachments.normals, attachments.position },
attachments.depth
);
}

View File

@ -58,7 +58,8 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
attachments.albedo = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
attachments.normals = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // normals
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // position
if ( !settings::experimental::deferredReconstructPosition )
attachments.position = renderTarget.attach( VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false ); // position
attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false ); // depth
attachments.output = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true ); // albedo
// attachments.ping = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo
@ -76,7 +77,14 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
}
*/
// First pass: fill the G-Buffer
{
if ( settings::experimental::deferredReconstructPosition ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.albedo, attachments.normals },
{},
attachments.depth
);
} else {
renderTarget.addPass(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
{ attachments.albedo, attachments.normals, attachments.position },
@ -85,8 +93,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
);
}
// Second pass: write to output
/*
if ( i == 0 ) {
if ( settings::experimental::deferredReconstructPosition ) {
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
@ -101,13 +108,6 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
attachments.depth
);
}
*/
renderTarget.addPass(
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
{ attachments.output },
{ attachments.albedo, attachments.normals, attachments.position },
attachments.depth
);
renderTarget.initialize( device );
{
uf::BaseMesh<pod::Vertex_2F2F, uint16_t> mesh;
@ -127,6 +127,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
blitter.initialize( this->getName() );
blitter.initializeGeometry( mesh );
/*
if ( i == 0 ) {
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
@ -139,6 +140,18 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
}
*/
if ( settings::experimental::deferredReconstructPosition ) {
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
} else {
blitter.material.initializeShaders({
{"./data/shaders/display.subpass.vert.spv", VK_SHADER_STAGE_VERTEX_BIT},
{"./data/shaders/display.subpass.stereo.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT}
});
}
{
auto& scene = uf::scene::getCurrentScene();
auto& metadata = scene.getComponent<uf::Serializer>();
@ -164,7 +177,6 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) {
}
blitter.initializePipeline();
}
++i;
}
}
void ext::vulkan::StereoscopicDeferredRenderMode::tick() {
@ -396,7 +408,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&imageBlitRegion,
VK_FILTER_LINEAR
settings::swapchainUpscaleFilter
);
{

View File

@ -70,7 +70,7 @@ size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usa
imageCreateInfo.format = format;
imageCreateInfo.extent = { width, height, 1 };
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = USEVR ? 2 : 1;
imageCreateInfo.arrayLayers = this->multiviews;
imageCreateInfo.samples = samples;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = usage;
@ -106,7 +106,7 @@ size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usa
imageView.subresourceRange.baseMipLevel = 0;
imageView.subresourceRange.levelCount = 1;
imageView.subresourceRange.baseArrayLayer = 0;
imageView.subresourceRange.layerCount = USEVR ? 2 : 1;
imageView.subresourceRange.layerCount = this->multiviews;
imageView.image = attachment->image;
VK_CHECK_RESULT(vkCreateImageView(*device, &imageView, nullptr, &attachment->view));
@ -203,6 +203,12 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
description.pPreserveAttachments = nullptr;
description.pResolveAttachments = nullptr;
description.flags = 0;
for ( auto& input : pass.inputs ) {
if ( input.attachment == pass.depth.attachment ) {
description.pDepthStencilAttachment = NULL;
break;
}
}
descriptions.push_back(description);
/*
std::cout << "Pass: " << descriptions.size() - 1 << std::endl;
@ -280,6 +286,26 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) {
renderPassInfo.dependencyCount = static_cast<uint32_t>(dependencies.size());
renderPassInfo.pDependencies = &dependencies[0];
uint32_t mask = 0;
std::vector<uint32_t> masks;
for ( size_t i = 0; i < this->multiviews; ++i ) {
mask |= (0b00000001 << i);
}
for ( size_t i = 0; i < static_cast<uint32_t>(descriptions.size()); ++i ) {
masks.emplace_back(mask);
}
VkRenderPassMultiviewCreateInfo renderPassMultiviewInfo = {};
renderPassMultiviewInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
renderPassMultiviewInfo.subpassCount = 1; //static_cast<uint32_t>(descriptions.size());
// renderPassMultiviewInfo.dependencyCount = static_cast<uint32_t>(dependencies.size());
renderPassMultiviewInfo.pViewMasks = masks.data();
renderPassMultiviewInfo.pCorrelationMasks = masks.data();
renderPassMultiviewInfo.correlationMaskCount = 1;
if ( this->multiviews > 1 ) {
renderPassInfo.pNext = &renderPassMultiviewInfo;
}
VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass));
// std::cout << renderPass << ": " << attachments.size() << std::endl;

View File

@ -19,10 +19,15 @@ std::vector<std::string> ext::vulkan::settings::requestedDeviceFeatures;
std::vector<std::string> ext::vulkan::settings::requestedDeviceExtensions;
std::vector<std::string> ext::vulkan::settings::requestedInstanceExtensions;
VkFilter ext::vulkan::settings::swapchainUpscaleFilter = VK_FILTER_LINEAR;
bool ext::vulkan::settings::experimental::rebuildOnTickBegin = false;
bool ext::vulkan::settings::experimental::waitOnRenderEnd = false;
bool ext::vulkan::settings::experimental::individualPipelines = false;
bool ext::vulkan::settings::experimental::multithreadedCommandRecording = false;
bool ext::vulkan::settings::experimental::deferredReconstructPosition = false;
bool ext::vulkan::settings::experimental::deferredAliasOutputToSwapchain = true;
bool ext::vulkan::settings::experimental::multiview = true;
ext::vulkan::Device ext::vulkan::device;
ext::vulkan::Allocator ext::vulkan::allocator;

View File

@ -1295,7 +1295,7 @@ std::string UF_API_CALL spec::win32::Window::getKey(WPARAM key, LPARAM flags) {
case '0': return "Num0";
}
// return "Unknown";
return std::string( "" + (int) key );
return std::to_string((int) key);
}
#if defined(UF_USE_VULKAN) && UF_USE_VULKAN == 1
std::vector<std::string> UF_API_CALL spec::win32::Window::getExtensions( bool validationEnabled ) {

View File

@ -19,5 +19,6 @@ uf::Component::~Component() {
// override serializers
template<>
uf::Serializer uf::Serializer::toBase64( const pod::Component& input ) {
uf::Serializer serialized;
return serialized;
}

View File

@ -418,6 +418,7 @@ uf::Image uf::Image::replace(const Image::pixel_t& from, const Image::pixel_t& t
}
// Crops an image
uf::Image uf::Image::subImage( const Image::vec2_t& start, const Image::vec2_t& end) const {
return *this;
/*
uf::Vector2ui size = parameter;
if ( mode == uf::Image::CropMode::START_SPAN_SIZE ) size = parameter;

View File

@ -1,7 +1,7 @@
#include <uf/utils/serialize/serializable.h>
void uf::Serializable::deserialize( const Serializer& input ) {
this->deserialize(input);
this->deserialize((const Serializer::input_t&) input);
}
void uf::Serializable::operator<<( const Serializer::input_t& input ) {

View File

@ -81,4 +81,20 @@ size_t UF_API uf::io::mtime( const std::string& filename ) {
static struct stat buffer;
if ( stat(filename.c_str(), &buffer) != 0 ) return -1;
return buffer.st_mtime;
}
std::string UF_API uf::io::resolveURI( const std::string& filename, const std::string& _root ) {
std::string root = _root;
if ( filename.substr(0,8) == "https://" ) return filename;
std::string extension = uf::io::extension(filename);
if ( filename[0] == '/' || root == "" ) {
if ( filename.substr(0,9) == "/smtsamo/" ) root = "./data/";
else if ( extension == "json" ) root = "./data/entities/";
else if ( extension == "png" ) root = "./data/textures/";
else if ( extension == "glb" ) root = "./data/models/";
else if ( extension == "gltf" ) root = "./data/models/";
else if ( extension == "ogg" ) root = "./data/audio/";
else if ( extension == "spv" ) root = "./data/shaders/";
else if ( extension == "lua" ) root = "./data/scripts/";
}
return uf::io::sanitize(filename, root);
}

View File

@ -228,6 +228,9 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
// } else {
// hasCompute = false;
// }
} else if ( renderMode.getType() == "Deferred (Stereoscopic, Multiview)" ) {
auto* renderModePointer = (uf::renderer::MultiviewStereoscopicDeferredRenderMode*) &renderMode;
blitters.push_back(&renderModePointer->blitter);
} else if ( renderMode.getType() == "Deferred (Stereoscopic)" ) {
auto* renderModePointer = (uf::renderer::StereoscopicDeferredRenderMode*) &renderMode;
blitters.push_back(&renderModePointer->blitters.left);
@ -297,8 +300,8 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
for ( size_t _ = 0; _ < blitters.size(); ++_ ) {
auto& blitter = *blitters[_];
uint8_t* buffer;
size_t len;
uint8_t* buffer = NULL;
size_t len = 0;
auto* shader = &blitter.material.shaders.front();
for ( auto& _ : blitter.material.shaders ) {
@ -395,7 +398,7 @@ void ext::ExtSceneBehavior::tick( uf::Object& self ) {
uint8_t i = 0;
for ( auto& attachment : renderTarget.attachments ) {
if ( !(attachment.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ) continue;
if ( (attachment.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();
texture.aliasAttachment(attachment);
if ( light.type == 0 ) light.type = 1;

View File

@ -11,12 +11,14 @@ EXT_BEHAVIOR_REGISTER_CPP(StaticEmitterBehavior)
#define this ((uf::Object*) &self)
void ext::StaticEmitterBehavior::initialize( uf::Object& self ) {
auto& metadata = this->getComponent<uf::Serializer>();
// this->addHook( "system:Load.Finished.%UID%", [&](const std::string& event)->std::string{
// uf::Serializer json = event;
auto* hud = this->loadChildPointer("/hud.json", true);
metadata["hud"]["uid"] = hud->getUid();
// return "true";
// });
if ( metadata["distance"].asBool() ) {
// this->addHook( "system:Load.Finished.%UID%", [&](const std::string& event)->std::string{
// uf::Serializer json = event;
auto* hud = this->loadChildPointer("/hud.json", true);
metadata["hud"]["uid"] = hud->getUid();
// return "true";
// });
}
}
void ext::StaticEmitterBehavior::tick( uf::Object& self ) {
auto& scene = uf::scene::getCurrentScene();

View File

@ -109,7 +109,7 @@ std::vector<pod::GlyphBox> ext::Gui::generateGlyphs( const std::string& _string
std::smatch match;
bool matched = false;
int maxTries = 128;
while ( matched = std::regex_search( text, match, regex ) && --maxTries > 0 ) {
while ( (matched = std::regex_search( text, match, regex )) && --maxTries > 0 ) {
struct {
std::string str;
int dec;

View File

@ -41,6 +41,7 @@
#include <uf/utils/renderer/renderer.h>
#include <uf/ext/discord/discord.h>
#include <uf/ext/openvr/openvr.h>
#include <uf/ext/lua/lua.h>
namespace {
struct {
@ -115,6 +116,9 @@ void EXT_API ext::initialize() {
/* Read persistent data */ {
// #include "./inits/persistence.inl"
}
/* Lua */ {
ext::lua::initialize();
}
/* Parse config */ {
// Set memory pool sizes
@ -190,8 +194,21 @@ void EXT_API ext::initialize() {
// Enable valiation layer
uf::renderer::settings::validation = ::config["engine"]["ext"]["vulkan"]["validation"]["enabled"].asBool();
if ( ::config["engine"]["ext"]["vulkan"]["msaa"].isNumeric() )
uf::renderer::settings::msaa = ::config["engine"]["ext"]["vulkan"]["msaa"].asUInt64();
if ( ::config["engine"]["ext"]["vulkan"]["framebuffer"]["msaa"].isNumeric() )
uf::renderer::settings::msaa = ::config["engine"]["ext"]["vulkan"]["framebuffer"]["msaa"].asUInt64();
if ( ::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].isNumeric() ) {
float scale = ::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].asFloat();
uf::renderer::settings::width *= scale;
uf::renderer::settings::height *= scale;
} else if ( ::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"].isArray() ) {
uf::renderer::settings::width = ::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"][0].asFloat();
uf::renderer::settings::height = ::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"][1].asFloat();
std::string filter = ::config["engine"]["ext"]["vulkan"]["framebuffer"]["size"][2].asString();
if ( uf::string::lowercase( filter ) == "nearest" ) uf::renderer::settings::swapchainUpscaleFilter = VK_FILTER_NEAREST;
else if ( uf::string::lowercase( filter ) == "linear" ) uf::renderer::settings::swapchainUpscaleFilter = VK_FILTER_LINEAR;
}
for ( int i = 0; i < ::config["engine"]["ext"]["vulkan"]["validation"]["filters"].size(); ++i ) {
uf::renderer::settings::validationFilters.push_back( ::config["engine"]["ext"]["vulkan"]["validation"]["filters"][i].asString() );
@ -209,6 +226,8 @@ void EXT_API ext::initialize() {
uf::renderer::settings::experimental::waitOnRenderEnd = ::config["engine"]["ext"]["vulkan"]["experimental"]["wait on render end"].asBool();
uf::renderer::settings::experimental::individualPipelines = ::config["engine"]["ext"]["vulkan"]["experimental"]["individual pipelines"].asBool();
uf::renderer::settings::experimental::multithreadedCommandRecording = ::config["engine"]["ext"]["vulkan"]["experimental"]["multithreaded command recording"].asBool();
uf::renderer::settings::experimental::deferredReconstructPosition = ::config["engine"]["ext"]["vulkan"]["experimental"]["deferred reconstruct position"].asBool();
uf::renderer::settings::experimental::deferredAliasOutputToSwapchain = ::config["engine"]["ext"]["vulkan"]["experimental"]["deferred alias output to swapchain"].asBool();
ext::openvr::enabled = ::config["engine"]["ext"]["vr"]["enable"].asBool();
ext::openvr::swapEyes = ::config["engine"]["ext"]["vr"]["swap eyes"].asBool();
@ -240,7 +259,9 @@ void EXT_API ext::initialize() {
uf::renderer::addRenderMode( renderMode, "Gui" );
renderMode->blitter.descriptor.subpass = 1;
}
if ( ::config["engine"]["render modes"]["stereo deferred"].asBool() )
if ( ::config["engine"]["render modes"]["multiview stereo deferred"].asBool() )
uf::renderer::addRenderMode( new uf::renderer::MultiviewStereoscopicDeferredRenderMode, "" );
else if ( ::config["engine"]["render modes"]["stereo deferred"].asBool() )
uf::renderer::addRenderMode( new uf::renderer::StereoscopicDeferredRenderMode, "" );
else if ( ::config["engine"]["render modes"]["deferred"].asBool() )
uf::renderer::addRenderMode( new uf::renderer::DeferredRenderMode, "" );
@ -255,7 +276,15 @@ void EXT_API ext::initialize() {
renderMode.width = width;
renderMode.height = height;
uf::iostream << "Recommended VR Resolution: " << width << ", " << height << "\n";
uf::iostream << "Recommended VR Resolution: " << renderMode.width << ", " << renderMode.height << "\n";
if ( ::config["engine"]["ext"]["vr"]["scale"].isNumeric() ) {
float scale = ::config["engine"]["ext"]["vr"]["scale"].asFloat();
renderMode.width *= scale;
renderMode.height *= scale;
uf::iostream << "VR Resolution: " << renderMode.width << ", " << renderMode.height << "\n";
}
}
uf::renderer::initialize();
@ -411,11 +440,18 @@ void EXT_API ext::tick() {
}
}
/* Update physics timer */ {
uf::physics::tick();
}
/* Update entities */ {
uf::scene::tick();
/* Limit tickrate */ {
// static uf::Timer<long long> timer(false);
// if ( !timer.running() ) timer.start();
// if ( timer.elapsed().asDouble() >= uf::thread::limiter ) { timer.reset();
{
/* Update physics timer */ {
uf::physics::tick();
}
/* Update entities */ {
uf::scene::tick();
}
}
}
/* Tick Main Thread Queue */ {
@ -478,11 +514,12 @@ void EXT_API ext::terminate() {
ext::openvr::terminate();
}
uf::scene::destroy();
/* Close vulkan */ {
uf::renderer::destroy();
}
/* Flush input buffer */ {
io.output << io.input << "\n";
for ( const auto& str : uf::iostream.getHistory() ) io.output << str << "\n";
@ -490,8 +527,6 @@ void EXT_API ext::terminate() {
io.output.close();
}
uf::scene::destroy();
/* Write persistent data */ if ( false ) {
struct {
bool exists = false;

View File

@ -27,7 +27,7 @@ void ext::TerrainBehavior::initialize( uf::Object& self ) {
// alias Mesh types
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
std::size_t seed;
std::size_t seed = 0;
if ( metadata["terrain"]["seed"].isUInt64() ) {
seed = metadata["terrain"]["seed"].asUInt64();
} else if ( metadata["terrain"]["seed"].isString() ) {

View File

@ -36,7 +36,7 @@ namespace {
return result;
}
uint16_t colorToUint16( COLOR color ) {
uint16_t result;
uint16_t result = 0;
// memcpy( &result, &color, sizeof color );
result |= (color.r << 12);
result |= (color.g << 8);

View File

@ -0,0 +1,4 @@
ARCH = win64
PREFIX = clang
CC = clang++
FLAGS = -Wall -Wno-unused-function -Wno-unused-variable -Wno-switch -Wno-reorder-ctor -Wno-ignored-attributes -Wno-c++11-narrowing -fcolor-diagnostics

4
makefiles/win64.gcc.make Normal file
View File

@ -0,0 +1,4 @@
ARCH = win64
PREFIX = gcc
CC = /opt/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/mingw64/bin/g++
FLAGS = -fdiagnostics-color=always -Og -g -Wall -Wno-unused-function -Wno-unused-variable -Wno-switch -Wno-reorder -Wno-sign-compare -Wno-unused-but-set-variable -Wno-ignored-attributes -Wno-narrowing -Wno-misleading-indentation

View File

@ -0,0 +1,4 @@
ARCH = win64
PREFIX = gcc10
CC = g++
FLAGS = -fdiagnostics-color=always -O3 -DUF_DISABLE_ALIGNAS -Wall -Wno-unused-function -Wno-unused-variable -Wno-switch -Wno-reorder -Wno-sign-compare -Wno-unused-but-set-variable -Wno-ignored-attributes -Wno-narrowing -Wno-misleading-indentation