Last active
August 24, 2018 07:25
-
-
Save kovrov/b638144f5f17f37d29f02d8fbe9dfcd6 to your computer and use it in GitHub Desktop.
offset std::tuple
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <typename T> | |
uint32_t location() { | |
return T::kLocation; | |
} | |
template <typename T> | |
VkFormat format() { | |
return T::kFormat; | |
} | |
template <class Tuple, size_t... indices> | |
std::vector<VkVertexInputAttributeDescription> make_descriptions(std::index_sequence<indices...>, uint32_t binding) { | |
std::vector<VkVertexInputAttributeDescription> descr{ | |
{ | |
location<typename std::tuple_element<indices, Tuple>::type>(), | |
binding, | |
format<typename std::tuple_element<indices, Tuple>::type>(), | |
tuple_element_offset<indices, Tuple>() | |
}..., | |
}; | |
return descr; | |
} | |
template <class Tuple, size_t... indices> | |
std::vector<VkVertexInputAttributeDescription> make_vertex_input_attribute_descriptions(uint32_t binding) { | |
return make_descriptions<Tuple>(std::make_index_sequence<std::tuple_size<Tuple>::value>(), binding); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <typename sizeT> | |
constexpr sizeT align(sizeT size, sizeT alignment) { | |
const auto diff = alignment ? size % alignment : 0; | |
return size + (diff ? alignment - diff : 0); | |
} | |
template <size_t Index, typename TupleT> | |
struct offset_of; | |
template <typename TupleT> | |
struct offset_of<0, TupleT> { | |
enum : size_t { value = 0, }; | |
}; | |
template <typename TupleT> | |
struct offset_of<1, TupleT> { | |
typedef typename std::tuple_element<0, TupleT>::type PrevType; | |
typedef typename std::tuple_element<1, TupleT>::type Type; | |
enum : size_t { value = align(offset_of<0, TupleT>::value + sizeof(PrevType), alignof(Type))}; | |
}; | |
template <size_t Index, typename TupleT> | |
struct offset_of { | |
typedef typename std::tuple_element<Index - 1, TupleT>::type PrevType; | |
typedef typename std::tuple_element<Index, TupleT>::type Type; | |
enum : size_t { | |
value = align(offset_of<Index - 1, TupleT>::value + sizeof(PrevType), alignof(Type)), | |
}; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<size_t Idx, typename T> | |
uint32_t tuple_element_offset() { | |
T* p{nullptr}; | |
return static_cast<uint32_t>(reinterpret_cast<char*>(&std::get<Idx>(*p)) - reinterpret_cast<char*>(0)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace attributes { | |
struct Position : public glm::vec4 { | |
static constexpr uint32_t kLocation{3}; | |
static constexpr VkFormat kFormat{VK_FORMAT_R32G32B32A32_SFLOAT}; | |
}; | |
struct Color : public glm::vec3 { | |
static constexpr uint32_t kLocation{4}; | |
static constexpr VkFormat kFormat{VK_FORMAT_R32G32B32_SFLOAT}; | |
}; | |
struct UV : public glm::vec2 { | |
static constexpr uint32_t kLocation{5}; | |
static constexpr VkFormat kFormat{VK_FORMAT_R32G32_SFLOAT}; | |
}; | |
struct Byte { | |
char data; | |
static constexpr uint32_t kLocation{6}; | |
static constexpr VkFormat kFormat{VK_FORMAT_R8_UNORM}; | |
}; | |
typedef std::tuple<Position, Byte, Color, UV> VertexInput; | |
} // namespace attributes | |
int main() { | |
auto descriptions = make_vertex_input_attribute_descriptions<attributes::VertexInput>(0); | |
assert (descriptions[0].location == attributes::Position::kLocation); | |
assert (descriptions[0].offset == 0); | |
assert (descriptions[1].location == attributes::Byte::kLocation); | |
assert (descriptions[1].offset == 16); // position | |
assert (descriptions[2].location == attributes::Color::kLocation); | |
assert (descriptions[2].offset == 16 + 4); // 3 bytes padding for alignment | |
assert (descriptions[3].location == attributes::UV::kLocation); | |
assert (descriptions[3].offset == 16 + 4 + 12); | |
assert ((offset_of<2, attributes::VertexInput>::value) == descriptions[2].offset); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment