Commit for 2020.08.12.7z

This commit is contained in:
mrq 2020-08-12 00:00:00 -05:00
parent de1e6e5cac
commit 014f7f8fe0
58 changed files with 1181 additions and 968 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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 );
}
}

View File

@ -15,7 +15,6 @@ layout (location = 2) out flat Cursor outCursor;
layout( push_constant ) uniform PushBlock {
uint pass;
vec2 cursor;
} PushConstant;
out gl_PerVertex {

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -1,46 +0,0 @@
#pragma once
#include <uf/ext/vulkan/device.h>
#include <uf/ext/vulkan/swapchain.h>
#include <uf/ext/vulkan/initializers.h>
#include <uf/ext/vulkan/graphic.h>
#include <uf/ext/vulkan/texture.h>
#include <uf/utils/math/matrix.h>
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();
};
}
}

View File

@ -1,40 +0,0 @@
#pragma once
#include <uf/ext/vulkan/device.h>
#include <uf/ext/vulkan/swapchain.h>
#include <uf/ext/vulkan/initializers.h>
#include <uf/ext/vulkan/graphic.h>
#include <uf/ext/vulkan/texture.h>
#include <uf/utils/math/matrix.h>
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();
};
}
}

View File

@ -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;

View File

@ -10,6 +10,7 @@ namespace ext {
VkFence fence;
VkCommandBuffer commandBuffer;
std::string target;
// RAII
virtual std::string getType() const;

View File

@ -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<std::string> passes;
// extern UF_API std::vector<Graphic*>* graphics;
extern UF_API std::vector<RenderMode*> 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<RenderMode*> 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();

View File

@ -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 );

View File

