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;
|
||||
GLenum type;
|
||||
GLboolean normalized;
|
||||
GLsizei stride;
|
||||
void const * pointer;
|
||||
GLuint divisor;
|
||||
};
|
||||
|
|
@ -27,7 +26,11 @@ namespace psemek::gfx
|
|||
struct attribs_description
|
||||
{
|
||||
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)
|
||||
|
|
@ -35,12 +38,21 @@ namespace psemek::gfx
|
|||
for (auto a : d2.attribs)
|
||||
{
|
||||
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.index_count += d2.index_count;
|
||||
d1.vertex_size += d2.vertex_size;
|
||||
d1.instance_size += d2.instance_size;
|
||||
return d1;
|
||||
}
|
||||
|
||||
inline attribs_description & attribs_description::operator += (attribs_description const & d)
|
||||
{
|
||||
(*this) = (*this) + d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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>
|
||||
struct make_attribs_description_impl;
|
||||
|
||||
|
|
@ -298,9 +284,17 @@ namespace psemek::gfx
|
|||
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;
|
||||
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)
|
||||
{
|
||||
std::size_t const stride = stride_helper<Instance, Attr1, Attribs...>::stride();
|
||||
make_impl(result, 0, 0, stride);
|
||||
make_impl(result, 0, 0);
|
||||
}
|
||||
|
||||
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>)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -339,14 +332,13 @@ namespace psemek::gfx
|
|||
attr.size = traits::size;
|
||||
attr.type = traits::type;
|
||||
attr.normalized = traits::normalized;
|
||||
attr.stride = stride;
|
||||
attr.pointer = reinterpret_cast<char const *>(offset + row * attr::static_columns * sizeof(T));
|
||||
attr.divisor = Instance ? 1 : 0;
|
||||
|
||||
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
|
||||
{
|
||||
|
|
@ -358,13 +350,12 @@ namespace psemek::gfx
|
|||
attr.size = traits::size;
|
||||
attr.type = traits::type;
|
||||
attr.normalized = traits::normalized;
|
||||
attr.stride = stride;
|
||||
attr.pointer = reinterpret_cast<char const *>(offset);
|
||||
attr.divisor = Instance ? 1 : 0;
|
||||
|
||||
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
|
||||
|
|
@ -373,11 +364,11 @@ namespace psemek::gfx
|
|||
|
||||
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
|
||||
{
|
||||
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;
|
||||
bool instanced = false;
|
||||
std::size_t stride = 0;
|
||||
std::size_t instance_stride = 0;
|
||||
|
||||
for (auto const & a : attribs.attribs)
|
||||
{
|
||||
max_index = std::max<std::size_t>(max_index, a.index);
|
||||
|
||||
if (a.divisor == 0)
|
||||
{
|
||||
stride = a.stride;
|
||||
}
|
||||
else
|
||||
if (a.divisor != 0)
|
||||
{
|
||||
assert(a.divisor == 1);
|
||||
instance_stride = a.stride;
|
||||
instanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
info_.max_attribute_index_ = max_index;
|
||||
info_.stride_ = stride;
|
||||
info_.instance_stride_ = instance_stride;
|
||||
info_.stride_ = attribs.vertex_size;
|
||||
info_.instance_stride_ = attribs.instance_size;
|
||||
info_.instanced_ = instanced;
|
||||
|
||||
if (!vertex_buffer_) vertex_buffer_ = buffer{};
|
||||
|
|
@ -77,7 +70,7 @@ namespace psemek::gfx
|
|||
if (a.divisor != 0) continue;
|
||||
|
||||
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)
|
||||
|
|
@ -90,7 +83,7 @@ namespace psemek::gfx
|
|||
if (a.divisor == 0) continue;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue