Now that all relevant code is C++, the indirection from the C struct `GPUVertBuf` to the C++ `blender::gpu::VertBuf` class just adds complexity and necessitates a wrapper API, making more cleanups like use of RAII or other C++ types more difficult. This commit replaces the C wrapper structs with direct use of the vertex and index buffer base classes. In C++ we can choose which parts of a class are private, so we don't risk exposing too many implementation details here. Pull Request: https://projects.blender.org/blender/blender/pulls/119825
62 lines
1.8 KiB
C++
62 lines
1.8 KiB
C++
/* SPDX-FileCopyrightText: 2005 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#include "BLI_array_utils.hh"
|
|
|
|
#include "BKE_attribute_math.hh"
|
|
|
|
#include "GPU_vertex_buffer.hh"
|
|
|
|
#include "attribute_convert.hh"
|
|
|
|
namespace blender::draw {
|
|
|
|
GPUVertFormat init_format_for_attribute(const eCustomDataType data_type,
|
|
const StringRefNull vbo_name)
|
|
{
|
|
GPUVertFormat format{};
|
|
bke::attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
|
|
using T = decltype(dummy);
|
|
using Converter = AttributeConverter<T>;
|
|
if constexpr (!std::is_void_v<typename Converter::VBOType>) {
|
|
GPU_vertformat_attr_add(&format,
|
|
vbo_name.c_str(),
|
|
Converter::gpu_component_type,
|
|
Converter::gpu_component_len,
|
|
Converter::gpu_fetch_mode);
|
|
}
|
|
});
|
|
return format;
|
|
}
|
|
|
|
void vertbuf_data_extract_direct(const GSpan attribute, gpu::VertBuf &vbo)
|
|
{
|
|
bke::attribute_math::convert_to_static_type(attribute.type(), [&](auto dummy) {
|
|
using T = decltype(dummy);
|
|
using Converter = AttributeConverter<T>;
|
|
using VBOType = typename Converter::VBOType;
|
|
if constexpr (!std::is_void_v<VBOType>) {
|
|
const Span<T> src = attribute.typed<T>();
|
|
MutableSpan<VBOType> data(static_cast<VBOType *>(GPU_vertbuf_get_data(&vbo)),
|
|
attribute.size());
|
|
if constexpr (std::is_same_v<T, VBOType>) {
|
|
array_utils::copy(src, data);
|
|
}
|
|
else {
|
|
threading::parallel_for(src.index_range(), 8192, [&](const IndexRange range) {
|
|
for (const int i : range) {
|
|
data[i] = Converter::convert(src[i]);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
} // namespace blender::draw
|