diff --git a/cocos2dx/include/CCMotionStreak.h b/cocos2dx/include/CCMotionStreak.h index 60551b5c2f..039d7f2237 100644 --- a/cocos2dx/include/CCMotionStreak.h +++ b/cocos2dx/include/CCMotionStreak.h @@ -23,50 +23,54 @@ THE SOFTWARE. ****************************************************************************/ #ifndef __CCMOTION_STREAK_H__ #define __CCMOTION_STREAK_H__ + #include "CCNode.h" #include "CCProtocols.h" + namespace cocos2d { - class CCRibbon; - /** - * @brief CCMotionStreak manages a Ribbon based on it's motion in absolute space. - * You construct it with a fadeTime, minimum segment size, texture path, texture - * length and color. The fadeTime controls how long it takes each vertex in - * the streak to fade out, the minimum segment size it how many pixels the - * streak will move before adding a new ribbon segement, and the texture - * length is the how many pixels the texture is stretched across. The texture - * is vertically aligned along the streak segemnts. - * - * Limitations: - * CCMotionStreak, by default, will use the GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA blending function. - * This blending function might not be the correct one for certain textures. - * But you can change it by using: - * [obj setBlendFunc: (ccBlendfunc) {new_src_blend_func, new_dst_blend_func}]; - * - * @since v0.8.1 - */ - class CCX_DLL CCMotionStreak : public CCNode, public CCTextureProtocol - { - /** Ribbon used by MotionStreak (weak reference) */ - CCX_PROPERTY_READONLY(CCRibbon*, m_pRibbon, Ribbon) - //CCTextureProtocol methods - CCX_PROPERTY(CCTexture2D*, m_pTexture, Texture) - CCX_PROPERTY(ccBlendFunc, m_tBlendFunc, BlendFunc) - public: - CCMotionStreak(){} - virtual ~CCMotionStreak(){} - /** creates the a MotionStreak. The image will be loaded using the TextureMgr. */ - static CCMotionStreak * streakWithFade(float fade, float seg, const char *imagePath, float width, float length, ccColor4B color); + +class CCRibbon; +/** +* @brief CCMotionStreak manages a Ribbon based on it's motion in absolute space. +* You construct it with a fadeTime, minimum segment size, texture path, texture +* length and color. The fadeTime controls how long it takes each vertex in +* the streak to fade out, the minimum segment size it how many pixels the +* streak will move before adding a new ribbon segement, and the texture +* length is the how many pixels the texture is stretched across. The texture +* is vertically aligned along the streak segemnts. +* +* Limitations: +* CCMotionStreak, by default, will use the GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA blending function. +* This blending function might not be the correct one for certain textures. +* But you can change it by using: +* [obj setBlendFunc: (ccBlendfunc) {new_src_blend_func, new_dst_blend_func}]; +* +* @since v0.8.1 +*/ +class CCX_DLL CCMotionStreak : public CCNode, public CCTextureProtocol +{ + /** Ribbon used by MotionStreak (weak reference) */ + CCX_PROPERTY_READONLY(CCRibbon*, m_pRibbon, Ribbon) + //CCTextureProtocol methods + CCX_PROPERTY(CCTexture2D*, m_pTexture, Texture) + CCX_PROPERTY(ccBlendFunc, m_tBlendFunc, BlendFunc) +public: + CCMotionStreak(){} + virtual ~CCMotionStreak(){} + /** creates the a MotionStreak. The image will be loaded using the TextureMgr. */ + static CCMotionStreak * streakWithFade(float fade, float seg, const char *imagePath, float width, float length, ccColor4B color); - /** initializes a MotionStreak. The file will be loaded using the TextureMgr. */ - bool initWithFade(float fade, float seg, const char *imagePath, float width, float length, ccColor4B color); + /** initializes a MotionStreak. The file will be loaded using the TextureMgr. */ + bool initWithFade(float fade, float seg, const char *imagePath, float width, float length, ccColor4B color); - /** polling function */ - void update(ccTime delta); - protected: - float m_fSegThreshold; - float m_fWidth; - CGPoint m_tLastLocation; - }; + /** polling function */ + void update(ccTime delta); +protected: + float m_fSegThreshold; + float m_fWidth; + CGPoint m_tLastLocation; +}; + } // namespace cocos2d -#endif //__CCMOTION_STREAK_H__ \ No newline at end of file +#endif //__CCMOTION_STREAK_H__ diff --git a/cocos2dx/include/CCProgressTimer.h b/cocos2dx/include/CCProgressTimer.h index c034282396..59ed2bfa67 100644 --- a/cocos2dx/include/CCProgressTimer.h +++ b/cocos2dx/include/CCProgressTimer.h @@ -80,7 +80,7 @@ public: static CCProgressTimer* progressWithTexture(CCTexture2D *pTexture); protected: - CGPoint vertexFromTexCoord(CGPoint texCoord); + ccVertex2F vertexFromTexCoord(CGPoint texCoord); void updateProgress(void); void updateBar(void); void updateRadial(void); diff --git a/cocos2dx/include/CCRenderTexture.h b/cocos2dx/include/CCRenderTexture.h index 8a5ea36197..1a94ad1069 100644 --- a/cocos2dx/include/CCRenderTexture.h +++ b/cocos2dx/include/CCRenderTexture.h @@ -24,50 +24,81 @@ THE SOFTWARE. #ifndef __CCRENDER_TEXTURE_H__ #define __CCRENDER_TEXTURE_H__ +#include "NSData.h" #include "CCNode.h" #include "CCSprite.h" namespace cocos2d { - enum tImageFormat - { - kImageFormatJPG = 0, - kImageFormatPNG = 1 - }; - /** - @brief RenderTexture is a generic rendering target. To render things into it, - simply construct a render target, call begin on it, call visit on any cocos - scenes or objects to render them, and call end. For convienience, render texture - adds a sprite as it's display child with the results, so you can simply add - the render texture to your scene and treat it like any other CocosNode. - There are also functions for saving the render texture to disk in PNG or JPG format. + +enum eImageFormat +{ + kCCImageFormatJPG = 0, + kCCImageFormatPNG = 1, + kCCImageFormatRawData = 2 +}; +/** +@brief CCRenderTexture is a generic rendering target. To render things into it, +simply construct a render target, call begin on it, call visit on any cocos +scenes or objects to render them, and call end. For convienience, render texture +adds a sprite as it's display child with the results, so you can simply add +the render texture to your scene and treat it like any other CocosNode. +There are also functions for saving the render texture to disk in PNG or JPG format. - @since v0.8.1 - */ - class CCX_DLL CCRenderTexture : public CCNode - { - /** sprite being used */ - CCX_PROPERTY(CCSprite*, m_pSprite, Sprite) - public: - CCRenderTexture(){} - virtual ~CCRenderTexture(); - /** creates a RenderTexture object with width and height */ - static CCRenderTexture *renderTextureWithWidthAndHeight(int width, int height); - /** initializes a RenderTexture object with width and height */ - bool initWithWidthAndHeight(int width, int height); - void begin(); - void end(); - /** get buffer as UIImage */ - UIImage *getUIImageFromBuffer(); - /** saves the texture into a file */ - bool saveBuffer(const char *name); - /** saves the texture into a file. The format can be JPG or PNG */ - bool saveBuffer(const char *name, int format); - /** clears the texture with a color */ - void clear(float r, float g, float b, float a); - protected: - GLuint m_uFBO; - GLint m_nOldFBO; - CCTexture2D* m_pTexture; - }; +@since v0.8.1 +*/ +class CCX_DLL CCRenderTexture : public CCNode +{ + /** The CCSprite being used. + The sprite, by default, will use the following blending function: GL_ONE, GL_ONE_MINUS_SRC_ALPHA. + The blending function can be changed in runtime by calling: + - [[renderTexture sprite] setBlendFunc:(ccBlendFunc){GL_ONE, GL_ONE_MINUS_SRC_ALPHA}]; + */ + CCX_PROPERTY(CCSprite*, m_pSprite, Sprite) +public: + CCRenderTexture(){} + virtual ~CCRenderTexture(); + /** creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid */ + static CCRenderTexture * renderTextureWithWidthAndHeight(int w, int h, CCTexture2DPixelFormat eFormat); + + /** creates a RenderTexture object with width and height in Points, pixel format is RGBA8888 */ + static CCRenderTexture * renderTextureWithWidthAndHeight(int w, int h); + + /** initializes a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid */ + bool initWithWidthAndHeight(int w, int h, CCTexture2DPixelFormat eFormat); + + /** starts grabbing */ + void begin(); + + /** starts rendering to the texture while clearing the texture first. + This is more efficient then calling -clear first and then -begin */ + void beginWithClear(float r, float g, float b, float a); + + /** ends grabbing */ + void end(); + + /** clears the texture with a color */ + void clear(float r, float g, float b, float a); + + /** saves the texture into a file */ + bool saveBuffer(const char *name); + /** saves the texture into a file. The format can be JPG or PNG */ + bool saveBuffer(const char *name, int format); + + /* get buffer as UIImage, can only save a render buffer which has a RGBA8888 pixel format */ + NSData *getUIImageAsDataFromBuffer(int format); +protected: + GLuint m_uFBO; + GLint m_nOldFBO; + CCTexture2D* m_pTexture; + + GLenum m_ePixelFormat; + GLfloat m_aClearColor[4]; + +private: + void saveGLstate(); + void restoreGLstate(); +}; + } // namespace cocos2d + #endif //__CCRENDER_TEXTURE_H__ \ No newline at end of file diff --git a/cocos2dx/include/CCRibbon.h b/cocos2dx/include/CCRibbon.h index 7a043c39ec..67c62b7041 100644 --- a/cocos2dx/include/CCRibbon.h +++ b/cocos2dx/include/CCRibbon.h @@ -23,89 +23,96 @@ THE SOFTWARE. ****************************************************************************/ #ifndef __CCRIBBON_H__ #define __CCRIBBON_H__ + /*#include */ #include "CCNode.h" #include "CCProtocols.h" + namespace cocos2d { - class CCRibbonSegment; - /** - * @brief A CCRibbon is a dynamically generated list of polygons drawn as a single or series - * of triangle strips. The primary use of CCRibbon is as the drawing class of Motion Streak, - * but it is quite useful on it's own. When manually drawing a ribbon, you can call addPointAt - * and pass in the parameters for the next location in the ribbon. The system will automatically - * generate new polygons, texture them accourding to your texture width, etc, etc. - * - * CCRibbon data is stored in a CCRibbonSegment class. This class statically allocates enough verticies and - * texture coordinates for 50 locations (100 verts or 48 triangles). The ribbon class will allocate - * new segments when they are needed, and reuse old ones if available. The idea is to avoid constantly - * allocating new memory and prefer a more static method. However, since there is no way to determine - * the maximum size of some ribbons (motion streaks), a truely static allocation is not possible. - * - * @since v0.8.1 - */ - class CCX_DLL CCRibbon : public CCNode, public CCTextureProtocol - { - /** Texture used by the ribbon. Conforms to CCTextureProtocol protocol */ - CCX_PROPERTY(CCTexture2D*, m_pTexture, Texture) - /** Texture lenghts in pixels */ - CCX_PROPERTY(float, m_fTextureLength, TextureLength) - /** GL blendind function */ - CCX_PROPERTY(ccBlendFunc, m_tBlendFunc, BlendFunc) - /** color used by the Ribbon (RGBA) */ - CCX_PROPERTY(ccColor4B, m_tColor, Color) - public: - CCRibbon(){} - virtual ~CCRibbon(); - /** creates the ribbon */ - static CCRibbon * ribbonWithWidth(float w, const char *path, float length, ccColor4B color, float fade); - /** init the ribbon */ - bool initWithWidth(float w, const char *path, float length, ccColor4B color, float fade); - /** add a point to the ribbon */ - void addPointAt(CGPoint location, float width); - /** polling function */ - void update(ccTime delta); - /** determine side of line */ - float sideOfLine(CGPoint p, CGPoint l1, CGPoint l2); - // super method - virtual void draw(); - private: - /** rotates a point around 0, 0 */ - CGPoint rotatePoint(CGPoint vec, float rotation); - protected: - NSMutableArray *m_pSegments; - NSMutableArray *m_pDeletedSegments; + +class CCRibbonSegment; +/** +* @brief A CCRibbon is a dynamically generated list of polygons drawn as a single or series +* of triangle strips. The primary use of CCRibbon is as the drawing class of Motion Streak, +* but it is quite useful on it's own. When manually drawing a ribbon, you can call addPointAt +* and pass in the parameters for the next location in the ribbon. The system will automatically +* generate new polygons, texture them accourding to your texture width, etc, etc. +* +* CCRibbon data is stored in a CCRibbonSegment class. This class statically allocates enough verticies and +* texture coordinates for 50 locations (100 verts or 48 triangles). The ribbon class will allocate +* new segments when they are needed, and reuse old ones if available. The idea is to avoid constantly +* allocating new memory and prefer a more static method. However, since there is no way to determine +* the maximum size of some ribbons (motion streaks), a truely static allocation is not possible. +* +* @since v0.8.1 +*/ +class CCX_DLL CCRibbon : public CCNode, public CCTextureProtocol +{ + /** Texture used by the ribbon. Conforms to CCTextureProtocol protocol */ + CCX_PROPERTY(CCTexture2D*, m_pTexture, Texture) + /** Texture lengths in pixels */ + CCX_PROPERTY(float, m_fTextureLength, TextureLength) + /** GL blendind function */ + CCX_PROPERTY(ccBlendFunc, m_tBlendFunc, BlendFunc) + /** color used by the Ribbon (RGBA) */ + CCX_PROPERTY(ccColor4B, m_tColor, Color) + +public: + CCRibbon() : m_pTexture(0), m_pSegments(0), m_pDeletedSegments(0){} + virtual ~CCRibbon(); + + /** creates the ribbon */ + static CCRibbon * ribbonWithWidth(float w, const char *path, float length, ccColor4B color, float fade); + /** init the ribbon */ + bool initWithWidth(float w, const char *path, float length, ccColor4B color, float fade); + /** add a point to the ribbon */ + void addPointAt(CGPoint location, float width); + /** polling function */ + void update(ccTime delta); + /** determine side of line */ + float sideOfLine(CGPoint p, CGPoint l1, CGPoint l2); + // super method + virtual void draw(); +private: + /** rotates a point around 0, 0 */ + CGPoint rotatePoint(CGPoint vec, float rotation); +protected: + NSMutableArray *m_pSegments; + NSMutableArray *m_pDeletedSegments; - CGPoint m_tLastPoint1; - CGPoint m_tLastPoint2; - CGPoint m_tLastLocation; - int m_nVertCount_; - float m_fTexVPos; - float m_fCurTime; - float m_fFadeTime; - float m_fDelta; - float m_fLastWidth; - float m_fLastSign; - bool m_bPastFirstPoint; - }; + CGPoint m_tLastPoint1; + CGPoint m_tLastPoint2; + CGPoint m_tLastLocation; +// int m_nVertCount_; + float m_fTexVPos; + float m_fCurTime; + float m_fFadeTime; + float m_fDelta; + float m_fLastWidth; + float m_fLastSign; + bool m_bPastFirstPoint; +}; - /** @brief object to hold ribbon segment data */ - class CCX_DLL CCRibbonSegment : public NSObject - { - public: - GLfloat m_pVerts[50*6]; - GLfloat m_pCoords[50*4]; - GLubyte m_pColors[50*8]; - float m_pCreationTime[50]; - bool m_bFinished; - unsigned int m_uEnd; - unsigned int m_uBegin; - public: - CCRibbonSegment(){} - virtual ~CCRibbonSegment(); - char * description(); - bool init(); - void reset(); - void draw(float curTime, float fadeTime, ccColor4B color); - }; +/** @brief object to hold ribbon segment data */ +class CCX_DLL CCRibbonSegment : public NSObject +{ +public: + GLfloat m_pVerts[50*6]; + GLfloat m_pCoords[50*4]; + GLubyte m_pColors[50*8]; + float m_pCreationTime[50]; + bool m_bFinished; + unsigned int m_uEnd; + unsigned int m_uBegin; +public: + CCRibbonSegment(){} + virtual ~CCRibbonSegment(); + char * description(); + bool init(); + void reset(); + void draw(float curTime, float fadeTime, ccColor4B color); +}; + } // namespace cocos2d + #endif //__CCRIBBON_H__ \ No newline at end of file diff --git a/cocos2dx/misc_nodes/CCMotionStreak.cpp b/cocos2dx/misc_nodes/CCMotionStreak.cpp index 5b818c3580..c5379df8ac 100644 --- a/cocos2dx/misc_nodes/CCMotionStreak.cpp +++ b/cocos2dx/misc_nodes/CCMotionStreak.cpp @@ -25,74 +25,81 @@ THE SOFTWARE. #include "CGPointExtension.h" #include "CCRibbon.h" namespace cocos2d { - /* - * Motion Streak manages a Ribbon based on it's motion in absolute space. - * You construct it with a fadeTime, minimum segment size, texture path, texture - * length and color. The fadeTime controls how long it takes each vertex in - * the streak to fade out, the minimum segment size it how many pixels the - * streak will move before adding a new ribbon segement, and the texture - * length is the how many pixels the texture is stretched across. The texture - * is vertically aligned along the streak segemnts. - */ - //implementation CCMotionStreak - - CCMotionStreak * CCMotionStreak::streakWithFade(float fade, float seg, const char *imagePath, float width, float length, ccColor4B color) - { - CCMotionStreak *pRet = new CCMotionStreak(); - if(pRet && pRet->initWithFade(fade, seg, imagePath, width, length, color)) - { - pRet->autorelease(); - return pRet; - } - CCX_SAFE_DELETE(pRet) - return NULL; - } - bool CCMotionStreak::initWithFade(float fade, float seg, const char *imagePath, float width, float length, ccColor4B color) - { - m_fSegThreshold = seg; - m_fWidth = width; - m_tLastLocation = CGPointZero; - m_pRibbon = CCRibbon::ribbonWithWidth(m_fWidth, imagePath, length, color, fade); - this->addChild(m_pRibbon); - - // update ribbon position - this->schedule(schedule_selector(CCMotionStreak::update), 0); - return true; - } - void CCMotionStreak::update(ccTime delta) - { - CGPoint location = this->convertToWorldSpace(CGPointZero); - m_pRibbon->setPosition(ccp(-1*location.x, -1*location.y)); - float len = sqrtf(powf(m_tLastLocation.x - location.x, 2) + powf(m_tLastLocation.y - location.y, 2)); - if (len > m_fSegThreshold) - { - m_pRibbon->addPointAt(location, m_fWidth); - m_tLastLocation = location; - } - m_pRibbon->update(delta); - } - - //MotionStreak - CocosNodeTexture protocol - - void CCMotionStreak::setTexture(CCTexture2D* texture) - { - m_pRibbon->setTexture(texture); - } - CCTexture2D * CCMotionStreak::getTexture() - { - return m_pRibbon->getTexture(); - } - ccBlendFunc CCMotionStreak::getBlendFunc() - { - return m_pRibbon->getBlendFunc(); - } - void CCMotionStreak::setBlendFunc(ccBlendFunc blendFunc) - { - m_pRibbon->setBlendFunc(blendFunc); - } - CCRibbon * CCMotionStreak::getRibbon() - { - return m_pRibbon; - } -}// namespace cocos2d \ No newline at end of file +/* + * Motion Streak manages a Ribbon based on it's motion in absolute space. + * You construct it with a fadeTime, minimum segment size, texture path, texture + * length and color. The fadeTime controls how long it takes each vertex in + * the streak to fade out, the minimum segment size it how many pixels the + * streak will move before adding a new ribbon segement, and the texture + * length is the how many pixels the texture is stretched across. The texture + * is vertically aligned along the streak segemnts. + */ +//implementation CCMotionStreak + +CCMotionStreak * CCMotionStreak::streakWithFade(float fade, float seg, const char *imagePath, float width, float length, ccColor4B color) +{ + CCMotionStreak *pRet = new CCMotionStreak(); + if(pRet && pRet->initWithFade(fade, seg, imagePath, width, length, color)) + { + pRet->autorelease(); + return pRet; + } + CCX_SAFE_DELETE(pRet) + return NULL; +} + +bool CCMotionStreak::initWithFade(float fade, float seg, const char *imagePath, float width, float length, ccColor4B color) +{ + m_fSegThreshold = seg; + m_fWidth = width; + m_tLastLocation = CGPointZero; + m_pRibbon = CCRibbon::ribbonWithWidth(m_fWidth, imagePath, length, color, fade); + this->addChild(m_pRibbon); + + // update ribbon position + this->schedule(schedule_selector(CCMotionStreak::update), 0); + return true; +} + +void CCMotionStreak::update(ccTime delta) +{ + CGPoint location = this->convertToWorldSpace(CGPointZero); + m_pRibbon->setPosition(ccp(-1*location.x, -1*location.y)); + float len = ccpLength(ccpSub(m_tLastLocation, location)); + if (len > m_fSegThreshold) + { + m_pRibbon->addPointAt(location, m_fWidth); + m_tLastLocation = location; + } + m_pRibbon->update(delta); +} + +//MotionStreak - CocosNodeTexture protocol + +void CCMotionStreak::setTexture(CCTexture2D* texture) +{ + m_pRibbon->setTexture(texture); +} + +CCTexture2D * CCMotionStreak::getTexture() +{ + return m_pRibbon->getTexture(); +} + +ccBlendFunc CCMotionStreak::getBlendFunc() +{ + return m_pRibbon->getBlendFunc(); +} + +void CCMotionStreak::setBlendFunc(ccBlendFunc blendFunc) +{ + m_pRibbon->setBlendFunc(blendFunc); +} + +CCRibbon * CCMotionStreak::getRibbon() +{ + return m_pRibbon; +} + +}// namespace cocos2d diff --git a/cocos2dx/misc_nodes/CCProgressTimer.cpp b/cocos2dx/misc_nodes/CCProgressTimer.cpp index a708fae027..c13079b053 100644 --- a/cocos2dx/misc_nodes/CCProgressTimer.cpp +++ b/cocos2dx/misc_nodes/CCProgressTimer.cpp @@ -29,562 +29,572 @@ THE SOFTWARE. #include -namespace cocos2d +namespace cocos2d { + +#define kProgressTextureCoordsCount 4 +const char kProgressTextureCoords = 0x1e; + +CCProgressTimer* CCProgressTimer::progressWithFile(const char *pszFileName) { - #define kProgressTextureCoordsCount 4 - const char kProgressTextureCoords = 0x1e; - - CCProgressTimer* CCProgressTimer::progressWithFile(const char *pszFileName) + CCProgressTimer *pProgressTimer = new CCProgressTimer(); + if (pProgressTimer->initWithFile(pszFileName)) { - CCProgressTimer *pProgressTimer = new CCProgressTimer(); - if (pProgressTimer->initWithFile(pszFileName)) + pProgressTimer->autorelease(); + } + else + { + delete pProgressTimer; + pProgressTimer = NULL; + } + + return pProgressTimer; +} + +bool CCProgressTimer::initWithFile(const char *pszFileName) +{ + return this->initWithTexture(CCTextureCache::sharedTextureCache()->addImage(pszFileName)); +} + +CCProgressTimer* CCProgressTimer::progressWithTexture(cocos2d::CCTexture2D *pTexture) +{ + CCProgressTimer *pProgressTimer = new CCProgressTimer(); + if (pProgressTimer->initWithTexture(pTexture)) + { + pProgressTimer->autorelease(); + } + else + { + delete pProgressTimer; + pProgressTimer = NULL; + } + + return pProgressTimer; +} + +bool CCProgressTimer::initWithTexture(cocos2d::CCTexture2D *pTexture) +{ + m_pSprite = CCSprite::spriteWithTexture(pTexture); + CCX_SAFE_RETAIN(m_pSprite); + m_fPercentage = 0.f; + m_pVertexData = NULL; + m_nVertexDataCount = 0; + m_tAnchorPoint = ccp(0.5f, 0.5f); + setContentSize(m_pSprite->getContentSize()); + m_eType = kCCProgressTimerTypeRadialCCW; + + return true; +} + +CCProgressTimer::~CCProgressTimer(void) +{ + if (m_pVertexData) + { + delete[] m_pVertexData; + } + + m_pSprite->release(); +} + +void CCProgressTimer::setPercentage(float fPercentage) +{ + if (m_fPercentage != fPercentage) + { + if (m_fPercentage < 0.f) { - pProgressTimer->autorelease(); + m_fPercentage = 0.f; + } else + if (fPercentage > 100.0f) + { + m_fPercentage = 100.f; } else { - delete pProgressTimer; - pProgressTimer = NULL; - } - - return pProgressTimer; - } - - bool CCProgressTimer::initWithFile(const char *pszFileName) - { - return this->initWithTexture(CCTextureCache::sharedTextureCache()->addImage(pszFileName)); - } - - CCProgressTimer* CCProgressTimer::progressWithTexture(cocos2d::CCTexture2D *pTexture) - { - CCProgressTimer *pProgressTimer = new CCProgressTimer(); - if (pProgressTimer->initWithTexture(pTexture)) - { - pProgressTimer->autorelease(); + m_fPercentage = fPercentage; } - else - { - delete pProgressTimer; - pProgressTimer = NULL; - } - return pProgressTimer; + updateProgress(); } +} - bool CCProgressTimer::initWithTexture(cocos2d::CCTexture2D *pTexture) +void CCProgressTimer::setSprite(cocos2d::CCSprite *pSprite) +{ + if (m_pSprite != pSprite) { - m_pSprite = CCSprite::spriteWithTexture(pTexture); - CCX_SAFE_RETAIN(m_pSprite); - m_fPercentage = 0.f; - m_pVertexData = NULL; - m_nVertexDataCount = 0; - m_tAnchorPoint = ccp(0.5f, 0.5f); - setContentSize(m_pSprite->getContentSize()); - m_eType = kCCProgressTimerTypeRadialCCW; + CCX_SAFE_RETAIN(pSprite); + CCX_SAFE_RELEASE(m_pSprite); + m_pSprite = pSprite; - return true; - } - - CCProgressTimer::~CCProgressTimer(void) - { + // Everytime we set a new sprite, we free the current vertex data if (m_pVertexData) { delete[] m_pVertexData; + m_pVertexData = NULL; + m_nVertexDataCount = 0; } + } +} - m_pSprite->release(); - } - - void CCProgressTimer::setPercentage(float fPercentage) +void CCProgressTimer::setType(cocos2d::CCProgressTimerType type) +{ + if (type != m_eType) { - if (m_fPercentage != fPercentage) - { - if (m_fPercentage < 0.f) - { - m_fPercentage = 0.f; - } else - if (fPercentage > 100.0f) - { - m_fPercentage = 100.f; - } - else - { - m_fPercentage = fPercentage; - } - - updateProgress(); - } - } - - void CCProgressTimer::setSprite(cocos2d::CCSprite *pSprite) - { - if (m_pSprite != pSprite) - { - CCX_SAFE_RETAIN(pSprite); - CCX_SAFE_RELEASE(m_pSprite); - m_pSprite = pSprite; - - // Everytime we set a new sprite, we free the current vertex data - if (m_pVertexData) - { - delete[] m_pVertexData; - m_pVertexData = NULL; - m_nVertexDataCount = 0; - } - } - } - - void CCProgressTimer::setType(cocos2d::CCProgressTimerType type) - { - if (type != m_eType) - { - // release all previous information - if (m_pVertexData) - { - delete[] m_pVertexData; - m_pVertexData = NULL; - m_nVertexDataCount = 0; - } - - m_eType = type; - } - } - - // Interval - - /// - // @returns the vertex position from the texture coordinate - /// - CGPoint CCProgressTimer::vertexFromTexCoord(cocos2d::CGPoint texCoord) - { - if (m_pSprite->getTexture()) - { - return ccp(m_pSprite->getTexture()->getContentSize().width * texCoord.x / m_pSprite->getTexture()->getMaxS(), - m_pSprite->getTexture()->getContentSize().height * (1 - (texCoord.y / m_pSprite->getTexture()->getMaxT()))); - } - else - { - return CGPointZero; - } - } - - void CCProgressTimer::updateColor(void) - { - ccColor4F color = ccc4FFromccc3B(m_pSprite->getColor()); - if (m_pSprite->getTexture()->getHasPremultipliedAlpha()) - { - float op = m_pSprite->getOpacity() / 255.f; - color.r *= op; - color.g *= op; - color.b *= op; - color.a = op; - } - else - { - color.a = m_pSprite->getOpacity() / 255.f; - } - + // release all previous information if (m_pVertexData) { - for (int i = 0; i < m_nVertexDataCount; ++i) + delete[] m_pVertexData; + m_pVertexData = NULL; + m_nVertexDataCount = 0; + } + + m_eType = type; + } +} + +// Interval + +/// +// @returns the vertex position from the texture coordinate +/// +ccVertex2F CCProgressTimer::vertexFromTexCoord(cocos2d::CGPoint texCoord) +{ + CGPoint tmp; + ccVertex2F ret; + + CCTexture2D *pTexture = m_pSprite->getTexture(); + if (pTexture) + { + CGSize texSize = pTexture->getContentSizeInPixels(); + tmp = ccp(texSize.width * texCoord.x / pTexture->getMaxS(), + texSize.height * (1 - (texCoord.y / pTexture->getMaxT()))); + } + else + { + tmp = CGPointZero; + } + + ret.x = tmp.x; + ret.y = tmp.y; + return ret; +} + +void CCProgressTimer::updateColor(void) +{ + ccColor4F color = ccc4FFromccc3B(m_pSprite->getColor()); + if (m_pSprite->getTexture()->getHasPremultipliedAlpha()) + { + float op = m_pSprite->getOpacity() / 255.f; + color.r *= op; + color.g *= op; + color.b *= op; + color.a = op; + } + else + { + color.a = m_pSprite->getOpacity() / 255.f; + } + + if (m_pVertexData) + { + for (int i = 0; i < m_nVertexDataCount; ++i) + { + m_pVertexData[i].colors = color; + } + } +} + +void CCProgressTimer::updateProgress(void) +{ + switch (m_eType) + { + case kCCProgressTimerTypeRadialCW: + case kCCProgressTimerTypeRadialCCW: + updateRadial(); + break; + case kCCProgressTimerTypeHorizontalBarLR: + case kCCProgressTimerTypeHorizontalBarRL: + case kCCProgressTimerTypeVerticalBarBT: + case kCCProgressTimerTypeVerticalBarTB: + updateBar(); + break; + default: + break; + } +} + +/// +// Update does the work of mapping the texture onto the triangles +// It now doesn't occur the cost of free/alloc data every update cycle. +// It also only changes the percentage point but no other points if they have not +// been modified. +// +// It now deals with flipped texture. If you run into this problem, just use the +// sprite property and enable the methods flipX, flipY. +/// +void CCProgressTimer::updateRadial(void) +{ + // Texture Max is the actual max coordinates to deal with non-power of 2 textures + CGPoint tMax = ccp(m_pSprite->getTexture()->getMaxS(), + m_pSprite->getTexture()->getMaxT()); + + // Grab the midpoint + CGPoint midpoint = ccpCompMult(m_tAnchorPoint, tMax); + + float alpha = m_fPercentage / 100.f; + + // Otherwise we can get the angle from the alpha + float angle = 2.f * ((float)M_PI) * (m_eType == kCCProgressTimerTypeRadialCW ? alpha : 1.f - alpha); + + // We find the vector to do a hit detection based on the percentage + // We know the first vector is the one @ 12 o'clock (top,mid) so we rotate + // from that by the progress angle around the midpoint pivot + CGPoint topMid = ccp(midpoint.x, 0.f); + CGPoint percentagePt = ccpRotateByAngle(topMid, midpoint, angle); + + int index = 0; + CGPoint hit = CGPointZero; + + if (alpha == 0.f) + { + // More efficient since we don't always need to check intersection + // If the alpha is zero then the hit point is top mid and the index is 0. + hit = topMid; + index = 0; + } else + if (alpha == 1.f) + { + // More efficient since we don't always need to check intersection + // If the alpha is one then the hit point is top mid and the index is 4. + hit = topMid; + index = 4; + } + else + { + // We run a for loop checking the edges of the texture to find the + // intersection point + // We loop through five points since the top is split in half + + float min_t = FLT_MAX; + + for (int i = 0; i <= kProgressTextureCoordsCount; ++i) + { + int pIndex = (i + (kProgressTextureCoordsCount - 1)) % kProgressTextureCoordsCount; + + CGPoint edgePtA = ccpCompMult(boundaryTexCoord(i % kProgressTextureCoordsCount), tMax); + CGPoint edgePtB = ccpCompMult(boundaryTexCoord(pIndex), tMax); + + // Remember that the top edge is split in half for the 12 o'clock position + // Let's deal with that here by finding the correct endpoints + if (i == 0) { - m_pVertexData[i].colors = color; - } + edgePtB = ccpLerp(edgePtA, edgePtB, 0.5f); + } else + if (i == 4) + { + edgePtA = ccpLerp(edgePtA, edgePtB, 0.5f); + } + + // s and t are returned by ccpLineIntersect + float s = 0; + float t = 0; + if (ccpLineIntersect(edgePtA, edgePtB, midpoint, percentagePt, &s, &t)) + { + // Since our hit test is on rays we have to deal with the top edge + // being in split in half so we have to test as a segment + if (i == 0 || i == 4) + { + // s represents the point between edgePtA--edgePtB + if (!(0.f <= s && s <= 1.f)) + { + continue; + } + } + + // As long as our t isn't negative we are at least finding a + // correct hitpoint from midpoint to percentagePt. + if (t >= 0.f) + { + // Because the percentage line and all the texture edges are + // rays we should only account for the shortest intersection + if (t < min_t) + { + min_t = t; + index = i; + } + } + } + + } + + // Now that we have the minimum magnitude we can use that to find our intersection + hit = ccpAdd(midpoint, ccpMult(ccpSub(percentagePt, midpoint),min_t)); + } + + // The size of the vertex data is the index from the hitpoint + // the 3 is for the midpoint, 12 o'clock point and hitpoint position. + + bool sameIndexCount = true; + if (m_nVertexDataCount != index + 3) + { + sameIndexCount = false; + if (m_pVertexData) + { + delete[] m_pVertexData; + m_pVertexData = NULL; + m_nVertexDataCount = 0; } } - void CCProgressTimer::updateProgress(void) + if (! m_pVertexData) { - switch (m_eType) - { - case kCCProgressTimerTypeRadialCW: - case kCCProgressTimerTypeRadialCCW: - updateRadial(); - break; - case kCCProgressTimerTypeHorizontalBarLR: - case kCCProgressTimerTypeHorizontalBarRL: - case kCCProgressTimerTypeVerticalBarBT: - case kCCProgressTimerTypeVerticalBarTB: - updateBar(); - break; - default: - break; - } + m_nVertexDataCount = index + 3; + m_pVertexData = new ccV2F_C4F_T2F[m_nVertexDataCount]; + assert(m_pVertexData); + + updateColor(); } - /// - // Update does the work of mapping the texture onto the triangles - // It now doesn't occur the cost of free/alloc data every update cycle. - // It also only changes the percentage point but no other points if they have not - // been modified. - // - // It now deals with flipped texture. If you run into this problem, just use the - // sprite property and enable the methods flipX, flipY. - /// - void CCProgressTimer::updateRadial(void) + if (! sameIndexCount) { - // Texture Max is the actual max coordinates to deal with non-power of 2 textures - CGPoint tMax = ccp(m_pSprite->getTexture()->getMaxS(), - m_pSprite->getTexture()->getMaxT()); + // First we populate the array with the midpoint, then all + // vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint + m_pVertexData[0].texCoords = tex2(midpoint.x, midpoint.y); + m_pVertexData[0].vertices = vertexFromTexCoord(midpoint); - // Grab the midpoint - CGPoint midpoint = ccpCompMult(m_tAnchorPoint, tMax); + m_pVertexData[1].texCoords = tex2(midpoint.x, 0.f); + m_pVertexData[1].vertices = vertexFromTexCoord(ccp(midpoint.x, 0.f)); - float alpha = m_fPercentage / 100.f; - - // Otherwise we can get the angle from the alpha - float angle = 2.f * ((float)M_PI) * (m_eType == kCCProgressTimerTypeRadialCW ? alpha : 1.f - alpha); - - // We find the vector to do a hit detection based on the percentage - // We know the first vector is the one @ 12 o'clock (top,mid) so we rotate - // from that by the progress angle around the midpoint pivot - CGPoint topMid = ccp(midpoint.x, 0.f); - CGPoint percentagePt = ccpRotateByAngle(topMid, midpoint, angle); - - int index = 0; - CGPoint hit = CGPointZero; - - if (alpha == 0.f) + for (int i = 0; i < index; ++i) { - // More efficient since we don't always need to check intersection - // If the alpha is zero then the hit point is top mid and the index is 0. - hit = topMid; - index = 0; - } else - if (alpha == 1.f) - { - // More efficient since we don't always need to check intersection - // If the alpha is one then the hit point is top mid and the index is 4. - hit = topMid; - index = 4; - } - else - { - // We run a for loop checking the edges of the texture to find the - // intersection point - // We loop through five points since the top is split in half - - float min_t = FLT_MAX; + CGPoint texCoords = ccpCompMult(boundaryTexCoord(i), tMax); - for (int i = 0; i <= kProgressTextureCoordsCount; ++i) - { - int pIndex = (i + (kProgressTextureCoordsCount - 1)) % kProgressTextureCoordsCount; - - CGPoint edgePtA = ccpCompMult(boundaryTexCoord(i % kProgressTextureCoordsCount), tMax); - CGPoint edgePtB = ccpCompMult(boundaryTexCoord(pIndex), tMax); - - // Remember that the top edge is split in half for the 12 o'clock position - // Let's deal with that here by finding the correct endpoints - if (i == 0) - { - edgePtB = ccpLerp(edgePtA, edgePtB, 0.5f); - } else - if (i == 4) - { - edgePtA = ccpLerp(edgePtA, edgePtB, 0.5f); - } - - // s and t are returned by ccpLineIntersect - float s = 0; - float t = 0; - if (ccpLineIntersect(edgePtA, edgePtB, midpoint, percentagePt, &s, &t)) - { - // Since our hit test is on rays we have to deal with the top edge - // being in split in half so we have to test as a segment - if (i == 0 || i == 4) - { - // s represents the point between edgePtA--edgePtB - if (!(0.f <= s && s <= 1.f)) - { - continue; - } - } - - // As long as our t isn't negative we are at least finding a - // correct hitpoint from midpoint to percentagePt. - if (t >= 0.f) - { - // Because the percentage line and all the texture edges are - // rays we should only account for the shortest intersection - if (t < min_t) - { - min_t = t; - index = i; - } - } - } - - } - - // Now that we have the minimum magnitude we can use that to find our intersection - hit = ccpAdd(midpoint, ccpMult(ccpSub(percentagePt, midpoint),min_t)); + m_pVertexData[i+2].texCoords = tex2(texCoords.x, texCoords.y); + m_pVertexData[i+2].vertices = vertexFromTexCoord(texCoords); } - // The size of the vertex data is the index from the hitpoint - // the 3 is for the midpoint, 12 o'clock point and hitpoint position. - - bool sameIndexCount = true; - if (m_nVertexDataCount != index + 3) - { - sameIndexCount = false; - if (m_pVertexData) - { - delete[] m_pVertexData; - m_pVertexData = NULL; - m_nVertexDataCount = 0; - } - } - - if (! m_pVertexData) - { - m_nVertexDataCount = index + 3; - m_pVertexData = new ccV2F_C4F_T2F[m_nVertexDataCount]; - assert(m_pVertexData); - - updateColor(); - } - - if (! sameIndexCount) - { - // First we populate the array with the midpoint, then all - // vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint - m_pVertexData[0].texCoords = tex2(midpoint.x, midpoint.y); - m_pVertexData[0].vertices = vertexFromTexCoord(midpoint); - - m_pVertexData[1].texCoords = tex2(midpoint.x, 0.f); - m_pVertexData[1].vertices = vertexFromTexCoord(ccp(midpoint.x, 0.f)); - - for (int i = 0; i < index; ++i) - { - CGPoint texCoords = ccpCompMult(boundaryTexCoord(i), tMax); - - m_pVertexData[i+2].texCoords = tex2(texCoords.x, texCoords.y); - m_pVertexData[i+2].vertices = vertexFromTexCoord(texCoords); - } - - // Flip the texture coordinates if set - if (m_pSprite->isFlipX() || m_pSprite->isFlipY()) - { - for (int i = 0; i < m_nVertexDataCount - 1; ++i) - { - if (m_pSprite->isFlipX()) - { - m_pVertexData[i].texCoords.u = tMax.x - m_pVertexData[i].texCoords.u; - } - - if (m_pSprite->isFlipY()) - { - m_pVertexData[i].texCoords.v = tMax.y - m_pVertexData[i].texCoords.v; - } - } - } - } - - // hitpoint will go last - m_pVertexData[m_nVertexDataCount - 1].texCoords = tex2(hit.x, hit.y); - m_pVertexData[m_nVertexDataCount - 1].vertices = vertexFromTexCoord(hit); - + // Flip the texture coordinates if set if (m_pSprite->isFlipX() || m_pSprite->isFlipY()) { - if (m_pSprite->isFlipX()) - { - m_pVertexData[m_nVertexDataCount - 1].texCoords.u = tMax.x - m_pVertexData[m_nVertexDataCount - 1].texCoords.u; - } - - if (m_pSprite->isFlipY()) - { - m_pVertexData[m_nVertexDataCount - 1].texCoords.v = tMax.y - m_pVertexData[m_nVertexDataCount - 1].texCoords.v; - } - } - } - - /// - // Update does the work of mapping the texture onto the triangles for the bar - // It now doesn't occur the cost of free/alloc data every update cycle. - // It also only changes the percentage point but no other points if they have not - // been modified. - // - // It now deals with flipped texture. If you run into this problem, just use the - // sprite property and enable the methods flipX, flipY. - /// - void CCProgressTimer::updateBar(void) - { - float alpha = m_fPercentage / 100.f; - - CGPoint tMax = ccp(m_pSprite->getTexture()->getMaxS(), m_pSprite->getTexture()->getMaxT()); - - unsigned char vIndexes[2] = {0, 0}; - - // We know vertex data is always equal to the 4 corners - // If we don't have vertex data then we create it here and populate - // the side of the bar vertices that won't ever change. - if (! m_pVertexData) - { - m_nVertexDataCount = kProgressTextureCoordsCount; - m_pVertexData = new ccV2F_C4F_T2F[m_nVertexDataCount]; - assert(m_pVertexData); - - if (m_eType == kCCProgressTimerTypeHorizontalBarLR) - { - m_pVertexData[vIndexes[0] = 0].texCoords = tex2(0, 0); - m_pVertexData[vIndexes[1] = 1].texCoords = tex2(0, tMax.y); - } else - if (m_eType == kCCProgressTimerTypeHorizontalBarRL) - { - m_pVertexData[vIndexes[0] = 2].texCoords = tex2(tMax.x, tMax.y); - m_pVertexData[vIndexes[1] = 3].texCoords = tex2(tMax.x, 0.f); - } else - if (m_eType == kCCProgressTimerTypeVerticalBarBT) - { - m_pVertexData[vIndexes[0] = 1].texCoords = tex2(0, tMax.y); - m_pVertexData[vIndexes[1] = 3].texCoords = tex2(tMax.x, tMax.y); - } else - if (m_eType == kCCProgressTimerTypeVerticalBarTB) - { - m_pVertexData[vIndexes[0] = 0].texCoords = tex2(0, 0); - m_pVertexData[vIndexes[1] = 2].texCoords = tex2(tMax.x, 0); - } - - unsigned char index = vIndexes[0]; - m_pVertexData[index].vertices = vertexFromTexCoord(ccp(m_pVertexData[index].texCoords.u, - m_pVertexData[index].texCoords.v)); - - index = vIndexes[1]; - m_pVertexData[index].vertices = vertexFromTexCoord(ccp(m_pVertexData[index].texCoords.u, - m_pVertexData[index].texCoords.v)); - - if (m_pSprite->isFlipY() || m_pSprite->isFlipX()) + for (int i = 0; i < m_nVertexDataCount - 1; ++i) { if (m_pSprite->isFlipX()) { - unsigned char index = vIndexes[0]; - m_pVertexData[index].texCoords.u = tMax.x - m_pVertexData[index].texCoords.u; - index = vIndexes[1]; - m_pVertexData[index].texCoords.u = tMax.x - m_pVertexData[index].texCoords.u; + m_pVertexData[i].texCoords.u = tMax.x - m_pVertexData[i].texCoords.u; } if (m_pSprite->isFlipY()) { - unsigned char index = vIndexes[0]; - m_pVertexData[index].texCoords.v = tMax.y - m_pVertexData[index].texCoords.v; - index = vIndexes[1]; - m_pVertexData[index].texCoords.v = tMax.y - m_pVertexData[index].texCoords.v; + m_pVertexData[i].texCoords.v = tMax.y - m_pVertexData[i].texCoords.v; } } + } + } - updateColor(); + // hitpoint will go last + m_pVertexData[m_nVertexDataCount - 1].texCoords = tex2(hit.x, hit.y); + m_pVertexData[m_nVertexDataCount - 1].vertices = vertexFromTexCoord(hit); + + if (m_pSprite->isFlipX() || m_pSprite->isFlipY()) + { + if (m_pSprite->isFlipX()) + { + m_pVertexData[m_nVertexDataCount - 1].texCoords.u = tMax.x - m_pVertexData[m_nVertexDataCount - 1].texCoords.u; } - if(m_eType == kCCProgressTimerTypeHorizontalBarLR) - { - m_pVertexData[vIndexes[0] = 3].texCoords = tex2(tMax.x*alpha, tMax.y); - m_pVertexData[vIndexes[1] = 2].texCoords = tex2(tMax.x*alpha, 0); - } else - if (m_eType == kCCProgressTimerTypeHorizontalBarRL) - { - m_pVertexData[vIndexes[0] = 1].texCoords = tex2(tMax.x*(1.f - alpha), 0); - m_pVertexData[vIndexes[1] = 0].texCoords = tex2(tMax.x*(1.f - alpha), tMax.y); - } else - if (m_eType == kCCProgressTimerTypeVerticalBarBT) - { - m_pVertexData[vIndexes[0] = 0].texCoords = tex2(0, tMax.y*(1.f - alpha)); - m_pVertexData[vIndexes[1] = 2].texCoords = tex2(tMax.x, tMax.y*(1.f - alpha)); - } else - if (m_eType == kCCProgressTimerTypeVerticalBarTB) - { - m_pVertexData[vIndexes[0] = 1].texCoords = tex2(0, tMax.y*alpha); - m_pVertexData[vIndexes[1] = 3].texCoords = tex2(tMax.x, tMax.y*alpha); + if (m_pSprite->isFlipY()) + { + m_pVertexData[m_nVertexDataCount - 1].texCoords.v = tMax.y - m_pVertexData[m_nVertexDataCount - 1].texCoords.v; + } + } +} + +/// +// Update does the work of mapping the texture onto the triangles for the bar +// It now doesn't occur the cost of free/alloc data every update cycle. +// It also only changes the percentage point but no other points if they have not +// been modified. +// +// It now deals with flipped texture. If you run into this problem, just use the +// sprite property and enable the methods flipX, flipY. +/// +void CCProgressTimer::updateBar(void) +{ + float alpha = m_fPercentage / 100.f; + + CGPoint tMax = ccp(m_pSprite->getTexture()->getMaxS(), m_pSprite->getTexture()->getMaxT()); + + unsigned char vIndexes[2] = {0, 0}; + + // We know vertex data is always equal to the 4 corners + // If we don't have vertex data then we create it here and populate + // the side of the bar vertices that won't ever change. + if (! m_pVertexData) + { + m_nVertexDataCount = kProgressTextureCoordsCount; + m_pVertexData = new ccV2F_C4F_T2F[m_nVertexDataCount]; + assert(m_pVertexData); + + if (m_eType == kCCProgressTimerTypeHorizontalBarLR) + { + m_pVertexData[vIndexes[0] = 0].texCoords = tex2(0, 0); + m_pVertexData[vIndexes[1] = 1].texCoords = tex2(0, tMax.y); + } else + if (m_eType == kCCProgressTimerTypeHorizontalBarRL) + { + m_pVertexData[vIndexes[0] = 2].texCoords = tex2(tMax.x, tMax.y); + m_pVertexData[vIndexes[1] = 3].texCoords = tex2(tMax.x, 0.f); + } else + if (m_eType == kCCProgressTimerTypeVerticalBarBT) + { + m_pVertexData[vIndexes[0] = 1].texCoords = tex2(0, tMax.y); + m_pVertexData[vIndexes[1] = 3].texCoords = tex2(tMax.x, tMax.y); + } else + if (m_eType == kCCProgressTimerTypeVerticalBarTB) + { + m_pVertexData[vIndexes[0] = 0].texCoords = tex2(0, 0); + m_pVertexData[vIndexes[1] = 2].texCoords = tex2(tMax.x, 0); } unsigned char index = vIndexes[0]; m_pVertexData[index].vertices = vertexFromTexCoord(ccp(m_pVertexData[index].texCoords.u, m_pVertexData[index].texCoords.v)); + index = vIndexes[1]; m_pVertexData[index].vertices = vertexFromTexCoord(ccp(m_pVertexData[index].texCoords.u, m_pVertexData[index].texCoords.v)); - if (m_pSprite->isFlipY() || m_pSprite->isFlipX()) - { - if (m_pSprite->isFlipX()) - { + if (m_pSprite->isFlipY() || m_pSprite->isFlipX()) + { + if (m_pSprite->isFlipX()) + { unsigned char index = vIndexes[0]; m_pVertexData[index].texCoords.u = tMax.x - m_pVertexData[index].texCoords.u; index = vIndexes[1]; - m_pVertexData[index].texCoords.u = tMax.x - m_pVertexData[index].texCoords.u; - } - - if (m_pSprite->isFlipY()) - { + m_pVertexData[index].texCoords.u = tMax.x - m_pVertexData[index].texCoords.u; + } + + if (m_pSprite->isFlipY()) + { unsigned char index = vIndexes[0]; m_pVertexData[index].texCoords.v = tMax.y - m_pVertexData[index].texCoords.v; index = vIndexes[1]; - m_pVertexData[index].texCoords.v = tMax.y - m_pVertexData[index].texCoords.v; - } + m_pVertexData[index].texCoords.v = tMax.y - m_pVertexData[index].texCoords.v; + } } + + updateColor(); } - CGPoint CCProgressTimer::boundaryTexCoord(char index) - { - if (index < kProgressTextureCoordsCount) - { - switch (m_eType) - { - case kCCProgressTimerTypeRadialCW: - return ccp( (float)((kProgressTextureCoords>>((index<<1)+1))&1), (float)((kProgressTextureCoords>>(index<<1))&1) ); - case kCCProgressTimerTypeRadialCCW: - return ccp( (float)((kProgressTextureCoords>>(7-(index<<1)))&1), (float)((kProgressTextureCoords>>(7-((index<<1)+1)))&1)); - default: - break; - } - } - - return CGPointZero; + if(m_eType == kCCProgressTimerTypeHorizontalBarLR) + { + m_pVertexData[vIndexes[0] = 3].texCoords = tex2(tMax.x*alpha, tMax.y); + m_pVertexData[vIndexes[1] = 2].texCoords = tex2(tMax.x*alpha, 0); + } else + if (m_eType == kCCProgressTimerTypeHorizontalBarRL) + { + m_pVertexData[vIndexes[0] = 1].texCoords = tex2(tMax.x*(1.f - alpha), 0); + m_pVertexData[vIndexes[1] = 0].texCoords = tex2(tMax.x*(1.f - alpha), tMax.y); + } else + if (m_eType == kCCProgressTimerTypeVerticalBarBT) + { + m_pVertexData[vIndexes[0] = 0].texCoords = tex2(0, tMax.y*(1.f - alpha)); + m_pVertexData[vIndexes[1] = 2].texCoords = tex2(tMax.x, tMax.y*(1.f - alpha)); + } else + if (m_eType == kCCProgressTimerTypeVerticalBarTB) + { + m_pVertexData[vIndexes[0] = 1].texCoords = tex2(0, tMax.y*alpha); + m_pVertexData[vIndexes[1] = 3].texCoords = tex2(tMax.x, tMax.y*alpha); } - void CCProgressTimer::draw(void) - { - if(! m_pVertexData) + unsigned char index = vIndexes[0]; + m_pVertexData[index].vertices = vertexFromTexCoord(ccp(m_pVertexData[index].texCoords.u, + m_pVertexData[index].texCoords.v)); + index = vIndexes[1]; + m_pVertexData[index].vertices = vertexFromTexCoord(ccp(m_pVertexData[index].texCoords.u, + m_pVertexData[index].texCoords.v)); + + if (m_pSprite->isFlipY() || m_pSprite->isFlipX()) + { + if (m_pSprite->isFlipX()) { - return; + unsigned char index = vIndexes[0]; + m_pVertexData[index].texCoords.u = tMax.x - m_pVertexData[index].texCoords.u; + index = vIndexes[1]; + m_pVertexData[index].texCoords.u = tMax.x - m_pVertexData[index].texCoords.u; } - if(! m_pSprite) + if (m_pSprite->isFlipY()) { - return; + unsigned char index = vIndexes[0]; + m_pVertexData[index].texCoords.v = tMax.y - m_pVertexData[index].texCoords.v; + index = vIndexes[1]; + m_pVertexData[index].texCoords.v = tMax.y - m_pVertexData[index].texCoords.v; } - - bool newBlend = false; - - ccBlendFunc bf = m_pSprite->getBlendFunc(); - if (bf.src != CC_BLEND_SRC || bf.dst != CC_BLEND_DST) - { - newBlend = true; - glBlendFunc(bf.src, bf.dst); - } - - /// ======================================================================== - // Replaced [texture_ drawAtPoint:CGPointZero] with my own vertexData - // Everything above me and below me is copied from CCTextureNode's draw - glBindTexture(GL_TEXTURE_2D, m_pSprite->getTexture()->getName()); - glVertexPointer(2, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &m_pVertexData[0].vertices); - glTexCoordPointer(2, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &m_pVertexData[0].texCoords); - glColorPointer(4, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &m_pVertexData[0].colors); - - if(m_eType == kCCProgressTimerTypeRadialCCW || m_eType == kCCProgressTimerTypeRadialCW) - { - glDrawArrays(GL_TRIANGLE_FAN, 0, m_nVertexDataCount); - } else - if ( m_eType == kCCProgressTimerTypeHorizontalBarLR || - m_eType == kCCProgressTimerTypeHorizontalBarRL || - m_eType == kCCProgressTimerTypeVerticalBarBT || - m_eType == kCCProgressTimerTypeVerticalBarTB) - { - glDrawArrays(GL_TRIANGLE_STRIP, 0, m_nVertexDataCount); - } - //glDrawElements(GL_TRIANGLES, indicesCount_, GL_UNSIGNED_BYTE, indices_); - /// ======================================================================== - - if( newBlend ) - glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST); - } + } } + +CGPoint CCProgressTimer::boundaryTexCoord(char index) +{ + if (index < kProgressTextureCoordsCount) + { + switch (m_eType) + { + case kCCProgressTimerTypeRadialCW: + return ccp( (float)((kProgressTextureCoords>>((index<<1)+1))&1), (float)((kProgressTextureCoords>>(index<<1))&1) ); + case kCCProgressTimerTypeRadialCCW: + return ccp( (float)((kProgressTextureCoords>>(7-(index<<1)))&1), (float)((kProgressTextureCoords>>(7-((index<<1)+1)))&1)); + default: + break; + } + } + + return CGPointZero; +} + +void CCProgressTimer::draw(void) +{ + if(! m_pVertexData) + { + return; + } + + if(! m_pSprite) + { + return; + } + + ccBlendFunc bf = m_pSprite->getBlendFunc(); + bool newBlend = (bf.src != CC_BLEND_SRC || bf.dst != CC_BLEND_DST) ? true : false; + if (newBlend) + { + glBlendFunc(bf.src, bf.dst); + } + + /// ======================================================================== + // Replaced [texture_ drawAtPoint:CGPointZero] with my own vertexData + // Everything above me and below me is copied from CCTextureNode's draw + glBindTexture(GL_TEXTURE_2D, m_pSprite->getTexture()->getName()); + glVertexPointer(2, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &m_pVertexData[0].vertices); + glTexCoordPointer(2, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &m_pVertexData[0].texCoords); + glColorPointer(4, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &m_pVertexData[0].colors); + + if(m_eType == kCCProgressTimerTypeRadialCCW || m_eType == kCCProgressTimerTypeRadialCW) + { + glDrawArrays(GL_TRIANGLE_FAN, 0, m_nVertexDataCount); + } else + if ( m_eType == kCCProgressTimerTypeHorizontalBarLR || + m_eType == kCCProgressTimerTypeHorizontalBarRL || + m_eType == kCCProgressTimerTypeVerticalBarBT || + m_eType == kCCProgressTimerTypeVerticalBarTB) + { + glDrawArrays(GL_TRIANGLE_STRIP, 0, m_nVertexDataCount); + } + //glDrawElements(GL_TRIANGLES, indicesCount_, GL_UNSIGNED_BYTE, indices_); + /// ======================================================================== + + if( newBlend ) + { + glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST); + } +} + +} // namespace cocos2d diff --git a/cocos2dx/misc_nodes/CCRenderTexture.cpp b/cocos2dx/misc_nodes/CCRenderTexture.cpp index 963d6d1c27..8d64689ac0 100644 --- a/cocos2dx/misc_nodes/CCRenderTexture.cpp +++ b/cocos2dx/misc_nodes/CCRenderTexture.cpp @@ -26,145 +26,312 @@ THE SOFTWARE. #include "CCDirector.h" #include "platform/platform.h" #include "CCXUIImage.h" +#include "Support/ccUtls.h" #include namespace cocos2d { - // implementation CCRenderTexture - CCSprite * CCRenderTexture::getSprite() - { - return m_pSprite; - } - void CCRenderTexture::setSprite(CCSprite* var) - { - m_pSprite = var; - } +// implementation CCRenderTexture +CCRenderTexture::CCRenderTexture() +: m_pSprite(NULL) +, m_uFBO(0) +, m_nOldFBO(0) +, m_pTexture(0) +, m_ePixelFormat(kCCPixelFormatRGBA8888) +{ + memset(m_aClearColor, 0, sizeof(m_aClearColor)); +} - CCRenderTexture * CCRenderTexture::renderTextureWithWidthAndHeight(int width, int height) - { - CCRenderTexture *pRet = new CCRenderTexture(); +CCRenderTexture::~CCRenderTexture() +{ + removeAllChildrenWithCleanup(true); + ccglDeleteFramebuffers(1, &m_uFBO); +} - if(pRet && pRet->initWithWidthAndHeight(width,height)) - { - pRet->autorelease(); - return pRet; - } - CCX_SAFE_DELETE(pRet) - return NULL; - } - bool CCRenderTexture::initWithWidthAndHeight(int width, int height) - { - glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &m_nOldFBO); - CCTexture2DPixelFormat format = kCCTexture2DPixelFormat_RGBA8888; - // textures must be power of two squared - int pow = 8; - while (pow < width || pow < height) - { - pow*=2; - } - void *data = malloc((int)(pow * pow * 4)); - memset(data, 0, (int)(pow * pow * 4)); - m_pTexture = new CCTexture2D(); - m_pTexture->initWithData(data, format, pow, pow, CGSizeMake((float)width, (float)height)); - free( data ); - // generate FBO - glGenFramebuffersOES(1, &m_uFBO); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_uFBO); - // associate texture with FBO - glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, m_pTexture->getName(), 0); +CCSprite * CCRenderTexture::getSprite() +{ + return m_pSprite; +} +void CCRenderTexture::setSprite(CCSprite* var) +{ + m_pSprite = var; +} - // check if it worked (probably worth doing :) ) - GLuint status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); - if (status != GL_FRAMEBUFFER_COMPLETE_OES) - { - NSAssert(0, "Render Texture : Could not attach texture to framebuffer") - CCX_SAFE_DELETE(m_pTexture); - return false; - } - m_pSprite = CCSprite::spriteWithTexture(m_pTexture); - m_pTexture->release(); - m_pSprite->setScaleY(-1); - this->addChild(m_pSprite); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_nOldFBO); - return true; - } - CCRenderTexture::~CCRenderTexture() - { - glDeleteFramebuffersOES(1, &m_uFBO); - } - void CCRenderTexture::begin() - { - CC_DISABLE_DEFAULT_GL_STATES(); - // Save the current matrix - glPushMatrix(); +CCRenderTexture * CCRenderTexture::renderTextureWithWidthAndHeight(int w, int h, CCTexture2DPixelFormat eFormat) +{ + CCRenderTexture *pRet = new CCRenderTexture(); - CGSize textureSize = m_pTexture->getContentSize(); + if(pRet && pRet->initWithWidthAndHeight(w, h, eFormat)) + { + pRet->autorelease(); + return pRet; + } + CCX_SAFE_DELETE(pRet); + return NULL; +} - // Calculate the adjustment ratios based on the old and new projections - CGSize size = CCDirector::sharedDirector()->getDisplaySize(); - float widthRatio = size.width / textureSize.width; - float heightRatio = size.height / textureSize.height; +CCRenderTexture * CCRenderTexture::renderTextureWithWidthAndHeight(int w, int h) +{ + CCRenderTexture *pRet = new CCRenderTexture(); - // Adjust the orthographic propjection and viewport - glOrthof((float)-1.0 / widthRatio, (float)1.0 / widthRatio, (float)-1.0 / heightRatio, (float)1.0 / heightRatio, -1,1); - glViewport(0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height); - - glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &m_nOldFBO); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_uFBO);//Will direct drawing to the frame buffer created above - - CC_ENABLE_DEFAULT_GL_STATES(); - } - void CCRenderTexture::end() + if(pRet && pRet->initWithWidthAndHeight(w, h, kCCTexture2DPixelFormat_RGBA8888)) { - glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_nOldFBO); - // Restore the original matrix and viewport - glPopMatrix(); - CGSize size = CCDirector::sharedDirector()->getDisplaySize(); - glViewport(0, 0, (GLsizei)size.width, (GLsizei)size.height); + pRet->autorelease(); + return pRet; + } + CCX_SAFE_DELETE(pRet) + return NULL; +} +bool CCRenderTexture::initWithWidthAndHeight(int w, int h, CCTexture2DPixelFormat eFormat) +{ + bool bRet = false; + do + { + w *= CC_CONTENT_SCALE_FACTOR(); + h *= CC_CONTENT_SCALE_FACTOR(); - glColorMask(true, true, true, true); - } - void CCRenderTexture::clear(float r, float g, float b, float a) - { - this->begin(); - glClearColor(r, g, b, a); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glColorMask(true, true, true, false); - this->end(); - } - bool CCRenderTexture::saveBuffer(const char *name) - { - return this->saveBuffer(name, kImageFormatJPG); - } - bool CCRenderTexture::saveBuffer(const char *name, int format) - { - bool bRet = false; - UIImage *myImage = this->getUIImageFromBuffer(); - if (myImage) - { - bRet = myImage->save(name, format); - delete myImage; - } - return bRet; - } + glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &m_nOldFBO); - /* get buffer as UIImage */ - UIImage * CCRenderTexture::getUIImageFromBuffer() - { - int tx = (int)m_pTexture->getContentSize().width; - int ty = (int)m_pTexture->getContentSize().height; - - char * pBuffer = new char[tx * ty * 4]; - - this->begin(); - glReadPixels(0,0,tx,ty,GL_RGBA,GL_UNSIGNED_BYTE, pBuffer); - this->end(); - - UIImage *pRet = new UIImage(); - pRet->initWithBuffer(tx, ty, (unsigned char*)pBuffer); - delete[] pBuffer; - return pRet; - } + // textures must be power of two squared + unsigned int powW = ccNextPOT(w); + unsigned int powH = ccNextPOT(h); + + void *data = malloc((int)(powW * powH * 4)); + CCX_BREAK_IF(! data); + + memset(data, 0, (int)(powW * powH * 4)); + m_ePixelFormat = eFormat; + + m_pTexture = new CCTexture2D(); + CCX_BREAK_IF(! m_pTexture); + + m_pTexture->initWithData(data, m_ePixelFormat, powW, powH, CGSizeMake((float)w, (float)h)); + free( data ); + + // generate FBO + ccglGenFramebuffers(1, &m_uFBO); + ccglBindFramebuffer(CC_GL_FRAMEBUFFER, m_uFBO); + + // associate texture with FBO + ccglFramebufferTexture2D(CC_GL_FRAMEBUFFER, CC_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pTexture->getName(), 0); + + // check if it worked (probably worth doing :) ) + GLuint status = ccglCheckFramebufferStatus(CC_GL_FRAMEBUFFER); + if (status != CC_GL_FRAMEBUFFER_COMPLETE) + { + NSAssert(0, "Render Texture : Could not attach texture to framebuffer"); + CCX_SAFE_DELETE(m_pTexture); + break; + } + + m_pTexture->setAliasTexParameters(); + + m_pSprite = CCSprite::spriteWithTexture(m_pTexture); + + m_pTexture->release(); + m_pSprite->setScaleY(-1); + this->addChild(m_pSprite); + + ccBlendFunc tBlendFunc = {GL_ONE, GL_ONE_MINUS_SRC_ALPHA }; + m_pSprite->setBlendFunc(tBlendFunc); + + ccglBindFramebuffer(CC_GL_FRAMEBUFFER, m_nOldFBO); + bRet = true; + } while (0); + return bRet; + +} + +void CCRenderTexture::begin() +{ + saveGLstate(); + + CC_DISABLE_DEFAULT_GL_STATES(); + // Save the current matrix + glPushMatrix(); + + CGSize texSize = m_pTexture->getContentSizeInPixels(); + + // Calculate the adjustment ratios based on the old and new projections + CGSize size = CCDirector::sharedDirector()->getDisplaySizeInPixels(); + float widthRatio = size.width / texSize.width; + float heightRatio = size.height / texSize.height; + + // Adjust the orthographic propjection and viewport + ccglOrtho((float)-1.0 / widthRatio, (float)1.0 / widthRatio, (float)-1.0 / heightRatio, (float)1.0 / heightRatio, -1,1); + glViewport(0, 0, (GLsizei)texSize.width, (GLsizei)texSize.height); + + glGetIntegerv(CC_GL_FRAMEBUFFER_BINDING, &m_nOldFBO); + ccglBindFramebuffer(CC_GL_FRAMEBUFFER, m_uFBO);//Will direct drawing to the frame buffer created above + + CC_ENABLE_DEFAULT_GL_STATES(); +} + +void CCRenderTexture::beginWithClear(float r, float g, float b, float a) +{ + this->saveGLstate(); + + CC_DISABLE_DEFAULT_GL_STATES(); + // Save the current matrix + glPushMatrix(); + + CGSize texSize = m_pTexture->getContentSizeInPixels(); + + // Calculate the adjustment ratios based on the old and new projections + CGSize size = CCDirector::sharedDirector()->getDisplaySizeInPixels(); + float widthRatio = size.width / texSize.width; + float heightRatio = size.height / texSize.height; + + // Adjust the orthographic propjection and viewport + ccglOrtho((float)-1.0 / widthRatio, (float)1.0 / widthRatio, (float)-1.0 / heightRatio, (float)1.0 / heightRatio, -1,1); + glViewport(0, 0, texSize.width, texSize.height); + + glGetIntegerv(CC_GL_FRAMEBUFFER_BINDING, &m_oldFBO); + ccglBindFramebuffer(CC_GL_FRAMEBUFFER, m_fbo);//Will direct drawing to the frame buffer created above + + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + CC_ENABLE_DEFAULT_GL_STATES(); +} + +void CCRenderTexture::end() +{ + ccglBindFramebuffer(CC_GL_FRAMEBUFFER, m_nOldFBO); + // Restore the original matrix and viewport + glPopMatrix(); + CGSize size = CCDirector::sharedDirector()->getDisplaySizeInPixels(); + glViewport(0, 0, (GLsizei)size.width, (GLsizei)size.height); + this->restoreGLstate(); +} + +void CCRenderTexture::clear(float r, float g, float b, float a) +{ + this->begin(); + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + this->end(); +} + +void CCRenderTexture::saveGLstate() +{ + glGetFloatv(GL_COLOR_CLEAR_VALUE, m_aClearColor); +} + +void CCRenderTexture::restoreGLstate() +{ + glClearColor(m_aClearColor[0], m_aClearColor[1], m_aClearColor[2], m_aClearColor[3]); +} + + +bool CCRenderTexture::saveBuffer(const char *name) +{ + return this->saveBuffer(name, kCCImageFormatJPG); +} +bool CCRenderTexture::saveBuffer(const char *fileName, int format) +{ + bool bRet = false; +//@ todo CCRenderTexture::saveBuffer +// UIImage *myImage = this->getUIImageFromBuffer(format); +// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); +// NSString *documentsDirectory = [paths objectAtIndex:0]; +// NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:fileName]; + +// NSData * data = this->getUIImageAsDataFromBuffer(format); +// if (data) +// { +// bRet = data->writeToFile(path, true); +// delete data; +// bRet = true; +// } + return bRet; +} + +NSData * CCRenderTexture::getUIImageAsDataFromBuffer(int format) +{ + NSData * pData = NULL; +//@ todo CCRenderTexture::getUIImageAsDataFromBuffer + +// #include "Availability.h" +// #include "UIKit.h" + +// GLubyte * pBuffer = NULL; +// GLubyte * pPixels = NULL; +// do +// { +// CCX_BREAK_IF(! m_pTexture); +// +// NSAssert(m_ePixelFormat == kCCTexture2DPixelFormat_RGBA8888, "only RGBA8888 can be saved as image"); +// +// CGSize s = m_pTexture->getContentSizeInPixels(); +// int tx = s.width; +// int ty = s.height; +// +// int bitsPerComponent = 8; +// int bitsPerPixel = 32; +// +// int bytesPerRow = (bitsPerPixel / 8) * tx; +// int myDataLength = bytesPerRow * ty; +// +// CCX_BREAK_IF(! (pBuffer = new GLubyte[tx * ty * 4])); +// CCX_BREAK_IF(! (pPixels = new GLubyte[tx * ty * 4])); +// +// this->begin(); +// glReadPixels(0,0,tx,ty,GL_RGBA,GL_UNSIGNED_BYTE, pBuffer); +// this->end(); +// +// int x,y; +// +// for(y = 0; y initWithWidth(w, path, length, color, fade)) + { + pRet->autorelease(); + return pRet; + } + CCX_SAFE_DELETE(pRet) + return NULL; +} + +bool CCRibbon::initWithWidth(float w, const char *path, float length, ccColor4B color, float fade) +{ + m_pSegments = new NSMutableArray(); + m_pDeletedSegments = new NSMutableArray(); + + /* 1 initial segment */ + CCRibbonSegment* seg = new CCRibbonSegment(); + seg->init(); + m_pSegments->addObject(seg); + seg->release(); + + m_fTextureLength = length; + + m_tColor = color; + m_fFadeTime = fade; + m_tLastLocation = CGPointZero; + m_fLastWidth = w/2; + m_fTexVPos = 0.0f; + + m_fCurTime = 0; + m_bPastFirstPoint = false; + + /* XXX: + Ribbon, by default uses this blend function, which might not be correct + if you are using premultiplied alpha images, + but 99% you might want to use this blending function regarding of the texture */ + m_tBlendFunc.src = GL_SRC_ALPHA; + m_tBlendFunc.dst = GL_ONE_MINUS_SRC_ALPHA; - // - // Ribbon - // - CCRibbon * CCRibbon::ribbonWithWidth(float w, const char *path, float length, ccColor4B color, float fade) + m_pTexture = CCTextureCache::sharedTextureCache()->addImage(path); + CCX_SAFE_RETAIN(m_pTexture); + + /* default texture parameter */ + ccTexParams params = { GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT }; + m_pTexture->setTexParameters(¶ms); + return true; +} + +CCRibbon::~CCRibbon() +{ + CCX_SAFE_RELEASE(m_pSegments); + CCX_SAFE_RELEASE(m_pDeletedSegments); + CCX_SAFE_RELEASE(m_pTexture); +} + +CGPoint CCRibbon::rotatePoint(CGPoint vec, float rotation) +{ + float xtemp = (vec.x * cosf(rotation)) - (vec.y * sinf(rotation)); + vec.y = (vec.x * sinf(rotation)) + (vec.y * cosf(rotation)); + vec.x = xtemp; + return vec; +} + +void CCRibbon::update(ccTime delta) +{ + m_fCurTime += delta; + m_fDelta = delta; +} + +float CCRibbon::sideOfLine(CGPoint p, CGPoint l1, CGPoint l2) +{ + CGPoint vp = ccpPerp(ccpSub(l1, l2)); + CGPoint vx = ccpSub(p, l1); + return ccpDot(vx, vp); +} + +// adds a new segment to the ribbon +void CCRibbon::addPointAt(CGPoint location, float width) +{ + location.x *= CC_CONTENT_SCALE_FACTOR(); + location.y *= CC_CONTENT_SCALE_FACTOR(); + + width = width * 0.5f; + // if this is the first point added, cache it and return + if (!m_bPastFirstPoint) { - CCRibbon *pRet = new CCRibbon(); - if(pRet && pRet->initWithWidth(w, path, length, color, fade)) - { - pRet->autorelease(); - return pRet; - } - CCX_SAFE_DELETE(pRet) - return NULL; - } - bool CCRibbon::initWithWidth(float w, const char *path, float length, ccColor4B color, float fade) - { - m_pSegments = new NSMutableArray(); - m_pDeletedSegments = new NSMutableArray(); - - /* 1 initial segment */ - CCRibbonSegment* seg = new CCRibbonSegment(); - seg->init(); - m_pSegments->addObject(seg); - seg->release(); - - m_fTextureLength = length; - - m_tColor = color; - m_fFadeTime = fade; - m_tLastLocation = CGPointZero; - m_fLastWidth = w/2; - m_fTexVPos = 0.0f; - - m_fCurTime = 0; - m_bPastFirstPoint = false; - - /* XXX: - Ribbon, by default uses this blend function, which might not be correct - if you are using premultiplied alpha images, - but 99% you might want to use this blending function regarding of the texture - */ - m_tBlendFunc.src = GL_SRC_ALPHA; - m_tBlendFunc.dst = GL_ONE_MINUS_SRC_ALPHA; - - m_pTexture = CCTextureCache::sharedTextureCache()->addImage(path); - CCX_SAFE_RETAIN(m_pTexture); - - /* default texture parameter */ - ccTexParams params = { GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT }; - m_pTexture->setTexParameters(¶ms); - return true; - } - CCRibbon::~CCRibbon() - { - m_pSegments->release(); - m_pDeletedSegments->release(); - m_pTexture->release(); - } - CGPoint CCRibbon::rotatePoint(CGPoint vec, float rotation) - { - float xtemp = (vec.x * cosf(rotation)) - (vec.y * sinf(rotation)); - vec.y = (vec.x * sinf(rotation)) + (vec.y * cosf(rotation)); - vec.x = xtemp; - return vec; - } - void CCRibbon::update(ccTime delta) - { - m_fCurTime += delta; - m_fDelta = delta; - } - float CCRibbon::sideOfLine(CGPoint p, CGPoint l1, CGPoint l2) - { - CGPoint vp = ccpPerp(ccpSub(l1, l2)); - CGPoint vx = ccpSub(p, l1); - return ccpDot(vx, vp); - } - - // adds a new segment to the ribbon - void CCRibbon::addPointAt(CGPoint location, float width) - { - width = width * 0.5f; - // if this is the first point added, cache it and return - if (!m_bPastFirstPoint) - { - m_fLastWidth = width; - m_tLastLocation = location; - m_bPastFirstPoint = true; - return; - } - - CGPoint sub = ccpSub(m_tLastLocation, location); - float r = ccpToAngle(sub) + (float)M_PI_2; - CGPoint p1 = ccpAdd(this->rotatePoint(ccp(-width, 0), r), location); - CGPoint p2 = ccpAdd(this->rotatePoint(ccp(+width, 0), r), location); - float len = sqrtf(powf(m_tLastLocation.x - location.x, 2) + powf(m_tLastLocation.y - location.y, 2)); - float tend = m_fTexVPos + len/m_fTextureLength; - CCRibbonSegment* seg; - // grab last segment - seg = m_pSegments->getLastObject(); - // lets kill old segments - if (m_pSegments && m_pSegments->count()>0) - { - NSMutableArray::NSMutableArrayIterator it; - for (it = m_pSegments->begin(); it != m_pSegments->end(); ++it) - { - if (*it != seg && (*it)->m_bFinished) - { - m_pDeletedSegments->addObject(*it); - } - } - } - - m_pSegments->removeObjectsInArray(m_pDeletedSegments); - // is the segment full? - if (seg->m_uEnd >= 50) - { - m_pSegments->removeObjectsInArray(m_pDeletedSegments); - } - // grab last segment and append to it if it's not full - seg = m_pSegments->getLastObject(); - // is the segment full? - if (seg->m_uEnd >= 50) - { - CCRibbonSegment* newSeg; - // grab it from the cache if we can - if (m_pDeletedSegments->count() > 0) - { - newSeg = m_pDeletedSegments->getObjectAtIndex(0); - newSeg->retain(); // will be released later - m_pDeletedSegments->removeObject(newSeg); - newSeg->reset(); - } - else - { - newSeg = new CCRibbonSegment(); // will be released later - newSeg->init(); - } - - newSeg->m_pCreationTime[0] = seg->m_pCreationTime[seg->m_uEnd- 1]; - int v = (seg->m_uEnd-1)*6; - int c = (seg->m_uEnd-1)*4; - newSeg->m_pVerts[0] = seg->m_pVerts[v]; - newSeg->m_pVerts[1] = seg->m_pVerts[v+1]; - newSeg->m_pVerts[2] = seg->m_pVerts[v+2]; - newSeg->m_pVerts[3] = seg->m_pVerts[v+3]; - newSeg->m_pVerts[4] = seg->m_pVerts[v+4]; - newSeg->m_pVerts[5] = seg->m_pVerts[v+5]; - - newSeg->m_pCoords[0] = seg->m_pCoords[c]; - newSeg->m_pCoords[1] = seg->m_pCoords[c+1]; - newSeg->m_pCoords[2] = seg->m_pCoords[c+2]; - newSeg->m_pCoords[3] = seg->m_pCoords[c+3]; - newSeg->m_uEnd++; - seg = newSeg; - m_pSegments->addObject(seg); - newSeg->release();// it was retained before - } - if (seg->m_uEnd == 0) - { - // first edge has to get rotation from the first real polygon - CGPoint lp1 = ccpAdd(this->rotatePoint(ccp(-m_fLastWidth, 0), r), m_tLastLocation); - CGPoint lp2 = ccpAdd(this->rotatePoint(ccp(+m_fLastWidth, 0), r), m_tLastLocation); - seg->m_pCreationTime[0] = m_fCurTime - m_fDelta; - seg->m_pVerts[0] = lp1.x; - seg->m_pVerts[1] = lp1.y; - seg->m_pVerts[2] = 0.0f; - seg->m_pVerts[3] = lp2.x; - seg->m_pVerts[4] = lp2.y; - seg->m_pVerts[5] = 0.0f; - seg->m_pCoords[0] = 0.0f; - seg->m_pCoords[1] = m_fTexVPos; - seg->m_pCoords[2] = 1.0f; - seg->m_pCoords[3] = m_fTexVPos; - seg->m_uEnd++; - } - - int v = seg->m_uEnd*6; - int c = seg->m_uEnd*4; - // add new vertex - seg->m_pCreationTime[seg->m_uEnd] = m_fCurTime; - seg->m_pVerts[v] = p1.x; - seg->m_pVerts[v+1] = p1.y; - seg->m_pVerts[v+2] = 0.0f; - seg->m_pVerts[v+3] = p2.x; - seg->m_pVerts[v+4] = p2.y; - seg->m_pVerts[v+5] = 0.0f; - - - seg->m_pCoords[c] = 0.0f; - seg->m_pCoords[c+1] = tend; - seg->m_pCoords[c+2] = 1.0f; - seg->m_pCoords[c+3] = tend; - - m_fTexVPos = tend; - m_tLastLocation = location; - m_tLastPoint1 = p1; - m_tLastPoint2 = p2; m_fLastWidth = width; - seg->m_uEnd++; + m_tLastLocation = location; + m_bPastFirstPoint = true; + return; } - void CCRibbon::draw() + + CGPoint sub = ccpSub(m_tLastLocation, location); + float r = ccpToAngle(sub) + (float)M_PI_2; + CGPoint p1 = ccpAdd(this->rotatePoint(ccp(-width, 0), r), location); + CGPoint p2 = ccpAdd(this->rotatePoint(ccp(+width, 0), r), location); + float len = sqrtf(powf(m_tLastLocation.x - location.x, 2) + powf(m_tLastLocation.y - location.y, 2)); + float tend = m_fTexVPos + len/m_fTextureLength; + CCRibbonSegment* seg; + // grab last segment + seg = m_pSegments->getLastObject(); + // lets kill old segments + if (m_pSegments && m_pSegments->count()>0) { - if (m_pSegments->count() > 0) + NSMutableArray::NSMutableArrayIterator it; + for (it = m_pSegments->begin(); it != m_pSegments->end(); ++it) { - // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY - // Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY - // Unneeded states: GL_COLOR_ARRAY - glDisableClientState(GL_COLOR_ARRAY); - - glBindTexture(GL_TEXTURE_2D, m_pTexture->getName()); - - bool newBlend = false; - if( m_tBlendFunc.src != CC_BLEND_SRC || m_tBlendFunc.dst != CC_BLEND_DST ) + if (*it != seg && (*it)->m_bFinished) { - newBlend = true; - glBlendFunc( m_tBlendFunc.src, m_tBlendFunc.dst ); + m_pDeletedSegments->addObject(*it); } - - if(m_pSegments && m_pSegments->count() > 0) - { - CCRibbonSegment* seg; - NSMutableArray::NSMutableArrayIterator it; - for( it = m_pSegments->begin(); it != m_pSegments->end(); it++) - { - seg = (CCRibbonSegment*)*it; - seg->draw(m_fCurTime, m_fFadeTime, m_tColor); - } - } - - if( newBlend ) - { - glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST); - } - - // restore default GL state - glEnableClientState( GL_COLOR_ARRAY ); } } - - // Ribbon - CocosNodeTexture protocol - void CCRibbon::setTexture(CCTexture2D* var) + + m_pSegments->removeObjectsInArray(m_pDeletedSegments); + // is the segment full? + if (seg->m_uEnd >= 50) { - CCX_SAFE_RETAIN(var); - CCX_SAFE_RELEASE(m_pTexture); - m_pTexture = var; - this->setContentSize(m_pTexture->getContentSize()); - /* XXX Don't update blending function in Ribbons */ + m_pSegments->removeObjectsInArray(m_pDeletedSegments); } - CCTexture2D *CCRibbon::getTexture() + // grab last segment and append to it if it's not full + seg = m_pSegments->getLastObject(); + // is the segment full? + if (seg->m_uEnd >= 50) { - return m_pTexture; - } - void CCRibbon::setTextureLength(float var) - { - m_fTextureLength = var; - } - float CCRibbon::getTextureLength() - { - return m_fTextureLength; - } - void CCRibbon::setBlendFunc(ccBlendFunc var) - { - m_tBlendFunc = var; - } - ccBlendFunc CCRibbon::getBlendFunc() - { - return m_tBlendFunc; - } - void CCRibbon::setColor(ccColor4B var) - { - m_tColor = var; - } - ccColor4B CCRibbon::getColor() - { - return m_tColor; - } - - // - //RibbonSegment - // - bool CCRibbonSegment::init() - { - this->reset(); - return true; - } - char * CCRibbonSegment::description() - { - char *ret = new char[100] ; - sprintf(ret, "", m_uEnd, m_uBegin); - return ret; - } - CCRibbonSegment::~CCRibbonSegment() - { - CCLOGINFO("cocos2d: deallocing."); - } - void CCRibbonSegment::reset() - { - m_uEnd = 0; - m_uBegin = 0; - m_bFinished = false; - } - void CCRibbonSegment::draw(float curTime, float fadeTime, ccColor4B color) - { - GLubyte r = color.r; - GLubyte g = color.g; - GLubyte b = color.b; - GLubyte a = color.a; - - if (m_uBegin < 50) + CCRibbonSegment* newSeg; + // grab it from the cache if we can + if (m_pDeletedSegments->count() > 0) { - // the motion streak class will call update and cause time to change, thus, if curTime_ != 0 - // we have to generate alpha for the ribbon each frame. - if (curTime == 0) - { - // no alpha over time, so just set the color - glColor4ub(r,g,b,a); - } - else - { - // generate alpha/color for each point - glEnableClientState(GL_COLOR_ARRAY); - unsigned int i = m_uBegin; - for (; i < m_uEnd; ++i) - { - int idx = i*8; - m_pColors[idx] = r; - m_pColors[idx+1] = g; - m_pColors[idx+2] = b; - m_pColors[idx+4] = r; - m_pColors[idx+5] = g; - m_pColors[idx+6] = b; - float alive = ((curTime - m_pCreationTime[i]) / fadeTime); - if (alive > 1) - { - m_uBegin++; - m_pColors[idx+3] = 0; - m_pColors[idx+7] = 0; - } - else - { - m_pColors[idx+3] = (GLubyte)(255.f - (alive * 255.f)); - m_pColors[idx+7] = m_pColors[idx+3]; - } - } - glColorPointer(4, GL_UNSIGNED_BYTE, 0, &m_pColors[m_uBegin*8]); - } - glVertexPointer(3, GL_FLOAT, 0, &m_pVerts[m_uBegin*6]); - glTexCoordPointer(2, GL_FLOAT, 0, &m_pCoords[m_uBegin*4]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, (m_uEnd - m_uBegin) * 2); + newSeg = m_pDeletedSegments->getObjectAtIndex(0); + newSeg->retain(); // will be released later + m_pDeletedSegments->removeObject(newSeg); + newSeg->reset(); } else { - m_bFinished = true; + newSeg = new CCRibbonSegment(); // will be released later + newSeg->init(); } + + newSeg->m_pCreationTime[0] = seg->m_pCreationTime[seg->m_uEnd- 1]; + int v = (seg->m_uEnd-1)*6; + int c = (seg->m_uEnd-1)*4; + newSeg->m_pVerts[0] = seg->m_pVerts[v]; + newSeg->m_pVerts[1] = seg->m_pVerts[v+1]; + newSeg->m_pVerts[2] = seg->m_pVerts[v+2]; + newSeg->m_pVerts[3] = seg->m_pVerts[v+3]; + newSeg->m_pVerts[4] = seg->m_pVerts[v+4]; + newSeg->m_pVerts[5] = seg->m_pVerts[v+5]; + + newSeg->m_pCoords[0] = seg->m_pCoords[c]; + newSeg->m_pCoords[1] = seg->m_pCoords[c+1]; + newSeg->m_pCoords[2] = seg->m_pCoords[c+2]; + newSeg->m_pCoords[3] = seg->m_pCoords[c+3]; + newSeg->m_uEnd++; + seg = newSeg; + m_pSegments->addObject(seg); + newSeg->release();// it was retained before + } + if (seg->m_uEnd == 0) + { + // first edge has to get rotation from the first real polygon + CGPoint lp1 = ccpAdd(this->rotatePoint(ccp(-m_fLastWidth, 0), r), m_tLastLocation); + CGPoint lp2 = ccpAdd(this->rotatePoint(ccp(+m_fLastWidth, 0), r), m_tLastLocation); + seg->m_pCreationTime[0] = m_fCurTime - m_fDelta; + seg->m_pVerts[0] = lp1.x; + seg->m_pVerts[1] = lp1.y; + seg->m_pVerts[2] = 0.0f; + seg->m_pVerts[3] = lp2.x; + seg->m_pVerts[4] = lp2.y; + seg->m_pVerts[5] = 0.0f; + seg->m_pCoords[0] = 0.0f; + seg->m_pCoords[1] = m_fTexVPos; + seg->m_pCoords[2] = 1.0f; + seg->m_pCoords[3] = m_fTexVPos; + seg->m_uEnd++; } -}// namespace cocos2d \ No newline at end of file + int v = seg->m_uEnd*6; + int c = seg->m_uEnd*4; + // add new vertex + seg->m_pCreationTime[seg->m_uEnd] = m_fCurTime; + seg->m_pVerts[v] = p1.x; + seg->m_pVerts[v+1] = p1.y; + seg->m_pVerts[v+2] = 0.0f; + seg->m_pVerts[v+3] = p2.x; + seg->m_pVerts[v+4] = p2.y; + seg->m_pVerts[v+5] = 0.0f; + + + seg->m_pCoords[c] = 0.0f; + seg->m_pCoords[c+1] = tend; + seg->m_pCoords[c+2] = 1.0f; + seg->m_pCoords[c+3] = tend; + + m_fTexVPos = tend; + m_tLastLocation = location; + m_tLastPoint1 = p1; + m_tLastPoint2 = p2; + m_fLastWidth = width; + seg->m_uEnd++; +} + +void CCRibbon::draw() +{ + if (m_pSegments->count() > 0) + { + // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY + // Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY + // Unneeded states: GL_COLOR_ARRAY + glDisableClientState(GL_COLOR_ARRAY); + + glBindTexture(GL_TEXTURE_2D, m_pTexture->getName()); + + bool newBlend = ( m_tBlendFunc.src != CC_BLEND_SRC || m_tBlendFunc.dst != CC_BLEND_DST ) ? true : false; + if( newBlend ) + { + glBlendFunc( m_tBlendFunc.src, m_tBlendFunc.dst ); + } + + if(m_pSegments && m_pSegments->count() > 0) + { + CCRibbonSegment* seg; + NSMutableArray::NSMutableArrayIterator it; + for( it = m_pSegments->begin(); it != m_pSegments->end(); it++) + { + seg = (CCRibbonSegment*)*it; + seg->draw(m_fCurTime, m_fFadeTime, m_tColor); + } + } + + if( newBlend ) + { + glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST); + } + + // restore default GL state + glEnableClientState( GL_COLOR_ARRAY ); + } +} + +// Ribbon - CocosNodeTexture protocol +void CCRibbon::setTexture(CCTexture2D* var) +{ + CCX_SAFE_RETAIN(var); + CCX_SAFE_RELEASE(m_pTexture); + m_pTexture = var; + this->setContentSize(m_pTexture->getContentSizeInPixels()); + /* XXX Don't update blending function in Ribbons */ +} + +CCTexture2D *CCRibbon::getTexture() +{ + return m_pTexture; +} + +void CCRibbon::setTextureLength(float var) +{ + m_fTextureLength = var; +} + +float CCRibbon::getTextureLength() +{ + return m_fTextureLength; +} +void CCRibbon::setBlendFunc(ccBlendFunc var) +{ + m_tBlendFunc = var; +} + +ccBlendFunc CCRibbon::getBlendFunc() +{ + return m_tBlendFunc; +} + +void CCRibbon::setColor(ccColor4B var) +{ + m_tColor = var; +} +ccColor4B CCRibbon::getColor() +{ + return m_tColor; +} + +// +//RibbonSegment +// +bool CCRibbonSegment::init() +{ + this->reset(); + return true; +} + +char * CCRibbonSegment::description() +{ + char *ret = new char[100] ; + sprintf(ret, "", m_uEnd, m_uBegin); + return ret; +} + +CCRibbonSegment::~CCRibbonSegment() +{ + CCLOGINFO("cocos2d: deallocing."); +} + +void CCRibbonSegment::reset() +{ + m_uEnd = 0; + m_uBegin = 0; + m_bFinished = false; +} + +void CCRibbonSegment::draw(float curTime, float fadeTime, ccColor4B color) +{ + GLubyte r = color.r; + GLubyte g = color.g; + GLubyte b = color.b; + GLubyte a = color.a; + + if (m_uBegin < 50) + { + // the motion streak class will call update and cause time to change, thus, if curTime_ != 0 + // we have to generate alpha for the ribbon each frame. + if (curTime == 0) + { + // no alpha over time, so just set the color + glColor4ub(r,g,b,a); + } + else + { + // generate alpha/color for each point + glEnableClientState(GL_COLOR_ARRAY); + unsigned int i = m_uBegin; + for (; i < m_uEnd; ++i) + { + int idx = i*8; + m_pColors[idx] = r; + m_pColors[idx+1] = g; + m_pColors[idx+2] = b; + m_pColors[idx+4] = r; + m_pColors[idx+5] = g; + m_pColors[idx+6] = b; + float alive = ((curTime - m_pCreationTime[i]) / fadeTime); + if (alive > 1) + { + m_uBegin++; + m_pColors[idx+3] = 0; + m_pColors[idx+7] = 0; + } + else + { + m_pColors[idx+3] = (GLubyte)(255.f - (alive * 255.f)); + m_pColors[idx+7] = m_pColors[idx+3]; + } + } + glColorPointer(4, GL_UNSIGNED_BYTE, 0, &m_pColors[m_uBegin*8]); + } + glVertexPointer(3, GL_FLOAT, 0, &m_pVerts[m_uBegin*6]); + glTexCoordPointer(2, GL_FLOAT, 0, &m_pCoords[m_uBegin*4]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, (m_uEnd - m_uBegin) * 2); + } + else + { + m_bFinished = true; + } +} + +}// namespace cocos2d diff --git a/cocos2dx/platform/uphone/CCXCocos2dDefine_uphone.h b/cocos2dx/platform/uphone/CCXCocos2dDefine_uphone.h index 676470788a..c90229af6a 100644 --- a/cocos2dx/platform/uphone/CCXCocos2dDefine_uphone.h +++ b/cocos2dx/platform/uphone/CCXCocos2dDefine_uphone.h @@ -81,6 +81,7 @@ public: inline varType get##funName(void){ return varName; }\ public: inline void set##funName(varType var){ varName = var; } #define CCX_SAFE_DELETE(p) if(p) { delete p; p=NULL; } +#define CCX_SAFE_DELETE_ARRAY(p) if(p) { delete[] p; p=NULL; } #define CCX_SAFE_FREE(p) if(p) { free(p); p=NULL; } #define CCX_SAFE_RELEASE(p) if(p) { p->release(); } #define CCX_SAFE_RELEASE_NULL(p) if(p) { p->release(); p = NULL; } diff --git a/cocos2dx/platform/uphone/CCXUIImage_uphone.cpp b/cocos2dx/platform/uphone/CCXUIImage_uphone.cpp index a7014a37fe..b190b783cb 100644 --- a/cocos2dx/platform/uphone/CCXUIImage_uphone.cpp +++ b/cocos2dx/platform/uphone/CCXUIImage_uphone.cpp @@ -116,7 +116,7 @@ UIImage::~UIImage(void) } } -bool UIImage::initWithContentsOfFile(const string &strPath, tImageFormat imageType) +bool UIImage::initWithContentsOfFile(const string &strPath, eImageFormat imageType) { bool bRet = false; @@ -138,11 +138,11 @@ bool UIImage::initWithContentsOfFile(const string &strPath, tImageFormat imageTy { switch (imageType) { - case kImageFormatPNG: + case kCCImageFormatPNG: // use libpng load image bRet = loadPngFromStream(pBuffer, nSize); break; - case kImageFormatJPG: + case kCCImageFormatJPG: bRet = loadJpgFromStream(pBuffer, nSize); break; default: diff --git a/cocos2dx/platform/uphone/CCXUIImage_uphone.h b/cocos2dx/platform/uphone/CCXUIImage_uphone.h index 90c531528f..ac9f2ca6ca 100644 --- a/cocos2dx/platform/uphone/CCXUIImage_uphone.h +++ b/cocos2dx/platform/uphone/CCXUIImage_uphone.h @@ -64,7 +64,7 @@ public: - kImageFormatJPG -> jpeg @return true if load correctly */ - bool initWithContentsOfFile(const std::string &strPath, tImageFormat imageType = kImageFormatPNG); + bool initWithContentsOfFile(const std::string &strPath, eImageFormat imageType = kCCImageFormatPNG); /** Load image from stream buffer. @param pBuffer stream buffer that hold the image data diff --git a/cocos2dx/textures/CCTextureCache.cpp b/cocos2dx/textures/CCTextureCache.cpp index e879d1579e..c8a6fd56f9 100644 --- a/cocos2dx/textures/CCTextureCache.cpp +++ b/cocos2dx/textures/CCTextureCache.cpp @@ -207,7 +207,7 @@ CCTexture2D * CCTextureCache::addImage(const char * path) else if (std::string::npos != lowerCase.find(".jpg") || std::string::npos != lowerCase.find(".jpeg")) { UIImage * image = new UIImage(); - if(! image->initWithContentsOfFile(fullpath, kImageFormatJPG)) + if(! image->initWithContentsOfFile(fullpath, kCCImageFormatJPG)) { delete image; break; @@ -235,7 +235,7 @@ CCTexture2D * CCTextureCache::addImage(const char * path) #else // prevents overloading the autorelease pool UIImage * image = new UIImage(); - if(! image->initWithContentsOfFile(fullpath, kImageFormatPNG)) + if(! image->initWithContentsOfFile(fullpath, kCCImageFormatPNG)) { delete image; break;