gs-vertexbuffer: Fix and improve various problematic locations

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2019-10-13 06:20:58 +02:00
parent 45d2431ef5
commit 0ef94aad0f
2 changed files with 46 additions and 39 deletions

View File

@ -32,6 +32,35 @@
#pragma warning(pop) #pragma warning(pop)
#endif #endif
void gs::vertex_buffer::initialize(size_t capacity, size_t layers)
{
if (capacity > MAXIMUM_VERTICES) {
throw std::out_of_range("capacity too large");
}
if (layers > MAXIMUM_UVW_LAYERS) {
throw std::out_of_range("too many layers");
}
// Allocate memory for data.
_data = gs_vbdata_create();
_data->num = _capacity;
_data->num_tex = _layers;
_data->points = _positions = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->normals = _normals = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->tangents = _tangents = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->colors = _colors = (uint32_t*)util::malloc_aligned(16, sizeof(uint32_t) * _capacity);
if (_layers > 0) {
_data->tvarray = _layer_data = (gs_tvertarray*)util::malloc_aligned(16, sizeof(gs_tvertarray) * _layers);
for (size_t n = 0; n < _layers; n++) {
_layer_data[n].array = _uvs[n] = (vec4*)util::malloc_aligned(16, sizeof(vec4) * _capacity);
_layer_data[n].width = 4;
memset(_uvs[n], 0, sizeof(vec4) * _capacity);
}
} else {
_data->tvarray = nullptr;
}
}
gs::vertex_buffer::~vertex_buffer() gs::vertex_buffer::~vertex_buffer()
{ {
if (_positions) { if (_positions) {
@ -82,6 +111,8 @@ gs::vertex_buffer::vertex_buffer(uint32_t vertices, uint8_t uvlayers)
: _size(vertices), _capacity(vertices), _layers(uvlayers), _positions(nullptr), _normals(nullptr), : _size(vertices), _capacity(vertices), _layers(uvlayers), _positions(nullptr), _normals(nullptr),
_tangents(nullptr), _colors(nullptr), _data(nullptr), _buffer(nullptr), _layer_data(nullptr) _tangents(nullptr), _colors(nullptr), _data(nullptr), _buffer(nullptr), _layer_data(nullptr)
{ {
initialize(vertices, uvlayers);
if (vertices > MAXIMUM_VERTICES) { if (vertices > MAXIMUM_VERTICES) {
throw std::out_of_range("vertices out of range"); throw std::out_of_range("vertices out of range");
} }
@ -89,34 +120,6 @@ gs::vertex_buffer::vertex_buffer(uint32_t vertices, uint8_t uvlayers)
throw std::out_of_range("uvlayers out of range"); throw std::out_of_range("uvlayers out of range");
} }
// Allocate memory for data.
_data = gs_vbdata_create();
_data->num = _capacity;
_data->points = _positions = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->normals = _normals = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->tangents = _tangents = (vec3*)util::malloc_aligned(16, sizeof(vec3) * _capacity);
_data->colors = _colors = (uint32_t*)util::malloc_aligned(16, sizeof(uint32_t) * _capacity);
// cppcheck-suppress memsetClassFloat
memset(_positions, 0, sizeof(vec3) * _capacity);
// cppcheck-suppress memsetClassFloat
memset(_normals, 0, sizeof(vec3) * _capacity);
// cppcheck-suppress memsetClassFloat
memset(_tangents, 0, sizeof(vec3) * _capacity);
memset(_colors, 0, sizeof(uint32_t) * _capacity);
_data->num_tex = _layers;
if (_layers > 0) {
_data->tvarray = _layer_data = (gs_tvertarray*)util::malloc_aligned(16, sizeof(gs_tvertarray) * _layers);
for (size_t n = 0; n < _layers; n++) {
_layer_data[n].array = _uvs[n] = (vec4*)util::malloc_aligned(16, sizeof(vec4) * _capacity);
_layer_data[n].width = 4;
memset(_uvs[n], 0, sizeof(vec4) * _capacity);
}
} else {
_data->tvarray = nullptr;
}
// Allocate GPU // Allocate GPU
auto gctx = gs::context(); auto gctx = gs::context();
_buffer = gs_vertexbuffer_create(_data, GS_DYNAMIC); _buffer = gs_vertexbuffer_create(_data, GS_DYNAMIC);
@ -130,29 +133,30 @@ gs::vertex_buffer::vertex_buffer(uint32_t vertices, uint8_t uvlayers)
// cppcheck-suppress uninitMemberVar // cppcheck-suppress uninitMemberVar
gs::vertex_buffer::vertex_buffer(gs_vertbuffer_t* vb) gs::vertex_buffer::vertex_buffer(gs_vertbuffer_t* vb)
: _size(0), _capacity(0), _layers(0), _positions(nullptr), _normals(nullptr), _tangents(nullptr), _colors(nullptr),
_uvs(), _data(nullptr), _buffer(nullptr), _layer_data(nullptr)
{ {
auto gctx = gs::context(); auto gctx = gs::context();
gs_vb_data* vbd = gs_vertexbuffer_get_data(vb); gs_vb_data* vbd = gs_vertexbuffer_get_data(vb);
if (!vbd) if (!vbd)
throw std::runtime_error("vertex buffer with no data"); throw std::runtime_error("vertex buffer with no data");
vertex_buffer((uint32_t)vbd->num); initialize(vbd->num, vbd->num_tex);
this->set_uv_layers((uint32_t)vbd->num_tex);
if (vbd->points != nullptr) if (_positions && vbd->points)
memcpy(_positions, vbd->points, vbd->num * sizeof(vec3)); memcpy(_positions, vbd->points, vbd->num * sizeof(vec3));
if (vbd->normals != nullptr) if (_normals && vbd->normals)
memcpy(_normals, vbd->normals, vbd->num * sizeof(vec3)); memcpy(_normals, vbd->normals, vbd->num * sizeof(vec3));
if (vbd->tangents != nullptr) if (_tangents && vbd->tangents)
memcpy(_tangents, vbd->tangents, vbd->num * sizeof(vec3)); memcpy(_tangents, vbd->tangents, vbd->num * sizeof(vec3));
if (vbd->colors != nullptr) if (_colors && vbd->colors)
memcpy(_colors, vbd->colors, vbd->num * sizeof(uint32_t)); memcpy(_colors, vbd->colors, vbd->num * sizeof(uint32_t));
if (vbd->tvarray != nullptr) { if (vbd->tvarray != nullptr) {
for (size_t n = 0; n < vbd->num_tex; n++) { for (size_t n = 0; n < vbd->num_tex; n++) {
if (vbd->tvarray[n].array != nullptr && vbd->tvarray[n].width <= 4 && vbd->tvarray[n].width > 0) { if (vbd->tvarray[n].array != nullptr && vbd->tvarray[n].width <= 4 && vbd->tvarray[n].width > 0) {
if (vbd->tvarray[n].width == 4) { if (vbd->tvarray[n].width == 4) {
memcpy(_uvs[n], vbd->tvarray[n].array, vbd->num * sizeof(vec4)); memcpy(_uvs[n], vbd->tvarray[n].array, vbd->num * sizeof(vec4));
} else { } else if (vbd->tvarray[n].width < 4) {
for (size_t idx = 0; idx < _capacity; idx++) { for (size_t idx = 0; idx < _capacity; idx++) {
float* mem = reinterpret_cast<float*>(vbd->tvarray[n].array) + (idx * vbd->tvarray[n].width); float* mem = reinterpret_cast<float*>(vbd->tvarray[n].array) + (idx * vbd->tvarray[n].width);
// cppcheck-suppress memsetClassFloat // cppcheck-suppress memsetClassFloat
@ -178,7 +182,7 @@ gs::vertex_buffer::vertex_buffer(vertex_buffer const& other) : vertex_buffer(oth
} }
} }
gs::vertex_buffer::vertex_buffer(vertex_buffer const&& other) gs::vertex_buffer::vertex_buffer(vertex_buffer const&& other) noexcept : _uvs()
{ {
// Move Constructor // Move Constructor
_capacity = other._capacity; _capacity = other._capacity;
@ -187,6 +191,7 @@ gs::vertex_buffer::vertex_buffer(vertex_buffer const&& other)
_positions = other._positions; _positions = other._positions;
_normals = other._normals; _normals = other._normals;
_tangents = other._tangents; _tangents = other._tangents;
_colors = other._colors;
for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) { for (size_t n = 0; n < MAXIMUM_UVW_LAYERS; n++) {
_uvs[n] = other._uvs[n]; _uvs[n] = other._uvs[n];
} }
@ -195,7 +200,7 @@ gs::vertex_buffer::vertex_buffer(vertex_buffer const&& other)
_layer_data = other._layer_data; _layer_data = other._layer_data;
} }
void gs::vertex_buffer::operator=(vertex_buffer const&& other) void gs::vertex_buffer::operator=(vertex_buffer const&& other) noexcept
{ {
// Move Assignment // Move Assignment
/// First self-destruct (semi-destruct itself). /// First self-destruct (semi-destruct itself).

View File

@ -52,6 +52,8 @@ namespace gs {
gs_vertbuffer_t* _buffer; gs_vertbuffer_t* _buffer;
gs_tvertarray* _layer_data; gs_tvertarray* _layer_data;
void initialize(size_t capacity, size_t layers);
public: public:
virtual ~vertex_buffer(); virtual ~vertex_buffer();
@ -109,7 +111,7 @@ namespace gs {
* *
* \param other * \param other
*/ */
vertex_buffer(vertex_buffer const&& other); vertex_buffer(vertex_buffer const&& other) noexcept;
/*! /*!
* \brief Move Assignment * \brief Move Assignment
@ -117,7 +119,7 @@ namespace gs {
* *
* \param other * \param other
*/ */
void operator=(vertex_buffer const&& other); void operator=(vertex_buffer const&& other) noexcept;
void resize(uint32_t new_size); void resize(uint32_t new_size);