issue #1056: Check bugs of SpriteTest.

This commit is contained in:
James Chen 2012-03-26 18:44:28 +08:00
parent 8b6de75be6
commit 0f5efaffd2
7 changed files with 134 additions and 108 deletions

View File

@ -303,9 +303,6 @@ protected:
// transform
CCAffineTransform m_tTransform, m_tInverse;
#ifdef CC_NODE_TRANSFORM_USING_AFFINE_MATRIX
GLfloat m_pTransformGL[16];
#endif
// To reduce memory, place bools that are not properties here:
bool m_bIsTransformDirty;
bool m_bIsInverseDirty;

View File

@ -32,7 +32,8 @@ THE SOFTWARE.
#include "CCObject.h"
#include "ccConfig.h"
namespace cocos2d {
NS_CC_BEGIN
class CCTexture2D;
/** @brief A class that implements a Texture Atlas.
@ -51,7 +52,9 @@ class CC_DLL CCTextureAtlas : public CCObject
{
protected:
GLushort* m_pIndices;
GLuint m_uVAOname;
#if CC_TEXTURE_ATLAS_USE_VAO
GLuint m_uVAOname;
#endif
GLuint m_pBuffersVBO[2]; //0: vertex 1: indices
bool m_bDirty; //indicates whether or not the array buffer of the VBO needs to be updated
@ -190,12 +193,17 @@ public:
/** draws all the Atlas's Quads
*/
void drawQuads();
private:
void initIndices();
void initVAO();
private:
void setupIndices();
void mapBuffers();
#if CC_TEXTURE_ATLAS_USE_VAO
void setupVBOandVAO();
#else
void setupVBO();
#endif
};
}//namespace cocos2d
NS_CC_END
#endif //__CCTEXTURE_ATLAS_H__

View File

