From 15ebea15339cd3993194838505e7c6bd98075be1 Mon Sep 17 00:00:00 2001 From: kearwood Date: Thu, 25 Oct 2012 18:28:30 +0000 Subject: [PATCH] Now using VAO's (OES_vertex_array_object extension) to improve performance of scenes with many materials and objects --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40140 --- KREngine/KREngine/Classes/KRCamera.cpp | 8 +- KREngine/KREngine/Classes/KRModelManager.cpp | 197 +++++++++---------- KREngine/KREngine/Classes/KRModelManager.h | 12 +- KREngine/KREngine/Classes/KRPointLight.cpp | 3 + 4 files changed, 102 insertions(+), 118 deletions(-) diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index f8a9dd9..a34599e 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -753,7 +753,9 @@ void KRCamera::renderPost() GLDEBUG(glBindTexture(GL_TEXTURE_2D, compositeDepthTexture)); // Update attribute values. - +#if GL_OES_vertex_array_object + GLDEBUG(glBindVertexArrayOES(0)); +#endif m_pContext->getModelManager()->configureAttribs(true, false, false, true, false); GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, 0, KRENGINE_VERTICES_2D_SQUARE_UV)); @@ -811,7 +813,9 @@ void KRCamera::renderPost() dTexScale * iCol + dTexScale, dTexScale * iRow + dTexScale, dTexScale * iCol + dTexScale, dTexScale * iRow }; - +#if GL_OES_vertex_array_object + GLDEBUG(glBindVertexArrayOES(0)); +#endif m_pContext->getModelManager()->configureAttribs(true, false, false, true, false); GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, 0, charTexCoords)); GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, charVertices)); diff --git a/KREngine/KREngine/Classes/KRModelManager.cpp b/KREngine/KREngine/Classes/KRModelManager.cpp index c2bcc58..d539896 100644 --- a/KREngine/KREngine/Classes/KRModelManager.cpp +++ b/KREngine/KREngine/Classes/KRModelManager.cpp @@ -35,14 +35,10 @@ #import "KRModel.h" KRModelManager::KRModelManager(KRContext &context) : KRContextObject(context) { - m_currentVBO.handle = 0; + m_currentVBO.vbo_handle = 0; + m_currentVBO.vao_handle = 0; m_currentVBO.data = NULL; m_vboMemUsed = 0; - m_bVBOAttribEnabled_Vertex = false; - m_bVBOAttribEnabled_Normal = false; - m_bVBOAttribEnabled_Tangent = false; - m_bVBOAttribEnabled_UVA = false; - m_bVBOAttribEnabled_UVB = false; } KRModelManager::~KRModelManager() { @@ -87,11 +83,6 @@ std::vector KRModelManager::getModel(const char *szName) { return matching_models; } -KRModel *KRModelManager::getFirstModel() { - static std::map::iterator model_itr = m_models.begin(); - return (*model_itr).second; -} - std::multimap KRModelManager::getModels() { return m_models; } @@ -101,7 +92,8 @@ void KRModelManager::unbindVBO() { GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, 0)); m_currentVBO.size = 0; m_currentVBO.data = NULL; - m_currentVBO.handle = -1; + m_currentVBO.vbo_handle = -1; + m_currentVBO.vao_handle = -1; } } @@ -111,12 +103,22 @@ void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex, if(m_vbosActive.find(data) != m_vbosActive.end()) { m_currentVBO = m_vbosActive[data]; - GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.handle)); +#if GL_OES_vertex_array_object + GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); +#else + GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); + configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb); +#endif } else if(m_vbosPool.find(data) != m_vbosPool.end()) { m_currentVBO = m_vbosPool[data]; m_vbosPool.erase(data); m_vbosActive[data] = m_currentVBO; - GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.handle)); +#if GL_OES_vertex_array_object + GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); +#else + GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); + configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb); +#endif } else { m_vboMemUsed += size; @@ -127,121 +129,104 @@ void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex, } std::map::iterator first_itr = m_vbosPool.begin(); vbo_info_type firstVBO = first_itr->second; - GLDEBUG(glDeleteBuffers(1, &firstVBO.handle)); +#if GL_OES_vertex_array_object + GLDEBUG(glDeleteVertexArraysOES(1, &firstVBO.vao_handle)); +#endif + GLDEBUG(glDeleteBuffers(1, &firstVBO.vbo_handle)); m_vboMemUsed -= firstVBO.size; m_vbosPool.erase(first_itr); fprintf(stderr, "VBO Swapping...\n"); } - m_currentVBO.handle = -1; - GLDEBUG(glGenBuffers(1, &m_currentVBO.handle)); - - GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.handle)); + m_currentVBO.vao_handle = -1; + m_currentVBO.vbo_handle = -1; + GLDEBUG(glGenBuffers(1, &m_currentVBO.vbo_handle)); +#if GL_OES_vertex_array_object + GLDEBUG(glGenVertexArraysOES(1, &m_currentVBO.vao_handle)); + GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle)); +#endif + + GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle)); GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); - //fprintf(stderr, "glBufferData(GL_ARRAY_BUFFER, %ld, data, GL_STATIC_DRAW)\n", size); + configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb); m_currentVBO.size = size; m_currentVBO.data = data; m_vbosActive[data] = m_currentVBO; } - - configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb); - } - -// fprintf(stderr, "VBO Mem: %i Kbyte Texture Mem: %i Kbyte\n", (int)m_pContext->getModelManager()->getMemUsed() / 1024, (int)m_pContext->getTextureManager()->getMemUsed() / 1024); } void KRModelManager::configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb) { - bool reconfigured = false; - - if(m_bVBOAttribEnabled_Vertex != enable_vertex) { - if(enable_vertex) { - GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX)); - } else { - GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX)); - } - m_bVBOAttribEnabled_Vertex = enable_vertex; - reconfigured = true; + if(enable_vertex) { + GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX)); + } else { + GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX)); } - if(m_bVBOAttribEnabled_Normal != enable_normal) { - if(enable_normal) { - GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_NORMAL)); - } else { - GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_NORMAL)); - } - m_bVBOAttribEnabled_Normal = enable_normal; - reconfigured = true; + + if(enable_normal) { + GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_NORMAL)); + } else { + GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_NORMAL)); } - if(m_bVBOAttribEnabled_Tangent != enable_tangent) { - if(enable_tangent) { - GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TANGENT)); - } else { - GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TANGENT)); - } - m_bVBOAttribEnabled_Tangent = enable_tangent; - reconfigured = true; + + if(enable_tangent) { + GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TANGENT)); + } else { + GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TANGENT)); } - if(m_bVBOAttribEnabled_UVA != enable_uva) { - if(enable_uva) { - GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVA)); - } else { - GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVA)); - } - m_bVBOAttribEnabled_UVA = enable_uva; - reconfigured = true; + + if(enable_uva) { + GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVA)); + } else { + GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVA)); } - if(m_bVBOAttribEnabled_UVB != enable_uvb) { - if(enable_uvb) { - GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVB)); - } else { - GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVB)); - } - m_bVBOAttribEnabled_UVB = enable_uvb; - reconfigured = true; + + if(enable_uvb) { + GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVB)); + } else { + GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVB)); + } + + int data_size = 0; + if(enable_vertex) { + data_size += sizeof(KRModel::KRVector3D); + } + if(enable_normal) { + data_size += sizeof(KRModel::KRVector3D); + } + if(enable_tangent) { + data_size += sizeof(KRModel::KRVector3D); + } + if(enable_uva) { + data_size += sizeof(KRModel::TexCoord); + } + if(enable_uvb) { + data_size += sizeof(KRModel::TexCoord); } - if(reconfigured || true) { - int data_size = 0; - if(enable_vertex) { - data_size += sizeof(KRModel::KRVector3D); - } - if(enable_normal) { - data_size += sizeof(KRModel::KRVector3D); - } - if(enable_tangent) { - data_size += sizeof(KRModel::KRVector3D); - } - if(enable_uva) { - data_size += sizeof(KRModel::TexCoord); - } - if(enable_uvb) { - data_size += sizeof(KRModel::TexCoord); - } - - int offset = 0; - if(enable_vertex) { - GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); - offset += sizeof(KRModel::KRVector3D); - } - if(enable_normal) { - GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); - offset += sizeof(KRModel::KRVector3D); - } - if(enable_tangent) { - GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); - offset += sizeof(KRModel::KRVector3D); - } - if(enable_uva) { - GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); - offset += sizeof(KRModel::TexCoord); - } - if(enable_uvb) { - GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); - offset += sizeof(KRModel::TexCoord); - } + int offset = 0; + if(enable_vertex) { + GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); + offset += sizeof(KRModel::KRVector3D); + } + if(enable_normal) { + GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); + offset += sizeof(KRModel::KRVector3D); + } + if(enable_tangent) { + GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); + offset += sizeof(KRModel::KRVector3D); + } + if(enable_uva) { + GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); + offset += sizeof(KRModel::TexCoord); + } + if(enable_uvb) { + GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset))); + offset += sizeof(KRModel::TexCoord); } } diff --git a/KREngine/KREngine/Classes/KRModelManager.h b/KREngine/KREngine/Classes/KRModelManager.h index dc0b894..a4c7ab4 100644 --- a/KREngine/KREngine/Classes/KRModelManager.h +++ b/KREngine/KREngine/Classes/KRModelManager.h @@ -52,7 +52,6 @@ public: KRModel *loadModel(const char *szName, KRDataBlock *pData); std::vector getModel(const char *szName); - KRModel *getFirstModel(); std::vector getModelNames(); std::multimap getModels(); @@ -68,7 +67,8 @@ private: std::multimap m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model typedef struct vbo_info { - GLuint handle; + GLuint vbo_handle; + GLuint vao_handle; GLsizeiptr size; GLvoid *data; } vbo_info_type; @@ -78,14 +78,6 @@ private: std::map m_vbosActive; std::map m_vbosPool; - - bool m_bVBOAttribEnabled_Vertex; - bool m_bVBOAttribEnabled_Normal; - bool m_bVBOAttribEnabled_Tangent; - bool m_bVBOAttribEnabled_UVA; - bool m_bVBOAttribEnabled_UVB; - - }; #endif diff --git a/KREngine/KREngine/Classes/KRPointLight.cpp b/KREngine/KREngine/Classes/KRPointLight.cpp index 9b183f6..3ca0499 100644 --- a/KREngine/KREngine/Classes/KRPointLight.cpp +++ b/KREngine/KREngine/Classes/KRPointLight.cpp @@ -114,6 +114,9 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &viewMa m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } else { +#if GL_OES_vertex_array_object + GLDEBUG(glBindVertexArrayOES(0)); +#endif m_pContext->getModelManager()->configureAttribs(true, false, false, false, false); // Render sphere of light's influence generateMesh();