vulkan-project/vertex.hpp
2022-10-07 23:30:44 +02:00

60 lines
1.8 KiB
C++

#pragma once
/* #include <bits/ranges_base.h> */
#include <glm/glm.hpp>
#include <glm/gtx/hash.hpp>
#include <array>
#include <string>
/* #include <vulkan/vulkan_core.h> */
struct VkVertexInputBindingDescription;
struct VkVertexInputAttributeDescription;
namespace gz::vk {
template<typename T>
concept VertexType = requires {
requires std::same_as<decltype(T::getBindingDescription()), VkVertexInputBindingDescription>;
requires std::ranges::forward_range<decltype(T::getAttributeDescriptions())>;
requires std::same_as<std::ranges::range_value_t<decltype(T::getAttributeDescriptions())>, VkVertexInputAttributeDescription>;
};
template<typename T>
concept GLM_vec2_or_3 = std::same_as<glm::vec3, T> or std::same_as<glm::vec2, T>;
//
// VERTEX
//
/**
* @brief Base for 2D and 3D vertices with texture and/or color
*/
template<GLM_vec2_or_3 PosVec>
struct Vertex {
PosVec pos;
glm::vec3 color;
glm::vec2 texCoord;
std::string toString() const;
bool operator==(const Vertex& other) const;
static VkVertexInputBindingDescription getBindingDescription();
static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions();
}; // struct Vertex
using Vertex3D = Vertex<glm::vec3>;
using Vertex2D = Vertex<glm::vec2>;
} // namespace gz::vk
//
// HASHES
//
namespace std {
template<gz::vk::GLM_vec2_or_3 PosVec>
struct hash<gz::vk::Vertex<PosVec>> {
size_t operator()(gz::vk::Vertex<PosVec> const& vertex) const {
return ((hash<PosVec>()(vertex.pos)) ^
(hash<glm::vec3>()(vertex.color) << 1) >> 1 ) ^
(hash<glm::vec2>()(vertex.texCoord) << 1);
}
};
}