|
|
|
@ -118,27 +118,137 @@ concept reflectable = refl::trait::is_reflectable_v<T>;
@@ -118,27 +118,137 @@ concept reflectable = refl::trait::is_reflectable_v<T>;
|
|
|
|
|
|
|
|
|
|
// void get_ubo(int size) { glGenBuffers(); }
|
|
|
|
|
|
|
|
|
|
struct gl_type_hint { |
|
|
|
|
size_t alignment; |
|
|
|
|
std::string name; |
|
|
|
|
bool is_array = false; |
|
|
|
|
size_t n_elems; |
|
|
|
|
size_t elem_size; |
|
|
|
|
size_t elem_alignment; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct field_info { |
|
|
|
|
std::string name; |
|
|
|
|
size_t size; |
|
|
|
|
size_t offset; |
|
|
|
|
gl_type_hint gl_type; |
|
|
|
|
void *data; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template <typename V> constexpr gl_type_hint get_alignment() { |
|
|
|
|
if constexpr (refl::is_reflectable<V>()) { |
|
|
|
|
size_t alignment = 4; |
|
|
|
|
auto type_name = refl::descriptor::get_simple_name( |
|
|
|
|
refl::reflect<std::remove_all_extents_t<V>>()); |
|
|
|
|
|
|
|
|
|
if (std::is_class<V>()) { |
|
|
|
|
return {4 * 4, type_name.c_str()}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (std::is_integral<V>()) { |
|
|
|
|
static_assert(!(std::is_integral<V>()) || sizeof(V) <= 4, |
|
|
|
|
"Only allow openglable integral types "); |
|
|
|
|
return {4, type_name.c_str()}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (sizeof(V) > 2) { |
|
|
|
|
// things that are 3 bytes or more get aligned to a vec4
|
|
|
|
|
alignment *= 4; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
spdlog::warn("Caution; using default logic for uniform alignment\n"); |
|
|
|
|
return {alignment, type_name.c_str()}; |
|
|
|
|
} |
|
|
|
|
spdlog::error("Unable to "); |
|
|
|
|
return {100, "SCREAMING"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <array_type V> static constexpr gl_type_hint get_alignment() { |
|
|
|
|
// static_assert(sizeof(std::remove_all_extents_t<V>) <= 4,
|
|
|
|
|
// "Don't support sizes > offset.");
|
|
|
|
|
auto type_hint = get_alignment<std::remove_all_extents_t<V>>(); |
|
|
|
|
type_hint.alignment = 4 * 4; |
|
|
|
|
type_hint.is_array = true; |
|
|
|
|
type_hint.elem_size = sizeof(std::remove_all_extents_t<V>); |
|
|
|
|
type_hint.elem_alignment = 4 * 4; |
|
|
|
|
// number of elements in the array
|
|
|
|
|
type_hint.n_elems = std::extent<V>::value; |
|
|
|
|
return type_hint; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<GLuint>() { |
|
|
|
|
return {4, "uint"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<GLint>() { return {4, "int"}; } |
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<GLboolean>() { |
|
|
|
|
return {4, "bool"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<bool>() { return {4, "bool"}; } |
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<glm::vec4>() { |
|
|
|
|
return {4 * 4, "vec4"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<glm::vec2>() { |
|
|
|
|
return {4 * 2, "vec2"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// template <> constexpr gl_type_hint get_alignment<ubo_proxy>() {
|
|
|
|
|
// gl_type_hint t = {};
|
|
|
|
|
// // get size
|
|
|
|
|
// return {4 * 4, "vec3"};
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// template <> constexpr gl_type_hint get_alignment<glm::vec3>() {
|
|
|
|
|
// return {4 * 4, "vec3"};
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<glm::mat3>() { |
|
|
|
|
gl_type_hint t = {4 * 4, "mat3"}; |
|
|
|
|
t.is_array = false; |
|
|
|
|
t.n_elems = 3; |
|
|
|
|
t.elem_alignment = 4 * 4; |
|
|
|
|
t.elem_size = sizeof(glm::vec3); |
|
|
|
|
return t; |
|
|
|
|
} |
|
|
|
|
template <> constexpr gl_type_hint get_alignment<glm::mat4>() { |
|
|
|
|
gl_type_hint t = {4 * 4, "mat4"}; |
|
|
|
|
t.is_array = false; |
|
|
|
|
t.n_elems = 3; |
|
|
|
|
t.elem_alignment = 4 * 4; |
|
|
|
|
t.elem_size = sizeof(glm::vec4); |
|
|
|
|
return t; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// template <reflectable V> constexpr gl_type_hint get_alignment() {
|
|
|
|
|
// // assuming is struct
|
|
|
|
|
// auto s = refl::reflect<V>();
|
|
|
|
|
// return {4 * 4, std::string(refl::descriptor::get_name(s))};
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<float>() { |
|
|
|
|
return {4, refl::descriptor::get_name(refl::reflect<float>()).c_str()}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> constexpr gl_type_hint get_alignment<double>() { |
|
|
|
|
return {4, "double"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename R, size_t N> |
|
|
|
|
static constexpr gl_type_hint |
|
|
|
|
get_alignment_field(refl::descriptor::field_descriptor<R, N> val) { |
|
|
|
|
return get_alignment< |
|
|
|
|
typename refl::descriptor::field_descriptor<R, N>::value_type>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <reflectable T> |
|
|
|
|
class ubo_proxy : public refl::runtime::proxy<ubo_proxy<T>, T> { |
|
|
|
|
// UBO proxy MUST have reflection enabled
|
|
|
|
|
// type to store a ubo containing <struct>
|
|
|
|
|
|
|
|
|
|
struct gl_type_hint { |
|
|
|
|
size_t alignment; |
|
|
|
|
const std::string name; |
|
|
|
|
bool is_array = false; |
|
|
|
|
size_t n_elems; |
|
|
|
|
size_t elem_size; |
|
|
|
|
size_t elem_alignment; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct field_info { |
|
|
|
|
std::string name; |
|
|
|
|
size_t size; |
|
|
|
|
size_t offset; |
|
|
|
|
gl_type_hint gl_type; |
|
|
|
|
void *data; |
|
|
|
|
}; |
|
|
|
|
GLuint ubo; |
|
|
|
|
GLuint binding_point; |
|
|
|
|
|
|
|
|
@ -167,126 +277,6 @@ private:
@@ -167,126 +277,6 @@ private:
|
|
|
|
|
typename refl::descriptor::field_descriptor<R, N>::value_type); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename R, size_t N> |
|
|
|
|
static constexpr gl_type_hint |
|
|
|
|
get_alignment_field(refl::descriptor::field_descriptor<R, N> val) { |
|
|
|
|
return get_alignment< |
|
|
|
|
typename refl::descriptor::field_descriptor<R, N>::value_type>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <reflectable V> static constexpr gl_type_hint get_alignment() { |
|
|
|
|
size_t alignment = 4; |
|
|
|
|
auto type_name = refl::descriptor::get_simple_name( |
|
|
|
|
refl::reflect<std::remove_all_extents_t<V>>()); |
|
|
|
|
|
|
|
|
|
if (std::is_class<V>()) { |
|
|
|
|
return {4 * 4, type_name.str()}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (std::is_integral<V>()) { |
|
|
|
|
static_assert(!(std::is_integral<V>()) || sizeof(V) <= 4, |
|
|
|
|
"Only allow openglable integral types "); |
|
|
|
|
return {4, std::string(type_name)}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (sizeof(V) > 2) { |
|
|
|
|
// things that are 3 bytes or more get aligned to a vec4
|
|
|
|
|
alignment *= 4; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
spdlog::warn("Caution; using default logic for uniform alignment\n"); |
|
|
|
|
return {alignment, std::string(type_name)}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename V> static constexpr gl_type_hint get_alignment() { |
|
|
|
|
fmt::print("Default"); |
|
|
|
|
spdlog::error("Invalid\n"); |
|
|
|
|
throw std::runtime_error("Invalid uniform data type"); |
|
|
|
|
return {4 * 4, "ERROR"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <array_type V> static constexpr gl_type_hint get_alignment() { |
|
|
|
|
// static_assert(sizeof(std::remove_all_extents_t<V>) <= 4,
|
|
|
|
|
// "Don't support sizes > offset.");
|
|
|
|
|
auto type_hint = get_alignment<std::remove_all_extents_t<V>>(); |
|
|
|
|
type_hint.alignment = 4 * 4; |
|
|
|
|
type_hint.is_array = true; |
|
|
|
|
type_hint.elem_size = sizeof(std::remove_all_extents_t<V>); |
|
|
|
|
type_hint.elem_alignment = 4 * 4; |
|
|
|
|
// number of elements in the array
|
|
|
|
|
type_hint.n_elems = std::extent<V>::value; |
|
|
|
|
return type_hint; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<GLuint>() { |
|
|
|
|
return {4, "uint"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<GLint>() { |
|
|
|
|
return {4, "int"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<int>() { |
|
|
|
|
return {4, "int"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<unsigned int>() { |
|
|
|
|
return {4, "uint"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<GLboolean>() { |
|
|
|
|
return {4, "bool"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<glm::vec4>() { |
|
|
|
|
return {4 * 4, "vec4"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<glm::vec2>() { |
|
|
|
|
return {4 * 2, "vec2"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// template <> static constexpr gl_type_hint get_alignment<ubo_proxy>() {
|
|
|
|
|
// gl_type_hint t = {};
|
|
|
|
|
// // get size
|
|
|
|
|
// return {4 * 4, "vec3"};
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// template <> static constexpr gl_type_hint get_alignment<glm::vec3>() {
|
|
|
|
|
// return {4 * 4, "vec3"};
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<glm::mat3>() { |
|
|
|
|
gl_type_hint t = {4 * 4, "mat3"}; |
|
|
|
|
t.is_array = false; |
|
|
|
|
t.n_elems = 3; |
|
|
|
|
t.elem_alignment = 4 * 4; |
|
|
|
|
t.elem_size = sizeof(glm::vec3); |
|
|
|
|
return t; |
|
|
|
|
} |
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<glm::mat4>() { |
|
|
|
|
gl_type_hint t = {4 * 4, "mat4"}; |
|
|
|
|
t.is_array = false; |
|
|
|
|
t.n_elems = 3; |
|
|
|
|
t.elem_alignment = 4 * 4; |
|
|
|
|
t.elem_size = sizeof(glm::vec4); |
|
|
|
|
return t; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// template <reflectable V> static constexpr gl_type_hint get_alignment() {
|
|
|
|
|
// // assuming is struct
|
|
|
|
|
// auto s = refl::reflect<V>();
|
|
|
|
|
// return {4 * 4, std::string(refl::descriptor::get_name(s))};
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<float>() { |
|
|
|
|
return {4, std::string(refl::descriptor::get_name(refl::reflect<float>()))}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <> static constexpr gl_type_hint get_alignment<double>() { |
|
|
|
|
return {4, "double"}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static constexpr size_t next_offset(size_t offset, size_t alignment) { |
|
|
|
|
return offset + (alignment - (offset % alignment)) % alignment; |
|
|
|
|
} |
|
|
|
@ -324,8 +314,8 @@ private:
@@ -324,8 +314,8 @@ private:
|
|
|
|
|
|
|
|
|
|
unsigned alignment = gl_type.alignment; |
|
|
|
|
auto n_offset = next_offset(offset, gl_type.alignment); |
|
|
|
|
fields.push_back({std::string(refl::descriptor::get_name(member)), |
|
|
|
|
size, n_offset, gl_type, |
|
|
|
|
fields.push_back({refl::descriptor::get_name(member).c_str(), size, |
|
|
|
|
n_offset, gl_type, |
|
|
|
|
static_cast<void *>(&member(item))}); |
|
|
|
|
|
|
|
|
|
offset = n_offset + static_cast<GLuint>(size); |
|
|
|
|