From 64665fe7c82e6717b84615c39350b081cf561c81 Mon Sep 17 00:00:00 2001 From: James Chen Date: Sat, 7 Apr 2012 12:02:40 +0800 Subject: [PATCH] issue #1094: Make ParticleBatchNode works on win32. --- cocos2dx/cocoa/CCDictionary.cpp | 5 +- cocos2dx/cocoa/CCObject.cpp | 4 +- cocos2dx/include/CCCamera.h | 126 ++++++++------- cocos2dx/include/CCObject.h | 8 +- cocos2dx/include/CCString.h | 152 ++++++++++-------- .../particle_nodes/CCParticleSystemQuad.cpp | 13 +- cocos2dx/support/CCArray.cpp | 11 +- cocos2dx/textures/CCTextureAtlas.cpp | 56 +++++-- 8 files changed, 220 insertions(+), 155 deletions(-) diff --git a/cocos2dx/cocoa/CCDictionary.cpp b/cocos2dx/cocoa/CCDictionary.cpp index 12036a27d9..7c68944273 100644 --- a/cocos2dx/cocoa/CCDictionary.cpp +++ b/cocos2dx/cocoa/CCDictionary.cpp @@ -220,6 +220,7 @@ void CCDictionary::removeAllObjects() CCObject* CCDictionary::copyWithZone(CCZone* pZone) { + CCAssert(pZone == NULL, "CCDirctionary should not be inherited."); CCDictionary* pNewDict = new CCDictionary(); CCDictElement* pElement = NULL; @@ -227,14 +228,14 @@ CCObject* CCDictionary::copyWithZone(CCZone* pZone) { CCDICT_FOREACH(this, pElement) { - pNewDict->setObject(pElement->getObject(), pElement->getIntKey()); + pNewDict->setObject(pElement->getObject()->copy(), pElement->getIntKey()); } } else if (m_eDictType == kCCDictStr) { CCDICT_FOREACH(this, pElement) { - pNewDict->setObject(pElement->getObject(), pElement->getStrKey()); + pNewDict->setObject(pElement->getObject()->copy(), pElement->getStrKey()); } } diff --git a/cocos2dx/cocoa/CCObject.cpp b/cocos2dx/cocoa/CCObject.cpp index de36894444..1aade9d140 100644 --- a/cocos2dx/cocoa/CCObject.cpp +++ b/cocos2dx/cocoa/CCObject.cpp @@ -28,7 +28,7 @@ THE SOFTWARE. #include "ccMacros.h" #include "CCScriptSupport.h" -namespace cocos2d { +NS_CC_BEGIN CCObject* CCCopying::copyWithZone(CCZone *pZone) { @@ -111,4 +111,4 @@ bool CCObject::isEqual(const CCObject *pObject) return this == pObject; } -}//namespace cocos2d +NS_CC_END diff --git a/cocos2dx/include/CCCamera.h b/cocos2dx/include/CCCamera.h index 599fbc05d3..dbd5d4e961 100755 --- a/cocos2dx/include/CCCamera.h +++ b/cocos2dx/include/CCCamera.h @@ -31,84 +31,86 @@ THE SOFTWARE. #include "ccMacros.h" #include #include "kazmath/mat4.h" -namespace cocos2d { - /** - A CCCamera is used in every CCNode. - Useful to look at the object from different views. - The OpenGL gluLookAt() function is used to locate the - camera. - If the object is transformed by any of the scale, rotation or - position attributes, then they will override the camera. +NS_CC_BEGIN - IMPORTANT: Either your use the camera or the rotation/scale/position properties. You can't use both. - World coordinates won't work if you use the camera. +/** +A CCCamera is used in every CCNode. +Useful to look at the object from different views. +The OpenGL gluLookAt() function is used to locate the +camera. - Limitations: +If the object is transformed by any of the scale, rotation or +position attributes, then they will override the camera. - - Some nodes, like CCParallaxNode, CCParticle uses world node coordinates, and they won't work properly if you move them (or any of their ancestors) - using the camera. +IMPORTANT: Either your use the camera or the rotation/scale/position properties. You can't use both. +World coordinates won't work if you use the camera. - - It doesn't work on batched nodes like CCSprite objects when they are parented to a CCSpriteBatchNode object. +Limitations: - - It is recommended to use it ONLY if you are going to create 3D effects. For 2D effecs, use the action CCFollow or position/scale/rotate. +- Some nodes, like CCParallaxNode, CCParticle uses world node coordinates, and they won't work properly if you move them (or any of their ancestors) +using the camera. - */ - class CC_DLL CCCamera : public CCObject - { - protected: - float m_fEyeX; - float m_fEyeY; - float m_fEyeZ; +- It doesn't work on batched nodes like CCSprite objects when they are parented to a CCSpriteBatchNode object. - float m_fCenterX; - float m_fCenterY; - float m_fCenterZ; +- It is recommended to use it ONLY if you are going to create 3D effects. For 2D effecs, use the action CCFollow or position/scale/rotate. - float m_fUpX; - float m_fUpY; - float m_fUpZ; +*/ +class CC_DLL CCCamera : public CCObject +{ +protected: + float m_fEyeX; + float m_fEyeY; + float m_fEyeZ; - bool m_bDirty; - kmMat4 m_lookupMatrix; - public: - CCCamera(void); - ~CCCamera(void); + float m_fCenterX; + float m_fCenterY; + float m_fCenterZ; - void init(void); + float m_fUpX; + float m_fUpY; + float m_fUpZ; - char * description(void); + bool m_bDirty; + kmMat4 m_lookupMatrix; +public: + CCCamera(void); + ~CCCamera(void); - /** sets the dirty value */ - inline void setDirty(bool bValue) { m_bDirty = bValue; } - /** get the dirty value */ - inline bool getDirty(void) { return m_bDirty; } + void init(void); - /** sets the camera in the default position */ - void restore(void); - /** Sets the camera using gluLookAt using its eye, center and up_vector */ - void locate(void); - /** sets the eye values in points */ - void setEyeXYZ(float fEyeX, float fEyeY, float fEyeZ); - /** sets the center values in points */ - void setCenterXYZ(float fCenterX, float fCenterY, float fCenterZ); - /** sets the up values */ - void setUpXYZ(float fUpX, float fUpY, float fUpZ); + char * description(void); - /** get the eye vector values in points */ - void getEyeXYZ(float *pEyeX, float *pEyeY, float *pEyeZ); - /** get the center vector values int points */ - void getCenterXYZ(float *pCenterX, float *pCenterY, float *pCenterZ); - /** get the up vector values */ - void getUpXYZ(float *pUpX, float *pUpY, float *pUpZ); - public: - /** returns the Z eye */ - static float getZEye(); + /** sets the dirty value */ + inline void setDirty(bool bValue) { m_bDirty = bValue; } + /** get the dirty value */ + inline bool getDirty(void) { return m_bDirty; } - private: - DISALLOW_COPY_AND_ASSIGN(CCCamera); - }; + /** sets the camera in the default position */ + void restore(void); + /** Sets the camera using gluLookAt using its eye, center and up_vector */ + void locate(void); + /** sets the eye values in points */ + void setEyeXYZ(float fEyeX, float fEyeY, float fEyeZ); + /** sets the center values in points */ + void setCenterXYZ(float fCenterX, float fCenterY, float fCenterZ); + /** sets the up values */ + void setUpXYZ(float fUpX, float fUpY, float fUpZ); -}//namespace cocos2d + /** get the eye vector values in points */ + void getEyeXYZ(float *pEyeX, float *pEyeY, float *pEyeZ); + /** get the center vector values int points */ + void getCenterXYZ(float *pCenterX, float *pCenterY, float *pCenterZ); + /** get the up vector values */ + void getUpXYZ(float *pUpX, float *pUpY, float *pUpZ); +public: + /** returns the Z eye */ + static float getZEye(); + +private: + DISALLOW_COPY_AND_ASSIGN(CCCamera); +}; + +NS_CC_END #endif // __CCCAMERA_H__ diff --git a/cocos2dx/include/CCObject.h b/cocos2dx/include/CCObject.h index e65b533f2f..9d59d9375c 100755 --- a/cocos2dx/include/CCObject.h +++ b/cocos2dx/include/CCObject.h @@ -28,7 +28,8 @@ THE SOFTWARE. #include "CCCommon.h" #include "ccTypes.h" -namespace cocos2d { +NS_CC_BEGIN + class CCZone; class CCObject; class CCString; @@ -86,8 +87,7 @@ typedef void (CCObject::*SEL_EventHandler)(CCEvent*); #define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR) #define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR) #define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR) - - -}//namespace cocos2d + +NS_CC_END #endif // __COCOA_NSOBJECT_H__ diff --git a/cocos2dx/include/CCString.h b/cocos2dx/include/CCString.h index ee04d17f8e..9ee58daeaa 100755 --- a/cocos2dx/include/CCString.h +++ b/cocos2dx/include/CCString.h @@ -23,87 +23,105 @@ THE SOFTWARE. ****************************************************************************/ #ifndef __CCSTRING_H__ #define __CCSTRING_H__ + #include #include #include "CCObject.h" #include "CCFileUtils.h" -namespace cocos2d { +NS_CC_BEGIN - class CC_DLL CCString : public CCObject +class CC_DLL CCString : public CCObject +{ +public: + std::string m_sString; +public: + CCString() + :m_sString("") + {} + + CCString(const char * str) { - public: - std::string m_sString; - public: - CCString() - :m_sString("") - {} - CCString(const char * str) - { - m_sString = str; - } - virtual ~CCString(){ m_sString.clear(); } - - int toInt() - { - return atoi(m_sString.c_str()); - } - unsigned int toUInt() - { - return (unsigned int)atoi(m_sString.c_str()); - } - float toFloat() - { - return (float)atof(m_sString.c_str()); - } - std::string toStdString() - { - return m_sString; - } + m_sString = str; + } - const char* c_str() - { - return m_sString.c_str(); - } + virtual ~CCString() + { + m_sString.clear(); + } + + int toInt() + { + return atoi(m_sString.c_str()); + } - bool isEmpty() - { - return m_sString.empty(); - } + unsigned int toUInt() + { + return (unsigned int)atoi(m_sString.c_str()); + } - virtual bool isEqual(const CCObject* pObject) + float toFloat() + { + return (float)atof(m_sString.c_str()); + } + + std::string toStdString() + { + return m_sString; + } + + const char* c_str() + { + return m_sString.c_str(); + } + + bool isEmpty() + { + return m_sString.empty(); + } + + virtual CCObject* copyWithZone(CCZone* pZone) + { + CCAssert(pZone == NULL, "CCString should not be inherited."); + CCString* pStr = new CCString(m_sString.c_str()); + return pStr; + } + + virtual bool isEqual(const CCObject* pObject) + { + bool bRet = false; + const CCString* pStr = dynamic_cast(pObject); + if (pStr != NULL) { - bool bRet = false; - const CCString* pStr = dynamic_cast(pObject); - if (pStr != NULL) + if (0 == m_sString.compare(pStr->m_sString)) { - if (0 == m_sString.compare(pStr->m_sString)) - { - bRet = true; - } + bRet = true; } - return bRet; } + return bRet; + } - /** @brief: Get string from a file. - * @return: a pointer which needs to be deleted manually by 'delete[]' . - */ - static char* stringWithContentsOfFile(const char* pszFileName) + /** @brief: Get string from a file. + * @return: a pointer which needs to be deleted manually by 'delete[]' . + */ + static char* stringWithContentsOfFile(const char* pszFileName) + { + unsigned long size = 0; + unsigned char* pData = 0; + char* pszRet = 0; + pData = CCFileUtils::getFileData(pszFileName, "rb", &size); + do { - unsigned long size = 0; - unsigned char* pData = 0; - char* pszRet = 0; - pData = CCFileUtils::getFileData(pszFileName, "rb", &size); - do - { - CC_BREAK_IF(!pData || size <= 0); - pszRet = new char[size+1]; - pszRet[size] = '\0'; - memcpy(pszRet, pData, size); - CC_SAFE_DELETE_ARRAY(pData); - } while (false); - return pszRet; - } - }; -}// namespace cocos2d + CC_BREAK_IF(!pData || size <= 0); + pszRet = new char[size+1]; + pszRet[size] = '\0'; + memcpy(pszRet, pData, size); + CC_SAFE_DELETE_ARRAY(pData); + } while (false); + return pszRet; + } +}; + +NS_CC_END + #endif //__CCSTRING_H__ \ No newline at end of file diff --git a/cocos2dx/particle_nodes/CCParticleSystemQuad.cpp b/cocos2dx/particle_nodes/CCParticleSystemQuad.cpp index 1cedd5dc54..e4a472c5e0 100644 --- a/cocos2dx/particle_nodes/CCParticleSystemQuad.cpp +++ b/cocos2dx/particle_nodes/CCParticleSystemQuad.cpp @@ -301,11 +301,18 @@ void CCParticleSystemQuad::draw() glBindVertexArray( m_uVAOname ); + /* Application will crash in glDrawElements function on some win32 computers which use Integrated Graphics. + Indices should be bound again to avoid this bug. + */ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); +#endif glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, 0); +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +#endif glBindVertexArray( 0 ); @@ -414,7 +421,7 @@ bool CCParticleSystemQuad::allocMemory() m_pQuads = (ccV3F_C4B_T2F_Quad*)malloc(m_uTotalParticles * sizeof(ccV3F_C4B_T2F_Quad)); m_pIndices = (GLushort*)malloc(m_uTotalParticles * 6 * sizeof(GLushort)); - + if( !m_pQuads || !m_pIndices) { CCLOG("cocos2d: Particle system: not enough memory"); @@ -423,6 +430,10 @@ bool CCParticleSystemQuad::allocMemory() return false; } + + memset(m_pQuads, 0, m_uTotalParticles * sizeof(ccV3F_C4B_T2F_Quad)); + memset(m_pIndices, 0, m_uTotalParticles * 6 * sizeof(GLushort)); + return true; } diff --git a/cocos2dx/support/CCArray.cpp b/cocos2dx/support/CCArray.cpp index 7b5ef42648..2dcaa76f16 100644 --- a/cocos2dx/support/CCArray.cpp +++ b/cocos2dx/support/CCArray.cpp @@ -336,12 +336,15 @@ void CCArray::replaceObjectAtIndex(unsigned int uIndex, CCObject* pObject, bool CCObject* CCArray::copyWithZone(CCZone* pZone) { + CCAssert(pZone == NULL, "CCArray should not be inherited."); CCArray* pArray = new CCArray(); + pArray->initWithCapacity(this->data->num > 0 ? this->data->num : 1); - if (!(pArray && pArray->initWithArray(this))) - { - CC_SAFE_DELETE(pArray); - } + CCObject* pObj = NULL; + CCARRAY_FOREACH(this, pObj) + { + pArray->addObject(pObj->copy()); + } return pArray; } diff --git a/cocos2dx/textures/CCTextureAtlas.cpp b/cocos2dx/textures/CCTextureAtlas.cpp index 7670499cdb..3430cfaf2d 100644 --- a/cocos2dx/textures/CCTextureAtlas.cpp +++ b/cocos2dx/textures/CCTextureAtlas.cpp @@ -156,8 +156,9 @@ bool CCTextureAtlas::initWithTexture(CCTexture2D *texture, unsigned int capacity m_pQuads = (ccV3F_C4B_T2F_Quad*)malloc( m_uCapacity * sizeof(ccV3F_C4B_T2F_Quad) ); m_pIndices = (GLushort *)malloc( m_uCapacity * 6 * sizeof(GLushort) ); - - if( ! ( m_pQuads && m_pIndices) && m_uCapacity > 0) { + + if( ! ( m_pQuads && m_pIndices) && m_uCapacity > 0) + { //CCLOG("cocos2d: CCTextureAtlas: not enough memory"); CC_SAFE_FREE(m_pQuads); CC_SAFE_FREE(m_pIndices); @@ -168,6 +169,9 @@ bool CCTextureAtlas::initWithTexture(CCTexture2D *texture, unsigned int capacity return false; } + memset( m_pQuads, 0, m_uCapacity * sizeof(ccV3F_C4B_T2F_Quad) ); + memset( m_pIndices, 0, m_uCapacity * 6 * sizeof(GLushort) ); + this->setupIndices(); #if CC_TEXTURE_ATLAS_USE_VAO @@ -426,31 +430,49 @@ bool CCTextureAtlas::resizeCapacity(unsigned int newCapacity) { return true; } + unsigned int uOldCapactiy = m_uCapacity; // update capacity and totolQuads m_uTotalQuads = MIN(m_uTotalQuads, newCapacity); m_uCapacity = newCapacity; - void * tmpQuads = NULL; - void * tmpIndices = NULL; + ccV3F_C4B_T2F_Quad* tmpQuads = NULL; + GLushort* tmpIndices = NULL; // when calling initWithTexture(fileName, 0) on bada device, calloc(0, 1) will fail and return NULL, // so here must judge whether m_pQuads and m_pIndices is NULL. if (m_pQuads == NULL) { - tmpQuads = malloc(m_uCapacity * sizeof(m_pQuads[0])); + tmpQuads = (ccV3F_C4B_T2F_Quad*)malloc( m_uCapacity * sizeof(m_pQuads[0]) ); + if (tmpQuads != NULL) + { + memset(tmpQuads, 0, m_uCapacity * sizeof(m_pQuads[0]) ); + } } else { - tmpQuads = realloc( m_pQuads, sizeof(m_pQuads[0]) * m_uCapacity ); + tmpQuads = (ccV3F_C4B_T2F_Quad*)realloc( m_pQuads, sizeof(m_pQuads[0]) * m_uCapacity ); + if (tmpQuads != NULL && m_uCapacity > uOldCapactiy) + { + memset(tmpQuads+uOldCapactiy, 0, (m_uCapacity - uOldCapactiy)*sizeof(m_pQuads[0]) ); + } } if (m_pIndices == NULL) { - tmpIndices = malloc( m_uCapacity * 6 * sizeof(m_pIndices[0])); + tmpIndices = (GLushort*)malloc( m_uCapacity * 6 * sizeof(m_pIndices[0]) ); + if (tmpIndices != NULL) + { + memset( tmpIndices, 0, m_uCapacity * 6 * sizeof(m_pIndices[0]) ); + } + } else { - tmpIndices = realloc( m_pIndices, sizeof(m_pIndices[0]) * m_uCapacity * 6 ); + tmpIndices = (GLushort*)realloc( m_pIndices, sizeof(m_pIndices[0]) * m_uCapacity * 6 ); + if (tmpIndices != NULL && m_uCapacity > uOldCapactiy) + { + memset( tmpIndices+uOldCapactiy, 0, (m_uCapacity-uOldCapactiy) * 6 * sizeof(m_pIndices[0]) ); + } } if( ! ( tmpQuads && tmpIndices) ) { @@ -463,8 +485,8 @@ bool CCTextureAtlas::resizeCapacity(unsigned int newCapacity) return false; } - m_pQuads = (ccV3F_C4B_T2F_Quad *)tmpQuads; - m_pIndices = (GLushort *)tmpIndices; + m_pQuads = tmpQuads; + m_pIndices = tmpIndices; setupIndices(); @@ -564,15 +586,24 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start) } glBindVertexArray( m_uVAOname ); + + /* Application will crash in glDrawElements function on some win32 computers which use Integrated Graphics. + Indices should be bound again to avoid this bug. + */ +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); - CHECK_GL_ERROR_DEBUG(); +#endif + #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 +#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +#endif + glBindVertexArray(0); #else // ! CC_TEXTURE_ATLAS_USE_VAO @@ -601,8 +632,6 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start) // 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 @@ -611,6 +640,7 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start) 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_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #endif // CC_TEXTURE_ATLAS_USE_VAO