diff --git a/source/gs-vertexbuffer.cpp b/source/gs-vertexbuffer.cpp index 560713d9..0dfe7cfe 100644 --- a/source/gs-vertexbuffer.cpp +++ b/source/gs-vertexbuffer.cpp @@ -69,7 +69,7 @@ GS::VertexBuffer::VertexBuffer(gs_vertbuffer_t* vb) { GS::VertexBuffer::VertexBuffer() : VertexBuffer(defaultMaximumVertices) {} -GS::VertexBuffer::VertexBuffer(std::vector& other) : VertexBuffer((uint32_t)other.capacity()) { +GS::VertexBuffer::VertexBuffer(std::vector& other) : VertexBuffer((uint32_t)other.capacity()) { std::copy(other.begin(), other.end(), this->end()); } @@ -101,8 +101,19 @@ gs_vertbuffer_t* GS::VertexBuffer::get(bool refreshGPU) { if (size() > m_maximumVertices) throw std::runtime_error("Too many vertices in Vertex Buffer."); + // Update data pointer from Graphics Subsystem. m_vertexbufferdata = gs_vertexbuffer_get_data(m_vertexbuffer); std::memset(m_vertexbufferdata, 0, sizeof(gs_vb_data)); + + // Resize buffers. + m_data.positions.resize(m_maximumVertices); + m_data.normals.resize(m_maximumVertices); + m_data.tangents.resize(m_maximumVertices); + m_data.colors.resize(m_maximumVertices); + m_data.uvws.resize(m_uvwLayers); + m_data.uvwdata.resize(m_uvwLayers); + + // Assign new data. m_vertexbufferdata->num = m_maximumVertices; m_vertexbufferdata->points = m_data.positions.data(); m_vertexbufferdata->normals = m_data.normals.data(); @@ -110,12 +121,15 @@ gs_vertbuffer_t* GS::VertexBuffer::get(bool refreshGPU) { m_vertexbufferdata->colors = m_data.colors.data(); m_vertexbufferdata->num_tex = m_uvwLayers; for (uint32_t n = 0; n < m_uvwLayers; n++) { + m_data.uvws[n].resize(m_maximumVertices); m_data.uvwdata[n].width = 4; m_data.uvwdata[n].array = m_data.uvws[n].data(); } m_vertexbufferdata->tvarray = m_data.uvwdata.data(); + + // Copy Data for (size_t vertexIdx = 0; vertexIdx < size(); vertexIdx++) { - Vertex& v = this->at(vertexIdx); + GS::Vertex& v = this->at(vertexIdx); vec3_copy(&m_data.positions[vertexIdx], &(v.position)); vec3_copy(&m_data.normals[vertexIdx], &(v.normal)); vec3_copy(&m_data.tangents[vertexIdx], &(v.tangent)); @@ -124,18 +138,20 @@ gs_vertbuffer_t* GS::VertexBuffer::get(bool refreshGPU) { } m_data.colors[vertexIdx] = v.color; } - m_vertexbufferdata->num = size(); - m_vertexbufferdata->num_tex = m_uvwLayers; + // Update GPU obs_enter_graphics(); gs_vertexbuffer_flush(m_vertexbuffer); + obs_leave_graphics(); + + // WORKAROUND: OBS Studio 20.x and below incorrectly deletes data that it doesn't own. std::memset(m_vertexbufferdata, 0, sizeof(gs_vb_data)); m_vertexbufferdata->num = m_maximumVertices; m_vertexbufferdata->num_tex = m_uvwLayers; for (uint32_t n = 0; n < m_uvwLayers; n++) { m_data.uvwdata[n].width = 4; } - obs_leave_graphics(); + } return m_vertexbuffer; } diff --git a/source/gs-vertexbuffer.h b/source/gs-vertexbuffer.h index f1ad7476..140c581b 100644 --- a/source/gs-vertexbuffer.h +++ b/source/gs-vertexbuffer.h @@ -19,6 +19,8 @@ #pragma once #include "gs-vertex.h" +#include "util-math.h" +#include "util-memory.h" #include #include extern "C" { @@ -29,7 +31,7 @@ extern "C" { } namespace GS { - class VertexBuffer : public std::vector { + class VertexBuffer : public std::vector> { public: /*! * \brief Create a Vertex Buffer with specific size @@ -59,7 +61,7 @@ namespace GS { * * \param other The Vertex array to use */ - VertexBuffer(std::vector& other); + VertexBuffer(std::vector& other); VertexBuffer(gs_vertbuffer_t* vb); @@ -82,11 +84,11 @@ namespace GS { // Data Storage struct { - std::vector positions; - std::vector normals; - std::vector tangents; + std::vector positions; + std::vector normals; + std::vector tangents; std::vector colors; - std::vector> uvws; + std::vector> uvws; std::vector uvwdata; } m_data; };