This commit is contained in:
parent
0b97e6eeec
commit
81e8b94a0f
|
@ -0,0 +1,77 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Math/Unit.h>
|
||||
#include <Orange/Math/Constants.h>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
class Radian;
|
||||
|
||||
template <typename T>
|
||||
class Degree : public Unit<Degree, T>
|
||||
{
|
||||
public:
|
||||
Degree() {}
|
||||
|
||||
explicit Degree(T value)
|
||||
: Unit<orange::detail::Degree, T>(value)
|
||||
{
|
||||
}
|
||||
|
||||
Degree(Unit<orange::detail::Degree, T> value)
|
||||
: Unit<orange::detail::Degree, T>(value)
|
||||
{
|
||||
}
|
||||
|
||||
template <class U>
|
||||
explicit Degree(Unit<orange::detail::Degree, U> value)
|
||||
: Unit<orange::detail::Degree, T>(value)
|
||||
{
|
||||
}
|
||||
|
||||
Degree(Unit<Radian, T> value);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Radian : public Unit<Radian, T>
|
||||
{
|
||||
public:
|
||||
Radian() {}
|
||||
|
||||
explicit Radian(T value)
|
||||
: Unit<orange::detail::Radian, T>(value)
|
||||
{
|
||||
}
|
||||
|
||||
Radian(Unit<orange::detail::Radian, T> value)
|
||||
: Unit<orange::detail::Radian, T>(value)
|
||||
{
|
||||
}
|
||||
template <class U>
|
||||
explicit Radian(Unit<orange::detail::Radian, U> value)
|
||||
: Unit<orange::detail::Radian, T>(value)
|
||||
{
|
||||
}
|
||||
|
||||
Radian(Unit<Degree, T> value);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Degree<T>::Degree(Unit<Radian, T> value)
|
||||
: Unit<orange::detail::Degree, T>(T(360) * T(value) / Math::Tau)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Radian<T>::Radian(Unit<Degree, T> value)
|
||||
: Unit<orange::detail::Radian, T>(T(value) * Math::Tau / T(360))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
using Radian = detail::Radian<float>;
|
||||
using Degree = detail::Degree<float>;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Math/Angle.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace orange::Math
|
||||
{
|
||||
inline float sin(const Radian& theta) { return sinf(static_cast<float>(theta)); }
|
||||
inline float cos(const Radian& theta) { return cosf(static_cast<float>(theta)); }
|
||||
inline float tan(const Radian& theta) { return tanf(static_cast<float>(theta)); }
|
||||
|
||||
template <typename T>
|
||||
constexpr T kroneckerDelta(const T& i, const T& j)
|
||||
{
|
||||
return i == j ? T{1} : T{0};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace orange::Math
|
||||
{
|
||||
static constexpr float Epsilon = std::numeric_limits<float>::epsilon();
|
||||
|
||||
static constexpr float Zero = 0.0f;
|
||||
static constexpr float One = 1.0f;
|
||||
static constexpr float Third = 0.33333333f;
|
||||
static constexpr float TwoThirds = 0.66666667f;
|
||||
|
||||
static constexpr float E = 2.718281828f;
|
||||
static constexpr float Pi = 3.141592654f;
|
||||
static constexpr float Tau = 6.283185307f;
|
||||
|
||||
static constexpr float Sqrt2 = 1.414213562f;
|
||||
static constexpr float Sqrt3 = 1.732050808f;
|
||||
|
||||
static constexpr float GoldenRatio = 1.618033989f;
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Math/Vector.h>
|
||||
#include <Orange/Math/Angle.h>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
|
@ -19,6 +20,16 @@ namespace orange
|
|||
}
|
||||
}
|
||||
|
||||
constexpr Matrix(const RowVector& scale)
|
||||
{
|
||||
for (size_t i = 0; i < Rows; i++)
|
||||
{
|
||||
RowVector vector{};
|
||||
vector[i] = scale[i];
|
||||
data[i] = vector;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
constexpr Matrix(const Args&... args)
|
||||
: data {{ args... }}
|
||||
|
@ -245,4 +256,6 @@ namespace orange
|
|||
return x.TransformResult(y, math::Multiply);
|
||||
}
|
||||
|
||||
using mat4 = Matrix<float, 4, 4>;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Math/Common.h>
|
||||
|
||||
namespace orange
|
||||
{
|
||||
mat4 translate(const vec3& v)
|
||||
{
|
||||
mat4 result;
|
||||
result[3] = vec4{ v[0], v[1], v[2], 1.0f };
|
||||
return result;
|
||||
}
|
||||
|
||||
mat4 scale(const vec3& v)
|
||||
{
|
||||
return mat4{vec4{v[0], v[1], v[2], 1.0f}};
|
||||
}
|
||||
|
||||
mat4 perspective(const Radian& fovy, float aspect, float zNear, float zFar)
|
||||
{
|
||||
Assert(fabsf(aspect - Math::Epsilon) > 0.0f && "Math::perspective `fovy` is 0/inf.");
|
||||
|
||||
const float tanHalfFovy = Math::tan(0.5f * fovy);
|
||||
|
||||
mat4 result{0.0f};
|
||||
result[0][0] = 1.0f / (aspect * tanHalfFovy);
|
||||
result[1][1] = 1.0f / (tanHalfFovy);
|
||||
result[2][2] = -(zFar + zNear) / (zFar - zNear);
|
||||
result[2][3] = -1.0f;
|
||||
result[3][2] = -2.0f * zFar * zNear / (zFar - zNear);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
#pragma once
|
||||
|
||||
namespace orange
|
||||
{
|
||||
|
||||
template <template <typename> class Derived, typename T>
|
||||
class Unit
|
||||
{
|
||||
template <template <typename> class, typename>
|
||||
friend class Unit;
|
||||
|
||||
public:
|
||||
using Type = T;
|
||||
|
||||
Unit()
|
||||
: m_value{T{0}}
|
||||
{
|
||||
}
|
||||
|
||||
explicit Unit(T value)
|
||||
: m_value{value}
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
explicit Unit(Unit<Derived, U> value)
|
||||
: m_value{T{value.m_value}}
|
||||
{
|
||||
}
|
||||
|
||||
explicit operator T() const { return m_value; }
|
||||
|
||||
bool operator==(Unit<Derived, T> other) const
|
||||
{
|
||||
return m_value == other.m_value;
|
||||
}
|
||||
|
||||
bool operator!=(Unit<Derived, T> other) const { return !operator==(other); }
|
||||
|
||||
bool operator<(Unit<Derived, T> other) const
|
||||
{
|
||||
return m_value < other.m_value;
|
||||
}
|
||||
|
||||
bool operator>(Unit<Derived, T> other) const
|
||||
{
|
||||
return m_value > other.m_value;
|
||||
}
|
||||
|
||||
bool operator<=(Unit<Derived, T> other) const { return !operator>(other); }
|
||||
|
||||
bool operator>=(Unit<Derived, T> other) const { return !operator<(other); }
|
||||
|
||||
Unit<Derived, T> operator-() const { return Unit<Derived, T>{-m_value}; }
|
||||
|
||||
Unit<Derived, T>& operator+=(Unit<Derived, T> other)
|
||||
{
|
||||
m_value += other.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Unit<Derived, T> operator+(Unit<Derived, T> other) const
|
||||
{
|
||||
return Unit<Derived, T>{m_value + other.m_value};
|
||||
}
|
||||
|
||||
Unit<Derived, T>& operator-=(Unit<Derived, T> other)
|
||||
{
|
||||
m_value -= other.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Unit<Derived, T> operator-(Unit<Derived, T> other) const
|
||||
{
|
||||
return Unit<Derived, T>{m_value - other.m_value};
|
||||
}
|
||||
|
||||
Unit<Derived, T>& operator*=(T number)
|
||||
{
|
||||
m_value *= number;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Unit<Derived, T> operator*(T number) const
|
||||
{
|
||||
return Unit<Derived, T>{m_value * number};
|
||||
}
|
||||
|
||||
Unit<Derived, T>& operator/=(T number)
|
||||
{
|
||||
m_value /= number;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Unit<Derived, T> operator/(T number) const
|
||||
{
|
||||
return Unit<Derived, T>{m_value / number};
|
||||
}
|
||||
|
||||
T operator/(Unit<Derived, T> other) const { return m_value / other.value; }
|
||||
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
|
||||
template <template <typename> class Derived, typename T>
|
||||
Unit<Derived, T> operator*(typename std::common_type<T>::type number,
|
||||
const Unit<Derived, T>& value)
|
||||
{
|
||||
return value * number;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <Orange/Core/Traits.h>
|
||||
#include <Orange/Core/Result.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace orange
|
||||
|
@ -40,4 +41,22 @@ namespace orange
|
|||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Formats>
|
||||
Result<VkFormat> FindSupportedFormat(VkPhysicalDevice physicalDevice, VkImageTiling tiling, VkFormatFeatureFlags features, Formats... formats)
|
||||
{
|
||||
for (auto& format : {formats...})
|
||||
{
|
||||
VkFormatProperties props;
|
||||
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props);
|
||||
|
||||
if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features)
|
||||
return Result<VkFormat>::Success(format);
|
||||
|
||||
if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features)
|
||||
return Result<VkFormat>::Success(format);
|
||||
}
|
||||
|
||||
return Result<VkFormat>::Error(BasicErrorCode::NotFound);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <Orange/Core/FileSystem.h>
|
||||
#include <Orange/Math/Vector.h>
|
||||
#include <Orange/Math/Matrix.h>
|
||||
#include <Orange/Math/Transformation.h>
|
||||
#include <Orange/Core/Parse.h>
|
||||
#include <Orange/Core/Variant.h>
|
||||
|
||||
|
@ -202,7 +203,7 @@ Result<MeshData> ParseOBJ(StringView buffer)
|
|||
if (j == 0 || stream::Consume(obj, end, "/"))
|
||||
{
|
||||
if (auto r_int = stream::Parse<uint32_t>(obj, end))
|
||||
indices[i][j] = *r_int;
|
||||
indices[i][j] = *r_int - 1; // OBJ indexing starts at one.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,19 +322,13 @@ int main(int argc, char** argv)
|
|||
},
|
||||
{
|
||||
.binding = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||
.descriptorCount = MaxBindlessResources,
|
||||
.stageFlags = VK_SHADER_STAGE_ALL,
|
||||
},
|
||||
{
|
||||
.binding = 2,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.pImmutableSamplers = &sampler,
|
||||
},
|
||||
{
|
||||
.binding = 3,
|
||||
.binding = 2,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.descriptorCount = MaxBindlessResources,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
|
@ -342,7 +337,6 @@ int main(int argc, char** argv)
|
|||
|
||||
constexpr VkDescriptorBindingFlags bindingFlags[] =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT,
|
||||
|
@ -453,7 +447,7 @@ int main(int argc, char** argv)
|
|||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||
.cullMode = VK_CULL_MODE_NONE, //VK_CULL_MODE_BACK_BIT,
|
||||
.frontFace = VK_FRONT_FACE_CLOCKWISE,
|
||||
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||
.lineWidth = 1.0f,
|
||||
};
|
||||
|
||||
|
@ -463,6 +457,16 @@ int main(int argc, char** argv)
|
|||
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
|
||||
};
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilInfo =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||
.depthTestEnable = VK_TRUE,
|
||||
.depthWriteEnable = VK_TRUE,
|
||||
.depthCompareOp = VK_COMPARE_OP_LESS,
|
||||
.minDepthBounds = 0.0f,
|
||||
.maxDepthBounds = 1.0f,
|
||||
};
|
||||
|
||||
VkPipelineColorBlendAttachmentState attachmentBlendState =
|
||||
{
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
|
||||
|
@ -505,7 +509,7 @@ int main(int argc, char** argv)
|
|||
.pViewportState = &viewportStateInfo,
|
||||
.pRasterizationState = &rasterizationInfo,
|
||||
.pMultisampleState = &multisampleInfo,
|
||||
.pDepthStencilState = nullptr,
|
||||
.pDepthStencilState = &depthStencilInfo,
|
||||
.pColorBlendState = &colorBlendStateInfo,
|
||||
.pDynamicState = &dynamicStateInfo,
|
||||
.layout = pipelineLayout,
|
||||
|
@ -533,11 +537,29 @@ int main(int argc, char** argv)
|
|||
VkBufferView bufferView = VK_NULL_HANDLE;
|
||||
vkCreateBufferView(r_renderContext->Device(), &bufferViewInfo, nullptr, &bufferView);
|
||||
|
||||
struct UniformData
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
};
|
||||
|
||||
UniformData uniformData
|
||||
{
|
||||
.projection = perspective(Degree(90.0f), 16.0f / 9.0f, 0.01f, 1024.0f),
|
||||
.view = translate(vec3{0.0f, 0.0f, -4.0f}),
|
||||
};
|
||||
|
||||
auto pooler = BufferPooler{ *r_buffer };
|
||||
auto meshData = r_mesh->vertexData.View();
|
||||
auto vertexSlice = *pooler.AllocSlice(meshData.size);
|
||||
auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t));
|
||||
auto uniformSlice = *pooler.AllocSlice(sizeof(UniformData));
|
||||
|
||||
VkDescriptorBufferInfo bufferInfo =
|
||||
{
|
||||
.buffer = r_buffer->buffer,
|
||||
.offset = 0,
|
||||
.range = r_buffer->size,
|
||||
.offset = uniformSlice.offset,
|
||||
.range = uniformSlice.size,
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet writeDescriptorSet[] =
|
||||
|
@ -550,25 +572,14 @@ int main(int argc, char** argv)
|
|||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.pBufferInfo = &bufferInfo,
|
||||
},
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSet,
|
||||
.dstBinding = 1,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||
.pTexelBufferView = &bufferView,
|
||||
},
|
||||
};
|
||||
vkUpdateDescriptorSets(r_renderContext->Device(), Size(writeDescriptorSet), writeDescriptorSet, 0, nullptr);
|
||||
|
||||
auto pooler = BufferPooler{ *r_buffer };
|
||||
auto meshData = r_mesh->vertexData.View();
|
||||
auto vertexSlice = *pooler.AllocSlice(meshData.size);
|
||||
auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t));
|
||||
|
||||
meshData.Copy ((uint8_t*)(r_buffer->ptr) + vertexSlice.offset);
|
||||
r_mesh->indices.Copy((uint8_t*)(r_buffer->ptr) + indexSlice.offset);
|
||||
|
||||
memcpy((uint8_t*)(r_buffer->ptr) + uniformSlice.offset, &uniformData, sizeof(uniformData));
|
||||
|
||||
while (r_window->Update())
|
||||
{
|
||||
VkCommandBuffer cmdBuf = r_swapchain->CommandBuffer();
|
||||
|
@ -637,7 +648,7 @@ int main(int argc, char** argv)
|
|||
.pColorAttachments = &attachmentInfo,
|
||||
};
|
||||
vkCmdBeginRendering(cmdBuf, &renderInfo);
|
||||
vkCmdDrawIndexed(cmdBuf, r_mesh->vertexData.VertexCount(), 1, 0, 0, 0);
|
||||
vkCmdDrawIndexed(cmdBuf, r_mesh->indices.Size(), 1, 0, 0, 0);
|
||||
vkCmdEndRendering(cmdBuf);
|
||||
|
||||
const VkImageMemoryBarrier colorToPresentBarrier =
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec3 inPos;
|
||||
layout(location = 1) in vec2 inUV;
|
||||
layout(location = 2) in vec3 inNormal;
|
||||
layout(binding = 0) uniform UniformData {
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
} u_data;
|
||||
|
||||
layout(location = 0) out vec4 outColor;
|
||||
layout(location = 0) in vec3 i_pos;
|
||||
layout(location = 1) in vec2 i_uv;
|
||||
layout(location = 2) in vec3 i_normal;
|
||||
|
||||
vec3 colors[3] = vec3[]
|
||||
layout(location = 0) out vec4 o_color;
|
||||
|
||||
vec3 k_colors[3] = vec3[]
|
||||
(
|
||||
vec3(1.0, 0.0, 0.0),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
|
@ -15,6 +20,6 @@ vec3 colors[3] = vec3[]
|
|||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(inPos, 1.0);
|
||||
outColor = vec4(colors[gl_VertexIndex], 1.0);
|
||||
gl_Position = u_data.projection * u_data.view * vec4(i_pos, 1.0);
|
||||
o_color = vec4(k_colors[gl_VertexIndex % 3], 1.0);
|
||||
}
|
|
@ -66,6 +66,12 @@ namespace orange
|
|||
return imageCount;
|
||||
}
|
||||
|
||||
static Result<VkFormat> FindDepthFormat(VkPhysicalDevice physicalDevice)
|
||||
{
|
||||
return FindSupportedFormat(physicalDevice, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
|
||||
VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT);
|
||||
}
|
||||
|
||||
Result<Swapchain> Swapchain::Create(RenderContext& context, VkSurfaceKHR surface)
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
|
@ -166,6 +172,8 @@ namespace orange
|
|||
renderFinishedSemaphores[i] = *r_renderSem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: Handle failure
|
||||
uint32_t imageIndex;
|
||||
vkAcquireNextImageKHR(context.Device(), swapchain, ~0u, imageAvailableSemaphores[0], VK_NULL_HANDLE, &imageIndex);
|
||||
|
|
Loading…
Reference in New Issue