diff --git a/cocos/3d/CCAnimate3D.cpp b/cocos/3d/CCAnimate3D.cpp index c967b0f990..27911095c4 100644 --- a/cocos/3d/CCAnimate3D.cpp +++ b/cocos/3d/CCAnimate3D.cpp @@ -45,17 +45,18 @@ Animate3D* Animate3D::create(Animation3D* animation) return animate; } -Animate3D* Animate3D::createSubAnimate3D(Animate3D* animate, float fromTime, float duration) +Animate3D* Animate3D::create(Animation3D* animation, float fromTime, float duration) { - auto subAnimate = animate->clone(); - float fullDuration = animate->getDuration(); + auto animate = Animate3D::create(animation); + + float fullDuration = animation->getDuration(); if (duration > fullDuration - fromTime) duration = fullDuration - fromTime; - subAnimate->_start = fromTime / fullDuration; - subAnimate->_last = duration / fullDuration; + animate->_start = fromTime / fullDuration; + animate->_last = duration / fullDuration; - return subAnimate; + return animate; } /** returns a clone of action */ diff --git a/cocos/3d/CCAnimate3D.h b/cocos/3d/CCAnimate3D.h index b34fc86977..fbda6328b5 100644 --- a/cocos/3d/CCAnimate3D.h +++ b/cocos/3d/CCAnimate3D.h @@ -49,13 +49,13 @@ public: static Animate3D* create(Animation3D* animation); /** - * create sub Animate3D - * @param animate Animate3D used to generate sub animate3D + * create Animate3D + * @param animation used to generate animate3D * @param formTime * @param duration Time the Animate3D lasts * @return Animate3D created using animate */ - static Animate3D* createSubAnimate3D(Animate3D* animate, float fromTime, float duration); + static Animate3D* create(Animation3D* animation, float fromTime, float duration); // // Overrides // diff --git a/cocos/3d/CCSprite3D.cpp b/cocos/3d/CCSprite3D.cpp index b54fb1760b..f92e4dc475 100644 --- a/cocos/3d/CCSprite3D.cpp +++ b/cocos/3d/CCSprite3D.cpp @@ -273,6 +273,8 @@ void Sprite3D::genGLProgramState() } setGLProgramState(programstate); + GLuint texID = _texture ? _texture->getName() : 0; + _meshCommand.genMaterialID(texID, programstate, _mesh, _blend); } GLProgram* Sprite3D::getDefaultGLProgram(bool textured) @@ -296,11 +298,12 @@ GLProgram* Sprite3D::getDefaultGLProgram(bool textured) void Sprite3D::setTexture(const std::string& texFile) { auto tex = Director::getInstance()->getTextureCache()->addImage(texFile); - if( tex && _texture != tex ) { - CC_SAFE_RETAIN(tex); - CC_SAFE_RELEASE_NULL(_texture); - _texture = tex; - } +// if( tex && _texture != tex ) { +// CC_SAFE_RETAIN(tex); +// CC_SAFE_RELEASE_NULL(_texture); +// _texture = tex; +// } + setTexture(tex); } void Sprite3D::setTexture(Texture2D* texture) @@ -309,6 +312,11 @@ void Sprite3D::setTexture(Texture2D* texture) CC_SAFE_RETAIN(texture); CC_SAFE_RELEASE_NULL(_texture); _texture = texture; + if (getGLProgramState() && _mesh) + { + GLuint texID = _texture ? _texture->getName() : 0; + _meshCommand.genMaterialID(texID, getGLProgramState(), _mesh, _blend); + } } } diff --git a/cocos/renderer/CCMeshCommand.cpp b/cocos/renderer/CCMeshCommand.cpp index f562f94310..fefbdd3f69 100644 --- a/cocos/renderer/CCMeshCommand.cpp +++ b/cocos/renderer/CCMeshCommand.cpp @@ -32,6 +32,7 @@ #include "renderer/CCTextureAtlas.h" #include "renderer/CCTexture2D.h" #include "renderer/ccGLStateCache.h" +#include "xxhash.h" NS_CC_BEGIN @@ -46,6 +47,7 @@ MeshCommand::MeshCommand() , _displayColor(1.0f, 1.0f, 1.0f, 1.0f) , _matrixPalette(nullptr) , _matrixPaletteSize(0) +, _materialID(0) { _type = RenderCommand::Type::MESH_COMMAND; } @@ -107,6 +109,8 @@ MeshCommand::~MeshCommand() void MeshCommand::applyRenderState() { + + if (_cullFaceEnabled) { glEnable(GL_CULL_FACE); @@ -138,16 +142,69 @@ void MeshCommand::restoreRenderState() } } +void MeshCommand::genMaterialID(GLuint texID, void* glProgramState, void* mesh, const BlendFunc& blend) +{ + int* intstate = static_cast(glProgramState); + int* intmesh = static_cast(mesh); + + int statekey[] = {intstate[0], 0}, meshkey[] = {intmesh[0], 0}; + if (sizeof(void*) > sizeof(int)) + { + statekey[1] = intstate[1]; + meshkey[1] = intmesh[1]; + } + 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); +} + void MeshCommand::MatrixPalleteCallBack( GLProgram* glProgram, Uniform* uniform) { glProgram->setUniformLocationWith4fv(uniform->location, (const float*)_matrixPalette, _matrixPaletteSize); } +void MeshCommand::preDraw() +{ + // set render state + applyRenderState(); + // Set material + GL::bindTexture2D(_textureID); + GL::blendFunc(_blendType.src, _blendType.dst); + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); +// + //_glProgramState->apply(_mv); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); +} +void MeshCommand::draw() +{ + auto glProgram = _glProgramState->getGLProgram(); + + _glProgramState->setUniformVec4("u_color", _displayColor); + + if (_matrixPaletteSize && _matrixPalette) + { + _glProgramState->setUniformCallback("u_matrixPalette", CC_CALLBACK_2(MeshCommand::MatrixPalleteCallBack, this)); + + } + + _glProgramState->apply(_mv); + + // Draw + glDrawElements(_primitive, (GLsizei)_indexCount, _indexFormat, 0); + + CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, _indexCount); +} +void MeshCommand::postDraw() +{ + //restore render state + restoreRenderState(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + void MeshCommand::execute() { // set render state applyRenderState(); - // Set material GL::bindTexture2D(_textureID); GL::blendFunc(_blendType.src, _blendType.dst); @@ -172,7 +229,6 @@ void MeshCommand::execute() //restore render state restoreRenderState(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); } diff --git a/cocos/renderer/CCMeshCommand.h b/cocos/renderer/CCMeshCommand.h index fb88674b90..02c71119e4 100644 --- a/cocos/renderer/CCMeshCommand.h +++ b/cocos/renderer/CCMeshCommand.h @@ -59,8 +59,17 @@ public: void setMatrixPalette(const Vec4* matrixPalette) { _matrixPalette = matrixPalette; } void setMatrixPaletteSize(int size) { _matrixPaletteSize = size; } - + void execute(); + + //used for bath + void preDraw(); + void draw(); + void postDraw(); + + void genMaterialID(GLuint texID, void* glProgramState, void* mesh, const BlendFunc& blend); + + uint32_t getMaterialID() const { return _materialID; } protected: // apply renderstate @@ -83,6 +92,8 @@ protected: const Vec4* _matrixPalette; int _matrixPaletteSize; + uint32_t _materialID; //material ID + GLuint _vertexBuffer; GLuint _indexBuffer; GLenum _primitive; diff --git a/cocos/renderer/CCRenderer.cpp b/cocos/renderer/CCRenderer.cpp index 222118da6f..870da5ba5b 100644 --- a/cocos/renderer/CCRenderer.cpp +++ b/cocos/renderer/CCRenderer.cpp @@ -108,6 +108,7 @@ static const int DEFAULT_RENDER_QUEUE = 0; // Renderer::Renderer() :_lastMaterialID(0) +,_lastBatchedMeshCommand(nullptr) ,_numQuads(0) ,_glViewAssigned(false) ,_isRendering(false) @@ -277,12 +278,14 @@ void Renderer::visitRenderQueue(const RenderQueue& queue) { ssize_t size = queue.size(); + uint32_t material3DID = 0; //last material 3d ID for (ssize_t index = 0; index < size; ++index) { auto command = queue[index]; auto commandType = command->getType(); if(RenderCommand::Type::QUAD_COMMAND == commandType) { + flush3D(); auto cmd = static_cast(command); //Batch quads if(_numQuads + cmd->getQuadCount() > VBO_SIZE) @@ -321,9 +324,20 @@ void Renderer::visitRenderQueue(const RenderQueue& queue) } else if (RenderCommand::Type::MESH_COMMAND == commandType) { - flush(); + flush2D(); auto cmd = static_cast(command); - cmd->execute(); + if (_lastBatchedMeshCommand == nullptr || _lastBatchedMeshCommand->getMaterialID() != cmd->getMaterialID()) + { + flush3D(); + cmd->preDraw(); + cmd->draw(); + } + else + { + cmd->draw(); + } + _lastBatchedMeshCommand = cmd; +// cmd->execute(); } else { @@ -376,6 +390,7 @@ void Renderer::clean() _numQuads = 0; _lastMaterialID = 0; + _lastBatchedMeshCommand = nullptr; } void Renderer::convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Mat4& modelView) @@ -505,11 +520,26 @@ void Renderer::drawBatchedQuads() } void Renderer::flush() +{ + flush2D(); + flush3D(); +} + +void Renderer::flush2D() { drawBatchedQuads(); _lastMaterialID = 0; } +void Renderer::flush3D() +{ + if (_lastBatchedMeshCommand) + { + _lastBatchedMeshCommand->postDraw(); + _lastBatchedMeshCommand = nullptr; + } +} + // helpers bool Renderer::checkVisibility(const Mat4 &transform, const Size &size) diff --git a/cocos/renderer/CCRenderer.h b/cocos/renderer/CCRenderer.h index 434214db09..7a1fd14253 100644 --- a/cocos/renderer/CCRenderer.h +++ b/cocos/renderer/CCRenderer.h @@ -38,6 +38,7 @@ NS_CC_BEGIN class EventListenerCustom; class QuadCommand; +class MeshCommand; /** Class that knows how to sort `RenderCommand` objects. Since the commands that have `z == 0` are "pushed back" in @@ -132,6 +133,10 @@ protected: //Draw the previews queued quads and flush previous context void flush(); + void flush2D(); + + void flush3D(); + void visitRenderQueue(const RenderQueue& queue); void convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Mat4& modelView); @@ -142,6 +147,7 @@ protected: uint32_t _lastMaterialID; + MeshCommand* _lastBatchedMeshCommand; std::vector _batchedQuadCommands; V3F_C4B_T2F_Quad _quads[VBO_SIZE]; diff --git a/cocos/renderer/ccShader_3D_PositionTex.vert b/cocos/renderer/ccShader_3D_PositionTex.vert index 33e8e6040c..cd6e8d2464 100644 --- a/cocos/renderer/ccShader_3D_PositionTex.vert +++ b/cocos/renderer/ccShader_3D_PositionTex.vert @@ -33,15 +33,11 @@ vec4 _skinnedPosition; vec4 getPosition() { - vec4 matrixPalette1 = vec4(0.0); - vec4 matrixPalette2 = vec4(0.0); - vec4 matrixPalette3 = vec4(0.0); - float blendWeight = a_blendWeight[0]; int matrixIndex = int (a_blendIndex[0]) * 3; - matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight; - matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight; - matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight; + 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; diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index 9b9b4ea7bd..cab2086881 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -541,7 +541,7 @@ std::string Sprite3DWithSkinTest::subtitle() const void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p) { - std::string fileName = "Sprite3DTest/girl.c3t"; + std::string fileName = "Sprite3DTest/girl.c3b"; auto sprite = Sprite3D::create(fileName); addChild(sprite); sprite->setRotation3D(Vec3(-90.f, 0.f, 0.f)); diff --git a/tools/bindings-generator b/tools/bindings-generator deleted file mode 160000 index 417bfcdce1..0000000000 --- a/tools/bindings-generator +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 417bfcdce1633a4f00de1ddb1084c2d7c33a33ce