From 014f7f8fe0174585dabd943d31373e3f34df9862 Mon Sep 17 00:00:00 2001 From: mrq Date: Wed, 12 Aug 2020 00:00:00 -0500 Subject: [PATCH] Commit for 2020.08.12.7z --- Makefile | 6 +- bin/data/shaders/base.stereo.vert.glsl | 1 - .../shaders/display.rendertarget.frag.glsl | 23 +- .../shaders/display.rendertarget.vert.glsl | 1 - engine/inc/uf/config.h | 1 + engine/inc/uf/engine/entity/entity.h | 2 +- .../ext/vulkan/graphics/deferredrendering.h | 4 +- engine/inc/uf/ext/vulkan/graphics/gui.h | 46 ---- engine/inc/uf/ext/vulkan/graphics/mesh.h | 40 --- .../inc/uf/ext/vulkan/graphics/rendertarget.h | 13 +- .../uf/ext/vulkan/rendermodes/rendertarget.h | 1 + engine/inc/uf/ext/vulkan/vulkan.h | 4 +- engine/inc/uf/utils/camera/camera.h | 9 +- engine/inc/uf/utils/image/pixel.h | 6 +- engine/inc/uf/utils/math/matrix.h | 3 +- engine/inc/uf/utils/math/quaternion.h | 8 +- engine/inc/uf/utils/math/quaternion/pod.inl | 50 +++- engine/inc/uf/utils/math/transform.h | 18 +- engine/inc/uf/utils/math/vector.h | 4 +- .../inc/uf/utils/math/vector/redundancy.inl | 16 +- engine/inc/uf/utils/mesh/mesh.h | 57 ++--- engine/inc/uf/utils/string/rle.inl | 4 +- engine/inc/uf/utils/time/time.h | 2 +- engine/inc/uf/utils/userdata/userdata.inl | 16 +- engine/src/engine/entity/entity.cpp | 3 +- engine/src/engine/object/object.cpp | 15 +- engine/src/ext/openvr/openvr.cpp | 48 ++-- engine/src/ext/vulkan/graphic.cpp | 4 +- engine/src/ext/vulkan/graphics/gui.cpp | 225 ----------------- engine/src/ext/vulkan/graphics/mesh.cpp | 231 ----------------- .../src/ext/vulkan/graphics/rendertarget.cpp | 120 ++++++++- engine/src/ext/vulkan/rendermode.cpp | 1 + engine/src/ext/vulkan/rendermodes/base.cpp | 7 +- .../src/ext/vulkan/rendermodes/deferred.cpp | 156 +++++++----- .../ext/vulkan/rendermodes/rendertarget.cpp | 60 ++++- .../rendermodes/stereoscopic_deferred.cpp | 158 ++++++++---- engine/src/ext/vulkan/rendertarget.cpp | 8 +- engine/src/ext/vulkan/vulkan.cpp | 72 ++++-- engine/src/spec/window/windows.cpp | 4 +- engine/src/utils/camera/camera.cpp | 116 +++++++-- engine/src/utils/text/glyph.cpp | 18 +- ext/gui/gui.cpp | 16 +- ext/main.cpp | 11 +- ext/scenes/world/gui/battle.cpp | 4 +- ext/scenes/world/gui/dialogue.cpp | 2 +- ext/scenes/world/gui/pause.cpp | 2 +- ext/scenes/world/housamo/battle.cpp | 2 +- ext/scenes/world/housamo/dialogue.cpp | 2 +- ext/scenes/world/housamo/sprite.cpp | 47 ++-- ext/scenes/world/player/hands.cpp | 234 +++++++++++++----- ext/scenes/world/player/player.cpp | 9 +- ext/scenes/world/portal/portal.cpp | 160 ++++++++++++ ext/scenes/world/portal/portal.h | 28 +++ ext/scenes/world/terrain/generator.cpp | 12 +- ext/scenes/world/terrain/region.cpp | 5 +- ext/scenes/world/terrain/terrain.cpp | 2 +- ext/scenes/world/world.cpp | 29 ++- ext/scenes/world/world.h | 3 + 58 files changed, 1181 insertions(+), 968 deletions(-) delete mode 100644 engine/inc/uf/ext/vulkan/graphics/gui.h delete mode 100644 engine/inc/uf/ext/vulkan/graphics/mesh.h delete mode 100644 engine/src/ext/vulkan/graphics/gui.cpp delete mode 100644 engine/src/ext/vulkan/graphics/mesh.cpp create mode 100644 ext/scenes/world/portal/portal.cpp create mode 100644 ext/scenes/world/portal/portal.h diff --git a/Makefile b/Makefile index e6fe79c0..8fa4c96e 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ UF_LIBS = # 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 -FLAGS = -Og -std=c++20 -Wall -g -DUF_DISABLE_ALIGNAS -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW +FLAGS = -std=c++20 -Wno-c++11-narrowing -Wno-narrowing -g -DVK_USE_PLATFORM_WIN32_KHR -DUF_USE_VULKAN -DGLM_ENABLE_EXPERIMENTAL -DUF_USE_JSON -DUF_USE_NCURSES -DUF_USE_OPENAL -DUF_USE_VORBIS -DUF_USE_FREETYPE -DUSE_OPENVR_MINGW #-march=native LIB_NAME = uf EXT_LIB_NAME = ext @@ -71,6 +71,10 @@ TARGET_WIN64 = $(BIN_DIR)/$(TARGET_NAME).exe SRCS_SHADERS = $(wildcard bin/data/shaders/*.glsl) TARGET_SHADERS = $(patsubst %.glsl,%.spv,$(SRCS_SHADERS)) +# clang-win64: WIN64_CC=clang++ +# make +# gcc-win64: WIN64_CC=g++ +# make win64: $(EX_WIN64_DLL) $(EXT_EX_WIN64_DLL) $(TARGET_WIN64) $(TARGET_SHADERS) rm-exe64: diff --git a/bin/data/shaders/base.stereo.vert.glsl b/bin/data/shaders/base.stereo.vert.glsl index e7cfa651..0b0af656 100644 --- a/bin/data/shaders/base.stereo.vert.glsl +++ b/bin/data/shaders/base.stereo.vert.glsl @@ -3,7 +3,6 @@ layout (location = 0) in vec3 inPos; layout (location = 1) in vec2 inUv; layout (location = 2) in vec3 inNormal; -layout (location = 3) in uint inColor; layout( push_constant ) uniform PushBlock { uint pass; diff --git a/bin/data/shaders/display.rendertarget.frag.glsl b/bin/data/shaders/display.rendertarget.frag.glsl index a907ee15..00d969ef 100644 --- a/bin/data/shaders/display.rendertarget.frag.glsl +++ b/bin/data/shaders/display.rendertarget.frag.glsl @@ -1,6 +1,10 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require -layout (binding = 1) uniform sampler2D samplerTexture; +layout (binding = 1) uniform sampler samp; +layout (binding = 2) uniform texture2D albedoTexture; +layout (binding = 3) uniform texture2D positionTexture; +layout (binding = 4) uniform texture2D normalTexture; struct Cursor { vec2 position; @@ -12,14 +16,25 @@ layout (location = 0) in vec2 inUv; layout (location = 1) in float inAlpha; layout (location = 2) in Cursor inCursor; -layout (location = 0) out vec4 outFragColor; +layout (location = 0) out vec4 outAlbedoSpecular; +layout (location = 1) out vec4 outPosition; +layout (location = 2) out vec4 outNormal; void main() { - outFragColor = texture(samplerTexture, inUv); + outAlbedoSpecular = texture(sampler2D(albedoTexture, samp), inUv); + if ( inCursor.radius.x <= 0 && inCursor.radius.y <= 0 ) { + vec2 uv = gl_FragCoord.xy / textureSize(albedoTexture, 0); + // uv.x = 1-uv.x; + outAlbedoSpecular = texture(sampler2D(albedoTexture, samp), uv); + outPosition = texture(sampler2D(positionTexture, samp), uv); + outNormal = texture(sampler2D(normalTexture, samp), uv); + if ( outAlbedoSpecular.a < 0.01f ) outAlbedoSpecular = vec4(0,0,0,1); + return; + } float dist = pow(inUv.x - inCursor.position.x, 2) / pow(inCursor.radius.x, 2) + pow(inUv.y - inCursor.position.y, 2) / pow(inCursor.radius.y, 2); if ( dist <= 1 ) { float attenuation = dist; - outFragColor.rgb = mix( inCursor.color.rgb * inCursor.color.a, outFragColor.rgb, attenuation ); + outAlbedoSpecular.rgb = mix( inCursor.color.rgb * inCursor.color.a, outAlbedoSpecular.rgb, attenuation ); } } \ No newline at end of file diff --git a/bin/data/shaders/display.rendertarget.vert.glsl b/bin/data/shaders/display.rendertarget.vert.glsl index bfa06613..7ee36239 100644 --- a/bin/data/shaders/display.rendertarget.vert.glsl +++ b/bin/data/shaders/display.rendertarget.vert.glsl @@ -15,7 +15,6 @@ layout (location = 2) out flat Cursor outCursor; layout( push_constant ) uniform PushBlock { uint pass; - vec2 cursor; } PushConstant; out gl_PerVertex { diff --git a/engine/inc/uf/config.h b/engine/inc/uf/config.h index 83f3c43a..7702cfb3 100644 --- a/engine/inc/uf/config.h +++ b/engine/inc/uf/config.h @@ -82,6 +82,7 @@ // Legacy support #define UF_API_VAR UF_API #define UF_API_CALL __cdecl + #ifdef UF_DISABLE_ALIGNAS #define alignas(X) #endif diff --git a/engine/inc/uf/engine/entity/entity.h b/engine/inc/uf/engine/entity/entity.h index 91b1046e..ad3108de 100644 --- a/engine/inc/uf/engine/entity/entity.h +++ b/engine/inc/uf/engine/entity/entity.h @@ -34,7 +34,7 @@ namespace uf { void setParent(); void setParent( uf::Entity& parent ); - void addChild( uf::Entity& child ); + uf::Entity& addChild( uf::Entity& child ); void moveChild( uf::Entity& child ); void removeChild( uf::Entity& child ); uf::Entity::container_t& getChildren(); diff --git a/engine/inc/uf/ext/vulkan/graphics/deferredrendering.h b/engine/inc/uf/ext/vulkan/graphics/deferredrendering.h index 0321a687..caa08629 100644 --- a/engine/inc/uf/ext/vulkan/graphics/deferredrendering.h +++ b/engine/inc/uf/ext/vulkan/graphics/deferredrendering.h @@ -13,8 +13,8 @@ namespace ext { namespace vulkan { struct UF_API DeferredRenderingGraphic : public Graphic { struct Vertex { - alignas(16) pod::Vector2f position; - alignas(16) pod::Vector2f uv; + pod::Vector2f position; + pod::Vector2f uv; }; static size_t maxLights; diff --git a/engine/inc/uf/ext/vulkan/graphics/gui.h b/engine/inc/uf/ext/vulkan/graphics/gui.h deleted file mode 100644 index ef108f45..00000000 --- a/engine/inc/uf/ext/vulkan/graphics/gui.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include - -namespace ext { - namespace vulkan { - struct UF_API GuiGraphic : public Graphic { - struct Vertex { - alignas(16) pod::Vector2f position; - alignas(16) pod::Vector2f uv; - }; - - struct { - struct { - alignas(16) pod::Matrix4f model[2]; - } matrices; - struct { - alignas(16) pod::Vector4f offset; - alignas(16) pod::Vector4f color; - int32_t mode = 0; - float depth = 0.0f; - } gui; - } uniforms; - struct { - uint32_t pass = 0; - } pushConstants; - - uint32_t indices = 0; - ext::vulkan::Texture2D texture; - - virtual void createCommandBuffer( VkCommandBuffer ); - virtual bool autoAssignable() const; - virtual std::string name() const; - // RAII - virtual void initialize( const std::string& = "" ); - virtual void initialize( Device& device, RenderMode& renderMode ); - virtual void destroy(); - }; - } -} \ No newline at end of file diff --git a/engine/inc/uf/ext/vulkan/graphics/mesh.h b/engine/inc/uf/ext/vulkan/graphics/mesh.h deleted file mode 100644 index e2b7fd9a..00000000 --- a/engine/inc/uf/ext/vulkan/graphics/mesh.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include - -namespace ext { - namespace vulkan { - struct UF_API MeshGraphic : public Graphic { - struct Vertex { - alignas(16) pod::Vector3f position; - alignas(16) pod::Vector2f uv; - alignas(16) pod::Vector3f normal; - }; - - struct { - struct { - alignas(16) pod::Matrix4f model; - alignas(16) pod::Matrix4f view; - alignas(16) pod::Matrix4f projection; - } matrices; - } uniforms; - - uint32_t indices = 0; - ext::vulkan::Texture2D texture; - - virtual void createCommandBuffer( VkCommandBuffer ); - virtual bool autoAssignable() const; - virtual std::string name() const; - // RAII - virtual void initialize( const std::string& = "" ); - virtual void initialize( Device& device, RenderMode& renderMode ); - virtual void destroy(); - }; - } -} \ No newline at end of file diff --git a/engine/inc/uf/ext/vulkan/graphics/rendertarget.h b/engine/inc/uf/ext/vulkan/graphics/rendertarget.h index 57a47c5f..f47d85ca 100644 --- a/engine/inc/uf/ext/vulkan/graphics/rendertarget.h +++ b/engine/inc/uf/ext/vulkan/graphics/rendertarget.h @@ -13,8 +13,8 @@ namespace ext { namespace vulkan { struct UF_API RenderTargetGraphic : public Graphic { struct Vertex { - alignas(16) pod::Vector2f position; - alignas(16) pod::Vector2f uv; + alignas(8) pod::Vector2f position; + alignas(8) pod::Vector2f uv; }; struct { @@ -22,12 +22,11 @@ namespace ext { alignas(16) pod::Matrix4f models[2]; } matrices; struct { - pod::Vector2f position = { 0.5f, 0.5f }; - pod::Vector2f radius = { 0.1f, 0.1f }; - pod::Vector4f color = { 1, 1, 1, 1 }; + alignas(8) pod::Vector2f position = { 0.5f, 0.5f }; + alignas(8) pod::Vector2f radius = { 0.1f, 0.1f }; + alignas(16) pod::Vector4f color = { 1, 1, 1, 1 }; } cursor; - float alpha; - uint8_t _buffer[4]; + alignas(4) float alpha; } uniforms; struct { uint32_t pass = 0; diff --git a/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h b/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h index f1571a28..37efcd0b 100644 --- a/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h +++ b/engine/inc/uf/ext/vulkan/rendermodes/rendertarget.h @@ -10,6 +10,7 @@ namespace ext { VkFence fence; VkCommandBuffer commandBuffer; + std::string target; // RAII virtual std::string getType() const; diff --git a/engine/inc/uf/ext/vulkan/vulkan.h b/engine/inc/uf/ext/vulkan/vulkan.h index b7855574..f9dc261a 100644 --- a/engine/inc/uf/ext/vulkan/vulkan.h +++ b/engine/inc/uf/ext/vulkan/vulkan.h @@ -50,7 +50,7 @@ namespace ext { extern UF_API bool resized; extern UF_API uint32_t currentBuffer; - extern UF_API std::string currentPass; + extern UF_API RenderMode* currentRenderMode; extern UF_API std::vector passes; // extern UF_API std::vector* graphics; extern UF_API std::vector renderModes; @@ -58,6 +58,8 @@ namespace ext { RenderMode& UF_API addRenderMode( RenderMode*, const std::string& = "" ); RenderMode& UF_API getRenderMode( const std::string&, bool = true ); + std::vector UF_API getRenderModes( const std::string&, bool = true ); + void UF_API removeRenderMode( RenderMode*, bool = true ); void UF_API initialize( uint8_t = 0 ); void UF_API tick(); diff --git a/engine/inc/uf/utils/camera/camera.h b/engine/inc/uf/utils/camera/camera.h index 3fa6cf86..29ec2042 100644 --- a/engine/inc/uf/utils/camera/camera.h +++ b/engine/inc/uf/utils/camera/camera.h @@ -24,7 +24,10 @@ namespace uf { pod::Vector3 offset; } m_settings; struct { - pod::Matrix4 view, projection, model; + struct { + pod::Matrix4 view, projection; + } left, right; + pod::Matrix4 model; } m_matrices; pod::Transform<> m_transform; public: @@ -61,8 +64,8 @@ namespace uf { void setTransform( const pod::Transform<>& transform ); - void setView( const pod::Matrix4& mat ); - void setProjection( const pod::Matrix4& mat ); + void setView( const pod::Matrix4& mat, size_t = -1 ); + void setProjection( const pod::Matrix4& mat, size_t = -1 ); void setModel( const pod::Matrix4& mat ); diff --git a/engine/inc/uf/utils/image/pixel.h b/engine/inc/uf/utils/image/pixel.h index 29c23ec5..990ee6f2 100644 --- a/engine/inc/uf/utils/image/pixel.h +++ b/engine/inc/uf/utils/image/pixel.h @@ -5,7 +5,7 @@ namespace pod { // Simple Pixels (designed [to store in arrays] with minimal headaches) template - struct UF_API Pixel { + struct /*UF_API*/ Pixel { // n-dimensional/unspecialized Pixel access T components[N]; // POD information @@ -30,7 +30,7 @@ namespace pod { inline bool operator!=( const Pixel& Pixel ) const; // Equality check between two Pixels (not equals) }; template - struct UF_API Pixel { + struct /*UF_API*/ Pixel { // XYZ access T r = 0; T g = 0; @@ -59,7 +59,7 @@ namespace pod { inline bool operator!=( const Pixel& Pixel ) const; // Equality check between two Pixels (not equals) }; template - struct UF_API Pixel { + struct /*UF_API*/ Pixel { // XYZW access T r = 0; T g = 0; diff --git a/engine/inc/uf/utils/math/matrix.h b/engine/inc/uf/utils/math/matrix.h index 6a2fedbf..2bbef403 100644 --- a/engine/inc/uf/utils/math/matrix.h +++ b/engine/inc/uf/utils/math/matrix.h @@ -61,6 +61,7 @@ namespace uf { // Writes to first value // template pod::Matrix& /*UF_API*/ multiply( T& left, const T& right ); // Multiplies two matrices of same type and size together template pod::Matrix multiply( T& left, const U& right ); // Multiplies two matrices of same type and size together + template pod::Matrix multiply( T& left, const T& right ); template T& /*UF_API*/ invert( T& matrix ); // Flip sign of all components // Complex arithmetic template T /*UF_API*/ translate( const T& matrix, const pod::Vector3t& vector ); @@ -77,7 +78,7 @@ namespace uf { namespace uf { template - class UF_API Matrix { + class /*UF_API*/ Matrix { public: // Easily access POD's type typedef pod::Matrix pod_t; diff --git a/engine/inc/uf/utils/math/quaternion.h b/engine/inc/uf/utils/math/quaternion.h index c63952e8..af0c28c4 100644 --- a/engine/inc/uf/utils/math/quaternion.h +++ b/engine/inc/uf/utils/math/quaternion.h @@ -44,8 +44,8 @@ namespace uf { template T /*UF_API*/ lerp( const T& from, const T& to, double delta ); // Linearly interpolate between two vectors template T /*UF_API*/ slerp( const T& from, const T& to, double delta ); // Spherically interpolate between two vectors - template typename T::type_t /*UF_API*/ distanceSquared( const T& vector ); // Gets the magnitude of the vector - template typename T::type_t /*UF_API*/ distance( const T& vector ); // Gets the magnitude of the vector + template typename T::type_t /*UF_API*/ distanceSquared( const T& a, const T& b ); // Gets the magnitude of the vector + template typename T::type_t /*UF_API*/ distance( const T& a, const T& b ); // Gets the magnitude of the vector template typename T::type_t /*UF_API*/ magnitude( const T& vector ); // Gets the magnitude of the vector template typename T::type_t /*UF_API*/ norm( const T& vector ); // Compute the norm of the vector template T /*UF_API*/ normalize( const T& vector ); // Normalizes a vector @@ -59,12 +59,14 @@ namespace uf { template T inverse( const T& quaternion ); template T& conjugate( T& quaternion ); template T& inverse( T& quaternion ); + + template pod::Quaternion fromMatrix( const pod::Matrix4t& matrix ); } } namespace uf { template - class UF_API Quaternion { + class /*UF_API*/ Quaternion { public: // Easily access POD's type typedef pod::Quaternion pod_t; diff --git a/engine/inc/uf/utils/math/quaternion/pod.inl b/engine/inc/uf/utils/math/quaternion/pod.inl index b3d8d4b7..ceae5157 100644 --- a/engine/inc/uf/utils/math/quaternion/pod.inl +++ b/engine/inc/uf/utils/math/quaternion/pod.inl @@ -33,14 +33,16 @@ template T uf::quaternion::multiply( const T& left, const T& right ) return q; } // Multiplies this quaternion by a scalar +/* template T uf::quaternion::multiply( const T& quaternion, const typename T::type_t& scalar ) { return uf::vector::multiply( quaternion, scalar ); } +*/ // Flip sign of all components template T uf::quaternion::negate( const T& quaternion ) { return uf::quaternion::inverse(quaternion); } -template pod::Quaternion uf::quaternion::identity() { +template pod::Quaternion uf::quaternion::identity() { return pod::Quaternion{ 0, 0, 0, 1 }; } // Writes to first value @@ -238,4 +240,50 @@ template T& uf::quaternion::inverse( T& quaternion ) { .z = -quaternion.z, .w = quaternion.w }; +} +template pod::Quaternion uf::quaternion::fromMatrix( const pod::Matrix4t& m ) { + pod::Quaternion q; +/* + T fourXSquaredMinus1 = m[(4*0)+0] - m[(4*1)+1] - m[(4*2)+2]; + T fourYSquaredMinus1 = m[(4*1)+1] - m[(4*0)+0] - m[(4*2)+2]; + T fourZSquaredMinus1 = m[(4*2)+2] - m[(4*0)+0] - m[(4*1)+1]; + T fourWSquaredMinus1 = m[(4*0)+0] + m[(4*1)+1] + m[(4*2)+2]; + + int biggestIndex = 0; + T fourBiggestSquaredMinus1 = fourWSquaredMinus1; + if(fourXSquaredMinus1 > fourBiggestSquaredMinus1) { + fourBiggestSquaredMinus1 = fourXSquaredMinus1; + biggestIndex = 1; + } + if(fourYSquaredMinus1 > fourBiggestSquaredMinus1) { + fourBiggestSquaredMinus1 = fourYSquaredMinus1; + biggestIndex = 2; + } + if(fourZSquaredMinus1 > fourBiggestSquaredMinus1) { + fourBiggestSquaredMinus1 = fourZSquaredMinus1; + biggestIndex = 3; + } + + T biggestVal = sqrt(fourBiggestSquaredMinus1 + static_cast(1)) * static_cast(0.5); + T mult = static_cast(0.25) / biggestVal; + + switch(biggestIndex) { + case 0: return pod::Quaternion{ biggestVal, (m[(4*1)+2] - m[(4*2)+1]) * mult, (m[(4*2)+0] - m[(4*0)+2]) * mult, (m[(4*0)+1] - m[(4*1)+0]) * mult }; + case 1: return pod::Quaternion{ (m[(4*1)+2] - m[(4*2)+1]) * mult, biggestVal, (m[(4*0)+1] + m[(4*1)+0]) * mult, (m[(4*2)+0] + m[(4*0)+2]) * mult }; + case 2: return pod::Quaternion{ (m[(4*2)+0] - m[(4*0)+2]) * mult, (m[(4*0)+1] + m[(4*1)+0]) * mult, biggestVal, (m[(4*1)+2] + m[(4*2)+1]) * mult }; + case 3: return pod::Quaternion{ (m[(4*0)+1] - m[(4*1)+0]) * mult, (m[(4*2)+0] + m[(4*0)+2]) * mult, (m[(4*1)+2] + m[(4*2)+1]) * mult, biggestVal }; + default: // Silence a -Wswitch-default warning in GCC. Should never actually get here. Assert is just for sanity. + return pod::Quaternion{ 1, 0, 0, 0 }; + } +*/ + + q.w = sqrt(fmax(0, 1 + m[(4*0)+0] + m[(4*1)+1] + m[(4*2)+2])) / 2; + q.x = sqrt(fmax(0, 1 + m[(4*0)+0] - m[(4*1)+1] - m[(4*2)+2])) / 2; + q.y = sqrt(fmax(0, 1 - m[(4*0)+0] + m[(4*1)+1] - m[(4*2)+2])) / 2; + q.z = sqrt(fmax(0, 1 - m[(4*0)+0] - m[(4*1)+1] + m[(4*2)+2])) / 2; + + q.x = copysign(q.x, m[(4*1)+2] - m[(4*2)+1]); + q.y = copysign(q.y, m[(4*2)+0] - m[(4*0)+2]); + q.z = copysign(q.z, m[(4*0)+1] - m[(4*1)+0]); + return q; } \ No newline at end of file diff --git a/engine/inc/uf/utils/math/transform.h b/engine/inc/uf/utils/math/transform.h index 1e19bf83..bfd49ee0 100644 --- a/engine/inc/uf/utils/math/transform.h +++ b/engine/inc/uf/utils/math/transform.h @@ -20,7 +20,7 @@ namespace pod { // Simple transforms (designed [to store in arrays] with minimal headaches) template - struct UF_API Transform { + struct /*UF_API*/ Transform { typedef T type_t; pod::Vector3t position; @@ -117,9 +117,9 @@ namespace uf { if ( flatten ) { uf::Matrix4t translation, rotation, scale; pod::Transform flatten = uf::transform::flatten(transform, false); - flatten.orientation.w *= -1; - rotation = uf::quaternion::matrix(flatten.orientation); + // flatten.orientation.w *= -1; scale = uf::matrix::scale( scale, transform.scale ); + rotation = uf::quaternion::matrix(flatten.orientation); translation = uf::matrix::translate( uf::matrix::identity(), flatten.position ); return translation * rotation * scale; } @@ -141,13 +141,11 @@ namespace uf { return model; } } - template pod::Matrix4t /*UF_API*/ view( const pod::Transform& transform, const pod::Vector3t& offset = {0, 0, 0} ) { - uf::Matrix4t translation, rotation; - pod::Transform flatten = uf::transform::flatten(transform, true); - rotation = uf::quaternion::matrix( flatten.orientation ); - flatten.position += uf::quaternion::rotate( flatten.orientation, offset ); - translation = uf::matrix::translate( uf::matrix::identity(), -flatten.position ); - return rotation * translation; + template pod::Transform fromMatrix( const pod::Matrix4t& matrix ) { + pod::Transform transform; + transform.position = uf::matrix::multiply( matrix, pod::Vector3f{ 0, 0, 0 } ); + transform.orientation = uf::quaternion::fromMatrix( matrix ); + return transform = reorient( transform ); } } } \ No newline at end of file diff --git a/engine/inc/uf/utils/math/vector.h b/engine/inc/uf/utils/math/vector.h index d4237181..690f9e2b 100644 --- a/engine/inc/uf/utils/math/vector.h +++ b/engine/inc/uf/utils/math/vector.h @@ -53,7 +53,7 @@ namespace pod { */ // Simple vectors (designed [to store in arrays] with minimal headaches) template - struct UF_API Vector { + struct /*UF_API*/ Vector { // n-dimensional/unspecialized vector access T components[N]; // POD information @@ -174,7 +174,7 @@ namespace uf { namespace uf { // Provides operations for POD vector template - class UF_API Vector { + class /*UF_API*/ Vector { public: // Easily access POD's type typedef pod::Vector pod_t; diff --git a/engine/inc/uf/utils/math/vector/redundancy.inl b/engine/inc/uf/utils/math/vector/redundancy.inl index b84470e0..221c34ab 100644 --- a/engine/inc/uf/utils/math/vector/redundancy.inl +++ b/engine/inc/uf/utils/math/vector/redundancy.inl @@ -1,6 +1,6 @@ namespace pod { template - struct UF_API Vector { + struct /*UF_API*/ Vector { // XY access T x; // n-dimensional/unspecialized vector access @@ -36,7 +36,7 @@ namespace pod { inline bool operator>=( const Vector& vector ) const; // Equality check between two vectors (greater than or equals) }; template - struct UF_API Vector { + struct /*UF_API*/ Vector { // XY access T x; T y; @@ -73,7 +73,7 @@ namespace pod { inline bool operator>=( const Vector& vector ) const; // Equality check between two vectors (greater than or equals) }; template - struct UF_API Vector { + struct /*UF_API*/ Vector { // XYZ access T x; T y; @@ -111,7 +111,7 @@ namespace pod { inline bool operator>=( const Vector& vector ) const; // Equality check between two vectors (greater than or equals) }; template - struct UF_API Vector { + struct /*UF_API*/ Vector { // XYZW access T x; T y; @@ -519,7 +519,7 @@ inline bool pod::Vector::operator>=( const pod::Vector& vector ) const // namespace uf { template - struct UF_API Vector { + struct /*UF_API*/ Vector { public: // Easily access POD's type typedef pod::Vector pod_t; @@ -609,7 +609,7 @@ namespace uf { inline operator const pod_t&() const { return this->m_pod; } }; template - struct UF_API Vector { + struct /*UF_API*/ Vector { public: // Easily access POD's type typedef pod::Vector pod_t; @@ -700,7 +700,7 @@ namespace uf { inline operator const pod_t&() const { return this->m_pod; } }; template - struct UF_API Vector { + struct /*UF_API*/ Vector { public: // Easily access POD's type typedef pod::Vector pod_t; @@ -796,7 +796,7 @@ namespace uf { inline operator const pod_t&() const { return this->m_pod; } }; template - struct UF_API Vector { + struct /*UF_API*/ Vector { public: // Easily access POD's type typedef pod::Vector pod_t; diff --git a/engine/inc/uf/utils/mesh/mesh.h b/engine/inc/uf/utils/mesh/mesh.h index e9dd1d2b..f202d531 100644 --- a/engine/inc/uf/utils/mesh/mesh.h +++ b/engine/inc/uf/utils/mesh/mesh.h @@ -8,13 +8,13 @@ #include namespace pod { - struct UF_API Vertex_3F2F3F32B { + struct /*UF_API*/ Vertex_3F2F3F32B { alignas(16) pod::Vector3f position; - alignas(16) pod::Vector2f uv; + alignas(8) pod::Vector2f uv; alignas(16) pod::Vector3f normal; alignas(16) pod::Vector4t color; - static std::vector descriptor; + static UF_API std::vector descriptor; bool operator==( const Vertex_3F2F3F32B& that ) const { return this->position == that.position && @@ -25,12 +25,12 @@ namespace pod { bool operator!=( const Vertex_3F2F3F32B& that ) const { return !(*this == that); } }; - struct UF_API Vertex_3F2F3F { + struct /*UF_API*/ Vertex_3F2F3F { alignas(16) pod::Vector3f position; - alignas(16) pod::Vector2f uv; + alignas(8) pod::Vector2f uv; alignas(16) pod::Vector3f normal; - static std::vector descriptor; + static UF_API std::vector descriptor; bool operator==( const Vertex_3F2F3F& that ) const { return this->position == that.position && @@ -40,11 +40,11 @@ namespace pod { bool operator!=( const Vertex_3F2F3F& that ) const { return !(*this == that); } }; - struct UF_API Vertex_3F2F { + struct /*UF_API*/ Vertex_3F2F { alignas(16) pod::Vector3f position; - alignas(16) pod::Vector2f uv; + alignas(8) pod::Vector2f uv; - static std::vector descriptor; + static UF_API std::vector descriptor; bool operator==( const Vertex_3F2F& that ) const { return this->position == that.position && @@ -52,10 +52,10 @@ namespace pod { } bool operator!=( const Vertex_3F2F& that ) const { return !(*this == that); } }; - struct UF_API Vertex_3F { + struct /*UF_API*/ Vertex_3F { alignas(16) pod::Vector3f position; - static std::vector descriptor; + static UF_API std::vector descriptor; bool operator==( const Vertex_3F& that ) const { return this->position == that.position; @@ -104,13 +104,13 @@ namespace std { }; } namespace uf { - struct UF_API MeshBase { + struct /*UF_API*/ MeshBase { public: ext::vulkan::BaseGraphic graphic; bool generated = false; }; template - class UF_API BaseMesh : public MeshBase { + class /*UF_API*/ BaseMesh : public MeshBase { public: typedef T vertex_t; std::vector vertices; @@ -177,8 +177,8 @@ namespace uf { struct { alignas(16) pod::Vector4f offset; alignas(16) pod::Vector4f color; - int32_t mode = 0; - float depth = 0.0f; + alignas(4) int32_t mode = 0; + alignas(4) float depth = 0.0f; } gui; }; struct StereoGuiMeshDescriptor { @@ -188,29 +188,8 @@ namespace uf { struct { alignas(16) pod::Vector4f offset; alignas(16) pod::Vector4f color; - int32_t mode = 0; - float depth = 0.0f; + alignas(4) int32_t mode = 0; + alignas(4) float depth = 0.0f; } gui; }; -} - -/* - struct { - struct { - alignas(16) pod::Matrix4f model; - alignas(16) pod::Matrix4f view; - alignas(16) pod::Matrix4f projection; - } matrices; - } uniforms; - struct { - struct { - alignas(16) pod::Matrix4f model; - } matrices; - struct { - alignas(16) pod::Vector4f offset; - alignas(16) pod::Vector4f color; - int32_t mode = 0; - float depth = 0.0f; - } gui; - } uniforms; -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/engine/inc/uf/utils/string/rle.inl b/engine/inc/uf/utils/string/rle.inl index 5c4123a9..f3e1e833 100644 --- a/engine/inc/uf/utils/string/rle.inl +++ b/engine/inc/uf/utils/string/rle.inl @@ -1,4 +1,4 @@ -template +template typename pod::RLE::string_t uf::rle::encode( const std::vector& source ) { typename pod::RLE::string_t destination; destination.reserve( source.size() ); @@ -12,7 +12,7 @@ typename pod::RLE::string_t uf::rle::encode( const std::vector& source ) destination.shrink_to_fit(); return destination; } -template +template std::vector uf::rle::decode( const pod::RLE& source ) { std::vector destination; diff --git a/engine/inc/uf/utils/time/time.h b/engine/inc/uf/utils/time/time.h index 695a0adf..f72740d3 100644 --- a/engine/inc/uf/utils/time/time.h +++ b/engine/inc/uf/utils/time/time.h @@ -54,7 +54,7 @@ namespace uf { uf::Time UF_API_CALL operator+( const uf::Time& t ); }; template - class UF_API Timer { + class /*UF_API*/ Timer { public: typedef T time_t; typedef spec::Time::exp_t exp_t; diff --git a/engine/inc/uf/utils/userdata/userdata.inl b/engine/inc/uf/utils/userdata/userdata.inl index 264499c4..012234e1 100644 --- a/engine/inc/uf/utils/userdata/userdata.inl +++ b/engine/inc/uf/utils/userdata/userdata.inl @@ -3,9 +3,22 @@ // Allows copy via assignment! template pod::Userdata* uf::userdata::create( const T& data ) { + void* pointer = operator new( sizeof(pod::Userdata) + sizeof(uint8_t) * (sizeof data) ); + pod::Userdata* userdata = (pod::Userdata*) pointer; + userdata->len = sizeof data; + //memcpy( userdata->data, &data, sizeof data ); + //new (userdata->data) T(data); + union { + uint8_t* from; + T* to; + } static kludge; + kludge.from = userdata->data; + new (kludge.to) T(data); + return userdata; +/* std::size_t len = sizeof data; // get size of data // void* pointer = malloc( sizeof(pod::Userdata) + sizeof(uint8_t) * len ); // allocate data for the userdata struct, and then some - void* pointer = operator new( sizeof(pod::Userdata) + sizeof(uint8_t) * len ); // allocate data for the userdata struct, and then some + void* pointer = operator new( sizeof(pod::Userdata) + sizeof(uint8_t) * (len) ); // allocate data for the userdata struct, and then some pod::Userdata* userdata = (pod::Userdata*) pointer; userdata->len = len; // don't forget to store its data's length! // Allows warningless conversion from placeholder storage type to userdata type @@ -16,6 +29,7 @@ pod::Userdata* uf::userdata::create( const T& data ) { kludge.from = userdata->data; new (kludge.to) T(data); // copy via placement new w/ copy constructor return userdata; // return address of userdata +*/ } // Easy way to get the userdata as a reference #include diff --git a/engine/src/engine/entity/entity.cpp b/engine/src/engine/entity/entity.cpp index 458e597f..01159739 100644 --- a/engine/src/engine/entity/entity.cpp +++ b/engine/src/engine/entity/entity.cpp @@ -20,9 +20,10 @@ void uf::Entity::setParent() { void uf::Entity::setParent( uf::Entity& parent ) { this->m_parent = &parent == &uf::Entity::null ? NULL : &parent; } -void uf::Entity::addChild( uf::Entity& child ) { +uf::Entity& uf::Entity::addChild( uf::Entity& child ) { this->m_children.push_back(&child); child.setParent(*this); + return child; } void uf::Entity::removeChild( uf::Entity& child ) { for ( uf::Entity::container_t::iterator it = this->m_children.begin(); it != this->m_children.end(); ++it ) { diff --git a/engine/src/engine/object/object.cpp b/engine/src/engine/object/object.cpp index 7b708360..a8529c7d 100644 --- a/engine/src/engine/object/object.cpp +++ b/engine/src/engine/object/object.cpp @@ -158,13 +158,16 @@ bool uf::Object::load( const uf::Serializer& json ) { load = true; } if ( load ) { - float x = json["transform"]["position"][0].asFloat(); - float y = json["transform"]["position"][1].asFloat(); - float z = json["transform"]["position"][2].asFloat(); - - transform.position = { x, y, z }; + transform.position.x = json["transform"]["position"][0].asFloat(); + transform.position.y = json["transform"]["position"][1].asFloat(); + transform.position.z = json["transform"]["position"][2].asFloat(); transform.orientation = uf::quaternion::identity(); - if ( json["transform"]["rotation"]["angle"].asFloat() != 0 ) { + if ( json["transform"]["orientation"].isArray() ) { + transform.orientation.x = json["transform"]["orientation"][0].asFloat(); + transform.orientation.y = json["transform"]["orientation"][1].asFloat(); + transform.orientation.z = json["transform"]["orientation"][2].asFloat(); + transform.orientation.w = json["transform"]["orientation"][3].asFloat(); + } else if ( json["transform"]["rotation"]["angle"].asFloat() != 0 ) { transform.orientation = uf::quaternion::axisAngle( { json["transform"]["rotation"]["axis"][0].asFloat(), json["transform"]["rotation"]["axis"][1].asFloat(), diff --git a/engine/src/ext/openvr/openvr.cpp b/engine/src/ext/openvr/openvr.cpp index 5c22ac47..baec6c0d 100644 --- a/engine/src/ext/openvr/openvr.cpp +++ b/engine/src/ext/openvr/openvr.cpp @@ -186,10 +186,30 @@ bool ext::openvr::initialize( int stage ) { split = uf::string::split( shortname, "." ); if ( split.front() == "hapticVibration" ) { std::cout << "Registered hook for haptic: " << ("VR:Haptics."+split.back()) << std::endl; - uf::hooks.addHook( "VR:Haptics."+split.back(), [&](const std::string& event)->std::string{ + + uf::hooks.addHook( "VR:Haptics."+split.back(), [](const std::string& event)->std::string{ uf::Serializer json = event; - if ( vr::VRInputError_None != vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].asFloat(), json["duration"].asFloat(), json["frequency"].asFloat(), json["amplitude"].asFloat(), vr::k_ulInvalidInputValueHandle ) ) + std::string name; + std::string side = json["side"].asString(); + uf::Serializer manifest; + manifest.readFromFile(ext::openvr::driver.manifest); + { + for ( auto i = 0; i < manifest["actions"].size(); ++i ) { + std::string handleName = manifest["actions"][i]["name"].asString(); + std::vector split = uf::string::split( handleName, "/" ); + std::string shortname = split.back(); + if ( shortname != "hapticVibration." + side ) continue; + name = handleName; + break; + } + } + if ( name == "" ) return "false"; + vr::VRActionHandle_t& handle = handles.actions[name]; + auto err = vr::VRInput()->TriggerHapticVibrationAction( handle, json["delay"].asFloat(), json["duration"].asFloat(), json["frequency"].asFloat(), json["amplitude"].asFloat(), vr::k_ulInvalidInputValueHandle ); + if ( err != vr::VRInputError_None ) { + std::cout << err << std::endl; return "false"; + } return "true"; }); } @@ -517,17 +537,7 @@ pod::Vector3f ext::openvr::hmdPosition( vr::Hmd_Eye eye ) { return hmdPosition() + hmdEyePosition( eye ); } pod::Quaternion<> ext::openvr::hmdQuaternion() { - pod::Matrix4t<> mat = hmdHeadPositionMatrix(); - pod::Quaternion<> q; - q.w = sqrt(fmax(0, 1 + mat[(4*0)+0] + mat[(4*1)+1] + mat[(4*2)+2])) / 2; - q.x = sqrt(fmax(0, 1 + mat[(4*0)+0] - mat[(4*1)+1] - mat[(4*2)+2])) / 2; - q.y = sqrt(fmax(0, 1 - mat[(4*0)+0] + mat[(4*1)+1] - mat[(4*2)+2])) / 2; - q.z = sqrt(fmax(0, 1 - mat[(4*0)+0] - mat[(4*1)+1] + mat[(4*2)+2])) / 2; - - q.x = copysign(q.x, mat[(4*1)+2] - mat[(4*2)+1]); - q.y = copysign(q.y, mat[(4*2)+0] - mat[(4*0)+2]); - q.z = copysign(q.z, mat[(4*0)+1] - mat[(4*1)+0]); - return q; // * pod::Vector4f{ 1, 1, -1, -1 }; + return uf::quaternion::fromMatrix( hmdHeadPositionMatrix() ); // * pod::Vector4f{ 1, 1, -1, -1 }; } pod::Matrix4t<> ext::openvr::hmdViewMatrix( vr::Hmd_Eye eye, const pod::Matrix4f& mv ) { return hmdEyePositionMatrix( eye ) * uf::matrix::translate( uf::matrix::identity(), hmdPosition() ) * uf::matrix::inverse( uf::quaternion::matrix( ext::openvr::hmdQuaternion() * pod::Vector4f{ 1, 1, -1, -1 } ) ) * mv; @@ -622,17 +632,7 @@ pod::Vector3f ext::openvr::controllerPosition( vr::Controller_Hand hand, bool ti }; } pod::Quaternion<> ext::openvr::controllerQuaternion( vr::Controller_Hand hand, bool tip ) { - pod::Matrix4t<> mat = controllerMatrix( hand, tip ); - pod::Quaternion<> q; - q.w = sqrt(fmax(0, 1 + mat[(4*0)+0] + mat[(4*1)+1] + mat[(4*2)+2])) / 2; - q.x = sqrt(fmax(0, 1 + mat[(4*0)+0] - mat[(4*1)+1] - mat[(4*2)+2])) / 2; - q.y = sqrt(fmax(0, 1 - mat[(4*0)+0] + mat[(4*1)+1] - mat[(4*2)+2])) / 2; - q.z = sqrt(fmax(0, 1 - mat[(4*0)+0] - mat[(4*1)+1] + mat[(4*2)+2])) / 2; - - q.x = copysign(q.x, mat[(4*1)+2] - mat[(4*2)+1]); - q.y = copysign(q.y, mat[(4*2)+0] - mat[(4*0)+2]); - q.z = copysign(q.z, mat[(4*0)+1] - mat[(4*1)+0]); - return q * pod::Vector4f{ 1, 1, -1, 1 }; + return uf::quaternion::fromMatrix( controllerMatrix( hand, tip ) ) * pod::Vector4f{ 1, 1, -1, 1 }; } pod::Matrix4t<> ext::openvr::controllerTranslationMatrix( vr::Controller_Hand hand, bool tip ) { return uf::matrix::translate( uf::matrix::identity(), controllerPosition( hand, tip ) ); diff --git a/engine/src/ext/vulkan/graphic.cpp b/engine/src/ext/vulkan/graphic.cpp index a4462811..2022599b 100644 --- a/engine/src/ext/vulkan/graphic.cpp +++ b/engine/src/ext/vulkan/graphic.cpp @@ -124,12 +124,12 @@ void ext::vulkan::Graphic::initializeDescriptorLayout( const std::vectorsubpass; VK_CHECK_RESULT(vkCreateGraphicsPipelines(*device, device->pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipeline)); - ext::vulkan::mutex.unlock(); + // ext::vulkan::mutex.unlock(); } // Set descriptor pool void ext::vulkan::Graphic::initializeDescriptorPool( const std::vector& poolSizes, size_t length ) { diff --git a/engine/src/ext/vulkan/graphics/gui.cpp b/engine/src/ext/vulkan/graphics/gui.cpp deleted file mode 100644 index 1fc0ca33..00000000 --- a/engine/src/ext/vulkan/graphics/gui.cpp +++ /dev/null @@ -1,225 +0,0 @@ -#include -#include -#include -#include - -namespace { - uint32_t VERTEX_BUFFER_BIND_ID = 0; -} -bool ext::vulkan::GuiGraphic::autoAssignable() const { - return false; -} -std::string ext::vulkan::GuiGraphic::name() const { - return "GuiGraphic"; -} -void ext::vulkan::GuiGraphic::createCommandBuffer( VkCommandBuffer commandBuffer ) { - Buffer& vertexBuffer = buffers.at(1); - Buffer& indexBuffer = buffers.at(2); - // - pushConstants = { ext::openvr::renderPass }; - vkCmdPushConstants( commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(pushConstants), &pushConstants ); - // Bind descriptor sets describing shader binding points - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); - // Bind the rendering pipeline - // The pipeline (state object) contains all states of the rendering pipeline, binding it will set all the states specified at pipeline creation time - vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - // Bind triangle vertex buffer (contains position and colors) - VkDeviceSize offsets[1] = { 0 }; - vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.buffer, offsets); - // Bind triangle index buffer - vkCmdBindIndexBuffer(commandBuffer, indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32); - // Draw indexed triangle - vkCmdDrawIndexed(commandBuffer, static_cast(indices), 1, 0, 0, 1); -} -void ext::vulkan::GuiGraphic::initialize( const std::string& renderMode ) { - return initialize(this->device ? *device : ext::vulkan::device, ext::vulkan::getRenderMode(renderMode)); -} -void ext::vulkan::GuiGraphic::initialize( Device& device, RenderMode& renderMode ) { - // asset correct buffer sizes - assert( buffers.size() >= 2 ); - ext::vulkan::Graphic::initialize( device, renderMode ); - // set descriptor layout - initializeDescriptorLayout({ - // Vertex shader - ext::vulkan::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - VK_SHADER_STAGE_VERTEX_BIT, - 0 - ), - // Fragment shader - ext::vulkan::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_SHADER_STAGE_FRAGMENT_BIT, - 1 - ) - }, sizeof(pushConstants)); - // Create uniform buffer - initializeBuffer( - (void*) &uniforms, - sizeof(uniforms), - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - false - ); - // Swap buffers - // Move uniform buffer to the front - { - for ( auto it = buffers.begin(); it != buffers.end(); ++it ) { - Buffer& buffer = *it; - if ( !(buffer.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) ) continue; - Buffer uniformBuffer = std::move(buffer); - buffers.erase(it); - buffers.insert( buffers.begin(), std::move(uniformBuffer) ); - break; - } - - } -/* - buffers = { - std::move(buffers.at(2)), - std::move(buffers.at(0)), - std::move(buffers.at(1)), - }; -*/ - - // check - // set pipeline - { - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = ext::vulkan::initializers::pipelineInputAssemblyStateCreateInfo( - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - 0, - VK_FALSE - ); - VkPipelineRasterizationStateCreateInfo rasterizationState = ext::vulkan::initializers::pipelineRasterizationStateCreateInfo( - VK_POLYGON_MODE_FILL, - VK_CULL_MODE_BACK_BIT, - ext::openvr::enabled ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE, - 0 - ); - VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState( - VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, - VK_TRUE - ); - blendAttachmentState.blendEnable = VK_TRUE; - blendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - blendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD; - blendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - blendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD; - VkPipelineColorBlendStateCreateInfo colorBlendState = ext::vulkan::initializers::pipelineColorBlendStateCreateInfo( - 1, - &blendAttachmentState - ); - colorBlendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - colorBlendState.logicOpEnable = VK_FALSE; - colorBlendState.logicOp = VK_LOGIC_OP_COPY; - colorBlendState.attachmentCount = 1; - colorBlendState.pAttachments = &blendAttachmentState; - colorBlendState.blendConstants[0] = 0.0f; - colorBlendState.blendConstants[1] = 0.0f; - colorBlendState.blendConstants[2] = 0.0f; - colorBlendState.blendConstants[3] = 0.0f; - VkPipelineDepthStencilStateCreateInfo depthStencilState = ext::vulkan::initializers::pipelineDepthStencilStateCreateInfo( - VK_TRUE, - VK_TRUE, - //VK_COMPARE_OP_LESS_OR_EQUAL - VK_COMPARE_OP_GREATER_OR_EQUAL - ); - VkPipelineViewportStateCreateInfo viewportState = ext::vulkan::initializers::pipelineViewportStateCreateInfo( - 1, 1, 0 - ); - VkPipelineMultisampleStateCreateInfo multisampleState = ext::vulkan::initializers::pipelineMultisampleStateCreateInfo( - VK_SAMPLE_COUNT_1_BIT, - 0 - ); - std::vector dynamicStateEnables = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR - }; - VkPipelineDynamicStateCreateInfo dynamicState = ext::vulkan::initializers::pipelineDynamicStateCreateInfo( - dynamicStateEnables.data(), - static_cast(dynamicStateEnables.size()), - 0 - ); - - // Binding description - std::vector vertexBindingDescriptions = { - ext::vulkan::initializers::vertexInputBindingDescription( - VERTEX_BUFFER_BIND_ID, - sizeof(Vertex), - VK_VERTEX_INPUT_RATE_VERTEX - ) - }; - // Attribute descriptions - // Describes memory layout and shader positions - std::vector vertexAttributeDescriptions = { - // Location 0 : Position - ext::vulkan::initializers::vertexInputAttributeDescription( - VERTEX_BUFFER_BIND_ID, - 0, - VK_FORMAT_R32G32_SFLOAT, - offsetof(Vertex, position) - ), - // Location 1 : Texture coordinates - ext::vulkan::initializers::vertexInputAttributeDescription( - VERTEX_BUFFER_BIND_ID, - 1, - VK_FORMAT_R32G32_SFLOAT, - offsetof(Vertex, uv) - ) - }; - - VkPipelineVertexInputStateCreateInfo vertexInputState = ext::vulkan::initializers::pipelineVertexInputStateCreateInfo(); - vertexInputState.vertexBindingDescriptionCount = static_cast(vertexBindingDescriptions.size()); - vertexInputState.pVertexBindingDescriptions = vertexBindingDescriptions.data(); - vertexInputState.vertexAttributeDescriptionCount = static_cast(vertexAttributeDescriptions.size()); - vertexInputState.pVertexAttributeDescriptions = vertexAttributeDescriptions.data(); - - VkGraphicsPipelineCreateInfo pipelineCreateInfo = ext::vulkan::initializers::pipelineCreateInfo( - pipelineLayout, - renderMode.renderTarget.renderPass, - 0 - ); - pipelineCreateInfo.pVertexInputState = &vertexInputState; - pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; - pipelineCreateInfo.pRasterizationState = &rasterizationState; - pipelineCreateInfo.pColorBlendState = &colorBlendState; - pipelineCreateInfo.pMultisampleState = &multisampleState; - pipelineCreateInfo.pViewportState = &viewportState; - pipelineCreateInfo.pDepthStencilState = &depthStencilState; - pipelineCreateInfo.pDynamicState = &dynamicState; - pipelineCreateInfo.stageCount = static_cast(shader.stages.size()); - pipelineCreateInfo.pStages = shader.stages.data(); - pipelineCreateInfo.subpass = this->subpass; - - initializePipeline(pipelineCreateInfo); - } - // Set descriptor pool - initializeDescriptorPool({ - ext::vulkan::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), - ext::vulkan::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1) - }, 1); - // Set descriptor set - initializeDescriptorSet({ - // Binding 0 : Projection/View matrix uniform buffer - ext::vulkan::initializers::writeDescriptorSet( - descriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &(buffers.at(0).descriptor) - ), - // Binding 1 : Fragment shader texture sampler - // Fragment shader: layout (binding = 1) uniform sampler2D samplerColor; - ext::vulkan::initializers::writeDescriptorSet( - descriptorSet, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, - &texture.descriptor - ) - }); -} -void ext::vulkan::GuiGraphic::destroy() { - texture.destroy(); - ext::vulkan::Graphic::destroy(); -} \ No newline at end of file diff --git a/engine/src/ext/vulkan/graphics/mesh.cpp b/engine/src/ext/vulkan/graphics/mesh.cpp deleted file mode 100644 index fef3c37a..00000000 --- a/engine/src/ext/vulkan/graphics/mesh.cpp +++ /dev/null @@ -1,231 +0,0 @@ -#include -#include -#include -#include - -namespace { - uint32_t VERTEX_BUFFER_BIND_ID = 0; -} -bool ext::vulkan::MeshGraphic::autoAssignable() const { - return false; -} -std::string ext::vulkan::MeshGraphic::name() const { - return "MeshGraphic"; -} -void ext::vulkan::MeshGraphic::createCommandBuffer( VkCommandBuffer commandBuffer ) { - assert( buffers.size() >= 2 ); - Buffer& vertexBuffer = buffers.at(1); - Buffer& indexBuffer = buffers.at(2); - // Bind descriptor sets describing shader binding points - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); - // Bind the rendering pipeline - // The pipeline (state object) contains all states of the rendering pipeline, binding it will set all the states specified at pipeline creation time - vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - // Bind triangle vertex buffer (contains position and colors) - VkDeviceSize offsets[1] = { 0 }; - vkCmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.buffer, offsets); - // Bind triangle index buffer - vkCmdBindIndexBuffer(commandBuffer, indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32); - // Draw indexed triangle - vkCmdDrawIndexed(commandBuffer, static_cast(indices), 1, 0, 0, 1); -} -void ext::vulkan::MeshGraphic::initialize( const std::string& renderMode ) { - return initialize(this->device ? *device : ext::vulkan::device, ext::vulkan::getRenderMode(renderMode)); -} -void ext::vulkan::MeshGraphic::initialize( Device& device, RenderMode& renderMode ) { - // asset correct buffer sizes - assert( buffers.size() >= 2 ); - ext::vulkan::Graphic::initialize( device, renderMode ); - // set descriptor layout - initializeDescriptorLayout({ - // Vertex shader - ext::vulkan::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - VK_SHADER_STAGE_VERTEX_BIT, - 0 - ), - // Fragment shader - ext::vulkan::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - VK_SHADER_STAGE_FRAGMENT_BIT, - 1 - ) - }); - // Create uniform buffer - initializeBuffer( - (void*) &uniforms, - sizeof(uniforms), - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - false - ); - // Move uniform buffer to the front - { - for ( auto it = buffers.begin(); it != buffers.end(); ++it ) { - Buffer& buffer = *it; - if ( !(buffer.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) ) continue; - Buffer uniformBuffer = std::move(buffer); - buffers.erase(it); - buffers.insert( buffers.begin(), std::move(uniformBuffer) ); - break; - } - - } -/* - buffers = { - std::move(buffers.at(2)), - std::move(buffers.at(0)), - std::move(buffers.at(1)), - }; -*/ - - // check -/* - { - size_t total = 0; - { - VK_CHECK_RESULT(buffers.at(2).map()); - std::cout << "INDICES\n"; for ( size_t i = 0; i < indices; ++i ) std::cout << ((uint32_t*) buffers.at(2).mapped)[i] << " "; std::cout << "\n" << std::endl; - for ( size_t i = 0; i < indices; ++i ) if ( ((uint32_t*) buffers.at(2).mapped)[i] > total ) total = ((uint32_t*) buffers.at(2).mapped)[i]; - buffers.at(2).unmap(); - } - ++total; - std::cout << (total *= 2 + 3 + 3 + 4) << std::endl; - { - VK_CHECK_RESULT(buffers.at(1).map()); - std::cout << "VERTICES\n"; for ( size_t i = 0; i < total; ++i ) std::cout << ((float*) buffers.at(1).mapped)[i] << " "; std::cout << "\n" << std::endl; - buffers.at(1).unmap(); - } - } -*/ - // set pipeline - { - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = ext::vulkan::initializers::pipelineInputAssemblyStateCreateInfo( - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - 0, - VK_FALSE - ); - VkPipelineRasterizationStateCreateInfo rasterizationState = ext::vulkan::initializers::pipelineRasterizationStateCreateInfo( - VK_POLYGON_MODE_FILL, - VK_CULL_MODE_BACK_BIT, - ext::openvr::enabled ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE, - 0 - ); - VkPipelineColorBlendAttachmentState blendAttachmentState = ext::vulkan::initializers::pipelineColorBlendAttachmentState( - 0xf, - VK_FALSE - ); - VkPipelineColorBlendStateCreateInfo colorBlendState = ext::vulkan::initializers::pipelineColorBlendStateCreateInfo( - 1, - &blendAttachmentState - ); - VkPipelineDepthStencilStateCreateInfo depthStencilState = ext::vulkan::initializers::pipelineDepthStencilStateCreateInfo( - VK_TRUE, - VK_TRUE, - //VK_COMPARE_OP_LESS_OR_EQUAL - VK_COMPARE_OP_GREATER_OR_EQUAL - ); - VkPipelineViewportStateCreateInfo viewportState = ext::vulkan::initializers::pipelineViewportStateCreateInfo( - 1, 1, 0 - ); - VkPipelineMultisampleStateCreateInfo multisampleState = ext::vulkan::initializers::pipelineMultisampleStateCreateInfo( - VK_SAMPLE_COUNT_1_BIT, - 0 - ); - std::vector dynamicStateEnables = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR - }; - VkPipelineDynamicStateCreateInfo dynamicState = ext::vulkan::initializers::pipelineDynamicStateCreateInfo( - dynamicStateEnables.data(), - static_cast(dynamicStateEnables.size()), - 0 - ); - - // Binding description - std::vector vertexBindingDescriptions = { - ext::vulkan::initializers::vertexInputBindingDescription( - VERTEX_BUFFER_BIND_ID, - sizeof(Vertex), - VK_VERTEX_INPUT_RATE_VERTEX - ) - }; - // Attribute descriptions - // Describes memory layout and shader positions - std::vector vertexAttributeDescriptions = { - // Location 0 : Position - ext::vulkan::initializers::vertexInputAttributeDescription( - VERTEX_BUFFER_BIND_ID, - 0, - VK_FORMAT_R32G32B32_SFLOAT, - offsetof(Vertex, position) - ), - // Location 1 : Texture coordinates - ext::vulkan::initializers::vertexInputAttributeDescription( - VERTEX_BUFFER_BIND_ID, - 1, - VK_FORMAT_R32G32_SFLOAT, - offsetof(Vertex, uv) - ), - // Location 1 : Vertex normal - ext::vulkan::initializers::vertexInputAttributeDescription( - VERTEX_BUFFER_BIND_ID, - 2, - VK_FORMAT_R32G32B32_SFLOAT, - offsetof(Vertex, normal) - ) - }; - - VkPipelineVertexInputStateCreateInfo vertexInputState = ext::vulkan::initializers::pipelineVertexInputStateCreateInfo(); - vertexInputState.vertexBindingDescriptionCount = static_cast(vertexBindingDescriptions.size()); - vertexInputState.pVertexBindingDescriptions = vertexBindingDescriptions.data(); - vertexInputState.vertexAttributeDescriptionCount = static_cast(vertexAttributeDescriptions.size()); - vertexInputState.pVertexAttributeDescriptions = vertexAttributeDescriptions.data(); - - VkGraphicsPipelineCreateInfo pipelineCreateInfo = ext::vulkan::initializers::pipelineCreateInfo( - pipelineLayout, - renderMode.renderTarget.renderPass, - 0 - ); - pipelineCreateInfo.pVertexInputState = &vertexInputState; - pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; - pipelineCreateInfo.pRasterizationState = &rasterizationState; - pipelineCreateInfo.pColorBlendState = &colorBlendState; - pipelineCreateInfo.pMultisampleState = &multisampleState; - pipelineCreateInfo.pViewportState = &viewportState; - pipelineCreateInfo.pDepthStencilState = &depthStencilState; - pipelineCreateInfo.pDynamicState = &dynamicState; - pipelineCreateInfo.stageCount = static_cast(shader.stages.size()); - pipelineCreateInfo.pStages = shader.stages.data(); - pipelineCreateInfo.subpass = this->subpass; - - initializePipeline(pipelineCreateInfo); - } - // Set descriptor pool - initializeDescriptorPool({ - ext::vulkan::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), - ext::vulkan::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1) - }, 1); - // Set descriptor set - initializeDescriptorSet({ - // Binding 0 : Projection/View matrix uniform buffer - ext::vulkan::initializers::writeDescriptorSet( - descriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &(buffers.at(0).descriptor) - ), - // Binding 1 : Fragment shader texture sampler - // Fragment shader: layout (binding = 1) uniform sampler2D samplerColor; - ext::vulkan::initializers::writeDescriptorSet( - descriptorSet, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, - &texture.descriptor - ) - }); -} -void ext::vulkan::MeshGraphic::destroy() { - texture.destroy(); - ext::vulkan::Graphic::destroy(); -} \ No newline at end of file diff --git a/engine/src/ext/vulkan/graphics/rendertarget.cpp b/engine/src/ext/vulkan/graphics/rendertarget.cpp index c4a19c8b..5b378300 100644 --- a/engine/src/ext/vulkan/graphics/rendertarget.cpp +++ b/engine/src/ext/vulkan/graphics/rendertarget.cpp @@ -86,6 +86,49 @@ void ext::vulkan::RenderTargetGraphic::initialize( Device& device, RenderMode& r assert( buffers.size() >= 2 ); ext::vulkan::Graphic::initialize( device, renderMode ); // set descriptor layout + { + std::vector bindings = { + // Uniforms + ext::vulkan::initializers::descriptorSetLayoutBinding( + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + VK_SHADER_STAGE_VERTEX_BIT, + 0 + ), + ext::vulkan::initializers::descriptorSetLayoutBinding( + VK_DESCRIPTOR_TYPE_SAMPLER, + VK_SHADER_STAGE_FRAGMENT_BIT, + 1 + ), + }; + /* + bindings.push_back(ext::vulkan::initializers::descriptorSetLayoutBinding( + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + VK_SHADER_STAGE_FRAGMENT_BIT, + bindings.size() + )); + */ + for ( auto& attachment : renderTarget->attachments ) { + if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue; + bindings.push_back(ext::vulkan::initializers::descriptorSetLayoutBinding( + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + VK_SHADER_STAGE_FRAGMENT_BIT, + bindings.size() + )); + //break; + } + /* + auto& subpass = renderMode.renderTarget.passes[this->subpass]; + for ( auto& color : subpass.colors ) { + bindings.push_back(ext::vulkan::initializers::descriptorSetLayoutBinding( + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + VK_SHADER_STAGE_FRAGMENT_BIT, + bindings.size() + )); + } + */ + initializeDescriptorLayout(bindings, sizeof(pushConstants)); + } +/* initializeDescriptorLayout({ // Vertex shader ext::vulkan::initializers::descriptorSetLayoutBinding( @@ -98,8 +141,9 @@ void ext::vulkan::RenderTargetGraphic::initialize( Device& device, RenderMode& r VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 1 - ) + ), }, sizeof(pushConstants)); +*/ // Create sampler { VkSamplerCreateInfo samplerInfo = {}; @@ -153,8 +197,8 @@ void ext::vulkan::RenderTargetGraphic::initialize( Device& device, RenderMode& r ); VkPipelineRasterizationStateCreateInfo rasterizationState = ext::vulkan::initializers::pipelineRasterizationStateCreateInfo( VK_POLYGON_MODE_FILL, - // VK_CULL_MODE_BACK_BIT, - VK_CULL_MODE_NONE, + VK_CULL_MODE_BACK_BIT, + // VK_CULL_MODE_NONE, ext::vulkan::Graphic::DEFAULT_WINDING_ORDER, 0 ); @@ -176,9 +220,10 @@ void ext::vulkan::RenderTargetGraphic::initialize( Device& device, RenderMode& r blendAttachmentStates.push_back(blendAttachmentState); } } + auto& subpass = renderMode.renderTarget.passes[this->subpass]; VkPipelineColorBlendStateCreateInfo colorBlendState = ext::vulkan::initializers::pipelineColorBlendStateCreateInfo( // renderMode.getType() == "Swapchain" ? 1 : blendAttachmentStates.size(), - 1, + subpass.colors.size(), blendAttachmentStates.data() ); /* @@ -233,8 +278,8 @@ void ext::vulkan::RenderTargetGraphic::initialize( Device& device, RenderMode& r colorBlendState.blendConstants[3] = 0.0f; */ VkPipelineDepthStencilStateCreateInfo depthStencilState = ext::vulkan::initializers::pipelineDepthStencilStateCreateInfo( - VK_FALSE,//VK_TRUE, - VK_FALSE,//VK_TRUE, + VK_TRUE, + VK_TRUE, //VK_COMPARE_OP_LESS_OR_EQUAL VK_COMPARE_OP_GREATER_OR_EQUAL ); @@ -307,6 +352,68 @@ void ext::vulkan::RenderTargetGraphic::initialize( Device& device, RenderMode& r initializePipeline(pipelineCreateInfo); } + + { + VkDescriptorImageInfo samplerDescriptor; samplerDescriptor.sampler = sampler; + std::vector colorDescriptors; + /* + colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( + renderTarget->attachments[0].view, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + )); + */ + // auto& subpass = renderMode.renderTarget.passes[this->subpass]; + for ( auto& attachment : renderTarget->attachments ) { + if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue; + colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( + attachment.view, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + )); + //break; + } + /* + auto& subpass = renderMode.renderTarget.passes[this->subpass]; + for ( auto& color : subpass.colors ) { + colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( + renderTarget->attachments[color].view, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + )); + } + */ + // Set descriptor pool + initializeDescriptorPool({ + ext::vulkan::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), + ext::vulkan::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_SAMPLER, 1), + ext::vulkan::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, colorDescriptors.size()), + }, 1); + // Set descriptor set + std::vector writeDescriptorSets = { + // Binding 0 : Projection/View matrix uniform buffer + ext::vulkan::initializers::writeDescriptorSet( + descriptorSet, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 0, + &(buffers.at(0).descriptor) + ), + // Binding 1 : Sampler + ext::vulkan::initializers::writeDescriptorSet( + descriptorSet, + VK_DESCRIPTOR_TYPE_SAMPLER, + 1, + &samplerDescriptor + ) + }; + for ( size_t i = 0; i < colorDescriptors.size(); ++i ) { + writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet( + descriptorSet, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + i + 2, + &colorDescriptors[i] + )); + } + initializeDescriptorSet(writeDescriptorSets); + } +/* // Set descriptor pool initializeDescriptorPool({ ext::vulkan::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1), @@ -338,6 +445,7 @@ void ext::vulkan::RenderTargetGraphic::initialize( Device& device, RenderMode& r ) }); } +*/ } void ext::vulkan::RenderTargetGraphic::destroy() { vkDestroySampler( *device, sampler, nullptr ); diff --git a/engine/src/ext/vulkan/rendermode.cpp b/engine/src/ext/vulkan/rendermode.cpp index f242bdcd..b162200d 100644 --- a/engine/src/ext/vulkan/rendermode.cpp +++ b/engine/src/ext/vulkan/rendermode.cpp @@ -147,5 +147,6 @@ void ext::vulkan::RenderMode::destroy() { } } void ext::vulkan::RenderMode::synchronize( uint64_t timeout ) { + if ( !device ) return; VK_CHECK_RESULT(vkWaitForFences( *device, fences.size(), fences.data(), VK_TRUE, timeout )); } \ No newline at end of file diff --git a/engine/src/ext/vulkan/rendermodes/base.cpp b/engine/src/ext/vulkan/rendermodes/base.cpp index 814ba89a..fe835879 100644 --- a/engine/src/ext/vulkan/rendermodes/base.cpp +++ b/engine/src/ext/vulkan/rendermodes/base.cpp @@ -75,11 +75,8 @@ void ext::vulkan::BaseRenderMode::createCommandBuffers( const std::vectorcreateCommandBuffer(commands[i] ); - } + for ( auto graphic : graphics ) { + graphic->createCommandBuffer(commands[i] ); } vkCmdEndRenderPass(commands[i]); diff --git a/engine/src/ext/vulkan/rendermodes/deferred.cpp b/engine/src/ext/vulkan/rendermodes/deferred.cpp index f960ec1e..00f0e8f8 100644 --- a/engine/src/ext/vulkan/rendermodes/deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/deferred.cpp @@ -10,7 +10,7 @@ #include std::string ext::vulkan::DeferredRenderMode::getType() const { - return "Defered"; + return "Deferred"; } void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { @@ -68,19 +68,27 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { // update layer rendertargets descriptor sets { - std::vector layers = { &ext::vulkan::getRenderMode("Gui") }; + std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); //{ &ext::vulkan::getRenderMode("Gui") }; for ( auto layer : layers ) { - if ( layer->getName() == "Gui" ) { - RenderTargetRenderMode* guiLayer = (RenderTargetRenderMode*) layer; - auto& blitter = guiLayer->blitter; - blitter.subpass = 1; - blitter.initialize( device, *this ); - } + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + auto& blitter = rtLayer->blitter; + // blitter.subpass = 1; + blitter.initialize( device, *this ); } } } void ext::vulkan::DeferredRenderMode::tick() { ext::vulkan::RenderMode::tick(); + std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); + for ( auto layer : layers ) { + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + auto& blitter = rtLayer->blitter; + // update descriptor set + if ( !blitter.initialized ) { + // blitter.subpass = 1; + if ( blitter.renderTarget ) blitter.initialize( *device, *this ); + } + } if ( ext::vulkan::resized ) { // destroy if exist { @@ -117,37 +125,49 @@ void ext::vulkan::DeferredRenderMode::tick() { blitter.initializeDescriptorSet( writeDescriptorSets ); } // update layer rendertargets descriptor sets - std::vector layers = { &ext::vulkan::getRenderMode("Gui") }; for ( auto layer : layers ) { - if ( layer->getName() == "Gui" ) { - RenderTargetRenderMode* guiLayer = (RenderTargetRenderMode*) layer; - auto& blitter = guiLayer->blitter; - auto& renderTarget = guiLayer->renderTarget; - // update descriptor set - if ( blitter.initialized ) { - VkDescriptorImageInfo renderTargetDescription = ext::vulkan::initializers::descriptorImageInfo( - renderTarget.attachments[0].view, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - blitter.sampler - ); - std::vector writeDescriptorSets = { - // Binding 0 : Projection/View matrix uniform buffer - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &(blitter.buffers.at(0).descriptor) - ), - // Binding 1 : Albedo input attachment - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, - &renderTargetDescription - ), - }; - vkUpdateDescriptorSets( *device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr ); + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + auto& blitter = rtLayer->blitter; + auto& renderTarget = rtLayer->renderTarget; + // update descriptor set + if ( blitter.initialized ) { + renderTarget.initialize( *renderTarget.device ); + VkDescriptorImageInfo samplerDescriptor; samplerDescriptor.sampler = blitter.sampler; + std::vector colorDescriptors; + for ( auto& attachment : renderTarget.attachments ) { + if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue; + colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( + attachment.view, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + )); } + + // Set descriptor set + std::vector writeDescriptorSets = { + // Binding 0 : Projection/View matrix uniform buffer + ext::vulkan::initializers::writeDescriptorSet( + blitter.descriptorSet, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 0, + &(blitter.buffers.at(0).descriptor) + ), + // Binding 1 : Sampler + ext::vulkan::initializers::writeDescriptorSet( + blitter.descriptorSet, + VK_DESCRIPTOR_TYPE_SAMPLER, + 1, + &samplerDescriptor + ), + }; + for ( size_t i = 0; i < colorDescriptors.size(); ++i ) { + writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet( + blitter.descriptorSet, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + i + 2, + &colorDescriptors[i] + )); + } + vkUpdateDescriptorSets( *device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr ); } } } @@ -175,7 +195,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector layers = { &ext::vulkan::getRenderMode("Gui") }; + std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); for (size_t i = 0; i < commands.size(); ++i) { VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo)); @@ -227,24 +247,33 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vectorgetName() == "" ) continue; RenderTarget& renderTarget = layer->renderTarget; - imageMemoryBarrier.image = renderTarget.attachments[0].image; - imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT; - imageMemoryBarrier.oldLayout = renderTarget.attachments[0].layout; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier ); - renderTarget.attachments[0].layout = imageMemoryBarrier.newLayout; + for ( auto& attachment : renderTarget.attachments ) { + if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue; + imageMemoryBarrier.image = attachment.image; + imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT; + imageMemoryBarrier.oldLayout = attachment.layout; + imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier ); + attachment.layout = imageMemoryBarrier.newLayout; + } } vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdSetViewport(commands[i], 0, 1, &viewport); vkCmdSetScissor(commands[i], 0, 1, &scissor); - for ( auto pass : passes ) { - ext::vulkan::currentPass = pass + ";DEFERRED"; - for ( auto graphic : graphics ) { - // only draw graphics that are assigned to this type of render mode - if ( graphic->renderMode->getName() != this->getName() ) continue; - graphic->createCommandBuffer(commands[i] ); + for ( auto graphic : graphics ) { + // only draw graphics that are assigned to this type of render mode + if ( graphic->renderMode->getName() != this->getName() ) continue; + graphic->createCommandBuffer(commands[i] ); + } + // render gui layer + { + for ( auto layer : layers ) { + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + if ( !rtLayer->blitter.initialized ) continue; + if ( rtLayer->blitter.subpass != 0 ) continue; + rtLayer->blitter.createCommandBuffer(commands[i]); } } vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); @@ -252,10 +281,10 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vectorgetName() == "Gui" ) { - RenderTargetRenderMode* guiLayer = (RenderTargetRenderMode*) layer; - guiLayer->blitter.createCommandBuffer(commands[i]); - } + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + if ( !rtLayer->blitter.initialized ) continue; + if ( rtLayer->blitter.subpass != 1 ) continue; + rtLayer->blitter.createCommandBuffer(commands[i]); } } vkCmdEndRenderPass(commands[i]); @@ -263,13 +292,16 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vectorgetName() == "" ) continue; RenderTarget& renderTarget = layer->renderTarget; - imageMemoryBarrier.image = renderTarget.attachments[0].image; - imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - imageMemoryBarrier.oldLayout = renderTarget.attachments[0].layout; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier ); - renderTarget.attachments[0].layout = imageMemoryBarrier.newLayout; + for ( auto& attachment : renderTarget.attachments ) { + if ( !(attachment.usage & VK_IMAGE_USAGE_SAMPLED_BIT) ) continue; + imageMemoryBarrier.image = attachment.image; + imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT; + imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + imageMemoryBarrier.oldLayout = attachment.layout; + imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier ); + attachment.layout = imageMemoryBarrier.newLayout; + } } } diff --git a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp index 860904a2..907f8ac6 100644 --- a/engine/src/ext/vulkan/rendermodes/rendertarget.cpp +++ b/engine/src/ext/vulkan/rendermodes/rendertarget.cpp @@ -10,25 +10,60 @@ std::string ext::vulkan::RenderTargetRenderMode::getType() const { void ext::vulkan::RenderTargetRenderMode::initialize( Device& device ) { ext::vulkan::RenderMode::initialize( device ); + + this->target = this->name; + { renderTarget.device = &device; // attach targets +/* struct { size_t color, depth; } attachments; attachments.color = renderTarget.attach( VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ); // albedo attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ); // depth +*/ + struct { + size_t albedo, position, normals, 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 ); // albedo + 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 ); // position + 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 ); // normals + attachments.depth = renderTarget.attach( device.formats.depth, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ); // depth + // Attach swapchain's image as output + if ( !false ) { + attachments.output = renderTarget.attach( device.formats.color, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ); // depth + } else { + attachments.output = 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: write to target { renderTarget.addPass( VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - { attachments.color }, + { attachments.albedo, attachments.position, attachments.normals }, {}, attachments.depth ); } + // NOP + { + renderTarget.addPass( + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + // { attachments.output }, + // { attachments.albedo, attachments.position, attachments.normals }, + { attachments.output }, + { attachments.albedo, attachments.position, attachments.normals }, + attachments.depth + ); + } } renderTarget.initialize( device ); @@ -93,9 +128,16 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vecto for (size_t i = 0; i < commands.size(); ++i) { VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo)); { - std::vector clearValues; clearValues.resize(2); - clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 0.0f } }; - clearValues[1].depthStencil = { 0.0f, 0 }; + std::vector clearValues; + for ( auto& attachment : renderTarget.attachments ) { + VkClearValue clearValue; + if ( attachment.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ) { + clearValue.color = { { 0.0f, 0.0f, 0.0f, 0.0f } }; + } 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; @@ -130,13 +172,11 @@ void ext::vulkan::RenderTargetRenderMode::createCommandBuffers( const std::vecto vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdSetViewport(commands[i], 0, 1, &viewport); vkCmdSetScissor(commands[i], 0, 1, &scissor); - for ( auto pass : passes ) { - ext::vulkan::currentPass = pass + ";TOTEXTURE"; - for ( auto graphic : graphics ) { - if ( graphic->renderMode && graphic->renderMode->getName() != this->getName() ) continue; - graphic->createCommandBuffer(commands[i] ); - } + for ( auto graphic : graphics ) { + if ( graphic->renderMode && graphic->renderMode->getName() != this->target ) continue; + graphic->createCommandBuffer(commands[i] ); } + vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); vkCmdEndRenderPass(commands[i]); } diff --git a/engine/src/ext/vulkan/rendermodes/stereoscopic_deferred.cpp b/engine/src/ext/vulkan/rendermodes/stereoscopic_deferred.cpp index 1eed7db5..41935ed5 100644 --- a/engine/src/ext/vulkan/rendermodes/stereoscopic_deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/stereoscopic_deferred.cpp @@ -21,7 +21,7 @@ ext::vulkan::StereoscopicDeferredRenderMode::StereoscopicDeferredRenderMode() : } std::string ext::vulkan::StereoscopicDeferredRenderMode::getType() const { - return "Stereoscopic Deferred"; + return "Deferred (Stereoscopic)"; } void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) { @@ -115,19 +115,27 @@ void ext::vulkan::StereoscopicDeferredRenderMode::initialize( Device& device ) { */ // update layer rendertargets descriptor sets { - std::vector layers = { &ext::vulkan::getRenderMode("Gui") }; + std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); //{ &ext::vulkan::getRenderMode("Gui") }; for ( auto layer : layers ) { - if ( layer->getName() == "Gui" ) { - RenderTargetRenderMode* guiLayer = (RenderTargetRenderMode*) layer; - auto& blitter = guiLayer->blitter; - blitter.subpass = 1; - blitter.initialize( device, *this ); - } + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + auto& blitter = rtLayer->blitter; + // blitter.subpass = 1; + blitter.initialize( device, *this ); } } } void ext::vulkan::StereoscopicDeferredRenderMode::tick() { ext::vulkan::RenderMode::tick(); + std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); + for ( auto layer : layers ) { + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + auto& blitter = rtLayer->blitter; + // update descriptor set + if ( !blitter.initialized ) { + // blitter.subpass = 1; + if ( blitter.renderTarget ) blitter.initialize( *device, *this ); + } + } if ( ext::vulkan::resized ) { struct EYES { RenderTarget* renderTarget; @@ -208,37 +216,79 @@ void ext::vulkan::StereoscopicDeferredRenderMode::tick() { } } // update layer rendertargets descriptor sets - std::vector layers = { &ext::vulkan::getRenderMode("Gui") }; for ( auto layer : layers ) { - if ( layer->getName() == "Gui" ) { - RenderTargetRenderMode* guiLayer = (RenderTargetRenderMode*) layer; - auto& blitter = guiLayer->blitter; - auto& renderTarget = guiLayer->renderTarget; - // update descriptor set - if ( blitter.initialized ) { - VkDescriptorImageInfo renderTargetDescription = ext::vulkan::initializers::descriptorImageInfo( - renderTarget.attachments[0].view, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - blitter.sampler - ); - std::vector writeDescriptorSets = { - // Binding 0 : Projection/View matrix uniform buffer - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 0, - &(blitter.buffers.at(0).descriptor) - ), - // Binding 1 : Albedo input attachment - ext::vulkan::initializers::writeDescriptorSet( - blitter.descriptorSet, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, - &renderTargetDescription - ), - }; - vkUpdateDescriptorSets( *device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr ); + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + auto& blitter = rtLayer->blitter; + auto& renderTarget = rtLayer->renderTarget; + // update descriptor set + if ( blitter.initialized ) { + VkDescriptorImageInfo samplerDescriptor; samplerDescriptor.sampler = blitter.sampler; + std::vector colorDescriptors; + /* + colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( + renderTarget.attachments[0].view, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + )); + */ + + for ( auto& attachment : renderTarget.attachments ) { + colorDescriptors.push_back(ext::vulkan::initializers::descriptorImageInfo( + attachment.view, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + )); + //break; } + + // Set descriptor set + std::vector writeDescriptorSets = { + // Binding 0 : Projection/View matrix uniform buffer + ext::vulkan::initializers::writeDescriptorSet( + blitter.descriptorSet, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 0, + &(blitter.buffers.at(0).descriptor) + ), + // Binding 1 : Sampler + ext::vulkan::initializers::writeDescriptorSet( + blitter.descriptorSet, + VK_DESCRIPTOR_TYPE_SAMPLER, + 1, + &samplerDescriptor + ), + }; + for ( size_t i = 0; i < colorDescriptors.size(); ++i ) { + writeDescriptorSets.push_back(ext::vulkan::initializers::writeDescriptorSet( + blitter.descriptorSet, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + i + 2, + &colorDescriptors[i] + )); + } + vkUpdateDescriptorSets( *device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr ); + /* + VkDescriptorImageInfo renderTargetDescription = ext::vulkan::initializers::descriptorImageInfo( + renderTarget.attachments[0].view, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + blitter.sampler + ); + std::vector writeDescriptorSets = { + // Binding 0 : Projection/View matrix uniform buffer + ext::vulkan::initializers::writeDescriptorSet( + blitter.descriptorSet, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 0, + &(blitter.buffers.at(0).descriptor) + ), + // Binding 1 : Albedo input attachment + ext::vulkan::initializers::writeDescriptorSet( + blitter.descriptorSet, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + 1, + &renderTargetDescription + ), + }; + vkUpdateDescriptorSets( *device, static_cast(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr ); + */ } } } @@ -269,7 +319,7 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st imageMemoryBarrier.subresourceRange.layerCount = 1; imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - std::vector layers = { &ext::vulkan::getRenderMode("Gui") }; + std::vector layers = ext::vulkan::getRenderModes("RenderTarget", false); for (size_t i = 0; i < commands.size(); ++i) { VK_CHECK_RESULT(vkBeginCommandBuffer(commands[i], &cmdBufInfo)); @@ -329,25 +379,32 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st // transition layers for read for ( auto layer : layers ) { + if ( layer->getName() == "" ) continue; RenderTarget& renderTarget = layer->renderTarget; imageMemoryBarrier.image = renderTarget.attachments[0].image; imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT; imageMemoryBarrier.oldLayout = renderTarget.attachments[0].layout; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0 , 0, NULL, 0, NULL, 1, &imageMemoryBarrier ); + vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier ); renderTarget.attachments[0].layout = imageMemoryBarrier.newLayout; } vkCmdBeginRenderPass(commands[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdSetViewport(commands[i], 0, 1, &viewport); vkCmdSetScissor(commands[i], 0, 1, &scissor); - for ( auto pass : passes ) { - ext::vulkan::currentPass = pass + ";DEFERRED;" + ( i == 0 ? "LEFT" : "RIGHT" ); - for ( auto graphic : graphics ) { - // only draw graphics that are assigned to this type of render mode - if ( graphic->renderMode->getName() != this->getName() ) continue; - graphic->createCommandBuffer(commands[i] ); + for ( auto graphic : graphics ) { + // only draw graphics that are assigned to this type of render mode + if ( graphic->renderMode->getName() != this->getName() ) continue; + graphic->createCommandBuffer(commands[i] ); + } + // render gui layer + { + for ( auto layer : layers ) { + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + if ( !rtLayer->blitter.initialized ) continue; + if ( rtLayer->blitter.subpass != 0 ) continue; + rtLayer->blitter.createCommandBuffer(commands[i]); } } vkCmdNextSubpass(commands[i], VK_SUBPASS_CONTENTS_INLINE); @@ -355,10 +412,10 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st // render gui layer { for ( auto layer : layers ) { - if ( layer->getName() == "Gui" ) { - RenderTargetRenderMode* guiLayer = (RenderTargetRenderMode*) layer; - if ( guiLayer->blitter.subpass == 1 ) guiLayer->blitter.createCommandBuffer(commands[i]); - } + RenderTargetRenderMode* rtLayer = (RenderTargetRenderMode*) layer; + if ( !rtLayer->blitter.initialized ) continue; + if ( rtLayer->blitter.subpass != 1 ) continue; + rtLayer->blitter.createCommandBuffer(commands[i]); } } /* @@ -386,13 +443,14 @@ void ext::vulkan::StereoscopicDeferredRenderMode::createCommandBuffers( const st vkCmdEndRenderPass(commands[i]); for ( auto layer : layers ) { + if ( layer->getName() == "" ) continue; RenderTarget& renderTarget = layer->renderTarget; imageMemoryBarrier.image = renderTarget.attachments[0].image; imageMemoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_SHADER_READ_BIT; imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.oldLayout = renderTarget.attachments[0].layout; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , 0 , 0, NULL, 0, NULL, 1, &imageMemoryBarrier ); + vkCmdPipelineBarrier( commands[i], VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT , 0, 0, NULL, 0, NULL, 1, &imageMemoryBarrier ); renderTarget.attachments[0].layout = imageMemoryBarrier.newLayout; } } diff --git a/engine/src/ext/vulkan/rendertarget.cpp b/engine/src/ext/vulkan/rendertarget.cpp index 6cacd8b4..4fedddf5 100644 --- a/engine/src/ext/vulkan/rendertarget.cpp +++ b/engine/src/ext/vulkan/rendertarget.cpp @@ -11,9 +11,9 @@ void ext::vulkan::RenderTarget::addPass( VkPipelineStageFlags stage, VkAccessFla Subpass pass; pass.stage = stage; pass.access = access; - for ( auto& i : colors ) pass.colors.push_back( { i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL } ); - for ( auto& i : inputs ) pass.inputs.push_back( { i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } ); - if ( depth < attachments.size() ) pass.depth = { depth, attachments[depth].layout }; + for ( auto& i : colors ) pass.colors.push_back( { (uint32_t) i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL } ); + for ( auto& i : inputs ) pass.inputs.push_back( { (uint32_t) i, i == depth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL } ); + if ( depth < attachments.size() ) pass.depth = { (uint32_t) depth, attachments[depth].layout }; passes.push_back(pass); } size_t ext::vulkan::RenderTarget::attach( VkFormat format, VkImageUsageFlags usage, VkImageLayout layout, Attachment* attachment ) { @@ -211,7 +211,7 @@ void ext::vulkan::RenderTarget::initialize( Device& device ) { VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass)); - // std::cout << "Renderpass: " << renderPass << std::endl; + std::cout << renderPass << ": " << attachments.size() << std::endl; } { diff --git a/engine/src/ext/vulkan/vulkan.cpp b/engine/src/ext/vulkan/vulkan.cpp index cdb72603..55555bea 100644 --- a/engine/src/ext/vulkan/vulkan.cpp +++ b/engine/src/ext/vulkan/vulkan.cpp @@ -21,7 +21,7 @@ bool ext::vulkan::rebuild = false; uint32_t ext::vulkan::currentBuffer = 0; std::vector ext::vulkan::passes = { "BASE" }; std::vector ext::vulkan::scenes; -std::string ext::vulkan::currentPass = "BASE"; +ext::vulkan::RenderMode* ext::vulkan::currentRenderMode = NULL; std::vector ext::vulkan::renderModes = { new ext::vulkan::BaseRenderMode, @@ -151,9 +151,25 @@ void ext::vulkan::alignedFree(void* data) { free(data); #endif } + +namespace { + bool hasRenderMode( const std::string& name, bool isName ) { + for ( auto& renderMode: ext::vulkan::renderModes ) { + if ( isName ) { + if ( renderMode->getName() == name ) return true; + } else { + if ( renderMode->getType() == name ) return true; + } + } + return false; + } +} + ext::vulkan::RenderMode& ext::vulkan::addRenderMode( ext::vulkan::RenderMode* mode, const std::string& name ) { mode->name = name; renderModes.push_back(mode); + std::cout << "Adding RenderMode: " << name << ": " << mode->getType() << std::endl; + // reorder return *mode; } ext::vulkan::RenderMode& ext::vulkan::getRenderMode( const std::string& name, bool isName ) { @@ -172,9 +188,25 @@ ext::vulkan::RenderMode& ext::vulkan::getRenderMode( const std::string& name, bo } } } - // std::cout << "Requesting RenderMode `" << name << "`, got `" << target->getName() << "` (" << target->getType() << ")" << std::endl; +// std::cout << "Requesting RenderMode `" << name << "`, got `" << target->getName() << "` (" << target->getType() << ")" << std::endl; return *target; } +std::vector ext::vulkan::getRenderModes( const std::string& name, bool isName ) { + std::vector targets; + for ( auto& renderMode: renderModes ) { + if ( ( isName && renderMode->getName() == name ) || renderMode->getType() == name ) { + targets.push_back(renderMode); +// std::cout << "Requestings RenderMode `" << name << "`, got `" << renderMode->getName() << "` (" << renderMode->getType() << ")" << std::endl; + } + } + return targets; +} +void ext::vulkan::removeRenderMode( ext::vulkan::RenderMode* mode, bool free ) { + if ( !mode ) return; + renderModes.erase( std::remove( renderModes.begin(), renderModes.end(), mode ), renderModes.end() ); + mode->destroy(); + if ( free ) delete mode; +} void ext::vulkan::initialize( uint8_t stage ) { switch ( stage ) { @@ -256,7 +288,6 @@ std::ostream& operator<<(std::ostream& os, const ext::vulkan::Graphic& graphic) return os; } void ext::vulkan::tick() { - // check for changes in swapchain ext::vulkan::mutex.lock(); if ( ext::vulkan::resized ) ext::vulkan::rebuild = true; @@ -276,47 +307,34 @@ void ext::vulkan::tick() { } for ( auto& renderMode : renderModes ) { if ( !renderMode ) continue; + if ( !renderMode->device ) renderMode->initialize(ext::vulkan::device); renderMode->tick(); } for ( auto& renderMode : renderModes ) { if ( !renderMode ) continue; - if ( ext::vulkan::rebuild ) { + if ( ext::vulkan::rebuild ) renderMode->createCommandBuffers(); - } } ext::vulkan::rebuild = false; ext::vulkan::resized = false; ext::vulkan::mutex.unlock(); } void ext::vulkan::render() { -/* - if ( ext::vulkan::graphics ) { - auto& graphics = *ext::vulkan::graphics; - for ( Graphic* graphic : graphics ) { - if ( !graphic || !graphic->process ) continue; - graphic->render(); - } + if ( hasRenderMode("", true) ) { + RenderMode& primary = getRenderMode("", true); + auto it = std::find( renderModes.begin(), renderModes.end(), &primary ); + if ( it + 1 != renderModes.end() ) std::rotate( it, it + 1, renderModes.end() ); } -*/ -/* - std::function filter = [&]( uf::Entity* entity ) { - if ( !entity->hasComponent() ) return; - uf::MeshBase& mesh = entity->getComponent(); - ext::vulkan::Graphic& graphic = mesh.graphic; - // if ( !graphic.process ) return; - if ( !graphic.initialized ) return; - graphic.render(); - }; - for ( uf::Scene* scene : ext::vulkan::scenes ) { - if ( !scene ) continue; - scene->process(filter); - } -*/ + ext::vulkan::mutex.lock(); for ( auto& renderMode : renderModes ) { if ( !renderMode ) continue; + ext::vulkan::currentRenderMode = renderMode; + for ( uf::Scene* scene : ext::vulkan::scenes ) scene->render(); renderMode->render(); } + + ext::vulkan::currentRenderMode = NULL; ext::vulkan::mutex.unlock(); } void ext::vulkan::destroy() { diff --git a/engine/src/spec/window/windows.cpp b/engine/src/spec/window/windows.cpp index 20f1c5b7..73b3eb4d 100644 --- a/engine/src/spec/window/windows.cpp +++ b/engine/src/spec/window/windows.cpp @@ -1106,11 +1106,11 @@ bool UF_API_CALL spec::win32::Window::isKeyPressed(const std::string& key) { if ( (key == "Escape") && (GetAsyncKeyState(VK_ESCAPE) & 0x8000) ) return true; if ( (key == "LControl") && (GetAsyncKeyState(VK_LCONTROL) & 0x8000) ) return true; if ( (key == "LShift") && (GetAsyncKeyState(VK_LSHIFT) & 0x8000) ) return true; - if ( (key == "LMenu") && (GetAsyncKeyState(VK_LMENU) & 0x8000) ) return true; + if ( (key == "LAlt") && (GetAsyncKeyState(VK_LMENU) & 0x8000) ) return true; if ( (key == "LSystem") && (GetAsyncKeyState(VK_LWIN) & 0x8000) ) return true; if ( (key == "RControl") && (GetAsyncKeyState(VK_RCONTROL) & 0x8000) ) return true; if ( (key == "RShift") && (GetAsyncKeyState(VK_RSHIFT) & 0x8000) ) return true; - if ( (key == "RMenu") && (GetAsyncKeyState(VK_RMENU) & 0x8000) ) return true; + if ( (key == "RAlt") && (GetAsyncKeyState(VK_RMENU) & 0x8000) ) return true; if ( (key == "RSystem") && (GetAsyncKeyState(VK_RWIN) & 0x8000) ) return true; if ( (key == "Apps") && (GetAsyncKeyState(VK_APPS) & 0x8000) ) return true; if ( (key == "OEM4") && (GetAsyncKeyState(VK_OEM_4) & 0x8000) ) return true; diff --git a/engine/src/utils/camera/camera.cpp b/engine/src/utils/camera/camera.cpp index da1603a9..0b733edd 100644 --- a/engine/src/utils/camera/camera.cpp +++ b/engine/src/utils/camera/camera.cpp @@ -18,8 +18,8 @@ uf::Camera::Camera() : this->m_settings.offset = {0, 0, 0}; this->m_settings.mode = 1; - this->m_matrices.view = uf::matrix::identity(); - this->m_matrices.projection = uf::matrix::identity(); + this->setView(uf::matrix::identity()); + this->setProjection(uf::matrix::identity()); this->m_transform = uf::transform::initialize(this->m_transform); this->m_transform.position = {0,1.725,0}; @@ -61,32 +61,84 @@ const pod::Transform<>& uf::Camera::getTransform() const { } pod::Matrix4& uf::Camera::getView( size_t eye ) { + switch ( eye ) { + case 0: + return this->m_matrices.left.view; + break; + case 1: + return this->m_matrices.right.view; + break; + default: + return this->m_matrices.left.view; + break; + } +/* if ( ext::openvr::context ) { return eye == 0 ? ::eye.left : ::eye.right; } return this->m_matrices.view; +*/ } pod::Matrix4& uf::Camera::getProjection( size_t eye ) { + switch ( eye ) { + case 0: + return this->m_matrices.left.projection; + break; + case 1: + return this->m_matrices.right.projection; + break; + default: + return this->m_matrices.left.projection; + break; + } +/* if ( ext::openvr::context ) { return eye == 0 ? ::projection.left : ::projection.right; } return this->m_matrices.projection; +*/ } pod::Matrix4& uf::Camera::getModel() { return this->m_matrices.model; } const pod::Matrix4& uf::Camera::getView( size_t eye ) const { + switch ( eye ) { + case 0: + return this->m_matrices.left.view; + break; + case 1: + return this->m_matrices.right.view; + break; + default: + return this->m_matrices.left.view; + break; + } +/* if ( ext::openvr::context ) { return eye == 0 ? ::eye.left : ::eye.right; } return this->m_matrices.view; +*/ } const pod::Matrix4& uf::Camera::getProjection( size_t eye ) const { + switch ( eye ) { + case 0: + return this->m_matrices.left.projection; + break; + case 1: + return this->m_matrices.right.projection; + break; + default: + return this->m_matrices.left.projection; + break; + } +/* if ( ext::openvr::context ) { return eye == 0 ? ::projection.left : ::projection.right; } return this->m_matrices.projection; +*/ } const pod::Matrix4& uf::Camera::getModel() const { return this->m_matrices.model; @@ -124,11 +176,33 @@ void uf::Camera::setTransform( const pod::Transform<>& transform ) { this->m_transform = transform; this->update(true); } -void uf::Camera::setView( const pod::Matrix4& mat ) { - this->m_matrices.view = mat; +void uf::Camera::setView( const pod::Matrix4& mat, size_t i ) { + switch ( i ) { + case 0: + this->m_matrices.left.view = mat; + break; + case 1: + this->m_matrices.right.view = mat; + break; + default: + this->setView( mat, 0 ); + this->setView( mat, 1 ); + break; + } } -void uf::Camera::setProjection( const pod::Matrix4& mat ) { - this->m_matrices.projection = mat; +void uf::Camera::setProjection( const pod::Matrix4& mat, size_t i ) { + switch ( i ) { + case 0: + this->m_matrices.left.projection = mat; + break; + case 1: + this->m_matrices.right.projection = mat; + break; + default: + this->setProjection( mat, 0 ); + this->setProjection( mat, 1 ); + break; + } } void uf::Camera::setModel( const pod::Matrix4& mat ) { this->m_matrices.model = mat; @@ -179,10 +253,10 @@ void uf::Camera::updateView() { pod::Matrix4t<> translation = uf::matrix::translate( uf::matrix::identity(), -position ); pod::Matrix4t<> rotation = uf::quaternion::matrix( flatten.orientation ); - this->m_matrices.view = rotation * translation; //uf::matrix::inverse( translation * rotation ); + pod::Matrix4t<> view = rotation * translation; //uf::matrix::inverse( translation * rotation ); transform.orientation = ext::openvr::hmdQuaternion(); - ::eye.left = ext::openvr::hmdViewMatrix(vr::Eye_Left, this->m_matrices.view); - ::eye.right = ext::openvr::hmdViewMatrix(vr::Eye_Right, this->m_matrices.view); + this->setView( ext::openvr::hmdViewMatrix(vr::Eye_Left, view ), 0 ); + this->setView( ext::openvr::hmdViewMatrix(vr::Eye_Right, view ), 1 ); // ::eye.left = ext::openvr::hmdEyePositionMatrix(vr::Eye_Left) * ext::openvr::hmdHeadPositionMatrix() * this->m_matrices.view; // ::eye.right = ext::openvr::hmdEyePositionMatrix(vr::Eye_Right) * ext::openvr::hmdHeadPositionMatrix() * this->m_matrices.view; @@ -242,37 +316,41 @@ void uf::Camera::updateView() { } } void uf::Camera::updateProjection() { + if ( ext::openvr::context ) { + // ::projection.left = ext::openvr::hmdProjectionMatrix( vr::Eye_Left, this->m_settings.perspective.bounds.x, this->m_settings.perspective.bounds.y ); + // ::projection.right = ext::openvr::hmdProjectionMatrix( vr::Eye_Right, this->m_settings.perspective.bounds.x, this->m_settings.perspective.bounds.y ); + this->setProjection( ext::openvr::hmdProjectionMatrix( vr::Eye_Left, this->m_settings.perspective.bounds.x, this->m_settings.perspective.bounds.y ), 0 ); + this->setProjection( ext::openvr::hmdProjectionMatrix( vr::Eye_Right, this->m_settings.perspective.bounds.x, this->m_settings.perspective.bounds.y ), 1 ); + return; + } + if ( this->m_settings.mode < 0 ) { // Maintain aspect ratio if ( this->m_settings.ortho.lr.x == this->m_settings.ortho.bt.x && this->m_settings.ortho.lr.y == this->m_settings.ortho.bt.y && this->m_settings.ortho.bt.x == -this->m_settings.ortho.bt.y ) { pod::Math::num_t raidou = this->m_settings.perspective.size.x / this->m_settings.perspective.size.y; pod::Math::num_t range = this->m_settings.ortho.bt.y - this->m_settings.ortho.bt.x; pod::Math::num_t correction = raidou * range / 2.0; - this->m_matrices.projection = uf::matrix::ortho( + this->setProjection(uf::matrix::ortho( -correction, correction, this->m_settings.ortho.bt.x, this->m_settings.ortho.bt.y, this->m_settings.ortho.nf.x, this->m_settings.ortho.nf.y - ); + )); return; } - this->m_matrices.projection = uf::matrix::ortho( + this->setProjection(uf::matrix::ortho( this->m_settings.ortho.lr.x, this->m_settings.ortho.lr.y, this->m_settings.ortho.bt.x, this->m_settings.ortho.bt.y, this->m_settings.ortho.nf.x, this->m_settings.ortho.nf.y - ); + )); return; } float fov = this->m_settings.perspective.fov * (3.14159265358f / 180.0f); float raidou = (float) this->m_settings.perspective.size.x / (float) this->m_settings.perspective.size.y; float f = 1.0f / tan( 0.5f * fov ); - this->m_matrices.projection = { + this->setProjection({ f / raidou, 0.0f, 0.0f, 0.0f, 0.0f, -f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, this->m_settings.perspective.bounds.x, 0.0f - }; - if ( ext::openvr::context ) { - ::projection.left = ext::openvr::hmdProjectionMatrix( vr::Eye_Left, this->m_settings.perspective.bounds.x, this->m_settings.perspective.bounds.y ); - ::projection.right = ext::openvr::hmdProjectionMatrix( vr::Eye_Right, this->m_settings.perspective.bounds.x, this->m_settings.perspective.bounds.y ); - } + }); } \ No newline at end of file diff --git a/engine/src/utils/text/glyph.cpp b/engine/src/utils/text/glyph.cpp index f8924edb..24e0d37a 100644 --- a/engine/src/utils/text/glyph.cpp +++ b/engine/src/utils/text/glyph.cpp @@ -1,4 +1,5 @@ #include +#include uf::Glyph::~Glyph() { delete[] this->m_buffer; @@ -178,8 +179,21 @@ void uf::Glyph::generateSdf( uint8_t* buffer ) { if ( !buffer ) return; lowest = std::min( lowest, dist ); highest = std::max( highest, dist ); - - buffer[y * this->m_size.x + x] = dist * this->getSpread() + 128; + + { + int value = dist * this->getSpread() + 128; + uint8_t uvalue = std::max( 0, std::min(255, value) ); + buffer[y * this->m_size.x + x] = uvalue; + } + + /* + { + float value = 0.5f + 0.5f * ((float) dist / (float) this->getSpread()); + value = std::max( 0.0f, std::min(1.0f, value) ); + uint8_t uvalue = value * 256; + buffer[y * this->m_size.x + x] = uvalue; + } + */ } } } diff --git a/ext/gui/gui.cpp b/ext/gui/gui.cpp index f48acf82..5828b840 100644 --- a/ext/gui/gui.cpp +++ b/ext/gui/gui.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include @@ -62,14 +62,14 @@ namespace { struct { alignas(16) pod::Vector4f offset; alignas(16) pod::Vector4f color; - int32_t mode = 0; - float depth = 0.0f; - int32_t sdf = false; - int32_t shadowbox = false; + alignas(4) int32_t mode = 0; + alignas(4) float depth = 0.0f; + alignas(4) int32_t sdf = false; + alignas(4) int32_t shadowbox = false; alignas(16) pod::Vector4f stroke; - float weight; - int32_t spread; - float scale; + alignas(4) float weight; + alignas(4) int32_t spread; + alignas(4) float scale; } gui; }; diff --git a/ext/main.cpp b/ext/main.cpp index 169a7274..2632138a 100644 --- a/ext/main.cpp +++ b/ext/main.cpp @@ -121,8 +121,11 @@ void EXT_API ext::initialize() { // ext::vulkan::height = ::config["window"]["size"]["y"].asInt(); // setup render mode - if ( ::config["engine"]["render modes"]["gui"].asBool() ) - ext::vulkan::addRenderMode( new ext::vulkan::RenderTargetRenderMode, "Gui" ); + if ( ::config["engine"]["render modes"]["gui"].asBool() ) { + auto* renderMode = new ext::vulkan::RenderTargetRenderMode; + ext::vulkan::addRenderMode( renderMode, "Gui" ); + renderMode->blitter.subpass = 1; + } if ( ::config["engine"]["render modes"]["stereo deferred"].asBool() ) ext::vulkan::addRenderMode( new ext::vulkan::StereoscopicDeferredRenderMode, "" ); else if ( ::config["engine"]["render modes"]["deferred"].asBool() ) @@ -200,7 +203,7 @@ void EXT_API ext::tick() { uf::iostream << entity->getName() << ": " << entity->getUid(); if ( entity->hasComponent>() ) { pod::Transform<> t = uf::transform::flatten(entity->getComponent>()); - uf::iostream << " (" << t.position.x << ", " << t.position.y << ", " << t.position.z << ")"; + uf::iostream << " (" << t.position.x << ", " << t.position.y << ", " << t.position.z << ") (" << t.orientation.x << ", " << t.orientation.y << ", " << t.orientation.z << ", " << t.orientation.w << ")"; } uf::iostream << "\n"; }; @@ -258,7 +261,7 @@ void EXT_API ext::tick() { } } void EXT_API ext::render() { - uf::scene::render(); + // uf::scene::render(); ext::vulkan::render(); diff --git a/ext/scenes/world/gui/battle.cpp b/ext/scenes/world/gui/battle.cpp index ce50c73b..95d56d12 100644 --- a/ext/scenes/world/gui/battle.cpp +++ b/ext/scenes/world/gui/battle.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include @@ -719,7 +719,7 @@ void ext::GuiBattle::tick() { string += "\n" + text; } if ( stats.currentMember["skills"].size() > stats.skill.selectionsMax ) { - for ( int i = 0; i < i < stats.currentMember["skills"].size(); ++i ) { + for ( int i = 0; i < stats.currentMember["skills"].size(); ++i ) { std::string id = stats.currentMember["skills"][i].asString(); std::string text = ""; if ( std::find( stats.skill.invalids.begin(), stats.skill.invalids.end(), id ) != stats.skill.invalids.end() ) continue; diff --git a/ext/scenes/world/gui/dialogue.cpp b/ext/scenes/world/gui/dialogue.cpp index ddd4bd21..1c73e093 100644 --- a/ext/scenes/world/gui/dialogue.cpp +++ b/ext/scenes/world/gui/dialogue.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/ext/scenes/world/gui/pause.cpp b/ext/scenes/world/gui/pause.cpp index d26bfcf0..bdefa050 100644 --- a/ext/scenes/world/gui/pause.cpp +++ b/ext/scenes/world/gui/pause.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/ext/scenes/world/housamo/battle.cpp b/ext/scenes/world/housamo/battle.cpp index 74a78500..8bfb1b71 100644 --- a/ext/scenes/world/housamo/battle.cpp +++ b/ext/scenes/world/housamo/battle.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ext/scenes/world/housamo/dialogue.cpp b/ext/scenes/world/housamo/dialogue.cpp index b79d5d5d..cdce6ea3 100644 --- a/ext/scenes/world/housamo/dialogue.cpp +++ b/ext/scenes/world/housamo/dialogue.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ext/scenes/world/housamo/sprite.cpp b/ext/scenes/world/housamo/sprite.cpp index a91e8566..4bf07aad 100644 --- a/ext/scenes/world/housamo/sprite.cpp +++ b/ext/scenes/world/housamo/sprite.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -54,6 +54,19 @@ void ext::HousamoSprite::initialize() { uf::Asset& assetLoader = world.getComponent(); this->addHook( "graphics:Assign.%UID%", [&](const std::string& event)->std::string{ + uf::Serializer json = event; + std::string filename = json["filename"].asString(); + metadata["system"]["control"] = false; + + if ( uf::string::extension(filename) != "png" ) return "false"; + + uf::Scene& scene = this->getRootParent(); + uf::Asset& assetLoader = scene.getComponent(); + const uf::Image* imagePointer = NULL; + try { imagePointer = &assetLoader.get(filename); } catch ( ... ) {} + if ( !imagePointer ) return "false"; + + uf::Image image = *imagePointer; uf::Mesh& mesh = this->getComponent(); mesh.vertices = { {{-1*-0.5f, 0.0f, 0.0f}, {1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f } }, @@ -71,6 +84,7 @@ void ext::HousamoSprite::initialize() { {{-1*0.5f, 1.0f, 0.0f}, {0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f } }, }; mesh.initialize(true); + mesh.graphic.texture.loadFromImage( image ); mesh.graphic.bindUniform(); mesh.graphic.initializeShaders({ {"./data/shaders/base.stereo.vert.spv", VK_SHADER_STAGE_VERTEX_BIT}, @@ -83,23 +97,8 @@ void ext::HousamoSprite::initialize() { metadata["system"]["loaded"] = true; return "true"; }); - this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{ - uf::Serializer json = event; - std::string filename = json["filename"].asString(); - metadata["system"]["control"] = false; - - if ( uf::string::extension(filename) != "png" ) return "false"; - - ext::World& world = this->getRootParent(); - uf::Asset& assetLoader = world.getComponent(); - const uf::Image* imagePointer = NULL; - try { imagePointer = &assetLoader.get(filename); } catch ( ... ) {} - if ( !imagePointer ) return "false"; - - uf::Image image = *imagePointer; - uf::Mesh& mesh = this->getComponent(); - mesh.graphic.texture.loadFromImage( image ); - this->queueHook("graphics:Assign.%UID%", "", 0.5); + this->addHook( "asset:Load.%UID%", [&](const std::string& event)->std::string{ + this->queueHook("graphics:Assign.%UID%", event, 0.0f); return "true"; }); @@ -140,16 +139,14 @@ void ext::HousamoSprite::render() { ext::Craeture::render(); /* Update uniforms */ if ( this->hasComponent() ) { auto& mesh = this->getComponent(); - auto& world = this->getRootParent(); - auto& player = *world.getController(); - auto& camera = player.getComponent(); - auto& transform = player.getComponent>(); - auto& model = this->getComponent>(); + auto& scene = uf::scene::getCurrentScene(); + auto& controller = *scene.getController(); + auto& camera = controller.getComponent(); + auto& transform = this->getComponent>(); if ( !mesh.generated ) return; - uf::Serializer& metadata = this->getComponent(); //auto& uniforms = mesh.graphic.uniforms(); auto& uniforms = mesh.graphic.uniforms(); - uniforms.matrices.model = uf::transform::model( this->getComponent>() ); + uniforms.matrices.model = uf::transform::model( transform ); for ( std::size_t i = 0; i < 2; ++i ) { uniforms.matrices.view[i] = camera.getView( i ); uniforms.matrices.projection[i] = camera.getProjection( i ); diff --git a/ext/scenes/world/player/hands.cpp b/ext/scenes/world/player/hands.cpp index e3239abc..c5ef7604 100644 --- a/ext/scenes/world/player/hands.cpp +++ b/ext/scenes/world/player/hands.cpp @@ -5,8 +5,14 @@ #include #include #include +#include +#include + #include +#include "../terrain/generator.h" +#include "../world.h" + namespace { struct { uf::Object left, right; @@ -170,68 +176,184 @@ void ext::Hands::tick() { transform.orientation = ext::openvr::controllerQuaternion( vr::Controller_Hand::Hand_Right, true ); transform.scale = { 1, 1, 1 }; // transform.reference = hands.right.getComponentPointer>(); + } - // test - struct { - pod::Vector3f origin; - pod::Vector3f direction; - } ray; - struct { - pod::Vector3f center; - pod::Vector3f normal; - } plane; + // raytrace pointer / hand collision + { + std::vector handPointers = { &::hands.left, &::hands.right }; + for ( auto pointer : handPointers ) { auto& hand = *pointer; + std::string side = &hand == &hands.left ? "left" : "right"; + if ( !ext::openvr::controllerActive( side == "left" ? vr::Controller_Hand::Hand_Left : vr::Controller_Hand::Hand_Right ) ) continue; + { + pod::Transform<>& transform = (side == "left" ? lines.left : lines.right).getComponent>(); + struct { + pod::Vector3f origin; + pod::Vector3f direction; + } ray; + struct { + pod::Vector3f center; + pod::Vector3f normal; + } plane; - transform = uf::transform::reorient( transform ); - ray.origin = transform.position; - ray.direction = transform.forward; + transform = uf::transform::reorient( transform ); + ray.origin = transform.position; + ray.direction = transform.forward; - pod::Transform<> gtransform; - pod::Matrix4f mvp; - uf::Serializer& cMetadata = controller.getComponent(); - if ( cMetadata["overlay"]["position"].isArray() ) - gtransform.position = { - cMetadata["overlay"]["position"][0].asFloat(), - cMetadata["overlay"]["position"][1].asFloat(), - cMetadata["overlay"]["position"][2].asFloat(), - }; - if ( cMetadata["overlay"]["scale"].isArray() ) - gtransform.scale = { - cMetadata["overlay"]["scale"][0].asFloat(), - cMetadata["overlay"]["scale"][1].asFloat(), - cMetadata["overlay"]["scale"][2].asFloat(), - }; - if ( cMetadata["overlay"]["orientation"].isArray() ) - gtransform.orientation = { - cMetadata["overlay"]["orientation"][0].asFloat(), - cMetadata["overlay"]["orientation"][1].asFloat(), - cMetadata["overlay"]["orientation"][2].asFloat(), - cMetadata["overlay"]["orientation"][3].asFloat(), - }; + pod::Transform<> gtransform; + pod::Matrix4f mvp; + uf::Serializer& cMetadata = controller.getComponent(); + if ( cMetadata["overlay"]["position"].isArray() ) + gtransform.position = { + cMetadata["overlay"]["position"][0].asFloat(), + cMetadata["overlay"]["position"][1].asFloat(), + cMetadata["overlay"]["position"][2].asFloat(), + }; + if ( cMetadata["overlay"]["scale"].isArray() ) + gtransform.scale = { + cMetadata["overlay"]["scale"][0].asFloat(), + cMetadata["overlay"]["scale"][1].asFloat(), + cMetadata["overlay"]["scale"][2].asFloat(), + }; + if ( cMetadata["overlay"]["orientation"].isArray() ) + gtransform.orientation = { + cMetadata["overlay"]["orientation"][0].asFloat(), + cMetadata["overlay"]["orientation"][1].asFloat(), + cMetadata["overlay"]["orientation"][2].asFloat(), + cMetadata["overlay"]["orientation"][3].asFloat(), + }; - plane.center = gtransform.position; - { - auto rotated = uf::quaternion::multiply( gtransform.orientation, pod::Vector4f{ 0, 0, 1, 1 } ); - plane.normal.x = rotated.x; - plane.normal.y = rotated.y; - plane.normal.z = rotated.z; - plane.normal = uf::vector::normalize( plane.normal ); - } - - float denom = uf::vector::dot(plane.normal, ray.direction); - if (abs(denom) > 0.0001f) { - float t = uf::vector::dot( uf::vector::subtract(plane.center, ray.origin), plane.normal ) / denom; - if ( t >= 0 ) { - pod::Vector3f hit = ray.origin + (ray.direction * t); - pod::Vector3f translated = uf::matrix::multiply( uf::matrix::inverse( uf::matrix::scale( uf::matrix::identity(), gtransform.scale ) ), uf::vector::subtract( plane.center, hit ) ); + plane.center = gtransform.position; { - auto& metadata = this->getComponent(); - cMetadata["overlay"]["cursor"]["type"] = "vr"; - cMetadata["overlay"]["cursor"]["position"][0] = translated.x; - cMetadata["overlay"]["cursor"]["position"][1] = translated.y; - cMetadata["overlay"]["cursor"]["position"][2] = translated.z; - - metadata["hands"]["right"]["cursor"] = cMetadata["overlay"]["cursor"]; + auto rotated = uf::quaternion::multiply( gtransform.orientation, pod::Vector4f{ 0, 0, 1, 1 } ); + plane.normal.x = rotated.x; + plane.normal.y = rotated.y; + plane.normal.z = rotated.z; + plane.normal = uf::vector::normalize( plane.normal ); } + + float denom = uf::vector::dot(plane.normal, ray.direction); + if (abs(denom) > 0.0001f) { + float t = uf::vector::dot( uf::vector::subtract(plane.center, ray.origin), plane.normal ) / denom; + if ( t >= 0 ) { + pod::Vector3f hit = ray.origin + (ray.direction * t); + pod::Vector3f translated = uf::matrix::multiply( uf::matrix::inverse( uf::matrix::scale( uf::matrix::identity(), gtransform.scale ) ), uf::vector::subtract( plane.center, hit ) ); + { + auto& metadata = this->getComponent(); + cMetadata["overlay"]["cursor"]["type"] = "vr"; + cMetadata["overlay"]["cursor"]["position"][0] = translated.x; + cMetadata["overlay"]["cursor"]["position"][1] = translated.y; + cMetadata["overlay"]["cursor"]["position"][2] = translated.z; + + metadata["hands"][side]["cursor"] = cMetadata["overlay"]["cursor"]; + } + } + } + } + + #define DEBUG_MARKER() std::cout << side << ": " << __LINE__ << std::endl; + + /* Collision against world */ { + bool local = true; + bool sort = false; + // pod::Thread& thread = uf::thread::fetchWorker(); + pod::Thread& thread = uf::thread::has("Physics") ? uf::thread::get("Physics") : uf::thread::create( "Physics", true, false ); + auto function = [&]() -> int { + if ( !controller.hasParent() ) return 0; + if ( controller.getParent().getName() != "Region" ) return 0; + + pod::Transform<> transform = hand.getComponent>(); + transform.position = uf::quaternion::rotate( controller.getComponent>().orientation, transform.position ); + transform.position += controller.getComponent>().position; + transform.position += camera.getTransform().position; + + uf::Entity& parent = controller.getParent(); + ext::TerrainGenerator& generator = parent.getComponent(); + uf::Serializer& rMetadata = parent.getComponent(); + pod::Transform<>& rTransform = parent.getComponent>(); + + pod::Vector3ui size; { + size.x = rMetadata["region"]["size"][0].asUInt(); + size.y = rMetadata["region"]["size"][1].asUInt(); + size.z = rMetadata["region"]["size"][2].asUInt(); + } + pod::Vector3f voxelPosition = transform.position - rTransform.position; + voxelPosition.x += size.x / 2.0f; + voxelPosition.y += size.y / 2.0f + 1; + voxelPosition.z += size.z / 2.0f; + + uf::CollisionBody pCollider; + std::vector positions = { + { voxelPosition.x, voxelPosition.y, voxelPosition.z }, + { voxelPosition.x - 1, voxelPosition.y, voxelPosition.z }, + { voxelPosition.x + 1, voxelPosition.y, voxelPosition.z }, + { voxelPosition.x, voxelPosition.y - 1, voxelPosition.z }, + { voxelPosition.x, voxelPosition.y + 1, voxelPosition.z }, + { voxelPosition.x, voxelPosition.y, voxelPosition.z - 1 }, + { voxelPosition.x, voxelPosition.y, voxelPosition.z + 1 }, + }; + + { + auto& metadata = this->getComponent(); + // bottom + uint16_t uid = generator.getVoxel( voxelPosition.x, voxelPosition.y, voxelPosition.z ); + auto light = generator.getLight( voxelPosition.x, voxelPosition.y, voxelPosition.z ); + metadata["hands"][side]["controller"]["color"][0] = ((light >> 12) & 0xF) / (float) (0xF); + metadata["hands"][side]["controller"]["color"][1] = ((light >> 8) & 0xF) / (float) (0xF); + metadata["hands"][side]["controller"]["color"][2] = ((light >> 4) & 0xF) / (float) (0xF); + metadata["hands"][side]["controller"]["color"][3] = ((light ) & 0xF) / (float) (0xF); + } + + for ( auto& position : positions ) { + ext::TerrainVoxel voxel = ext::TerrainVoxel::atlas( generator.getVoxel( position.x, position.y, position.z ) ); + pod::Vector3 offset = rTransform.position; + offset.x += position.x - (size.x / 2.0f); + offset.y += position.y - (size.y / 2.0f); + offset.z += position.z - (size.z / 2.0f); + + if ( !voxel.solid() ) continue; + + uf::Collider* box = new uf::AABBox( offset, {0.5, 0.5, 0.5} ); + pCollider.add(box); + } + + uf::CollisionBody& collider = hand.getComponent(); { + collider.clear(); + uf::Collider* box = new uf::AABBox( transform.position, {0.25, 0.25, 0.25} ); + collider.add(box); + } + + pod::Physics& physics = hand.getComponent(); + auto result = pCollider.intersects(collider); + uf::Collider::Manifold strongest; + strongest.depth = 0.001; + for ( auto manifold : result ) { + if ( manifold.colliding && manifold.depth > 0 ) { + if ( strongest.depth < manifold.depth ) strongest = manifold; + } + } + if ( strongest.colliding ) { + + pod::Vector3 correction = uf::vector::normalize(strongest.normal) * -(strongest.depth * strongest.depth * 1.001); + { + float mag = uf::vector::magnitude( correction ); + uf::Serializer payload; + payload["delay"] = 0.0f; + payload["duration"] = uf::physics::time::delta; + payload["frequency"] = 1.0f; + payload["amplitude"] = fmin(1.0f, 1000.0f * mag); + payload["side"] = side; + uf::hooks.call( "VR:Haptics." + side, payload ); + } + /* + transform.position += correction; + if ( strongest.normal.x == 1 || strongest.normal.x == -1 ) physics.linear.velocity.x = 0; + if ( strongest.normal.y == 1 || strongest.normal.y == -1 ) physics.linear.velocity.y = 0; + if ( strongest.normal.z == 1 || strongest.normal.z == -1 ) physics.linear.velocity.z = 0; + */ + } + return 0; + }; + if ( local ) function(); else uf::thread::add( thread, function, true ); } } } diff --git a/ext/scenes/world/player/player.cpp b/ext/scenes/world/player/player.cpp index e1e29825..91b6136a 100644 --- a/ext/scenes/world/player/player.cpp +++ b/ext/scenes/world/player/player.cpp @@ -312,6 +312,7 @@ void ext::Player::tick() { bool paused = uf::Window::isKeyPressed("Escape"); bool aux = uf::Window::isKeyPressed("F"); bool vee = uf::Window::isKeyPressed("V"); + bool walk = uf::Window::isKeyPressed("LAlt"); } keys; if ( ext::openvr::context ) { @@ -339,7 +340,7 @@ void ext::Player::tick() { struct { float move = 4; //uf::physics::time::delta * 4; - float rotate = uf::physics::time::delta * 0.75; + float rotate = uf::physics::time::delta * 1.25f; float limitSquared = 4*4; } speed; static uf::Timer timer(false); @@ -348,10 +349,12 @@ void ext::Player::tick() { if ( timer.elapsed().asDouble() >= 0.25 ) { timer.reset(); metadata["collision"]["should"] = !metadata["collision"]["should"].asBool(); - std::cout << metadata["collision"] << std::endl; + + physics.linear.velocity = {0,0,0}; } } - if ( keys.running ) speed.move = 8; + if ( keys.running ) speed.move *= 2; + else if ( keys.walk ) speed.move /= 4; speed.limitSquared = speed.move * speed.move; uf::Object* menu = (uf::Object*) this->getRootParent().findByName("Gui: Menu"); diff --git a/ext/scenes/world/portal/portal.cpp b/ext/scenes/world/portal/portal.cpp new file mode 100644 index 00000000..42e99154 --- /dev/null +++ b/ext/scenes/world/portal/portal.cpp @@ -0,0 +1,160 @@ +#include "portal.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include "../terrain/generator.h" +#include "../world.h" + +namespace { + +} + +EXT_OBJECT_REGISTER_CPP(Portals) +void ext::Portals::initialize() { + uf::Object::initialize(); + + auto& metadata = this->getComponent(); + + ext::Portal& red = *(new ext::Portal); this->addChild(red); + ext::Portal& blue = *(new ext::Portal); this->addChild(blue); + + metadata["portals"][0]["name"] = "Portal"; + metadata["portals"][1]["name"] = "Portal"; + + red.load( metadata["portals"][0] ); + blue.load( metadata["portals"][1] ); + + red.initialize(); + blue.initialize(); + + red.getComponent()["target"] = blue.getUid(); + blue.getComponent()["target"] = red.getUid(); +} +void ext::Portals::tick() { + uf::Object::tick(); +} +void ext::Portals::render() { + uf::Object::render(); +} +void ext::Portals::destroy() { + uf::Object::destroy(); +} + +EXT_OBJECT_REGISTER_CPP(Portal) +void ext::Portal::initialize() { + uf::Object::initialize(); + + auto& metadata = this->getComponent(); + auto& transform = this->getComponent>(); + auto& camera = this->getComponent(); + { + auto& scene = uf::scene::getCurrentScene(); + auto& controller = *scene.getController(); + // copies camera settings + camera = controller.getComponent(); + } + { + auto& renderMode = this->getComponent(); + std::string name = this->getName() + ": " + std::to_string((int) this->getUid()); + ext::vulkan::addRenderMode( &renderMode, name ); + if ( ext::openvr::enabled ) { + ext::openvr::initialize(); + + uint32_t width, height; + ext::openvr::recommendedResolution( width, height ); + + renderMode.width = width; + renderMode.height = height; + } + } +} +void ext::Portal::tick() { + uf::Object::tick(); + + auto& renderMode = this->getComponent(); + renderMode.target = ""; + + auto& scene = uf::scene::getCurrentScene(); + auto& controller = *scene.getController(); + auto& camera = this->getComponent(); + auto& metadata = this->getComponent(); +/* + static pod::Transform<> otherSideTransform = this->getComponent>(); + { + float step = 4.0f; + if ( uf::Window::isKeyPressed("B") ) otherSideTransform.position.x -= step * uf::physics::time::delta; + if ( uf::Window::isKeyPressed("M") ) otherSideTransform.position.x += step * uf::physics::time::delta; + if ( uf::Window::isKeyPressed("G") ) otherSideTransform.position.y += step * uf::physics::time::delta; + if ( uf::Window::isKeyPressed("J") ) otherSideTransform.position.y -= step * uf::physics::time::delta; + if ( uf::Window::isKeyPressed("H") ) otherSideTransform.position.z += step * uf::physics::time::delta; + if ( uf::Window::isKeyPressed("N") ) otherSideTransform.position.z -= step * uf::physics::time::delta; + if ( uf::Window::isKeyPressed("L") ) { + std::cout << otherSideTransform.position.x << ", " << otherSideTransform.position.y << ", " << otherSideTransform.position.z << "\t" << step * uf::physics::time::delta << std::endl; + } + } +*/ + { + auto& conCamera = controller.getComponent(); + auto& prtTransform = this->getComponent>(); + auto& otherSideTransform = this->getParent().findByUid( metadata["target"].asUInt() )->getComponent>(); + + for ( std::size_t i = 0; i < 2; ++i ) { + pod::Matrix4f controllerCameraToWorldMatrix = uf::matrix::inverse( conCamera.getView(i) ); + pod::Matrix4f worldToPortalMatrix = uf::matrix::inverse( uf::transform::model( prtTransform ) ); + pod::Matrix4f otherSideToWorldMatrix = uf::transform::model( otherSideTransform ); + camera.setView( uf::matrix::inverse(otherSideToWorldMatrix * worldToPortalMatrix * controllerCameraToWorldMatrix), i ); + } + } + +} +void ext::Portal::render() { + uf::Object::render(); + { + auto& renderMode = this->getComponent(); + auto& blitter = renderMode.blitter; + auto& transform = this->getComponent>(); + auto& scene = uf::scene::getCurrentScene(); + auto& controller = *scene.getController(); + auto& camera = this->getComponent(); + auto& controllerCamera = controller.getComponent(); + if ( !blitter.initialized ) return; + + for ( std::size_t i = 0; i < 2; ++i ) { + pod::Matrix4f model = uf::transform::model( transform ); + + blitter.uniforms.matrices.models[i] = controllerCamera.getProjection(i) * controllerCamera.getView(i) * model; + + blitter.uniforms.alpha = 1.0f; + + blitter.uniforms.cursor.position.x = -1.0f; + blitter.uniforms.cursor.position.y = -1.0f; + + blitter.uniforms.cursor.radius.x = 0.0f; + blitter.uniforms.cursor.radius.y = 0.0f; + + blitter.uniforms.cursor.color.x = 0.0f; + blitter.uniforms.cursor.color.y = 0.0f; + blitter.uniforms.cursor.color.z = 0.0f; + blitter.uniforms.cursor.color.w = 0.0f; + } + blitter.updateBuffer( (void*) &blitter.uniforms, sizeof(blitter.uniforms), 0 ); + } +} +void ext::Portal::destroy() { + auto& renderMode = this->getComponent(); + ext::vulkan::removeRenderMode( &renderMode, false ); + uf::Object::destroy(); +} \ No newline at end of file diff --git a/ext/scenes/world/portal/portal.h b/ext/scenes/world/portal/portal.h new file mode 100644 index 00000000..d79b44f2 --- /dev/null +++ b/ext/scenes/world/portal/portal.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include + +namespace ext { + class EXT_API Portal : public uf::Object { + protected: + public: + virtual void initialize(); + virtual void tick(); + virtual void render(); + virtual void destroy(); + }; +} + +namespace ext { + class EXT_API Portals : public uf::Object { + protected: + public: + virtual void initialize(); + virtual void tick(); + virtual void render(); + virtual void destroy(); + }; +} \ No newline at end of file diff --git a/ext/scenes/world/terrain/generator.cpp b/ext/scenes/world/terrain/generator.cpp index 08b14410..2ad0d752 100644 --- a/ext/scenes/world/terrain/generator.cpp +++ b/ext/scenes/world/terrain/generator.cpp @@ -28,12 +28,20 @@ namespace { COLOR uint16ToColor( uint16_t color ) { COLOR result; - memcpy( &result, &color, sizeof color ); + // memcpy( &result, &color, sizeof color ); + result.r = (color >> 12) & 0xF; + result.g = (color >> 8) & 0xF; + result.b = (color >> 4) & 0xF; + result.a = (color ) & 0xF; return result; } uint16_t colorToUint16( COLOR color ) { uint16_t result; - memcpy( &result, &color, sizeof color ); + // memcpy( &result, &color, sizeof color ); + result |= (color.r << 12); + result |= (color.g << 8); + result |= (color.b << 4); + result |= (color.a ); return result; } bool inBounds( int x, int y, int z, const pod::Vector3ui& size ) { diff --git a/ext/scenes/world/terrain/region.cpp b/ext/scenes/world/terrain/region.cpp index 006993ae..05876298 100644 --- a/ext/scenes/world/terrain/region.cpp +++ b/ext/scenes/world/terrain/region.cpp @@ -290,11 +290,8 @@ void ext::Region::render( ) { /* Update uniforms */ if ( this->hasComponent() ) { auto& world = this->getRootParent(); auto& mesh = this->getComponent(); - auto& camera = world.getController()->getComponent(); - + auto& camera = world.getController()->getComponent(); if ( !mesh.generated ) return; - camera.updateView(); - auto& uniforms = mesh.graphic.uniforms(); uniforms.matrices.model = uf::matrix::identity(); for ( std::size_t i = 0; i < 2; ++i ) { diff --git a/ext/scenes/world/terrain/terrain.cpp b/ext/scenes/world/terrain/terrain.cpp index fa8a4f5c..9616888f 100644 --- a/ext/scenes/world/terrain/terrain.cpp +++ b/ext/scenes/world/terrain/terrain.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/ext/scenes/world/world.cpp b/ext/scenes/world/world.cpp index a27203ec..818f54a3 100644 --- a/ext/scenes/world/world.cpp +++ b/ext/scenes/world/world.cpp @@ -293,16 +293,21 @@ void ext::World::tick() { ext::oal.listener( "VELOCITY", { 0, 0, 0 } ); ext::oal.listener( "ORIENTATION", { 0, 0, 1, 1, 0, 0 } ); } +} + +void ext::World::render() { + uf::Scene::render(); /* Update lights */ { + uf::Serializer& metadata = this->getComponent(); auto& scene = *this; std::vector blitters; - auto& renderMode = ext::vulkan::getRenderMode("Stereoscopic Deferred", true); - if ( renderMode.getType() == "Stereoscopic Deferred" ) { + auto& renderMode = ext::vulkan::getRenderMode("", true); + if ( renderMode.getType() == "Deferred (Stereoscopic)" ) { auto* renderModePointer = (ext::vulkan::StereoscopicDeferredRenderMode*) &renderMode; blitters.push_back(&renderModePointer->blitters.left); blitters.push_back(&renderModePointer->blitters.right); - } else { + } else if ( renderMode.getType() == "Deferred" ) { auto* renderModePointer = (ext::vulkan::DeferredRenderMode*) &renderMode; blitters.push_back(&renderModePointer->blitter); } @@ -394,6 +399,20 @@ void ext::World::tick() { } } -void ext::World::render() { - uf::Scene::render(); +uf::Entity* ext::World::getController() { + if ( ext::vulkan::currentRenderMode ) { + auto& renderMode = *ext::vulkan::currentRenderMode; + std::string name = renderMode.name; + auto split = uf::string::split( name, ": " ); + if ( split.front() == "Portal" ) { + uint64_t uid = std::stoi( split.back() ); + uf::Entity* portal = this->findByUid( uid ); + if ( portal ) return portal; + } + } + return uf::Scene::getController(); +} + +const uf::Entity* ext::World::getController() const { + return uf::Scene::getController(); } \ No newline at end of file diff --git a/ext/scenes/world/world.h b/ext/scenes/world/world.h index 3daed9a0..a31008f0 100644 --- a/ext/scenes/world/world.h +++ b/ext/scenes/world/world.h @@ -12,5 +12,8 @@ namespace ext { virtual void initialize(); virtual void tick(); virtual void render(); + + virtual uf::Entity* getController(); + virtual const uf::Entity* getController() const; }; } \ No newline at end of file