Refactor gfx attribs: store vertex & instance size in attrib description
This commit is contained in:
parent
0bed4ae39f
commit
e4f0675a1d
2 changed files with 36 additions and 52 deletions
|
|
@ -19,7 +19,6 @@ namespace psemek::gfx
|
||||||
GLint size;
|
GLint size;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
GLboolean normalized;
|
GLboolean normalized;
|
||||||
GLsizei stride;
|
|
||||||
void const * pointer;
|
void const * pointer;
|
||||||
GLuint divisor;
|
GLuint divisor;
|
||||||
};
|
};
|
||||||
|
|
@ -27,7 +26,11 @@ namespace psemek::gfx
|
||||||
struct attribs_description
|
struct attribs_description
|
||||||
{
|
{
|
||||||
std::vector<attrib_description> attribs;
|
std::vector<attrib_description> attribs;
|
||||||
GLuint index_count;
|
GLuint index_count = 0;
|
||||||
|
GLuint vertex_size = 0;
|
||||||
|
GLuint instance_size = 0;
|
||||||
|
|
||||||
|
attribs_description & operator += (attribs_description const & d);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline attribs_description operator + (attribs_description d1, attribs_description const & d2)
|
inline attribs_description operator + (attribs_description d1, attribs_description const & d2)
|
||||||
|
|
@ -35,12 +38,21 @@ namespace psemek::gfx
|
||||||
for (auto a : d2.attribs)
|
for (auto a : d2.attribs)
|
||||||
{
|
{
|
||||||
a.index += d1.index_count;
|
a.index += d1.index_count;
|
||||||
|
a.pointer = reinterpret_cast<char const *>(a.pointer) + (a.divisor == 0 ? d1.vertex_size : d1.instance_size);
|
||||||
d1.attribs.push_back(a);
|
d1.attribs.push_back(a);
|
||||||
}
|
}
|
||||||
d1.index_count += d2.index_count;
|
d1.index_count += d2.index_count;
|
||||||
|
d1.vertex_size += d2.vertex_size;
|
||||||
|
d1.instance_size += d2.instance_size;
|
||||||
return d1;
|
return d1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline attribs_description & attribs_description::operator += (attribs_description const & d)
|
||||||
|
{
|
||||||
|
(*this) = (*this) + d;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct normalized
|
struct normalized
|
||||||
{
|
{
|
||||||
|
|
@ -263,32 +275,6 @@ namespace psemek::gfx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool Instance, typename ... Attribs>
|
|
||||||
struct stride_helper;
|
|
||||||
|
|
||||||
template <bool Instance>
|
|
||||||
struct stride_helper<Instance>
|
|
||||||
{
|
|
||||||
static std::size_t stride()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool Instance, typename Attr1, typename ... Attribs>
|
|
||||||
struct stride_helper<Instance, Attr1, Attribs...>
|
|
||||||
{
|
|
||||||
static std::size_t stride()
|
|
||||||
{
|
|
||||||
std::size_t s = 0;
|
|
||||||
if constexpr (is_instanced<Attr1>::value == Instance)
|
|
||||||
{
|
|
||||||
s = attr_size<Attr1>();
|
|
||||||
}
|
|
||||||
return s + stride_helper<Instance, Attribs...>::stride();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool Instance, typename ... Attribs>
|
template <bool Instance, typename ... Attribs>
|
||||||
struct make_attribs_description_impl;
|
struct make_attribs_description_impl;
|
||||||
|
|
||||||
|
|
@ -298,9 +284,17 @@ namespace psemek::gfx
|
||||||
static void make(attribs_description &)
|
static void make(attribs_description &)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
static void make_impl(attribs_description & result, std::size_t index, std::size_t, std::size_t)
|
static void make_impl(attribs_description & result, std::size_t index, std::size_t offset)
|
||||||
{
|
{
|
||||||
result.index_count = index;
|
result.index_count = index;
|
||||||
|
if constexpr (Instance)
|
||||||
|
{
|
||||||
|
result.instance_size = offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.vertex_size = offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -309,19 +303,18 @@ namespace psemek::gfx
|
||||||
{
|
{
|
||||||
static void make(attribs_description & result)
|
static void make(attribs_description & result)
|
||||||
{
|
{
|
||||||
std::size_t const stride = stride_helper<Instance, Attr1, Attribs...>::stride();
|
make_impl(result, 0, 0);
|
||||||
make_impl(result, 0, 0, stride);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_impl(attribs_description & result, std::size_t index, std::size_t offset, std::size_t stride)
|
static void make_impl(attribs_description & result, std::size_t index, std::size_t offset)
|
||||||
{
|
{
|
||||||
if constexpr (std::is_same_v<Attr1, skip>)
|
if constexpr (std::is_same_v<Attr1, skip>)
|
||||||
{
|
{
|
||||||
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + 1, offset, stride);
|
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + 1, offset);
|
||||||
}
|
}
|
||||||
else if constexpr (is_padding<Attr1>::value)
|
else if constexpr (is_padding<Attr1>::value)
|
||||||
{
|
{
|
||||||
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index, Instance ? offset : offset + Attr1::size, stride);
|
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index, Instance ? offset : offset + Attr1::size);
|
||||||
}
|
}
|
||||||
else if constexpr (is_instanced<Attr1>::value == Instance)
|
else if constexpr (is_instanced<Attr1>::value == Instance)
|
||||||
{
|
{
|
||||||
|
|
@ -339,14 +332,13 @@ namespace psemek::gfx
|
||||||
attr.size = traits::size;
|
attr.size = traits::size;
|
||||||
attr.type = traits::type;
|
attr.type = traits::type;
|
||||||
attr.normalized = traits::normalized;
|
attr.normalized = traits::normalized;
|
||||||
attr.stride = stride;
|
|
||||||
attr.pointer = reinterpret_cast<char const *>(offset + row * attr::static_columns * sizeof(T));
|
attr.pointer = reinterpret_cast<char const *>(offset + row * attr::static_columns * sizeof(T));
|
||||||
attr.divisor = Instance ? 1 : 0;
|
attr.divisor = Instance ? 1 : 0;
|
||||||
|
|
||||||
result.attribs.push_back(attr);
|
result.attribs.push_back(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + attr::static_rows, offset + attr_size<Attr1>(), stride);
|
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + attr::static_rows, offset + attr_size<Attr1>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -358,13 +350,12 @@ namespace psemek::gfx
|
||||||
attr.size = traits::size;
|
attr.size = traits::size;
|
||||||
attr.type = traits::type;
|
attr.type = traits::type;
|
||||||
attr.normalized = traits::normalized;
|
attr.normalized = traits::normalized;
|
||||||
attr.stride = stride;
|
|
||||||
attr.pointer = reinterpret_cast<char const *>(offset);
|
attr.pointer = reinterpret_cast<char const *>(offset);
|
||||||
attr.divisor = Instance ? 1 : 0;
|
attr.divisor = Instance ? 1 : 0;
|
||||||
|
|
||||||
result.attribs.push_back(attr);
|
result.attribs.push_back(attr);
|
||||||
|
|
||||||
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + 1, offset + attr_size<Attr1>(), stride);
|
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + 1, offset + attr_size<Attr1>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -373,11 +364,11 @@ namespace psemek::gfx
|
||||||
|
|
||||||
if constexpr (is_matrix<attr>::value)
|
if constexpr (is_matrix<attr>::value)
|
||||||
{
|
{
|
||||||
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + attr::static_rows, offset, stride);
|
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + attr::static_rows, offset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + 1, offset, stride);
|
make_attribs_description_impl<Instance, Attribs...>::make_impl(result, index + 1, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,28 +45,21 @@ namespace psemek::gfx
|
||||||
|
|
||||||
std::size_t max_index = 0;
|
std::size_t max_index = 0;
|
||||||
bool instanced = false;
|
bool instanced = false;
|
||||||
std::size_t stride = 0;
|
|
||||||
std::size_t instance_stride = 0;
|
|
||||||
|
|
||||||
for (auto const & a : attribs.attribs)
|
for (auto const & a : attribs.attribs)
|
||||||
{
|
{
|
||||||
max_index = std::max<std::size_t>(max_index, a.index);
|
max_index = std::max<std::size_t>(max_index, a.index);
|
||||||
|
|
||||||
if (a.divisor == 0)
|
if (a.divisor != 0)
|
||||||
{
|
|
||||||
stride = a.stride;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
assert(a.divisor == 1);
|
assert(a.divisor == 1);
|
||||||
instance_stride = a.stride;
|
|
||||||
instanced = true;
|
instanced = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info_.max_attribute_index_ = max_index;
|
info_.max_attribute_index_ = max_index;
|
||||||
info_.stride_ = stride;
|
info_.stride_ = attribs.vertex_size;
|
||||||
info_.instance_stride_ = instance_stride;
|
info_.instance_stride_ = attribs.instance_size;
|
||||||
info_.instanced_ = instanced;
|
info_.instanced_ = instanced;
|
||||||
|
|
||||||
if (!vertex_buffer_) vertex_buffer_ = buffer{};
|
if (!vertex_buffer_) vertex_buffer_ = buffer{};
|
||||||
|
|
@ -77,7 +70,7 @@ namespace psemek::gfx
|
||||||
if (a.divisor != 0) continue;
|
if (a.divisor != 0) continue;
|
||||||
|
|
||||||
gl::EnableVertexAttribArray(a.index);
|
gl::EnableVertexAttribArray(a.index);
|
||||||
gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, a.stride, a.pointer);
|
gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.vertex_size, a.pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanced)
|
if (instanced)
|
||||||
|
|
@ -90,7 +83,7 @@ namespace psemek::gfx
|
||||||
if (a.divisor == 0) continue;
|
if (a.divisor == 0) continue;
|
||||||
|
|
||||||
gl::EnableVertexAttribArray(a.index);
|
gl::EnableVertexAttribArray(a.index);
|
||||||
gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, a.stride, a.pointer);
|
gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.instance_size, a.pointer);
|
||||||
gl::VertexAttribDivisor(a.index, a.divisor);
|
gl::VertexAttribDivisor(a.index, a.divisor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue