issue #1094: Make ParticleBatchNode works on win32.

This commit is contained in:
James Chen 2012-04-07 12:02:40 +08:00
parent df58a09255
commit 64665fe7c8
8 changed files with 220 additions and 155 deletions

View File

@ -220,6 +220,7 @@ void CCDictionary::removeAllObjects()
CCObject* CCDictionary::copyWithZone(CCZone* pZone) CCObject* CCDictionary::copyWithZone(CCZone* pZone)
{ {
CCAssert(pZone == NULL, "CCDirctionary should not be inherited.");
CCDictionary* pNewDict = new CCDictionary(); CCDictionary* pNewDict = new CCDictionary();
CCDictElement* pElement = NULL; CCDictElement* pElement = NULL;
@ -227,14 +228,14 @@ CCObject* CCDictionary::copyWithZone(CCZone* pZone)
{ {
CCDICT_FOREACH(this, pElement) CCDICT_FOREACH(this, pElement)
{ {
pNewDict->setObject(pElement->getObject(), pElement->getIntKey()); pNewDict->setObject(pElement->getObject()->copy(), pElement->getIntKey());
} }
} }
else if (m_eDictType == kCCDictStr) else if (m_eDictType == kCCDictStr)
{ {
CCDICT_FOREACH(this, pElement) CCDICT_FOREACH(this, pElement)
{ {
pNewDict->setObject(pElement->getObject(), pElement->getStrKey()); pNewDict->setObject(pElement->getObject()->copy(), pElement->getStrKey());
} }
} }

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
#include "ccMacros.h" #include "ccMacros.h"
#include "CCScriptSupport.h" #include "CCScriptSupport.h"
namespace cocos2d { NS_CC_BEGIN
CCObject* CCCopying::copyWithZone(CCZone *pZone) CCObject* CCCopying::copyWithZone(CCZone *pZone)
{ {
@ -111,4 +111,4 @@ bool CCObject::isEqual(const CCObject *pObject)
return this == pObject; return this == pObject;
} }
}//namespace cocos2d NS_CC_END

View File

@ -31,84 +31,86 @@ THE SOFTWARE.
#include "ccMacros.h" #include "ccMacros.h"
#include <string> #include <string>
#include "kazmath/mat4.h" #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 NS_CC_BEGIN
position attributes, then they will override 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. 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) IMPORTANT: Either your use the camera or the rotation/scale/position properties. You can't use both.
using the camera. 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.
*/ - It doesn't work on batched nodes like CCSprite objects when they are parented to a CCSpriteBatchNode object.
class CC_DLL CCCamera : public CCObject
{
protected:
float m_fEyeX;
float m_fEyeY;
float m_fEyeZ;
float m_fCenterX; - 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_fCenterY;
float m_fCenterZ;
float m_fUpX; */
float m_fUpY; class CC_DLL CCCamera : public CCObject
float m_fUpZ; {
protected:
float m_fEyeX;
float m_fEyeY;
float m_fEyeZ;
bool m_bDirty; float m_fCenterX;
kmMat4 m_lookupMatrix; float m_fCenterY;
public: float m_fCenterZ;
CCCamera(void);
~CCCamera(void);
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 */ void init(void);
inline void setDirty(bool bValue) { m_bDirty = bValue; }
/** get the dirty value */
inline bool getDirty(void) { return m_bDirty; }
/** sets the camera in the default position */ char * description(void);
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);
/** get the eye vector values in points */ /** sets the dirty value */
void getEyeXYZ(float *pEyeX, float *pEyeY, float *pEyeZ); inline void setDirty(bool bValue) { m_bDirty = bValue; }
/** get the center vector values int points */ /** get the dirty value */
void getCenterXYZ(float *pCenterX, float *pCenterY, float *pCenterZ); inline bool getDirty(void) { return m_bDirty; }
/** get the up vector values */
void getUpXYZ(float *pUpX, float *pUpY, float *pUpZ);
public:
/** returns the Z eye */
static float getZEye();
private: /** sets the camera in the default position */
DISALLOW_COPY_AND_ASSIGN(CCCamera); 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__ #endif // __CCCAMERA_H__

View File

@ -28,7 +28,8 @@ THE SOFTWARE.
#include "CCCommon.h" #include "CCCommon.h"
#include "ccTypes.h" #include "ccTypes.h"
namespace cocos2d { NS_CC_BEGIN
class CCZone; class CCZone;
class CCObject; class CCObject;
class CCString; class CCString;
@ -87,7 +88,6 @@ typedef void (CCObject::*SEL_EventHandler)(CCEvent*);
#define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR) #define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR)
#define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR) #define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR)
NS_CC_END
}//namespace cocos2d
#endif // __COCOA_NSOBJECT_H__ #endif // __COCOA_NSOBJECT_H__

View File

@ -23,87 +23,105 @@ THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#ifndef __CCSTRING_H__ #ifndef __CCSTRING_H__
#define __CCSTRING_H__ #define __CCSTRING_H__
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
#include "CCObject.h" #include "CCObject.h"
#include "CCFileUtils.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: m_sString = str;
std::string m_sString; }
public:
CCString()
:m_sString("")
{}
CCString(const char * str)
{
m_sString = str;
}
virtual ~CCString(){ m_sString.clear(); }
int toInt() virtual ~CCString()
{ {
return atoi(m_sString.c_str()); m_sString.clear();
} }
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;
}
const char* c_str() int toInt()
{ {
return m_sString.c_str(); return atoi(m_sString.c_str());
} }
bool isEmpty() unsigned int toUInt()
{ {
return m_sString.empty(); 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<const CCString*>(pObject);
if (pStr != NULL)
{ {
bool bRet = false; if (0 == m_sString.compare(pStr->m_sString))
const CCString* pStr = dynamic_cast<const CCString*>(pObject);
if (pStr != NULL)
{ {
if (0 == m_sString.compare(pStr->m_sString)) bRet = true;
{
bRet = true;
}
} }
return bRet;
} }
return bRet;
}
/** @brief: Get string from a file. /** @brief: Get string from a file.
* @return: a pointer which needs to be deleted manually by 'delete[]' . * @return: a pointer which needs to be deleted manually by 'delete[]' .
*/ */
static char* stringWithContentsOfFile(const char* pszFileName) 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; CC_BREAK_IF(!pData || size <= 0);
unsigned char* pData = 0; pszRet = new char[size+1];
char* pszRet = 0; pszRet[size] = '\0';
pData = CCFileUtils::getFileData(pszFileName, "rb", &size); memcpy(pszRet, pData, size);
do CC_SAFE_DELETE_ARRAY(pData);
{ } while (false);
CC_BREAK_IF(!pData || size <= 0); return pszRet;
pszRet = new char[size+1]; }
pszRet[size] = '\0'; };
memcpy(pszRet, pData, size);
CC_SAFE_DELETE_ARRAY(pData); NS_CC_END
} while (false);
return pszRet;
}
};
}// namespace cocos2d
#endif //__CCSTRING_H__ #endif //__CCSTRING_H__

View File

@ -301,11 +301,18 @@ void CCParticleSystemQuad::draw()
glBindVertexArray( m_uVAOname ); 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]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
#endif
glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, 0); glDrawElements(GL_TRIANGLES, (GLsizei) m_uParticleIdx*6, GL_UNSIGNED_SHORT, 0);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif
glBindVertexArray( 0 ); glBindVertexArray( 0 );
@ -423,6 +430,10 @@ bool CCParticleSystemQuad::allocMemory()
return false; return false;
} }
memset(m_pQuads, 0, m_uTotalParticles * sizeof(ccV3F_C4B_T2F_Quad));
memset(m_pIndices, 0, m_uTotalParticles * 6 * sizeof(GLushort));
return true; return true;
} }

View File

@ -336,11 +336,14 @@ void CCArray::replaceObjectAtIndex(unsigned int uIndex, CCObject* pObject, bool
CCObject* CCArray::copyWithZone(CCZone* pZone) CCObject* CCArray::copyWithZone(CCZone* pZone)
{ {
CCAssert(pZone == NULL, "CCArray should not be inherited.");
CCArray* pArray = new CCArray(); CCArray* pArray = new CCArray();
pArray->initWithCapacity(this->data->num > 0 ? this->data->num : 1);
if (!(pArray && pArray->initWithArray(this))) CCObject* pObj = NULL;
CCARRAY_FOREACH(this, pObj)
{ {
CC_SAFE_DELETE(pArray); pArray->addObject(pObj->copy());
} }
return pArray; return pArray;
} }

View File

@ -157,7 +157,8 @@ bool CCTextureAtlas::initWithTexture(CCTexture2D *texture, unsigned int capacity
m_pQuads = (ccV3F_C4B_T2F_Quad*)malloc( m_uCapacity * sizeof(ccV3F_C4B_T2F_Quad) ); m_pQuads = (ccV3F_C4B_T2F_Quad*)malloc( m_uCapacity * sizeof(ccV3F_C4B_T2F_Quad) );
m_pIndices = (GLushort *)malloc( m_uCapacity * 6 * sizeof(GLushort) ); 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"); //CCLOG("cocos2d: CCTextureAtlas: not enough memory");
CC_SAFE_FREE(m_pQuads); CC_SAFE_FREE(m_pQuads);
CC_SAFE_FREE(m_pIndices); CC_SAFE_FREE(m_pIndices);
@ -168,6 +169,9 @@ bool CCTextureAtlas::initWithTexture(CCTexture2D *texture, unsigned int capacity
return false; return false;
} }
memset( m_pQuads, 0, m_uCapacity * sizeof(ccV3F_C4B_T2F_Quad) );
memset( m_pIndices, 0, m_uCapacity * 6 * sizeof(GLushort) );
this->setupIndices(); this->setupIndices();
#if CC_TEXTURE_ATLAS_USE_VAO #if CC_TEXTURE_ATLAS_USE_VAO
@ -426,31 +430,49 @@ bool CCTextureAtlas::resizeCapacity(unsigned int newCapacity)
{ {
return true; return true;
} }
unsigned int uOldCapactiy = m_uCapacity;
// update capacity and totolQuads // update capacity and totolQuads
m_uTotalQuads = MIN(m_uTotalQuads, newCapacity); m_uTotalQuads = MIN(m_uTotalQuads, newCapacity);
m_uCapacity = newCapacity; m_uCapacity = newCapacity;
void * tmpQuads = NULL; ccV3F_C4B_T2F_Quad* tmpQuads = NULL;
void * tmpIndices = NULL; GLushort* tmpIndices = NULL;
// when calling initWithTexture(fileName, 0) on bada device, calloc(0, 1) will fail and return 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. // so here must judge whether m_pQuads and m_pIndices is NULL.
if (m_pQuads == 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 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) 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 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) ) { if( ! ( tmpQuads && tmpIndices) ) {
@ -463,8 +485,8 @@ bool CCTextureAtlas::resizeCapacity(unsigned int newCapacity)
return false; return false;
} }
m_pQuads = (ccV3F_C4B_T2F_Quad *)tmpQuads; m_pQuads = tmpQuads;
m_pIndices = (GLushort *)tmpIndices; m_pIndices = tmpIndices;
setupIndices(); setupIndices();
@ -564,15 +586,24 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start)
} }
glBindVertexArray( m_uVAOname ); 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]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
CHECK_GL_ERROR_DEBUG(); #endif
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#else #else
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif
glBindVertexArray(0); glBindVertexArray(0);
#else // ! CC_TEXTURE_ATLAS_USE_VAO #else // ! CC_TEXTURE_ATLAS_USE_VAO
@ -601,8 +632,6 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start)
// tex coords // tex coords
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); 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]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #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])) ); glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif // CC_TEXTURE_ATLAS_USE_VAO #endif // CC_TEXTURE_ATLAS_USE_VAO