From fca472721b3b0433ab540e0d69aca10f6caafd70 Mon Sep 17 00:00:00 2001 From: kearwood Date: Thu, 15 Mar 2012 20:44:57 +0000 Subject: [PATCH] Optimized further to reduce redundant GL state changes --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4011 --- KREngine/KREngine/Classes/KRMaterial.cpp | 54 +++++++++++++++--------- KREngine/KREngine/Classes/KRMesh.cpp | 35 +++++++++------ KREngine/KREngine/Classes/KRMesh.h | 2 +- KREngine/KREngine/Classes/KRModel.cpp | 6 ++- 4 files changed, 61 insertions(+), 36 deletions(-) diff --git a/KREngine/KREngine/Classes/KRMaterial.cpp b/KREngine/KREngine/Classes/KRMaterial.cpp index 6184b52..4495c03 100644 --- a/KREngine/KREngine/Classes/KRMaterial.cpp +++ b/KREngine/KREngine/Classes/KRMaterial.cpp @@ -119,30 +119,45 @@ void KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC strcpy(szPrevShaderKey, pShader->getKey()); } - glUniform3f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_AMBIENT], - m_ka_r + pCamera->dAmbientR, - m_ka_g + pCamera->dAmbientG, - m_ka_b + pCamera->dAmbientB - ); + bool bSameAmbient = false; + bool bSameDiffuse = false; + bool bSameSpecular = false; - glUniform3f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE], - m_kd_r * pCamera->dSunR, - m_kd_g * pCamera->dSunG, - m_kd_b * pCamera->dSunB - ); + if(*prevBoundMaterial && bSameShader) { + bSameAmbient = (*prevBoundMaterial)->m_ka_r == m_ka_r && (*prevBoundMaterial)->m_ka_g == m_ka_g && (*prevBoundMaterial)->m_ka_b == m_ka_b; + bSameDiffuse = (*prevBoundMaterial)->m_kd_r == m_kd_r && (*prevBoundMaterial)->m_kd_g == m_kd_g && (*prevBoundMaterial)->m_kd_b == m_kd_b; + bSameSpecular = (*prevBoundMaterial)->m_ks_r == m_ks_r && (*prevBoundMaterial)->m_ks_g == m_ks_g && (*prevBoundMaterial)->m_ks_b == m_ks_b; + } - glUniform3f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR], - m_ks_r * pCamera->dSunR, - m_ks_g * pCamera->dSunG, - m_ks_b * pCamera->dSunB - ); + if(!bSameAmbient) { + glUniform3f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_AMBIENT], + m_ka_r + pCamera->dAmbientR, + m_ka_g + pCamera->dAmbientG, + m_ka_b + pCamera->dAmbientB + ); + } + + if(!bSameDiffuse) { + glUniform3f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_DIFFUSE], + m_kd_r * pCamera->dSunR, + m_kd_g * pCamera->dSunG, + m_kd_b * pCamera->dSunB + ); + } + + if(!bSameSpecular) { + glUniform3f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_SPECULAR], + m_ks_r * pCamera->dSunR, + m_ks_g * pCamera->dSunG, + m_ks_b * pCamera->dSunB + ); + } glUniform1f(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA], 1.0f - m_tr); - bool bSameDiffuseMap = false; bool bSameSpecMap = false; bool bSameNormalMap = false; @@ -157,6 +172,7 @@ void KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC bSameNormalMap = true; } } + if(bDiffuseMap && !bSameDiffuseMap) { int iTextureName = m_pDiffuseMap->getName(); glActiveTexture(GL_TEXTURE0); diff --git a/KREngine/KREngine/Classes/KRMesh.cpp b/KREngine/KREngine/Classes/KRMesh.cpp index 2d7a761..0f23751 100644 --- a/KREngine/KREngine/Classes/KRMesh.cpp +++ b/KREngine/KREngine/Classes/KRMesh.cpp @@ -150,7 +150,7 @@ vector KRMesh::getSubmeshes() { return m_submeshes; } -void KRMesh::renderSubmesh(int iSubmesh) { +void KRMesh::renderSubmesh(int iSubmesh, int *iPrevBuffer) { Submesh *pSubmesh = m_submeshes[iSubmesh]; @@ -159,19 +159,27 @@ void KRMesh::renderSubmesh(int iSubmesh) { iVertex = iVertex % MAX_VBO_SIZE; int cVertexes = pSubmesh->vertex_count; while(cVertexes > 0) { - glBindBuffer(GL_ARRAY_BUFFER, m_pBuffers[iBuffer]); + if(*iPrevBuffer != iBuffer) { + glBindBuffer(GL_ARRAY_BUFFER, m_pBuffers[iBuffer]); - glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, sizeof(VertexData), BUFFER_OFFSET(0)); - glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX); - - glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, sizeof(VertexData), BUFFER_OFFSET(sizeof(Vertex3D))); - glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_NORMAL); - - glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, sizeof(VertexData), BUFFER_OFFSET(sizeof(Vertex3D) + sizeof(Vector3D))); - glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TANGENT); - - glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUV, 2, GL_FLOAT, 0, sizeof(VertexData), BUFFER_OFFSET(sizeof(Vertex3D) + sizeof(Vector3D) * 2)); - glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUV); + if(*iPrevBuffer == -1) { + glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX); + glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_NORMAL); + glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TANGENT); + glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUV); + } + + glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, sizeof(VertexData), BUFFER_OFFSET(0)); + + glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, sizeof(VertexData), BUFFER_OFFSET(sizeof(Vertex3D))); + + glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, sizeof(VertexData), BUFFER_OFFSET(sizeof(Vertex3D) + sizeof(Vector3D))); + + glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUV, 2, GL_FLOAT, 0, sizeof(VertexData), BUFFER_OFFSET(sizeof(Vertex3D) + sizeof(Vector3D) * 2)); + + + *iPrevBuffer = iBuffer; + } if(iVertex + cVertexes >= MAX_VBO_SIZE) { glDrawArrays(GL_TRIANGLES, iVertex, (MAX_VBO_SIZE - iVertex)); @@ -183,5 +191,4 @@ void KRMesh::renderSubmesh(int iSubmesh) { cVertexes = 0; } } - glBindBuffer(GL_ARRAY_BUFFER, 0); } diff --git a/KREngine/KREngine/Classes/KRMesh.h b/KREngine/KREngine/Classes/KRMesh.h index fbc0fa9..92f8a0a 100644 --- a/KREngine/KREngine/Classes/KRMesh.h +++ b/KREngine/KREngine/Classes/KRMesh.h @@ -53,7 +53,7 @@ public: ~KRMesh(); void loadPack(std::string path); - void renderSubmesh(int iSubmesh); + void renderSubmesh(int iSubmesh, int *iPrevBuffer); GLfloat getMaxDimension(); GLfloat getMinX(); diff --git a/KREngine/KREngine/Classes/KRModel.cpp b/KREngine/KREngine/Classes/KRModel.cpp index ace53fe..0f7041e 100644 --- a/KREngine/KREngine/Classes/KRModel.cpp +++ b/KREngine/KREngine/Classes/KRModel.cpp @@ -67,6 +67,7 @@ KRModel::~KRModel() { void KRModel::render(KRCamera *pCamera, KRMaterialManager *pMaterialManager, bool bRenderShadowMap, KRMat4 &mvpMatrix, Vector3 &cameraPosition, Vector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers) { KRMaterial *pPrevBoundMaterial = NULL; + int iPrevBuffer = -1; char szPrevShaderKey[128]; szPrevShaderKey[0] = '\0'; int cSubmeshes = m_mesh.getSubmeshes().size(); @@ -78,7 +79,7 @@ void KRModel::render(KRCamera *pCamera, KRMaterialManager *pMaterialManager, boo if(pMaterial->isTransparent()) { // Exclude transparent and semi-transparent meshes from shadow maps - m_mesh.renderSubmesh(iSubmesh); + m_mesh.renderSubmesh(iSubmesh, &iPrevBuffer); } } @@ -91,11 +92,12 @@ void KRModel::render(KRCamera *pCamera, KRMaterialManager *pMaterialManager, boo if(pMaterial != NULL && pMaterial == (*mat_itr)) { pMaterial->bind(&pPrevBoundMaterial, szPrevShaderKey, pCamera, mvpMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers); - m_mesh.renderSubmesh(iSubmesh); + m_mesh.renderSubmesh(iSubmesh, &iPrevBuffer); } } } } + glBindBuffer(GL_ARRAY_BUFFER, 0); } KRMesh *KRModel::getMesh() {