@ -5,7 +5,7 @@
namespace pod {
// Simple Pixels (designed [to store in arrays] with minimal headaches)
template<typename T = pod::Math::num_t, std::size_t N = 4>
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<T,N>& Pixel ) const; // Equality check between two Pixels (not equals)
};
template<typename T>
struct UF_API Pixel<T,3> {
struct /*UF_API*/ Pixel<T,3> {
// XYZ access
T r = 0;
T g = 0;
@ -59,7 +59,7 @@ namespace pod {
inline bool operator!=( const Pixel<T,3>& Pixel ) const; // Equality check between two Pixels (not equals)
};
template<typename T>
struct UF_API Pixel<T,4> {
struct /*UF_API*/ Pixel<T,4> {
// XYZW access
T r = 0;
T g = 0;

View File

@ -61,6 +61,7 @@ namespace uf {
// Writes to first value
// template<typename T=pod::Matrix4> pod::Matrix<typename T::type_t, C, C>& /*UF_API*/ multiply( T& left, const T& right ); // Multiplies two matrices of same type and size together
template<typename T, typename U> pod::Matrix<typename T::type_t, T::columns, T::columns> multiply( T& left, const U& right ); // Multiplies two matrices of same type and size together
template<typename T> pod::Matrix<typename T::type_t, T::columns, T::columns> multiply( T& left, const T& right );
template<typename T=pod::Matrix4> T& /*UF_API*/ invert( T& matrix ); // Flip sign of all components
// Complex arithmetic
template<typename T=pod::Matrix4> T /*UF_API*/ translate( const T& matrix, const pod::Vector3t<typename T::type_t>& vector );
@ -77,7 +78,7 @@ namespace uf {
namespace uf {
template<typename T = pod::Math::num_t, std::size_t R = 4, std::size_t C = R>
class UF_API Matrix {
class /*UF_API*/ Matrix {
public:
// Easily access POD's type
typedef pod::Matrix<T,R,C> pod_t;

View File

@ -44,8 +44,8 @@ namespace uf {
template<typename T> T /*UF_API*/ lerp( const T& from, const T& to, double delta ); // Linearly interpolate between two vectors
template<typename T> T /*UF_API*/ slerp( const T& from, const T& to, double delta ); // Spherically interpolate between two vectors
template<typename T> typename T::type_t /*UF_API*/ distanceSquared( const T& vector ); // Gets the magnitude of the vector
template<typename T> typename T::type_t /*UF_API*/ distance( const T& vector ); // Gets the magnitude of the vector
template<typename T> typename T::type_t /*UF_API*/ distanceSquared( const T& a, const T& b ); // Gets the magnitude of the vector
template<typename T> typename T::type_t /*UF_API*/ distance( const T& a, const T& b ); // Gets the magnitude of the vector
template<typename T> typename T::type_t /*UF_API*/ magnitude( const T& vector ); // Gets the magnitude of the vector
template<typename T> typename T::type_t /*UF_API*/ norm( const T& vector ); // Compute the norm of the vector
template<typename T> T /*UF_API*/ normalize( const T& vector ); // Normalizes a vector
@ -59,12 +59,14 @@ namespace uf {
template<typename T> T inverse( const T& quaternion );
template<typename T> T& conjugate( T& quaternion );
template<typename T> T& inverse( T& quaternion );
template<typename T> pod::Quaternion<T> fromMatrix( const pod::Matrix4t<T>& matrix );
}
}
namespace uf {
template<typename T = pod::Math::num_t>
class UF_API Quaternion {
class /*UF_API*/ Quaternion {
public:
// Easily access POD's type
typedef pod::Quaternion<T> pod_t;

View File

@ -33,14 +33,16 @@ template<typename T> T uf::quaternion::multiply( const T& left, const T& right )
return q;
}
// Multiplies this quaternion by a scalar
/*
template<typename T> 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<typename T> T uf::quaternion::negate( const T& quaternion ) {
return uf::quaternion::inverse(quaternion);
}
template<typename T = pod::Math::num_t> pod::Quaternion<T> uf::quaternion::identity() {
template<typename T> pod::Quaternion<T> uf::quaternion::identity() {
return pod::Quaternion<T>{ 0, 0, 0, 1 };
}
// Writes to first value
@ -238,4 +240,50 @@ template<typename T> T& uf::quaternion::inverse( T& quaternion ) {
.z = -quaternion.z,
.w = quaternion.w
};
}
template<typename T> pod::Quaternion<T> uf::quaternion::fromMatrix( const pod::Matrix4t<T>& m ) {
pod::Quaternion<T> 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<T>(1)) * static_cast<T>(0.5);
T mult = static_cast<T>(0.25) / biggestVal;
switch(biggestIndex) {
case 0: return pod::Quaternion<T>{ 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<T>{ (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<T>{ (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<T>{ (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<T>{ 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;
}

View File

@ -20,7 +20,7 @@
namespace pod {
// Simple transforms (designed [to store in arrays] with minimal headaches)
template<typename T = pod::Math::num_t>
struct UF_API Transform {
struct /*UF_API*/ Transform {
typedef T type_t;
pod::Vector3t<T> position;
@ -117,9 +117,9 @@ namespace uf {
if ( flatten ) {
uf::Matrix4t<T> translation, rotation, scale;
pod::Transform<T> 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<typename T> pod::Matrix4t<T> /*UF_API*/ view( const pod::Transform<T>& transform, const pod::Vector3t<T>& offset = {0, 0, 0} ) {
uf::Matrix4t<T> translation, rotation;
pod::Transform<T> 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<typename T> pod::Transform<T> fromMatrix( const pod::Matrix4t<T>& matrix ) {
pod::Transform<T> transform;
transform.position = uf::matrix::multiply<float>( matrix, pod::Vector3f{ 0, 0, 0 } );
transform.orientation = uf::quaternion::fromMatrix( matrix );
return transform = reorient( transform );
}
}
}

View File

@ -53,7 +53,7 @@ namespace pod {
*/
// Simple vectors (designed [to store in arrays] with minimal headaches)
template<typename T = pod::Math::num_t, std::size_t N = 3>
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<typename T = pod::Math::num_t, std::size_t N = 3>
class UF_API Vector {
class /*UF_API*/ Vector {
public:
// Easily access POD's type
typedef pod::Vector<T,N> pod_t;

View File

@ -1,6 +1,6 @@
namespace pod {
template<typename T>
struct UF_API Vector<T,1> {
struct /*UF_API*/ Vector<T,1> {
// XY access
T x;
// n-dimensional/unspecialized vector access
@ -36,7 +36,7 @@ namespace pod {
inline bool operator>=( const Vector<T,1>& vector ) const; // Equality check between two vectors (greater than or equals)
};
template<typename T>
struct UF_API Vector<T,2> {
struct /*UF_API*/ Vector<T,2> {
// XY access
T x;
T y;
@ -73,7 +73,7 @@ namespace pod {
inline bool operator>=( const Vector<T,2>& vector ) const; // Equality check between two vectors (greater than or equals)
};
template<typename T>
struct UF_API Vector<T,3> {
struct /*UF_API*/ Vector<T,3> {
// XYZ access
T x;
T y;
@ -111,7 +111,7 @@ namespace pod {
inline bool operator>=( const Vector<T,3>& vector ) const; // Equality check between two vectors (greater than or equals)
};
template<typename T>
struct UF_API Vector<T,4> {
struct /*UF_API*/ Vector<T,4> {
// XYZW access
T x;
T y;
@ -519,7 +519,7 @@ inline bool pod::Vector<T,4>::operator>=( const pod::Vector<T,4>& vector ) const
//
namespace uf {
template<typename T>
struct UF_API Vector<T,1> {
struct /*UF_API*/ Vector<T,1> {
public:
// Easily access POD's type
typedef pod::Vector<T,1> pod_t;
@ -609,7 +609,7 @@ namespace uf {
inline operator const pod_t&() const { return this->m_pod; }
};
template<typename T>
struct UF_API Vector<T,2> {
struct /*UF_API*/ Vector<T,2> {
public:
// Easily access POD's type
typedef pod::Vector<T,2> pod_t;
@ -700,7 +700,7 @@ namespace uf {
inline operator const pod_t&() const { return this->m_pod; }
};
template<typename T>
struct UF_API Vector<T,3> {
struct /*UF_API*/ Vector<T,3> {
public:
// Easily access POD's type
typedef pod::Vector<T,3> pod_t;
@ -796,7 +796,7 @@ namespace uf {
inline operator const pod_t&() const { return this->m_pod; }
};
template<typename T>
struct UF_API Vector<T,4> {
struct /*UF_API*/ Vector<T,4> {
public:
// Easily access POD's type
typedef pod::Vector<T,4> pod_t;

View File

@ -8,13 +8,13 @@
#include <unordered_map>
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<uint8_t> color;
static std::vector<ext::vulkan::VertexDescriptor> descriptor;
static UF_API std::vector<ext::vulkan::VertexDescriptor> 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<ext::vulkan::VertexDescriptor> descriptor;
static UF_API std::vector<ext::vulkan::VertexDescriptor> 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<ext::vulkan::VertexDescriptor> descriptor;
static UF_API std::vector<ext::vulkan::VertexDescriptor> 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<ext::vulkan::VertexDescriptor> descriptor;
static UF_API std::vector<ext::vulkan::VertexDescriptor> 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<typename T>
class UF_API BaseMesh : public MeshBase {
class /*UF_API*/ BaseMesh : public MeshBase {
public:
typedef T vertex_t;
std::vector<vertex_t> 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;
*/
}

View File

@ -1,4 +1,4 @@
template<typename T, typename U = uint16_t>
template<typename T, typename U>
typename pod::RLE<T,U>::string_t uf::rle::encode( const std::vector<T>& source ) {
typename pod::RLE<T,U>::string_t destination;
destination.reserve( source.size() );
@ -12,7 +12,7 @@ typename pod::RLE<T,U>::string_t uf::rle::encode( const std::vector<T>& source )
destination.shrink_to_fit();
return destination;
}
template<typename T, typename U = uint16_t>
template<typename T, typename U>
std::vector<T> uf::rle::decode( const pod::RLE<T,U>& source ) {
std::vector<T> destination;

View File

@ -54,7 +54,7 @@ namespace uf {
uf::Time<T> UF_API_CALL operator+( const uf::Time<T>& t );
};
template<typename T = spec::Time::time_t>
class UF_API Timer {
class /*UF_API*/ Timer {
public:
typedef T time_t;
typedef spec::Time::exp_t exp_t;

View File

@ -3,9 +3,22 @@
// Allows copy via assignment!
template<typename T>
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 <stdexcept>

View File

@ -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 ) {

View File

@ -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(),

View File

@ -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<std::string> 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 ) );

View File

@ -124,12 +124,12 @@ void ext::vulkan::Graphic::initializeDescriptorLayout( const std::vector<VkDescr
}
// Create pipeline
void ext::vulkan::Graphic::initializePipeline( VkGraphicsPipelineCreateInfo pipelineCreateInfo ) {
ext::vulkan::mutex.lock();
// ext::vulkan::mutex.lock();
pipelineCreateInfo.subpass = this->subpass;
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<VkDescriptorPoolSize>& poolSizes, size_t length ) {

View File

@ -1,225 +0,0 @@
#include <uf/ext/vulkan/initializers.h>
#include <uf/ext/vulkan/graphics/gui.h>
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/openvr/openvr.h>
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<uint32_t>(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<VkDynamicState> dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo dynamicState = ext::vulkan::initializers::pipelineDynamicStateCreateInfo(
dynamicStateEnables.data(),
static_cast<uint32_t>(dynamicStateEnables.size()),
0
);
// Binding description
std::vector<VkVertexInputBindingDescription> 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<VkVertexInputAttributeDescription> 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<uint32_t>(vertexBindingDescriptions.size());
vertexInputState.pVertexBindingDescriptions = vertexBindingDescriptions.data();
vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(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<uint32_t>(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();
}

View File

@ -1,231 +0,0 @@
#include <uf/ext/vulkan/initializers.h>
#include <uf/ext/vulkan/graphics/mesh.h>
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/openvr/openvr.h>
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<uint32_t>(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<VkDynamicState> dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR
};
VkPipelineDynamicStateCreateInfo dynamicState = ext::vulkan::initializers::pipelineDynamicStateCreateInfo(
dynamicStateEnables.data(),
static_cast<uint32_t>(dynamicStateEnables.size()),
0
);
// Binding description
std::vector<VkVertexInputBindingDescription> 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<VkVertexInputAttributeDescription> 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<uint32_t>(vertexBindingDescriptions.size());
vertexInputState.pVertexBindingDescriptions = vertexBindingDescriptions.data();
vertexInputState.vertexAttributeDescriptionCount = static_cast<uint32_t>(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<uint32_t>(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();
}

View File

@ -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<VkDescriptorSetLayoutBinding> 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<VkDescriptorImageInfo> 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<VkWriteDescriptorSet> 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 );

View File

@ -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 ));
}

View File

@ -75,11 +75,8 @@ void ext::vulkan::BaseRenderMode::createCommandBuffers( const std::vector<ext::v
scissor.offset.y = 0;
vkCmdSetScissor(commands[i], 0, 1, &scissor);
for ( auto pass : passes ) {
ext::vulkan::currentPass = pass;
for ( auto graphic : graphics ) {
graphic->createCommandBuffer(commands[i] );
}
for ( auto graphic : graphics ) {
graphic->createCommandBuffer(commands[i] );
}
vkCmdEndRenderPass(commands[i]);

View File

@ -10,7 +10,7 @@
#include <uf/utils/math/transform.h>
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<RenderMode*> layers = { &ext::vulkan::getRenderMode("Gui") };
std::vector<RenderMode*> 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<RenderMode*> 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<RenderMode*> 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<VkWriteDescriptorSet> 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<uint32_t>(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<VkDescriptorImageInfo> 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<VkWriteDescriptorSet> 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<uint32_t>(writeDescriptorSets.size()), writeDescriptorSets.data(), 0, nullptr );
}
}
}
@ -175,7 +195,7 @@ void ext::vulkan::DeferredRenderMode::createCommandBuffers( const std::vector<ex
imageMemoryBarrier.subresourceRange.layerCount = 1;
imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
std::vector<RenderMode*> layers = { &ext::vulkan::getRenderMode("Gui") };
std::vector<RenderMode*> 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::vector<ex
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 );
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::vector<ex
// render gui layer
{
for ( auto layer : layers ) {
if ( layer->getName() == "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::vector<ex
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 );
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;
}
}
}

View File

@ -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<VkClearValue> clearValues; clearValues.resize(2);
clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 0.0f } };
clearValues[1].depthStencil = { 0.0f, 0 };
std::vector<VkClearValue> 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]);
}

View File

@ -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<RenderMode*> layers = { &ext::vulkan::getRenderMode("Gui") };
std::vector<RenderMode*> 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<RenderMode*> 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<RenderMode*> 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<VkWriteDescriptorSet> 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<uint32_t>(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<VkDescriptorImageInfo> 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<VkWriteDescriptorSet> 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<uint32_t>(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<VkWriteDescriptorSet> 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<uint32_t>(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<RenderMode*> layers = { &ext::vulkan::getRenderMode("Gui") };
std::vector<RenderMode*> 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;
}
}

View File

@ -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;
}
{

View File

@ -21,7 +21,7 @@ bool ext::vulkan::rebuild = false;
uint32_t ext::vulkan::currentBuffer = 0;
std::vector<std::string> ext::vulkan::passes = { "BASE" };
std::vector<uf::Scene*> ext::vulkan::scenes;
std::string ext::vulkan::currentPass = "BASE";
ext::vulkan::RenderMode* ext::vulkan::currentRenderMode = NULL;
std::vector<ext::vulkan::RenderMode*> 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::RenderMode*> ext::vulkan::getRenderModes( const std::string& name, bool isName ) {
std::vector<RenderMode*> 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<void(uf::Entity*)> filter = [&]( uf::Entity* entity ) {
if ( !entity->hasComponent<uf::Mesh>() ) return;
uf::MeshBase& mesh = entity->getComponent<uf::Mesh>();
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() {

View File

@ -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;

View File

@ -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 );
}
});
}

View File

@ -1,4 +1,5 @@
#include <uf/utils/text/glyph.h>
#include <iostream>
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;
}
*/
}
}
}

View File

@ -18,7 +18,7 @@
#include <codecvt>
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/vulkan/graphics/gui.h>
#include <uf/ext/vulkan/graphics/base.h>
#include <uf/ext/vulkan/rendermodes/rendertarget.h>
#include <uf/ext/openvr/openvr.h>
@ -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;
};

View File

@ -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<>>() ) {
pod::Transform<> t = uf::transform::flatten(entity->getComponent<pod::Transform<>>());
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();

View File

@ -16,7 +16,7 @@
#include <unordered_map>
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/vulkan/graphics/gui.h>
#include <uf/ext/vulkan/graphics/base.h>
#include <uf/utils/http/http.h>
#include <uf/utils/audio/audio.h>
@ -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;

View File

@ -14,7 +14,7 @@
#include <unordered_map>
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/vulkan/graphics/gui.h>
#include <uf/ext/vulkan/graphics/base.h>
#include <uf/utils/http/http.h>
#include <uf/utils/audio/audio.h>

View File

@ -14,7 +14,7 @@
#include <unordered_map>
#include <uf/ext/vulkan/vulkan.h>
#include <uf/ext/vulkan/graphics/gui.h>
#include <uf/ext/vulkan/graphics/base.h>
#include <uf/utils/http/http.h>
#include <uf/utils/audio/audio.h>

View File

@ -9,7 +9,7 @@
#include <uf/utils/mesh/mesh.h>
#include <uf/utils/window/window.h>
#include <uf/utils/camera/camera.h>
#include <uf/ext/vulkan/graphics/mesh.h>
#include <uf/ext/vulkan/graphics/base.h>
#include <uf/ext/vulkan/device.h>
#include <uf/ext/vulkan/swapchain.h>
#include <uf/ext/vulkan/vulkan.h>

View File

@ -9,7 +9,7 @@
#include <uf/utils/mesh/mesh.h>
#include <uf/utils/window/window.h>
#include <uf/utils/camera/camera.h>
#include <uf/ext/vulkan/graphics/mesh.h>
#include <uf/ext/vulkan/graphics/base.h>
#include <uf/ext/vulkan/device.h>
#include <uf/ext/vulkan/swapchain.h>
#include <uf/ext/vulkan/vulkan.h>

View File

@ -7,7 +7,7 @@
#include <uf/utils/mesh/mesh.h>
#include <uf/utils/window/window.h>
#include <uf/utils/camera/camera.h>
#include <uf/ext/vulkan/graphics/mesh.h>
#include <uf/ext/vulkan/graphics/base.h>
#include <uf/ext/vulkan/device.h>
#include <uf/ext/vulkan/swapchain.h>
#include <uf/ext/vulkan/vulkan.h>
@ -54,6 +54,19 @@ void ext::HousamoSprite::initialize() {
uf::Asset& assetLoader = world.getComponent<uf::Asset>();
this->addHook( "graphics:Assign.%UID%", [&](const std::string& event)->std::string{
uf::Serializer json = event;
std::string filename = json["filename"].asString();
metadata["system"]["control"] = false;
if ( uf::string::extension(filename) != "png" ) return "false";
uf::Scene& scene = this->getRootParent<uf::Scene>();
uf::Asset& assetLoader = scene.getComponent<uf::Asset>();
const uf::Image* imagePointer = NULL;
try { imagePointer = &assetLoader.get<uf::Image>(filename); } catch ( ... ) {}
if ( !imagePointer ) return "false";
uf::Image image = *imagePointer;
uf::Mesh& mesh = this->getComponent<uf::Mesh>();
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<uf::StereoMeshDescriptor>();
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<ext::World>();
uf::Asset& assetLoader = world.getComponent<uf::Asset>();
const uf::Image* imagePointer = NULL;
try { imagePointer = &assetLoader.get<uf::Image>(filename); } catch ( ... ) {}
if ( !imagePointer ) return "false";
uf::Image image = *imagePointer;
uf::Mesh& mesh = this->getComponent<uf::Mesh>();
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<uf::Mesh>() ) {
auto& mesh = this->getComponent<uf::Mesh>();
auto& world = this->getRootParent<ext::World>();
auto& player = *world.getController();
auto& camera = player.getComponent<uf::Camera>();
auto& transform = player.getComponent<pod::Transform<>>();
auto& model = this->getComponent<pod::Transform<>>();
auto& scene = uf::scene::getCurrentScene();
auto& controller = *scene.getController();
auto& camera = controller.getComponent<uf::Camera>();
auto& transform = this->getComponent<pod::Transform<>>();
if ( !mesh.generated ) return;
uf::Serializer& metadata = this->getComponent<uf::Serializer>();
//auto& uniforms = mesh.graphic.uniforms<uf::StereoMeshDescriptor>();
auto& uniforms = mesh.graphic.uniforms<uf::StereoMeshDescriptor>();
uniforms.matrices.model = uf::transform::model( this->getComponent<pod::Transform<>>() );
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 );

View File

@ -5,8 +5,14 @@
#include <uf/utils/math/transform.h>
#include <uf/utils/math/physics.h>
#include <uf/utils/serialize/serializer.h>
#include <uf/utils/math/collision.h>
#include <uf/utils/thread/thread.h>
#include <uf/ext/openvr/openvr.h>
#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<pod::Transform<>>();
}
// test
struct {
pod::Vector3f origin;
pod::Vector3f direction;
} ray;
struct {
pod::Vector3f center;
pod::Vector3f normal;
} plane;
// raytrace pointer / hand collision
{
std::vector<uf::Object*> 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<pod::Transform<>>();
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<uf::Serializer>();
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<uf::Serializer>();
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<float>( 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<uf::Serializer>();
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<float>( uf::matrix::inverse( uf::matrix::scale( uf::matrix::identity(), gtransform.scale ) ), uf::vector::subtract( plane.center, hit ) );
{
auto& metadata = this->getComponent<uf::Serializer>();
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<pod::Transform<>>();
transform.position = uf::quaternion::rotate( controller.getComponent<pod::Transform<>>().orientation, transform.position );
transform.position += controller.getComponent<pod::Transform<>>().position;
transform.position += camera.getTransform().position;
uf::Entity& parent = controller.getParent();
ext::TerrainGenerator& generator = parent.getComponent<ext::TerrainGenerator>();
uf::Serializer& rMetadata = parent.getComponent<uf::Serializer>();
pod::Transform<>& rTransform = parent.getComponent<pod::Transform<>>();
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<pod::Vector3ui> 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<uf::Serializer>();
// 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<uf::CollisionBody>(); {
collider.clear();
uf::Collider* box = new uf::AABBox( transform.position, {0.25, 0.25, 0.25} );
collider.add(box);
}
pod::Physics& physics = hand.getComponent<pod::Physics>();
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 );
}
}
}

View File

@ -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<long long> 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");

View File

@ -0,0 +1,160 @@
#include "portal.h"
#include <uf/utils/mesh/mesh.h>
#include <uf/utils/camera/camera.h>
#include <uf/utils/math/transform.h>
#include <uf/utils/math/physics.h>
#include <uf/utils/serialize/serializer.h>
#include <uf/utils/math/collision.h>
#include <uf/utils/thread/thread.h>
#include <uf/utils/math/physics.h>
#include <uf/utils/window/window.h>
#include <uf/ext/openvr/openvr.h>
#include <uf/ext/vulkan/rendermodes/rendertarget.h>
#include "../terrain/generator.h"
#include "../world.h"
namespace {
}
EXT_OBJECT_REGISTER_CPP(Portals)
void ext::Portals::initialize() {
uf::Object::initialize();
auto& metadata = this->getComponent<uf::Serializer>();
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<uf::Serializer>()["target"] = blue.getUid();
blue.getComponent<uf::Serializer>()["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<uf::Serializer>();
auto& transform = this->getComponent<pod::Transform<>>();
auto& camera = this->getComponent<uf::Camera>();
{
auto& scene = uf::scene::getCurrentScene();
auto& controller = *scene.getController();
// copies camera settings
camera = controller.getComponent<uf::Camera>();
}
{
auto& renderMode = this->getComponent<ext::vulkan::RenderTargetRenderMode>();
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<ext::vulkan::RenderTargetRenderMode>();
renderMode.target = "";
auto& scene = uf::scene::getCurrentScene();
auto& controller = *scene.getController();
auto& camera = this->getComponent<uf::Camera>();
auto& metadata = this->getComponent<uf::Serializer>();
/*
static pod::Transform<> otherSideTransform = this->getComponent<pod::Transform<>>();
{
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<uf::Camera>();
auto& prtTransform = this->getComponent<pod::Transform<>>();
auto& otherSideTransform = this->getParent().findByUid( metadata["target"].asUInt() )->getComponent<pod::Transform<>>();
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<ext::vulkan::RenderTargetRenderMode>();
auto& blitter = renderMode.blitter;
auto& transform = this->getComponent<pod::Transform<>>();
auto& scene = uf::scene::getCurrentScene();
auto& controller = *scene.getController();
auto& camera = this->getComponent<uf::Camera>();
auto& controllerCamera = controller.getComponent<uf::Camera>();
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::RenderTargetRenderMode>();
ext::vulkan::removeRenderMode( &renderMode, false );
uf::Object::destroy();
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <uf/config.h>
#include <uf/ext/ext.h>
#include <uf/engine/entity/entity.h>
#include <uf/engine/object/object.h>
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();
};
}

View File

@ -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 ) {

View File

@ -290,11 +290,8 @@ void ext::Region::render( ) {
/* Update uniforms */ if ( this->hasComponent<ext::TerrainGenerator::mesh_t>() ) {
auto& world = this->getRootParent<uf::Scene>();
auto& mesh = this->getComponent<ext::TerrainGenerator::mesh_t>();
auto& camera = world.getController()->getComponent<uf::Camera>();
auto& camera = world.getController()->getComponent<uf::Camera>();
if ( !mesh.generated ) return;
camera.updateView();
auto& uniforms = mesh.graphic.uniforms<uf::StereoMeshDescriptor>();
uniforms.matrices.model = uf::matrix::identity();
for ( std::size_t i = 0; i < 2; ++i ) {

View File

@ -10,7 +10,7 @@
#include <uf/utils/mesh/mesh.h>
#include <uf/utils/camera/camera.h>
#include <uf/utils/thread/thread.h>
#include <uf/ext/vulkan/graphics/mesh.h>
#include <uf/ext/vulkan/graphics/base.h>
#include <uf/ext/vulkan/vulkan.h>
#include <uf/utils/string/hash.h>

View File

@ -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<uf::Serializer>();
auto& scene = *this;
std::vector<ext::vulkan::DeferredRenderingGraphic*> 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();
}

View File

@ -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;
};
}