From 05626214d4fc0dfe1e8308125c3addd468d5036d Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Sat, 9 Nov 2013 16:08:08 -0800 Subject: [PATCH] Asynchronous streaming and memory management improvements in progress. --HG-- branch : async_streaming --- KREngine/kraken/KRCamera.cpp | 94 ++++---- KREngine/kraken/KRCamera.h | 2 +- KREngine/kraken/KRDataBlock.cpp | 14 ++ KREngine/kraken/KRDataBlock.h | 1 + KREngine/kraken/KRDirectionalLight.cpp | 2 +- KREngine/kraken/KRLight.cpp | 8 +- KREngine/kraken/KRMesh.cpp | 194 ++++++++++------ KREngine/kraken/KRMesh.h | 30 ++- KREngine/kraken/KRMeshManager.cpp | 208 +++++++++++------- KREngine/kraken/KRMeshManager.h | 27 ++- KREngine/kraken/KRParticleSystemNewtonian.cpp | 4 +- KREngine/kraken/KRPointLight.cpp | 2 +- KREngine/kraken/KRRenderSettings.cpp | 2 +- KREngine/kraken/KRScene.cpp | 2 +- KREngine/kraken/KRStockGeometry.h | 31 +-- KREngine/kraken/KRTextureManager.cpp | 1 + 16 files changed, 379 insertions(+), 243 deletions(-) diff --git a/KREngine/kraken/KRCamera.cpp b/KREngine/kraken/KRCamera.cpp index fb67f83..b997093 100644 --- a/KREngine/kraken/KRCamera.cpp +++ b/KREngine/kraken/KRCamera.cpp @@ -54,14 +54,9 @@ KRCamera::KRCamera(KRScene &scene, std::string name) : KRNode(scene, name) { volumetricLightAccumulationBuffer = 0; volumetricLightAccumulationTexture = 0; m_frame_times_filled = 0; - - m_debug_text_vertices = NULL; } KRCamera::~KRCamera() { - if(m_debug_text_vertices) { - delete m_debug_text_vertices; - } destroyBuffers(); } @@ -315,7 +310,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } @@ -472,7 +467,7 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende KRShader *pVisShader = getContext().getShaderManager()->getShader("visualize_overlay", this, std::vector(), std::vector(), std::vector(), 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_ATTRIBS, true); for(unordered_map::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) { KRMat4 matModel = KRMat4(); matModel.scale((*itr).first.size() * 0.5f); @@ -704,7 +699,7 @@ void KRCamera::renderPost() } // Update attribute values. - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); @@ -726,7 +721,7 @@ void KRCamera::renderPost() // viewMatrix.translate(-0.70, 0.70 - 0.45 * iShadow, 0.0); // getContext().getShaderManager()->selectShader(blitShader, KRViewport(getViewportSize(), viewMatrix, KRMat4()), shadowViewports, KRMat4(), KRVector3(), NULL, 0, KRNode::RENDER_PASS_FORWARD_TRANSPARENT); // m_pContext->getTextureManager()->selectTexture(1, NULL); -// m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); +// m_pContext->getModelManager()->bindVBO(KRENGINE_VBO_2D_SQUARE_INDICES, KRENGINE_VBO_2D_SQUARE_VERTEXES, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); // m_pContext->getTextureManager()->_setActiveTexture(0); // GLDEBUG(glBindTexture(GL_TEXTURE_2D, shadowDepthTexture[iShadow])); //#if GL_EXT_shadow_samplers @@ -745,7 +740,7 @@ void KRCamera::renderPost() - if(m_debug_text_vertices) { + if(m_debug_text_vertices.getSize()) { m_pContext->getModelManager()->releaseVBO(m_debug_text_vertices); } @@ -791,12 +786,13 @@ void KRCamera::renderPost() const int DEBUG_TEXT_COLUMNS = 256; const int DEBUG_TEXT_ROWS = 128; - if(m_debug_text_vertices == NULL) { - m_debug_text_vertices = new DebugTextVertexData[DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6]; + if(m_debug_text_vertices.getSize() == 0) { + m_debug_text_vertices.expand(sizeof(DebugTextVertexData) * DEBUG_TEXT_COLUMNS * DEBUG_TEXT_ROWS * 6); } int vertex_count = 0; - + m_debug_text_vertices.lock(); + DebugTextVertexData *vertex_data = (DebugTextVertexData *)m_debug_text_vertices.getStart(); pChar = szText; float dScaleX = 2.0 / (1024 / 16); @@ -824,47 +820,47 @@ void KRCamera::renderPost() KRVector2 top_left_uv = KRVector2(dTexScale * iTexCol, dTexScale * iTexRow); KRVector2 bottom_right_uv = KRVector2(dTexScale * iTexCol + dTexScale, dTexScale * iTexRow + dTexScale); - m_debug_text_vertices[vertex_count].x = top_left_pos.x; - m_debug_text_vertices[vertex_count].y = top_left_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = top_left_uv.x; - m_debug_text_vertices[vertex_count].v = top_left_uv.y; + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; - m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; - m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = top_left_pos.x; - m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = top_left_uv.x; - m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = top_left_pos.x; - m_debug_text_vertices[vertex_count].y = top_left_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = top_left_uv.x; - m_debug_text_vertices[vertex_count].v = top_left_uv.y; + vertex_data[vertex_count].x = top_left_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = top_left_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; - m_debug_text_vertices[vertex_count].y = top_left_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; - m_debug_text_vertices[vertex_count].v = top_left_uv.y; + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = top_left_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = top_left_uv.y; vertex_count++; - m_debug_text_vertices[vertex_count].x = bottom_right_pos.x; - m_debug_text_vertices[vertex_count].y = bottom_right_pos.y; - m_debug_text_vertices[vertex_count].z = 0.0f; - m_debug_text_vertices[vertex_count].u = bottom_right_uv.x; - m_debug_text_vertices[vertex_count].v = bottom_right_uv.y; + vertex_data[vertex_count].x = bottom_right_pos.x; + vertex_data[vertex_count].y = bottom_right_pos.y; + vertex_data[vertex_count].z = 0.0f; + vertex_data[vertex_count].u = bottom_right_uv.x; + vertex_data[vertex_count].v = bottom_right_uv.y; vertex_count++; } @@ -892,18 +888,20 @@ void KRCamera::renderPost() m_pContext->getTextureManager()->selectTexture(0, m_pContext->getTextureManager()->getTexture("font")); - - m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); + KRDataBlock index_data; + //m_pContext->getModelManager()->bindVBO((void *)m_debug_text_vertices, vertex_count * sizeof(DebugTextVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); + m_pContext->getModelManager()->bindVBO(m_debug_text_vertices, index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, vertex_count)); // Re-enable z-buffer write GLDEBUG(glDepthMask(GL_TRUE)); + + m_debug_text_vertices.unlock(); } else { - if(m_debug_text_vertices) { - delete m_debug_text_vertices; - m_debug_text_vertices = NULL; + if(m_debug_text_vertices.getSize() > 0) { + m_debug_text_vertices = KRDataBlock(); } } } diff --git a/KREngine/kraken/KRCamera.h b/KREngine/kraken/KRCamera.h index 03d518a..560dd4e 100644 --- a/KREngine/kraken/KRCamera.h +++ b/KREngine/kraken/KRCamera.h @@ -99,7 +99,7 @@ private: GLfloat v; } DebugTextVertexData; - DebugTextVertexData *m_debug_text_vertices; + KRDataBlock m_debug_text_vertices; // std::string getDebugText(); diff --git a/KREngine/kraken/KRDataBlock.cpp b/KREngine/kraken/KRDataBlock.cpp index 33050ad..7331f70 100644 --- a/KREngine/kraken/KRDataBlock.cpp +++ b/KREngine/kraken/KRDataBlock.cpp @@ -52,6 +52,20 @@ KRDataBlock::KRDataBlock() { m_bReadOnly = false; } +KRDataBlock::KRDataBlock(void *data, size_t size) { + m_data = NULL; + m_data_size = 0; + m_data_offset = 0; + m_fdPackFile = 0; + m_fileName = ""; + m_mmapData = NULL; + m_fileOwnerDataBlock = NULL; + m_bMalloced = false; + m_lockCount = 0; + m_bReadOnly = false; + load(data, size); +} + KRDataBlock::~KRDataBlock() { unload(); } diff --git a/KREngine/kraken/KRDataBlock.h b/KREngine/kraken/KRDataBlock.h index 80aeb0c..5198375 100644 --- a/KREngine/kraken/KRDataBlock.h +++ b/KREngine/kraken/KRDataBlock.h @@ -37,6 +37,7 @@ class KRDataBlock { public: KRDataBlock(); + KRDataBlock(void *data, size_t size); ~KRDataBlock(); // Encapsulate a pointer. Note - The pointer will not be free'ed diff --git a/KREngine/kraken/KRDirectionalLight.cpp b/KREngine/kraken/KRDirectionalLight.cpp index 2335b95..db78f9c 100644 --- a/KREngine/kraken/KRDirectionalLight.cpp +++ b/KREngine/kraken/KRDirectionalLight.cpp @@ -119,7 +119,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector & GLDEBUG(glDisable(GL_DEPTH_TEST)); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KRLight.cpp b/KREngine/kraken/KRLight.cpp index c5337a6..d6162f5 100644 --- a/KREngine/kraken/KRLight.cpp +++ b/KREngine/kraken/KRLight.cpp @@ -226,7 +226,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_PARTICLE_ORIGIN, KRMat4::DotWDiv(KRMat4::Invert(particleModelMatrix), KRVector3::Zero())); pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_dust_particle_size); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRMeshManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); + KRDataBlock particle_index_data; + m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getRandomParticles(), particle_index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); } } @@ -266,7 +267,8 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE, KRVector2(slice_near, slice_spacing)); pFogShader->setUniform(KRShader::KRENGINE_UNIFORM_LIGHT_COLOR, (m_color * pCamera->settings.volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f)); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRMeshManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRMeshManager::VolumetricLightingVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true); + KRDataBlock index_data; + m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getVolumetricLightingVertexes(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX), true); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6)); } @@ -333,7 +335,7 @@ void KRLight::render(KRCamera *pCamera, std::vector &point_light if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, m_flareSize); m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture); - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } diff --git a/KREngine/kraken/KRMesh.cpp b/KREngine/kraken/KRMesh.cpp index a044244..5082a07 100644 --- a/KREngine/kraken/KRMesh.cpp +++ b/KREngine/kraken/KRMesh.cpp @@ -42,22 +42,23 @@ KRMesh::KRMesh(KRContext &context, std::string name) : KRResource(context, name) { - m_hasTransparency = false; - m_materials.clear(); - m_uniqueMaterials.clear(); - m_pData = new KRDataBlock(); - m_pData->lock(); setName(name); + + m_hasTransparency = false; + m_pData = NULL; + m_pMetaData = NULL; + m_pIndexBaseData = NULL; + } KRMesh::KRMesh(KRContext &context, std::string name, KRDataBlock *data) : KRResource(context, name) { - m_hasTransparency = false; - m_materials.clear(); - m_uniqueMaterials.clear(); - m_pData = new KRDataBlock(); - m_pData->lock(); setName(name); + m_hasTransparency = false; + m_pData = NULL; + m_pMetaData = NULL; + m_pIndexBaseData = NULL; + loadPack(data); } @@ -105,9 +106,24 @@ int KRMesh::GetLODCoverage(const std::string &name) KRMesh::~KRMesh() { - clearData(); - m_pData->unlock(); - if(m_pData) delete m_pData; + releaseData(); +} + +void KRMesh::releaseData() { + if(m_pIndexBaseData) { + m_pIndexBaseData->unlock(); + delete m_pIndexBaseData; + m_pIndexBaseData = NULL; + } + if(m_pMetaData) { + m_pMetaData->unlock(); + delete m_pMetaData; + m_pMetaData = NULL; + } + if(m_pData) { + delete m_pData; + m_pData = NULL; + } } std::string KRMesh::getExtension() { @@ -115,32 +131,36 @@ std::string KRMesh::getExtension() { } bool KRMesh::save(const std::string& path) { - clearBuffers(); return m_pData->save(path); } bool KRMesh::save(KRDataBlock &data) { - clearBuffers(); data.append(*m_pData); return true; } void KRMesh::loadPack(KRDataBlock *data) { - clearData(); - m_pData->unlock(); - delete m_pData; + releaseData(); + m_pData = data; - m_pData->lock(); + + pack_header ph; + m_pData->copy((void *)&ph, 0, sizeof(ph)); + m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count); + m_pMetaData->lock(); + + m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8); + m_pIndexBaseData->lock(); + + m_minPoint = KRVector3(ph.minx, ph.miny, ph.minz); + m_maxPoint = KRVector3(ph.maxx, ph.maxy, ph.maxz); + updateAttributeOffsets(); - pack_header *pHeader = getHeader(); - m_minPoint = KRVector3(pHeader->minx, pHeader->miny, pHeader->minz); - m_maxPoint = KRVector3(pHeader->maxx, pHeader->maxy, pHeader->maxz); } void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vector &point_lights, std::vector &directional_lights, std::vector&spot_lights, const KRViewport &viewport, const KRMat4 &matModel, KRTexture *pLightMap, KRNode::RenderPass renderPass, const std::vector &bones) { - m_pData->lock(); - + //fprintf(stderr, "Rendering model: %s\n", m_name.c_str()); if(renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_PARTICLE_OCCLUSION && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { getSubmeshes(); @@ -221,8 +241,6 @@ void KRMesh::render(const std::string &object_name, KRCamera *pCamera, std::vect } } } - - m_pData->unlock(); } GLfloat KRMesh::getMaxDimension() { @@ -259,21 +277,21 @@ void KRMesh::getSubmeshes() { } void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const std::string &object_name, const std::string &material_name) { + //m_pData->lock(); getSubmeshes(); Submesh *pSubmesh = m_submeshes[iSubmesh]; int cVertexes = pSubmesh->vertex_count; // fprintf(stderr, "start - object: %s material: %s vertices: %i\n", object_name.c_str(), material_name.c_str(), cVertexes); - unsigned char *pVertexData = getVertexData(); + int vertex_data_offset = getVertexDataOffset(); + int index_data_offset = getIndexDataOffset(); pack_header *pHeader = getHeader(); - + int32_t vertex_attrib_flags = pHeader->vertex_attrib_flags; + int32_t vertex_count = pHeader->vertex_count; + int vbo_index=0; if(getModelFormat() == KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES) { - - - - __uint16_t *index_data = getIndexData(); int index_group = getSubmesh(iSubmesh)->index_group; int index_group_offset = getSubmesh(iSubmesh)->index_group_offset; while(cVertexes > 0) { @@ -281,7 +299,22 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st int start_index_offset, start_vertex_offset, index_count, vertex_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); - m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, pHeader->vertex_attrib_flags, true); + KRDataBlock *vertex_data_block = NULL; + KRDataBlock *index_data_block = NULL; + if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { + vertex_data_block = m_pData->getSubBlock(vertex_data_offset + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size); + index_data_block = m_pData->getSubBlock(index_data_offset + start_index_offset * 2, index_count * 2); + m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); + m_submeshes[iSubmesh]->index_data_blocks.push_back(index_data_block); + } else { + vertex_data_block = m_submeshes[iSubmesh]->vertex_data_blocks[vbo_index]; + index_data_block = m_submeshes[iSubmesh]->index_data_blocks[vbo_index]; + } + vbo_index++; + + //m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + start_vertex_offset * m_vertex_size, vertex_count * m_vertex_size, index_data + start_index_offset, index_count * 2, vertex_attrib_flags, true); + m_pContext->getModelManager()->bindVBO(*vertex_data_block, *index_data_block, vertex_attrib_flags, true); + int vertex_draw_count = cVertexes; if(vertex_draw_count > index_count - index_group_offset) vertex_draw_count = index_count - index_group_offset; @@ -293,21 +326,27 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st } } else { - int cBuffers = (pHeader->vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; + int cBuffers = (vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE; int iVertex = pSubmesh->start_vertex; int iBuffer = iVertex / MAX_VBO_SIZE; iVertex = iVertex % MAX_VBO_SIZE; while(cVertexes > 0) { - GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE; + GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : vertex_count % MAX_VBO_SIZE; int vertex_size = m_vertex_size; - void *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size + vertex_size * cBufferVertexes; - void *buffer_end = m_pData->getEnd(); - assert(vbo_end <= buffer_end); - assert(cBufferVertexes <= 65535); + KRDataBlock *vertex_data_block = NULL; + KRDataBlock *index_data_block = NULL; + if(m_submeshes[iSubmesh]->vertex_data_blocks.size() <= vbo_index) { + vertex_data_block = m_pData->getSubBlock(vertex_data_offset + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes); + + m_submeshes[iSubmesh]->vertex_data_blocks.push_back(vertex_data_block); + } else { + vertex_data_block = m_submeshes[iSubmesh]->vertex_data_blocks[vbo_index]; + } + vbo_index++; - - m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, pHeader->vertex_attrib_flags, true); + //m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, NULL, 0, vertex_attrib_flags, true); + m_pContext->getModelManager()->bindVBO(*vertex_data_block, *index_data_block, vertex_attrib_flags, true); if(iVertex + cVertexes >= MAX_VBO_SIZE) { @@ -353,13 +392,12 @@ void KRMesh::renderSubmesh(int iSubmesh, KRNode::RenderPass renderPass, const st } } - // fprintf(stderr, "end object\n"); - + //m_pData->unlock(); } -void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vector > vertex_index_bases, std::vector vertices, std::vector uva, std::vector uvb, std::vector normals, std::vector tangents, std::vector submesh_starts, std::vector submesh_lengths, std::vector material_names, std::vector bone_names, std::vector bone_bind_poses, std::vector > bone_indexes, std::vector > bone_weights, model_format_t model_format, */const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) { +void KRMesh::LoadData(const KRMesh::mesh_info &mi, bool calculate_normals, bool calculate_tangents) { - clearData(); + clearBuffers(); // TODO, FINDME - These values should be passed as a parameter and set by GUI flags bool use_short_vertexes = false; @@ -438,10 +476,10 @@ void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vectorunlock(); + m_pData = new KRDataBlock(); + m_pMetaData = m_pData; m_pData->expand(new_file_size); m_pData->lock(); - pack_header *pHeader = getHeader(); memset(pHeader, 0, sizeof(pack_header)); pHeader->vertex_attrib_flags = vertex_attrib_flags; @@ -583,6 +621,18 @@ void KRMesh::LoadData(/*std::vector<__uint16_t> vertex_indexes, std::vectorunlock(); + + // ---- + + pack_header ph; + m_pData->copy((void *)&ph, 0, sizeof(ph)); + m_pMetaData = m_pData->getSubBlock(0, sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count); + m_pMetaData->lock(); + m_pIndexBaseData = m_pData->getSubBlock(sizeof(pack_header) + sizeof(pack_material) * ph.submesh_count + sizeof(pack_bone) * ph.bone_count + KRALIGN(2 * ph.index_count), ph.index_base_count * 8); + m_pIndexBaseData->lock(); + + // ---- optimize(); } @@ -595,12 +645,6 @@ KRVector3 KRMesh::getMaxPoint() const { return m_maxPoint; } -void KRMesh::clearData() { - m_pData->unlock(); - m_pData->unload(); - m_pData->lock(); -} - void KRMesh::clearBuffers() { m_submeshes.clear(); } @@ -632,34 +676,47 @@ bool KRMesh::has_vertex_attribute(int vertex_attrib_flags, vertex_attrib_t attri KRMesh::pack_header *KRMesh::getHeader() const { - return (pack_header *)m_pData->getStart(); + return (pack_header *)m_pMetaData->getStart(); } KRMesh::pack_bone *KRMesh::getBone(int index) { pack_header *header = getHeader(); - return (pack_bone *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index); + return (pack_bone *)((unsigned char *)m_pMetaData->getStart() + sizeof(pack_header) + sizeof(pack_material) * header->submesh_count + sizeof(pack_bone) * index); } unsigned char *KRMesh::getVertexData() const { + return ((unsigned char *)m_pData->getStart()) + getVertexDataOffset(); +} + +size_t KRMesh::getVertexDataOffset() const { pack_header *pHeader = getHeader(); - return ((unsigned char *)m_pData->getStart()) + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count) + KRALIGN(8 * pHeader->index_base_count); + return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count) + KRALIGN(8 * pHeader->index_base_count); } __uint16_t *KRMesh::getIndexData() const { + + return (__uint16_t *)((unsigned char *)m_pData->getStart() + getIndexDataOffset()); +} + +size_t KRMesh::getIndexDataOffset() const { pack_header *pHeader = getHeader(); - return (__uint16_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count); + return sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count; } __uint32_t *KRMesh::getIndexBaseData() const { - pack_header *pHeader = getHeader(); - return (__uint32_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count)); + if(m_pIndexBaseData == NULL) { + pack_header *pHeader = getHeader(); + return (__uint32_t *)((unsigned char *)m_pData->getStart() + sizeof(pack_header) + sizeof(pack_material) * pHeader->submesh_count + sizeof(pack_bone) * pHeader->bone_count + KRALIGN(2 * pHeader->index_count)); + } else { + return (__uint32_t *)m_pIndexBaseData->getStart(); + } } KRMesh::pack_material *KRMesh::getSubmesh(int mesh_index) const { - return (pack_material *)((unsigned char *)m_pData->getStart() + sizeof(pack_header)) + mesh_index; + return (pack_material *)((unsigned char *)m_pMetaData->getStart() + sizeof(pack_header)) + mesh_index; } unsigned char *KRMesh::getVertexData(int index) const @@ -670,7 +727,8 @@ unsigned char *KRMesh::getVertexData(int index) const int KRMesh::getSubmeshCount() const { pack_header *header = getHeader(); - return header->submesh_count; + int submesh_count = header->submesh_count; + return submesh_count; } int KRMesh::getVertexCount(int submesh) const @@ -904,10 +962,8 @@ size_t KRMesh::AttributeOffset(__int32_t vertex_attrib, __int32_t vertex_attrib_ int KRMesh::getBoneCount() { - m_pData->lock(); pack_header *header = getHeader(); int bone_count = header->bone_count; - m_pData->unlock(); return bone_count; } @@ -923,9 +979,7 @@ KRMat4 KRMesh::getBoneBindPose(int bone_index) KRMesh::model_format_t KRMesh::getModelFormat() const { - m_pData->lock(); model_format_t f = (model_format_t)getHeader()->model_format; - m_pData->unlock(); return f; } @@ -1018,6 +1072,7 @@ bool KRMesh::rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_ind bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitinfo) const { + m_pData->lock(); bool hit_found = false; for(int submesh_index=0; submesh_index < getSubmeshCount(); submesh_index++) { // int vertex_start = getSubmesh(submesh_index)->start_vertex; @@ -1054,20 +1109,24 @@ bool KRMesh::rayCast(const KRVector3 &v0, const KRVector3 &dir, KRHitInfo &hitin break; } } + m_pData->unlock(); return hit_found; } bool KRMesh::lineCast(const KRVector3 &v0, const KRVector3 &v1, KRHitInfo &hitinfo) const { + m_pData->lock(); KRHitInfo new_hitinfo; KRVector3 dir = KRVector3::Normalize(v1 - v0); if(rayCast(v0, dir, new_hitinfo)) { if((new_hitinfo.getPosition() - v0).sqrMagnitude() <= (v1 - v0).sqrMagnitude()) { // The hit was between v1 and v2 hitinfo = new_hitinfo; + m_pData->unlock(); return true; } } + m_pData->unlock(); return false; // Either no hit, or the hit was beyond v1 } @@ -1284,6 +1343,9 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const switch(getModelFormat()) { case KRENGINE_MODEL_FORMAT_INDEXED_TRIANGLES: { + __uint16_t *index_data = getIndexData(); + + int start_index_offset, start_vertex_offset, index_count, vertex_count; int index_group = getSubmesh(submesh)->index_group; int index_group_offset = getSubmesh(submesh)->index_group_offset; @@ -1293,7 +1355,7 @@ int KRMesh::getTriangleVertexIndex(int submesh, int index) const remaining_vertices -= index_count; getIndexedRange(index_group++, start_index_offset, start_vertex_offset, index_count, vertex_count); } - return getIndexData()[start_index_offset + remaining_vertices] + start_vertex_offset; + return index_data[start_index_offset + remaining_vertices] + start_vertex_offset; } break; default: diff --git a/KREngine/kraken/KRMesh.h b/KREngine/kraken/KRMesh.h index abc03d7..602a5a6 100644 --- a/KREngine/kraken/KRMesh.h +++ b/KREngine/kraken/KRMesh.h @@ -133,11 +133,24 @@ public: - typedef struct { + class Submesh { + public: + Submesh() {}; + ~Submesh() { + for(std::vector::iterator itr = vertex_data_blocks.begin(); itr != vertex_data_blocks.end(); itr++) { + delete (*itr); + } + for(std::vector::iterator itr = index_data_blocks.begin(); itr != index_data_blocks.end(); itr++) { + delete (*itr); + } + }; + GLint start_vertex; GLsizei vertex_count; char szMaterialName[KRENGINE_MAX_NAME_LENGTH]; - } Submesh; + vector vertex_data_blocks; + vector index_data_blocks; + }; typedef struct { union { @@ -198,6 +211,10 @@ public: static int GetLODCoverage(const std::string &name); private: + KRDataBlock *m_pData; + KRDataBlock *m_pMetaData; + KRDataBlock *m_pIndexBaseData; + void getSubmeshes(); // bool rayCast(const KRVector3 &line_v0, const KRVector3 &dir, int tri_index0, int tri_index1, int tri_index2, KRHitInfo &hitinfo) const; @@ -212,8 +229,7 @@ private: KRVector3 m_minPoint, m_maxPoint; - KRDataBlock *m_pData; - + typedef struct { @@ -235,7 +251,6 @@ private: void updateAttributeOffsets(); - void clearData(); void clearBuffers(); void setName(const std::string name); @@ -244,14 +259,19 @@ private: pack_material *getSubmesh(int mesh_index) const; unsigned char *getVertexData() const; + size_t getVertexDataOffset() const; unsigned char *getVertexData(int index) const; __uint16_t *getIndexData() const; + size_t getIndexDataOffset() const; __uint32_t *getIndexBaseData() const; pack_header *getHeader() const; pack_bone *getBone(int index); void getIndexedRange(int index_group, int &start_index_offset, int &start_vertex_offset, int &index_count, int &vertex_count) const; + + void releaseData(); + }; diff --git a/KREngine/kraken/KRMeshManager.cpp b/KREngine/kraken/KRMeshManager.cpp index 9905f3b..d4905d0 100644 --- a/KREngine/kraken/KRMeshManager.cpp +++ b/KREngine/kraken/KRMeshManager.cpp @@ -43,8 +43,6 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_s m_currentVBO.vao_handle = -1; m_currentVBO.data = NULL; m_vboMemUsed = 0; - m_randomParticleVertexData = NULL; - m_volumetricLightingVertexData = NULL; m_memoryTransferredThisFrame = 0; // addModel(new KRMeshCube(context)); // FINDME - HACK! This needs to be fixed, as it currently segfaults @@ -52,6 +50,45 @@ KRMeshManager::KRMeshManager(KRContext &context) : KRContextObject(context), m_s addModel(new KRMeshSphere(context)); m_draw_call_logging_enabled = false; m_draw_call_log_used = false; + + + + // ---- Initialize stock models ---- + + static const GLfloat _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = { + 1.0, 1.0, 1.0, + -1.0, 1.0, 1.0, + 1.0,-1.0, 1.0, + -1.0,-1.0, 1.0, + -1.0,-1.0,-1.0, + -1.0, 1.0, 1.0, + -1.0, 1.0,-1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0,-1.0, + 1.0,-1.0, 1.0, + 1.0,-1.0,-1.0, + -1.0,-1.0,-1.0, + 1.0, 1.0,-1.0, + -1.0, 1.0,-1.0 + }; + + KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); + KRENGINE_VBO_3D_CUBE_VERTICES.expand(sizeof(GLfloat) * 3 * 14); + KRENGINE_VBO_3D_CUBE_VERTICES.lock(); + memcpy(KRENGINE_VBO_3D_CUBE_VERTICES.getStart(), _KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(GLfloat) * 3 * 14); + KRENGINE_VBO_3D_CUBE_VERTICES.unlock(); + + static const GLfloat _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = { + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f + }; + KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); + KRENGINE_VBO_2D_SQUARE_VERTICES.expand(sizeof(GLfloat) * 5 * 4); + KRENGINE_VBO_2D_SQUARE_VERTICES.lock(); + memcpy(KRENGINE_VBO_2D_SQUARE_VERTICES.getStart(), _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(GLfloat) * 5 * 4); + KRENGINE_VBO_2D_SQUARE_VERTICES.unlock(); } KRMeshManager::~KRMeshManager() { @@ -59,8 +96,6 @@ KRMeshManager::~KRMeshManager() { delete (*itr).second; } m_models.empty(); - if(m_randomParticleVertexData != NULL) delete m_randomParticleVertexData; - if(m_volumetricLightingVertexData != NULL) delete m_volumetricLightingVertexData; } KRMesh *KRMeshManager::loadModel(const char *szName, KRDataBlock *pData) { @@ -115,24 +150,24 @@ void KRMeshManager::unbindVBO() { } } -void KRMeshManager::releaseVBO(GLvoid *data) +void KRMeshManager::releaseVBO(KRDataBlock &data) { - if(m_currentVBO.data == data) { + if(m_currentVBO.data == &data) { unbindVBO(); } vbo_info_type vbo_to_release; - if(m_vbosActive.find(data) != m_vbosActive.end()) { + if(m_vbosActive.find(&data) != m_vbosActive.end()) { fprintf(stderr, "glFinish called due to releasing a VBO that is active in the current frame.\n"); GLDEBUG(glFinish()); // The VBO is active - vbo_to_release = m_vbosActive[data]; - m_vbosActive.erase(data); + vbo_to_release = m_vbosActive[&data]; + m_vbosActive.erase(&data); } else { // The VBO is inactive - vbo_to_release = m_vbosPool[data]; - m_vbosPool.erase(data); + vbo_to_release = m_vbosPool[&data]; + m_vbosPool.erase(&data); } m_vboMemUsed -= vbo_to_release.size; @@ -146,12 +181,12 @@ void KRMeshManager::releaseVBO(GLvoid *data) } } -void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo) { +void KRMeshManager::bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo) { - if(m_currentVBO.data != data || m_currentVBO.size != size + index_data_size) { + if(m_currentVBO.data != &data) { - if(m_vbosActive.find(data) != m_vbosActive.end()) { - m_currentVBO = m_vbosActive[data]; + if(m_vbosActive.find(&data) != m_vbosActive.end()) { + m_currentVBO = m_vbosActive[&data]; #if GL_OES_vertex_array_object GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); #else @@ -163,10 +198,10 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); } #endif - } else if(m_vbosPool.find(data) != m_vbosPool.end()) { - m_currentVBO = m_vbosPool[data]; - m_vbosPool.erase(data); - m_vbosActive[data] = m_currentVBO; + } else if(m_vbosPool.find(&data) != m_vbosPool.end()) { + m_currentVBO = m_vbosPool[&data]; + m_vbosPool.erase(&data); + m_vbosActive[&data] = m_currentVBO; #if GL_OES_vertex_array_object GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); #else @@ -181,12 +216,12 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G } else { - while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + size + index_data_size >= KRContext::KRENGINE_MAX_VBO_MEM) { + while(m_vbosPool.size() + m_vbosActive.size() + 1 >= KRContext::KRENGINE_MAX_VBO_HANDLES || m_vboMemUsed + data.getSize() + index_data.getSize() >= KRContext::KRENGINE_MAX_VBO_MEM) { if(m_vbosPool.empty()) { fprintf(stderr, "flushBuffers due to VBO exhaustion...\n"); m_pContext->rotateBuffers(false); } - unordered_map::iterator first_itr = m_vbosPool.begin(); + unordered_map::iterator first_itr = m_vbosPool.begin(); vbo_info_type firstVBO = first_itr->second; #if GL_OES_vertex_array_object GLDEBUG(glDeleteVertexArraysOES(1, &firstVBO.vao_handle)); @@ -204,7 +239,7 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G m_currentVBO.vbo_handle = -1; m_currentVBO.vbo_handle_indexes = -1; GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle)); - if(index_data != NULL) { + if(index_data.getSize() > 0) { GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle_indexes)); } @@ -216,41 +251,47 @@ void KRMeshManager::bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, G GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); #if GL_OES_mapbuffer - GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + GLDEBUG(glBufferData(GL_ARRAY_BUFFER, data.getSize(), NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); GLDEBUG(void *map_ptr = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); - memcpy(map_ptr, data, size); + data.copy(map_ptr); + //memcpy(map_ptr, data, size); GLDEBUG(glUnmapBufferOES(GL_ARRAY_BUFFER)); #else - GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + data.lock(); + GLDEBUG(glBufferData(GL_ARRAY_BUFFER, data.getSize(), data.getStart(), static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + data.unlock(); #endif - m_memoryTransferredThisFrame += size; - m_vboMemUsed += size; + m_memoryTransferredThisFrame += data.getSize(); + m_vboMemUsed += data.getSize(); configureAttribs(vertex_attrib_flags); - m_currentVBO.size = size; - m_currentVBO.data = data; + m_currentVBO.size = data.getSize(); + m_currentVBO.data = &data; - if(index_data == NULL) { + if(index_data.getSize() == 0) { GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); } else { GLDEBUG(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currentVBO.vbo_handle_indexes)); #if GL_OES_mapbuffer - GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data_size, NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.getSize(), NULL, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); GLDEBUG(void *map_ptr = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES)); - memcpy(map_ptr, index_data, index_data_size); + index_data.copy(map_ptr); + //memcpy(map_ptr, index_data, index_data.getSize()); GLDEBUG(glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER)); #else - GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data_size, index_data, static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + index_data.lock(); + GLDEBUG(glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.getSize(), index_data.getStart(), static_vbo ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW)); + index_data.unlock(); #endif - m_memoryTransferredThisFrame += index_data_size; - m_vboMemUsed += index_data_size; - m_currentVBO.size += index_data_size; + m_memoryTransferredThisFrame += index_data.getSize(); + m_vboMemUsed += index_data.getSize(); + m_currentVBO.size += index_data.getSize(); } - m_vbosActive[data] = m_currentVBO; + m_vbosActive[&data] = m_currentVBO; } } } @@ -332,7 +373,7 @@ long KRMeshManager::getMemUsed() long KRMeshManager::getMemActive() { long mem_active = 0; - for(unordered_map::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { + for(unordered_map::iterator itr = m_vbosActive.begin(); itr != m_vbosActive.end(); itr++) { mem_active += (*itr).second.size; } return mem_active; @@ -350,56 +391,56 @@ void KRMeshManager::rotateBuffers(bool new_frame) } -KRMeshManager::VolumetricLightingVertexData *KRMeshManager::getVolumetricLightingVertexes() +KRDataBlock &KRMeshManager::getVolumetricLightingVertexes() { - if(m_volumetricLightingVertexData == NULL) { - m_volumetricLightingVertexData = (VolumetricLightingVertexData *)malloc(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6); + if(m_volumetricLightingVertexData.getSize() == 0) { + m_volumetricLightingVertexData.expand(sizeof(VolumetricLightingVertexData) * KRENGINE_MAX_VOLUMETRIC_PLANES * 6); + m_volumetricLightingVertexData.lock(); + VolumetricLightingVertexData * vertex_data = (VolumetricLightingVertexData *)m_volumetricLightingVertexData.getStart(); int iVertex=0; for(int iPlane=0; iPlane < KRENGINE_MAX_VOLUMETRIC_PLANES; iPlane++) { - m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = -1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = -1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = -1.0f; + vertex_data[iVertex].vertex.z = iPlane; iVertex++; + vertex_data[iVertex].vertex.x = 1.0f; + vertex_data[iVertex].vertex.y = 1.0f; + vertex_data[iVertex].vertex.z = iPlane; + iVertex++; - m_volumetricLightingVertexData[iVertex].vertex.x = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.y = 1.0f; - m_volumetricLightingVertexData[iVertex].vertex.z = iPlane; - iVertex++; - -// -1.0f, -1.0f, -// 1.0f, -1.0f, -// -1.0f, 1.0f, -// 1.0f, 1.0f, } + m_volumetricLightingVertexData.unlock(); } return m_volumetricLightingVertexData; } -KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles() +KRDataBlock &KRMeshManager::getRandomParticles() { - if(m_randomParticleVertexData == NULL) { - m_randomParticleVertexData = (RandomParticleVertexData *)malloc(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3); + if(m_randomParticleVertexData.getSize() == 0) { + m_randomParticleVertexData.expand(sizeof(RandomParticleVertexData) * KRENGINE_MAX_RANDOM_PARTICLES * 3); + m_randomParticleVertexData.lock(); + RandomParticleVertexData *vertex_data = (RandomParticleVertexData *)m_randomParticleVertexData.getStart(); // Generate vertices for randomly placed equilateral triangles with a side length of 1 and an origin point centered so that an inscribed circle can be efficiently rendered without wasting fill @@ -408,27 +449,28 @@ KRMeshManager::RandomParticleVertexData *KRMeshManager::getRandomParticles() int iVertex=0; for(int iParticle=0; iParticle < KRENGINE_MAX_RANDOM_PARTICLES; iParticle++) { - m_randomParticleVertexData[iVertex].vertex.x = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; - m_randomParticleVertexData[iVertex].vertex.y = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; - m_randomParticleVertexData[iVertex].vertex.z = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; - m_randomParticleVertexData[iVertex].uva.u = -0.5f; - m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius; + vertex_data[iVertex].vertex.x = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].vertex.y = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].vertex.z = (float)(arc4random() % 2000) / 1000.0f - 1000.0f; + vertex_data[iVertex].uva.u = -0.5f; + vertex_data[iVertex].uva.v = -inscribed_circle_radius; iVertex++; - m_randomParticleVertexData[iVertex].vertex.x = m_randomParticleVertexData[iVertex-1].vertex.x; - m_randomParticleVertexData[iVertex].vertex.y = m_randomParticleVertexData[iVertex-1].vertex.y; - m_randomParticleVertexData[iVertex].vertex.z = m_randomParticleVertexData[iVertex-1].vertex.z; - m_randomParticleVertexData[iVertex].uva.u = 0.5f; - m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius; + vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x; + vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y; + vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z; + vertex_data[iVertex].uva.u = 0.5f; + vertex_data[iVertex].uva.v = -inscribed_circle_radius; iVertex++; - m_randomParticleVertexData[iVertex].vertex.x = m_randomParticleVertexData[iVertex-1].vertex.x; - m_randomParticleVertexData[iVertex].vertex.y = m_randomParticleVertexData[iVertex-1].vertex.y; - m_randomParticleVertexData[iVertex].vertex.z = m_randomParticleVertexData[iVertex-1].vertex.z; - m_randomParticleVertexData[iVertex].uva.u = 0.0f; - m_randomParticleVertexData[iVertex].uva.v = -inscribed_circle_radius + equilateral_triangle_height; + vertex_data[iVertex].vertex.x = vertex_data[iVertex-1].vertex.x; + vertex_data[iVertex].vertex.y = vertex_data[iVertex-1].vertex.y; + vertex_data[iVertex].vertex.z = vertex_data[iVertex-1].vertex.z; + vertex_data[iVertex].uva.u = 0.0f; + vertex_data[iVertex].uva.v = -inscribed_circle_radius + equilateral_triangle_height; iVertex++; } + m_randomParticleVertexData.unlock(); } return m_randomParticleVertexData; } diff --git a/KREngine/kraken/KRMeshManager.h b/KREngine/kraken/KRMeshManager.h index f1782b4..2783617 100644 --- a/KREngine/kraken/KRMeshManager.h +++ b/KREngine/kraken/KRMeshManager.h @@ -61,8 +61,8 @@ public: std::vector getModelNames(); unordered_multimap &getModels(); - void bindVBO(GLvoid *data, GLsizeiptr size, GLvoid *index_data, GLsizeiptr index_data_size, int vertex_attrib_flags, bool static_vbo); - void releaseVBO(GLvoid *data); + void bindVBO(KRDataBlock &data, KRDataBlock &index_data, int vertex_attrib_flags, bool static_vbo); + void releaseVBO(KRDataBlock &data); void unbindVBO(); long getMemUsed(); long getMemActive(); @@ -90,10 +90,8 @@ public: } VolumetricLightingVertexData; - - - RandomParticleVertexData *getRandomParticles(); - VolumetricLightingVertexData *getVolumetricLightingVertexes(); + KRDataBlock &getRandomParticles(); + KRDataBlock &getVolumetricLightingVertexes(); long getMemoryTransferedThisFrame(); @@ -111,6 +109,13 @@ public: void log_draw_call(KRNode::RenderPass pass, const std::string &object_name, const std::string &material_name, int vertex_count); std::vector getDrawCalls(); + + KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES, KRENGINE_VBO_3D_CUBE_INDEXES; + __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS; + + KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES, KRENGINE_VBO_2D_SQUARE_INDEXES; + __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS; + private: unordered_multimap m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model @@ -119,17 +124,17 @@ private: GLuint vbo_handle_indexes; GLuint vao_handle; GLsizeiptr size; - GLvoid *data; + KRDataBlock *data; } vbo_info_type; long m_vboMemUsed; vbo_info_type m_currentVBO; - unordered_map m_vbosActive; - unordered_map m_vbosPool; + unordered_map m_vbosActive; + unordered_map m_vbosPool; - RandomParticleVertexData *m_randomParticleVertexData; - VolumetricLightingVertexData *m_volumetricLightingVertexData; + KRDataBlock m_randomParticleVertexData; + KRDataBlock m_volumetricLightingVertexData; long m_memoryTransferredThisFrame; diff --git a/KREngine/kraken/KRParticleSystemNewtonian.cpp b/KREngine/kraken/KRParticleSystemNewtonian.cpp index 81324cd..f6bbdb5 100644 --- a/KREngine/kraken/KRParticleSystemNewtonian.cpp +++ b/KREngine/kraken/KRParticleSystemNewtonian.cpp @@ -77,7 +77,9 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vectorselectShader(*pCamera, pParticleShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass)) { pParticleShader->setUniform(KRShader::KRENGINE_UNIFORM_FLARE_SIZE, 1.0f); - m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); + //m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRMeshManager::RandomParticleVertexData), NULL, 0, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); + KRDataBlock index_data; + m_pContext->getModelManager()->bindVBO(m_pContext->getModelManager()->getRandomParticles(), index_data, (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA), false); GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3)); } } diff --git a/KREngine/kraken/KRPointLight.cpp b/KREngine/kraken/KRPointLight.cpp index d18ddcb..db5a3d2 100644 --- a/KREngine/kraken/KRPointLight.cpp +++ b/KREngine/kraken/KRPointLight.cpp @@ -96,7 +96,7 @@ void KRPointLight::render(KRCamera *pCamera, std::vector &point_ GLDEBUG(glDisable(GL_DEPTH_TEST)); // Render a full screen quad - m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, NULL, 0, KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); + m_pContext->getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_2D_SQUARE_ATTRIBS, true); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } else { #if GL_OES_vertex_array_object diff --git a/KREngine/kraken/KRRenderSettings.cpp b/KREngine/kraken/KRRenderSettings.cpp index 6c9efe8..7a31679 100644 --- a/KREngine/kraken/KRRenderSettings.cpp +++ b/KREngine/kraken/KRRenderSettings.cpp @@ -15,7 +15,7 @@ KRRenderSettings::KRRenderSettings() siren_enable_hrtf = true; siren_reverb_max_length = 2.0f; - m_enable_realtime_occlusion = true; + m_enable_realtime_occlusion = false; bShowShadowBuffer = false; bShowOctree = false; bShowDeferred = false; diff --git a/KREngine/kraken/KRScene.cpp b/KREngine/kraken/KRScene.cpp index 87c2f66..4f04ad2 100644 --- a/KREngine/kraken/KRScene.cpp +++ b/KREngine/kraken/KRScene.cpp @@ -272,7 +272,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, unordered_map &visi KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix(); - getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, NULL, 0, KRENGINE_VBO_3D_CUBE_ATTRIBS, true); + getContext().getModelManager()->bindVBO(getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_VERTICES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_INDEXES, getContext().getModelManager()->KRENGINE_VBO_3D_CUBE_ATTRIBS, true); // Enable additive blending if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) { diff --git a/KREngine/kraken/KRStockGeometry.h b/KREngine/kraken/KRStockGeometry.h index 4dc7e18..37297c2 100644 --- a/KREngine/kraken/KRStockGeometry.h +++ b/KREngine/kraken/KRStockGeometry.h @@ -10,8 +10,9 @@ #define KRSTOCKGEOMETRY_H #include "KRMesh.h" - -static const GLfloat KRENGINE_VBO_3D_CUBE[] = { +#include "KRDataBlock.h" +/* +static const GLfloat _KRENGINE_VBO_3D_CUBE_VERTEX_DATA[] = { 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0,-1.0, 1.0, @@ -28,32 +29,20 @@ static const GLfloat KRENGINE_VBO_3D_CUBE[] = { -1.0, 1.0,-1.0 }; -static int KRENGINE_VBO_3D_CUBE_SIZE = sizeof(GLfloat) * 3 * 14; +static KRDataBlock KRENGINE_VBO_3D_CUBE_VERTICES, KRENGINE_VBO_3D_CUBE_INDEXES; +KRENGINE_VBO_3D_CUBE_VERTICES.load((void *)_KRENGINE_VBO_3D_CUBE_VERTEX_DATA, sizeof(GLfloat) * 3 * 14); + static const __int32_t KRENGINE_VBO_3D_CUBE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX); -static const GLfloat KRENGINE_VERTICES_2D_SQUARE[] = { - -1.0f, -1.0f, - 1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, 1.0f, -}; - -static const GLfloat KRENGINE_VERTICES_2D_SQUARE_UV[] = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, -}; - -static const GLfloat KRENGINE_VBO_2D_SQUARE[] = { +static const GLfloat _KRENGINE_VBO_2D_SQUARE_VERTEX_DATA[] = { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }; -static const int KRENGINE_VBO_2D_SQUARE_SIZE = sizeof(GLfloat) * 5 * 4; +static KRDataBlock KRENGINE_VBO_2D_SQUARE_VERTICES, KRENGINE_VBO_2D_SQUARE_INDEXES; +KRENGINE_VBO_2D_SQUARE_VERTICES.load((void *)_KRENGINE_VBO_2D_SQUARE_VERTEX_DATA, sizeof(GLfloat) * 5 * 4); static const __int32_t KRENGINE_VBO_2D_SQUARE_ATTRIBS = (1 << KRMesh::KRENGINE_ATTRIB_VERTEX) | (1 << KRMesh::KRENGINE_ATTRIB_TEXUVA); - - +*/ #endif diff --git a/KREngine/kraken/KRTextureManager.cpp b/KREngine/kraken/KRTextureManager.cpp index e258841..605e48e 100644 --- a/KREngine/kraken/KRTextureManager.cpp +++ b/KREngine/kraken/KRTextureManager.cpp @@ -236,6 +236,7 @@ void KRTextureManager::endFrame(float deltaTime) void KRTextureManager::balanceTextureMemory() { + return; // Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures // Favour performance over maximum texture resolution when memory is insufficient for textures at full resolution.