From accf6f91ea1c29da86e2657d01ebcd358eb635e9 Mon Sep 17 00:00:00 2001 From: yangxiao Date: Wed, 25 Jun 2014 17:36:55 +0800 Subject: [PATCH] render optimization --- cocos/renderer/CCGLProgramState.cpp | 5 ++- cocos/renderer/CCGLProgramState.h | 6 ++- cocos/renderer/CCMeshCommand.cpp | 22 +++++++---- cocos/renderer/CCRenderer.cpp | 3 +- cocos/renderer/ccShader_3D_PositionTex.vert | 41 ++++++++++++++------- 5 files changed, 51 insertions(+), 26 deletions(-) diff --git a/cocos/renderer/CCGLProgramState.cpp b/cocos/renderer/CCGLProgramState.cpp index 00e3b34180..bcda666f60 100644 --- a/cocos/renderer/CCGLProgramState.cpp +++ b/cocos/renderer/CCGLProgramState.cpp @@ -358,13 +358,14 @@ void GLProgramState::applyGLProgram(const Mat4& modelView) _glprogram->use(); _glprogram->setUniformsForBuiltins(modelView); } -void GLProgramState::applyAttributes() +void GLProgramState::applyAttributes(bool applyAttribFlags) { // Don't set attributes if they weren't set // Use Case: Auto-batching if(_vertexAttribsFlags) { // enable/disable vertex attribs - GL::enableVertexAttribs(_vertexAttribsFlags); + if (applyAttribFlags) + GL::enableVertexAttribs(_vertexAttribsFlags); // set attributes for(auto &attribute : _attributes) { diff --git a/cocos/renderer/CCGLProgramState.h b/cocos/renderer/CCGLProgramState.h index 9c5c6adab4..b627fb672c 100644 --- a/cocos/renderer/CCGLProgramState.h +++ b/cocos/renderer/CCGLProgramState.h @@ -161,7 +161,11 @@ public: void apply(const Mat4& modelView); void applyGLProgram(const Mat4& modelView); - void applyAttributes(); + /** + * apply vertex attributes + * @param applyAttribFlags Call GL::enableVertexAttribs(_vertexAttribsFlags) or not + */ + void applyAttributes(bool applyAttribFlags = true); void applyUniforms(); void setGLProgram(GLProgram* glprogram); diff --git a/cocos/renderer/CCMeshCommand.cpp b/cocos/renderer/CCMeshCommand.cpp index bacea1db76..b73d3a6637 100644 --- a/cocos/renderer/CCMeshCommand.cpp +++ b/cocos/renderer/CCMeshCommand.cpp @@ -85,7 +85,6 @@ void MeshCommand::init(float globalOrder, _indexBuffer = indexBuffer; _primitive = primitive; _indexFormat = indexFormat; - //_vao = vao; _indexCount = indexCount; _mv = mv; } @@ -169,8 +168,6 @@ void MeshCommand::genMaterialID(GLuint texID, void* glProgramState, void* mesh, } int intArray[] = {(int)texID, statekey[0], statekey[1], meshkey[0], meshkey[1], (int)blend.src, (int)blend.dst}; _materialID = XXH32((const void*)intArray, sizeof(intArray), 0); - - //generate vao here } void MeshCommand::MatrixPalleteCallBack( GLProgram* glProgram, Uniform* uniform) @@ -185,12 +182,13 @@ void MeshCommand::preBatchDraw() // Set material GL::bindTexture2D(_textureID); GL::blendFunc(_blendType.src, _blendType.dst); - + if (_vao == 0) buildVAO(); if (_vao) { GL::bindVAO(_vao); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); } else { @@ -198,8 +196,6 @@ void MeshCommand::preBatchDraw() _glProgramState->applyAttributes(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); } - - //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); } void MeshCommand::batchDraw() { @@ -215,7 +211,6 @@ void MeshCommand::batchDraw() _glProgramState->applyGLProgram(_mv); _glProgramState->applyUniforms(); - //_glProgramState->apply(_mv); // Draw glDrawElements(_primitive, (GLsizei)_indexCount, _indexFormat, 0); @@ -274,10 +269,20 @@ void MeshCommand::buildVAO() releaseVAO(); if (Configuration::getInstance()->supportsShareableVAO()) { + glGenVertexArrays(1, &_vao); + GL::bindVAO(_vao); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - _glProgramState->applyAttributes(); + auto flags = _glProgramState->getVertexAttribsFlags(); + for (int i = 0; flags > 0; i++) { + int flag = 1 << i; + if (flag & flags) + glEnableVertexAttribArray(i); + flags &= ~flag; + } + _glProgramState->applyAttributes(false); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); + GL::bindVAO(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -288,6 +293,7 @@ void MeshCommand::releaseVAO() if (Configuration::getInstance()->supportsShareableVAO() && _vao) { glDeleteVertexArrays(1, &_vao); + _vao = 0; GL::bindVAO(0); } } diff --git a/cocos/renderer/CCRenderer.cpp b/cocos/renderer/CCRenderer.cpp index d5afd00e83..5489a87fcd 100644 --- a/cocos/renderer/CCRenderer.cpp +++ b/cocos/renderer/CCRenderer.cpp @@ -331,12 +331,13 @@ void Renderer::visitRenderQueue(const RenderQueue& queue) flush3D(); cmd->preBatchDraw(); cmd->batchDraw(); + _lastBatchedMeshCommand = cmd; } else { cmd->batchDraw(); } - _lastBatchedMeshCommand = cmd; + // cmd->execute(); } else diff --git a/cocos/renderer/ccShader_3D_PositionTex.vert b/cocos/renderer/ccShader_3D_PositionTex.vert index cd6e8d2464..95af35228c 100644 --- a/cocos/renderer/ccShader_3D_PositionTex.vert +++ b/cocos/renderer/ccShader_3D_PositionTex.vert @@ -29,34 +29,47 @@ uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3]; // Varyings varying vec2 TextureCoordOut; -vec4 _skinnedPosition; - vec4 getPosition() { float blendWeight = a_blendWeight[0]; + int matrixIndex = int (a_blendIndex[0]) * 3; vec4 matrixPalette1 = u_matrixPalette[matrixIndex] * blendWeight; vec4 matrixPalette2 = u_matrixPalette[matrixIndex + 1] * blendWeight; vec4 matrixPalette3 = u_matrixPalette[matrixIndex + 2] * blendWeight; + blendWeight = a_blendWeight[1]; - matrixIndex = int(a_blendIndex[1]) * 3; - matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; - matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; - matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + if (blendWeight > 0.0) + { + matrixIndex = int(a_blendIndex[1]) * 3; + matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; + matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; + matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + } + blendWeight = a_blendWeight[2]; - matrixIndex = int(a_blendIndex[2]) * 3; - matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; - matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; - matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + if (blendWeight > 0.0) + { + matrixIndex = int(a_blendIndex[2]) * 3; + matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; + matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; + matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + } + blendWeight = a_blendWeight[3]; - matrixIndex = int(a_blendIndex[3]) * 3; - matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; - matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; - matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + if (blendWeight > 0.0) + { + matrixIndex = int(a_blendIndex[3]) * 3; + matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; + matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; + matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + } + + vec4 _skinnedPosition; _skinnedPosition.x = dot(a_position, matrixPalette1); _skinnedPosition.y = dot(a_position, matrixPalette2); _skinnedPosition.z = dot(a_position, matrixPalette3);