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)
{
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());
}
}

View File

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

View File

@ -31,84 +31,86 @@ THE SOFTWARE.
#include "ccMacros.h"
#include <string>
#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__

View File

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

View File

@ -23,87 +23,105 @@ THE SOFTWARE.
****************************************************************************/
#ifndef __CCSTRING_H__
#define __CCSTRING_H__
#include <string>
#include <stdlib.h>
#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<const CCString*>(pObject);
if (pStr != NULL)
{
bool bRet = false;
const CCString* pStr = dynamic_cast<const CCString*>(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__

View File

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

View File

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

View File

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