mirror of https://github.com/axmolengine/axmol.git
merge mingo-upto-0.99.5 to upto-0.99.5
This commit is contained in:
commit
33ad2881b7
|
@ -43,10 +43,10 @@ namespace cocos2d
|
|||
glGetIntegerv(CC_GL_FRAMEBUFFER_BINDING, &m_oldFBO);
|
||||
|
||||
// bind
|
||||
glBindFramebufferOES(CC_GL_FRAMEBUFFER, m_fbo);
|
||||
ccglBindFramebuffer(CC_GL_FRAMEBUFFER, m_fbo);
|
||||
|
||||
// associate texture with FBO
|
||||
glFramebufferTexture2DOES(CC_GL_FRAMEBUFFER, CC_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
ccglFramebufferTexture2D(CC_GL_FRAMEBUFFER, CC_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
pTexture->getName(), 0);
|
||||
|
||||
// check if it worked (probably worth doing :) )
|
||||
|
|
|
@ -26,7 +26,7 @@ THE SOFTWARE.
|
|||
#include "CCDirector.h"
|
||||
#include "CCGrabber.h"
|
||||
|
||||
#include "support/opengl_support/glu.h"
|
||||
#include "CCGL.h"
|
||||
#include "CGPointExtension.h"
|
||||
|
||||
namespace cocos2d
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#ifndef __CC_ANIMATION_H__
|
||||
#define __CC_ANIMATION_H__
|
||||
|
||||
#include "NSObject.h"
|
||||
#include "NSMutableArray.h"
|
||||
#include "CGGeometry.h"
|
||||
#include "CCXCocos2dDefine.h"
|
||||
#include <string.h>
|
||||
|
||||
namespace cocos2d {
|
||||
class CCSpriteFrame;
|
||||
class CCTexture2D;
|
||||
/** A CCAnimation object is used to perform animations on the CCSprite objects.
|
||||
|
||||
The CCAnimation object contains CCSpriteFrame objects, and a possible delay between the frames.
|
||||
You can animate a CCAnimation object by using the CCAnimate action. Example:
|
||||
|
||||
[sprite runAction:[CCAnimate actionWithAnimation:animation]];
|
||||
|
||||
*/
|
||||
class CCX_DLL CCAnimation : public NSObject
|
||||
{
|
||||
protected:
|
||||
std::string m_nameStr;
|
||||
float m_fDelay;
|
||||
NSMutableArray<CCSpriteFrame*> *m_pobFrames;
|
||||
|
||||
public:
|
||||
// attributes
|
||||
|
||||
/** get name of the animation */
|
||||
inline const char* getName(void) { return m_nameStr.c_str(); }
|
||||
/** set name of the animation */
|
||||
inline void setName(const char *pszName){ m_nameStr = pszName; }
|
||||
|
||||
/** get delay between frames in seconds */
|
||||
inline float getDelay(void) { return m_fDelay; }
|
||||
/** set delay between frames in seconds */
|
||||
inline void setDelay(float fDelay) { m_fDelay = fDelay; }
|
||||
|
||||
/** get array of frames */
|
||||
inline NSMutableArray<CCSpriteFrame*>* getFrames(void) { return m_pobFrames; }
|
||||
/** set array of frames, the Frames is retained */
|
||||
inline void setFrames(NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
CCX_SAFE_RETAIN(pFrames);
|
||||
CCX_SAFE_RELEASE(m_pobFrames);
|
||||
m_pobFrames = pFrames;
|
||||
}
|
||||
|
||||
public:
|
||||
~CCAnimation(void);
|
||||
|
||||
/** Initializes a CCAnimation with frames.
|
||||
@since v0.99.5
|
||||
*/
|
||||
bool initWithFrames(NSArray<CCSpriteFrame*> *pFrames);
|
||||
|
||||
/** Initializes a CCAnimation with frames and a delay between frames
|
||||
@since v0.99.5
|
||||
*/
|
||||
bool initWithFrames(NSArray<CCSpriteFrame*> *pFrames, float delay);
|
||||
|
||||
/** Initializes a CCAnimation with a name
|
||||
@since v0.99.3
|
||||
@deprecated Will be removed in 1.0.1. Use "init" instead.
|
||||
*/
|
||||
bool initWithName(const char *pszName);
|
||||
|
||||
/** Initializes a CCAnimation with a name and frames
|
||||
@since v0.99.3
|
||||
@deprecated Will be removed in 1.0.1. Use "initWithFrames" instead.
|
||||
*/
|
||||
bool initWithName(const char *pszName, NSArray<CCSpriteFrame*> *pFrames);
|
||||
|
||||
/** Initializes a CCAnimation with a name and delay between frames.
|
||||
@deprecated Will be removed in 1.0.1. Use "initWithFrames:nil delay:delay" instead.
|
||||
*/
|
||||
bool initWithName(const char *pszName, float fDelay);
|
||||
|
||||
/** Initializes a CCAnimation with a name, delay and an array of CCSpriteFrames.
|
||||
@deprecated Will be removed in 1.0.1. Use "initWithFrames:frames delay:delay" instead.
|
||||
*/
|
||||
bool initWithName(const char *pszName, float fDelay, NSArray<CCSpriteFrame*> *pFrames);
|
||||
|
||||
/** adds a frame to a CCAnimation */
|
||||
void addFrame(CCSpriteFrame *pFrame);
|
||||
|
||||
/** Adds a frame with an image filename. Internally it will create a CCSpriteFrame and it will add it.
|
||||
Added to facilitate the migration from v0.8 to v0.9.
|
||||
*/
|
||||
void addFrameWithFileName(const char *pszFileName);
|
||||
|
||||
/** Adds a frame with a texture and a rect. Internally it will create a CCSpriteFrame and it will add it.
|
||||
Added to facilitate the migration from v0.8 to v0.9.
|
||||
*/
|
||||
void addFrameWithTexture(CCTexture2D* pobTexture, CGRect rect);
|
||||
|
||||
bool init(void);
|
||||
|
||||
public:
|
||||
/** Creates an animation
|
||||
@since v0.99.5
|
||||
*/
|
||||
static CCAnimation* animation(void);
|
||||
|
||||
/** Creates an animation with frames.
|
||||
@since v0.99.5
|
||||
*/
|
||||
static CCAnimation* animationWithFrames(NSArray<CCSpriteFrame*> *frames);
|
||||
|
||||
/* Creates an animation with frames and a delay between frames.
|
||||
@since v0.99.5
|
||||
*/
|
||||
static CCAnimation* animationWithFrames(NSArray<CCSpriteFrame*> *frames, float delay);
|
||||
|
||||
/** Creates a CCAnimation with a name
|
||||
@since v0.99.3
|
||||
@deprecated Will be removed in 1.0.1. Use "animation" instead.
|
||||
*/
|
||||
static CCAnimation* animationWithName(const char *pszName);
|
||||
|
||||
/** Creates a CCAnimation with a name and frames
|
||||
@since v0.99.3
|
||||
@deprecated Will be removed in 1.0.1. Use "animationWithFrames" instead.
|
||||
*/
|
||||
static CCAnimation* animationWithName(const char *pszName, NSArray<CCSpriteFrame*> *pFrames);
|
||||
|
||||
/** Creates a CCAnimation with a name and delay between frames. */
|
||||
static CCAnimation* animationWithName(const char *pszName, float fDelay);
|
||||
|
||||
/** Creates a CCAnimation with a name, delay and an array of CCSpriteFrames. */
|
||||
static CCAnimation* animationWithName(const char *pszName, float fDelay, NSArray<CCSpriteFrame*> *pFrames);
|
||||
};
|
||||
} // end of name sapce cocos2d
|
||||
|
||||
#endif // __CC_ANIMATION_H__
|
|
@ -0,0 +1,70 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#ifndef __CC_ANIMATION_CACHE_H__
|
||||
#define __CC_ANIMATION_CACHE_H__
|
||||
|
||||
#include "NSObject.h"
|
||||
#include "NSMutableArray.h"
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
class CCAnimation;
|
||||
|
||||
/** Singleton that manages the Animations.
|
||||
It saves in a cache the animations. You should use this class if you want to save your animations in a cache.
|
||||
|
||||
Before v0.99.5, the recommend way was to save them on the CCSprite. Since v0.99.5, you should use this class instead.
|
||||
|
||||
@since v0.99.5
|
||||
*/
|
||||
class CCX_DLL CCAnimationCache : public NSObject
|
||||
{
|
||||
public:
|
||||
/** Retruns ths shared instance of the Animation cache */
|
||||
static CCAnimationCache* sharedAnimationCache(void);
|
||||
|
||||
/** Purges the cache. It releases all the CCAnimation objects and the shared instance.
|
||||
*/
|
||||
static void purgeSharedAnimationCache(void);
|
||||
|
||||
/** Adds a CCAnimation with a name.
|
||||
*/
|
||||
void addAnimation(CCAnimation *animation, const char * name);
|
||||
|
||||
/** Deletes a CCAnimation from the cache.
|
||||
*/
|
||||
void removeAnimationByName(const char* name);
|
||||
|
||||
/** Returns a CCAnimation that was previously added.
|
||||
If the name is not found it will return nil.
|
||||
You should retain the returned copy if you are going to use it.
|
||||
*/
|
||||
CCAnimation* animationByName(const char* name);
|
||||
|
||||
private:
|
||||
NSMutableArray<CCAnimation*> *m_pAnimations;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __CC_ANIMATION_CACHE_H__
|
|
@ -25,7 +25,6 @@ THE SOFTWARE.
|
|||
#ifndef __PLATFOMR_CCNODE_H__
|
||||
#define __PLATFOMR_CCNODE_H__
|
||||
|
||||
#include "config_platform.h"
|
||||
#include "CCXCocos2dDefine.h"
|
||||
#include "ccMacros.h"
|
||||
#include "CGAffineTransform.h"
|
||||
|
|
|
@ -35,7 +35,9 @@ THE SOFTWARE.
|
|||
#include <string>
|
||||
namespace cocos2d {
|
||||
|
||||
class CCSpriteBatchNode;
|
||||
class CCSpriteSheet;
|
||||
class CCSpriteSheetInternalOnly;
|
||||
class CCSpriteFrame;
|
||||
class CCAnimation;
|
||||
class CGRect;
|
||||
|
@ -45,7 +47,7 @@ class CCTexture2D;
|
|||
struct transformValues_;
|
||||
|
||||
enum {
|
||||
/// CCSprite invalid index on the CCSpriteSheet
|
||||
/// CCSprite invalid index on the CCSpriteBatchNode
|
||||
CCSpriteIndexNotInitialized = 0xffffffff,
|
||||
};
|
||||
|
||||
|
@ -68,27 +70,28 @@ typedef enum {
|
|||
|
||||
} ccHonorParentTransform;
|
||||
|
||||
/** @brief CCSprite is a 2d image ( http://en.wikipedia.org/wiki/Sprite_(computer_graphics) ).
|
||||
*
|
||||
* CCSprite can be created with an image, or with a sub-rectangle of an image.
|
||||
*
|
||||
* If the parent or any of its ancestors is a CCSpriteSheet then the following features/limitations are valid
|
||||
* - Features when the parent is a CCSpriteSheet:
|
||||
* - MUCH faster rendering, specially if the CCSpriteSheet has many children. All the children will be drawn in a single batch.
|
||||
*
|
||||
* - Limitations
|
||||
* - Camera is not supported yet (eg: CCOrbitCamera action doesn't work)
|
||||
* - GridBase actions are not supported (eg: CCLens, CCRipple, CCTwirl)
|
||||
* - The Alias/Antialias property belongs to CCSpriteSheet, so you can't individually set the aliased property.
|
||||
* - The Blending function property belongs to CCSpriteSheet, so you can't individually set the blending function property.
|
||||
* - Parallax scroller is not supported, but can be simulated with a "proxy" sprite.
|
||||
*
|
||||
* If the parent is an standard CCNode, then CCSprite behaves like any other CCNode:
|
||||
* - It supports blending functions
|
||||
* - It supports aliasing / antialiasing
|
||||
* - But the rendering will be slower: 1 draw per children.
|
||||
*
|
||||
*/
|
||||
/** CCSprite is a 2d image ( http://en.wikipedia.org/wiki/Sprite_(computer_graphics) )
|
||||
*
|
||||
* CCSprite can be created with an image, or with a sub-rectangle of an image.
|
||||
*
|
||||
* If the parent or any of its ancestors is a CCSpriteBatchNode then the following features/limitations are valid
|
||||
* - Features when the parent is a CCBatchNode:
|
||||
* - MUCH faster rendering, specially if the CCSpriteBatchNode has many children. All the children will be drawn in a single batch.
|
||||
*
|
||||
* - Limitations
|
||||
* - Camera is not supported yet (eg: CCOrbitCamera action doesn't work)
|
||||
* - GridBase actions are not supported (eg: CCLens, CCRipple, CCTwirl)
|
||||
* - The Alias/Antialias property belongs to CCSpriteBatchNode, so you can't individually set the aliased property.
|
||||
* - The Blending function property belongs to CCSpriteBatchNode, so you can't individually set the blending function property.
|
||||
* - Parallax scroller is not supported, but can be simulated with a "proxy" sprite.
|
||||
*
|
||||
* If the parent is an standard CCNode, then CCSprite behaves like any other CCNode:
|
||||
* - It supports blending functions
|
||||
* - It supports aliasing / antialiasing
|
||||
* - But the rendering will be slower: 1 draw per children.
|
||||
*
|
||||
* The default anchorPoint in CCSprite is (0.5, 0.5).
|
||||
*/
|
||||
class CCX_DLL CCSprite : public CCNode, public CCTextureProtocol, public CCRGBAProtocol
|
||||
{
|
||||
public:
|
||||
|
@ -104,6 +107,9 @@ public:
|
|||
|
||||
/** get the quad (tex coords, vertex coords and color) information */
|
||||
inline ccV3F_C4B_T2F_Quad getQuad(void) { return m_sQuad; }
|
||||
|
||||
/** returns whether or not the texture rectangle is rotated */
|
||||
inline bool isTextureRectTotated(void) { return m_bRectRotated; }
|
||||
|
||||
/** Set the index used on the TextureAtlas. */
|
||||
inline unsigned int getAtlasIndex(void) { return m_uAtlasIndex; }
|
||||
|
@ -112,19 +118,19 @@ public:
|
|||
*/
|
||||
inline void setAtlasIndex(unsigned int uAtlasIndex) { m_uAtlasIndex = uAtlasIndex; }
|
||||
|
||||
/** returns the rect of the CCSprite */
|
||||
/** returns the rect of the CCSprite in points */
|
||||
inline CGRect getTextureRect(void) { return m_obRect; }
|
||||
|
||||
/** whether or not the Sprite is rendered using a CCSpriteSheet */
|
||||
inline bool isUsesSpriteSheet(void) { return m_bUsesSpriteSheet; }
|
||||
/** make the Sprite been rendered using a CCSpriteSheet */
|
||||
inline void setUsesSpriteSheet(bool bUsesSpriteSheet) { m_bUsesSpriteSheet = bUsesSpriteSheet; }
|
||||
/** whether or not the Sprite is rendered using a CCSpriteBatchNode */
|
||||
inline bool isUsesBatchNode(void) { return m_bUsesBatchNode; }
|
||||
/** make the Sprite been rendered using a CCSpriteBatchNode */
|
||||
inline void setUsesSpriteBatchNode(bool bUsesSpriteBatchNode) { m_bUsesBatchNode = bUsesSpriteBatchNode; }
|
||||
|
||||
inline CCTextureAtlas* getTextureAtlas(void) { return m_pobTextureAtlas; }
|
||||
inline void setTextureAtlas(CCTextureAtlas *pobTextureAtlas) { m_pobTextureAtlas = pobTextureAtlas; }
|
||||
|
||||
inline CCSpriteSheet* getSpriteSheet(void) { return m_pobSpriteSheet; }
|
||||
inline void setSpriteSheet(CCSpriteSheet *pobSpriteSheet) { m_pobSpriteSheet = pobSpriteSheet; }
|
||||
inline CCSpriteBatchNode* getSpriteBatchNode(void) { return m_pobBatchNode; }
|
||||
inline void setSpriteBatchNode(CCSpriteBatchNode *pobSpriteBatchNode) { m_pobBatchNode = pobSpriteBatchNode; }
|
||||
|
||||
/** whether or not to transform according to its parent transformations.
|
||||
Useful for health bars. eg: Don't rotate the health bar, even if the parent rotates.
|
||||
|
@ -142,7 +148,7 @@ public:
|
|||
/** Get offset position of the sprite. Calculated automatically by editors like Zwoptex.
|
||||
@since v0.99.0
|
||||
*/
|
||||
inline CGPoint getOffsetPosition(void) { return m_obOffsetPosition; }
|
||||
inline CGPoint getOffsetPositionInPixels(void) { return m_obOffsetPositionInPixels; }
|
||||
|
||||
/** conforms to CCTextureProtocol protocol */
|
||||
inline ccBlendFunc getBlendFunc(void) { return m_sBlendFunc; }
|
||||
|
@ -184,12 +190,12 @@ public:
|
|||
The offset will be (0,0).
|
||||
*/
|
||||
static CCSprite* spriteWithFile(const char *pszFileName, CGRect rect);
|
||||
|
||||
/** Creates an sprite with an CCBatchNode and a rect
|
||||
*/
|
||||
static CCSprite* spriteWithBatchNode(CCSpriteBatchNode *batchNode, CGRect rect);
|
||||
|
||||
/** Creates an sprite with an CCSpriteSheet and a rect */
|
||||
static CCSprite* spriteWithSpriteSheet(CCSpriteSheet *pSpriteSheet, CGRect rect);
|
||||
|
||||
/** Creates an sprite with a texture, a rect and offset. */
|
||||
static CCSprite* spriteWithSpriteSheet(CCSpriteSheet *pSpriteSheet, CGRect rect, CGPoint offset);
|
||||
static CCSprite* spriteWithSpriteSheet(CCSpriteSheetInternalOnly *pSpriteSheet, CGRect rect);
|
||||
|
||||
public:
|
||||
bool init(void);
|
||||
|
@ -199,12 +205,13 @@ public:
|
|||
virtual void removeChild(CCNode* pChild, bool bCleanup);
|
||||
virtual void removeAllChildrenWithCleanup(bool bCleanup);
|
||||
virtual void reorderChild(CCNode *pChild, int zOrder);
|
||||
virtual CCNode* addChild(CCNode *pChild);
|
||||
virtual CCNode* addChild(CCNode *pChild, int zOrder);
|
||||
virtual CCNode* addChild(CCNode *pChild, int zOrder, int tag);
|
||||
virtual void addChild(CCNode *pChild);
|
||||
virtual void addChild(CCNode *pChild, int zOrder);
|
||||
virtual void addChild(CCNode *pChild, int zOrder, int tag);
|
||||
|
||||
virtual void setDirtyRecursively(bool bValue);
|
||||
virtual void setPosition(CGPoint pos);
|
||||
virtual void setPositionInPixels(CGPoint pos);
|
||||
virtual void setRotation(float fRotation);
|
||||
virtual void setScaleX(float fScaleX);
|
||||
virtual void setScaleY(float fScaleY);
|
||||
|
@ -281,10 +288,16 @@ public:
|
|||
*/
|
||||
bool initWithFile(const char *pszFilename, CGRect rect);
|
||||
|
||||
/** Initializes an sprite with an CCSpriteSheet and a rect */
|
||||
bool initWithSpriteSheet(CCSpriteSheet *pSpriteSheet, CGRect rect);
|
||||
/** Initializes an sprite with an CCSpriteSheet and a rect in points */
|
||||
bool initWithBatchNode(CCSpriteBatchNode *batchNode, CGRect rect);
|
||||
bool initWithSpriteSheet(CCSpriteSheetInternalOnly *pSpriteSheet, CGRect rect);
|
||||
|
||||
// sprite sheet methods
|
||||
/** Initializes an sprite with an CCSpriteSheet and a rect in pixels
|
||||
@since v0.99.5
|
||||
*/
|
||||
bool initWithBatchNodeRectInPixels(CCSpriteBatchNode *batchNode, CGRect rect);
|
||||
|
||||
// BatchNode methods
|
||||
|
||||
/** updates the quad according the the rotation, position, scale values. */
|
||||
void updateTransform(void);
|
||||
|
@ -294,13 +307,18 @@ public:
|
|||
*/
|
||||
void useSelfRender(void);
|
||||
|
||||
/** updates the texture rect of the CCSprite. */
|
||||
/** updates the texture rect of the CCSprite in points. */
|
||||
void setTextureRect(CGRect rect);
|
||||
|
||||
/** tell the sprite to use sprite sheet render.
|
||||
/** updates the texture rect, rectRotated and untrimmed size of the CCSprite in pixels
|
||||
*/
|
||||
void setTextureRectInPixels(CGRect rect, bool rotated, CGSize size);
|
||||
|
||||
/** tell the sprite to use batch node render.
|
||||
@since v0.99.0
|
||||
*/
|
||||
void useSpriteSheetRender(CCSpriteSheet *pSpriteSheet);
|
||||
void useBatchNode(CCSpriteBatchNode *batchNode);
|
||||
void useSpriteSheetRender(CCSpriteSheetInternalOnly *pSpriteSheet);
|
||||
|
||||
// Frames
|
||||
|
||||
|
@ -313,23 +331,36 @@ public:
|
|||
/** returns the current displayed frame. */
|
||||
CCSpriteFrame* displayedFrame(void);
|
||||
|
||||
/** adds an Animation to the Sprite. */
|
||||
/** adds an Animation to the Sprite.
|
||||
|
||||
@deprecated Use CCAnimationCache instead. Will be removed in 1.0.1
|
||||
*/
|
||||
void addAnimation(CCAnimation *pAnimation);
|
||||
|
||||
/** returns an Animation given it's name. */
|
||||
/** returns an Animation given it's name.
|
||||
|
||||
@deprecated Use CCAnimationCache instead. Will be removed in 1.0.1
|
||||
*/
|
||||
CCAnimation* animationByName(const char *pszAnimationName);
|
||||
|
||||
// Animation
|
||||
|
||||
/** changes the display frame based on an animation and an index. */
|
||||
/** changes the display frame based on an animation and an index.
|
||||
@deprecated Will be removed in 1.0.1. Use setDisplayFrameWithAnimationName:index instead
|
||||
*/
|
||||
void setDisplayFrame(const char *pszAnimationName, int nFrameIndex);
|
||||
|
||||
/** changes the display frame with animation name and index.
|
||||
The animation name will be get from the CCAnimationCache
|
||||
@since v0.99.5
|
||||
*/
|
||||
void setDisplayFrameWithAnimationName(const char *animationName, int frameIndex);
|
||||
|
||||
protected:
|
||||
void updateTextureCoords(CGRect rect);
|
||||
void updateBlendFunc(void);
|
||||
void initAnimationDictionary(void);
|
||||
void setTextureRect(CGRect rect, CGSize size);
|
||||
struct transformValues_ getTransformValues(void);
|
||||
void getTransformValues(struct transformValues_ *tv); // optimization
|
||||
|
||||
protected:
|
||||
//
|
||||
|
@ -337,7 +368,7 @@ protected:
|
|||
//
|
||||
CCTextureAtlas *m_pobTextureAtlas; // Sprite Sheet texture atlas (weak reference)
|
||||
unsigned int m_uAtlasIndex; // Absolute (real) Index on the SpriteSheet
|
||||
CCSpriteSheet *m_pobSpriteSheet; // Used spritesheet (weak reference)
|
||||
CCSpriteBatchNode *m_pobBatchNode; // Used batch node (weak reference)
|
||||
ccHonorParentTransform m_eHonorParentTransform;// whether or not to transform according to its parent transformations
|
||||
bool m_bDirty; // Sprite needs to be updated
|
||||
bool m_bRecursiveDirty; // Subchildren needs to be updated
|
||||
|
@ -353,14 +384,16 @@ protected:
|
|||
// Shared data
|
||||
//
|
||||
|
||||
// whether or not it's parent is a CCSpriteSheet
|
||||
bool m_bUsesSpriteSheet;
|
||||
// whether or not it's parent is a CCSpriteBatchNode
|
||||
bool m_bUsesBatchNode;
|
||||
|
||||
// texture pixels
|
||||
// texture
|
||||
CGRect m_obRect;
|
||||
CGRect m_obRectInPixels;
|
||||
bool m_bRectRotated;
|
||||
|
||||
// Offset Position (used by Zwoptex)
|
||||
CGPoint m_obOffsetPosition; // absolute
|
||||
CGPoint m_obOffsetPositionInPixels; // absolute
|
||||
CGPoint m_obUnflippedOffsetPositionFromCenter;
|
||||
|
||||
// vertex coords, texture coords and color info
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __CC_SPRITE_BATCH_NODE_H__
|
||||
#define __CC_SPRITE_BATCH_NODE_H__
|
||||
|
||||
#include "CCNode.h"
|
||||
#include "CCProtocols.h"
|
||||
#include "CCTextureAtlas.h"
|
||||
#include "ccMacros.h"
|
||||
#include "NSMutableArray.h"
|
||||
#include "CCXCocos2dDefine.h"
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
class CCSprite;
|
||||
|
||||
/** CCSpriteBatchNode is like a batch node: if it contains children, it will draw them in 1 single OpenGL call
|
||||
* (often known as "batch draw").
|
||||
*
|
||||
* A CCSpriteBatchNode can reference one and only one texture (one image file, one texture atlas).
|
||||
* Only the CCSprites that are contained in that texture can be added to the CCSpriteBatchNode.
|
||||
* All CCSprites added to a CCSpriteBatchNode are drawn in one OpenGL ES draw call.
|
||||
* If the CCSprites are not added to a CCSpriteBatchNode then an OpenGL ES draw call will be needed for each one, which is less efficient.
|
||||
*
|
||||
*
|
||||
* Limitations:
|
||||
* - The only object that is accepted as child (or grandchild, grand-grandchild, etc...) is CCSprite or any subclass of CCSprite. eg: particles, labels and layer can't be added to a CCSpriteBatchNode.
|
||||
* - Either all its children are Aliased or Antialiased. It can't be a mix. This is because "alias" is a property of the texture, and all the sprites share the same texture.
|
||||
*
|
||||
* @since v0.7.1
|
||||
*/
|
||||
class CCX_DLL CCSpriteBatchNode : public CCNode, public CCTextureProtocol
|
||||
{
|
||||
public:
|
||||
~CCSpriteBatchNode();
|
||||
|
||||
// property
|
||||
|
||||
// retain
|
||||
inline CCTextureAtlas* getTextureAtlas(void) { return m_pobTextureAtlas; }
|
||||
inline void setTextureAtlas(CCTextureAtlas* textureAtlas)
|
||||
{
|
||||
if (textureAtlas != m_pobTextureAtlas)
|
||||
{
|
||||
CCX_SAFE_RETAIN(textureAtlas);
|
||||
CCX_SAFE_RELEASE(m_pobTextureAtlas);
|
||||
m_pobTextureAtlas = textureAtlas;
|
||||
}
|
||||
}
|
||||
|
||||
inline NSArray<CCSprite*>* getDescendants(void) { return m_pobDescendants; }
|
||||
|
||||
/** creates a CCSpriteBatchNode with a texture2d and a default capacity of 29 children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
*/
|
||||
static CCSpriteBatchNode* batchNodeWithTexture(CCTexture2D *tex);
|
||||
static CCSpriteBatchNode* spriteSheetWithTexture(CCTexture2D *tex); // deprecated
|
||||
|
||||
/** creates a CCSpriteBatchNode with a texture2d and capacity of children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
*/
|
||||
static CCSpriteBatchNode* batchNodeWithTexture(CCTexture2D* tex, unsigned int capacity);
|
||||
static CCSpriteBatchNode* spriteSheetWithTexture(CCTexture2D *tex, unsigned int capacity); // deprecated
|
||||
|
||||
/** creates a CCSpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) with a default capacity of 29 children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
The file will be loaded using the TextureMgr.
|
||||
*/
|
||||
static CCSpriteBatchNode* batchNodeWithFile(const char* fileImage);
|
||||
static CCSpriteBatchNode* spriteSheetWithFile(const char* fileImage); // deprecated
|
||||
|
||||
/** creates a CCSpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and capacity of children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
The file will be loaded using the TextureMgr.
|
||||
*/
|
||||
static CCSpriteBatchNode* batchNodeWithFile(const char* fileImage, unsigned int capacity);
|
||||
static CCSpriteBatchNode* spriteSheetWithFile(const char* fileImage, unsigned int capacity); // deprecated
|
||||
|
||||
/** initializes a CCSpriteBatchNode with a texture2d and capacity of children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
*/
|
||||
bool initWithTexture(CCTexture2D *tex, unsigned int capacity);
|
||||
/** initializes a CCSpriteBatchNode with a file image (.png, .jpeg, .pvr, etc) and a capacity of children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
The file will be loaded using the TextureMgr.
|
||||
*/
|
||||
bool initWithFile(const char* fileImage, unsigned int capacity);
|
||||
|
||||
void increaseAtlasCapacity();
|
||||
|
||||
/** creates an sprite with a rect in the CCSpriteBatchNode.
|
||||
It's the same as:
|
||||
- create an standard CCSsprite
|
||||
- set the usingSpriteSheet = YES
|
||||
- set the textureAtlas to the same texture Atlas as the CCSpriteBatchNode
|
||||
@deprecated Use [CCSprite spriteWithBatchNode:rect:] instead;
|
||||
*/
|
||||
CCSprite* createSpriteWithRect(CGRect rect);
|
||||
|
||||
/** initializes a previously created sprite with a rect. This sprite will have the same texture as the CCSpriteBatchNode.
|
||||
It's the same as:
|
||||
- initialize an standard CCSsprite
|
||||
- set the usingBatchNode = YES
|
||||
- set the textureAtlas to the same texture Atlas as the CCSpriteBatchNode
|
||||
@since v0.99.0
|
||||
@deprecated Use [CCSprite initWithBatchNode:rect:] instead;
|
||||
*/
|
||||
void initSprite(CCSprite *sprite, CGRect rect);
|
||||
|
||||
/** removes a child given a certain index. It will also cleanup the running actions depending on the cleanup parameter.
|
||||
@warning Removing a child from a CCSpriteBatchNode is very slow
|
||||
*/
|
||||
void removeChildAtIndex(unsigned int index, bool doCleanup);
|
||||
|
||||
/** removes a child given a reference. It will also cleanup the running actions depending on the cleanup parameter.
|
||||
@warning Removing a child from a CCSpriteBatchNode is very slow
|
||||
*/
|
||||
void removeChild(CCSprite *sprite, bool doCleanup);
|
||||
|
||||
void insertChild(CCSprite *child, unsigned int index);
|
||||
void removeSpriteFromAtlas(CCSprite *sprite);
|
||||
|
||||
unsigned int rebuildIndexInOrder(CCSprite *parent, unsigned int index);
|
||||
unsigned int highestAtlasIndexInChild(CCSprite *sprite);
|
||||
unsigned int lowestAtlasIndexInChild(CCSprite *sprite);
|
||||
unsigned int atlasIndexForChild(CCSprite *sprite, int z);
|
||||
|
||||
// CCTextureProtocol
|
||||
virtual CCTexture2D* getTexture(void);
|
||||
virtual void setTexture(CCTexture2D *texture);
|
||||
virtual void setBlendFunc(ccBlendFunc blendFunc);
|
||||
virtual ccBlendFunc getBlendFunc(void);
|
||||
|
||||
virtual void visit(void);
|
||||
virtual void addChild(CCNode * child);
|
||||
virtual void addChild(CCNode * child, int zOrder);
|
||||
virtual void addChild(CCNode * child, int zOrder, int tag);
|
||||
virtual void reorderChild(CCNode * child, int zOrder);
|
||||
|
||||
virtual void removeChild(CCNode* child, bool cleanup);
|
||||
virtual void removeAllChildrenWithCleanup(bool cleanup);
|
||||
virtual void draw(void);
|
||||
|
||||
private:
|
||||
void updateBlendFunc();
|
||||
|
||||
private:
|
||||
CCTextureAtlas *m_pobTextureAtlas;
|
||||
ccBlendFunc m_blendFunc;
|
||||
|
||||
// all descendants: chlidren, gran children, etc...
|
||||
NSArray<CCSprite*>* m_pobDescendants;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __CC_SPRITE_BATCH_NODE_H__
|
|
@ -27,11 +27,8 @@ THE SOFTWARE.
|
|||
|
||||
#include "CCNode.h"
|
||||
#include "CCProtocols.h"
|
||||
#include "NSMutableArray.h"
|
||||
#include "NSObject.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace cocos2d {
|
||||
class CGRect;
|
||||
class CGPoint;
|
||||
|
@ -54,20 +51,26 @@ class CCX_DLL CCSpriteFrame : public NSObject
|
|||
public:
|
||||
// attributes
|
||||
|
||||
inline CGRect getRectInPixels(void) { return m_obRectInPixels; }
|
||||
inline void setRectInPixels(CGRect rectInPixels) { m_obRectInPixels = rectInPixels; }
|
||||
|
||||
inline bool isRotated(void) { return m_bRotated; }
|
||||
inline void setRotated(bool bRotated) { m_bRotated = bRotated; }
|
||||
|
||||
/** get rect of the frame */
|
||||
inline CGRect getRect(void) { return m_obRect; }
|
||||
/** set rect of the frame */
|
||||
inline void setRect(CGRect rect) { m_obRect = rect; }
|
||||
|
||||
/** get offset of the frame */
|
||||
inline CGPoint getOffset(void) { return m_obOffset; }
|
||||
inline CGPoint getOffsetInPixels(void) { return m_obOffsetInPixels; }
|
||||
/** set offset of the frame */
|
||||
inline void setOffset(CGPoint offset) { m_obOffset = offset; }
|
||||
inline void setOffsetInPixels(CGPoint offsetInPixels) { m_obOffsetInPixels = offsetInPixels; }
|
||||
|
||||
/** get original size of the trimmed image */
|
||||
inline CGSize getOriginalSize(void) { return m_obOriginalSize; }
|
||||
inline CGSize getOriginalSizeInPixels(void) { return m_obOriginalSizeInPixels; }
|
||||
/** set original size of the trimmed image */
|
||||
inline void setOriginalSize(CGSize size) { m_obOriginalSize = size; }
|
||||
inline void setOriginalSizeInPixels(CGSize sizeInPixels) { m_obOriginalSizeInPixels = sizeInPixels; }
|
||||
|
||||
/** get texture of the frame */
|
||||
inline CCTexture2D* getTexture(void) { return m_pobTexture; }
|
||||
|
@ -83,113 +86,35 @@ public:
|
|||
~CCSpriteFrame(void);
|
||||
virtual NSObject* copyWithZone(NSZone *pZone);
|
||||
|
||||
/** Create a CCSpriteFrame with a texture, rect and offset.
|
||||
/** Create a CCSpriteFrame with a texture, rect in points.
|
||||
It is assumed that the frame was not trimmed.
|
||||
*/
|
||||
static CCSpriteFrame* frameWithTexture(CCTexture2D* pobTexture, CGRect rect, CGPoint offset);
|
||||
static CCSpriteFrame* frameWithTexture(CCTexture2D* pobTexture, CGRect rect);
|
||||
|
||||
/** Create a CCSpriteFrame with a texture, rect, offset and originalSize.
|
||||
The originalSize is the size in pixels of the frame before being trimmed.
|
||||
/** Create a CCSpriteFrame with a texture, rect, rotated, offset and originalSize in pixels.
|
||||
The originalSize is the size in points of the frame before being trimmed.
|
||||
*/
|
||||
static CCSpriteFrame* frameWithTexture(CCTexture2D* pobTexture, CGRect rect, CGPoint offset, CGSize originalSize);
|
||||
static CCSpriteFrame* frameWithTexture(CCTexture2D* pobTexture, CGRect rect, bool rotated, CGPoint offset, CGSize originalSize);
|
||||
|
||||
public:
|
||||
/** Initializes a CCSpriteFrame with a texture, rect and offset.
|
||||
/** Initializes a CCSpriteFrame with a texture, rect in points.
|
||||
It is assumed that the frame was not trimmed.
|
||||
*/
|
||||
bool initWithTexture(CCTexture2D* pobTexture, CGRect rect, CGPoint offset);
|
||||
bool initWithTexture(CCTexture2D* pobTexture, CGRect rect);
|
||||
|
||||
/** Initializes a CCSpriteFrame with a texture, rect, offset and originalSize.
|
||||
The originalSize is the size in pixels of the frame before being trimmed.
|
||||
*/
|
||||
bool initWithTexture(CCTexture2D* pobTexture, CGRect rect, CGPoint offset, CGSize originalSize);
|
||||
/** Initializes a CCSpriteFrame with a texture, rect, rotated, offset and originalSize in pixels.
|
||||
The originalSize is the size in points of the frame before being trimmed.
|
||||
*/
|
||||
bool initWithTexture(CCTexture2D* pobTexture, CGRect rect, bool rotated, CGPoint offset, CGSize originalSize);
|
||||
protected:
|
||||
CGRect m_obRectInPixels;
|
||||
bool m_bRotated;
|
||||
CGRect m_obRect;
|
||||
CGPoint m_obOffset;
|
||||
CGSize m_obOriginalSize;
|
||||
CGPoint m_obOffsetInPixels;
|
||||
CGSize m_obOriginalSizeInPixels;
|
||||
CCTexture2D *m_pobTexture;
|
||||
};
|
||||
|
||||
//! @brief an Animation object used within Sprites to perform animations
|
||||
class CCX_DLL CCAnimation : public NSObject
|
||||
{
|
||||
protected:
|
||||
std::string m_nameStr;
|
||||
float m_fDelay;
|
||||
NSMutableArray<CCSpriteFrame*> *m_pobFrames;
|
||||
|
||||
public:
|
||||
// attributes
|
||||
|
||||
/** get name of the animation */
|
||||
inline const char* getName(void) { return m_nameStr.c_str(); }
|
||||
/** set name of the animation */
|
||||
inline void setName(const char *pszName){ m_nameStr = pszName; }
|
||||
|
||||
/** get delay between frames in seconds */
|
||||
inline float getDelay(void) { return m_fDelay; }
|
||||
/** set delay between frames in seconds */
|
||||
inline void setDelay(float fDelay) { m_fDelay = fDelay; }
|
||||
|
||||
/** get array of frames */
|
||||
inline NSMutableArray<CCSpriteFrame*>* getFrames(void) { return m_pobFrames; }
|
||||
/** set array of frames, the Frames is retained */
|
||||
inline void setFrames(NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
CCX_SAFE_RETAIN(pFrames);
|
||||
CCX_SAFE_RELEASE(m_pobFrames);
|
||||
m_pobFrames = pFrames;
|
||||
}
|
||||
|
||||
public:
|
||||
~CCAnimation(void);
|
||||
|
||||
/** Initializes a CCAnimation with a name
|
||||
@since v0.99.3
|
||||
*/
|
||||
bool initWithName(const char *pszName);
|
||||
|
||||
/** Initializes a CCAnimation with a name and frames
|
||||
@since v0.99.3
|
||||
*/
|
||||
bool initWithName(const char *pszName, NSArray<CCSpriteFrame*> *pFrames);
|
||||
|
||||
/** Initializes a CCAnimation with a name and delay between frames. */
|
||||
bool initWithName(const char *pszName, float fDelay);
|
||||
|
||||
/** Initializes a CCAnimation with a name, delay and an array of CCSpriteFrames. */
|
||||
bool initWithName(const char *pszName, float fDelay, NSArray<CCSpriteFrame*> *pFrames);
|
||||
|
||||
/** adds a frame to a CCAnimation */
|
||||
void addFrame(CCSpriteFrame *pFrame);
|
||||
|
||||
/** Adds a frame with an image filename. Internally it will create a CCSpriteFrame and it will add it.
|
||||
Added to facilitate the migration from v0.8 to v0.9.
|
||||
*/
|
||||
void addFrameWithFileName(const char *pszFileName);
|
||||
|
||||
/** Adds a frame with a texture and a rect. Internally it will create a CCSpriteFrame and it will add it.
|
||||
Added to facilitate the migration from v0.8 to v0.9.
|
||||
*/
|
||||
void addFrameWithTexture(CCTexture2D* pobTexture, CGRect rect);
|
||||
|
||||
public:
|
||||
/** Creates a CCAnimation with a name
|
||||
@since v0.99.3
|
||||
*/
|
||||
static CCAnimation* animationWithName(const char *pszName);
|
||||
|
||||
/** Creates a CCAnimation with a name and frames
|
||||
@since v0.99.3
|
||||
*/
|
||||
static CCAnimation* animationWithName(const char *pszName, NSArray<CCSpriteFrame*> *pFrames);
|
||||
|
||||
/** Creates a CCAnimation with a name and delay between frames. */
|
||||
static CCAnimation* animationWithName(const char *pszName, float fDelay);
|
||||
|
||||
/** Creates a CCAnimation with a name, delay and an array of CCSpriteFrames. */
|
||||
static CCAnimation* animationWithName(const char *pszName, float fDelay, NSArray<CCSpriteFrame*> *pFrames);
|
||||
};
|
||||
}//namespace cocos2d
|
||||
|
||||
#endif //__SPRITE_CCSPRITE_FRAME_H__
|
||||
|
|
|
@ -59,6 +59,11 @@ public:
|
|||
*/
|
||||
void addSpriteFramesWithFile(const char *pszPlist);
|
||||
|
||||
/** Adds multiple Sprite Frames from a plist file. The texture will be associated with the created sprite frames.
|
||||
@since v0.99.5
|
||||
*/
|
||||
void addSpriteFramesWithFile(const char* plist, const char* textureFileName);
|
||||
|
||||
/** Adds multiple Sprite Frames from a plist file. The texture will be associated with the created sprite frames. */
|
||||
void addSpriteFramesWithFile(const char *pszPlist, CCTexture2D *pobTexture);
|
||||
|
||||
|
@ -84,6 +89,24 @@ public:
|
|||
/** Deletes an sprite frame from the sprite frame cache. */
|
||||
void removeSpriteFrameByName(const char *pszName);
|
||||
|
||||
/** Removes multiple Sprite Frames from a plist file.
|
||||
* Sprite Frames stored in this file will be removed.
|
||||
* It is convinient to call this method when a specific texture needs to be removed.
|
||||
* @since v0.99.5
|
||||
*/
|
||||
void removeSpriteFramesFromFile(const char* plist);
|
||||
|
||||
/** Removes multiple Sprite Frames from NSDictionary.
|
||||
* @since v0.99.5
|
||||
*/
|
||||
void removeSpriteFramesFromDictionary(NSDictionary<std::string, CCSpriteFrame*> *dictionary);
|
||||
|
||||
/** Removes all Sprite Frames associated with the specified textures.
|
||||
* It is convinient to call this method when a specific texture needs to be removed.
|
||||
* @since v0.995.
|
||||
*/
|
||||
void removeSpriteFramesFromTexture(CCTexture2D* texture);
|
||||
|
||||
/** Returns an Sprite Frame that was previously added.
|
||||
If the name is not found it will return nil.
|
||||
You should retain the returned copy if you are going to use it.
|
||||
|
@ -110,6 +133,7 @@ private:
|
|||
|
||||
protected:
|
||||
NSDictionary<std::string, CCSpriteFrame*> *m_pSpriteFrames;
|
||||
NSDictionary<std::string, CCSpriteFrame*> *m_pSpriteFramesAliases;
|
||||
};
|
||||
}//namespace cocos2d
|
||||
|
||||
|
|
|
@ -25,164 +25,36 @@ THE SOFTWARE.
|
|||
#ifndef __SPRITE_CCSPRITE_SHEET_H__
|
||||
#define __SPRITE_CCSPRITE_SHEET_H__
|
||||
|
||||
#include "CCNode.h"
|
||||
#include "CCProtocols.h"
|
||||
#include "CCTextureAtlas.h"
|
||||
#include "ccMacros.h"
|
||||
#include "NSMutableArray.h"
|
||||
|
||||
#include "CCSpriteBatchNode.h"
|
||||
|
||||
namespace cocos2d {
|
||||
class CCSprite;
|
||||
class CGRect;
|
||||
|
||||
/** @brief CCSpriteSheet is like a batch node: if it contains children, it will draw them in 1 single OpenGL call
|
||||
* (often known as "batch draw").
|
||||
*
|
||||
* A CCSpriteSheet can reference one and only one texture (one image file, one texture atlas).
|
||||
* Only the CCSprites that are contained in that texture can be added to the CCSpriteSheet.
|
||||
* All CCSprites added to a CCSpriteSheet are drawn in one OpenGL ES draw call.
|
||||
* If the CCSprites are not added to a CCSpriteSheet then an OpenGL ES draw call will be needed for each one, which is less efficient.
|
||||
*
|
||||
*
|
||||
* Limitations:
|
||||
* - The only object that is accepted as child (or grandchild) is CCSprite or any subclass of CCSprite. eg: particles, labels and layer can't be added to a CCSpriteSheet.
|
||||
* - Either all its children are Aliased or Antialiased. It can't be a mix. This is because "alias" is a property of the texture, and all the sprites share the same texture.
|
||||
*
|
||||
* @since v0.7.1
|
||||
*/
|
||||
class CCX_DLL CCSpriteSheet : public CCNode, public CCTextureProtocol
|
||||
{
|
||||
public:
|
||||
~CCSpriteSheet(void);
|
||||
|
||||
/** initializes a CCSpriteSheet with a texture2d and capacity of children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
*/
|
||||
bool initWithTexture(CCTexture2D *pobTexture, unsigned int uCapacity);
|
||||
|
||||
/** initializes a CCSpriteSheet with a file image (.png, .jpeg, .pvr, etc) and a capacity of children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
The file will be loaded using the TextureMgr.
|
||||
*/
|
||||
bool initWithFile(const char *pszFileImage, unsigned int uCapacity);
|
||||
|
||||
void increaseAtlasCapacity(void);
|
||||
|
||||
/** creates an sprite with a rect in the CCSpriteSheet.
|
||||
It's the same as:
|
||||
- create an standard CCSsprite
|
||||
- set the usingSpriteSheet = true
|
||||
- set the textureAtlas to the same texture Atlas as the CCSpriteSheet
|
||||
@deprecated Use CCSprite::spriteWithSpriteSheet(rect) instead;
|
||||
*/
|
||||
CCSprite* createSpriteWithRect(CGRect rect);
|
||||
|
||||
/** initializes a previously created sprite with a rect. This sprite will have the same texture as the CCSpriteSheet.
|
||||
It's the same as:
|
||||
- initialize an standard CCSsprite
|
||||
- set the usingSpriteSheet = true
|
||||
- set the textureAtlas to the same texture Atlas as the CCSpriteSheet
|
||||
@since v0.99.0
|
||||
@deprecated Use CCSprite::spriteWithSpriteSheet(rect) instead;
|
||||
*/
|
||||
void initSprite(CCSprite* pobSprite, CGRect rect);
|
||||
|
||||
/** removes a child given a certain index. It will also cleanup the running actions depending on the cleanup parameter.
|
||||
@warning Removing a child from a CCSpriteSheet is very slow
|
||||
*/
|
||||
void removeChildAtIndex(unsigned int uIndex, bool bDoCleanup);
|
||||
|
||||
void insertChild(CCSprite *pobSprite, unsigned int uIndex);
|
||||
void removeSpriteFromAtlas(CCSprite *pobSprite);
|
||||
|
||||
unsigned int rebuildIndexInOrder(CCSprite *pobParent, unsigned int uIndex);
|
||||
unsigned int atlasIndexForChild(CCSprite *pobSprite, int nZ);
|
||||
unsigned int highestAtlasIndexInChild(CCSprite *pSprite);
|
||||
unsigned int lowestAtlasIndexInChild(CCSprite *pSprite);
|
||||
|
||||
// CCTextureProtocol
|
||||
virtual CCTexture2D* getTexture(void);
|
||||
virtual void setTexture(CCTexture2D *texture);
|
||||
virtual void setBlendFunc(ccBlendFunc blendFunc);
|
||||
virtual ccBlendFunc getBlendFunc(void);
|
||||
|
||||
virtual void visit(void);
|
||||
virtual CCNode * addChild(CCNode * child);
|
||||
virtual CCNode * addChild(CCNode * child, int zOrder);
|
||||
virtual CCNode * addChild(CCNode * child, int zOrder, int tag);
|
||||
virtual void reorderChild(CCNode * child, int zOrder);
|
||||
/** removes a child given a reference. It will also cleanup the running actions depending on the cleanup parameter.
|
||||
@warning Removing a child from a CCSpriteSheet is very slow
|
||||
/* Added only to prevent GCC compile warnings
|
||||
Will be removed in v1.1
|
||||
*/
|
||||
virtual void removeChild(CCNode* child, bool cleanup);
|
||||
virtual void removeAllChildrenWithCleanup(bool cleanup);
|
||||
virtual void draw(void);
|
||||
public:
|
||||
/** creates a CCSpriteSheet with a texture2d and a default capacity of 29 children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
*/
|
||||
static CCSpriteSheet* spriteSheetWithTexture(CCTexture2D *pobTexture);
|
||||
|
||||
/** creates a CCSpriteSheet with a texture2d and capacity of children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
*/
|
||||
static CCSpriteSheet* spriteSheetWithTexture(CCTexture2D *pobTexture, unsigned int uCapacity);
|
||||
|
||||
/** creates a CCSpriteSheet with a file image (.png, .jpeg, .pvr, etc) with a default capacity of 29 children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
The file will be loaded using the TextureMgr.
|
||||
*/
|
||||
static CCSpriteSheet* spriteSheetWithFile(const char *pszFileImage);
|
||||
|
||||
/** creates a CCSpriteSheet with a file image (.png, .jpeg, .pvr, etc) and capacity of children.
|
||||
The capacity will be increased in 33% in runtime if it run out of space.
|
||||
The file will be loaded using the TextureMgr.
|
||||
*/
|
||||
static CCSpriteSheet* spriteSheetWithFile(const char *pszFileImage, unsigned int uCapacity);
|
||||
|
||||
private:
|
||||
void updateBlendFunc(void);
|
||||
|
||||
public:
|
||||
// attributes
|
||||
|
||||
// descendants (children, gran children, etc)
|
||||
inline NSArray<CCSprite*>* getDescendants(void) { return m_pobDescendants; }
|
||||
|
||||
// TextureAtlas
|
||||
inline CCTextureAtlas* getTextureAtlas(void) { return m_pobTextureAtlas; }
|
||||
inline void setTextureAtlas(CCTextureAtlas *pTextureAtlas)
|
||||
class CCX_DLL CCSpriteSheetInternalOnly : public CCSpriteBatchNode
|
||||
{
|
||||
m_pobTextureAtlas = pTextureAtlas;
|
||||
if (pTextureAtlas)
|
||||
{
|
||||
pTextureAtlas->retain();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
CCTextureAtlas *m_pobTextureAtlas;
|
||||
ccBlendFunc m_blendFunc;
|
||||
|
||||
// all descendants: children, gran children, etc...
|
||||
NSArray<CCSprite*> *m_pobDescendants;
|
||||
protected:
|
||||
/* IMPORTANT XXX IMPORTNAT:
|
||||
* These 2 methods can't be part of CCTMXLayer since they call [super add...], and CCSpriteSheet#add SHALL not be called
|
||||
*/
|
||||
|
||||
/* Adds a quad into the texture atlas but it won't be added into the children array.
|
||||
This method should be called only when you are dealing with very big AtlasSrite and when most of the CCSprite won't be updated.
|
||||
For example: a tile map (CCTMXMap) or a label with lots of characters (BitmapFontAtlas)
|
||||
/** @brief CCSpriteSheet is like a batch node: if it contains children, it will draw them in 1 single OpenGL call
|
||||
* (often known as "batch draw").
|
||||
*
|
||||
* A CCSpriteSheet can reference one and only one texture (one image file, one texture atlas).
|
||||
* Only the CCSprites that are contained in that texture can be added to the CCSpriteSheet.
|
||||
* All CCSprites added to a CCSpriteSheet are drawn in one OpenGL ES draw call.
|
||||
* If the CCSprites are not added to a CCSpriteSheet then an OpenGL ES draw call will be needed for each one, which is less efficient.
|
||||
*
|
||||
*
|
||||
* Limitations:
|
||||
* - The only object that is accepted as child (or grandchild) is CCSprite or any subclass of CCSprite. eg: particles, labels and layer can't be added to a CCSpriteSheet.
|
||||
* - Either all its children are Aliased or Antialiased. It can't be a mix. This is because "alias" is a property of the texture, and all the sprites share the same texture.
|
||||
*
|
||||
* @since v0.7.1
|
||||
* @deprecated Use CCSpriteBatchNode instead. This class will be removed in v1.1
|
||||
*/
|
||||
void addQuadFromSprite(CCSprite *sprite, unsigned int index);
|
||||
/* This is the opposite of "addQuadFromSprite.
|
||||
It add the sprite to the children and descendants array, but it doesn't update add it to the texture atlas
|
||||
*/
|
||||
CCSpriteSheet * addSpriteWithoutQuad(CCSprite*child, unsigned int z, int aTag);
|
||||
class CCX_DLL CCSpriteSheet: public CCSpriteSheetInternalOnly
|
||||
{
|
||||
};
|
||||
|
||||
};
|
||||
}//namespace cocos2d
|
||||
|
||||
#endif // __SPRITE_CCSPRITE_SHEET_H__
|
||||
|
|
|
@ -53,6 +53,11 @@ namespace cocos2d {
|
|||
{
|
||||
return (float)atof(m_sString.c_str());
|
||||
}
|
||||
|
||||
bool isEmpty()
|
||||
{
|
||||
return m_sString.empty();
|
||||
}
|
||||
};
|
||||
}// namespace cocos2d
|
||||
#endif //__NSSTRING_H__
|
|
@ -0,0 +1,640 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#include "ccMacros.h"
|
||||
#include "CCGrid.h"
|
||||
#include "CCDirector.h"
|
||||
#include "CCGrabber.h"
|
||||
|
||||
#include "CCGL.h"
|
||||
#include "CGPointExtension.h"
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
// implementation of CCGridBase
|
||||
|
||||
CCGridBase* CCGridBase::gridWithSize(cocos2d::ccGridSize gridSize)
|
||||
{
|
||||
CCGridBase *pGridBase = new CCGridBase();
|
||||
|
||||
if (pGridBase)
|
||||
{
|
||||
if (pGridBase->initWithSize(gridSize))
|
||||
{
|
||||
pGridBase->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
CCX_SAFE_RELEASE_NULL(pGridBase);
|
||||
}
|
||||
}
|
||||
|
||||
return pGridBase;
|
||||
}
|
||||
|
||||
CCGridBase* CCGridBase::gridWithSize(ccGridSize gridSize, CCTexture2D *texture, bool flipped)
|
||||
{
|
||||
CCGridBase *pGridBase = new CCGridBase();
|
||||
|
||||
if (pGridBase)
|
||||
{
|
||||
if (pGridBase->initWithSize(gridSize, texture, flipped))
|
||||
{
|
||||
pGridBase->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
CCX_SAFE_RELEASE_NULL(pGridBase);
|
||||
}
|
||||
}
|
||||
|
||||
return pGridBase;
|
||||
}
|
||||
|
||||
bool CCGridBase::initWithSize(ccGridSize gridSize, CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
bool bRet = true;
|
||||
|
||||
m_bActive = false;
|
||||
m_nReuseGrid = 0;
|
||||
m_sGridSize = gridSize;
|
||||
|
||||
m_pTexture = pTexture;
|
||||
CCX_SAFE_RETAIN(m_pTexture);
|
||||
m_bIsTextureFlipped = bFlipped;
|
||||
|
||||
CGSize texSize = m_pTexture->getContentSizeInPixels();
|
||||
m_obStep.x = texSize.width / m_sGridSize.x;
|
||||
m_obStep.y = texSize.height / m_sGridSize.y;
|
||||
|
||||
m_pGrabber = new CCGrabber();
|
||||
if (m_pGrabber)
|
||||
{
|
||||
m_pGrabber->grab(m_pTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
|
||||
calculateVertexPoints();
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool CCGridBase::initWithSize(ccGridSize gridSize)
|
||||
{
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
CGSize s = pDirector->getWinSizeInPixels();
|
||||
|
||||
unsigned int POTWide = ccNextPOT(s.width);
|
||||
unsigned int POTHigh = ccNextPOT(s.height);
|
||||
|
||||
CCTexture2DPixelFormat format = pDirector->getPiexFormat() == kCCPixelFormatRGB565 ? kCCTexture2DPixelFormat_RGB565 : kCCTexture2DPixelFormat_RGBA8888;
|
||||
|
||||
void *data = calloc((int)(POTWide * POTHigh * 4), 1);
|
||||
if (! data)
|
||||
{
|
||||
CCLOG("cocos2d: CCGrid: not enough memory.");
|
||||
this->release();
|
||||
return false;
|
||||
}
|
||||
|
||||
CCTexture2D *pTexture = new CCTexture2D();
|
||||
pTexture->initWithData(data, format, textureSize, textureSize, s);
|
||||
|
||||
free(data);
|
||||
|
||||
if (! pTexture)
|
||||
{
|
||||
CCLOG("cocos2d: CCGrid: error creating texture");
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (initWithSize(gridSize, pTexture, false))
|
||||
{
|
||||
// do something
|
||||
}
|
||||
|
||||
pTexture->release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCGridBase::~CCGridBase(void)
|
||||
{
|
||||
CCLOGINFO("cocos2d: deallocing %p", this);
|
||||
|
||||
setActive(false);
|
||||
CCX_SAFE_RELEASE(m_pTexture);
|
||||
CCX_SAFE_RELEASE(m_pGrabber);
|
||||
}
|
||||
|
||||
// properties
|
||||
void CCGridBase::setActive(bool bActive)
|
||||
{
|
||||
m_bActive = bActive;
|
||||
if (! bActive)
|
||||
{
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
ccDirectorProjection proj = pDirector->getProjection();
|
||||
pDirector->setProjection(proj);
|
||||
}
|
||||
}
|
||||
|
||||
void CCGridBase::setIsTextureFlipped(bool bFlipped)
|
||||
{
|
||||
if (m_bIsTextureFlipped != bFlipped)
|
||||
{
|
||||
m_bIsTextureFlipped = bFlipped;
|
||||
calculateVertexPoints();
|
||||
}
|
||||
}
|
||||
|
||||
// This routine can be merged with Director
|
||||
void CCGridBase::applyLandscape(void)
|
||||
{
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
|
||||
CGSize winSize = pDirector->getDisplaySize();
|
||||
float w = winSize.width / 2;
|
||||
float h = winSize.height / 2;
|
||||
|
||||
ccDeviceOrientation orientation = pDirector->getDeviceOrientation();
|
||||
|
||||
switch (orientation)
|
||||
{
|
||||
case CCDeviceOrientationLandscapeLeft:
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(-90,0,0,1);
|
||||
glTranslatef(-h,-w,0);
|
||||
break;
|
||||
case CCDeviceOrientationLandscapeRight:
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(90,0,0,1);
|
||||
glTranslatef(-h,-w,0);
|
||||
break;
|
||||
case CCDeviceOrientationPortraitUpsideDown:
|
||||
glTranslatef(w,h,0);
|
||||
glRotatef(180,0,0,1);
|
||||
glTranslatef(-w,-h,0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CCGridBase::set2DProjection()
|
||||
{
|
||||
CGSize winSize = CCDirector::sharedDirector()->getWinSizeInPixels();
|
||||
|
||||
glLoadIdentity();
|
||||
glViewport((GLsizei)0, (GLsizei)0, (GLsizei)winSize.width, (GLsizei)winSize.height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
ccglOrtho(0, winSize.width, 0, winSize.height, -1024, 1024);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
// This routine can be merged with Director
|
||||
void CCGridBase::set3DProjection()
|
||||
{
|
||||
CGSize winSize = CCDirector::sharedDirector()->getDisplaySizeInPixels();
|
||||
|
||||
glViewport(0, 0, (GLsizei)winSize.width, (GLsizei)winSize.height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60, (GLfloat)winSize.width/winSize.height, 0.5f, 1500.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt( winSize.width/2, winSize.height/2, CCDirector::sharedDirector()->getZEye(),
|
||||
winSize.width/2, winSize.height/2, 0,
|
||||
0.0f, 1.0f, 0.0f
|
||||
);
|
||||
}
|
||||
|
||||
void CCGridBase::beforeDraw(void)
|
||||
{
|
||||
set2DProjection();
|
||||
m_pGrabber->beforeRender(m_pTexture);
|
||||
}
|
||||
|
||||
void CCGridBase::afterDraw(cocos2d::CCNode *pTarget)
|
||||
{
|
||||
m_pGrabber->afterRender(m_pTexture);
|
||||
|
||||
set3DProjection();
|
||||
applyLandscape();
|
||||
|
||||
if (pTarget->getCamera()->getDirty())
|
||||
{
|
||||
CGPoint offset = pTarget->getAnchorPointInPixels();
|
||||
|
||||
//
|
||||
// XXX: Camera should be applied in the AnchorPoint
|
||||
//
|
||||
ccglTranslate(offset.x, offset.y, 0);
|
||||
pTarget->getCamera()->locate();
|
||||
ccglTranslate(-offset.x, -offset.y, 0);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_pTexture->getName());
|
||||
|
||||
blit();
|
||||
}
|
||||
|
||||
void CCGridBase::blit(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCGridBase::reuse(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCGridBase::calculateVertexPoints(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// implementation of CCGrid3D
|
||||
|
||||
CCGrid3D* CCGrid3D::gridWithSize(ccGridSize gridSize, CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
CCGrid3D *pRet= new CCGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize, pTexture, bFlipped))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCGrid3D* CCGrid3D::gridWithSize(ccGridSize gridSize)
|
||||
{
|
||||
CCGrid3D *pRet= new CCGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCGrid3D::~CCGrid3D(void)
|
||||
{
|
||||
free(m_pTexCoordinates);
|
||||
free(m_pVertices);
|
||||
free(m_pIndices);
|
||||
free(m_pOriginalVertices);
|
||||
}
|
||||
|
||||
void CCGrid3D::blit(void)
|
||||
{
|
||||
int n = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
// 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);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, m_pVertices);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, m_pTexCoordinates);
|
||||
glDrawElements(GL_TRIANGLES, n * 6, GL_UNSIGNED_SHORT, m_pIndices);
|
||||
|
||||
// restore GL default state
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
void CCGrid3D::calculateVertexPoints(void)
|
||||
{
|
||||
float width = (float)m_pTexture->getPixelsWide();
|
||||
float height = (float)m_pTexture->getPixelsHigh();
|
||||
float imageH = m_pTexture->getContentSizeInPixels().height;
|
||||
|
||||
int x, y, i;
|
||||
|
||||
m_pVertices = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
m_pOriginalVertices = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
m_pTexCoordinates = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(CGPoint));
|
||||
m_pIndices = (GLushort*)malloc(m_sGridSize.x * m_sGridSize.y * sizeof(GLushort) * 6);
|
||||
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
float *texArray = (float*)m_pTexCoordinates;
|
||||
GLushort *idxArray = m_pIndices;
|
||||
|
||||
for (x = 0; x < m_sGridSize.x; ++x)
|
||||
{
|
||||
for (y = 0; y < m_sGridSize.y; ++y)
|
||||
{
|
||||
int idx = (y * m_sGridSize.x) + x;
|
||||
|
||||
float x1 = x * m_obStep.x;
|
||||
float x2 = x1 + m_obStep.x;
|
||||
float y1 = y * m_obStep.y;
|
||||
float y2= y1 + m_obStep.y;
|
||||
|
||||
GLushort a = x * (m_sGridSize.y + 1) + y;
|
||||
GLushort b = (x + 1) * (m_sGridSize.y + 1) + y;
|
||||
GLushort c = (x + 1) * (m_sGridSize.y + 1) + (y + 1);
|
||||
GLushort d = x * (m_sGridSize.y + 1) + (y + 1);
|
||||
|
||||
GLushort tempidx[6] = {a, b, d, b, c, d};
|
||||
|
||||
memcpy(&idxArray[6*idx], tempidx, 6*sizeof(GLushort));
|
||||
|
||||
int l1[4] = {a*3, b*3, c*3, d*3};
|
||||
ccVertex3F e = {x1, y1, 0};
|
||||
ccVertex3F f = {x2, y1, 0};
|
||||
ccVertex3F g = {x2, y2, 0};
|
||||
ccVertex3F h = {x1, y2, 0};
|
||||
|
||||
ccVertex3F l2[4] = {e, f, g, h};
|
||||
|
||||
int tex1[4] = {a*2, b*2, c*2, d*2};
|
||||
CGPoint tex2[4] = {ccp(x1, y1), ccp(x2, y1), ccp(x2, y2), ccp(x1, y2)};
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
vertArray[l1[i]] = l2[i].x;
|
||||
vertArray[l1[i] + 1] = l2[i].y;
|
||||
vertArray[l1[i] + 2] = l2[i].z;
|
||||
|
||||
texArray[tex1[i]] = tex2[i].x / width;
|
||||
if (m_bIsTextureFlipped)
|
||||
{
|
||||
texArray[tex1[i] + 1] = (imageH - tex2[i].y) / height;
|
||||
}
|
||||
else
|
||||
{
|
||||
texArray[tex1[i] + 1] = tex2[i].y / height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, (m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
}
|
||||
|
||||
ccVertex3F CCGrid3D::vertex(ccGridSize pos)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y+1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
|
||||
ccVertex3F vert = {vertArray[index], vertArray[index+1], vertArray[index+2]};
|
||||
|
||||
return vert;
|
||||
}
|
||||
|
||||
ccVertex3F CCGrid3D::originalVertex(cocos2d::ccGridSize pos)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y+1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pOriginalVertices;
|
||||
|
||||
ccVertex3F vert = {vertArray[index], vertArray[index+1], vertArray[index+2]};
|
||||
|
||||
return vert;
|
||||
}
|
||||
|
||||
void CCGrid3D::setVertex(ccGridSize pos, ccVertex3F vertex)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y + 1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
vertArray[index] = vertex.x;
|
||||
vertArray[index+1] = vertex.y;
|
||||
vertArray[index+2] = vertex.z;
|
||||
}
|
||||
|
||||
void CCGrid3D::reuse(void)
|
||||
{
|
||||
if (m_nReuseGrid > 0)
|
||||
{
|
||||
memcpy(m_pOriginalVertices, m_pVertices, (m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
--m_nReuseGrid;
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of CCTiledGrid3D
|
||||
|
||||
CCTiledGrid3D::~CCTiledGrid3D(void)
|
||||
{
|
||||
free(m_pTexCoordinates);
|
||||
free(m_pVertices);
|
||||
free(m_pOriginalVertices);
|
||||
free(m_pIndices);
|
||||
}
|
||||
|
||||
CCTiledGrid3D* CCTiledGrid3D::gridWithSize(cocos2d::ccGridSize gridSize, cocos2d::CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
CCTiledGrid3D *pRet= new CCTiledGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize, pTexture, bFlipped))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCTiledGrid3D* CCTiledGrid3D::gridWithSize(cocos2d::ccGridSize gridSize)
|
||||
{
|
||||
CCTiledGrid3D *pRet= new CCTiledGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::blit(void)
|
||||
{
|
||||
int n = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
// 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);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, m_pVertices);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, m_pTexCoordinates);
|
||||
glDrawElements(GL_TRIANGLES, n*6, GL_UNSIGNED_SHORT, m_pIndices);
|
||||
|
||||
// restore default GL state
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::calculateVertexPoints(void)
|
||||
{
|
||||
float width = (float)m_pTexture->getPixelsWide();
|
||||
float height = (float)m_pTexture->getPixelsHigh();
|
||||
float imageH = m_pTexture->getContentSizeInPixels().height;
|
||||
|
||||
int numQuads = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
m_pVertices = malloc(numQuads * 12 * sizeof(GLfloat));
|
||||
m_pOriginalVertices = malloc(numQuads * 12 * sizeof(GLfloat));
|
||||
m_pTexCoordinates = malloc(numQuads * 8 * sizeof(GLfloat));
|
||||
m_pIndices = (GLushort *)malloc(numQuads * 6 * sizeof(GLushort));
|
||||
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
float *texArray = (float*)m_pTexCoordinates;
|
||||
GLushort *idxArray = m_pIndices;
|
||||
|
||||
int x, y;
|
||||
|
||||
for( x = 0; x < m_sGridSize.x; x++ )
|
||||
{
|
||||
for( y = 0; y < m_sGridSize.y; y++ )
|
||||
{
|
||||
float x1 = x * m_obStep.x;
|
||||
float x2 = x1 + m_obStep.x;
|
||||
float y1 = y * m_obStep.y;
|
||||
float y2 = y1 + m_obStep.y;
|
||||
|
||||
*vertArray++ = x1;
|
||||
*vertArray++ = y1;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x2;
|
||||
*vertArray++ = y1;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x1;
|
||||
*vertArray++ = y2;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x2;
|
||||
*vertArray++ = y2;
|
||||
*vertArray++ = 0;
|
||||
|
||||
float newY1 = y1;
|
||||
float newY2 = y2;
|
||||
|
||||
if (m_bIsTextureFlipped)
|
||||
{
|
||||
newY1 = imageH - y1;
|
||||
newY2 = imageH - y2;
|
||||
}
|
||||
|
||||
*texArray++ = x1 / width;
|
||||
*texArray++ = newY1 / height;
|
||||
*texArray++ = x2 / width;
|
||||
*texArray++ = newY1 / height;
|
||||
*texArray++ = x1 / width;
|
||||
*texArray++ = newY2 / height;
|
||||
*texArray++ = x2 / width;
|
||||
*texArray++ = newY2 / height;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < numQuads; x++)
|
||||
{
|
||||
idxArray[x*6+0] = x * 4 + 0;
|
||||
idxArray[x*6+1] = x * 4 + 1;
|
||||
idxArray[x*6+2] = x * 4 + 2;
|
||||
|
||||
idxArray[x*6+3] = x * 4 + 1;
|
||||
idxArray[x*6+4] = x * 4 + 2;
|
||||
idxArray[x*6+5] = x * 4 + 3;
|
||||
}
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, numQuads * 12 * sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::setTile(cocos2d::ccGridSize pos, cocos2d::ccQuad3 coords)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
memcpy(&vertArray[idx], &coords, sizeof(ccQuad3));
|
||||
}
|
||||
|
||||
ccQuad3 CCTiledGrid3D::originalTile(ccGridSize pos)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pOriginalVertices;
|
||||
|
||||
ccQuad3 ret;
|
||||
memcpy(&ret, &vertArray[idx], sizeof(ccQuad3));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ccQuad3 CCTiledGrid3D::tile(cocos2d::ccGridSize pos)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
|
||||
ccQuad3 ret;
|
||||
memcpy(&ret, &vertArray[idx], sizeof(ccQuad3));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::reuse(void)
|
||||
{
|
||||
if (m_nReuseGrid > 0)
|
||||
{
|
||||
int numQuads = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, numQuads * 12 * sizeof(GLfloat));
|
||||
--m_nReuseGrid;
|
||||
}
|
||||
}
|
||||
} // end of namespace cocos2d
|
|
@ -0,0 +1,83 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __PLATFOMR_CCNS_H__
|
||||
#define __PLATFOMR_CCNS_H__
|
||||
|
||||
#include "config_platform.h"
|
||||
|
||||
#ifdef CCX_PLATFORM_IPHONE
|
||||
|
||||
#include <Availability.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
#define CCRectFromString(__r__) CGRectFromString(__r__)
|
||||
#define CCPointFromString(__p__) CGPointFromString(__p__)
|
||||
#define CCSizeFromString(__s__) CGSizeFromString(__s__)
|
||||
#define CCNSSizeToCGSize
|
||||
#define CCNSRectToCGRect
|
||||
#define CCNSPointToCGPoint
|
||||
#define CCTextAlignment UITextAlignment
|
||||
#define CCTextAlignmentCenter UITextAlignmentCenter
|
||||
#define CCTextAlignmentLeft UITextAlignmentLeft
|
||||
#define CCTextAlignmentRight UITextAlignmentRight
|
||||
|
||||
|
||||
#elif defined(CCX_PLATFORM_MAC)
|
||||
|
||||
#include <Availability.h>
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
#define CCRectFromString(__r__) NSRectToCGRect( NSRectFromString(__r__) )
|
||||
#define CCPointFromString(__p__) NSPointToCGPoint( NSPointFromString(__p__) )
|
||||
#define CCSizeFromString(__s__) NSSizeToCGSize( NSSizeFromString(__s__) )
|
||||
#define CCNSSizeToCGSize NSSizeToCGSize
|
||||
#define CCNSRectToCGRect NSRectToCGRect
|
||||
#define CCNSPointToCGPoint NSPointToCGPoint
|
||||
#define CCTextAlignment NSTextAlignment
|
||||
#define CCTextAlignmentCenter NSCenterTextAlignment
|
||||
#define CCTextAlignmentLeft NSLeftTextAlignment
|
||||
#define CCTextAlignmentRight NSRightTextAlignment
|
||||
|
||||
#else
|
||||
|
||||
/// @todo
|
||||
#include "CGGeometry.h"
|
||||
|
||||
#define CCRectFromString(__r__) CGRectZero
|
||||
#define CCPointFromString(__p__) CGPointZero
|
||||
#define CCSizeFromString(__s__) CGSizeZero
|
||||
#define CCNSSizeToCGSize CGSizeZero
|
||||
#define CCNSRectToCGRect CGRectZero
|
||||
#define CCNSPointToCGPoint CGPointZero
|
||||
#define CCTextAlignment 0
|
||||
#define CCTextAlignmentCenter 0
|
||||
#define CCTextAlignmentLeft 0
|
||||
#define CCTextAlignmentRight 0
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __PLATFOMR_CCNS_H__
|
||||
|
||||
|
|
@ -0,0 +1,614 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#include "ccMacros.h"
|
||||
#include "CCGrid.h"
|
||||
#include "CCDirector.h"
|
||||
#include "CCGrabber.h"
|
||||
|
||||
#include "CCGL.h"
|
||||
#include "CGPointExtension.h"
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
// implementation of CCGridBase
|
||||
|
||||
CCGridBase* CCGridBase::gridWithSize(cocos2d::ccGridSize gridSize)
|
||||
{
|
||||
CCGridBase *pGridBase = new CCGridBase();
|
||||
|
||||
if (pGridBase)
|
||||
{
|
||||
if (pGridBase->initWithSize(gridSize))
|
||||
{
|
||||
pGridBase->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
CCX_SAFE_RELEASE_NULL(pGridBase);
|
||||
}
|
||||
}
|
||||
|
||||
return pGridBase;
|
||||
}
|
||||
|
||||
CCGridBase* CCGridBase::gridWithSize(ccGridSize gridSize, CCTexture2D *texture, bool flipped)
|
||||
{
|
||||
CCGridBase *pGridBase = new CCGridBase();
|
||||
|
||||
if (pGridBase)
|
||||
{
|
||||
if (pGridBase->initWithSize(gridSize, texture, flipped))
|
||||
{
|
||||
pGridBase->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
CCX_SAFE_RELEASE_NULL(pGridBase);
|
||||
}
|
||||
}
|
||||
|
||||
return pGridBase;
|
||||
}
|
||||
|
||||
bool CCGridBase::initWithSize(ccGridSize gridSize, CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
bool bRet = true;
|
||||
|
||||
m_bActive = false;
|
||||
m_nReuseGrid = 0;
|
||||
m_sGridSize = gridSize;
|
||||
|
||||
m_pTexture = pTexture;
|
||||
CCX_SAFE_RETAIN(m_pTexture);
|
||||
m_bIsTextureFlipped = bFlipped;
|
||||
|
||||
CGSize texSize = m_pTexture->getContentSizeInPixels();
|
||||
m_obStep.x = texSize.width / m_sGridSize.x;
|
||||
m_obStep.y = texSize.height / m_sGridSize.y;
|
||||
|
||||
m_pGrabber = new CCGrabber();
|
||||
if (m_pGrabber)
|
||||
{
|
||||
m_pGrabber->grab(m_pTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
bRet = false;
|
||||
}
|
||||
|
||||
|
||||
calculateVertexPoints();
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool CCGridBase::initWithSize(ccGridSize gridSize)
|
||||
{
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
CGSize s = pDirector->getWinSizeInPixels();
|
||||
|
||||
unsigned int POTWide = ccNextPOT(s.width);
|
||||
unsigned int POTHigh = ccNextPOT(s.height);
|
||||
|
||||
// on mac, it use kCCTexture2DPixelFormat_RGBA8888
|
||||
CCTexture2DPixelFormat format = kCCTexture2DPixelFormat_RGBA8888;
|
||||
|
||||
void *data = calloc((int)(POTWide * POTHigh * 4), 1);
|
||||
if (! data)
|
||||
{
|
||||
CCLOG("cocos2d: CCGrid: not enough memory.");
|
||||
this->release();
|
||||
return false;
|
||||
}
|
||||
|
||||
CCTexture2D *pTexture = new CCTexture2D();
|
||||
pTexture->initWithData(data, format, textureSize, textureSize, s);
|
||||
|
||||
free(data);
|
||||
|
||||
if (! pTexture)
|
||||
{
|
||||
CCLOG("cocos2d: CCGrid: error creating texture");
|
||||
delete this;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (initWithSize(gridSize, pTexture, false))
|
||||
{
|
||||
// do something
|
||||
}
|
||||
|
||||
pTexture->release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCGridBase::~CCGridBase(void)
|
||||
{
|
||||
CCLOGINFO("cocos2d: deallocing %p", this);
|
||||
|
||||
setActive(false);
|
||||
CCX_SAFE_RELEASE(m_pTexture);
|
||||
CCX_SAFE_RELEASE(m_pGrabber);
|
||||
}
|
||||
|
||||
// properties
|
||||
void CCGridBase::setActive(bool bActive)
|
||||
{
|
||||
m_bActive = bActive;
|
||||
if (! bActive)
|
||||
{
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
ccDirectorProjection proj = pDirector->getProjection();
|
||||
pDirector->setProjection(proj);
|
||||
}
|
||||
}
|
||||
|
||||
void CCGridBase::setIsTextureFlipped(bool bFlipped)
|
||||
{
|
||||
if (m_bIsTextureFlipped != bFlipped)
|
||||
{
|
||||
m_bIsTextureFlipped = bFlipped;
|
||||
calculateVertexPoints();
|
||||
}
|
||||
}
|
||||
|
||||
// mac can not applay land space
|
||||
void CCGridBase::applyLandscape(void)
|
||||
{
|
||||
}
|
||||
|
||||
void CCGridBase::set2DProjection()
|
||||
{
|
||||
CGSize winSize = CCDirector::sharedDirector()->getWinSizeInPixels();
|
||||
|
||||
glLoadIdentity();
|
||||
glViewport((GLsizei)0, (GLsizei)0, (GLsizei)winSize.width, (GLsizei)winSize.height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
ccglOrtho(0, winSize.width, 0, winSize.height, -1024, 1024);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
// This routine can be merged with Director
|
||||
void CCGridBase::set3DProjection()
|
||||
{
|
||||
CGSize winSize = CCDirector::sharedDirector()->getDisplaySizeInPixels();
|
||||
|
||||
glViewport(0, 0, (GLsizei)winSize.width, (GLsizei)winSize.height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60, (GLfloat)winSize.width/winSize.height, 0.5f, 1500.0f);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt( winSize.width/2, winSize.height/2, CCDirector::sharedDirector()->getZEye(),
|
||||
winSize.width/2, winSize.height/2, 0,
|
||||
0.0f, 1.0f, 0.0f
|
||||
);
|
||||
}
|
||||
|
||||
void CCGridBase::beforeDraw(void)
|
||||
{
|
||||
set2DProjection();
|
||||
m_pGrabber->beforeRender(m_pTexture);
|
||||
}
|
||||
|
||||
void CCGridBase::afterDraw(cocos2d::CCNode *pTarget)
|
||||
{
|
||||
m_pGrabber->afterRender(m_pTexture);
|
||||
|
||||
set3DProjection();
|
||||
// mac can not applay land space
|
||||
//applyLandscape();
|
||||
|
||||
if (pTarget->getCamera()->getDirty())
|
||||
{
|
||||
CGPoint offset = pTarget->getAnchorPointInPixels();
|
||||
|
||||
//
|
||||
// XXX: Camera should be applied in the AnchorPoint
|
||||
//
|
||||
ccglTranslate(offset.x, offset.y, 0);
|
||||
pTarget->getCamera()->locate();
|
||||
ccglTranslate(-offset.x, -offset.y, 0);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_pTexture->getName());
|
||||
|
||||
blit();
|
||||
}
|
||||
|
||||
void CCGridBase::blit(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCGridBase::reuse(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CCGridBase::calculateVertexPoints(void)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
// implementation of CCGrid3D
|
||||
|
||||
CCGrid3D* CCGrid3D::gridWithSize(ccGridSize gridSize, CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
CCGrid3D *pRet= new CCGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize, pTexture, bFlipped))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCGrid3D* CCGrid3D::gridWithSize(ccGridSize gridSize)
|
||||
{
|
||||
CCGrid3D *pRet= new CCGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCGrid3D::~CCGrid3D(void)
|
||||
{
|
||||
free(m_pTexCoordinates);
|
||||
free(m_pVertices);
|
||||
free(m_pIndices);
|
||||
free(m_pOriginalVertices);
|
||||
}
|
||||
|
||||
void CCGrid3D::blit(void)
|
||||
{
|
||||
int n = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
// 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);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, m_pVertices);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, m_pTexCoordinates);
|
||||
glDrawElements(GL_TRIANGLES, n * 6, GL_UNSIGNED_SHORT, m_pIndices);
|
||||
|
||||
// restore GL default state
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
void CCGrid3D::calculateVertexPoints(void)
|
||||
{
|
||||
float width = (float)m_pTexture->getPixelsWide();
|
||||
float height = (float)m_pTexture->getPixelsHigh();
|
||||
float imageH = m_pTexture->getContentSizeInPixels().height;
|
||||
|
||||
int x, y, i;
|
||||
|
||||
m_pVertices = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
m_pOriginalVertices = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
m_pTexCoordinates = malloc((m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(CGPoint));
|
||||
m_pIndices = (GLushort*)malloc(m_sGridSize.x * m_sGridSize.y * sizeof(GLushort) * 6);
|
||||
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
float *texArray = (float*)m_pTexCoordinates;
|
||||
GLushort *idxArray = m_pIndices;
|
||||
|
||||
for (x = 0; x < m_sGridSize.x; ++x)
|
||||
{
|
||||
for (y = 0; y < m_sGridSize.y; ++y)
|
||||
{
|
||||
int idx = (y * m_sGridSize.x) + x;
|
||||
|
||||
float x1 = x * m_obStep.x;
|
||||
float x2 = x1 + m_obStep.x;
|
||||
float y1 = y * m_obStep.y;
|
||||
float y2= y1 + m_obStep.y;
|
||||
|
||||
GLushort a = x * (m_sGridSize.y + 1) + y;
|
||||
GLushort b = (x + 1) * (m_sGridSize.y + 1) + y;
|
||||
GLushort c = (x + 1) * (m_sGridSize.y + 1) + (y + 1);
|
||||
GLushort d = x * (m_sGridSize.y + 1) + (y + 1);
|
||||
|
||||
GLushort tempidx[6] = {a, b, d, b, c, d};
|
||||
|
||||
memcpy(&idxArray[6*idx], tempidx, 6*sizeof(GLushort));
|
||||
|
||||
int l1[4] = {a*3, b*3, c*3, d*3};
|
||||
ccVertex3F e = {x1, y1, 0};
|
||||
ccVertex3F f = {x2, y1, 0};
|
||||
ccVertex3F g = {x2, y2, 0};
|
||||
ccVertex3F h = {x1, y2, 0};
|
||||
|
||||
ccVertex3F l2[4] = {e, f, g, h};
|
||||
|
||||
int tex1[4] = {a*2, b*2, c*2, d*2};
|
||||
CGPoint tex2[4] = {ccp(x1, y1), ccp(x2, y1), ccp(x2, y2), ccp(x1, y2)};
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
vertArray[l1[i]] = l2[i].x;
|
||||
vertArray[l1[i] + 1] = l2[i].y;
|
||||
vertArray[l1[i] + 2] = l2[i].z;
|
||||
|
||||
texArray[tex1[i]] = tex2[i].x / width;
|
||||
if (m_bIsTextureFlipped)
|
||||
{
|
||||
texArray[tex1[i] + 1] = (imageH - tex2[i].y) / height;
|
||||
}
|
||||
else
|
||||
{
|
||||
texArray[tex1[i] + 1] = tex2[i].y / height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, (m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
}
|
||||
|
||||
ccVertex3F CCGrid3D::vertex(ccGridSize pos)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y+1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
|
||||
ccVertex3F vert = {vertArray[index], vertArray[index+1], vertArray[index+2]};
|
||||
|
||||
return vert;
|
||||
}
|
||||
|
||||
ccVertex3F CCGrid3D::originalVertex(cocos2d::ccGridSize pos)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y+1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pOriginalVertices;
|
||||
|
||||
ccVertex3F vert = {vertArray[index], vertArray[index+1], vertArray[index+2]};
|
||||
|
||||
return vert;
|
||||
}
|
||||
|
||||
void CCGrid3D::setVertex(ccGridSize pos, ccVertex3F vertex)
|
||||
{
|
||||
int index = (pos.x * (m_sGridSize.y + 1) + pos.y) * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
vertArray[index] = vertex.x;
|
||||
vertArray[index+1] = vertex.y;
|
||||
vertArray[index+2] = vertex.z;
|
||||
}
|
||||
|
||||
void CCGrid3D::reuse(void)
|
||||
{
|
||||
if (m_nReuseGrid > 0)
|
||||
{
|
||||
memcpy(m_pOriginalVertices, m_pVertices, (m_sGridSize.x+1) * (m_sGridSize.y+1) * sizeof(ccVertex3F));
|
||||
--m_nReuseGrid;
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of CCTiledGrid3D
|
||||
|
||||
CCTiledGrid3D::~CCTiledGrid3D(void)
|
||||
{
|
||||
free(m_pTexCoordinates);
|
||||
free(m_pVertices);
|
||||
free(m_pOriginalVertices);
|
||||
free(m_pIndices);
|
||||
}
|
||||
|
||||
CCTiledGrid3D* CCTiledGrid3D::gridWithSize(cocos2d::ccGridSize gridSize, cocos2d::CCTexture2D *pTexture, bool bFlipped)
|
||||
{
|
||||
CCTiledGrid3D *pRet= new CCTiledGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize, pTexture, bFlipped))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
CCTiledGrid3D* CCTiledGrid3D::gridWithSize(cocos2d::ccGridSize gridSize)
|
||||
{
|
||||
CCTiledGrid3D *pRet= new CCTiledGrid3D();
|
||||
|
||||
if (pRet)
|
||||
{
|
||||
if (pRet->initWithSize(gridSize))
|
||||
{
|
||||
pRet->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pRet;
|
||||
pRet = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::blit(void)
|
||||
{
|
||||
int n = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
// 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);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, m_pVertices);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, m_pTexCoordinates);
|
||||
glDrawElements(GL_TRIANGLES, n*6, GL_UNSIGNED_SHORT, m_pIndices);
|
||||
|
||||
// restore default GL state
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::calculateVertexPoints(void)
|
||||
{
|
||||
float width = (float)m_pTexture->getPixelsWide();
|
||||
float height = (float)m_pTexture->getPixelsHigh();
|
||||
float imageH = m_pTexture->getContentSizeInPixels().height;
|
||||
|
||||
int numQuads = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
m_pVertices = malloc(numQuads * 12 * sizeof(GLfloat));
|
||||
m_pOriginalVertices = malloc(numQuads * 12 * sizeof(GLfloat));
|
||||
m_pTexCoordinates = malloc(numQuads * 8 * sizeof(GLfloat));
|
||||
m_pIndices = (GLushort *)malloc(numQuads * 6 * sizeof(GLushort));
|
||||
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
float *texArray = (float*)m_pTexCoordinates;
|
||||
GLushort *idxArray = m_pIndices;
|
||||
|
||||
int x, y;
|
||||
|
||||
for( x = 0; x < m_sGridSize.x; x++ )
|
||||
{
|
||||
for( y = 0; y < m_sGridSize.y; y++ )
|
||||
{
|
||||
float x1 = x * m_obStep.x;
|
||||
float x2 = x1 + m_obStep.x;
|
||||
float y1 = y * m_obStep.y;
|
||||
float y2 = y1 + m_obStep.y;
|
||||
|
||||
*vertArray++ = x1;
|
||||
*vertArray++ = y1;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x2;
|
||||
*vertArray++ = y1;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x1;
|
||||
*vertArray++ = y2;
|
||||
*vertArray++ = 0;
|
||||
*vertArray++ = x2;
|
||||
*vertArray++ = y2;
|
||||
*vertArray++ = 0;
|
||||
|
||||
float newY1 = y1;
|
||||
float newY2 = y2;
|
||||
|
||||
if (m_bIsTextureFlipped)
|
||||
{
|
||||
newY1 = imageH - y1;
|
||||
newY2 = imageH - y2;
|
||||
}
|
||||
|
||||
*texArray++ = x1 / width;
|
||||
*texArray++ = newY1 / height;
|
||||
*texArray++ = x2 / width;
|
||||
*texArray++ = newY1 / height;
|
||||
*texArray++ = x1 / width;
|
||||
*texArray++ = newY2 / height;
|
||||
*texArray++ = x2 / width;
|
||||
*texArray++ = newY2 / height;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < numQuads; x++)
|
||||
{
|
||||
idxArray[x*6+0] = x * 4 + 0;
|
||||
idxArray[x*6+1] = x * 4 + 1;
|
||||
idxArray[x*6+2] = x * 4 + 2;
|
||||
|
||||
idxArray[x*6+3] = x * 4 + 1;
|
||||
idxArray[x*6+4] = x * 4 + 2;
|
||||
idxArray[x*6+5] = x * 4 + 3;
|
||||
}
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, numQuads * 12 * sizeof(GLfloat));
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::setTile(cocos2d::ccGridSize pos, cocos2d::ccQuad3 coords)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
memcpy(&vertArray[idx], &coords, sizeof(ccQuad3));
|
||||
}
|
||||
|
||||
ccQuad3 CCTiledGrid3D::originalTile(ccGridSize pos)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pOriginalVertices;
|
||||
|
||||
ccQuad3 ret;
|
||||
memcpy(&ret, &vertArray[idx], sizeof(ccQuad3));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ccQuad3 CCTiledGrid3D::tile(cocos2d::ccGridSize pos)
|
||||
{
|
||||
int idx = (m_sGridSize.y * pos.x + pos.y) * 4 * 3;
|
||||
float *vertArray = (float*)m_pVertices;
|
||||
|
||||
ccQuad3 ret;
|
||||
memcpy(&ret, &vertArray[idx], sizeof(ccQuad3));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CCTiledGrid3D::reuse(void)
|
||||
{
|
||||
if (m_nReuseGrid > 0)
|
||||
{
|
||||
int numQuads = m_sGridSize.x * m_sGridSize.y;
|
||||
|
||||
memcpy(m_pOriginalVertices, m_pVertices, numQuads * 12 * sizeof(GLfloat));
|
||||
--m_nReuseGrid;
|
||||
}
|
||||
}
|
||||
} // end of namespace cocos2d
|
|
@ -308,6 +308,14 @@
|
|||
RelativePath="..\include\CCActionTiledGrid.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\CCAnimation.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\CCAnimationCache.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\CCAtlasNode.h"
|
||||
>
|
||||
|
@ -420,6 +428,10 @@
|
|||
RelativePath="..\include\CCSprite.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\CCSpriteBatchNode.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\include\CCSpriteFrame.h"
|
||||
>
|
||||
|
@ -656,10 +668,18 @@
|
|||
<Filter
|
||||
Name="sprite_nodes"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\sprite_nodes\CCAnimation.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sprite_nodes\CCSprite.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sprite_nodes\CCSpriteBatchNode.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sprite_nodes\CCSpriteFrame.cpp"
|
||||
>
|
||||
|
@ -888,6 +908,14 @@
|
|||
RelativePath="..\platform\CCMenu_mobile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\platform\CCGL.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\platform\CCGrid_mobile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\platform\CCNode_mobile.cpp"
|
||||
>
|
||||
|
@ -896,6 +924,10 @@
|
|||
RelativePath="..\platform\CCTransition_mobile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\platform\CCNS.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\platform\CCXApplication_platform.h"
|
||||
>
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#include "CCAnimation.h"
|
||||
#include "CCTextureCache.h"
|
||||
#include "CCTexture2D.h"
|
||||
#include "ccMacros.h"
|
||||
#include "CCSpriteFrame.h"
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
// implementation of CCAnimation
|
||||
|
||||
CCAnimation* CCAnimation::animation()
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->init();
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
bool CCAnimation::init()
|
||||
{
|
||||
return initWithFrames(NULL, 0);
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithFrames(NSArray<CCSpriteFrame*> *frames)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithFrames(frames);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithFrames(NSArray<CCSpriteFrame*> *frames, float delay)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithFrames(frames, delay);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithName(const char *pszName)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithName(pszName);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithName(const char *pszName, NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithName(pszName, pFrames);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithName(const char *pszName, float fDelay, NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithName(pszName, fDelay, pFrames);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithName(const char *pszName, float fDelay)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithName(pszName, fDelay);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithFrames(NSArray<CCSpriteFrame*> *pFrames, float delay)
|
||||
{
|
||||
m_fDelay = delay;
|
||||
m_pobFrames = NSMutableArray<CCSpriteFrame*>::arrayWithArray(pFrames);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithFrames(NSArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
return initWithFrames(pFrames, 0);
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithName(const char *pszName)
|
||||
{
|
||||
return initWithName(pszName, 0, NULL);
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithName(const char *pszName, float fDelay)
|
||||
{
|
||||
return initWithName(pszName, fDelay, NULL);
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithName(const char *pszName, NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
return initWithName(pszName, 0, pFrames);
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithName(const char *pszName, float fDelay, NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
m_fDelay = fDelay;
|
||||
m_nameStr = pszName;
|
||||
m_pobFrames = NSMutableArray<CCSpriteFrame*>::arrayWithArray(pFrames);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCAnimation::~CCAnimation(void)
|
||||
{
|
||||
CCLOGINFO("cocos2d, deallocing %p", this);
|
||||
// [name_ release];
|
||||
m_nameStr.clear();
|
||||
CCX_SAFE_RELEASE(m_pobFrames);
|
||||
}
|
||||
|
||||
void CCAnimation::addFrame(CCSpriteFrame *pFrame)
|
||||
{
|
||||
m_pobFrames->addObject(pFrame);
|
||||
}
|
||||
|
||||
void CCAnimation::addFrameWithFileName(const char *pszFileName)
|
||||
{
|
||||
CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(pszFileName);
|
||||
CGRect rect = CGRectZero;
|
||||
rect.size = pTexture->getContentSize();
|
||||
CCSpriteFrame *pFrame = CCSpriteFrame::frameWithTexture(pTexture, rect);
|
||||
m_pobFrames->addObject(pFrame);
|
||||
}
|
||||
|
||||
void CCAnimation::addFrameWithTexture(CCTexture2D *pobTexture, CGRect rect)
|
||||
{
|
||||
CCSpriteFrame *pFrame = CCSpriteFrame::frameWithTexture(pobTexture, rect);
|
||||
m_pobFrames->addObject(pFrame);
|
||||
}
|
||||
}
|
|
@ -22,6 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "CCSpriteBatchNode.h"
|
||||
#include "CCAnimation.h"
|
||||
#include "CCAnimationCache.h"
|
||||
#include "CCSpriteSheet.h"
|
||||
#include "ccConfig.h"
|
||||
#include "CCSprite.h"
|
||||
|
@ -39,7 +42,7 @@ THE SOFTWARE.
|
|||
using namespace std;
|
||||
namespace cocos2d {
|
||||
|
||||
#if CC_SPRITESHEET_RENDER_SUBPIXEL
|
||||
#if CC_SPRITEBATCHNODE_RENDER_SUBPIXEL
|
||||
#define RENDER_IN_SUBPIXEL
|
||||
#else
|
||||
#define RENDER_IN_SUBPIXEL(__A__) ( (int)(__A__))
|
||||
|
@ -51,8 +54,42 @@ struct transformValues_ {
|
|||
CGPoint scale; // scale x and y
|
||||
float rotation;
|
||||
CGPoint ap; // anchor point in pixels
|
||||
bool visible;
|
||||
};
|
||||
|
||||
CCSprite* CCSprite::spriteWithBatchNode(CCSpriteBatchNode *batchNode, CGRect rect)
|
||||
{
|
||||
CCSprite *pobSprite = new CCSprite();
|
||||
if (pobSprite->initWithBatchNode(batchNode, rect))
|
||||
{
|
||||
pobSprite->autorelease();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pobSprite;
|
||||
pobSprite = NULL;
|
||||
}
|
||||
|
||||
return pobSprite;
|
||||
}
|
||||
|
||||
bool CCSprite::initWithBatchNode(CCSpriteBatchNode *batchNode, CGRect rect)
|
||||
{
|
||||
bool ret = initWithTexture(batchNode->getTexture(), rect);
|
||||
useBatchNode(batchNode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CCSprite::initWithBatchNodeRectInPixels(CCSpriteBatchNode *batchNode, CGRect rect)
|
||||
{
|
||||
bool ret = initWithTexture(batchNode->getTexture());
|
||||
setTextureRectInPixels(rect, false, rect.size);
|
||||
useBatchNode(batchNode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CCSprite* CCSprite::spriteWithTexture(CCTexture2D *pTexture)
|
||||
{
|
||||
CCSprite *pobSprite = new CCSprite();
|
||||
|
@ -111,37 +148,9 @@ CCSprite* CCSprite::spriteWithSpriteFrameName(const char *pszSpriteFrameName)
|
|||
return spriteWithSpriteFrame(pFrame);
|
||||
}
|
||||
|
||||
|
||||
// XXX: deprecated
|
||||
/*
|
||||
CCSprite* CCSprite::spriteWithCGImage(CGImageRef pImage)
|
||||
CCSprite* CCSprite::spriteWithSpriteSheet(CCSpriteSheetInternalOnly *pSpriteSheet, CGRect rect)
|
||||
{
|
||||
CCSprite *pobSprite = new CCSprite();
|
||||
pobSprite->initWithCGImage(pImage);
|
||||
pobSprite->autorelease();
|
||||
|
||||
return pobSprite;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
CCSprite* CCSprite::spriteWithCGImage(CGImageRef pImage, const char *pszKey)
|
||||
{
|
||||
CCSprite *pobSprite = new CCSprite();
|
||||
pobSprite->initWithCGImage(pImage, pszKey);
|
||||
pobSprite->autorelease();
|
||||
|
||||
return pobSprite;
|
||||
}
|
||||
*/
|
||||
|
||||
CCSprite* CCSprite::spriteWithSpriteSheet(CCSpriteSheet *pSpriteSheet, CGRect rect)
|
||||
{
|
||||
CCSprite *pobSprite = new CCSprite();
|
||||
pobSprite->initWithSpriteSheet(pSpriteSheet, rect);
|
||||
pobSprite->autorelease();
|
||||
|
||||
return pobSprite;
|
||||
return spriteWithBatchNode(pSpriteSheet, rect);
|
||||
}
|
||||
|
||||
bool CCSprite::init(void)
|
||||
|
@ -174,7 +183,7 @@ bool CCSprite::init(void)
|
|||
m_tAnchorPoint = ccp(0.5f, 0.5f);
|
||||
|
||||
// zwoptex default values
|
||||
m_obOffsetPosition = CGPointZero;
|
||||
m_obOffsetPositionInPixels = CGPointZero;
|
||||
|
||||
m_eHonorParentTransform = CC_HONOR_PARENT_TRANSFORM_ALL;
|
||||
m_bHasChildren = false;
|
||||
|
@ -191,7 +200,7 @@ bool CCSprite::init(void)
|
|||
// updated in "useSelfRender"
|
||||
|
||||
// Atlas: TexCoords
|
||||
setTextureRect(CGRectZero);
|
||||
setTextureRectInPixels(CGRectZero, false, CGSizeZero);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -295,13 +304,9 @@ CCSprite* CCSprite::initWithCGImage(CGImageRef pImage, const char *pszKey)
|
|||
}
|
||||
*/
|
||||
|
||||
bool CCSprite::initWithSpriteSheet(CCSpriteSheet *pSpriteSheet, CGRect rect)
|
||||
bool CCSprite::initWithSpriteSheet(CCSpriteSheetInternalOnly *pSpriteSheet, CGRect rect)
|
||||
{
|
||||
assert(pSpriteSheet != NULL);
|
||||
bool bRet = initWithTexture(pSpriteSheet->getTexture(), rect);
|
||||
useSpriteSheetRender(pSpriteSheet);
|
||||
|
||||
return bRet;
|
||||
return initWithBatchNode(pSpriteSheet, rect);
|
||||
}
|
||||
|
||||
CCSprite::CCSprite()
|
||||
|
@ -319,26 +324,30 @@ CCSprite::~CCSprite(void)
|
|||
void CCSprite::useSelfRender(void)
|
||||
{
|
||||
m_uAtlasIndex = CCSpriteIndexNotInitialized;
|
||||
m_bUsesSpriteSheet = false;
|
||||
m_bUsesBatchNode = false;
|
||||
m_pobTextureAtlas = NULL;
|
||||
m_pobSpriteSheet = NULL;
|
||||
m_pobBatchNode = NULL;
|
||||
m_bDirty = m_bRecursiveDirty = false;
|
||||
|
||||
float x1 = 0 + m_obOffsetPosition.x;
|
||||
float y1 = 0 + m_obOffsetPosition.y;
|
||||
float x2 = x1 + m_obRect.size.width;
|
||||
float y2 = y1 + m_obRect.size.height;
|
||||
float x1 = 0 + m_obOffsetPositionInPixels.x;
|
||||
float y1 = 0 + m_obOffsetPositionInPixels.y;
|
||||
float x2 = x1 + m_obRectInPixels.size.width;
|
||||
float y2 = y1 + m_obRectInPixels.size.height;
|
||||
m_sQuad.bl.vertices = vertex3(x1, y1, 0);
|
||||
m_sQuad.br.vertices = vertex3(x2, y1, 0);
|
||||
m_sQuad.tl.vertices = vertex3(x1, y2, 0);
|
||||
m_sQuad.tr.vertices = vertex3(x2, y2, 0);
|
||||
}
|
||||
|
||||
void CCSprite::useSpriteSheetRender(CCSpriteSheet *pSpriteSheet)
|
||||
void CCSprite::useBatchNode(CCSpriteBatchNode *batchNode)
|
||||
{
|
||||
m_bUsesSpriteSheet = true;
|
||||
m_pobTextureAtlas = pSpriteSheet->getTextureAtlas();
|
||||
m_pobSpriteSheet = pSpriteSheet;
|
||||
m_bUsesBatchNode = true;
|
||||
m_pobTextureAtlas = m_pobBatchNode->getTextureAtlas(); // weak ref
|
||||
}
|
||||
|
||||
void CCSprite::useSpriteSheetRender(CCSpriteSheetInternalOnly *pSpriteSheet)
|
||||
{
|
||||
useBatchNode(pSpriteSheet);
|
||||
}
|
||||
|
||||
void CCSprite::initAnimationDictionary(void)
|
||||
|
@ -348,33 +357,37 @@ void CCSprite::initAnimationDictionary(void)
|
|||
|
||||
void CCSprite::setTextureRect(CGRect rect)
|
||||
{
|
||||
setTextureRect(rect, rect.size);
|
||||
CGRect rectInPixels = CC_RECT_POINTS_TO_PIXELS(rect);
|
||||
setTextureRectInPixels(rectInPixels, false, rectInPixels.size);
|
||||
}
|
||||
|
||||
void CCSprite::setTextureRect(CGRect rect, CGSize size)
|
||||
|
||||
void CCSprite::setTextureRectInPixels(CGRect rect, bool rotated, CGSize size)
|
||||
{
|
||||
m_obRect = rect;
|
||||
m_obRectInPixels = rect;
|
||||
m_obRect = CC_RECT_PIXELS_TO_POINTS(rect);
|
||||
m_bRectRotated = rotated;
|
||||
|
||||
setContentSize(size);
|
||||
updateTextureCoords(rect);
|
||||
setContentSizeInPixels(size);
|
||||
updateTextureCoords(m_obRectInPixels);
|
||||
|
||||
CGPoint relativeOffset = m_obUnflippedOffsetPositionFromCenter;
|
||||
CGPoint relativeOffsetInPixels = m_obUnflippedOffsetPositionFromCenter;
|
||||
|
||||
// issue #732
|
||||
if (m_bFlipX)
|
||||
{
|
||||
relativeOffset.x = -relativeOffset.x;
|
||||
relativeOffsetInPixels.x = -relativeOffsetInPixels.x;
|
||||
}
|
||||
if (m_bFlipY)
|
||||
{
|
||||
relativeOffset.y = -relativeOffset.y;
|
||||
relativeOffsetInPixels.y = -relativeOffsetInPixels.y;
|
||||
}
|
||||
|
||||
m_obOffsetPosition.x = relativeOffset.x + (m_tContentSize.width - m_obRect.size.width) / 2;
|
||||
m_obOffsetPosition.y = relativeOffset.y + (m_tContentSize.height - m_obRect.size.height) / 2;
|
||||
m_obOffsetPositionInPixels.x = relativeOffsetInPixels.x + (m_tContentSizeInPixels.width - m_obRectInPixels.size.width) / 2;
|
||||
m_obOffsetPositionInPixels.y = relativeOffsetInPixels.y + (m_tContentSizeInPixels.height - m_obRectInPixels.size.height) / 2;
|
||||
|
||||
// rendering using SpriteSheet
|
||||
if (m_bUsesSpriteSheet)
|
||||
if (m_bUsesBatchNode)
|
||||
{
|
||||
// update dirty_, don't update recursiveDirty_
|
||||
m_bDirty = true;
|
||||
|
@ -384,10 +397,10 @@ void CCSprite::setTextureRect(CGRect rect, CGSize size)
|
|||
// self rendering
|
||||
|
||||
// Atlas: Vertex
|
||||
float x1 = 0 + m_obOffsetPosition.x;
|
||||
float y1 = 0 + m_obOffsetPosition.y;
|
||||
float x2 = x1 + m_obRect.size.width;
|
||||
float y2 = y1 + m_obRect.size.height;
|
||||
float x1 = 0 + m_obOffsetPositionInPixels.x;
|
||||
float y1 = 0 + m_obOffsetPositionInPixels.y;
|
||||
float x2 = x1 + m_obRectInPixels.size.width;
|
||||
float y2 = y1 + m_obRectInPixels.size.height;
|
||||
|
||||
// Don't update Z.
|
||||
m_sQuad.bl.vertices = vertex3(x1, y1, 0);
|
||||
|
@ -397,46 +410,97 @@ void CCSprite::setTextureRect(CGRect rect, CGSize size)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CCSprite::updateTextureCoords(CGRect rect)
|
||||
{
|
||||
if (m_pobTexture)
|
||||
CCTexture2D *tex = m_bUsesBatchNode ? m_pobTextureAtlas->getTexture() : m_pobTexture;
|
||||
if (! tex)
|
||||
{
|
||||
float atlasWidth = (float)m_pobTexture->getPixelsWide();
|
||||
float atlasHeight = (float)m_pobTexture->getPixelsHigh();
|
||||
return;
|
||||
}
|
||||
|
||||
float left = m_obRect.origin.x / atlasWidth;
|
||||
float right = (m_obRect.origin.x + m_obRect.size.width) / atlasWidth;
|
||||
float top = m_obRect.origin.y / atlasHeight;
|
||||
float bottom = (m_obRect.origin.y + m_obRect.size.height) / atlasHeight;
|
||||
float atlasWidth = (float)tex->getPixelsWide();
|
||||
float atlasHeight = (float)tex->getPixelsHigh();
|
||||
|
||||
float left, right, top, bottom;
|
||||
|
||||
if (m_bRectRotated)
|
||||
{
|
||||
#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
|
||||
left = (2*rect.origin.x+1)/(2*atlasWidth);
|
||||
right = left+(rect.size.height*2-2)/(2*atlasWidth);
|
||||
top = (2*rect.origin.y+1)/(2*atlasHeight);
|
||||
bottom = top+(rect.size.width*2-2)/(2*atlasHeight);
|
||||
#else
|
||||
left = rect.origin.x/atlasWidth;
|
||||
right = left+(rect.size.height/atlasWidth);
|
||||
top = rect.origin.y/atlasHeight;
|
||||
bottom = top+(rect.size.width/atlasHeight);
|
||||
#endif // CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
|
||||
|
||||
if (m_bFlipX)
|
||||
{
|
||||
float tmp = left;
|
||||
left = right;
|
||||
right = tmp;
|
||||
CC_SWAP(top, bottom, float);
|
||||
}
|
||||
|
||||
if (m_bFlipY)
|
||||
{
|
||||
float tmp = top;
|
||||
top = bottom;
|
||||
bottom = tmp;
|
||||
CC_SWAP(left, right, float);
|
||||
}
|
||||
|
||||
m_sQuad.bl.texCoords.u = left;
|
||||
m_sQuad.bl.texCoords.v = bottom;
|
||||
m_sQuad.br.texCoords.u = right;
|
||||
m_sQuad.br.texCoords.v = bottom;
|
||||
m_sQuad.tl.texCoords.u = left;
|
||||
m_sQuad.tl.texCoords.v = top;
|
||||
m_sQuad.tr.texCoords.u = right;
|
||||
m_sQuad.bl.texCoords.u = left;
|
||||
m_sQuad.bl.texCoords.v = top;
|
||||
m_sQuad.br.texCoords.u = left;
|
||||
m_sQuad.br.texCoords.v = bottom;
|
||||
m_sQuad.tl.texCoords.u = right;
|
||||
m_sQuad.tl.texCoords.v = top;
|
||||
m_sQuad.tr.texCoords.u = right;
|
||||
m_sQuad.tr.texCoords.v = bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
|
||||
left = (2*rect.origin.x+1)/(2*atlasWidth);
|
||||
right = left + (rect.size.width*2-2)/(2*atlasWidth);
|
||||
top = (2*rect.origin.y+1)/(2*atlasHeight);
|
||||
bottom = top + (rect.size.height*2-2)/(2*atlasHeight);
|
||||
#else
|
||||
left = rect.origin.x/atlasWidth;
|
||||
right = left + rect.size.width/atlasWidth;
|
||||
top = rect.origin.y/atlasHeight;
|
||||
bottom = top + rect.size.height/atlasHeight;
|
||||
#endif // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
|
||||
|
||||
if(m_bFlipX)
|
||||
{
|
||||
CC_SWAP(left,right,float);
|
||||
}
|
||||
|
||||
if(m_bFlipY)
|
||||
{
|
||||
CC_SWAP(top,bottom,float);
|
||||
}
|
||||
|
||||
m_sQuad.bl.texCoords.u = left;
|
||||
m_sQuad.bl.texCoords.v = bottom;
|
||||
m_sQuad.br.texCoords.u = right;
|
||||
m_sQuad.br.texCoords.v = bottom;
|
||||
m_sQuad.tl.texCoords.u = left;
|
||||
m_sQuad.tl.texCoords.v = top;
|
||||
m_sQuad.tr.texCoords.u = right;
|
||||
m_sQuad.tr.texCoords.v = top;
|
||||
}
|
||||
}
|
||||
|
||||
void CCSprite::updateTransform(void)
|
||||
{
|
||||
assert(m_bUsesSpriteSheet);
|
||||
assert(m_bUsesBatchNode);
|
||||
|
||||
// optimization. Quick return if not dirty
|
||||
if (! m_bDirty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CGAffineTransform matrix;
|
||||
|
||||
|
@ -449,9 +513,9 @@ void CCSprite::updateTransform(void)
|
|||
return;
|
||||
}
|
||||
|
||||
// Optimization: If parent is spritesheet, or parent is nil
|
||||
// Optimization: If parent is batchnode, or parent is nil
|
||||
// build Affine transform manually
|
||||
if (! m_pParent || m_pParent == m_pobSpriteSheet)
|
||||
if (! m_pParent || m_pParent == m_pobBatchNode)
|
||||
{
|
||||
float radians = -CC_DEGREES_TO_RADIANS(m_fRotation);
|
||||
float c = cosf(radians);
|
||||
|
@ -459,18 +523,31 @@ void CCSprite::updateTransform(void)
|
|||
|
||||
matrix = CGAffineTransformMake(c * m_fScaleX, s * m_fScaleX,
|
||||
-s * m_fScaleY, c * m_fScaleY,
|
||||
m_tPosition.x, m_tPosition.y);
|
||||
m_tPositionInPixels.x, m_tPositionInPixels.y);
|
||||
matrix = CGAffineTransformTranslate(matrix, -m_tAnchorPointInPixels.x, -m_tAnchorPointInPixels.y);
|
||||
} else
|
||||
if (m_pParent != m_pobSpriteSheet)
|
||||
} else // parent_ != batchNode_
|
||||
{
|
||||
// else do affine transformation according to the HonorParentTransform
|
||||
matrix = CGAffineTransformIdentity;
|
||||
ccHonorParentTransform prevHonor = CC_HONOR_PARENT_TRANSFORM_ALL;
|
||||
|
||||
for (CCNode *p = this; p && p != m_pobSpriteSheet; p = p->getParent())
|
||||
for (CCNode *p = this; p && p != m_pobBatchNode; p = p->getParent())
|
||||
{
|
||||
struct transformValues_ tv = ((CCSprite*)p)->getTransformValues();
|
||||
// Might happen. Issue #1053
|
||||
// how to implement, we can not use dynamic
|
||||
// NSAssert( [p isKindOfClass:[CCSprite class]], @"CCSprite should be a CCSprite subclass. Probably you initialized an sprite with a batchnode, but you didn't add it to the batch node." );
|
||||
struct transformValues_ tv;
|
||||
((CCSprite*)p)->getTransformValues(&tv);
|
||||
|
||||
// If any of the parents are not visible, then don't draw this node
|
||||
if (! tv.visible)
|
||||
{
|
||||
m_sQuad.br.vertices = m_sQuad.tl.vertices = m_sQuad.tr.vertices = m_sQuad.bl.vertices = vertex3(0,0,0);
|
||||
m_pobTextureAtlas->updateQuad(&m_sQuad, m_uAtlasIndex);
|
||||
m_bDirty = m_bRecursiveDirty = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CGAffineTransform newMatrix = CGAffineTransformIdentity;
|
||||
|
||||
|
@ -503,10 +580,10 @@ void CCSprite::updateTransform(void)
|
|||
//
|
||||
// calculate the Quad based on the Affine Matrix
|
||||
//
|
||||
CGSize size = m_obRect.size;
|
||||
CGSize size = m_obRectInPixels.size;
|
||||
|
||||
float x1 = m_obOffsetPosition.x;
|
||||
float y1 = m_obOffsetPosition.y;
|
||||
float x1 = m_obOffsetPositionInPixels.x;
|
||||
float y1 = m_obOffsetPositionInPixels.y;
|
||||
|
||||
float x2 = x1 + size.width;
|
||||
float y2 = y1 + size.height;
|
||||
|
@ -529,10 +606,10 @@ void CCSprite::updateTransform(void)
|
|||
float dx = x1 * cr - y2 * sr2 + x;
|
||||
float dy = x1 * sr + y2 * cr2 + y;
|
||||
|
||||
m_sQuad.bl.vertices = vertex3(RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), m_fVertexZ);
|
||||
m_sQuad.br.vertices = vertex3(RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), m_fVertexZ);
|
||||
m_sQuad.tl.vertices = vertex3(RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), m_fVertexZ);
|
||||
m_sQuad.tr.vertices = vertex3(RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), m_fVertexZ);
|
||||
m_sQuad.bl.vertices = vertex3((float)RENDER_IN_SUBPIXEL(ax), (float)RENDER_IN_SUBPIXEL(ay), m_fVertexZ);
|
||||
m_sQuad.br.vertices = vertex3((float)RENDER_IN_SUBPIXEL(bx), (float)RENDER_IN_SUBPIXEL(by), m_fVertexZ);
|
||||
m_sQuad.tl.vertices = vertex3((float)RENDER_IN_SUBPIXEL(dx), (float)RENDER_IN_SUBPIXEL(dy), m_fVertexZ);
|
||||
m_sQuad.tr.vertices = vertex3((float)RENDER_IN_SUBPIXEL(cx), (float)RENDER_IN_SUBPIXEL(cy), m_fVertexZ);
|
||||
|
||||
m_pobTextureAtlas->updateQuad(&m_sQuad, m_uAtlasIndex);
|
||||
m_bDirty = m_bRecursiveDirty = false;
|
||||
|
@ -540,31 +617,28 @@ void CCSprite::updateTransform(void)
|
|||
|
||||
// XXX: Optimization: instead of calling 5 times the parent sprite to obtain: position, scale.x, scale.y, anchorpoint and rotation,
|
||||
// this fuction return the 5 values in 1 single call
|
||||
struct transformValues_ CCSprite::getTransformValues(void)
|
||||
void CCSprite::getTransformValues(struct transformValues_ *tv)
|
||||
{
|
||||
struct transformValues_ tv;
|
||||
tv.pos = m_tPosition;
|
||||
tv.scale.x = m_fScaleX;
|
||||
tv.scale.y = m_fScaleY;
|
||||
tv.rotation = m_fRotation;
|
||||
tv.ap = m_tAnchorPointInPixels;
|
||||
|
||||
return tv;
|
||||
tv->pos = m_tPositionInPixels;
|
||||
tv->scale.x = m_fScaleX;
|
||||
tv->scale.y = m_fScaleY;
|
||||
tv->rotation = m_fRotation;
|
||||
tv->ap = m_tAnchorPointInPixels;
|
||||
tv->visible = m_bIsVisible;
|
||||
}
|
||||
|
||||
// draw
|
||||
|
||||
void CCSprite::draw(void)
|
||||
{
|
||||
assert(! m_bUsesSpriteSheet);
|
||||
assert(! m_bUsesBatchNode);
|
||||
|
||||
// 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_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
|
||||
// Unneeded states: -
|
||||
bool newBlend = false;
|
||||
if (m_sBlendFunc.src != CC_BLEND_SRC || m_sBlendFunc.dst != CC_BLEND_DST)
|
||||
bool newBlend = m_sBlendFunc.src != CC_BLEND_SRC || m_sBlendFunc.dst != CC_BLEND_DST;
|
||||
if (newBlend)
|
||||
{
|
||||
newBlend = true;
|
||||
glBlendFunc(m_sBlendFunc.src, m_sBlendFunc.dst);
|
||||
}
|
||||
|
||||
|
@ -578,7 +652,7 @@ void CCSprite::draw(void)
|
|||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
int offset = (int)&m_sQuad;
|
||||
long offset = (long)&m_sQuad;
|
||||
|
||||
// vertex
|
||||
int diff = offsetof(ccV3F_C4B_T2F, vertices);
|
||||
|
@ -611,30 +685,29 @@ void CCSprite::draw(void)
|
|||
|
||||
// CCNode overrides
|
||||
|
||||
CCNode* CCSprite::addChild(CCNode* pChild)
|
||||
void CCSprite::addChild(CCNode* pChild)
|
||||
{
|
||||
return CCNode::addChild(pChild);
|
||||
CCNode::addChild(pChild);
|
||||
}
|
||||
|
||||
CCNode* CCSprite::addChild(CCNode *pChild, int zOrder)
|
||||
void CCSprite::addChild(CCNode *pChild, int zOrder)
|
||||
{
|
||||
return CCNode::addChild(pChild, zOrder);
|
||||
CCNode::addChild(pChild, zOrder);
|
||||
}
|
||||
|
||||
CCNode* CCSprite::addChild(CCNode *pChild, int zOrder, int tag)
|
||||
void CCSprite::addChild(CCNode *pChild, int zOrder, int tag)
|
||||
{
|
||||
assert(pChild != NULL);
|
||||
CCNode* pRet = CCNode::addChild(pChild, zOrder, tag);
|
||||
CCNode::addChild(pChild, zOrder, tag);
|
||||
|
||||
if (m_bUsesSpriteSheet)
|
||||
if (m_bUsesBatchNode)
|
||||
{
|
||||
unsigned int index = m_pobSpriteSheet->atlasIndexForChild((CCSprite*)(pChild), zOrder);
|
||||
m_pobSpriteSheet->insertChild((CCSprite*)(pChild), index);
|
||||
assert(((CCSprite*)pChild)->getTexture()->getName() == m_pobTextureAtlas->getTexture()->getName());
|
||||
unsigned int index = m_pobBatchNode->atlasIndexForChild((CCSprite*)(pChild), zOrder);
|
||||
m_pobBatchNode->insertChild((CCSprite*)(pChild), index);
|
||||
}
|
||||
|
||||
m_bHasChildren = true;
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
void CCSprite::reorderChild(CCNode *pChild, int zOrder)
|
||||
|
@ -647,7 +720,7 @@ void CCSprite::reorderChild(CCNode *pChild, int zOrder)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_bUsesSpriteSheet)
|
||||
if (m_bUsesBatchNode)
|
||||
{
|
||||
// XXX: Instead of removing/adding, it is more efficient to reorder manually
|
||||
pChild->retain();
|
||||
|
@ -663,9 +736,9 @@ void CCSprite::reorderChild(CCNode *pChild, int zOrder)
|
|||
|
||||
void CCSprite::removeChild(CCNode *pChild, bool bCleanup)
|
||||
{
|
||||
if (m_bUsesSpriteSheet)
|
||||
if (m_bUsesBatchNode)
|
||||
{
|
||||
m_pobSpriteSheet->removeSpriteFromAtlas((CCSprite*)(pChild));
|
||||
m_pobBatchNode->removeSpriteFromAtlas((CCSprite*)(pChild));
|
||||
}
|
||||
|
||||
CCNode::removeChild(pChild, bCleanup);
|
||||
|
@ -674,7 +747,7 @@ void CCSprite::removeChild(CCNode *pChild, bool bCleanup)
|
|||
|
||||
void CCSprite::removeAllChildrenWithCleanup(bool bCleanup)
|
||||
{
|
||||
if (m_bUsesSpriteSheet)
|
||||
if (m_bUsesBatchNode)
|
||||
{
|
||||
CCSprite *pChild;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
|
@ -682,7 +755,7 @@ void CCSprite::removeAllChildrenWithCleanup(bool bCleanup)
|
|||
{
|
||||
pChild = (CCSprite*)(*iter);
|
||||
CCX_BREAK_IF(! pChild);
|
||||
m_pobSpriteSheet->removeSpriteFromAtlas(pChild);
|
||||
m_pobBatchNode->removeSpriteFromAtlas(pChild);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -693,7 +766,7 @@ void CCSprite::removeAllChildrenWithCleanup(bool bCleanup)
|
|||
|
||||
//
|
||||
// CCNode property overloads
|
||||
// used only when parent is CCSpriteSheet
|
||||
// used only when parent is CCSpriteBatchNode
|
||||
//
|
||||
|
||||
void CCSprite::setDirtyRecursively(bool bValue)
|
||||
|
@ -715,7 +788,7 @@ void CCSprite::setDirtyRecursively(bool bValue)
|
|||
|
||||
// XXX HACK: optimization
|
||||
#define SET_DIRTY_RECURSIVELY() { \
|
||||
if (m_bUsesSpriteSheet && ! m_bRecursiveDirty) { \
|
||||
if (m_bUsesBatchNode && ! m_bRecursiveDirty) { \
|
||||
m_bDirty = m_bRecursiveDirty = true; \
|
||||
if ( m_bHasChildren) \
|
||||
setDirtyRecursively(true); \
|
||||
|
@ -725,6 +798,12 @@ void CCSprite::setDirtyRecursively(bool bValue)
|
|||
void CCSprite::setPosition(CGPoint pos)
|
||||
{
|
||||
CCNode::setPosition(pos);
|
||||
SET_DIRTY_RECURSIVELY();
|
||||
}
|
||||
|
||||
void CCSprite::setPositionInPixels(CGPoint pos)
|
||||
{
|
||||
CCNode::setPositionInPixels(pos);
|
||||
SET_DIRTY_RECURSIVELY();
|
||||
}
|
||||
|
||||
|
@ -766,32 +845,14 @@ void CCSprite::setAnchorPoint(CGPoint anchor)
|
|||
|
||||
void CCSprite::setIsRelativeAnchorPoint(bool bRelative)
|
||||
{
|
||||
assert(! m_bUsesSpriteSheet);
|
||||
assert(! m_bUsesBatchNode);
|
||||
CCNode::setIsRelativeAnchorPoint(bRelative);
|
||||
}
|
||||
|
||||
void CCSprite::setIsVisible(bool bVisible)
|
||||
{
|
||||
if (bVisible != m_bIsVisible)
|
||||
{
|
||||
CCNode::setIsVisible(bVisible);
|
||||
if (m_bUsesSpriteSheet && m_bRecursiveDirty)
|
||||
{
|
||||
m_bDirty = m_bRecursiveDirty = true;
|
||||
CCNode *pChild;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
if (m_pChildren && m_pChildren->count() != 0)
|
||||
{
|
||||
for (iter = m_pChildren->begin(); iter != m_pChildren->end(); ++iter)
|
||||
{
|
||||
pChild = *iter;
|
||||
|
||||
CCX_BREAK_IF(! pChild);
|
||||
pChild->setIsVisible(bVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CCNode::setIsVisible(bVisible);
|
||||
SET_DIRTY_RECURSIVELY();
|
||||
}
|
||||
|
||||
void CCSprite::setFlipX(bool bFlipX)
|
||||
|
@ -799,7 +860,7 @@ void CCSprite::setFlipX(bool bFlipX)
|
|||
if (m_bFlipX != bFlipX)
|
||||
{
|
||||
m_bFlipX = bFlipX;
|
||||
setTextureRect(m_obRect);
|
||||
setTextureRectInPixels(m_obRectInPixels, m_bRectRotated, m_obRectInPixels.size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -813,7 +874,7 @@ void CCSprite::setFlipY(bool bFlipY)
|
|||
if (m_bFlipY != bFlipY)
|
||||
{
|
||||
m_bFlipY = bFlipY;
|
||||
setTextureRect(m_obRect);
|
||||
setTextureRectInPixels(m_obRectInPixels, m_bRectRotated, m_obRectInPixels.size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,7 +897,7 @@ void CCSprite::updateColor(void)
|
|||
m_sQuad.tr.colors = color4;
|
||||
|
||||
// renders using Sprite Manager
|
||||
if (m_bUsesSpriteSheet)
|
||||
if (m_bUsesBatchNode)
|
||||
{
|
||||
if (m_uAtlasIndex != CCSpriteIndexNotInitialized)
|
||||
{
|
||||
|
@ -908,11 +969,11 @@ bool CCSprite::getIsOpacityModifyRGB(void)
|
|||
return m_bOpacityModifyRGB;
|
||||
}
|
||||
|
||||
// CCFrameProtocol protocol
|
||||
// Frames
|
||||
|
||||
void CCSprite::setDisplayFrame(CCSpriteFrame *pNewFrame)
|
||||
{
|
||||
m_obUnflippedOffsetPositionFromCenter = pNewFrame->getOffset();
|
||||
m_obUnflippedOffsetPositionFromCenter = pNewFrame->getOffsetInPixels();
|
||||
|
||||
CCTexture2D *pNewTexture = pNewFrame->getTexture();
|
||||
// update texture before updating texture rect
|
||||
|
@ -923,9 +984,11 @@ void CCSprite::setDisplayFrame(CCSpriteFrame *pNewFrame)
|
|||
}
|
||||
|
||||
// update rect
|
||||
setTextureRect(pNewFrame->getRect(), pNewFrame->getOriginalSize());
|
||||
m_bRectRotated = pNewFrame->isRotated();
|
||||
setTextureRectInPixels(pNewFrame->getRectInPixels(), pNewFrame->isRotated(), pNewFrame->getOriginalSizeInPixels());
|
||||
}
|
||||
|
||||
// XXX deprecated
|
||||
void CCSprite::setDisplayFrame(const char *pszAnimationName, int nFrameIndex)
|
||||
{
|
||||
if (! m_pAnimations)
|
||||
|
@ -941,18 +1004,32 @@ void CCSprite::setDisplayFrame(const char *pszAnimationName, int nFrameIndex)
|
|||
setDisplayFrame(pFrame);
|
||||
}
|
||||
|
||||
void CCSprite::setDisplayFrameWithAnimationName(const char *animationName, int frameIndex)
|
||||
{
|
||||
assert(animationName);
|
||||
|
||||
CCAnimation *a = CCAnimationCache::sharedAnimationCache()->animationByName(animationName);
|
||||
|
||||
assert(a);
|
||||
|
||||
CCSpriteFrame *frame = a->getFrames()->getObjectAtIndex(frameIndex);
|
||||
|
||||
assert(frame);
|
||||
|
||||
setDisplayFrame(frame);
|
||||
}
|
||||
|
||||
bool CCSprite::isFrameDisplayed(CCSpriteFrame *pFrame)
|
||||
{
|
||||
CGRect r = pFrame->getRect();
|
||||
CGPoint p = pFrame->getOffset();
|
||||
|
||||
return (CGRect::CGRectEqualToRect(r, m_obRect) &&
|
||||
pFrame->getTexture()->getName() == m_pobTexture->getName() &&
|
||||
CGPoint::CGPointEqualToPoint(p, m_obOffsetPosition));
|
||||
pFrame->getTexture()->getName() == m_pobTexture->getName());
|
||||
}
|
||||
|
||||
CCSpriteFrame* CCSprite::displayedFrame(void)
|
||||
{
|
||||
return CCSpriteFrame::frameWithTexture(m_pobTexture, m_obRect, CGPointZero);
|
||||
return CCSpriteFrame::frameWithTexture(m_pobTexture, m_obRect);
|
||||
}
|
||||
|
||||
void CCSprite::addAnimation(CCAnimation *pAnimation)
|
||||
|
@ -978,7 +1055,7 @@ CCAnimation* CCSprite::animationByName(const char *pszAnimationName)
|
|||
void CCSprite::updateBlendFunc(void)
|
||||
{
|
||||
// CCSprite: updateBlendFunc doesn't work when the sprite is rendered using a CCSpriteSheet
|
||||
assert (! m_bUsesSpriteSheet);
|
||||
assert (! m_bUsesBatchNode);
|
||||
|
||||
// it's possible to have an untextured sprite
|
||||
if (! m_pobTexture || ! m_pobTexture->getHasPremultipliedAlpha())
|
||||
|
@ -998,7 +1075,7 @@ void CCSprite::updateBlendFunc(void)
|
|||
void CCSprite::setTexture(CCTexture2D *texture)
|
||||
{
|
||||
// CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteSheet
|
||||
assert(! m_bUsesSpriteSheet);
|
||||
assert(! m_bUsesBatchNode);
|
||||
|
||||
// we can not use RTTI, so we do not known the type of object
|
||||
// accept texture==nil as argument
|
||||
|
|
|
@ -0,0 +1,628 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010 cocos2d-x.org
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#include "CCSpriteBatchNode.h"
|
||||
#include "ccConfig.h"
|
||||
#include "CCSprite.h"
|
||||
#include "effects/CCGrid.h"
|
||||
#include "CCDrawingPrimitives.h"
|
||||
#include "CCTextureCache.h"
|
||||
#include "CGPointExtension.h"
|
||||
|
||||
namespace cocos2d
|
||||
{
|
||||
const int defaultCapacity = 29;
|
||||
|
||||
/*
|
||||
* creation with CCTexture2D
|
||||
*/
|
||||
CCSpriteBatchNode* CCSpriteBatchNode::batchNodeWithTexture(cocos2d::CCTexture2D *tex)
|
||||
{
|
||||
CCSpriteBatchNode *batchNode = new CCSpriteBatchNode();
|
||||
batchNode->initWithTexture(tex, defaultCapacity);
|
||||
batchNode->autorelease();
|
||||
|
||||
return batchNode;
|
||||
}
|
||||
|
||||
CCSpriteBatchNode* CCSpriteBatchNode::spriteSheetWithTexture(cocos2d::CCTexture2D *tex)
|
||||
{
|
||||
return batchNodeWithTexture(tex);
|
||||
}
|
||||
|
||||
CCSpriteBatchNode* CCSpriteBatchNode::batchNodeWithTexture(CCTexture2D* tex, unsigned int capacity)
|
||||
{
|
||||
CCSpriteBatchNode *batchNode = new CCSpriteBatchNode();
|
||||
batchNode->initWithTexture(tex, capacity);
|
||||
batchNode->autorelease();
|
||||
|
||||
return batchNode;
|
||||
}
|
||||
|
||||
CCSpriteBatchNode* CCSpriteBatchNode::spriteSheetWithTexture(CCTexture2D *tex, unsigned int capacity)
|
||||
{
|
||||
return batchNodeWithTexture(tex, capacity);
|
||||
}
|
||||
|
||||
/*
|
||||
* creation with File Image
|
||||
*/
|
||||
CCSpriteBatchNode* CCSpriteBatchNode::batchNodeWithFile(const char *fileImage, unsigned int capacity)
|
||||
{
|
||||
CCSpriteBatchNode *batchNode = new CCSpriteBatchNode();
|
||||
batchNode->initWithFile(fileImage, capacity);
|
||||
batchNode->autorelease();
|
||||
|
||||
return batchNode;
|
||||
}
|
||||
|
||||
CCSpriteBatchNode* CCSpriteBatchNode::spriteSheetWithFile(const char *fileImage, unsigned int capacity)
|
||||
{
|
||||
return batchNodeWithFile(fileImage, capacity);
|
||||
}
|
||||
|
||||
CCSpriteBatchNode* CCSpriteBatchNode::batchNodeWithFile(const char *fileImage)
|
||||
{
|
||||
CCSpriteBatchNode *batchNode = new CCSpriteBatchNode();
|
||||
batchNode->initWithFile(fileImage, defaultCapacity);
|
||||
batchNode->autorelease();
|
||||
|
||||
return batchNode;
|
||||
}
|
||||
|
||||
CCSpriteBatchNode* CCSpriteBatchNode::spriteSheetWithFile(const char *fileImage)
|
||||
{
|
||||
return batchNodeWithFile(fileImage);
|
||||
}
|
||||
|
||||
/*
|
||||
* init with CCTexture2D
|
||||
*/
|
||||
bool CCSpriteBatchNode::initWithTexture(cocos2d::CCTexture2D *tex, unsigned int capacity)
|
||||
{
|
||||
m_blendFunc.src = CC_BLEND_SRC;
|
||||
m_blendFunc.dst = CC_BLEND_DST;
|
||||
m_pobTextureAtlas = new CCTextureAtlas();
|
||||
m_pobTextureAtlas->initWithTexture(tex, capacity);
|
||||
|
||||
updateBlendFunc();
|
||||
|
||||
// no lazy alloc in this node
|
||||
m_pChildren = new NSMutableArray<CCNode*>();
|
||||
m_pobDescendants = new NSMutableArray<CCSprite*>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* init with FileImage
|
||||
*/
|
||||
bool CCSpriteBatchNode::initWithFile(const char* fileImage, unsigned int capacity)
|
||||
{
|
||||
CCTexture2D *pTexture2D = CCTextureCache::sharedTextureCache()->addImage(fileImage);
|
||||
return initWithTexture(pTexture2D, capacity);
|
||||
}
|
||||
|
||||
CCSpriteBatchNode::~CCSpriteBatchNode()
|
||||
{
|
||||
m_pobTextureAtlas->release();
|
||||
m_pobDescendants->release();
|
||||
}
|
||||
|
||||
// override visit
|
||||
// don't call visit on it's children
|
||||
void CCSpriteBatchNode::visit(void)
|
||||
{
|
||||
// CAREFUL:
|
||||
// This visit is almost identical to CocosNode#visit
|
||||
// with the exception that it doesn't call visit on it's children
|
||||
//
|
||||
// The alternative is to have a void CCSprite#visit, but
|
||||
// although this is less mantainable, is faster
|
||||
//
|
||||
if (! m_bIsVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
if (m_pGrid && m_pGrid->isActive())
|
||||
{
|
||||
m_pGrid->beforeDraw();
|
||||
transformAncestors();
|
||||
}
|
||||
|
||||
transform();
|
||||
|
||||
draw();
|
||||
|
||||
if (m_pGrid && m_pGrid->isActive())
|
||||
{
|
||||
m_pGrid->afterDraw(this);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
// xxx deprecated
|
||||
CCSprite* CCSpriteBatchNode::createSpriteWithRect(CGRect rect)
|
||||
{
|
||||
CCSprite *pSprite = CCSprite::spriteWithTexture(m_pobTextureAtlas->getTexture(), rect);
|
||||
pSprite->useBatchNode(this);
|
||||
|
||||
return pSprite;
|
||||
}
|
||||
|
||||
// XXX deprecated
|
||||
void CCSpriteBatchNode::initSprite(cocos2d::CCSprite *sprite, cocos2d::CGRect rect)
|
||||
{
|
||||
if (sprite)
|
||||
{
|
||||
sprite->initWithTexture(m_pobTextureAtlas->getTexture(), rect);
|
||||
sprite->useBatchNode(this);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::addChild(CCNode *child, int zOrder, int tag)
|
||||
{
|
||||
assert(child != NULL);
|
||||
|
||||
CCSprite *pSprite = (CCSprite*)(child);
|
||||
// check CCSprite is using the same texture id
|
||||
assert(pSprite->getTexture()->getName() == m_pobTextureAtlas->getTexture()->getName());
|
||||
|
||||
CCNode::addChild(child, zOrder, tag);
|
||||
|
||||
unsigned int uIndex = atlasIndexForChild(pSprite, zOrder);
|
||||
insertChild(pSprite, uIndex);
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::addChild(CCNode *child)
|
||||
{
|
||||
CCNode::addChild(child);
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::addChild(CCNode *child, int zOrder)
|
||||
{
|
||||
CCNode::addChild(child, zOrder);
|
||||
}
|
||||
|
||||
// override reorderChild
|
||||
void CCSpriteBatchNode::reorderChild(CCNode *child, int zOrder)
|
||||
{
|
||||
assert(child != NULL);
|
||||
assert(m_pChildren->containsObject(child));
|
||||
|
||||
if (zOrder == child->getZOrder())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// xxx: instead of removing/adding, it is more efficient ot reorder manually
|
||||
child->retain();
|
||||
removeChild(child, false);
|
||||
addChild(child, zOrder);
|
||||
child->release();
|
||||
}
|
||||
|
||||
// override remove child
|
||||
void CCSpriteBatchNode::removeChild(CCNode *child, bool cleanup)
|
||||
{
|
||||
CCSprite *pSprite = (CCSprite*)(child);
|
||||
|
||||
// explicit null handling
|
||||
if (pSprite == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_pChildren->containsObject(pSprite));
|
||||
|
||||
// cleanup before removing
|
||||
removeSpriteFromAtlas(pSprite);
|
||||
|
||||
CCNode::removeChild(pSprite, cleanup);
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::removeChildAtIndex(unsigned int uIndex, bool bDoCleanup)
|
||||
{
|
||||
removeChild((CCSprite*)(m_pChildren->getObjectAtIndex(uIndex)), bDoCleanup);
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::removeAllChildrenWithCleanup(bool bCleanup)
|
||||
{
|
||||
// Invalidate atlas index. issue #569
|
||||
if (m_pChildren && m_pChildren->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
for (iter = m_pChildren->begin(); iter != m_pChildren->end(); ++iter)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iter);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pSprite->useSelfRender();
|
||||
}
|
||||
}
|
||||
|
||||
CCNode::removeAllChildrenWithCleanup(bCleanup);
|
||||
|
||||
m_pobDescendants->removeAllObjects();
|
||||
m_pobTextureAtlas->removeAllQuads();
|
||||
}
|
||||
|
||||
// draw
|
||||
void CCSpriteBatchNode::draw(void)
|
||||
{
|
||||
// Optimization: Fast Dispatch
|
||||
if (m_pobTextureAtlas->getTotalQuads() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pobDescendants && m_pobDescendants->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCSprite*>::NSMutableArrayIterator iter;
|
||||
for (iter = m_pobDescendants->begin(); iter != m_pobDescendants->end(); ++iter)
|
||||
{
|
||||
pSprite = *iter;
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// fast dispatch
|
||||
pSprite->updateTransform();
|
||||
|
||||
|
||||
#if CC_SPRITESHEET_DEBUG_DRAW
|
||||
// issue #528
|
||||
CGRect rect = pSprite->boundingBox();
|
||||
CGPoint vertices[4]={
|
||||
ccp(rect.origin.x,rect.origin.y),
|
||||
ccp(rect.origin.x+rect.size.width,rect.origin.y),
|
||||
ccp(rect.origin.x+rect.size.width,rect.origin.y+rect.size.height),
|
||||
ccp(rect.origin.x,rect.origin.y+rect.size.height),
|
||||
};
|
||||
ccDrawPoly(vertices, 4, true);
|
||||
#endif // CC_SPRITESHEET_DEBUG_DRAW
|
||||
}
|
||||
}
|
||||
|
||||
// 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_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
|
||||
// Unneeded states: -
|
||||
bool newBlend = m_blendFunc.src != CC_BLEND_SRC || m_blendFunc.dst != CC_BLEND_DST;
|
||||
if (newBlend)
|
||||
{
|
||||
glBlendFunc(m_blendFunc.src, m_blendFunc.dst);
|
||||
}
|
||||
|
||||
m_pobTextureAtlas->drawQuads();
|
||||
if (newBlend)
|
||||
{
|
||||
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::increaseAtlasCapacity(void)
|
||||
{
|
||||
// if we're going beyond the current TextureAtlas's capacity,
|
||||
// all the previously initialized sprites will need to redo their texture coords
|
||||
// this is likely computationally expensive
|
||||
unsigned int quantity = (m_pobTextureAtlas->getCapacity() + 1) * 4 / 3;
|
||||
|
||||
CCLOG("cocos2d: CCSpriteSheet: resizing TextureAtlas capacity from %u to %u.",
|
||||
(unsigned int)m_pobTextureAtlas->getCapacity(), (unsigned int)quantity);
|
||||
|
||||
if (! m_pobTextureAtlas->resizeCapacity(quantity))
|
||||
{
|
||||
// serious problems
|
||||
CCLOG("cocos2d: WARNING: Not enough memory to resize the atlas");
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CCSpriteBatchNode::rebuildIndexInOrder(CCSprite *pobParent, unsigned int uIndex)
|
||||
{
|
||||
NSMutableArray<CCNode*> *pChildren = pobParent->getChildren();
|
||||
|
||||
if (pChildren && pChildren->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iter);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (pSprite->getZOrder() < 0)
|
||||
{
|
||||
uIndex = rebuildIndexInOrder(pSprite, uIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ignore self (batch node)
|
||||
if (! pobParent->isEqual(this))
|
||||
{
|
||||
pobParent->setAtlasIndex(uIndex);
|
||||
uIndex++;
|
||||
}
|
||||
|
||||
if (pChildren && pChildren->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iter);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (pSprite->getZOrder() >= 0)
|
||||
{
|
||||
uIndex = rebuildIndexInOrder(pSprite, uIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return uIndex;
|
||||
}
|
||||
|
||||
unsigned int CCSpriteBatchNode::highestAtlasIndexInChild(CCSprite *pSprite)
|
||||
{
|
||||
NSMutableArray<CCNode*> *pChildren = pSprite->getChildren();
|
||||
|
||||
if (! pChildren || pChildren->count() == 0)
|
||||
{
|
||||
return pSprite->getAtlasIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
return highestAtlasIndexInChild((CCSprite*)(pChildren->getLastObject()));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CCSpriteBatchNode::lowestAtlasIndexInChild(CCSprite *pSprite)
|
||||
{
|
||||
NSMutableArray<CCNode*> *pChildren = pSprite->getChildren();
|
||||
|
||||
if (! pChildren || pChildren->count() == 0)
|
||||
{
|
||||
return pSprite->getAtlasIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
return lowestAtlasIndexInChild((CCSprite*)(pChildren->getObjectAtIndex(0)));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CCSpriteBatchNode::atlasIndexForChild(CCSprite *pobSprite, int nZ)
|
||||
{
|
||||
NSMutableArray<CCNode*> *pBrothers = pobSprite->getParent()->getChildren();
|
||||
unsigned int uChildIndex = pBrothers->getIndexOfObject(pobSprite);
|
||||
|
||||
// ignore parent Z if parent is spriteSheet
|
||||
bool bIgnoreParent = (CCSpriteBatchNode*)(pobSprite->getParent()) == this;
|
||||
CCSprite *pPrevious = NULL;
|
||||
if (uChildIndex > 0)
|
||||
{
|
||||
pPrevious = (CCSprite*)(pBrothers->getObjectAtIndex(uChildIndex - 1));
|
||||
}
|
||||
|
||||
// first child of the sprite sheet
|
||||
if (bIgnoreParent)
|
||||
{
|
||||
if (uChildIndex == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return highestAtlasIndexInChild(pPrevious) + 1;
|
||||
}
|
||||
|
||||
// parent is a CCSprite, so, it must be taken into account
|
||||
|
||||
// first child of an CCSprite ?
|
||||
if (uChildIndex == 0)
|
||||
{
|
||||
CCSprite *p = (CCSprite*)(pobSprite->getParent());
|
||||
|
||||
// less than parent and brothers
|
||||
if (nZ < 0)
|
||||
{
|
||||
return p->getAtlasIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
return p->getAtlasIndex() + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// previous & sprite belong to the same branch
|
||||
if ((pPrevious->getZOrder() < 0 && nZ < 0) || (pPrevious->getZOrder() >= 0 && nZ >= 0))
|
||||
{
|
||||
return highestAtlasIndexInChild(pPrevious) + 1;
|
||||
}
|
||||
|
||||
// else (previous < 0 and sprite >= 0 )
|
||||
CCSprite *p = (CCSprite*)(pobSprite->getParent());
|
||||
return p->getAtlasIndex() + 1;
|
||||
}
|
||||
|
||||
// Should not happen. Error calculating Z on SpriteSheet
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add child helper
|
||||
|
||||
void CCSpriteBatchNode::insertChild(CCSprite *pobSprite, unsigned int uIndex)
|
||||
{
|
||||
pobSprite->useBatchNode(this);
|
||||
pobSprite->setAtlasIndex(uIndex);
|
||||
pobSprite->setDirty(true);
|
||||
|
||||
if (m_pobTextureAtlas->getTotalQuads() == m_pobTextureAtlas->getCapacity())
|
||||
{
|
||||
increaseAtlasCapacity();
|
||||
}
|
||||
|
||||
ccV3F_C4B_T2F_Quad quad = pobSprite->getQuad();
|
||||
m_pobTextureAtlas->insertQuad(&quad, uIndex);
|
||||
|
||||
m_pobDescendants->insertObjectAtIndex(pobSprite, uIndex);
|
||||
|
||||
// update indices
|
||||
unsigned int i = 0;
|
||||
if (m_pobDescendants && m_pobDescendants->count() > 0)
|
||||
{
|
||||
NSMutableArray<CCSprite*>::NSMutableArrayIterator iter;
|
||||
for (iter = m_pobDescendants->begin(); iter != m_pobDescendants->end(); ++iter)
|
||||
{
|
||||
if (! *iter)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (i > uIndex)
|
||||
{
|
||||
(*iter)->setAtlasIndex((*iter)->getAtlasIndex() + 1);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// add children recursively
|
||||
NSMutableArray<CCNode*> *pChildren = pobSprite->getChildren();
|
||||
if (pChildren && pChildren->count() > 0)
|
||||
{
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iterNode;
|
||||
CCSprite *pSprite;
|
||||
for (iterNode = pChildren->begin(); iterNode != pChildren->end(); ++iterNode)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iterNode);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int uIndex = atlasIndexForChild(pSprite, pSprite->getZOrder());
|
||||
insertChild(pSprite, uIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::removeSpriteFromAtlas(CCSprite *pobSprite)
|
||||
{
|
||||
// remove from TextureAtlas
|
||||
m_pobTextureAtlas->removeQuadAtIndex(pobSprite->getAtlasIndex());
|
||||
|
||||
// Cleanup sprite. It might be reused (issue #569)
|
||||
pobSprite->useSelfRender();
|
||||
|
||||
unsigned int uIndex = m_pobDescendants->getIndexOfObject(pobSprite);
|
||||
if (uIndex != -1)
|
||||
{
|
||||
m_pobDescendants->removeObjectAtIndex(uIndex);
|
||||
|
||||
// update all sprites beyond this one
|
||||
unsigned int count = m_pobDescendants->count();
|
||||
|
||||
for(; uIndex < count; ++uIndex)
|
||||
{
|
||||
CCSprite* s = (CCSprite*)(m_pobDescendants->getObjectAtIndex(uIndex));
|
||||
s->setAtlasIndex( s->getAtlasIndex() - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// remove children recursively
|
||||
NSMutableArray<CCNode*> *pChildren = pobSprite->getChildren();
|
||||
if (pChildren && pChildren->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iter);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
removeSpriteFromAtlas(pSprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::updateBlendFunc(void)
|
||||
{
|
||||
if (! m_pobTextureAtlas->getTexture()->getHasPremultipliedAlpha())
|
||||
{
|
||||
m_blendFunc.src = GL_SRC_ALPHA;
|
||||
m_blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
// CocosNodeTexture protocol
|
||||
void CCSpriteBatchNode::setBlendFunc(ccBlendFunc blendFunc)
|
||||
{
|
||||
m_blendFunc = blendFunc;
|
||||
}
|
||||
|
||||
ccBlendFunc CCSpriteBatchNode::getBlendFunc(void)
|
||||
{
|
||||
return m_blendFunc;
|
||||
}
|
||||
|
||||
CCTexture2D* CCSpriteBatchNode::getTexture(void)
|
||||
{
|
||||
return m_pobTextureAtlas->getTexture();
|
||||
}
|
||||
|
||||
void CCSpriteBatchNode::setTexture(CCTexture2D *texture)
|
||||
{
|
||||
m_pobTextureAtlas->setTexture(texture);
|
||||
updateBlendFunc();
|
||||
}
|
||||
|
||||
}
|
|
@ -22,136 +22,45 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "CCTextureCache.h"
|
||||
#include "CCSpriteFrame.h"
|
||||
#include "ccMacros.h"
|
||||
#include "CCTexture2D.h"
|
||||
#include "CGGeometry.h"
|
||||
|
||||
namespace cocos2d {
|
||||
|
||||
// implementation of CCAnimation
|
||||
|
||||
CCAnimation* CCAnimation::animationWithName(const char *pszName)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithName(pszName);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithName(const char *pszName, NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithName(pszName, pFrames);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithName(const char *pszName, float fDelay, NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithName(pszName, fDelay, pFrames);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
CCAnimation* CCAnimation::animationWithName(const char *pszName, float fDelay)
|
||||
{
|
||||
CCAnimation *pAnimation = new CCAnimation();
|
||||
pAnimation->initWithName(pszName, fDelay);
|
||||
pAnimation->autorelease();
|
||||
|
||||
return pAnimation;
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithName(const char *pszName)
|
||||
{
|
||||
return initWithName(pszName, 0, NULL);
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithName(const char *pszName, float fDelay)
|
||||
{
|
||||
return initWithName(pszName, fDelay, NULL);
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithName(const char *pszName, NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
return initWithName(pszName, 0, pFrames);
|
||||
}
|
||||
|
||||
bool CCAnimation::initWithName(const char *pszName, float fDelay, NSMutableArray<CCSpriteFrame*> *pFrames)
|
||||
{
|
||||
m_fDelay = fDelay;
|
||||
m_nameStr = pszName;
|
||||
m_pobFrames = NSMutableArray<CCSpriteFrame*>::arrayWithArray(pFrames);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCAnimation::~CCAnimation(void)
|
||||
{
|
||||
CCLOGINFO("cocos2d, deallocing %p", this);
|
||||
// [name_ release];
|
||||
m_nameStr.clear();
|
||||
CCX_SAFE_RELEASE(m_pobFrames);
|
||||
}
|
||||
|
||||
void CCAnimation::addFrame(CCSpriteFrame *pFrame)
|
||||
{
|
||||
m_pobFrames->addObject(pFrame);
|
||||
}
|
||||
|
||||
void CCAnimation::addFrameWithFileName(const char *pszFileName)
|
||||
{
|
||||
CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(pszFileName);
|
||||
CGRect rect = CGRectZero;
|
||||
rect.size = pTexture->getContentSize();
|
||||
CCSpriteFrame *pFrame = CCSpriteFrame::frameWithTexture(pTexture, rect, CGPointZero);
|
||||
m_pobFrames->addObject(pFrame);
|
||||
}
|
||||
|
||||
void CCAnimation::addFrameWithTexture(CCTexture2D *pobTexture, CGRect rect)
|
||||
{
|
||||
CCSpriteFrame *pFrame = CCSpriteFrame::frameWithTexture(pobTexture, rect, CGPointZero);
|
||||
m_pobFrames->addObject(pFrame);
|
||||
}
|
||||
|
||||
|
||||
// implementation of CCSpriteFrame
|
||||
|
||||
CCSpriteFrame* CCSpriteFrame::frameWithTexture(CCTexture2D *pobTexture, CGRect rect, CGPoint offset)
|
||||
CCSpriteFrame* CCSpriteFrame::frameWithTexture(CCTexture2D *pobTexture, CGRect rect)
|
||||
{
|
||||
CCSpriteFrame *pSpriteFrame = new CCSpriteFrame();;
|
||||
pSpriteFrame->initWithTexture(pobTexture, rect, offset, rect.size);
|
||||
pSpriteFrame->initWithTexture(pobTexture, rect);
|
||||
pSpriteFrame->autorelease();
|
||||
|
||||
return pSpriteFrame;
|
||||
}
|
||||
|
||||
CCSpriteFrame* CCSpriteFrame::frameWithTexture(CCTexture2D *pobTexture, CGRect rect, CGPoint offset, CGSize originalSize)
|
||||
CCSpriteFrame* CCSpriteFrame::frameWithTexture(CCTexture2D* pobTexture, CGRect rect, bool rotated, CGPoint offset, CGSize originalSize)
|
||||
{
|
||||
CCSpriteFrame *pSpriteFrame = new CCSpriteFrame();;
|
||||
pSpriteFrame->initWithTexture(pobTexture, rect, offset, originalSize);
|
||||
pSpriteFrame->initWithTexture(pobTexture, rect, rotated, offset, originalSize);
|
||||
pSpriteFrame->autorelease();
|
||||
|
||||
return pSpriteFrame;
|
||||
}
|
||||
|
||||
bool CCSpriteFrame::initWithTexture(CCTexture2D *pobTexture, CGRect rect, CGPoint offset)
|
||||
bool CCSpriteFrame::initWithTexture(CCTexture2D* pobTexture, CGRect rect)
|
||||
{
|
||||
return initWithTexture(pobTexture, rect, offset, rect.size);
|
||||
CGRect rectInPixels = CC_RECT_POINTS_TO_PIXELS(rect);
|
||||
return initWithTexture(pobTexture, rectInPixels, false, CGPointZero, rectInPixels.size);
|
||||
}
|
||||
|
||||
bool CCSpriteFrame::initWithTexture(CCTexture2D *pobTexture, CGRect rect, CGPoint offset, CGSize originalSize)
|
||||
bool CCSpriteFrame::initWithTexture(CCTexture2D* pobTexture, CGRect rect, bool rotated, CGPoint offset, CGSize originalSize)
|
||||
{
|
||||
m_pobTexture = pobTexture;
|
||||
pobTexture->retain();
|
||||
m_obOffset = offset;
|
||||
m_obRect = rect;
|
||||
m_obOriginalSize = originalSize;
|
||||
m_obRectInPixels = rect;
|
||||
m_obRect = CC_RECT_PIXELS_TO_POINTS(rect);
|
||||
m_bRotated = rotated;
|
||||
m_obOffsetInPixels = offset;
|
||||
|
||||
m_obOriginalSizeInPixels = originalSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -166,7 +75,7 @@ NSObject* CCSpriteFrame::copyWithZone(NSZone *pZone)
|
|||
{
|
||||
CCSpriteFrame *pCopy = new CCSpriteFrame();
|
||||
|
||||
pCopy->initWithTexture(m_pobTexture, m_obRect, m_obOffset, m_obOriginalSize);
|
||||
pCopy->initWithTexture(m_pobTexture, m_obRectInPixels, m_bRotated, m_obOffsetInPixels, m_obOriginalSizeInPixels);
|
||||
|
||||
return pCopy;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "platform/CCNS.h"
|
||||
#include "ccMacros.h"
|
||||
#include "CCTextureCache.h"
|
||||
#include "CCSpriteFrameCache.h"
|
||||
|
@ -54,22 +55,25 @@ void CCSpriteFrameCache::purgeSharedSpriteFrameCache(void)
|
|||
bool CCSpriteFrameCache::init(void)
|
||||
{
|
||||
m_pSpriteFrames= new NSDictionary<std::string, CCSpriteFrame*>();
|
||||
m_pSpriteFramesAliases = new NSDictionary<std::string, CCSpriteFrame*>();
|
||||
return true;
|
||||
}
|
||||
|
||||
CCSpriteFrameCache::~CCSpriteFrameCache(void)
|
||||
{
|
||||
m_pSpriteFrames->release();
|
||||
m_pSpriteFramesAliases->release();
|
||||
}
|
||||
|
||||
void CCSpriteFrameCache::addSpriteFramesWithDictionary(NSDictionary<std::string, NSObject*> *dictionary, CCTexture2D *pobTexture)
|
||||
{
|
||||
/*
|
||||
Supported Zwoptex Formats:
|
||||
enum {
|
||||
ZWTCoordinatesListXMLFormat_Legacy = 0
|
||||
ZWTCoordinatesListXMLFormat_v1_0,
|
||||
};
|
||||
|
||||
ZWTCoordinatesFormatOptionXMLLegacy = 0, // Flash Version
|
||||
ZWTCoordinatesFormatOptionXML1_0 = 1, // Desktop Version 0.0 - 0.4b
|
||||
ZWTCoordinatesFormatOptionXML1_1 = 2, // Desktop Version 1.0.0 - 1.0.1
|
||||
ZWTCoordinatesFormatOptionXML1_2 = 3, // Desktop Version 1.0.2+
|
||||
*/
|
||||
|
||||
NSDictionary<std::string, NSObject*> *metadataDict = (NSDictionary<std::string, NSObject*>*)dictionary->objectForKey(std::string("metadata"));
|
||||
|
@ -83,11 +87,7 @@ void CCSpriteFrameCache::addSpriteFramesWithDictionary(NSDictionary<std::string,
|
|||
}
|
||||
|
||||
// check the format
|
||||
if(format < 0 || format > 1)
|
||||
{
|
||||
NSAssert(0, "cocos2d: WARNING: format is not supported for CCSpriteFrameCache addSpriteFramesWithDictionary:texture:");
|
||||
return;
|
||||
}
|
||||
assert(format >=0 && format <= 3);
|
||||
|
||||
framesDict->begin();
|
||||
std::string key = "";
|
||||
|
@ -119,25 +119,69 @@ void CCSpriteFrameCache::addSpriteFramesWithDictionary(NSDictionary<std::string,
|
|||
ow = abs(ow);
|
||||
oh = abs(oh);
|
||||
// create frame
|
||||
spriteFrame = CCSpriteFrame::frameWithTexture(pobTexture, CGRectMake(x, y, w, h), CGPointMake(ox, oy), CGSizeMake((float)ow, (float)oh));
|
||||
spriteFrame = new CCSpriteFrame();
|
||||
spriteFrame->initWithTexture(pobTexture,
|
||||
CGRectMake(x, y, w, h),
|
||||
false,
|
||||
CGPointMake(ox, oy),
|
||||
CGSizeMake((float)ow, (float)oh)
|
||||
);
|
||||
}
|
||||
else if(format == 1)
|
||||
else if(format == 1 || format == 2)
|
||||
{
|
||||
/** @todo
|
||||
CGRect frame = CGRectFromString([frameDict objectForKey:@"frame"]);
|
||||
CGPoint offset = CGPointFromString([frameDict objectForKey:@"offset"]);
|
||||
CGSize sourceSize = CGSizeFromString([frameDict objectForKey:@"sourceSize"]);
|
||||
|
||||
CGRect frame = CCRectFromString(valueForKey("frame", frameDict));
|
||||
bool rotated = false;
|
||||
|
||||
// rotation
|
||||
if (format == 2)
|
||||
{
|
||||
rotated = atoi(valueForKey("rotated", frameDict)) == 0 ? false : true;
|
||||
}
|
||||
|
||||
CGPoint offset = CCPointFromString(valueForKey("offset", frameDict));
|
||||
CGSize sourceSize = CCSizeFromString(valueForKey("sourceSize", frameDict));
|
||||
|
||||
// create frame
|
||||
spriteFrame = [CCSpriteFrame frameWithTexture:texture rect:frame offset:offset originalSize:sourceSize];
|
||||
spriteFrame = new CCSpriteFrame();
|
||||
spriteFrame->initWithTexture(pobTexture,
|
||||
frame,
|
||||
rotated,
|
||||
offset,
|
||||
sourceSize
|
||||
);
|
||||
} else
|
||||
if (format == 3)
|
||||
{
|
||||
/// @todo what's the format look like?
|
||||
assert(false);
|
||||
return;
|
||||
/*
|
||||
// get values
|
||||
CGSize spriteSize = CCSizeFromString(valueForKey("spriteSize", frameDict));
|
||||
CGPoint spriteOffset = CCPointFromString(valueForKey("spriteOffset", frameDict));
|
||||
CGSize spriteSourceSize = CCSizeFromString(valueForKey("spriteSourceSize", frameDict));
|
||||
CGRect textureRect = CCRectFromString(valueForKey("textureRect", frameDict));
|
||||
bool textureRotated = atoi(valueForKey("textureRotated", frameDict)) == 0;
|
||||
|
||||
// get aliases
|
||||
NSArray<NSString*> *aliases = NSArray<NSString*>dictionary->objectForKey(std::string("aliases"));
|
||||
|
||||
while( alias = (NSDictionary<std::string, NSObject*>*)aliases->next(&key) )
|
||||
{
|
||||
std::string value = ((NSString*)alias->objectForKey(key))->m_sString();
|
||||
if (m_pSpriteFramesAliases->objectForKey(value))
|
||||
{
|
||||
CCLOG("cocos2d: WARNING: an alias with name %s already exists", value.c_str());
|
||||
}
|
||||
|
||||
m_pSpriteFramesAliases->setObject(frameDict, value);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOG("cocos2d: Unsupported Zwoptex version. Update cocos2d.");
|
||||
}
|
||||
|
||||
// add sprite frame
|
||||
m_pSpriteFrames->setObject(spriteFrame, key);
|
||||
spriteFrame->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,23 +193,79 @@ void CCSpriteFrameCache::addSpriteFramesWithFile(const char *pszPlist, CCTexture
|
|||
return addSpriteFramesWithDictionary(dict, pobTexture);
|
||||
}
|
||||
|
||||
void CCSpriteFrameCache::addSpriteFramesWithFile(const char* plist, const char* textureFileName)
|
||||
{
|
||||
assert(textureFileName);
|
||||
CCTexture2D *texture = CCTextureCache::sharedTextureCache()->addImage(textureFileName);
|
||||
|
||||
if (texture)
|
||||
{
|
||||
addSpriteFramesWithFile(plist, texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOG("cocos2d: CCSpriteFrameCache: couldn't load texture file. File not found %s", textureFileName);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteFrameCache::addSpriteFramesWithFile(const char *pszPlist)
|
||||
{
|
||||
const char *pszPath = CCFileUtils::fullPathFromRelativePath(pszPlist);
|
||||
NSDictionary<std::string, NSObject*> *dict = CCFileUtils::dictionaryWithContentsOfFile(pszPath);
|
||||
|
||||
string texturePath = string(pszPlist);
|
||||
string texturePath("");
|
||||
|
||||
// remove .xxx
|
||||
size_t startPos = texturePath.find_last_of(".");
|
||||
texturePath = texturePath.erase(startPos);
|
||||
NSDictionary<std::string, NSObject*>* metadataDict = (NSDictionary<std::string, NSObject*>*)dict->objectForKey(string("metadata"));
|
||||
if (metadataDict)
|
||||
{
|
||||
// try to read texture file name from meta data
|
||||
texturePath = string(valueForKey("textureFileName", metadataDict));
|
||||
}
|
||||
|
||||
// append .png
|
||||
texturePath = texturePath.append(".png");
|
||||
if (! texturePath.empty())
|
||||
{
|
||||
// build texture path relative to plist file
|
||||
|
||||
// stringByDeletingLastPathComponent
|
||||
string textureBase(pszPlist);
|
||||
int indexOfLastSeperator = textureBase.find_last_of('/');
|
||||
if (indexOfLastSeperator == textureBase.length() - 1)
|
||||
{
|
||||
textureBase.erase(indexOfLastSeperator, 1);
|
||||
indexOfLastSeperator = textureBase.find_last_of('/');
|
||||
}
|
||||
textureBase.erase(indexOfLastSeperator);
|
||||
|
||||
// stringByAppendingPathComponent
|
||||
if (! textureBase.empty())
|
||||
{
|
||||
texturePath = textureBase + "/" + texturePath;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// build texture path by replacing file extension
|
||||
|
||||
// remove .xxx
|
||||
size_t startPos = texturePath.find_last_of(".");
|
||||
texturePath = texturePath.erase(startPos);
|
||||
|
||||
// append .png
|
||||
texturePath = texturePath.append(".png");
|
||||
|
||||
CCLOG("cocos2d: CCSpriteFrameCache: Trying to use file %s as texture", texturePath);
|
||||
}
|
||||
|
||||
CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(texturePath.c_str());
|
||||
|
||||
return addSpriteFramesWithDictionary(dict, pTexture);
|
||||
if (pTexture)
|
||||
{
|
||||
addSpriteFramesWithDictionary(dict, pTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
CCLOG("cocos2d: CCSpriteFrameCache: Couldn't load texture");
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteFrameCache::addSpriteFrame(CCSpriteFrame *pobFrame, const char *pszFrameName)
|
||||
|
@ -176,6 +276,7 @@ void CCSpriteFrameCache::addSpriteFrame(CCSpriteFrame *pobFrame, const char *psz
|
|||
void CCSpriteFrameCache::removeSpriteFrames(void)
|
||||
{
|
||||
m_pSpriteFrames->removeAllObjects();
|
||||
m_pSpriteFramesAliases->removeAllObjects();
|
||||
}
|
||||
|
||||
void CCSpriteFrameCache::removeUnusedSpriteFrames(void)
|
||||
|
@ -197,15 +298,97 @@ void CCSpriteFrameCache::removeUnusedSpriteFrames(void)
|
|||
|
||||
void CCSpriteFrameCache::removeSpriteFrameByName(const char *pszName)
|
||||
{
|
||||
m_pSpriteFrames->removeObjectForKey(std::string(pszName));
|
||||
// explicit nil handling
|
||||
if( ! pszName )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Is this an alias ?
|
||||
NSString *key = (NSString*)m_pSpriteFramesAliases->objectForKey(string(pszName));
|
||||
|
||||
if (key)
|
||||
{
|
||||
m_pSpriteFrames->removeObjectForKey(key->m_sString);
|
||||
m_pSpriteFramesAliases->removeObjectForKey(key->m_sString);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pSpriteFrames->removeObjectForKey(std::string(pszName));
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteFrameCache::removeSpriteFramesFromFile(const char* plist)
|
||||
{
|
||||
const char* path = CCFileUtils::fullPathFromRelativePath(plist);
|
||||
NSDictionary<std::string, NSObject*>* dict = CCFileUtils::dictionaryWithContentsOfFile(path);
|
||||
|
||||
removeSpriteFramesFromDictionary((NSDictionary<std::string, CCSpriteFrame*>*)dict);
|
||||
}
|
||||
|
||||
void CCSpriteFrameCache::removeSpriteFramesFromDictionary(NSDictionary<std::string, CCSpriteFrame*> *dictionary)
|
||||
{
|
||||
NSDictionary<std::string, NSObject*>* framesDict = (NSDictionary<std::string, NSObject*>*)dictionary->objectForKey(string("frames"));
|
||||
vector<string> keysToRemove;
|
||||
|
||||
framesDict->begin();
|
||||
std::string key = "";
|
||||
NSDictionary<std::string, NSObject*> *frameDict = NULL;
|
||||
while( frameDict = (NSDictionary<std::string, NSObject*>*)framesDict->next(&key) )
|
||||
{
|
||||
if (m_pSpriteFrames->objectForKey(key))
|
||||
{
|
||||
keysToRemove.push_back(key);
|
||||
}
|
||||
}
|
||||
framesDict->end();
|
||||
|
||||
vector<string>::iterator iter;
|
||||
for (iter = keysToRemove.begin(); iter != keysToRemove.end(); iter++)
|
||||
{
|
||||
m_pSpriteFrames->removeObjectForKey(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteFrameCache::removeSpriteFramesFromTexture(CCTexture2D* texture)
|
||||
{
|
||||
vector<string> keysToRemove;
|
||||
|
||||
m_pSpriteFrames->begin();
|
||||
std::string key = "";
|
||||
NSDictionary<std::string, NSObject*> *frameDict = NULL;
|
||||
while( frameDict = (NSDictionary<std::string, NSObject*>*)m_pSpriteFrames->next(&key) )
|
||||
{
|
||||
CCSpriteFrame *frame = m_pSpriteFrames->objectForKey(key);
|
||||
if (frame && (frame->getTexture() == texture))
|
||||
{
|
||||
keysToRemove.push_back(key);
|
||||
}
|
||||
}
|
||||
m_pSpriteFrames->end();
|
||||
|
||||
vector<string>::iterator iter;
|
||||
for (iter = keysToRemove.begin(); iter != keysToRemove.end(); iter++)
|
||||
{
|
||||
m_pSpriteFrames->removeObjectForKey(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
CCSpriteFrame* CCSpriteFrameCache::spriteFrameByName(const char *pszName)
|
||||
{
|
||||
CCSpriteFrame *frame = m_pSpriteFrames->objectForKey(std::string(pszName));
|
||||
if( ! frame )
|
||||
if (! frame)
|
||||
{
|
||||
CCLOG("cocos2d: CCSpriteFrameCache: Frame '%s' not found", pszName);
|
||||
// try alias dictionary
|
||||
NSString *key = (NSString*)m_pSpriteFramesAliases->objectForKey(string(pszName));
|
||||
if (key)
|
||||
{
|
||||
frame = m_pSpriteFrames->objectForKey(key->m_sString);
|
||||
if (! frame)
|
||||
{
|
||||
CCLOG("cocos2d: CCSpriteFrameCahce: Frame '%s' not found", pszName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
|
|
@ -22,632 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "ccConfig.h"
|
||||
#include "CCSprite.h"
|
||||
#include "CCSpriteSheet.h"
|
||||
#include "effects/CCGrid.h"
|
||||
#include "CCDrawingPrimitives.h"
|
||||
#include "CCTextureCache.h"
|
||||
#include "CGPointExtension.h"
|
||||
|
||||
namespace cocos2d {
|
||||
|
||||
const int defaultCapacity = 29;
|
||||
|
||||
// creation with CCTexture2D
|
||||
CCSpriteSheet* CCSpriteSheet::spriteSheetWithTexture(CCTexture2D *pobTexture)
|
||||
{
|
||||
CCSpriteSheet *pSpriteSheet = new CCSpriteSheet();
|
||||
pSpriteSheet->initWithTexture(pobTexture, defaultCapacity);
|
||||
pSpriteSheet->autorelease();
|
||||
|
||||
return pSpriteSheet;
|
||||
}
|
||||
|
||||
CCSpriteSheet* CCSpriteSheet::spriteSheetWithTexture(CCTexture2D *pobTexture, unsigned int uCapacity)
|
||||
{
|
||||
CCSpriteSheet *pSpriteSheet = new CCSpriteSheet();
|
||||
pSpriteSheet->initWithTexture(pobTexture, uCapacity);
|
||||
pSpriteSheet->autorelease();
|
||||
|
||||
return pSpriteSheet;
|
||||
}
|
||||
|
||||
// creation with file image
|
||||
CCSpriteSheet* CCSpriteSheet::spriteSheetWithFile(const char *pszFileImage, unsigned int uCapacity)
|
||||
{
|
||||
CCSpriteSheet *pSpriteSheet = new CCSpriteSheet();
|
||||
pSpriteSheet->initWithFile(pszFileImage, uCapacity);
|
||||
pSpriteSheet->autorelease();
|
||||
|
||||
return pSpriteSheet;
|
||||
}
|
||||
|
||||
CCSpriteSheet* CCSpriteSheet::spriteSheetWithFile(const char *pszFileImage)
|
||||
{
|
||||
CCSpriteSheet *pSpriteSheet = new CCSpriteSheet();
|
||||
pSpriteSheet->initWithFile(pszFileImage, defaultCapacity);
|
||||
pSpriteSheet->autorelease();
|
||||
|
||||
return pSpriteSheet;
|
||||
}
|
||||
|
||||
// init with CCTexture2D
|
||||
bool CCSpriteSheet::initWithTexture(CCTexture2D *pobTexture, unsigned int uCapacity)
|
||||
{
|
||||
m_blendFunc.src = CC_BLEND_SRC;
|
||||
m_blendFunc.dst = CC_BLEND_DST;
|
||||
m_pobTextureAtlas = new CCTextureAtlas();
|
||||
m_pobTextureAtlas->initWithTexture(pobTexture, uCapacity);
|
||||
|
||||
updateBlendFunc();
|
||||
|
||||
// no lazy alloc in this node
|
||||
m_pChildren = new NSMutableArray<CCNode*>();
|
||||
m_pobDescendants = new NSMutableArray<CCSprite*>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// init with FileImage
|
||||
bool CCSpriteSheet::initWithFile(const char *pszFileImage, unsigned int uCapacity)
|
||||
{
|
||||
CCTexture2D *pTexture2D = CCTextureCache::sharedTextureCache()->addImage(pszFileImage);
|
||||
return initWithTexture(pTexture2D, uCapacity);
|
||||
}
|
||||
|
||||
CCSpriteSheet::~CCSpriteSheet(void)
|
||||
{
|
||||
m_pobTextureAtlas->release();
|
||||
m_pobDescendants->release();
|
||||
}
|
||||
|
||||
// composition
|
||||
|
||||
// override visit
|
||||
// don't call visit on it's children
|
||||
void CCSpriteSheet::visit(void)
|
||||
{
|
||||
// CAREFUL:
|
||||
// This visit is almost identical to CocosNode#visit
|
||||
// with the exception that it doesn't call visit on it's children
|
||||
//
|
||||
// The alternative is to have a void CCSprite#visit, but
|
||||
// although this is less mantainable, is faster
|
||||
//
|
||||
if (! m_bIsVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
if (m_pGrid && m_pGrid->isActive())
|
||||
{
|
||||
m_pGrid->beforeDraw();
|
||||
transformAncestors();
|
||||
}
|
||||
|
||||
transform();
|
||||
|
||||
draw();
|
||||
|
||||
if (m_pGrid && m_pGrid->isActive())
|
||||
{
|
||||
m_pGrid->afterDraw(this);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
// xxx deprecated
|
||||
CCSprite* CCSpriteSheet::createSpriteWithRect(CGRect rect)
|
||||
{
|
||||
CCSprite *pSprite = CCSprite::spriteWithTexture(m_pobTextureAtlas->getTexture(), rect);
|
||||
pSprite->useSpriteSheetRender(this);
|
||||
|
||||
return pSprite;
|
||||
}
|
||||
|
||||
// override add child
|
||||
CCNode* CCSpriteSheet::addChild(CCNode *child)
|
||||
{
|
||||
return CCNode::addChild(child);
|
||||
}
|
||||
|
||||
CCNode* CCSpriteSheet::addChild(CCNode *child, int zOrder)
|
||||
{
|
||||
return CCNode::addChild(child, zOrder);
|
||||
}
|
||||
|
||||
CCNode* CCSpriteSheet::addChild(CCNode *child, int zOrder, int tag)
|
||||
{
|
||||
assert(child != NULL);
|
||||
|
||||
CCSprite *pSprite = (CCSprite*)(child);
|
||||
// check CCSprite is using the same texture id
|
||||
assert(pSprite->getTexture()->getName() == m_pobTextureAtlas->getTexture()->getName());
|
||||
|
||||
CCNode *pRet = CCNode::addChild(child, zOrder, tag);
|
||||
|
||||
unsigned int uIndex = atlasIndexForChild(pSprite, zOrder);
|
||||
insertChild(pSprite, uIndex);
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
// override reorderChild
|
||||
void CCSpriteSheet::reorderChild(CCNode *child, int zOrder)
|
||||
{
|
||||
assert(child != NULL);
|
||||
assert(m_pChildren->containsObject(child));
|
||||
|
||||
if (zOrder == child->getZOrder())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// xxx: instead of removing/adding, it is more efficient ot reorder manually
|
||||
child->retain();
|
||||
removeChild(child, false);
|
||||
addChild(child, zOrder);
|
||||
child->release();
|
||||
}
|
||||
|
||||
// override remove child
|
||||
void CCSpriteSheet::removeChild(CCNode *child, bool cleanup)
|
||||
{
|
||||
CCSprite *pSprite = (CCSprite*)(child);
|
||||
|
||||
// explicit null handling
|
||||
if (pSprite == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
assert(m_pChildren->containsObject(pSprite));
|
||||
|
||||
// cleanup before removing
|
||||
removeSpriteFromAtlas(pSprite);
|
||||
|
||||
CCNode::removeChild(pSprite, cleanup);
|
||||
}
|
||||
|
||||
void CCSpriteSheet::removeChildAtIndex(unsigned int uIndex, bool bDoCleanup)
|
||||
{
|
||||
removeChild((CCSprite*)(m_pChildren->getObjectAtIndex(uIndex)), bDoCleanup);
|
||||
}
|
||||
|
||||
void CCSpriteSheet::removeAllChildrenWithCleanup(bool bCleanup)
|
||||
{
|
||||
// Invalidate atlas index. issue #569
|
||||
if (m_pChildren && m_pChildren->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
for (iter = m_pChildren->begin(); iter != m_pChildren->end(); ++iter)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iter);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pSprite->useSelfRender();
|
||||
}
|
||||
}
|
||||
|
||||
CCNode::removeAllChildrenWithCleanup(bCleanup);
|
||||
|
||||
m_pobDescendants->removeAllObjects();
|
||||
m_pobTextureAtlas->removeAllQuads();
|
||||
}
|
||||
|
||||
// draw
|
||||
void CCSpriteSheet::draw(void)
|
||||
{
|
||||
if (m_pobTextureAtlas->getTotalQuads() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pobDescendants && m_pobDescendants->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCSprite*>::NSMutableArrayIterator iter;
|
||||
for (iter = m_pobDescendants->begin(); iter != m_pobDescendants->end(); ++iter)
|
||||
{
|
||||
pSprite = *iter;
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// fast dispatch
|
||||
if (pSprite->isDirty())
|
||||
{
|
||||
pSprite->updateTransform();
|
||||
}
|
||||
|
||||
#if CC_SPRITESHEET_DEBUG_DRAW
|
||||
CGRect rect = pSprite->boundingBox(); // Issue #528
|
||||
CGPoint vertices[4]={
|
||||
ccp(rect.origin.x,rect.origin.y),
|
||||
ccp(rect.origin.x+rect.size.width,rect.origin.y),
|
||||
ccp(rect.origin.x+rect.size.width,rect.origin.y+rect.size.height),
|
||||
ccp(rect.origin.x,rect.origin.y+rect.size.height),
|
||||
};
|
||||
ccDrawPoly(vertices, 4, YES);
|
||||
#endif // CC_SPRITESHEET_DEBUG_DRAW
|
||||
}
|
||||
}
|
||||
|
||||
// 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_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
|
||||
// Unneeded states: -
|
||||
bool newBlend = false;
|
||||
if (m_blendFunc.src != CC_BLEND_SRC || m_blendFunc.dst != CC_BLEND_DST)
|
||||
{
|
||||
newBlend = true;
|
||||
glBlendFunc(m_blendFunc.src, m_blendFunc.dst);
|
||||
}
|
||||
|
||||
m_pobTextureAtlas->drawQuads();
|
||||
if (newBlend)
|
||||
{
|
||||
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteSheet::increaseAtlasCapacity(void)
|
||||
{
|
||||
// if we're going beyond the current TextureAtlas's capacity,
|
||||
// all the previously initialized sprites will need to redo their texture coords
|
||||
// this is likely computationally expensive
|
||||
unsigned int quantity = (m_pobTextureAtlas->getCapacity() + 1) * 4 / 3;
|
||||
|
||||
CCLOG("cocos2d: CCSpriteSheet: resizing TextureAtlas capacity from %d to %d.",
|
||||
m_pobTextureAtlas->getCapacity(), quantity);
|
||||
|
||||
if (! m_pobTextureAtlas->resizeCapacity(quantity))
|
||||
{
|
||||
// serious problems
|
||||
CCLOG("cocos2d: WARNING: Not enough memory to resize the atlas");
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CCSpriteSheet::rebuildIndexInOrder(CCSprite *pobParent, unsigned int uIndex)
|
||||
{
|
||||
NSMutableArray<CCNode*> *pChildren = pobParent->getChildren();
|
||||
|
||||
if (pChildren && pChildren->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iter);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (pSprite->getZOrder() < 0)
|
||||
{
|
||||
uIndex = rebuildIndexInOrder(pSprite, uIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ignore self (spritesheet)
|
||||
if (! pobParent->isEqual(this))
|
||||
{
|
||||
pobParent->setAtlasIndex(uIndex);
|
||||
uIndex++;
|
||||
}
|
||||
|
||||
if (pChildren && pChildren->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iter);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (pSprite->getZOrder() >= 0)
|
||||
{
|
||||
uIndex = rebuildIndexInOrder(pSprite, uIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return uIndex;
|
||||
}
|
||||
|
||||
unsigned int CCSpriteSheet::highestAtlasIndexInChild(CCSprite *pSprite)
|
||||
{
|
||||
NSMutableArray<CCNode*> *pChildren = pSprite->getChildren();
|
||||
|
||||
if (! pChildren || pChildren->count() == 0)
|
||||
{
|
||||
return pSprite->getAtlasIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
return highestAtlasIndexInChild((CCSprite*)(pChildren->getLastObject()));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CCSpriteSheet::lowestAtlasIndexInChild(CCSprite *pSprite)
|
||||
{
|
||||
NSMutableArray<CCNode*> *pChildren = pSprite->getChildren();
|
||||
|
||||
if (! pChildren || pChildren->count() == 0)
|
||||
{
|
||||
return pSprite->getAtlasIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
return lowestAtlasIndexInChild((CCSprite*)(pChildren->getObjectAtIndex(0)));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CCSpriteSheet::atlasIndexForChild(CCSprite *pobSprite, int nZ)
|
||||
{
|
||||
NSMutableArray<CCNode*> *pBrothers = pobSprite->getParent()->getChildren();
|
||||
unsigned int uChildIndex = pBrothers->getIndexOfObject(pobSprite);
|
||||
|
||||
// ignore parent Z if parent is spriteSheet
|
||||
bool bIgnoreParent = (CCSpriteSheet*)(pobSprite->getParent()) == this;
|
||||
CCSprite *pPrevious = NULL;
|
||||
if (uChildIndex > 0)
|
||||
{
|
||||
pPrevious = (CCSprite*)(pBrothers->getObjectAtIndex(uChildIndex - 1));
|
||||
}
|
||||
|
||||
// first child of the sprite sheet
|
||||
if (bIgnoreParent)
|
||||
{
|
||||
if (uChildIndex == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return highestAtlasIndexInChild(pPrevious) + 1;
|
||||
}
|
||||
|
||||
// parent is a CCSprite, so, it must be taken into account
|
||||
|
||||
// first child of an CCSprite ?
|
||||
if (uChildIndex == 0)
|
||||
{
|
||||
CCSprite *p = (CCSprite*)(pobSprite->getParent());
|
||||
|
||||
// less than parent and brothers
|
||||
if (nZ < 0)
|
||||
{
|
||||
return p->getAtlasIndex();
|
||||
}
|
||||
else
|
||||
{
|
||||
return p->getAtlasIndex() + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// previous & sprite belong to the same branch
|
||||
if ((pPrevious->getZOrder() < 0 && nZ < 0) || (pPrevious->getZOrder() >= 0 && nZ >= 0))
|
||||
{
|
||||
return highestAtlasIndexInChild(pPrevious) + 1;
|
||||
}
|
||||
|
||||
// else (previous < 0 and sprite >= 0 )
|
||||
CCSprite *p = (CCSprite*)(pobSprite->getParent());
|
||||
return p->getAtlasIndex() + 1;
|
||||
}
|
||||
|
||||
// Should not happen. Error calculating Z on SpriteSheet
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add child helper
|
||||
|
||||
void CCSpriteSheet::insertChild(CCSprite *pobSprite, unsigned int uIndex)
|
||||
{
|
||||
pobSprite->useSpriteSheetRender(this);
|
||||
pobSprite->setAtlasIndex(uIndex);
|
||||
pobSprite->setDirty(true);
|
||||
|
||||
if (m_pobTextureAtlas->getTotalQuads() == m_pobTextureAtlas->getCapacity())
|
||||
{
|
||||
increaseAtlasCapacity();
|
||||
}
|
||||
|
||||
ccV3F_C4B_T2F_Quad quad = pobSprite->getQuad();
|
||||
m_pobTextureAtlas->insertQuad(&quad, uIndex);
|
||||
|
||||
m_pobDescendants->insertObjectAtIndex(pobSprite, uIndex);
|
||||
|
||||
// update indices
|
||||
unsigned int i = 0;
|
||||
if (m_pobDescendants && m_pobDescendants->count() > 0)
|
||||
{
|
||||
NSMutableArray<CCSprite*>::NSMutableArrayIterator iter;
|
||||
for (iter = m_pobDescendants->begin(); iter != m_pobDescendants->end(); ++iter)
|
||||
{
|
||||
if (! *iter)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (i > uIndex)
|
||||
{
|
||||
(*iter)->setAtlasIndex((*iter)->getAtlasIndex() + 1);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// add children recursively
|
||||
NSMutableArray<CCNode*> *pChildren = pobSprite->getChildren();
|
||||
if (pChildren && pChildren->count() > 0)
|
||||
{
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iterNode;
|
||||
CCSprite *pSprite;
|
||||
for (iterNode = pChildren->begin(); iterNode != pChildren->end(); ++iterNode)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iterNode);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int uIndex = atlasIndexForChild(pSprite, pSprite->getZOrder());
|
||||
insertChild(pSprite, uIndex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CCSpriteSheet::removeSpriteFromAtlas(CCSprite *pobSprite)
|
||||
{
|
||||
// remove from TextureAtlas
|
||||
m_pobTextureAtlas->removeQuadAtIndex(pobSprite->getAtlasIndex());
|
||||
|
||||
// Cleanup sprite. It might be reused (issue #569)
|
||||
pobSprite->useSelfRender();
|
||||
|
||||
unsigned int uIndex = m_pobDescendants->getIndexOfObject(pobSprite);
|
||||
if (uIndex != -1)
|
||||
{
|
||||
m_pobDescendants->removeObjectAtIndex(uIndex);
|
||||
|
||||
// update all sprites beyond this one
|
||||
unsigned int count = m_pobDescendants->count();
|
||||
|
||||
for(; uIndex < count; ++uIndex)
|
||||
{
|
||||
CCSprite* s = (CCSprite*)(m_pobDescendants->getObjectAtIndex(uIndex));
|
||||
s->setAtlasIndex( s->getAtlasIndex() - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// remove children recursively
|
||||
NSMutableArray<CCNode*> *pChildren = pobSprite->getChildren();
|
||||
|
||||
if (pChildren && pChildren->count() > 0)
|
||||
{
|
||||
CCSprite *pSprite;
|
||||
NSMutableArray<CCNode*>::NSMutableArrayIterator iter;
|
||||
for (iter = pChildren->begin(); iter != pChildren->end(); ++iter)
|
||||
{
|
||||
pSprite = (CCSprite*)(*iter);
|
||||
|
||||
if (! pSprite)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
removeSpriteFromAtlas(pSprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCSpriteSheet::updateBlendFunc(void)
|
||||
{
|
||||
if (! m_pobTextureAtlas->getTexture()->getHasPremultipliedAlpha())
|
||||
{
|
||||
m_blendFunc.src = GL_SRC_ALPHA;
|
||||
m_blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
// CocosNodeTexture protocol
|
||||
void CCSpriteSheet::setBlendFunc(ccBlendFunc blendFunc)
|
||||
{
|
||||
m_blendFunc = blendFunc;
|
||||
}
|
||||
|
||||
ccBlendFunc CCSpriteSheet::getBlendFunc(void)
|
||||
{
|
||||
return m_blendFunc;
|
||||
}
|
||||
|
||||
CCTexture2D* CCSpriteSheet::getTexture(void)
|
||||
{
|
||||
return m_pobTextureAtlas->getTexture();
|
||||
}
|
||||
|
||||
void CCSpriteSheet::setTexture(CCTexture2D *texture)
|
||||
{
|
||||
m_pobTextureAtlas->setTexture(texture);
|
||||
}
|
||||
|
||||
// CCSpriteSheet Extension
|
||||
//implementation CCSpriteSheet (TMXTiledMapExtension)
|
||||
|
||||
void CCSpriteSheet::addQuadFromSprite(CCSprite *sprite, unsigned int index)
|
||||
{
|
||||
NSAssert( sprite != NULL, "Argument must be non-nil");
|
||||
/// @todo NSAssert( [sprite isKindOfClass:[CCSprite class]], @"CCSpriteSheet only supports CCSprites as children");
|
||||
|
||||
while(index >= m_pobTextureAtlas->getCapacity() || m_pobTextureAtlas->getCapacity() == m_pobTextureAtlas->getTotalQuads())
|
||||
{
|
||||
this->increaseAtlasCapacity();
|
||||
}
|
||||
//
|
||||
// update the quad directly. Don't add the sprite to the scene graph
|
||||
//
|
||||
sprite->useSpriteSheetRender(this);
|
||||
sprite->setAtlasIndex(index);
|
||||
|
||||
ccV3F_C4B_T2F_Quad quad = sprite->getQuad();
|
||||
m_pobTextureAtlas->insertQuad(&quad, index);
|
||||
|
||||
// XXX: updateTransform will update the textureAtlas too using updateQuad.
|
||||
// XXX: so, it should be AFTER the insertQuad
|
||||
sprite->updateTransform();
|
||||
}
|
||||
|
||||
CCSpriteSheet * CCSpriteSheet::addSpriteWithoutQuad(CCSprite*child, unsigned int z, int aTag)
|
||||
{
|
||||
NSAssert( child != NULL, "Argument must be non-nil");
|
||||
/// @todo NSAssert( [child isKindOfClass:[CCSprite class]], @"CCSpriteSheet only supports CCSprites as children");
|
||||
|
||||
// quad index is Z
|
||||
child->setAtlasIndex(z);
|
||||
|
||||
// XXX: optimize with a binary search
|
||||
int i=0;
|
||||
if (m_pobDescendants && m_pobDescendants->count() > 0)
|
||||
{
|
||||
NSMutableArray<CCSprite*>::NSMutableArrayIterator iter;
|
||||
for (iter = m_pobDescendants->begin(); iter != m_pobDescendants->end(); ++iter)
|
||||
{
|
||||
// fast dispatch
|
||||
if (!(*iter) || (*iter)->getAtlasIndex() >=z)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
m_pobDescendants->insertObjectAtIndex(child, i);
|
||||
|
||||
// IMPORTANT: Call super, and not self. Avoid adding it to the texture atlas array
|
||||
CCNode::addChild(child, z, aTag);
|
||||
return this;
|
||||
}
|
||||
}//namespace cocos2d
|
||||
|
|
Loading…
Reference in New Issue