// если m_has_own_data == false то шарим все буффера из мапы m_buffers_cache // если m_has_own_data == true то храним два своих уникальных буфера, остальные шарим Buffers m_buffers;
Так ведь поместить его в общую мапу как weak значение не могу, первые 2 буфера личные.
typedef QVector<QVector3D> TVerArray; typedef QVector<int> TIndArray;struct Buffers{ QSharedPointer<QOpenGLBuffer> m_vertex_buffer; QSharedPointer<QOpenGLBuffer> m_color_buffer; // итд};enum class BufferTypes { VertexBuffer = 0x1; ColorBuffer = 0x2, AllBufers = 0xff};struct CRenderObject {...// данные рисования, могут шариться любым кол-вом CRenderObject QSharedPointer<CGeometry> m_geometry; // уровень деталировки, 0 = исходная геометрия int m_detailLevel; // Если к объекту применены нелинейные преобразования// то его "личные" вертексы и нормали должны использоваться// (вместо тех же данных в m_geomretry) bool m_has_own_data; TVerArray m_vertex, m_normal; QSharedPointer<Buffers> m_buffers; QSharedPointer<Buffers> buffers() // можно и ссылку { if (!m_buffers) { if (!m_has_own_data) { // вместо булки можно заюзаьт пару Optional<TVerArray> для массивов вершин и нормалей (ходят они парой или нет, яхз) // берем шаредную копию m_buffers = m_geometry->buffers(m_detailLevel, BufferTypes::AllBuffers); } else { // берем шаредную копию и модифицируем её своими буферами // qMakeShared в Qt нет // оптимизация - передаем флаги нужных буферов чтобы не создавать лишнего (можно не передавать, тогда будут лишние операции) auto copy = qMakeShared<Buffers>(*m_geometry->buffers(m_detailLevel, BufferTypes::AllBuffers & BufferTypes::~VertexBuffer)); copy->m_vertex_buffer = createVertexBuffer(m_vertex); m_buffers = copy; } } return m_buffers; } void setVerArray(TVerArray array) { m_buffers.reset(); // сбросили кешированное значение m_has_own_data = true; m_vertex = array; }};struct CGeometry { TVerArray m_vertex, m_normal, m_color, m_uv0, m_uv1; TIndArray m_indices, m_ver_per_face; QMap<int /*level*/, QWeakPointer<Buffers>> m_buffers_cache; QSharedPointer buffers(int level, BufferTypes types) { auto result = m_buffers_cache[level].lock(); if (!result) { result = qMakeShared<Buffers>(); m_buffers_cache[level] = result; // записали в кэш } // заполнили недостающие буфера if (types & BufferTypes::VertexBuffer) result->m_vertex_buffer = createVertexBuffer(m_vertex); ... return result; } void setVertex(TVerArray vertex) { m_vertex = vertex; for (auto item : m_buffers_cache) { if (item.second.m_vertex_buffer) updateVertexBuffer(m_vertex, item.second.m_vertex_buffer); // обновляет буфер, не пересоздавая объект. Нужно чтобы те, кто хранит копии, обновили буфера } }};
typedef QVector<QVector3D> TVerArray; typedef QVector<int> TIndArray;struct Buffers{ QSharedPointer<QOpenGLBuffer> m_vertex_buffer; QSharedPointer<QOpenGLBuffer> m_color_buffer; // итд};enum class BufferTypes { VertexBuffer = 0x1; ColorBuffer = 0x2, AllBufers = 0xff};struct CRenderObject {...// данные рисования, могут шариться любым кол-вом CRenderObject QSharedPointer<CGeometry> m_geometry; // уровень деталировки, 0 = исходная геометрия int m_detailLevel; // Если к объекту применены нелинейные преобразования// то его "личные" вертексы и нормали должны использоваться// (вместо тех же данных в m_geomretry) bool m_has_own_data; TVerArray m_vertex, m_normal; QSharedPointer<Buffers> m_buffers; QSharedPointer<Buffers> buffers() // можно и ссылку { if (!m_buffers) { if (!m_has_own_data) { // вместо булки можно заюзаьт пару Optional<TVerArray> для массивов вершин и нормалей (ходят они парой или нет, яхз) // берем шаредную копию m_buffers = m_geometry->buffers(m_detailLevel, BufferTypes::AllBuffers); } else { // берем шаредную копию и модифицируем её своими буферами // qMakeShared в Qt нет // оптимизация - передаем флаги нужных буферов чтобы не создавать лишнего (можно не передавать, тогда будут лишние операции) auto copy = qMakeShared<Buffers>(*m_geometry->buffers(m_detailLevel, BufferTypes::AllBuffers & BufferTypes::~VertexBuffer)); copy->m_vertex_buffer = createVertexBuffer(m_vertex); m_buffers = copy; } } return m_buffers; }