diff --git a/kraken/KREngine-common.h b/kraken/KREngine-common.h index a736191..6a79d78 100755 --- a/kraken/KREngine-common.h +++ b/kraken/KREngine-common.h @@ -98,6 +98,8 @@ using std::string; using std::set; using std::list; using std::map; +using std::unique_ptr; +using std::shared_ptr; using std::multimap; diff --git a/kraken/KRMesh.cpp b/kraken/KRMesh.cpp index 15aa840..ab1a2e9 100755 --- a/kraken/KRMesh.cpp +++ b/kraken/KRMesh.cpp @@ -212,10 +212,9 @@ void KRMesh::preStream(float lodCoverage) (*mat_itr)->preStream(lodCoverage); } - int cSubmeshes = (int)m_submeshes.size(); - for (int iSubmesh = 0; iSubmesh < cSubmeshes; iSubmesh++) { - for (auto vbo_data_itr = m_submeshes[iSubmesh].vbo_data_blocks.begin(); vbo_data_itr != m_submeshes[iSubmesh].vbo_data_blocks.end(); vbo_data_itr++) { - (*vbo_data_itr)->resetPoolExpiry(lodCoverage); + for (Submesh& mesh : m_submeshes) { + for (shared_ptr& vbo : mesh.vbo_data_blocks) { + vbo->resetPoolExpiry(lodCoverage); } } } @@ -231,10 +230,9 @@ kraken_stream_level KRMesh::getStreamLevel() } bool all_vbo_data_loaded = true; bool vbo_data_loaded = false; - int cSubmeshes = (int)m_submeshes.size(); - for (int iSubmesh = 0; iSubmesh < cSubmeshes; iSubmesh++) { - for (auto vbo_data_itr = m_submeshes[iSubmesh].vbo_data_blocks.begin(); vbo_data_itr != m_submeshes[iSubmesh].vbo_data_blocks.end(); vbo_data_itr++) { - if ((*vbo_data_itr)->isVBOReady()) { + for (const Submesh& mesh : m_submeshes) { + for (const shared_ptr& vbo_data : mesh.vbo_data_blocks) { + if (vbo_data->isVBOReady()) { vbo_data_loaded = true; } else { all_vbo_data_loaded = false; @@ -381,15 +379,13 @@ void KRMesh::createDataBlocks(KRMeshManager::KRVBOData::vbo_type t) if ((int)mesh.vertex_data_blocks.size() <= vbo_index) { KRDataBlock* vertex_data_block = m_pData->getSubBlock(vertex_data_offset + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size); KRDataBlock* index_data_block = m_pData->getSubBlock(index_data_offset + start_index_offset * 2, index_count * 2); - KRMeshManager::KRVBOData* vbo_data_block = new KRMeshManager::KRVBOData(getContext().getMeshManager(), vertex_data_block, index_data_block, vertex_attrib_flags, true, t + mesh.vbo_data_blocks.emplace_back(std::make_shared(getContext().getMeshManager(), vertex_data_block, index_data_block, vertex_attrib_flags, true, t #if KRENGINE_DEBUG_GPU_LABELS , m_lodBaseName.c_str() #endif - - ); + )); mesh.vertex_data_blocks.push_back(vertex_data_block); mesh.index_data_blocks.push_back(index_data_block); - mesh.vbo_data_blocks.push_back(vbo_data_block); } vbo_index++; @@ -412,13 +408,12 @@ void KRMesh::createDataBlocks(KRMeshManager::KRVBOData::vbo_type t) if ((int)mesh.vertex_data_blocks.size() <= vbo_index) { KRDataBlock* index_data_block = NULL; KRDataBlock* vertex_data_block = m_pData->getSubBlock(vertex_data_offset + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes); - KRMeshManager::KRVBOData* vbo_data_block = new KRMeshManager::KRVBOData(getContext().getMeshManager(), vertex_data_block, index_data_block, vertex_attrib_flags, true, t + mesh.vbo_data_blocks.emplace_back(std::make_shared(getContext().getMeshManager(), vertex_data_block, index_data_block, vertex_attrib_flags, true, t #if KRENGINE_DEBUG_GPU_LABELS , m_lodBaseName.c_str() #endif - ); - mesh.vertex_data_blocks.push_back(vertex_data_block); - mesh.vbo_data_blocks.push_back(vbo_data_block); + )); + mesh.vertex_data_blocks.emplace_back(vertex_data_block); } vbo_index++; @@ -451,7 +446,7 @@ bool KRMesh::isReady() const { // TODO - This should be cached... for (const Submesh& mesh : m_submeshes) { - for (const KRMeshManager::KRVBOData* vbo_data_block : mesh.vbo_data_blocks) { + for (const shared_ptr& vbo_data_block : mesh.vbo_data_blocks) { if (!vbo_data_block->isVBOReady()) { return false; } @@ -467,6 +462,7 @@ void KRMesh::renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, KRNode: Submesh& mesh = m_submeshes[iSubmesh]; int cVertexes = mesh.vertex_count; + vector>::iterator vbo_itr = mesh.vbo_data_blocks.begin(); int vbo_index = 0; if (getModelFormat() == ModelFormat::KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { @@ -477,11 +473,10 @@ void KRMesh::renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, KRNode: int start_index_offset, start_vertex_offset, index_count, vertex_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - KRMeshManager::KRVBOData* vbo_data_block = mesh.vbo_data_blocks[vbo_index++]; - assert(vbo_data_block->isVBOReady()); - - m_pContext->getMeshManager()->bindVBO(commandBuffer, vbo_data_block, lodCoverage); + KRMeshManager::KRVBOData& vbo_data_block = **(vbo_itr++); + assert(vbo_data_block.isVBOReady()); + m_pContext->getMeshManager()->bindVBO(commandBuffer, &vbo_data_block, lodCoverage); int vertex_draw_count = cVertexes; if (vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; @@ -500,9 +495,9 @@ void KRMesh::renderSubmesh(VkCommandBuffer& commandBuffer, int iSubmesh, KRNode: while (cVertexes > 0) { GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : cVertexes % MAX_VBO_SIZE; - KRMeshManager::KRVBOData* vbo_data_block = mesh.vbo_data_blocks[vbo_index++]; - assert(vbo_data_block->isVBOReady()); - m_pContext->getMeshManager()->bindVBO(commandBuffer, vbo_data_block, lodCoverage); + KRMeshManager::KRVBOData& vbo_data_block = **vbo_itr++; + assert(vbo_data_block.isVBOReady()); + m_pContext->getMeshManager()->bindVBO(commandBuffer, &vbo_data_block, lodCoverage); if (iVertex + cVertexes >= MAX_VBO_SIZE) { diff --git a/kraken/KRMesh.h b/kraken/KRMesh.h index 27956ad..af0ef2a 100755 --- a/kraken/KRMesh.h +++ b/kraken/KRMesh.h @@ -148,9 +148,7 @@ public: {}; ~Submesh() { - for (auto itr = vbo_data_blocks.begin(); itr != vbo_data_blocks.end(); itr++) { - delete (*itr); - } + vbo_data_blocks.clear(); for (auto itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) { delete (*itr); } @@ -159,12 +157,15 @@ public: } }; - GLint start_vertex; - GLsizei vertex_count; + int start_vertex; + int vertex_count; char szMaterialName[KRENGINE_MAX_NAME_LENGTH]; vector vertex_data_blocks; vector index_data_blocks; - vector vbo_data_blocks; + // KRMeshManager depends on the address of KRVBOData's being constant + // after allocation, enforced by deleted copy constructors. + // As std::vector requires copy constuctors, we wrap these in shared_ptr. + vector> vbo_data_blocks; }; typedef struct diff --git a/kraken/KRMeshManager.h b/kraken/KRMeshManager.h index f488ddd..c0afe3c 100755 --- a/kraken/KRMeshManager.h +++ b/kraken/KRMeshManager.h @@ -113,7 +113,8 @@ public: void unload(); void bind(VkCommandBuffer& commandBuffer); - // Disable copy constructors + // KRMeshManager depends on the address of KRVBOData's being constant + // after allocation. This is enforced by deleted copy constructors. KRVBOData(const KRVBOData& o) = delete; KRVBOData& operator=(const KRVBOData& o) = delete;