diff --git a/cocos/2d/CCFastTMXLayer.cpp b/cocos/2d/CCFastTMXLayer.cpp index 4f7ef7956d..169df9c211 100644 --- a/cocos/2d/CCFastTMXLayer.cpp +++ b/cocos/2d/CCFastTMXLayer.cpp @@ -128,6 +128,11 @@ FastTMXLayer::~FastTMXLayer() CC_SAFE_DELETE_ARRAY(_tiles); } +bool sortQuadCommand(const V3F_C4B_T2F_Quad& a, const V3F_C4B_T2F_Quad& b) +{ + return a.bl.vertices.z < b.bl.vertices.z; +} + void FastTMXLayer::draw(Renderer *renderer, const Mat4& transform, uint32_t flags) { if( flags != 0 || _dirty ) @@ -140,7 +145,7 @@ void FastTMXLayer::draw(Renderer *renderer, const Mat4& transform, uint32_t flag rect = RectApplyTransform(rect, inv); _verticesToDraw = updateTiles(rect, renderer); - + std::sort(_quads.begin(), _quads.end(), sortQuadCommand); // don't draw more than 65535 vertices since we are using GL_UNSIGNED_SHORT for indices _verticesToDraw = std::min(_verticesToDraw, 65535); @@ -148,13 +153,22 @@ void FastTMXLayer::draw(Renderer *renderer, const Mat4& transform, uint32_t flag } - auto glprogramState = GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP); - for( int index = 0; index < _verticesToDraw/6; ++index) + auto glprogramState = GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR); + int index = 0; + for(const auto& quadNumberIter : _quadsNumber) { - float z = _quads[index].bl.vertices.z; - _renderCommands[index].init(z, _texture->getName(), glprogramState, BlendFunc::ALPHA_PREMULTIPLIED, &_quads[index], 1, transform); - renderer->addCommand(&_renderCommands[index]); + int z = quadNumberIter.first; + auto& quadCommand = _renderCommands2[quadNumberIter.first]; + quadCommand.init(z, _texture->getName(), glprogramState, BlendFunc::ALPHA_PREMULTIPLIED, &_quads[index], quadNumberIter.second, transform); + index += quadNumberIter.second; + renderer->addCommand(&quadCommand); } +// for( int index = 0; index < _verticesToDraw/6; ++index) +// { +// float z = _quads[index].bl.vertices.z; +// _renderCommands[index].init(z, _texture->getName(), glprogramState, BlendFunc::ALPHA_PREMULTIPLIED, &_quads[index], 1, transform); +// renderer->addCommand(&_renderCommands[index]); +// } // _customCommand.init(_globalZOrder); // _customCommand.func = CC_CALLBACK_0(FastTMXLayer::onDraw, this, transform, flags); @@ -218,6 +232,9 @@ int FastTMXLayer::updateTiles(const Rect& culledRect, Renderer* renderer) _indices.resize(quadsNeed * 6); } + //clear quadsNumber + _quadsNumber.clear(); + Size texSize = _tileSet->_imageSize; for (int y = visibleTiles.origin.y - tilesOverY; y < visibleTiles.origin.y + visibleTiles.size.height + tilesOverY; ++y) { @@ -242,7 +259,18 @@ int FastTMXLayer::updateTiles(const Rect& culledRect, Renderer* renderer) float left, right, top, bottom, z; z = getVertexZForPos(Vec2(x, y)); - + + //add quadsNumber + auto quadsNumberIter = _quadsNumber.find(z); + if(quadsNumberIter == _quadsNumber.end()) + { + _quadsNumber.insert(std::make_pair(z, 1)); + } + else + { + quadsNumberIter->second += 1; + } + // vertices if (tileGID & kTMXTileDiagonalFlag) { diff --git a/cocos/2d/CCFastTMXLayer.h b/cocos/2d/CCFastTMXLayer.h index 052c6a8184..7291921f4c 100644 --- a/cocos/2d/CCFastTMXLayer.h +++ b/cocos/2d/CCFastTMXLayer.h @@ -34,6 +34,7 @@ THE SOFTWARE. #include "renderer/CCQuadCommand.h" #include +#include NS_CC_BEGIN @@ -245,6 +246,9 @@ protected: /** quads to be rendered */ std::vector _quads; std::vector _renderCommands; + + std::map _quadsNumber; + std::unordered_map _renderCommands2; /** indices */ std::vector _indices; bool _dirty; diff --git a/cocos/base/CCDirector.cpp b/cocos/base/CCDirector.cpp index 9d1e02f187..a2d22b46e9 100644 --- a/cocos/base/CCDirector.cpp +++ b/cocos/base/CCDirector.cpp @@ -1066,7 +1066,7 @@ void Director::showStats() { char buffer[30]; - if (_accumDt > CC_DIRECTOR_STATS_INTERVAL) + if (_accumDt > CC_DIRECTOR_STATS_INTERVAL * 20) { _frameRate = _frames / _accumDt; _frames = 0; diff --git a/cocos/renderer/CCQuadCommand.cpp b/cocos/renderer/CCQuadCommand.cpp index 4b497ff253..eb4fe6e66e 100644 --- a/cocos/renderer/CCQuadCommand.cpp +++ b/cocos/renderer/CCQuadCommand.cpp @@ -40,6 +40,7 @@ QuadCommand::QuadCommand() ,_blendType(BlendFunc::DISABLE) ,_quads(nullptr) ,_quadsCount(0) +,_preMultiplyMV(true) { _type = RenderCommand::Type::QUAD_COMMAND; } diff --git a/cocos/renderer/CCQuadCommand.h b/cocos/renderer/CCQuadCommand.h index 8f3d3622f1..7024a2050f 100644 --- a/cocos/renderer/CCQuadCommand.h +++ b/cocos/renderer/CCQuadCommand.h @@ -38,7 +38,7 @@ public: static const int MATERIAL_ID_DO_NOT_BATCH = 0; QuadCommand(); - ~QuadCommand(); + virtual ~QuadCommand(); /** Initializes the command with a globalZOrder, a texture ID, a `GLProgram`, a blending function, a pointer to quads, * quantity of quads, and the Model View transform to be used for the quads */ @@ -55,10 +55,10 @@ public: inline GLProgramState* getGLProgramState() const { return _glProgramState; } inline BlendFunc getBlendType() const { return _blendType; } inline const Mat4& getModelView() const { return _mv; } - + inline bool getPremultiplyMV() const { return _preMultiplyMV; } protected: - void generateMaterialID(); + virtual void generateMaterialID(); uint32_t _materialID; GLuint _textureID; @@ -67,7 +67,29 @@ protected: V3F_C4B_T2F_Quad* _quads; ssize_t _quadsCount; Mat4 _mv; + bool _preMultiplyMV; }; + +class NopreMultiplyMVQuadCommand : public QuadCommand +{ +public: + NopreMultiplyMVQuadCommand() + :QuadCommand() + { + _preMultiplyMV = false; + } + + virtual ~NopreMultiplyMVQuadCommand() + { + } + +protected: + virtual void generateMaterialID() + { + _materialID = QuadCommand::MATERIAL_ID_DO_NOT_BATCH; + } +}; + NS_CC_END #endif //_CC_QUADCOMMAND_H_ diff --git a/cocos/renderer/CCRenderer.cpp b/cocos/renderer/CCRenderer.cpp index 222118da6f..5a5964a28d 100644 --- a/cocos/renderer/CCRenderer.cpp +++ b/cocos/renderer/CCRenderer.cpp @@ -296,7 +296,13 @@ void Renderer::visitRenderQueue(const RenderQueue& queue) _batchedQuadCommands.push_back(cmd); memcpy(_quads + _numQuads, cmd->getQuads(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount()); - convertToWorldCoordinates(_quads + _numQuads, cmd->getQuadCount(), cmd->getModelView()); + + //only multiply mv when getPremultiplyMV is true + if(cmd->getPremultiplyMV()) + { + convertToWorldCoordinates(_quads + _numQuads, cmd->getQuadCount(), cmd->getModelView()); + } + _numQuads += cmd->getQuadCount();