Sprite now using New renderer

This commit is contained in:
Nite Luo 2013-11-25 16:33:05 -08:00
parent 19b8ba89e2
commit f3830985bb
8 changed files with 245 additions and 125 deletions

View File

@ -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 <map>
#include <sstream>
@ -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:
/**

View File

@ -198,7 +198,7 @@ protected:
/** font tint */
Color3B _textFillColor;
};

View File

@ -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)

View File

@ -315,7 +315,7 @@ protected:
Vertex2F _squareVertices[4];
Color4F _squareColors[4];
kmMat4 _matrixMV;
kmMat4 _transformMatrix;
};
//

View File

@ -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

View File

@ -28,7 +28,7 @@ public:
protected:
NewDrawNode();
kmMat4 _matrixMV;
kmMat4 _transformMatrix;
};
NS_CC_END

View File

@ -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<NewSprite*>(_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<Sprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite");
// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast<NewSprite*>(_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)

View File

@ -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<Sprite*>(_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<Sprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite");
// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast<Sprite*>(_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<Sprite*>(_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<Sprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite");
_transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast<Sprite*>(_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