@ -149,14 +149,14 @@ Only valid for cocos2d-mac. Not supported on cocos2d-ios.
#define CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD 1
#endif
/** @def CC_COCOSNODE_RENDER_SUBPIXEL
/** @def CC_NODE_RENDER_SUBPIXEL
If enabled, the CCNode objects (CCSprite, CCLabel,etc) will be able to render in subpixels.
If disabled, integer pixels will be used.
To enable set it to 1. Enabled by default.
*/
#ifndef CC_COCOSNODE_RENDER_SUBPIXEL
#define CC_COCOSNODE_RENDER_SUBPIXEL 1
#ifndef CC_NODE_RENDER_SUBPIXEL
#define CC_NODE_RENDER_SUBPIXEL 1
#endif
/** @def CC_SPRITEBATCHNODE_RENDER_SUBPIXEL
@ -169,35 +169,6 @@ Only valid for cocos2d-mac. Not supported on cocos2d-ios.
#define CC_SPRITEBATCHNODE_RENDER_SUBPIXEL 1
#endif
/** @def CC_NODE_TRANSFORM_USING_AFFINE_MATRIX
If enabled, CCNode will transform the nodes using a cached Affine matrix.
If disabled, the node will be transformed using glTranslate,glRotate,glScale.
Using the affine matrix only requires 2 GL calls.
Using the translate/rotate/scale requires 5 GL calls.
But computing the Affine matrix is relative expensive.
But according to performance tests, Affine matrix performs better.
This parameter doesn't affect CCSpriteBatchNode nodes.
To enable set it to a value different than 0. Enabled by default.
*/
#ifndef CC_NODE_TRANSFORM_USING_AFFINE_MATRIX
#define CC_NODE_TRANSFORM_USING_AFFINE_MATRIX 1
#endif
/** @def CC_OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA
If most of your imamges have pre-multiplied alpha, set it to 1 (if you are going to use .PNG/.JPG file images).
Only set to 0 if ALL your images by-pass Apple UIImage loading system (eg: if you use libpng or PVR images)
To enable set it to a value different than 0. Enabled by default.
@since v0.99.5
*/
#ifndef CC_OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA
#define CC_OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA 1
#endif
/** @def CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
Use GL_TRIANGLE_STRIP instead of GL_TRIANGLES when rendering the texture atlas.
It seems it is the recommend way, but it is much slower, so, enable it at your own risk

View File

@ -74,19 +74,10 @@ simple macro that swaps 2 variables
/** @def CC_BLEND_SRC
default gl blend src function. Compatible with premultiplied alpha images.
*/
#if CC_OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA
#define CC_BLEND_SRC GL_ONE
#define CC_BLEND_DST GL_ONE_MINUS_SRC_ALPHA
#else
#define CC_BLEND_SRC GL_SRC_ALPHA
#define CC_BLEND_DST GL_ONE_MINUS_SRC_ALPHA
#endif // ! CC_OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA
/** @def CC_BLEND_DST
default gl blend dst function. Compatible with premultiplied alpha images.
*/
#define CC_BLEND_SRC GL_ONE
#define CC_BLEND_DST GL_ONE_MINUS_SRC_ALPHA
/** @def CC_NODE_DRAW_SETUP
Helpful macro that setups the GL server state, the correct GL program and sets the Model View Projection matrix
@since v2.0

View File

@ -459,19 +459,21 @@ void CCSprite::updateTransform(void)
if( isDirty() ) {
// If it is not visible, or one of its ancestors is not visible, then do nothing:
if( !m_bIsVisible || ( m_pParent && m_pParent != m_pobBatchNode && ((CCSprite*)m_pParent)->m_bShouldBeHidden) ) {
if( !m_bIsVisible || ( m_pParent && m_pParent != m_pobBatchNode && ((CCSprite*)m_pParent)->m_bShouldBeHidden) )
{
m_sQuad.br.vertices = m_sQuad.tl.vertices = m_sQuad.tr.vertices = m_sQuad.bl.vertices = vertex3(0,0,0);
m_bShouldBeHidden = true;
}
else {
else
{
m_bShouldBeHidden = false;
if( ! m_pParent || m_pParent == m_pobBatchNode )
{
m_transformToBatch = nodeToParentTransform();
else {
}
else
{
CCAssert( dynamic_cast<CCSprite*>(m_pParent), "Logic error in CCSprite. Parent must be a CCSprite");
m_transformToBatch = CCAffineTransformConcat( nodeToParentTransform() , ((CCSprite*)m_pParent)->m_transformToBatch );
}

View File

@ -162,7 +162,7 @@ void CCSpriteBatchNode::visit(void)
}
kmGLPopMatrix();
m_nOrderOfArrival = 0;
setOrderOfArrival(0);
CC_PROFILER_STOP_CATEGORY(kCCProfilerCategoryBatchSprite, "CCSpriteBatchNode - visit");
@ -195,7 +195,7 @@ void CCSpriteBatchNode::addChild(CCNode *child, int zOrder)
void CCSpriteBatchNode::reorderChild(CCNode *child, int zOrder)
{
CCAssert(child != NULL, "the child should not be null");
CCAssert(m_pChildren->containsObject(child), "sprite batch node should contain the child");
CCAssert(m_pChildren->containsObject(child), "Child doesn't belong to Sprite");
if (zOrder == child->getZOrder())
{
@ -233,6 +233,7 @@ void CCSpriteBatchNode::removeChildAtIndex(unsigned int uIndex, bool bDoCleanup)
void CCSpriteBatchNode::removeAllChildrenWithCleanup(bool bCleanup)
{
// Invalidate atlas index. issue #569
// useSelfRender should be performed on all descendants. issue #1216
arrayMakeObjectsPerformSelectorWithObject(m_pobDescendants, &CCSprite::setBatchNode, NULL, CCSprite*);
CCNode::removeAllChildrenWithCleanup(bCleanup);

View File

@ -39,7 +39,7 @@ THE SOFTWARE.
// implementation CCTextureAtlas
namespace cocos2d {
NS_CC_BEGIN
CCTextureAtlas::CCTextureAtlas()
:m_pIndices(NULL)
@ -50,14 +50,16 @@ CCTextureAtlas::CCTextureAtlas()
CCTextureAtlas::~CCTextureAtlas()
{
// CCLOGINFO("cocos2d: deallocing CCTextureAtlas.");
CCLOGINFO("cocos2d: CCTextureAtlas deallocing %p."this);
CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices);
glDeleteBuffers(2, m_pBuffersVBO);
glDeleteVertexArrays(1, &m_uVAOname);
#if CC_TEXTURE_ATLAS_USE_VAO
glDeleteVertexArrays(1, &m_uVAOname);
#endif
CC_SAFE_RELEASE(m_pTexture);
}
@ -166,8 +168,13 @@ bool CCTextureAtlas::initWithTexture(CCTexture2D *texture, unsigned int capacity
return false;
}
this->initIndices();
this->initVAO();
this->setupIndices();
#if CC_TEXTURE_ATLAS_USE_VAO
setupVBOandVAO();
#else
setupVBO();
#endif
m_bDirty = true;
@ -185,7 +192,7 @@ const char* CCTextureAtlas::description()
}
void CCTextureAtlas::initIndices()
void CCTextureAtlas::setupIndices()
{
if (m_uCapacity == 0)
return;
@ -200,60 +207,65 @@ void CCTextureAtlas::initIndices()
m_pIndices[i*6+4] = i*4+3;
m_pIndices[i*6+5] = i*4+3;
#else
m_pIndices[i*6+0] = (GLushort)(i*4+0);
m_pIndices[i*6+1] = (GLushort)(i*4+1);
m_pIndices[i*6+2] = (GLushort)(i*4+2);
m_pIndices[i*6+0] = i*4+0;
m_pIndices[i*6+1] = i*4+1;
m_pIndices[i*6+2] = i*4+2;
// inverted index. issue #179
m_pIndices[i*6+3] = (GLushort)(i*4+3);
m_pIndices[i*6+4] = (GLushort)(i*4+2);
m_pIndices[i*6+5] = (GLushort)(i*4+1);
// m_pIndices[i*6+3] = i*4+2;
// m_pIndices[i*6+4] = i*4+3;
// m_pIndices[i*6+5] = i*4+1;
m_pIndices[i*6+3] = i*4+3;
m_pIndices[i*6+4] = i*4+2;
m_pIndices[i*6+5] = i*4+1;
#endif
}
}
void CCTextureAtlas::initVAO()
//TextureAtlas - VAO / VBO specific
#if CC_TEXTURE_ATLAS_USE_VAO
void CCTextureAtlas::setupVBOandVAO()
{
glGenVertexArrays(1, &m_uVAOname);
glBindVertexArray(m_uVAOname);
glGenVertexArrays(1, &m_uVAOname);
glBindVertexArray(m_uVAOname);
#define kQuadSize sizeof(m_pQuads[0].bl)
glGenBuffers(2, &m_pBuffersVBO[0]);
glGenBuffers(2, &m_pBuffersVBO[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW);
// vertices
glEnableVertexAttribArray(kCCVertexAttrib_Position);
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices));
// vertices
glEnableVertexAttribArray(kCCVertexAttrib_Position);
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices));
// colors
glEnableVertexAttribArray(kCCVertexAttrib_Color);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors));
// colors
glEnableVertexAttribArray(kCCVertexAttrib_Color);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors));
// tex coords
glEnableVertexAttribArray(kCCVertexAttrib_TexCoords);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords));
// tex coords
glEnableVertexAttribArray(kCCVertexAttrib_TexCoords);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERROR_DEBUG();
CHECK_GL_ERROR_DEBUG();
}
#else // CC_TEXTURE_ATLAS_USE_VAO
void setupVBO()
{
glGenBuffers(2, &m_pBuffersVBO[0]);
mapBuffers();
}
#endif // ! // CC_TEXTURE_ATLAS_USE_VAO
void CCTextureAtlas::mapBuffers()
{
initIndices();
initVAO();
{
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@ -447,12 +459,8 @@ bool CCTextureAtlas::resizeCapacity(unsigned int newCapacity)
m_pIndices = (GLushort *)tmpIndices;
glDeleteBuffers(2, m_pBuffersVBO);
glDeleteVertexArrays(1, &m_uVAOname);
// initial binding
glGenBuffers(2, &m_pBuffersVBO[0]);
this->mapBuffers();
setupIndices();
mapBuffers();
m_bDirty = true;
@ -529,6 +537,12 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start)
if (0 == n) return;
ccGLBindTexture2D( m_pTexture->getName() );
#if CC_TEXTURE_ATLAS_USE_VAO
//
// Using VBO and VAO
//
// XXX: update is done in draw... perhaps it should be done in a timer
if (m_bDirty) {
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
@ -554,8 +568,50 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start)
glBindVertexArray(0);
#else // ! CC_TEXTURE_ATLAS_USE_VAO
//
// Using VBO without VAO
//
#define kQuadSize sizeof(m_pQuads[0].bl)
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
// XXX: update is done in draw... perhaps it should be done in a timer
if (m_bDirty) {
glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] );
m_bDirty = false;
}
ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex );
// vertices
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices));
// colors
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors));
// tex coords
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#else
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif // CC_TEXTURE_ATLAS_USE_VAO
CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG();
}
}//namespace cocos2d
NS_CC_END