diff --git a/cocos/2d/CCLabelBMFont.h b/cocos/2d/CCLabelBMFont.h index a825d28ed6..60ed157773 100644 --- a/cocos/2d/CCLabelBMFont.h +++ b/cocos/2d/CCLabelBMFont.h @@ -33,7 +33,7 @@ Use any of these editors to generate BMFonts: #ifndef __CCBITMAP_FONT_ATLAS_H__ #define __CCBITMAP_FONT_ATLAS_H__ -#include "CCSpriteBatchNode.h" +#include "CCNewSpriteBatchNode.h" #include "uthash.h" #include #include @@ -190,7 +190,7 @@ http://www.angelcode.com/products/bmfont/ (Free, Windows only) @since v0.8 */ -class CC_DLL LabelBMFont : public SpriteBatchNode, public LabelProtocol, public RGBAProtocol +class CC_DLL LabelBMFont : public NewSpriteBatchNode, public LabelProtocol, public RGBAProtocol { public: /** diff --git a/cocos/2d/CCLabelTTF.h b/cocos/2d/CCLabelTTF.h index b63d63db3b..0d35a2c4ce 100644 --- a/cocos/2d/CCLabelTTF.h +++ b/cocos/2d/CCLabelTTF.h @@ -198,7 +198,7 @@ protected: /** font tint */ Color3B _textFillColor; - + }; diff --git a/cocos/2d/CCLayer.cpp b/cocos/2d/CCLayer.cpp index 01309b8b65..cb9c493df5 100644 --- a/cocos/2d/CCLayer.cpp +++ b/cocos/2d/CCLayer.cpp @@ -694,7 +694,7 @@ void LayerColor::updateColor() void LayerColor::draw() { - kmGLGetMatrix(KM_GL_MODELVIEW, &_matrixMV); + kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); CustomCommand* cmd = new CustomCommand(0, _vertexZ); cmd->func = CC_CALLBACK_0(LayerColor::onDraw, this); Renderer::getInstance()->addCommand(cmd); @@ -702,9 +702,11 @@ void LayerColor::draw() void LayerColor::onDraw() { - kmMat4 prevMat; - kmGLGetMatrix(KM_GL_MODELVIEW, &prevMat); - kmGLLoadMatrix(&_matrixMV); + //TODO we can just reuse the base MV matrix instead of save and reset everytime + //TODO need to find out where do we set the base MV matrix + kmMat4 prevMatrix; + kmGLGetMatrix(KM_GL_MODELVIEW, &prevMatrix); + kmGLLoadMatrix(&_transformMatrix); CC_NODE_DRAW_SETUP(); @@ -730,7 +732,7 @@ void LayerColor::onDraw() CC_INCREMENT_GL_DRAWS(1); - kmGLLoadMatrix(&prevMat); + kmGLLoadMatrix(&prevMatrix); } void LayerColor::setColor(const Color3B &color) diff --git a/cocos/2d/CCLayer.h b/cocos/2d/CCLayer.h index 8b9e377271..1fc8a5963a 100644 --- a/cocos/2d/CCLayer.h +++ b/cocos/2d/CCLayer.h @@ -315,7 +315,7 @@ protected: Vertex2F _squareVertices[4]; Color4F _squareColors[4]; - kmMat4 _matrixMV; + kmMat4 _transformMatrix; }; // diff --git a/cocos/2d/CCNewDrawNode.cpp b/cocos/2d/CCNewDrawNode.cpp index 90183feca6..c10c472dcd 100644 --- a/cocos/2d/CCNewDrawNode.cpp +++ b/cocos/2d/CCNewDrawNode.cpp @@ -42,7 +42,7 @@ bool NewDrawNode::init() void NewDrawNode::draw() { - kmGLGetMatrix(KM_GL_MODELVIEW, &_matrixMV); + kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix); CustomCommand* cmd = new CustomCommand(0, _vertexZ); cmd->func = CC_CALLBACK_0(NewDrawNode::onDraw, this); @@ -51,14 +51,17 @@ void NewDrawNode::draw() void NewDrawNode::onDraw() { - kmGLLoadMatrix(&_matrixMV); + kmMat4 prevMatrix; + kmGLGetMatrix(KM_GL_MODELVIEW, &prevMatrix); + + kmGLLoadMatrix(&_transformMatrix); CC_NODE_DRAW_SETUP(); GL::blendFunc(_blendFunc.src, _blendFunc.dst); render(); - kmGLLoadIdentity(); + kmGLLoadMatrix(&prevMatrix); } NS_CC_END \ No newline at end of file diff --git a/cocos/2d/CCNewDrawNode.h b/cocos/2d/CCNewDrawNode.h index 5030f49121..6b470d083a 100644 --- a/cocos/2d/CCNewDrawNode.h +++ b/cocos/2d/CCNewDrawNode.h @@ -28,7 +28,7 @@ public: protected: NewDrawNode(); - kmMat4 _matrixMV; + kmMat4 _transformMatrix; }; NS_CC_END diff --git a/cocos/2d/CCNewSprite.cpp b/cocos/2d/CCNewSprite.cpp index 02d5ff5626..b93dabf6e2 100644 --- a/cocos/2d/CCNewSprite.cpp +++ b/cocos/2d/CCNewSprite.cpp @@ -64,10 +64,18 @@ bool NewSprite::initWithTexture(Texture2D *texture, const Rect &rect, bool rotat void NewSprite::updateTransform() { + +#ifdef CC_USE_PHYSICS + updatePhysicsTransform(); + setDirty(true); +#endif + //TODO optimize the performance cache affineTransformation -// if(_dirty) -// { - if(!_visible) + + // recalculate matrix only if it is dirty + if(isDirty()) + { + if( !_visible || ( _parent && _parent != (Node*)_batchNode && static_cast(_parent)->_shouldBeHidden) ) { _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); _shouldBeHidden = true; @@ -76,6 +84,16 @@ void NewSprite::updateTransform() { _shouldBeHidden = false; +// if( ! _parent || _parent == (Node*)_batchNode ) +// { +// _transformToBatch = getNodeToParentTransform(); +// } +// else +// { +// CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); +// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); +// } + //TODO optimize this transformation, should use parent's transformation instead _transformToBatch = getNodeToWorldTransform(); @@ -114,10 +132,29 @@ void NewSprite::updateTransform() _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); } -// } -// _recursiveDirty = false; - setDirty(false); + // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS + if (_textureAtlas) + { + _textureAtlas->updateQuad(&_quad, _atlasIndex); + } + + _recursiveDirty = false; + setDirty(false); + } + + Node::updateTransform(); + +#if CC_SPRITE_DEBUG_DRAW + // draw bounding box + Point vertices[4] = { + Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), + Point( _quad.br.vertices.x, _quad.br.vertices.y ), + Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), + Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), + }; + ccDrawPoly(vertices, 4, true); +#endif // CC_SPRITE_DEBUG_DRAW } void NewSprite::draw(void) diff --git a/cocos/2d/CCSprite.cpp b/cocos/2d/CCSprite.cpp index f4118fc505..6f5ccce9bb 100644 --- a/cocos/2d/CCSprite.cpp +++ b/cocos/2d/CCSprite.cpp @@ -44,6 +44,8 @@ THE SOFTWARE. #include "CCAffineTransform.h" #include "TransformUtils.h" #include "CCProfiling.h" +#include "Renderer.h" +#include "QuadCommand.h" // external #include "kazmath/GL/matrix.h" @@ -446,37 +448,189 @@ void Sprite::setTextureCoords(Rect rect) } } -void Sprite::updateTransform(void) -{ - CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); - -#ifdef CC_USE_PHYSICS - updatePhysicsTransform(); - setDirty(true); -#endif - - // recalculate matrix only if it is dirty - if( isDirty() ) { +//void Sprite::updateTransform(void) +//{ +// CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); +// +//#ifdef CC_USE_PHYSICS +// updatePhysicsTransform(); +// setDirty(true); +//#endif +// +// // recalculate matrix only if it is dirty +// if( isDirty() ) { +// +// // If it is not visible, or one of its ancestors is not visible, then do nothing: +// if( !_visible || ( _parent && _parent != _batchNode && static_cast(_parent)->_shouldBeHidden) ) +// { +// _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); +// _shouldBeHidden = true; +// } +// else +// { +// _shouldBeHidden = false; +// +// if( ! _parent || _parent == _batchNode ) +// { +// _transformToBatch = getNodeToParentTransform(); +// } +// else +// { +// CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); +// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); +// } +// +// // +// // calculate the Quad based on the Affine Matrix +// // +// +// Size size = _rect.size; +// +// float x1 = _offsetPosition.x; +// float y1 = _offsetPosition.y; +// +// float x2 = x1 + size.width; +// float y2 = y1 + size.height; +// float x = _transformToBatch.tx; +// float y = _transformToBatch.ty; +// +// float cr = _transformToBatch.a; +// float sr = _transformToBatch.b; +// float cr2 = _transformToBatch.d; +// float sr2 = -_transformToBatch.c; +// float ax = x1 * cr - y1 * sr2 + x; +// float ay = x1 * sr + y1 * cr2 + y; +// +// float bx = x2 * cr - y1 * sr2 + x; +// float by = x2 * sr + y1 * cr2 + y; +// +// float cx = x2 * cr - y2 * sr2 + x; +// float cy = x2 * sr + y2 * cr2 + y; +// +// float dx = x1 * cr - y2 * sr2 + x; +// float dy = x1 * sr + y2 * cr2 + y; +// +// _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ ); +// _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ ); +// _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); +// _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); +// } +// +// // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS +// if (_textureAtlas) +// { +// _textureAtlas->updateQuad(&_quad, _atlasIndex); +// } +// +// _recursiveDirty = false; +// setDirty(false); +// } +// +// // MARMALADE CHANGED +// // recursively iterate over children +///* if( _hasChildren ) +// { +// // MARMALADE: CHANGED TO USE Node* +// // NOTE THAT WE HAVE ALSO DEFINED virtual Node::updateTransform() +// arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*); +// }*/ +// Node::updateTransform(); +// +//#if CC_SPRITE_DEBUG_DRAW +// // draw bounding box +// Point vertices[4] = { +// Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), +// Point( _quad.br.vertices.x, _quad.br.vertices.y ), +// Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), +// Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), +// }; +// ccDrawPoly(vertices, 4, true); +//#endif // CC_SPRITE_DEBUG_DRAW +//} - // If it is not visible, or one of its ancestors is not visible, then do nothing: - if( !_visible || ( _parent && _parent != _batchNode && static_cast(_parent)->_shouldBeHidden) ) +//// draw +// +//void Sprite::draw(void) +//{ +// CC_PROFILER_START_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); +// +// CCASSERT(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); +// +// CC_NODE_DRAW_SETUP(); +// +// GL::blendFunc( _blendFunc.src, _blendFunc.dst ); +// +// GL::bindTexture2D( _texture->getName() ); +// GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); +// +//#define kQuadSize sizeof(_quad.bl) +//#ifdef EMSCRIPTEN +// long offset = 0; +// setGLBufferData(&_quad, 4 * kQuadSize, 0); +//#else +// long offset = (long)&_quad; +//#endif // EMSCRIPTEN +// +// // vertex +// int diff = offsetof( V3F_C4B_T2F, vertices); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); +// +// // texCoods +// diff = offsetof( V3F_C4B_T2F, texCoords); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); +// +// // color +// diff = offsetof( V3F_C4B_T2F, colors); +// glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); +// +// +// glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +// +// CHECK_GL_ERROR_DEBUG(); +// +// +//#if CC_SPRITE_DEBUG_DRAW == 1 +// // draw bounding box +// Point vertices[4]={ +// Point(_quad.tl.vertices.x,_quad.tl.vertices.y), +// Point(_quad.bl.vertices.x,_quad.bl.vertices.y), +// Point(_quad.br.vertices.x,_quad.br.vertices.y), +// Point(_quad.tr.vertices.x,_quad.tr.vertices.y), +// }; +// ccDrawPoly(vertices, 4, true); +//#elif CC_SPRITE_DEBUG_DRAW == 2 +// // draw texture box +// Size s = this->getTextureRect().size; +// Point offsetPix = this->getOffsetPosition(); +// Point vertices[4] = { +// Point(offsetPix.x,offsetPix.y), Point(offsetPix.x+s.width,offsetPix.y), +// Point(offsetPix.x+s.width,offsetPix.y+s.height), Point(offsetPix.x,offsetPix.y+s.height) +// }; +// ccDrawPoly(vertices, 4, true); +//#endif // CC_SPRITE_DEBUG_DRAW +// +// CC_INCREMENT_GL_DRAWS(1); +// +// CC_PROFILER_STOP_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); +//} + + +void Sprite::updateTransform() +{ + //TODO optimize the performance cache affineTransformation + if(_dirty) + { + if(!_visible) { _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); _shouldBeHidden = true; } - else + else { _shouldBeHidden = false; - if( ! _parent || _parent == _batchNode ) - { - _transformToBatch = getNodeToParentTransform(); - } - else - { - CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); - _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); - } + //TODO optimize this transformation, should use parent's transformation instead + _transformToBatch = getNodeToWorldTransform(); // // calculate the Quad based on the Affine Matrix @@ -513,103 +667,27 @@ void Sprite::updateTransform(void) _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ ); _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ ); } - // MARMALADE CHANGE: ADDED CHECK FOR NULL, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS if (_textureAtlas) - { + { _textureAtlas->updateQuad(&_quad, _atlasIndex); } - + _recursiveDirty = false; setDirty(false); + } - // MARMALADE CHANGED - // recursively iterate over children -/* if( _hasChildren ) - { - // MARMALADE: CHANGED TO USE Node* - // NOTE THAT WE HAVE ALSO DEFINED virtual Node::updateTransform() - arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*); - }*/ Node::updateTransform(); - -#if CC_SPRITE_DEBUG_DRAW - // draw bounding box - Point vertices[4] = { - Point( _quad.bl.vertices.x, _quad.bl.vertices.y ), - Point( _quad.br.vertices.x, _quad.br.vertices.y ), - Point( _quad.tr.vertices.x, _quad.tr.vertices.y ), - Point( _quad.tl.vertices.x, _quad.tl.vertices.y ), - }; - ccDrawPoly(vertices, 4, true); -#endif // CC_SPRITE_DEBUG_DRAW } -// draw - void Sprite::draw(void) { - CC_PROFILER_START_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); - - CCASSERT(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); - - CC_NODE_DRAW_SETUP(); + updateTransform(); + //TODO implement z order + QuadCommand* renderCommand = new QuadCommand(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); - GL::blendFunc( _blendFunc.src, _blendFunc.dst ); - - GL::bindTexture2D( _texture->getName() ); - GL::enableVertexAttribs( GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX ); - -#define kQuadSize sizeof(_quad.bl) -#ifdef EMSCRIPTEN - long offset = 0; - setGLBufferData(&_quad, 4 * kQuadSize, 0); -#else - long offset = (long)&_quad; -#endif // EMSCRIPTEN - - // vertex - int diff = offsetof( V3F_C4B_T2F, vertices); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); - - // texCoods - diff = offsetof( V3F_C4B_T2F, texCoords); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORDS, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); - - // color - diff = offsetof( V3F_C4B_T2F, colors); - glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); - - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - CHECK_GL_ERROR_DEBUG(); - - -#if CC_SPRITE_DEBUG_DRAW == 1 - // draw bounding box - Point vertices[4]={ - Point(_quad.tl.vertices.x,_quad.tl.vertices.y), - Point(_quad.bl.vertices.x,_quad.bl.vertices.y), - Point(_quad.br.vertices.x,_quad.br.vertices.y), - Point(_quad.tr.vertices.x,_quad.tr.vertices.y), - }; - ccDrawPoly(vertices, 4, true); -#elif CC_SPRITE_DEBUG_DRAW == 2 - // draw texture box - Size s = this->getTextureRect().size; - Point offsetPix = this->getOffsetPosition(); - Point vertices[4] = { - Point(offsetPix.x,offsetPix.y), Point(offsetPix.x+s.width,offsetPix.y), - Point(offsetPix.x+s.width,offsetPix.y+s.height), Point(offsetPix.x,offsetPix.y+s.height) - }; - ccDrawPoly(vertices, 4, true); -#endif // CC_SPRITE_DEBUG_DRAW - - CC_INCREMENT_GL_DRAWS(1); - - CC_PROFILER_STOP_CATEGORY(kProfilerCategorySprite, "CCSprite - draw"); + Renderer::getInstance()->addCommand(renderCommand); } // Node overrides