Merge branch 'develop' of https://github.com/cocos2d/cocos2d-x into developDynamic

This commit is contained in:
samuele3hu 2014-02-24 09:38:08 +08:00
commit a765178a5f
42 changed files with 1428 additions and 1967 deletions

View File

@ -610,9 +610,10 @@ Developers:
Makes Colors are now comparable and explicit convertible
bmanGH
Use gl caching functions in TexturePVR::createGLTexture()
Used gl caching functions in TexturePVR::createGLTexture()
Configuration of VAO in runtime
Add setUniformLocationWithMatrix2fv, setUniformLocationWithMatrix3fv mothed into GLProgram class
Added setUniformLocationWithMatrix2fv, setUniformLocationWithMatrix3fv mothed into GLProgram class
Fixed a bug that object which isn't in Vector would also be released when invoking Vector::eraseObject.
metadao
make create_project.py more pythonic and fix some typoes

View File

@ -1,12 +1,24 @@
cocos2d-x-3.0rc0 Feb.?? 2014
[All]
[NEW] Adds more console commands: director resume|pause|stopanimation|startanimation.
[NEW] Adds Dutch Language support.
[NEW] Action: RotateBy supports 3D rotations
[NEW] Bindings: Using python to automatically generate script bindings
[NEW] Bindings: Added JS bindings support for Linux
[NEW] Console: Added 'resolution', 'projection' commands. Improved API
[NEW] Console: Added more commands: director resume|pause|stopanimation|startanimation.
[NEW] Director: Displays 'Vertices drawn' in the stats. Useful to measure performance.
[NEW] Using python to automatically generate script bindings codes.
[NEW] Linux javascript bindings support.
[NEW] Node: Added set/get Position3D() and set/get Rotation3D()
Node: Calculates rotation X and Y correctly.
Node: set/get VertexZ() -> set/get PositionZ()
Node: setRotationX() -> setRotationSkewX()
Node: setRotationY() -> setRotationSkewY()
[NEW] Language: Added Dutch support.
[NEW] Sprite: Added auto-culling support
[FIX] Character would not be aligned on the baseline when label using distance field.
[FIX] Adds a macro to disable inserting script binding relevant codes.
[FIX] Removing child from TMXLayer may cause crash.
[FIX] Voice recognition input would cause crash on ios7.
[FIX] Object which isn't in Vector would also be released when invoking Vector::eraseObject.
[FIX] Potential crash when websocket connection closes.
[FIX] No callback is invoked when websocket connection fails.
[FIX] s3tc compressed textures with no mipmaps fail to be loaded.

View File

@ -1 +1 @@
950b17f47eba6685e87c69b3eede566ec28e9b23
96ebe58c64783ed2e976ff504db835a397475f00

View File

@ -747,7 +747,7 @@ void RotateTo::startWithTarget(Node *target)
ActionInterval::startWithTarget(target);
// Calculate X
_startAngleX = target->getRotationX();
_startAngleX = target->getRotationSkewX();
if (_startAngleX > 0)
{
_startAngleX = fmodf(_startAngleX, 360.0f);
@ -768,7 +768,7 @@ void RotateTo::startWithTarget(Node *target)
}
//Calculate Y: It's duplicated from calculating X since the rotation wrap should be the same
_startAngleY = _target->getRotationY();
_startAngleY = _target->getRotationSkewY();
if (_startAngleY > 0)
{
@ -795,8 +795,8 @@ void RotateTo::update(float time)
{
if (_target)
{
_target->setRotationX(_startAngleX + _diffAngleX * time);
_target->setRotationY(_startAngleY + _diffAngleY * time);
_target->setRotationSkewX(_startAngleX + _diffAngleX * time);
_target->setRotationSkewY(_startAngleY + _diffAngleY * time);
}
}
@ -819,17 +819,6 @@ RotateBy* RotateBy::create(float duration, float deltaAngle)
return rotateBy;
}
bool RotateBy::initWithDuration(float duration, float deltaAngle)
{
if (ActionInterval::initWithDuration(duration))
{
_angleX = _angleY = deltaAngle;
return true;
}
return false;
}
RotateBy* RotateBy::create(float duration, float deltaAngleX, float deltaAngleY)
{
RotateBy *rotateBy = new RotateBy();
@ -839,23 +828,64 @@ RotateBy* RotateBy::create(float duration, float deltaAngleX, float deltaAngleY)
return rotateBy;
}
RotateBy* RotateBy::create(float duration, const Vertex3F& deltaAngle3D)
{
RotateBy *rotateBy = new RotateBy();
rotateBy->initWithDuration(duration, deltaAngle3D);
rotateBy->autorelease();
return rotateBy;
}
RotateBy::RotateBy()
: _is3D(false)
{
}
bool RotateBy::initWithDuration(float duration, float deltaAngle)
{
if (ActionInterval::initWithDuration(duration))
{
_angleZ_X = _angleZ_Y = deltaAngle;
return true;
}
return false;
}
bool RotateBy::initWithDuration(float duration, float deltaAngleX, float deltaAngleY)
{
if (ActionInterval::initWithDuration(duration))
{
_angleX = deltaAngleX;
_angleY = deltaAngleY;
_angleZ_X = deltaAngleX;
_angleZ_Y = deltaAngleY;
return true;
}
return false;
}
bool RotateBy::initWithDuration(float duration, const Vertex3F& deltaAngle3D)
{
if (ActionInterval::initWithDuration(duration))
{
_angle3D = deltaAngle3D;
_is3D = true;
return true;
}
return false;
}
RotateBy* RotateBy::clone(void) const
{
// no copy constructor
auto a = new RotateBy();
a->initWithDuration(_duration, _angleX, _angleY);
if(_is3D)
a->initWithDuration(_duration, _angle3D);
else
a->initWithDuration(_duration, _angleZ_X, _angleZ_Y);
a->autorelease();
return a;
}
@ -863,8 +893,15 @@ RotateBy* RotateBy::clone(void) const
void RotateBy::startWithTarget(Node *target)
{
ActionInterval::startWithTarget(target);
_startAngleX = target->getRotationX();
_startAngleY = target->getRotationY();
if(_is3D)
{
_startAngle3D = target->getRotation3D();
}
else
{
_startAngleZ_X = target->getRotationSkewX();
_startAngleZ_Y = target->getRotationSkewY();
}
}
void RotateBy::update(float time)
@ -872,14 +909,33 @@ void RotateBy::update(float time)
// XXX: shall I add % 360
if (_target)
{
_target->setRotationX(_startAngleX + _angleX * time);
_target->setRotationY(_startAngleY + _angleY * time);
if(_is3D)
{
Vertex3F v;
v.x = _startAngle3D.x + _angle3D.x * time;
v.y = _startAngle3D.y + _angle3D.y * time;
v.z = _startAngle3D.z + _angle3D.z * time;
_target->setRotation3D(v);
}
else
{
_target->setRotationSkewX(_startAngleZ_X + _angleZ_X * time);
_target->setRotationSkewY(_startAngleZ_Y + _angleZ_Y * time);
}
}
}
RotateBy* RotateBy::reverse() const
{
return RotateBy::create(_duration, -_angleX, -_angleY);
if(_is3D)
{
Vertex3F v;
v.x = - _angle3D.x;
v.y = - _angle3D.y;
v.z = - _angle3D.z;
return RotateBy::create(_duration, v);
}
return RotateBy::create(_duration, -_angleZ_X, -_angleZ_Y);
}
//

View File

@ -322,7 +322,8 @@ class CC_DLL RotateBy : public ActionInterval
public:
/** creates the action */
static RotateBy* create(float duration, float deltaAngle);
static RotateBy* create(float duration, float deltaAngleX, float deltaAngleY);
static RotateBy* create(float duration, float deltaAngleZ_X, float deltaAngleZ_Y);
static RotateBy* create(float duration, const Vertex3F& deltaAngle3D);
//
// Override
@ -333,16 +334,21 @@ public:
virtual void update(float time) override;
protected:
RotateBy() {}
RotateBy();
virtual ~RotateBy() {}
/** initializes the action */
bool initWithDuration(float duration, float deltaAngle);
bool initWithDuration(float duration, float deltaAngleX, float deltaAngleY);
bool initWithDuration(float duration, float deltaAngleZ_X, float deltaAngleZ_Y);
bool initWithDuration(float duration, const Vertex3F& deltaAngle3D);
float _angleX;
float _startAngleX;
float _angleY;
float _startAngleY;
float _angleZ_X;
float _startAngleZ_X;
float _angleZ_Y;
float _startAngleZ_Y;
bool _is3D;
Vertex3F _angle3D;
Vertex3F _startAngle3D;
private:
CC_DISALLOW_COPY_AND_ASSIGN(RotateBy);

View File

@ -44,7 +44,7 @@ THE SOFTWARE.
#include "CCAutoreleasePool.h"
#include "platform/CCFileUtils.h"
#include "CCApplication.h"
#include "CCLabelBMFont.h"
#include "CCFontFNT.h"
#include "CCActionManager.h"
#include "CCAnimationCache.h"
#include "CCTouch.h"
@ -134,8 +134,6 @@ bool Director::init(void)
_openGLView = nullptr;
_cullingFrustum = new Frustum();
_contentScaleFactor = 1.0f;
// scheduler
@ -277,16 +275,6 @@ void Director::drawScene()
kmGLPushMatrix();
//construct the frustum
{
kmMat4 view;
kmMat4 projection;
kmGLGetMatrix(KM_GL_PROJECTION, &projection);
kmGLGetMatrix(KM_GL_MODELVIEW, &view);
_cullingFrustum->setupFromMatrix(view, projection);
}
// draw the scene
if (_runningScene)
{
@ -459,19 +447,20 @@ void Director::setProjection(Projection projection)
kmGLLoadIdentity();
// issue #1334
kmMat4PerspectiveProjection(&matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, zeye*2);
// kmMat4PerspectiveProjection( &matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, 1500);
kmMat4PerspectiveProjection(&matrixPerspective, 60, (GLfloat)size.width/size.height, 10, zeye+size.height/2);
// kmMat4PerspectiveProjection( &matrixPerspective, 60, (GLfloat)size.width/size.height, 0.1f, 1500);
kmGLMultMatrix(&matrixPerspective);
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLLoadIdentity();
kmVec3 eye, center, up;
kmVec3Fill(&eye, size.width/2, size.height/2, zeye);
kmVec3Fill(&center, size.width/2, size.height/2, 0.0f);
kmVec3Fill(&up, 0.0f, 1.0f, 0.0f);
kmMat4LookAt(&matrixLookup, &eye, &center, &up);
kmGLMultMatrix(&matrixLookup);
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLLoadIdentity();
break;
}
@ -493,7 +482,7 @@ void Director::setProjection(Projection projection)
void Director::purgeCachedData(void)
{
LabelBMFont::purgeCachedData();
FontFNT::purgeCachedData();
if (s_SharedDirector->getOpenGLView())
{
SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();
@ -743,10 +732,9 @@ void Director::purgeDirector()
CC_SAFE_RELEASE_NULL(_FPSLabel);
CC_SAFE_RELEASE_NULL(_drawnBatchesLabel);
CC_SAFE_RELEASE_NULL(_drawnVerticesLabel);
CC_SAFE_DELETE(_cullingFrustum);
// purge bitmap cache
LabelBMFont::purgeCachedData();
FontFNT::purgeCachedData();
FontFreeType::shutdownFreeType();

View File

@ -58,7 +58,6 @@ class EventDispatcher;
class EventCustom;
class EventListenerCustom;
class TextureCache;
class Frustum;
class Renderer;
class Console;
@ -330,12 +329,6 @@ public:
*/
void setContentScaleFactor(float scaleFactor);
float getContentScaleFactor() const { return _contentScaleFactor; }
/**
Get the Culling Frustum
*/
Frustum* getFrustum() const { return _cullingFrustum; }
/** Gets the Scheduler associated with this director
@since v2.0
@ -450,8 +443,6 @@ protected:
unsigned int _frames;
float _secondsPerFrame;
Frustum *_cullingFrustum;
/* The running scene */
Scene *_runningScene;

View File

@ -63,14 +63,14 @@ FontAtlas * FontAtlasCache::getFontAtlasTTF(const std::string& fontFileName, int
return tempAtlas;
}
FontAtlas * FontAtlasCache::getFontAtlasFNT(const std::string& fontFileName)
FontAtlas * FontAtlasCache::getFontAtlasFNT(const std::string& fontFileName, const Point& imageOffset /* = Point::ZERO */)
{
std::string atlasName = generateFontName(fontFileName, 0, GlyphCollection::CUSTOM,false);
FontAtlas *tempAtlas = _atlasMap[atlasName];
if ( !tempAtlas )
{
Font *font = FontFNT::create(fontFileName);
Font *font = FontFNT::create(fontFileName,imageOffset);
if(font)
{

View File

@ -38,7 +38,7 @@ class CC_DLL FontAtlasCache
{
public:
static FontAtlas * getFontAtlasTTF(const std::string& fontFileName, int size, GlyphCollection glyphs, const char *customGlyphs = 0, bool useDistanceField = false);
static FontAtlas * getFontAtlasFNT(const std::string& fontFileName);
static FontAtlas * getFontAtlasFNT(const std::string& fontFileName, const Point& imageOffset = Point::ZERO);
static FontAtlas * getFontAtlasCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
static FontAtlas * getFontAtlasCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);

View File

@ -24,17 +24,650 @@
****************************************************************************/
#include "CCFontFNT.h"
#include "CCFontAtlas.h"
#include "CCLabelBMFont.h"
#include "uthash.h"
#include "CCConfiguration.h"
#include "CCDirector.h"
#include "CCFontAtlas.h"
#include "CCMap.h"
#include "CCString.h"
#include "CCTextureCache.h"
#include "ccUTF8.h"
#include "platform/CCFileUtils.h"
using namespace std;
NS_CC_BEGIN
FontFNT * FontFNT::create(const std::string& fntFilePath)
/**
* @addtogroup GUI
* @{
* @addtogroup label
* @{
*/
enum {
kLabelAutomaticWidth = -1,
};
struct _FontDefHashElement;
/**
@struct BMFontDef
BMFont definition
*/
typedef struct _BMFontDef {
//! ID of the character
unsigned int charID;
//! origin and size of the font
Rect rect;
//! The X amount the image should be offset when drawing the image (in pixels)
short xOffset;
//! The Y amount the image should be offset when drawing the image (in pixels)
short yOffset;
//! The amount to move the current position after drawing the character (in pixels)
short xAdvance;
} BMFontDef;
/** @struct BMFontPadding
BMFont padding
@since v0.8.2
*/
typedef struct _BMFontPadding {
/// padding left
int left;
/// padding top
int top;
/// padding right
int right;
/// padding bottom
int bottom;
} BMFontPadding;
typedef struct _FontDefHashElement
{
CCBMFontConfiguration *newConf = FNTConfigLoadFile(fntFilePath);
unsigned int key; // key. Font Unicode value
BMFontDef fontDef; // font definition
UT_hash_handle hh;
} tFontDefHashElement;
// Equal function for targetSet.
typedef struct _KerningHashElement
{
int key; // key for the hash. 16-bit for 1st element, 16-bit for 2nd element
int amount;
UT_hash_handle hh;
} tKerningHashElement;
/** @brief BMFontConfiguration has parsed configuration of the the .fnt file
@since v0.8
*/
class CC_DLL BMFontConfiguration : public Ref
{
// XXX: Creating a public interface so that the bitmapFontArray[] is accessible
public://@public
// BMFont definitions
tFontDefHashElement *_fontDefDictionary;
//! FNTConfig: Common Height Should be signed (issue #1343)
int _commonHeight;
//! Padding
BMFontPadding _padding;
//! atlas name
std::string _atlasName;
//! values for kerning
tKerningHashElement *_kerningDictionary;
// Character Set defines the letters that actually exist in the font
std::set<unsigned int> *_characterSet;
public:
/**
* @js ctor
*/
BMFontConfiguration();
/**
* @js NA
* @lua NA
*/
virtual ~BMFontConfiguration();
/**
* @js NA
* @lua NA
*/
std::string description() const;
/** allocates a BMFontConfiguration with a FNT file */
static BMFontConfiguration * create(const std::string& FNTfile);
/** initializes a BitmapFontConfiguration with a FNT file */
bool initWithFNTfile(const std::string& FNTfile);
inline const std::string& getAtlasName(){ return _atlasName; }
inline void setAtlasName(const std::string& atlasName) { _atlasName = atlasName; }
std::set<unsigned int>* getCharacterSet() const;
private:
std::set<unsigned int>* parseConfigFile(const std::string& controlFile);
std::set<unsigned int>* parseBinaryConfigFile(unsigned char* pData, unsigned long size, const std::string& controlFile);
void parseCharacterDefinition(std::string line, BMFontDef *characterDefinition);
void parseInfoArguments(std::string line);
void parseCommonArguments(std::string line);
void parseImageFileName(std::string line, const std::string& fntFile);
void parseKerningEntry(std::string line);
void purgeKerningDictionary();
void purgeFontDefDictionary();
};
//
//FNTConfig Cache - free functions
//
static Map<std::string, BMFontConfiguration*>* s_configurations = nullptr;
BMFontConfiguration* FNTConfigLoadFile(const std::string& fntFile)
{
BMFontConfiguration* ret = nullptr;
if( s_configurations == nullptr )
{
s_configurations = new Map<std::string, BMFontConfiguration*>();
}
ret = s_configurations->at(fntFile);
if( ret == nullptr )
{
ret = BMFontConfiguration::create(fntFile.c_str());
if (ret)
{
s_configurations->insert(fntFile, ret);
}
}
return ret;
}
//
//BitmapFontConfiguration
//
BMFontConfiguration * BMFontConfiguration::create(const std::string& FNTfile)
{
BMFontConfiguration * ret = new BMFontConfiguration();
if (ret->initWithFNTfile(FNTfile))
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
bool BMFontConfiguration::initWithFNTfile(const std::string& FNTfile)
{
_kerningDictionary = nullptr;
_fontDefDictionary = nullptr;
_characterSet = this->parseConfigFile(FNTfile);
if (! _characterSet)
{
return false;
}
return true;
}
std::set<unsigned int>* BMFontConfiguration::getCharacterSet() const
{
return _characterSet;
}
BMFontConfiguration::BMFontConfiguration()
: _fontDefDictionary(nullptr)
, _commonHeight(0)
, _kerningDictionary(nullptr)
, _characterSet(nullptr)
{
}
BMFontConfiguration::~BMFontConfiguration()
{
CCLOGINFO( "deallocing BMFontConfiguration: %p", this );
this->purgeFontDefDictionary();
this->purgeKerningDictionary();
_atlasName.clear();
CC_SAFE_DELETE(_characterSet);
}
std::string BMFontConfiguration::description(void) const
{
return StringUtils::format(
"<BMFontConfiguration = " CC_FORMAT_PRINTF_SIZE_T " | Glphys:%d Kernings:%d | Image = %s>",
(size_t)this,
HASH_COUNT(_fontDefDictionary),
HASH_COUNT(_kerningDictionary),
_atlasName.c_str()
);
}
void BMFontConfiguration::purgeKerningDictionary()
{
tKerningHashElement *current;
while(_kerningDictionary)
{
current = _kerningDictionary;
HASH_DEL(_kerningDictionary,current);
free(current);
}
}
void BMFontConfiguration::purgeFontDefDictionary()
{
tFontDefHashElement *current, *tmp;
HASH_ITER(hh, _fontDefDictionary, current, tmp) {
HASH_DEL(_fontDefDictionary, current);
free(current);
}
}
std::set<unsigned int>* BMFontConfiguration::parseConfigFile(const std::string& controlFile)
{
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(controlFile);
Data data = FileUtils::getInstance()->getDataFromFile(fullpath);
CCASSERT((!data.isNull() && data.getSize() > 0), "BMFontConfiguration::parseConfigFile | Open file error.");
if (memcmp("BMF", data.getBytes(), 3) == 0) {
std::set<unsigned int>* ret = parseBinaryConfigFile(data.getBytes(), data.getSize(), controlFile);
return ret;
}
std::string contents((const char*)data.getBytes(), data.getSize());
std::set<unsigned int> *validCharsString = new std::set<unsigned int>();
if (contents.empty())
{
CCLOG("cocos2d: Error parsing FNTfile %s", controlFile.c_str());
return nullptr;
}
// parse spacing / padding
std::string line;
std::string strLeft(contents);
while (strLeft.length() > 0)
{
size_t pos = strLeft.find('\n');
if (pos != std::string::npos)
{
// the data is more than a line.get one line
line = strLeft.substr(0, pos);
strLeft = strLeft.substr(pos + 1);
}
else
{
// get the left data
line = strLeft;
strLeft.erase();
}
if(line.substr(0,strlen("info face")) == "info face")
{
// XXX: info parsing is incomplete
// Not needed for the Hiero editors, but needed for the AngelCode editor
// [self parseInfoArguments:line];
this->parseInfoArguments(line);
}
// Check to see if the start of the line is something we are interested in
else if(line.substr(0,strlen("common lineHeight")) == "common lineHeight")
{
this->parseCommonArguments(line);
}
else if(line.substr(0,strlen("page id")) == "page id")
{
this->parseImageFileName(line, controlFile);
}
else if(line.substr(0,strlen("chars c")) == "chars c")
{
// Ignore this line
}
else if(line.substr(0,strlen("char")) == "char")
{
// Parse the current line and create a new CharDef
tFontDefHashElement* element = (tFontDefHashElement*)malloc( sizeof(*element) );
this->parseCharacterDefinition(line, &element->fontDef);
element->key = element->fontDef.charID;
HASH_ADD_INT(_fontDefDictionary, key, element);
validCharsString->insert(element->fontDef.charID);
}
// else if(line.substr(0,strlen("kernings count")) == "kernings count")
// {
// this->parseKerningCapacity(line);
// }
else if(line.substr(0,strlen("kerning first")) == "kerning first")
{
this->parseKerningEntry(line);
}
}
return validCharsString;
}
std::set<unsigned int>* BMFontConfiguration::parseBinaryConfigFile(unsigned char* pData, unsigned long size, const std::string& controlFile)
{
/* based on http://www.angelcode.com/products/bmfont/doc/file_format.html file format */
set<unsigned int> *validCharsString = new set<unsigned int>();
unsigned long remains = size;
CCASSERT(pData[3] == 3, "Only version 3 is supported");
pData += 4; remains -= 4;
while (remains > 0)
{
unsigned char blockId = pData[0]; pData += 1; remains -= 1;
uint32_t blockSize = 0; memcpy(&blockSize, pData, 4);
pData += 4; remains -= 4;
if (blockId == 1)
{
/*
fontSize 2 int 0
bitField 1 bits 2 bit 0: smooth, bit 1: unicode, bit 2: italic, bit 3: bold, bit 4: fixedHeigth, bits 5-7: reserved
charSet 1 uint 3
stretchH 2 uint 4
aa 1 uint 6
paddingUp 1 uint 7
paddingRight 1 uint 8
paddingDown 1 uint 9
paddingLeft 1 uint 10
spacingHoriz 1 uint 11
spacingVert 1 uint 12
outline 1 uint 13 added with version 2
fontName n+1 string 14 null terminated string with length n
*/
_padding.top = (unsigned char)pData[7];
_padding.right = (unsigned char)pData[8];
_padding.bottom = (unsigned char)pData[9];
_padding.left = (unsigned char)pData[10];
}
else if (blockId == 2)
{
/*
lineHeight 2 uint 0
base 2 uint 2
scaleW 2 uint 4
scaleH 2 uint 6
pages 2 uint 8
bitField 1 bits 10 bits 0-6: reserved, bit 7: packed
alphaChnl 1 uint 11
redChnl 1 uint 12
greenChnl 1 uint 13
blueChnl 1 uint 14
*/
uint16_t lineHeight = 0; memcpy(&lineHeight, pData, 2);
_commonHeight = lineHeight;
uint16_t scaleW = 0; memcpy(&scaleW, pData + 4, 2);
uint16_t scaleH = 0; memcpy(&scaleH, pData + 6, 2);
CCASSERT(scaleW <= Configuration::getInstance()->getMaxTextureSize() && scaleH <= Configuration::getInstance()->getMaxTextureSize(), "CCLabelBMFont: page can't be larger than supported");
uint16_t pages = 0; memcpy(&pages, pData + 8, 2);
CCASSERT(pages == 1, "CCBitfontAtlas: only supports 1 page");
}
else if (blockId == 3)
{
/*
pageNames p*(n+1) strings 0 p null terminated strings, each with length n
*/
const char *value = (const char *)pData;
CCASSERT(strlen(value) < blockSize, "Block size should be less then string");
_atlasName = FileUtils::getInstance()->fullPathFromRelativeFile(value, controlFile);
}
else if (blockId == 4)
{
/*
id 4 uint 0+c*20 These fields are repeated until all characters have been described
x 2 uint 4+c*20
y 2 uint 6+c*20
width 2 uint 8+c*20
height 2 uint 10+c*20
xoffset 2 int 12+c*20
yoffset 2 int 14+c*20
xadvance 2 int 16+c*20
page 1 uint 18+c*20
chnl 1 uint 19+c*20
*/
unsigned long count = blockSize / 20;
for (unsigned long i = 0; i < count; i++)
{
tFontDefHashElement* element = (tFontDefHashElement*)malloc( sizeof(*element) );
uint32_t charId = 0; memcpy(&charId, pData + (i * 20), 4);
element->fontDef.charID = charId;
uint16_t charX = 0; memcpy(&charX, pData + (i * 20) + 4, 2);
element->fontDef.rect.origin.x = charX;
uint16_t charY = 0; memcpy(&charY, pData + (i * 20) + 6, 2);
element->fontDef.rect.origin.y = charY;
uint16_t charWidth = 0; memcpy(&charWidth, pData + (i * 20) + 8, 2);
element->fontDef.rect.size.width = charWidth;
uint16_t charHeight = 0; memcpy(&charHeight, pData + (i * 20) + 10, 2);
element->fontDef.rect.size.height = charHeight;
int16_t xoffset = 0; memcpy(&xoffset, pData + (i * 20) + 12, 2);
element->fontDef.xOffset = xoffset;
int16_t yoffset = 0; memcpy(&yoffset, pData + (i * 20) + 14, 2);
element->fontDef.yOffset = yoffset;
int16_t xadvance = 0; memcpy(&xadvance, pData + (i * 20) + 16, 2);
element->fontDef.xAdvance = xadvance;
element->key = element->fontDef.charID;
HASH_ADD_INT(_fontDefDictionary, key, element);
validCharsString->insert(element->fontDef.charID);
}
}
else if (blockId == 5) {
/*
first 4 uint 0+c*10 These fields are repeated until all kerning pairs have been described
second 4 uint 4+c*10
amount 2 int 8+c*10
*/
unsigned long count = blockSize / 20;
for (unsigned long i = 0; i < count; i++)
{
uint32_t first = 0; memcpy(&first, pData + (i * 10), 4);
uint32_t second = 0; memcpy(&second, pData + (i * 10) + 4, 4);
int16_t amount = 0; memcpy(&amount, pData + (i * 10) + 8, 2);
tKerningHashElement *element = (tKerningHashElement *)calloc( sizeof( *element ), 1 );
element->amount = amount;
element->key = (first<<16) | (second&0xffff);
HASH_ADD_INT(_kerningDictionary,key, element);
}
}
pData += blockSize; remains -= blockSize;
}
return validCharsString;
}
void BMFontConfiguration::parseImageFileName(std::string line, const std::string& fntFile)
{
//////////////////////////////////////////////////////////////////////////
// line to parse:
// page id=0 file="bitmapFontTest.png"
//////////////////////////////////////////////////////////////////////////
// page ID. Sanity check
auto index = line.find('=')+1;
auto index2 = line.find(' ', index);
std::string value = line.substr(index, index2-index);
CCASSERT(atoi(value.c_str()) == 0, "LabelBMFont file could not be found");
// file
index = line.find('"')+1;
index2 = line.find('"', index);
value = line.substr(index, index2-index);
_atlasName = FileUtils::getInstance()->fullPathFromRelativeFile(value.c_str(), fntFile);
}
void BMFontConfiguration::parseInfoArguments(std::string line)
{
//////////////////////////////////////////////////////////////////////////
// possible lines to parse:
// info face="Script" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=1,4,3,2 spacing=0,0 outline=0
// info face="Cracked" size=36 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1
//////////////////////////////////////////////////////////////////////////
// padding
auto index = line.find("padding=");
auto index2 = line.find(' ', index);
std::string value = line.substr(index, index2-index);
sscanf(value.c_str(), "padding=%d,%d,%d,%d", &_padding.top, &_padding.right, &_padding.bottom, &_padding.left);
CCLOG("cocos2d: padding: %d,%d,%d,%d", _padding.left, _padding.top, _padding.right, _padding.bottom);
}
void BMFontConfiguration::parseCommonArguments(std::string line)
{
//////////////////////////////////////////////////////////////////////////
// line to parse:
// common lineHeight=104 base=26 scaleW=1024 scaleH=512 pages=1 packed=0
//////////////////////////////////////////////////////////////////////////
// Height
auto index = line.find("lineHeight=");
auto index2 = line.find(' ', index);
std::string value = line.substr(index, index2-index);
sscanf(value.c_str(), "lineHeight=%d", &_commonHeight);
// scaleW. sanity check
index = line.find("scaleW=") + strlen("scaleW=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
CCASSERT(atoi(value.c_str()) <= Configuration::getInstance()->getMaxTextureSize(), "CCLabelBMFont: page can't be larger than supported");
// scaleH. sanity check
index = line.find("scaleH=") + strlen("scaleH=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
CCASSERT(atoi(value.c_str()) <= Configuration::getInstance()->getMaxTextureSize(), "CCLabelBMFont: page can't be larger than supported");
// pages. sanity check
index = line.find("pages=") + strlen("pages=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
CCASSERT(atoi(value.c_str()) == 1, "CCBitfontAtlas: only supports 1 page");
// packed (ignore) What does this mean ??
}
void BMFontConfiguration::parseCharacterDefinition(std::string line, BMFontDef *characterDefinition)
{
//////////////////////////////////////////////////////////////////////////
// line to parse:
// char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=44 xadvance=14 page=0 chnl=0
//////////////////////////////////////////////////////////////////////////
// Character ID
auto index = line.find("id=");
auto index2 = line.find(' ', index);
std::string value = line.substr(index, index2-index);
sscanf(value.c_str(), "id=%u", &characterDefinition->charID);
// Character x
index = line.find("x=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "x=%f", &characterDefinition->rect.origin.x);
// Character y
index = line.find("y=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "y=%f", &characterDefinition->rect.origin.y);
// Character width
index = line.find("width=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "width=%f", &characterDefinition->rect.size.width);
// Character height
index = line.find("height=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "height=%f", &characterDefinition->rect.size.height);
// Character xoffset
index = line.find("xoffset=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "xoffset=%hd", &characterDefinition->xOffset);
// Character yoffset
index = line.find("yoffset=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "yoffset=%hd", &characterDefinition->yOffset);
// Character xadvance
index = line.find("xadvance=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "xadvance=%hd", &characterDefinition->xAdvance);
}
void BMFontConfiguration::parseKerningEntry(std::string line)
{
//////////////////////////////////////////////////////////////////////////
// line to parse:
// kerning first=121 second=44 amount=-7
//////////////////////////////////////////////////////////////////////////
// first
int first;
auto index = line.find("first=");
auto index2 = line.find(' ', index);
std::string value = line.substr(index, index2-index);
sscanf(value.c_str(), "first=%d", &first);
// second
int second;
index = line.find("second=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "second=%d", &second);
// amount
int amount;
index = line.find("amount=");
index2 = line.find(' ', index);
value = line.substr(index, index2-index);
sscanf(value.c_str(), "amount=%d", &amount);
tKerningHashElement *element = (tKerningHashElement *)calloc( sizeof( *element ), 1 );
element->amount = amount;
element->key = (first<<16) | (second&0xffff);
HASH_ADD_INT(_kerningDictionary,key, element);
}
FontFNT * FontFNT::create(const std::string& fntFilePath, const Point& imageOffset /* = Point::ZERO */)
{
BMFontConfiguration *newConf = FNTConfigLoadFile(fntFilePath);
if (!newConf)
return nullptr;
@ -46,7 +679,7 @@ FontFNT * FontFNT::create(const std::string& fntFilePath)
return nullptr;
}
FontFNT *tempFont = new FontFNT(newConf);
FontFNT *tempFont = new FontFNT(newConf,imageOffset);
if (!tempFont)
{
@ -57,11 +690,27 @@ FontFNT * FontFNT::create(const std::string& fntFilePath)
return tempFont;
}
FontFNT::FontFNT(BMFontConfiguration *theContfig, const Point& imageOffset /* = Point::ZERO */)
:_configuration(theContfig)
,_imageOffset(CC_POINT_PIXELS_TO_POINTS(imageOffset))
{
}
FontFNT::~FontFNT()
{
}
void FontFNT::purgeCachedData()
{
if (s_configurations)
{
s_configurations->clear();
CC_SAFE_DELETE(s_configurations);
}
}
int * FontFNT::getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const
{
if (!text)
@ -125,7 +774,7 @@ FontAtlas * FontFNT::createFontAtlas()
tempAtlas->setCommonLineHeight(_configuration->_commonHeight);
ccBMFontDef fontDef;
BMFontDef fontDef;
tFontDefHashElement *currentElement, *tmp;
// Purge uniform hash
@ -145,8 +794,8 @@ FontAtlas * FontFNT::createFontAtlas()
tempDefinition.offsetX = fontDef.xOffset;
tempDefinition.offsetY = fontDef.yOffset;
tempDefinition.U = tempRect.origin.x;
tempDefinition.V = tempRect.origin.y;
tempDefinition.U = tempRect.origin.x + _imageOffset.x;
tempDefinition.V = tempRect.origin.y + _imageOffset.y;
tempDefinition.width = tempRect.size.width;
tempDefinition.height = tempRect.size.height;
@ -174,4 +823,4 @@ FontAtlas * FontFNT::createFontAtlas()
}
NS_CC_END
NS_CC_END

View File

@ -30,22 +30,24 @@
NS_CC_BEGIN
class CCBMFontConfiguration;
class BMFontConfiguration;
class FontFNT : public Font
{
public:
static FontFNT * create(const std::string& fntFilePath);
static FontFNT * create(const std::string& fntFilePath, const Point& imageOffset = Point::ZERO);
/** Purges the cached data.
Removes from memory the cached configurations and the atlas name dictionary.
*/
static void purgeCachedData();
virtual int* getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const override;
virtual FontAtlas *createFontAtlas() override;
protected:
FontFNT(CCBMFontConfiguration *theContfig) :
_configuration(theContfig) {}
FontFNT(BMFontConfiguration *theContfig, const Point& imageOffset = Point::ZERO);
/**
* @js NA
* @lua NA
@ -56,7 +58,8 @@ private:
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const;
CCBMFontConfiguration * _configuration;
BMFontConfiguration * _configuration;
Point _imageOffset;
};

View File

@ -156,8 +156,17 @@ bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect, int &xA
return false;
// load glyph infos
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT))
return false;
if (_distanceFieldEnabled)
{
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
return false;
}
else
{
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT))
return false;
}
// store result in the passed rectangle
outRect.origin.x = _fontRef->glyph->metrics.horiBearingX >> 6;
@ -236,7 +245,7 @@ unsigned char * FontFreeType::getGlyphBitmap(unsigned short theChar, int &outWid
return 0;
if (_distanceFieldEnabled)
{
{
if (FT_Load_Char(_fontRef,theChar,FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT))
return 0;
}

View File

@ -79,16 +79,16 @@ Label* Label::createWithTTF(const std::string& text, const std::string& fontFile
return createWithTTF(ttfConfig,text,alignment,lineSize);
}
Label* Label::createWithBMFont(const std::string& bmfontFilePath, const std::string& text,const TextHAlignment& alignment /* = TextHAlignment::CENTER */, int lineSize /* = 0 */)
Label* Label::createWithBMFont(const std::string& bmfontFilePath, const std::string& text,const TextHAlignment& alignment /* = TextHAlignment::LEFT */, int lineWidth /* = 0 */, const Point& imageOffset /* = Point::ZERO */)
{
Label *ret = new Label(nullptr,alignment);
if (!ret)
return nullptr;
if (ret->setBMFontFilePath(bmfontFilePath))
if (ret->setBMFontFilePath(bmfontFilePath,imageOffset))
{
ret->setMaxLineWidth(lineSize);
ret->setMaxLineWidth(lineWidth);
ret->setString(text);
ret->autorelease();
return ret;
@ -299,9 +299,9 @@ bool Label::setTTFConfig(const TTFConfig& ttfConfig)
return initWithFontAtlas(newAtlas,ttfConfig.distanceFieldEnabled,true);
}
bool Label::setBMFontFilePath(const std::string& bmfontFilePath)
bool Label::setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset /* = Point::ZERO */)
{
FontAtlas *newAtlas = FontAtlasCache::getFontAtlasFNT(bmfontFilePath);
FontAtlas *newAtlas = FontAtlasCache::getFontAtlasFNT(bmfontFilePath,imageOffset);
if (!newAtlas)
return false;

View File

@ -76,7 +76,7 @@ public:
CC_DEPRECATED_ATTRIBUTE static Label* createWithTTF(const std::string& label, const std::string& fontFilePath, int fontSize, int lineSize = 0, TextHAlignment alignment = TextHAlignment::LEFT, GlyphCollection glyphs = GlyphCollection::NEHE, const char *customGlyphs = 0, bool useDistanceField = false);
static Label* createWithTTF(const TTFConfig& ttfConfig, const std::string& text, TextHAlignment alignment = TextHAlignment::LEFT, int lineWidth = 0);
static Label* createWithBMFont(const std::string& bmfontFilePath, const std::string& text,const TextHAlignment& alignment = TextHAlignment::LEFT, int lineWidth = 0);
static Label* createWithBMFont(const std::string& bmfontFilePath, const std::string& text,const TextHAlignment& alignment = TextHAlignment::LEFT, int lineWidth = 0, const Point& imageOffset = Point::ZERO);
static Label * createWithCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
static Label * createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
@ -84,7 +84,7 @@ public:
bool setTTFConfig(const TTFConfig& ttfConfig);
bool setBMFontFilePath(const std::string& bmfontFilePath);
bool setBMFontFilePath(const std::string& bmfontFilePath, const Point& imageOffset = Point::ZERO);
bool setCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);
bool setCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);

File diff suppressed because it is too large Load Diff

View File

@ -34,134 +34,10 @@ Use any of these editors to generate BMFonts:
#ifndef __CCBITMAP_FONT_ATLAS_H__
#define __CCBITMAP_FONT_ATLAS_H__
#include "CCSpriteBatchNode.h"
#include "uthash.h"
#include <map>
#include <sstream>
#include <iostream>
#include <vector>
#include "CCLabel.h"
NS_CC_BEGIN
/**
* @addtogroup GUI
* @{
* @addtogroup label
* @{
*/
enum {
kLabelAutomaticWidth = -1,
};
struct _FontDefHashElement;
/**
@struct ccBMFontDef
BMFont definition
*/
typedef struct _BMFontDef {
//! ID of the character
unsigned int charID;
//! origin and size of the font
Rect rect;
//! The X amount the image should be offset when drawing the image (in pixels)
short xOffset;
//! The Y amount the image should be offset when drawing the image (in pixels)
short yOffset;
//! The amount to move the current position after drawing the character (in pixels)
short xAdvance;
} ccBMFontDef;
/** @struct ccBMFontPadding
BMFont padding
@since v0.8.2
*/
typedef struct _BMFontPadding {
/// padding left
int left;
/// padding top
int top;
/// padding right
int right;
/// padding bottom
int bottom;
} ccBMFontPadding;
typedef struct _FontDefHashElement
{
unsigned int key; // key. Font Unicode value
ccBMFontDef fontDef; // font definition
UT_hash_handle hh;
} tFontDefHashElement;
// Equal function for targetSet.
typedef struct _KerningHashElement
{
int key; // key for the hash. 16-bit for 1st element, 16-bit for 2nd element
int amount;
UT_hash_handle hh;
} tKerningHashElement;
/** @brief CCBMFontConfiguration has parsed configuration of the the .fnt file
@since v0.8
*/
class CC_DLL CCBMFontConfiguration : public Ref
{
// XXX: Creating a public interface so that the bitmapFontArray[] is accessible
public://@public
// BMFont definitions
tFontDefHashElement *_fontDefDictionary;
//! FNTConfig: Common Height Should be signed (issue #1343)
int _commonHeight;
//! Padding
ccBMFontPadding _padding;
//! atlas name
std::string _atlasName;
//! values for kerning
tKerningHashElement *_kerningDictionary;
// Character Set defines the letters that actually exist in the font
std::set<unsigned int> *_characterSet;
public:
/**
* @js ctor
*/
CCBMFontConfiguration();
/**
* @js NA
* @lua NA
*/
virtual ~CCBMFontConfiguration();
/**
* @js NA
* @lua NA
*/
std::string description() const;
/** allocates a CCBMFontConfiguration with a FNT file */
static CCBMFontConfiguration * create(const std::string& FNTfile);
/** initializes a BitmapFontConfiguration with a FNT file */
bool initWithFNTfile(const std::string& FNTfile);
inline const std::string& getAtlasName(){ return _atlasName; }
inline void setAtlasName(const std::string& atlasName) { _atlasName = atlasName; }
std::set<unsigned int>* getCharacterSet() const;
private:
std::set<unsigned int>* parseConfigFile(const std::string& controlFile);
std::set<unsigned int>* parseBinaryConfigFile(unsigned char* pData, unsigned long size, const std::string& controlFile);
void parseCharacterDefinition(std::string line, ccBMFontDef *characterDefinition);
void parseInfoArguments(std::string line);
void parseCommonArguments(std::string line);
void parseImageFileName(std::string line, const std::string& fntFile);
void parseKerningEntry(std::string line);
void purgeKerningDictionary();
void purgeFontDefDictionary();
};
/** @brief LabelBMFont is a subclass of SpriteBatchNode.
Features:
@ -192,7 +68,7 @@ http://www.angelcode.com/products/bmfont/ (Free, Windows only)
@since v0.8
*/
class CC_DLL LabelBMFont : public SpriteBatchNode, public LabelProtocol
class CC_DLL LabelBMFont : public Node, public LabelProtocol, public BlendProtocol
{
public:
/**
@ -204,101 +80,56 @@ public:
* @lua NA
*/
virtual ~LabelBMFont();
/** Purges the cached data.
Removes from memory the cached configurations and the atlas name dictionary.
@since v0.99.3
*/
static void purgeCachedData();
/** creates a bitmap font atlas with an initial string and the FNT file */
static LabelBMFont * create(const std::string& str, const std::string& fntFile, float width, TextHAlignment alignment, Point imageOffset);
static LabelBMFont * create(const std::string& str, const std::string& fntFile, float width, TextHAlignment alignment);
static LabelBMFont * create(const std::string& str, const std::string& fntFile, float width);
static LabelBMFont * create(const std::string& str, const std::string& fntFile);
static LabelBMFont * create(const std::string& str, const std::string& fntFile, float width = 0, TextHAlignment alignment = TextHAlignment::LEFT,const Point& imageOffset = Point::ZERO);
/** Creates an label.
*/
static LabelBMFont * create();
bool init();
/** init a bitmap font atlas with an initial string and the FNT file */
bool initWithString(const std::string& str, const std::string& fntFile, float width = kLabelAutomaticWidth, TextHAlignment alignment = TextHAlignment::LEFT, Point imageOffset = Point::ZERO);
bool initWithString(const std::string& str, const std::string& fntFile, float width = 0, TextHAlignment alignment = TextHAlignment::LEFT,const Point& imageOffset = Point::ZERO);
/** updates the font chars based on the string to render */
void createFontChars();
// super method
virtual void setString(const std::string& newString) override;
virtual void setString(const std::string& newString, bool needUpdateLabel);
virtual const std::string& getString() const override;
virtual void setCString(const char *label);
virtual void setAnchorPoint(const Point& var) override;
virtual void updateLabel();
virtual void setAlignment(TextHAlignment alignment);
virtual void setWidth(float width);
virtual void setLineBreakWithoutSpace(bool breakWithoutSpace);
virtual void setScale(float scale);
virtual void setScaleX(float scaleX);
virtual void setScaleY(float scaleY);
// RGBAProtocol
virtual bool isOpacityModifyRGB() const;
virtual void setOpacityModifyRGB(bool isOpacityModifyRGB);
void setFntFile(const std::string& fntFile);
void setFntFile(const std::string& fntFile, const Point& imageOffset = Point::ZERO);
const std::string& getFntFile() const;
virtual void setBlendFunc(const BlendFunc &blendFunc) override;
virtual const BlendFunc &getBlendFunc() const override;
virtual Sprite * getLetter(int ID) { return _label->getLetter(ID);}
virtual Node * getChildByTag(int tag) override;
virtual void setColor(const Color3B& color) override { _label->setColor(color);}
virtual std::string getDescription() const override;
#if CC_LABELBMFONT_DEBUG_DRAW
virtual void draw();
#endif // CC_LABELBMFONT_DEBUG_DRAW
protected:
char * atlasNameFromFntFile(const std::string& fntFile);
int kerningAmountForFirst(unsigned short first, unsigned short second);
float getLetterPosXLeft( Sprite* characterSprite );
float getLetterPosXRight( Sprite* characterSprite );
virtual void setString(unsigned short *newString, bool needUpdateLabel);
// string to render
unsigned short* _string;
private:
// name of fntFile
std::string _fntFile;
// initial string without line breaks
unsigned short* _initialString;
std::string _initialStringUTF8;
// alignment of all lines
TextHAlignment _alignment;
// max width until a line break is added
float _width;
CCBMFontConfiguration *_configuration;
bool _lineBreakWithoutSpaces;
// offset of the texture atlas
Point _imageOffset;
// reused char
Sprite *_reusedChar;
// texture RGBA
bool _isOpacityModifyRGB;
Label* _label;
};
/** Free function that parses a FNT file a place it on the cache
*/
CC_DLL CCBMFontConfiguration * FNTConfigLoadFile(const std::string &file);
/** Purges the FNT config cache
*/
CC_DLL void FNTConfigRemoveCache( void );
// end of GUI group
/// @}
/// @}

View File

@ -590,7 +590,7 @@ void LayerColor::draw()
for(int i = 0; i < 4; ++i)
{
kmVec3 pos;
pos.x = _squareVertices[i].x; pos.y = _squareVertices[i].y; pos.z = _vertexZ;
pos.x = _squareVertices[i].x; pos.y = _squareVertices[i].y; pos.z = _positionZ;
kmVec3TransformCoord(&pos, &pos, &_modelViewTransform);
_noMVPVertices[i] = Vertex3F(pos.x,pos.y,pos.z);
}

View File

@ -77,9 +77,12 @@ static int s_globalOrderOfArrival = 1;
Node::Node(void)
: _rotationX(0.0f)
, _rotationY(0.0f)
, _rotationZ_X(0.0f)
, _rotationZ_Y(0.0f)
, _scaleX(1.0f)
, _scaleY(1.0f)
, _vertexZ(0.0f)
, _scaleZ(1.0f)
, _positionZ(0.0f)
, _position(Point::ZERO)
, _skewX(0.0f)
, _skewY(0.0f)
@ -230,32 +233,17 @@ void Node::setGlobalZOrder(float globalZOrder)
}
}
/// vertexZ getter
float Node::getVertexZ() const
{
return _vertexZ;
}
/// vertexZ setter
void Node::setVertexZ(float zOrder)
{
_vertexZ = zOrder;
setGlobalZOrder(zOrder);
}
/// rotation getter
float Node::getRotation() const
{
CCASSERT(_rotationX == _rotationY, "CCNode#rotation. RotationX != RotationY. Don't know which one to return");
return _rotationX;
CCASSERT(_rotationZ_X == _rotationZ_Y, "CCNode#rotation. RotationX != RotationY. Don't know which one to return");
return _rotationZ_X;
}
/// rotation setter
void Node::setRotation(float newRotation)
{
_rotationX = _rotationY = newRotation;
_rotationZ_X = _rotationZ_Y = newRotation;
_transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
@ -266,25 +254,51 @@ void Node::setRotation(float newRotation)
#endif
}
float Node::getRotationX() const
float Node::getRotationSkewX() const
{
return _rotationX;
return _rotationZ_X;
}
void Node::setRotationX(float fRotationX)
void Node::setRotation3D(const Vertex3F& rotation)
{
_rotationX = fRotationX;
_transformDirty = _inverseDirty = true;
_rotationX = rotation.x;
_rotationY = rotation.y;
// rotation Z is decomposed in 2 to simulate Skew for Flash animations
_rotationZ_Y = _rotationZ_X = rotation.z;
#if CC_USE_PHYSICS
if (_physicsBody)
{
_physicsBody->setRotation(_rotationZ_X);
}
#endif
}
Vertex3F Node::getRotation3D() const
{
// rotation Z is decomposed in 2 to simulate Skew for Flash animations
CCASSERT(_rotationZ_X == _rotationZ_Y, "_rotationZ_X != _rotationZ_Y");
return Vertex3F(_rotationX,_rotationY,_rotationZ_X);
}
void Node::setRotationSkewX(float fRotationX)
{
_rotationZ_X = fRotationX;
_transformDirty = _inverseDirty = true;
}
float Node::getRotationY() const
float Node::getRotationSkewY() const
{
return _rotationY;
return _rotationZ_Y;
}
void Node::setRotationY(float rotationY)
void Node::setRotationSkewY(float rotationY)
{
_rotationY = rotationY;
_rotationZ_Y = rotationY;
_transformDirty = _inverseDirty = true;
}
@ -329,6 +343,19 @@ float Node::getScaleY() const
return _scaleY;
}
/// scaleY setter
void Node::setScaleZ(float newScaleZ)
{
_scaleZ = newScaleZ;
_transformDirty = _inverseDirty = true;
}
/// scaleY getter
float Node::getScaleZ() const
{
return _scaleZ;
}
/// scaleY setter
void Node::setScaleY(float newScaleY)
{
@ -336,6 +363,7 @@ void Node::setScaleY(float newScaleY)
_transformDirty = _inverseDirty = true;
}
/// position getter
const Point& Node::getPosition() const
{
@ -367,26 +395,72 @@ void Node::setPosition(float x, float y)
setPosition(Point(x, y));
}
void Node::setPosition3D(const Vertex3F& position)
{
_positionZ = position.z;
setPosition(Point(position.x, position.y));
}
Vertex3F Node::getPosition3D() const
{
Vertex3F ret;
ret.x = _position.x;
ret.y = _position.y;
ret.z = _positionZ;
return ret;
}
float Node::getPositionX() const
{
return _position.x;
}
float Node::getPositionY() const
{
return _position.y;
}
void Node::setPositionX(float x)
{
setPosition(Point(x, _position.y));
}
float Node::getPositionY() const
{
return _position.y;
}
void Node::setPositionY(float y)
{
setPosition(Point(_position.x, y));
}
float Node::getPositionZ() const
{
return _positionZ;
}
void Node::setPositionZ(float positionZ)
{
_transformDirty = _inverseDirty = true;
_positionZ = positionZ;
// XXX BUG
// Global Z Order should based on the modelViewTransform
setGlobalZOrder(positionZ);
}
void Node::setNormalizedPosition(const cocos2d::Point &position)
{
_normalizedPosition = position;
Size s = Director::getInstance()->getVisibleSize();
Point p;
p.x = s.width * position.x;
p.y = s.height * position.y;
setPosition(p);
}
const Point& Node::getNormalizedPosition() const
{
return _normalizedPosition;
}
ssize_t Node::getChildrenCount() const
{
return _children.size();
@ -1139,6 +1213,7 @@ const kmMat4& Node::getNodeToParentTransform() const
// Translate values
float x = _position.x;
float y = _position.y;
float z = _positionZ;
if (_ignoreAnchorPointForPosition)
{
@ -1150,10 +1225,10 @@ const kmMat4& Node::getNodeToParentTransform() const
// Change rotation code to handle X and Y
// If we skew with the exact same value for both x and y then we're simply just rotating
float cx = 1, sx = 0, cy = 1, sy = 0;
if (_rotationX || _rotationY)
if (_rotationZ_X || _rotationZ_Y)
{
float radiansX = -CC_DEGREES_TO_RADIANS(_rotationX);
float radiansY = -CC_DEGREES_TO_RADIANS(_rotationY);
float radiansX = -CC_DEGREES_TO_RADIANS(_rotationZ_X);
float radiansY = -CC_DEGREES_TO_RADIANS(_rotationZ_Y);
cx = cosf(radiansX);
sx = sinf(radiansX);
cy = cosf(radiansY);
@ -1175,13 +1250,28 @@ const kmMat4& Node::getNodeToParentTransform() const
// Build Transform Matrix
// Adjusted transform calculation for rotational skew
kmScalar mat[] = { cy * _scaleX, sy * _scaleX, 0, 0,
-sx * _scaleY, cx * _scaleY, 0, 0,
0, 0, 1, 0,
x, y, 0, 1 };
kmScalar mat[] = {
cy * _scaleX, sy * _scaleX, 0, 0,
-sx * _scaleY, cx * _scaleY, 0, 0,
0, 0, _scaleZ, 0,
x, y, z, 1 };
kmMat4Fill(&_transform, mat);
// XXX
// FIX ME: Expensive operation.
// FIX ME: It should be done together with the rotationZ
if(_rotationY) {
kmMat4 rotY;
kmMat4RotationY(&rotY,CC_DEGREES_TO_RADIANS(_rotationY));
kmMat4Multiply(&_transform, &_transform, &rotY);
}
if(_rotationX) {
kmMat4 rotX;
kmMat4RotationX(&rotX,CC_DEGREES_TO_RADIANS(_rotationX));
kmMat4Multiply(&_transform, &_transform, &rotX);
}
// XXX: Try to inline skew
// If skew is needed, apply skew and then anchor point
if (needsSkewMatrix)
@ -1203,9 +1293,6 @@ const kmMat4& Node::getNodeToParentTransform() const
}
}
// vertex Z
_transform.mat[14] = _vertexZ;
if (_useAdditionalTransform)
{
kmMat4Multiply(&_transform, &_transform, &_additionalTransform);
@ -1348,7 +1435,7 @@ bool Node::updatePhysicsTransform()
if (_physicsBody != nullptr && _physicsBody->getWorld() != nullptr && !_physicsBody->isResting())
{
_position = _physicsBody->getPosition();
_rotationX = _rotationY = _physicsBody->getRotation();
_rotationZ_X = _rotationZ_Y = _physicsBody->getRotation();
_transformDirty = _inverseDirty = true;
return true;
}

View File

@ -35,7 +35,6 @@
#include "CCGL.h"
#include "ccGLStateCache.h"
#include "CCGLProgram.h"
#include "kazmath/kazmath.h"
#include "CCScriptSupport.h"
#include "CCProtocols.h"
#include "CCEventDispatcher.h"
@ -214,29 +213,6 @@ public:
*/
virtual float getGlobalZOrder() const { return _globalZOrder; }
/**
* Sets the 'z' value in the OpenGL Depth Buffer.
*
* The OpenGL depth buffer and depth testing are disabled by default. You need to turn them on
* in order to use this property correctly.
*
* `setVertexZ()` also sets the `setGlobalZValue()` with the vertexZ value.
*
* @see `setGlobalZValue()`
*
* @param vertexZ OpenGL Z vertex of this node.
*/
virtual void setVertexZ(float vertexZ);
/**
* Gets OpenGL Z vertex of this node.
*
* @see setVertexZ(float)
*
* @return OpenGL Z vertex of this node
*/
virtual float getVertexZ() const;
/**
* Changes the scale factor on X axis of this node
*
@ -272,6 +248,23 @@ public:
*/
virtual float getScaleY() const;
/**
* Changes the scale factor on Z axis of this node
*
* The Default value is 1.0 if you haven't changed it before.
*
* @param scaleY The scale factor on Y axis.
*/
virtual void setScaleZ(float scaleZ);
/**
* Returns the scale factor on Z axis of this node
*
* @see `setScaleZ(float)`
*
* @return The scale factor on Z axis.
*/
virtual float getScaleZ() const;
/**
* Changes both X and Y scale factor of the node.
@ -359,17 +352,62 @@ public:
virtual void setPositionY(float y);
virtual float getPositionY(void) const;
/**
* Sets the X, Y, and Z axis position
*/
virtual void setPosition3D(const Vertex3F& position);
/**
* returns the X, Y and Z axis position
*/
virtual Vertex3F getPosition3D() const;
/**
* Sets the 'z' axis in the position. It is the OpenGL Z vertex value.
*
* The OpenGL depth buffer and depth testing are disabled by default. You need to turn them on
* in order to use this property correctly.
*
* `setPositionZ()` also sets the `setGlobalZValue()` with the positionZ as value.
*
* @see `setGlobalZValue()`
*
* @param vertexZ OpenGL Z vertex of this node.
*/
virtual void setPositionZ(float positionZ);
CC_DEPRECATED_ATTRIBUTE virtual void setVertexZ(float vertexZ) { setPositionZ(vertexZ); }
/**
* Gets position Z axis of this node.
*
* @see setPositionZ(float)
*
* @return the position Z axis of this node.
*/
virtual float getPositionZ() const;
CC_DEPRECATED_ATTRIBUTE virtual float getVertexZ() const { return getPositionZ(); }
/** Sets the position using normalized coordinates.
- (0,0) means bottom,left corner
- (1,1) means top,right corner
- (0.5,0.5) means center
*/
virtual void setNormalizedPosition(const Point& position);
/** returns the normalized position */
const Point& getNormalizedPosition() const;
/**
* Changes the X skew angle of the node in degrees.
*
* The difference between `setRotationalSkew()` and `setSkew()` is that the first one simulate Flash's skew functionality
* while the second one uses the real skew funciton.
*
* This angle describes the shear distortion in the X direction.
* Thus, it is the angle between the Y axis and the left edge of the shape
* The default skewX angle is 0. Positive values distort the node in a CW direction.
*
* @param fSkewX The X skew angle of the node in degrees.
* @param skewX The X skew angle of the node in degrees.
*/
virtual void setSkewX(float fSkewX);
virtual void setSkewX(float skewX);
/**
* Returns the X skew angle of the node in degrees.
*
@ -383,13 +421,16 @@ public:
/**
* Changes the Y skew angle of the node in degrees.
*
* The difference between `setRotationalSkew()` and `setSkew()` is that the first one simulate Flash's skew functionality
* while the second one uses the real skew funciton.
*
* This angle describes the shear distortion in the Y direction.
* Thus, it is the angle between the X axis and the bottom edge of the shape
* The default skewY angle is 0. Positive values distort the node in a CCW direction.
*
* @param fSkewY The Y skew angle of the node in degrees.
* @param skewY The Y skew angle of the node in degrees.
*/
virtual void setSkewY(float fSkewY);
virtual void setSkewY(float skewY);
/**
* Returns the Y skew angle of the node in degrees.
*
@ -486,44 +527,63 @@ public:
*/
virtual float getRotation() const;
/**
* Sets the X, Y and Z axis rotation
* Useful for 3d rotations
*/
virtual void setRotation3D(const Vertex3F& rotation);
/**
* returns the X, Y and Z axis rotation
*/
virtual Vertex3F getRotation3D() const;
/**
* Sets the X rotation (angle) of the node in degrees which performs a horizontal rotational skew.
*
* The difference between setRotationalSkew() and setSkew() is that the first one simulate Flash's skew functionality
* while the second one uses the real skew funciton.
*
* 0 is the default rotation angle.
* Positive values rotate node clockwise, and negative values for anti-clockwise.
*
* @param rotationX The X rotation in degrees which performs a horizontal rotational skew.
*/
virtual void setRotationX(float rotationX);
virtual void setRotationSkewX(float rotationX);
CC_DEPRECATED_ATTRIBUTE virtual void setRotationX(float rotationX) { return setRotationSkewX(rotationX); }
/**
* Gets the X rotation (angle) of the node in degrees which performs a horizontal rotation skew.
*
* @see `setRotationX(float)`
* @see `setRotationSkewX(float)`
*
* @return The X rotation in degrees.
*/
virtual float getRotationX() const;
virtual float getRotationSkewX() const;
CC_DEPRECATED_ATTRIBUTE virtual float getRotationX() const { return getRotationSkewX(); }
/**
* Sets the Y rotation (angle) of the node in degrees which performs a vertical rotational skew.
*
* The difference between setRotationalSkew() and setSkew() is that the first one simulate Flash's skew functionality
* while the second one uses the real skew funciton.
*
* 0 is the default rotation angle.
* Positive values rotate node clockwise, and negative values for anti-clockwise.
*
* @param rotationY The Y rotation in degrees.
*/
virtual void setRotationY(float rotationY);
virtual void setRotationSkewY(float rotationY);
CC_DEPRECATED_ATTRIBUTE virtual void setRotationY(float rotationY) { return setRotationSkewY(rotationY); }
/**
* Gets the Y rotation (angle) of the node in degrees which performs a vertical rotational skew.
*
* @see `setRotationY(float)`
* @see `setRotationSkewY(float)`
*
* @return The Y rotation in degrees.
*/
virtual float getRotationY() const;
virtual float getRotationSkewY() const;
CC_DEPRECATED_ATTRIBUTE virtual float getRotationY() const { return getRotationSkewY(); }
/**
* Sets the arrival order when this node has a same ZOrder with other children.
@ -1429,18 +1489,23 @@ protected:
virtual void disableCascadeColor();
virtual void updateColor() {}
float _rotationX; ///< rotation on the X-axis
float _rotationY; ///< rotation on the Y-axis
float _rotationX; ///< rotation angle on x-axis
float _rotationY; ///< rotation angle on y-axis
// rotation Z is decomposed in 2 to simulate Skew for Flash animations
float _rotationZ_X; ///< rotation angle on Z-axis, component X
float _rotationZ_Y; ///< rotation angle on Z-axis, component Y
float _scaleX; ///< scaling factor on x-axis
float _scaleY; ///< scaling factor on y-axis
float _scaleX; ///< scaling factor on x-axis
float _scaleY; ///< scaling factor on y-axis
float _scaleZ; ///< scaling factor on z-axis
Point _position; ///< position of the node
float _positionZ; ///< OpenGL real Z position
Point _normalizedPosition; ///< position in normalized coordinates
Point _position; ///< position of the node
float _skewX; ///< skew angle on x-axis
float _skewY; ///< skew angle on y-axis
float _skewX; ///< skew angle on x-axis
float _skewY; ///< skew angle on y-axis
Point _anchorPointInPoints; ///< anchor point in points
Point _anchorPoint; ///< anchor point normalized (NOT in points)
@ -1460,8 +1525,6 @@ protected:
int _localZOrder; ///< Local order (relative to its siblings) used to sort the node
float _globalZOrder; ///< Global order used to sort the node
float _vertexZ; ///< OpenGL real Z vertex
Vector<Node*> _children; ///< array of children nodes
Node *_parent; ///< weak reference to parent node

View File

@ -45,12 +45,14 @@ THE SOFTWARE.
#include "CCAffineTransform.h"
#include "TransformUtils.h"
#include "CCProfiling.h"
#include "CCDirector.h"
#include "renderer/CCRenderer.h"
#include "renderer/CCQuadCommand.h"
#include "renderer/CCFrustum.h"
// external
#include "kazmath/GL/matrix.h"
#include "kazmath/kazmath.h"
using namespace std;
@ -563,10 +565,10 @@ void Sprite::updateTransform(void)
float dx = x1 * cr - y2 * sr2 + x;
float dy = x1 * sr + y2 * cr2 + y;
_quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ );
_quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ );
_quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ );
_quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ );
_quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _positionZ );
_quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _positionZ );
_quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _positionZ );
_quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _positionZ );
}
// MARMALADE CHANGE: ADDED CHECK FOR nullptr, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS
@ -597,7 +599,7 @@ void Sprite::updateTransform(void)
Point( _quad.tr.vertices.x, _quad.tr.vertices.y ),
Point( _quad.tl.vertices.x, _quad.tl.vertices.y ),
};
ccDrawPoly(vertices, 4, true);
DrawPrimitives::drawPoly(vertices, 4, true);
#endif // CC_SPRITE_DEBUG_DRAW
}
@ -605,83 +607,43 @@ void Sprite::updateTransform(void)
void Sprite::draw(void)
{
//TODO implement z order
_quadCommand.init(_globalZOrder, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, _modelViewTransform);
// if(culling())
if(culling())
{
_quadCommand.init(_globalZOrder, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, _modelViewTransform);
Director::getInstance()->getRenderer()->addCommand(&_quadCommand);
}
}
// Culling function from cocos2d-iphone CCSprite.m file
bool Sprite::culling() const
{
Frustum* frustum = Director::getInstance()->getFrustum();
//TODO optimize this transformation, should use parent's transformation instead
kmMat4 worldTM = getNodeToWorldTransform();
//generate aabb
// half size of the screen
Size screen_half = Director::getInstance()->getWinSize();
screen_half.width /= 2;
screen_half.height /= 2;
//
// calculate the Quad based on the Affine Matrix
//
Rect newRect = RectApplyTransform(_rect, worldTM);
float hcsx = _contentSize.width / 2;
float hcsy = _contentSize.height / 2;
kmVec3 point = {newRect.getMinX(), newRect.getMinY(), _vertexZ};
AABB aabb(point,point);
kmVec3Fill(&point,newRect.getMaxX(), newRect.getMinY(), _vertexZ);
aabb.expand(point);
kmVec3Fill(&point,newRect.getMinX(), newRect.getMaxY(), _vertexZ);
aabb.expand(point);
kmVec3Fill(&point,newRect.getMaxX(), newRect.getMaxY(), _vertexZ);
aabb.expand(point);
// convert to world coordinates
float x = hcsx * _modelViewTransform.mat[0] + hcsy * _modelViewTransform.mat[4] + _modelViewTransform.mat[12];
float y = hcsx * _modelViewTransform.mat[1] + hcsy * _modelViewTransform.mat[5] + _modelViewTransform.mat[13];
return Frustum::IntersectResult::OUTSIDE !=frustum->intersectAABB(aabb);
}
// center of screen is (0,0)
x -= screen_half.width;
y -= screen_half.height;
void Sprite::updateQuadVertices()
{
#if CC_USE_PHYSICS
updatePhysicsTransform();
setDirty(true);
#endif
// convert content size to world coordinates
float wchw = hcsx * fmaxf(fabsf(_modelViewTransform.mat[0] + _modelViewTransform.mat[4]), fabsf(_modelViewTransform.mat[0] - _modelViewTransform.mat[4]));
float wchh = hcsy * fmaxf(fabsf(_modelViewTransform.mat[1] + _modelViewTransform.mat[5]), fabsf(_modelViewTransform.mat[1] - _modelViewTransform.mat[5]));
//TODO optimize the performance cache affineTransformation
// recalculate matrix only if it is dirty
if(isDirty())
{
// if( ! _parent || _parent == (Node*)_batchNode )
// {
// _transformToBatch = getNodeToParentTransform();
// }
// else
// {
// CCASSERT( dynamic_cast<Sprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite");
// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast<Sprite*>(_parent)->_transformToBatch );
// }
//TODO optimize this transformation, should use parent's transformation instead
_transformToBatch = getNodeToWorldTransform();
//
// calculate the Quad based on the Affine Matrix
//
Rect newRect = RectApplyTransform(_rect, _transformToBatch);
_quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMinX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ );
_quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMaxX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ );
_quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMinX()), RENDER_IN_SUBPIXEL(newRect.getMaxY()), _vertexZ );
_quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMaxX()), RENDER_IN_SUBPIXEL(newRect.getMaxY()), _vertexZ );
_recursiveDirty = false;
setDirty(false);
}
// compare if it in the positive quarter of the screen
float tmpx = (fabsf(x)-wchw);
float tmpy = (fabsf(y)-wchh);
return (tmpx < screen_half.width && tmpy < screen_half.height);
}
// Node overrides
void Sprite::addChild(Node *child, int zOrder, int tag)
{
CCASSERT(child != nullptr, "Argument must be non-nullptr");
@ -847,15 +809,15 @@ void Sprite::setRotation(float rotation)
SET_DIRTY_RECURSIVELY();
}
void Sprite::setRotationX(float fRotationX)
void Sprite::setRotationSkewX(float fRotationX)
{
Node::setRotationX(fRotationX);
Node::setRotationSkewX(fRotationX);
SET_DIRTY_RECURSIVELY();
}
void Sprite::setRotationY(float fRotationY)
void Sprite::setRotationSkewY(float fRotationY)
{
Node::setRotationY(fRotationY);
Node::setRotationSkewY(fRotationY);
SET_DIRTY_RECURSIVELY();
}
@ -895,9 +857,9 @@ void Sprite::setScale(float scaleX, float scaleY)
SET_DIRTY_RECURSIVELY();
}
void Sprite::setVertexZ(float fVertexZ)
void Sprite::setPositionZ(float fVertexZ)
{
Node::setVertexZ(fVertexZ);
Node::setPositionZ(fVertexZ);
SET_DIRTY_RECURSIVELY();
}

View File

@ -408,8 +408,8 @@ public:
virtual void setPosition(const Point& pos) override;
virtual void setPosition(float x, float y) override;
virtual void setRotation(float rotation) override;
virtual void setRotationX(float rotationX) override;
virtual void setRotationY(float rotationY) override;
virtual void setRotationSkewX(float rotationX) override;
virtual void setRotationSkewY(float rotationY) override;
virtual void setSkewX(float sx) override;
virtual void setSkewY(float sy) override;
virtual void removeChild(Node* child, bool cleanup) override;
@ -419,11 +419,10 @@ public:
virtual void addChild(Node *child, int zOrder, int tag) override;
virtual void sortAllChildren() override;
virtual void setScale(float scale) override;
virtual void setVertexZ(float vertexZ) override;
virtual void setPositionZ(float positionZ) override;
virtual void setAnchorPoint(const Point& anchor) override;
virtual void ignoreAnchorPointForPosition(bool value) override;
virtual void setVisible(bool bVisible) override;
virtual void updateQuadVertices();
virtual void draw(void) override;
virtual void setOpacityModifyRGB(bool modify) override;
virtual bool isOpacityModifyRGB(void) const override;

View File

@ -23,8 +23,11 @@
THE SOFTWARE.
****************************************************************************/
#import <Foundation/Foundation.h>
#import <OpenGLES/EAGL.h>
#import "CCDirectorCaller.h"
#import "CCDirector.h"
#import "CCGLView.h"
#import "CCEAGLView.h"
static id s_sharedDirectorCaller;
@ -92,7 +95,9 @@ static id s_sharedDirectorCaller;
-(void) doCaller: (id) sender
{
cocos2d::Director::getInstance()->mainLoop();
cocos2d::Director* director = cocos2d::Director::getInstance();
[EAGLContext setCurrentContext: [(CCEAGLView*)director->getOpenGLView()->getEAGLView() context]];
director->mainLoop();
}
@end

View File

@ -50,6 +50,7 @@ static long getCurrentMillSecond() {
}
Application::Application()
: _animationInterval(1.0f/60.0f*1000.0f)
{
CC_ASSERT(! sm_pSharedApplication);
sm_pSharedApplication = this;
@ -59,7 +60,6 @@ Application::~Application()
{
CC_ASSERT(this == sm_pSharedApplication);
sm_pSharedApplication = NULL;
_animationInterval = 1.0f/60.0f*1000.0f;
}
int Application::run()
@ -75,7 +75,7 @@ int Application::run()
while (!glview->windowShouldClose())
{
long iLastTime = getCurrentMillSecond();
long iLastTime = getCurrentMillSecond();
director->mainLoop();
glview->pollEvents();
long iCurTime = getCurrentMillSecond();

View File

@ -104,6 +104,7 @@ public:
protected:
static Application * sm_pSharedApplication;
long _animationInterval; //micro second
std::string _resourceRootPath;
std::string _startupScriptFilename;
};

View File

@ -37,9 +37,20 @@ THE SOFTWARE.
NS_CC_BEGIN
static long getCurrentMillSecond()
{
long lLastTime = 0;
struct timeval stCurrentTime;
gettimeofday(&stCurrentTime,NULL);
lLastTime = stCurrentTime.tv_sec*1000+stCurrentTime.tv_usec*0.001; //millseconds
return lLastTime;
}
Application* Application::sm_pSharedApplication = 0;
Application::Application()
: _animationInterval(1.0f/60.0f*1000.0f)
{
CCASSERT(! sm_pSharedApplication, "sm_pSharedApplication already exist");
sm_pSharedApplication = this;
@ -61,8 +72,13 @@ int Application::run()
while (!glview->windowShouldClose())
{
long iLastTime = getCurrentMillSecond();
Director::getInstance()->mainLoop();
glview->pollEvents();
long iCurTime = getCurrentMillSecond();
if (iCurTime-iLastTime<_animationInterval){
usleep(static_cast<useconds_t>((_animationInterval - iCurTime+iLastTime)*1000));
}
}
/* Only work on Desktop
@ -77,7 +93,7 @@ int Application::run()
void Application::setAnimationInterval(double interval)
{
[[CCDirectorCaller sharedDirectorCaller] setAnimationInterval: interval ];
_animationInterval = interval*1000.0f;
}
Application::Platform Application::getTargetPlatform()

View File

@ -1,46 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
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 "CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_MAC
#import <Foundation/Foundation.h>
#import <QuartzCore/CVDisplayLink.h>
@interface CCDirectorCaller : NSObject {
CVDisplayLinkRef displayLink;
NSTimer *renderTimer;
int interval;
}
@property (readwrite) int interval;
-(void) startMainLoop;
-(void) end;
-(void) doCaller: (id) sender;
-(void) setAnimationInterval:(double)interval;
+(id) sharedDirectorCaller;
@end
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_MAC

View File

@ -1,207 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
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 "CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_MAC
#import "CCDirectorCaller.h"
#include "CCDirector.h"
#include "CCAutoreleasePool.h"
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
static id s_sharedDirectorCaller;
@interface NSObject(CADisplayLink)
+(id) displayLinkWithTarget: (id)arg1 selector:(SEL)arg2;
-(void) addToRunLoop: (id)arg1 forMode: (id)arg2;
-(void) setFrameInterval: (int)interval;
-(void) invalidate;
@end
@implementation CCDirectorCaller
@synthesize interval;
+(id) sharedDirectorCaller
{
if (s_sharedDirectorCaller == nil)
{
s_sharedDirectorCaller = [[CCDirectorCaller alloc] init];
}
return s_sharedDirectorCaller;
}
-(void) alloc
{
interval = 1;
}
-(void) dealloc
{
s_sharedDirectorCaller = nil;
CCLOGINFO("deallocing DirectorCaller: %p", self);
if (displayLink) {
CVDisplayLinkRelease(displayLink);
}
CCLOG("--------------------------------------------------------------------------------");
CCLOG("");
CCLOG("");
CCLOG("");
[super dealloc];
}
- (CVReturn) getFrameForTime:(const CVTimeStamp*)outputTime
{
#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
//if( ! runningThread_ )
//runningThread_ = [NSThread currentThread];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
cocos2d::Director::getInstance()->drawScene();
cocos2d::PoolManager::getInstance()->getCurrentPool()->clear();
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:nil];
// release the objects
[pool release];
#else
[self performSelector:@selector(drawScene) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES];
#endif
return kCVReturnSuccess;
}
// This is the renderer output callback function
static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{
// CVReturn result = [(DirectorCaller*)displayLinkContext getFrameForTime:outputTime];
// return result;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
cocos2d::Director::getInstance()->mainLoop();
[pool release];
return kCVReturnSuccess;
}
- (void)timerFired:(id)sender
{
// It is good practice in a Cocoa application to allow the system to send the -drawRect:
// message when it needs to draw, and not to invoke it directly from the timer.
// All we do here is tell the display it needs a refresh
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// run the main cocos2d loop
cocos2d::Director::getInstance()->mainLoop();
[pool release];
}
-(void) startMainLoop
{
// Director::setAnimationInterval() is called, we should invalide it first
// [displayLink invalidate];
// displayLink = nil;
//
// displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];
// [displayLink setFrameInterval: self.interval];
// [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
#if ! CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(mainLoop) object:nil];
[thread start];
#endif
// NSTimer
[renderTimer invalidate];
renderTimer = nil;
renderTimer = [NSTimer timerWithTimeInterval:self.interval/60.0f //a 1ms time interval
target:self
selector:@selector(timerFired:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:renderTimer
forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:renderTimer
forMode:NSEventTrackingRunLoopMode]; //Ensure timer fires during resize
/*
// CVDisplayLink
//cocos2d::Director::getInstance()->gettimeofday();
// Create a display link capable of being used with all active displays
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
// Set the renderer output callback function
CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
// Set the display link for the current renderer
CCEAGLView *openGLView_ = (CCEAGLView*)[CCEAGLView sharedEGLView];
CGLContextObj cglContext = (CGLContextObj)[[openGLView_ openGLContext] CGLContextObj];
CGLPixelFormatObj cglPixelFormat = (CGLPixelFormatObj)[[openGLView_ pixelFormat] CGLPixelFormatObj];
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
// Activate the display link
CVDisplayLinkStart(displayLink);
*/
}
-(void) end
{
[renderTimer invalidate];
renderTimer = nil;
[self release];
}
-(void) setAnimationInterval:(double)intervalNew
{
self.interval = 60.0 * intervalNew;
[renderTimer invalidate];
renderTimer = nil;
renderTimer = [NSTimer timerWithTimeInterval:self.interval/60.0f //a 1ms time interval
target:self
selector:@selector(timerFired:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:renderTimer
forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:renderTimer
forMode:NSEventTrackingRunLoopMode];
}
-(void) doCaller: (id) sender
{
cocos2d::Director::getInstance()->mainLoop();
}
@end
#endif //s CC_TARGET_PLATFORM == CC_PLATFORM_MAC

View File

@ -64,20 +64,6 @@ public:
class CC_DLL Ref
{
public:
/**
* Constructor
*
* The Ref's reference count is 1 after construction.
* @js NA
*/
Ref();
/**
* @js NA
* @lua NA
*/
virtual ~Ref();
/**
* Retains the ownership.
*
@ -125,7 +111,23 @@ public:
* @js NA
*/
unsigned int getReferenceCount() const;
protected:
/**
* Constructor
*
* The Ref's reference count is 1 after construction.
* @js NA
*/
Ref();
public:
/**
* @js NA
* @lua NA
*/
virtual ~Ref();
protected:
/// count of references
unsigned int _referenceCount;

View File

@ -309,18 +309,39 @@ public:
last->release();
}
/** @brief Remove a certain object.
/** @brief Remove a certain object in Vector.
* @param object The object to be removed.
* @param toRelease Whether to decrease the referece count of the deleted object.
* @param removeAll Whether to remove all elements with the same value.
* If its value is 'false', it will just erase the first occurrence.
*/
void eraseObject(T object, bool toRelease = true)
void eraseObject(T object, bool removeAll = false)
{
CCASSERT(object != nullptr, "The object should not be nullptr");
auto iter = std::find(_data.begin(), _data.end(), object);
if (iter != _data.end())
_data.erase(iter);
if (toRelease)
object->release();
if (removeAll)
{
for (auto iter = _data.begin(); iter != _data.end();)
{
if ((*iter) == object)
{
iter = _data.erase(iter);
object->release();
}
else
{
++iter;
}
}
}
else
{
auto iter = std::find(_data.begin(), _data.end(), object);
if (iter != _data.end())
{
_data.erase(iter);
object->release();
}
}
}
/** @brief Removes from the vector with an iterator.

View File

@ -188,10 +188,10 @@ void Skin::updateTransform()
float dx = x1 * cr - y2 * sr2 + x;
float dy = x1 * sr + y2 * cr2 + y;
SET_VERTEX3F( _quad.bl.vertices, RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _vertexZ );
SET_VERTEX3F( _quad.br.vertices, RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _vertexZ );
SET_VERTEX3F( _quad.tl.vertices, RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _vertexZ );
SET_VERTEX3F( _quad.tr.vertices, RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _vertexZ );
SET_VERTEX3F( _quad.bl.vertices, RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _positionZ );
SET_VERTEX3F( _quad.br.vertices, RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _positionZ );
SET_VERTEX3F( _quad.tl.vertices, RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _positionZ );
SET_VERTEX3F( _quad.tr.vertices, RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _positionZ );
}
// MARMALADE CHANGE: ADDED CHECK FOR nullptr, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS

View File

@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "vec2.h"
#include "vec3.h"
#include "vec4.h"
#include "mat3.h"
#include "mat4.h"
#include "utility.h"

@ -1 +1 @@
Subproject commit fbacec019c31361280c3a23d4a2576c1332c0f84
Subproject commit 42d96e2c6b04d0d75c12e3fdf1cc24a160160e89

View File

@ -186,7 +186,7 @@ void Control::removeTargetWithActionForControlEvent(Ref* target, Handler action,
//remove all invocations if the target and action are null
//TODO: should the invocations be deleted, or just removed from the array? Won't that cause issues if you add a single invocation for multiple events?
bool bDeleteObjects=true;
if (!target && !action)
{
//remove objects
@ -215,7 +215,7 @@ void Control::removeTargetWithActionForControlEvent(Ref* target, Handler action,
}
for(const auto &invocation : tobeRemovedInvocations) {
eventInvocationList.eraseObject(invocation, bDeleteObjects);
eventInvocationList.eraseObject(invocation);
}
}
}

View File

@ -95,6 +95,7 @@ public:
virtual void setText(const char* pText);
virtual const char* getText(void);
virtual void refreshInactiveText();
virtual void setPlaceHolder(const char* pText);
virtual void setPosition(const Point& pos);
virtual void setVisible(bool visible);

View File

@ -185,7 +185,7 @@ static const int CC_EDIT_BOX_PADDING = 5;
{
CCLOG("textFieldShouldEndEditing...");
editState_ = NO;
getEditBoxImplIOS()->setText(getEditBoxImplIOS()->getText());
getEditBoxImplIOS()->refreshInactiveText();
cocos2d::extension::EditBoxDelegate* pDelegate = getEditBoxImplIOS()->getDelegate();
if (pDelegate != NULL)
@ -343,30 +343,32 @@ void EditBoxImplIOS::initInactiveLabels(const Size& size)
setPlaceholderFont(pDefaultFontName, size.height*2/3);
}
void EditBoxImplIOS::placeInactiveLabels() {
void EditBoxImplIOS::placeInactiveLabels()
{
_label->setPosition(Point(CC_EDIT_BOX_PADDING, _contentSize.height / 2.0f));
_labelPlaceHolder->setPosition(Point(CC_EDIT_BOX_PADDING, _contentSize.height / 2.0f));
}
void EditBoxImplIOS::setInactiveText(const char* pText)
{
if(_systemControl.textField.secureTextEntry == YES)
{
std::string passwordString;
for(int i = 0; i < strlen(pText); ++i)
passwordString.append("\u25CF");
_label->setString(passwordString.c_str());
}
else
_label->setString(getText());
// Clip the text width to fit to the text box
float fMaxWidth = _editBox->getContentSize().width - CC_EDIT_BOX_PADDING * 2;
Rect clippingRect = _label->getTextureRect();
if(clippingRect.size.width > fMaxWidth) {
clippingRect.size.width = fMaxWidth;
_label->setTextureRect(clippingRect);
}
if(_systemControl.textField.secureTextEntry == YES)
{
std::string passwordString;
for(int i = 0; i < strlen(pText); ++i)
passwordString.append("\u25CF");
_label->setString(passwordString.c_str());
}
else
_label->setString(getText());
// Clip the text width to fit to the text box
float fMaxWidth = _editBox->getContentSize().width - CC_EDIT_BOX_PADDING * 2;
Rect clippingRect = _label->getTextureRect();
if(clippingRect.size.width > fMaxWidth)
{
clippingRect.size.width = fMaxWidth;
_label->setTextureRect(clippingRect);
}
}
void EditBoxImplIOS::setFont(const char* pFontName, int fontSize)
@ -419,25 +421,13 @@ void EditBoxImplIOS::setPlaceholderFontColor(const Color3B& color)
void EditBoxImplIOS::setInputMode(EditBox::InputMode inputMode)
{
// FIX ME: this is a temporary fix for issue #2920: IPA packed by Xcode5 may crash on iOS7 when switching to voice recognition input method.
// This temporary fix is only for ios version aboves 7.0.
// I don't know how to fix it, so I changed the keyboard type to hide the dictation button to avoid crash.
// Issue #2920 url: http://www.cocos2d-x.org/issues/2920
Boolean above7 = NO;
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:@"7" options:NSNumericSearch range:NSMakeRange(0, 1)] == 0)
{
above7 = YES;
}
switch (inputMode)
{
case EditBox::InputMode::EMAIL_ADDRESS:
_systemControl.textField.keyboardType = UIKeyboardTypeEmailAddress;
break;
case EditBox::InputMode::NUMERIC:
_systemControl.textField.keyboardType = (above7 ? UIKeyboardTypeDecimalPad : UIKeyboardTypeNumberPad);
_systemControl.textField.keyboardType = UIKeyboardTypeDecimalPad;
break;
case EditBox::InputMode::PHONE_NUMBER:
_systemControl.textField.keyboardType = UIKeyboardTypePhonePad;
@ -449,10 +439,10 @@ void EditBoxImplIOS::setInputMode(EditBox::InputMode inputMode)
_systemControl.textField.keyboardType = UIKeyboardTypeDecimalPad;
break;
case EditBox::InputMode::SINGLE_LINE:
_systemControl.textField.keyboardType = (above7 ? UIKeyboardTypeEmailAddress : UIKeyboardTypeDefault);
_systemControl.textField.keyboardType = UIKeyboardTypeDefault;
break;
default:
_systemControl.textField.keyboardType = (above7 ? UIKeyboardTypeEmailAddress : UIKeyboardTypeDefault);
_systemControl.textField.keyboardType = UIKeyboardTypeDefault;
break;
}
}
@ -520,12 +510,13 @@ bool EditBoxImplIOS::isEditing()
return [_systemControl isEditState] ? true : false;
}
void EditBoxImplIOS::setText(const char* pText)
void EditBoxImplIOS::refreshInactiveText()
{
_systemControl.textField.text = [NSString stringWithUTF8String:pText];
if(_systemControl.textField.hidden == YES) {
setInactiveText(pText);
if(strlen(pText) == 0)
const char* text = getText();
if(_systemControl.textField.hidden == YES)
{
setInactiveText(text);
if(strlen(text) == 0)
{
_label->setVisible(false);
_labelPlaceHolder->setVisible(true);
@ -538,9 +529,26 @@ void EditBoxImplIOS::setText(const char* pText)
}
}
void EditBoxImplIOS::setText(const char* text)
{
NSString* nsText =[NSString stringWithUTF8String:text];
if ([nsText compare:_systemControl.textField.text] != NSOrderedSame)
{
_systemControl.textField.text = nsText;
}
refreshInactiveText();
}
NSString* removeSiriString(NSString* str)
{
NSString* siriString = @"\xef\xbf\xbc";
return [str stringByReplacingOccurrencesOfString:siriString withString:@""];
}
const char* EditBoxImplIOS::getText(void)
{
return [_systemControl.textField.text UTF8String];
return [removeSiriString(_systemControl.textField.text) UTF8String];
}
void EditBoxImplIOS::setPlaceHolder(const char* pText)

View File

@ -33,9 +33,12 @@
static std::function<Layer*()> createFunctions[] = {
CL(ActionRotateBy3D),
CL(ActionManual),
CL(ActionMove),
CL(ActionRotate),
CL(ActionRotateBy3D),
CL(ActionScale),
CL(ActionSkew),
CL(ActionRotationalSkew),
@ -501,6 +504,31 @@ std::string ActionRotate::subtitle() const
return "RotateTo / RotateBy";
}
//------------------------------------------------------------------
//
// ActionRotateBy3D
//
//------------------------------------------------------------------
void ActionRotateBy3D::onEnter()
{
ActionsDemo::onEnter();
centerSprites(3);
auto actionBy1 = RotateBy::create(4, Vertex3F(360, 0, 0));
auto actionBy2 = RotateBy::create(4, Vertex3F(0, 360, 0));
auto actionBy3 = RotateBy::create(4 ,Vertex3F(0, 0, 360));
_tamara->runAction( Sequence::create(actionBy1, actionBy1->reverse(), nullptr));
_grossini->runAction( Sequence::create(actionBy2, actionBy2->reverse(), nullptr));
_kathia->runAction( Sequence::create(actionBy3, actionBy3->reverse(), nullptr));
}
std::string ActionRotateBy3D::subtitle() const
{
return "RotateBy in 3D";
}
//------------------------------------------------------------------
//
// ActionJump

View File

@ -49,7 +49,7 @@ protected:
Sprite* _tamara;
Sprite* _kathia;
public:
virtual void onEnter();
virtual void onEnter() override;
virtual void onExit();
void centerSprites(unsigned int numberOfSprites);
@ -67,7 +67,7 @@ class ActionManual : public ActionsDemo
public:
CREATE_FUNC(ActionManual);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -76,7 +76,7 @@ class ActionMove : public ActionsDemo
public:
CREATE_FUNC(ActionMove);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -85,7 +85,7 @@ class ActionScale : public ActionsDemo
public:
CREATE_FUNC(ActionScale);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -94,7 +94,7 @@ class ActionSkew : public ActionsDemo
public:
CREATE_FUNC(ActionSkew);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -103,7 +103,7 @@ class ActionRotationalSkew : public ActionsDemo
public:
CREATE_FUNC(ActionRotationalSkew);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -112,7 +112,7 @@ class ActionRotationalSkewVSStandardSkew : public ActionsDemo
public:
CREATE_FUNC(ActionRotationalSkewVSStandardSkew);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -121,7 +121,7 @@ class ActionSkewRotateScale : public ActionsDemo
public:
CREATE_FUNC(ActionSkewRotateScale);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -130,7 +130,16 @@ class ActionRotate : public ActionsDemo
public:
CREATE_FUNC(ActionRotate);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
class ActionRotateBy3D : public ActionsDemo
{
public:
CREATE_FUNC(ActionRotateBy3D);
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -139,7 +148,7 @@ class ActionJump : public ActionsDemo
public:
CREATE_FUNC(ActionJump);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -148,7 +157,7 @@ class ActionBezier : public ActionsDemo
public:
CREATE_FUNC(ActionBezier);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -157,7 +166,7 @@ class ActionBlink : public ActionsDemo
public:
CREATE_FUNC(ActionBlink);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -166,7 +175,7 @@ class ActionFade : public ActionsDemo
public:
CREATE_FUNC(ActionFade);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -175,7 +184,7 @@ class ActionTint : public ActionsDemo
public:
CREATE_FUNC(ActionTint);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -184,7 +193,7 @@ class ActionAnimate : public ActionsDemo
public:
CREATE_FUNC(ActionAnimate);
virtual void onEnter();
virtual void onEnter() override;
virtual void onExit();
virtual std::string title() const override;
virtual std::string subtitle() const override;
@ -195,7 +204,7 @@ class ActionSequence : public ActionsDemo
public:
CREATE_FUNC(ActionSequence);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -204,7 +213,7 @@ class ActionSequence2 : public ActionsDemo
public:
CREATE_FUNC(ActionSequence2);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
void callback1();
@ -217,7 +226,7 @@ class ActionSpawn : public ActionsDemo
public:
CREATE_FUNC(ActionSpawn);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -226,7 +235,7 @@ class ActionReverse : public ActionsDemo
public:
CREATE_FUNC(ActionReverse);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -235,7 +244,7 @@ class ActionRepeat : public ActionsDemo
public:
CREATE_FUNC(ActionRepeat);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -244,7 +253,7 @@ class ActionDelayTime : public ActionsDemo
public:
CREATE_FUNC(ActionDelayTime);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -253,7 +262,7 @@ class ActionReverseSequence : public ActionsDemo
public:
CREATE_FUNC(ActionReverseSequence);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -262,7 +271,7 @@ class ActionReverseSequence2 : public ActionsDemo
public:
CREATE_FUNC(ActionReverseSequence2);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -271,7 +280,7 @@ class ActionOrbit : public ActionsDemo
public:
CREATE_FUNC(ActionOrbit);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -280,7 +289,7 @@ class ActionRemoveSelf : public ActionsDemo
public:
CREATE_FUNC(ActionRemoveSelf);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -289,7 +298,7 @@ class ActionRepeatForever : public ActionsDemo
public:
CREATE_FUNC(ActionRepeatForever);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
void repeatForever(Node* pTarget);
@ -300,7 +309,7 @@ class ActionRotateToRepeat : public ActionsDemo
public:
CREATE_FUNC(ActionRotateToRepeat);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -309,7 +318,7 @@ class ActionRotateJerk : public ActionsDemo
public:
CREATE_FUNC(ActionRotateJerk);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
};
@ -318,7 +327,7 @@ class ActionCallFuncN : public ActionsDemo
public:
CREATE_FUNC(ActionCallFuncN);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
void callback(Node* sender);
@ -329,7 +338,7 @@ class ActionCallFuncND : public ActionsDemo
public:
CREATE_FUNC(ActionCallFuncND);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
void doRemoveFromParentAndCleanup(Node* sender, bool cleanup);
@ -340,7 +349,7 @@ class ActionCallFuncO : public ActionsDemo
public:
CREATE_FUNC(ActionCallFuncO);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
void callback(Node* object, bool cleanup);
@ -351,7 +360,7 @@ class ActionCallFunction : public ActionsDemo
public:
CREATE_FUNC(ActionCallFunction);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
void callback1();
@ -365,7 +374,7 @@ class ActionFollow : public ActionsDemo
public:
CREATE_FUNC(ActionFollow);
virtual void onEnter();
virtual void onEnter() override;
virtual void draw();
virtual std::string subtitle() const override;
@ -381,7 +390,7 @@ class ActionTargeted : public ActionsDemo
public:
CREATE_FUNC(ActionTargeted);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
@ -391,7 +400,7 @@ class ActionTargetedReverse : public ActionsDemo
public:
CREATE_FUNC(ActionTargetedReverse);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
@ -401,7 +410,7 @@ class ActionStacked : public ActionsDemo
public:
CREATE_FUNC(ActionStacked);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
virtual void addNewSpriteWithCoords(Point p);
@ -443,7 +452,7 @@ public:
virtual ~ActionCatmullRomStacked();
virtual void draw();
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
protected:
@ -464,7 +473,7 @@ public:
virtual ~ActionCardinalSplineStacked();
virtual void draw();
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
private:
@ -481,7 +490,7 @@ class Issue1305 : public ActionsDemo
public:
CREATE_FUNC(Issue1305);
virtual void onEnter();
virtual void onEnter() override;
virtual void onExit();
void log(Node* sender);
void addSprite(float dt);
@ -496,7 +505,7 @@ class Issue1305_2 : public ActionsDemo
public:
CREATE_FUNC(Issue1305_2);
virtual void onEnter();
virtual void onEnter() override;
void printLog1();
void printLog2();
void printLog3();
@ -510,7 +519,7 @@ class Issue1288 : public ActionsDemo
public:
CREATE_FUNC(Issue1288);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
@ -520,7 +529,7 @@ class Issue1288_2 : public ActionsDemo
public:
CREATE_FUNC(Issue1288_2);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
@ -530,7 +539,7 @@ class Issue1327 : public ActionsDemo
public:
CREATE_FUNC(Issue1327);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
virtual std::string title() const override;
void logSprRotation(Sprite* sender);
@ -543,7 +552,7 @@ public:
void incrementInteger();
void incrementIntegerCallback(void* data);
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
virtual std::string title() const override;
private:
@ -557,7 +566,7 @@ public:
~ActionCatmullRom();
virtual void onEnter();
virtual void onEnter() override;
virtual void draw();
virtual std::string subtitle() const override;
virtual std::string title() const override;
@ -578,7 +587,7 @@ public:
~ActionCardinalSpline();
virtual void onEnter();
virtual void onEnter() override;
virtual void draw();
virtual std::string subtitle() const override;
virtual std::string title() const override;
@ -598,7 +607,7 @@ public:
PauseResumeActions();
virtual ~PauseResumeActions();
virtual void onEnter();
virtual void onEnter() override;
virtual std::string subtitle() const override;
virtual std::string title() const override;

View File

@ -1368,11 +1368,11 @@ BMFontOneAtlas::BMFontOneAtlas()
{
auto s = Director::getInstance()->getWinSize();
auto label1 = LabelBMFont::create("This is Helvetica", "fonts/helvetica-32.fnt", kLabelAutomaticWidth, TextHAlignment::LEFT, Point::ZERO);
auto label1 = LabelBMFont::create("This is Helvetica", "fonts/helvetica-32.fnt");
addChild(label1);
label1->setPosition(Point(s.width/2, s.height/3*2));
auto label2 = LabelBMFont::create("And this is Geneva", "fonts/geneva-32.fnt", kLabelAutomaticWidth, TextHAlignment::LEFT, Point(0, 128));
auto label2 = LabelBMFont::create("And this is Geneva", "fonts/geneva-32.fnt", 0, TextHAlignment::LEFT, Point(0, 128));
addChild(label2);
label2->setPosition(Point(s.width/2, s.height/3*1));
}

View File

@ -1 +1 @@
dc22a9c6f7fee22f731cfe145212770b9a43b393
d381f5336bd2e06ba65eb51a5204c12eebe49c4e

View File

@ -731,6 +731,24 @@ public:
virtual std::string subtitle() const override;
};
class SpriteCullTest1 : public SpriteTestDemo
{
public:
CREATE_FUNC(SpriteCullTest1);
SpriteCullTest1();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class SpriteCullTest2 : public SpriteTestDemo
{
public:
CREATE_FUNC(SpriteCullTest2);
SpriteCullTest2();
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class SpriteTestScene : public TestScene
{
public:

View File

@ -233,6 +233,47 @@ void TemplateVectorTest::onEnter()
vec6.eraseObject(vec6.at(2));
CCASSERT(vec6.at(2)->getTag() == 1013, "");
vec6.clear();
auto objA = Node::create(); // retain count is 1
auto objB = Node::create();
auto objC = Node::create();
{
Vector<Node*> array1;
Vector<Node*> array2;
// push back objA 3 times
array1.pushBack(objA); // retain count is 2
array1.pushBack(objA); // retain count is 3
array1.pushBack(objA); // retain count is 4
array2.pushBack(objA); // retain count is 5
array2.pushBack(objB);
array2.pushBack(objC);
for (auto obj : array1) {
array2.eraseObject(obj);
}
CCASSERT(objA->getReferenceCount() == 4, "");
}
CCASSERT(objA->getReferenceCount() == 1, "");
{
Vector<Node*> array1;
// push back objA 3 times
array1.pushBack(objA); // retain count is 2
array1.pushBack(objA); // retain count is 3
array1.pushBack(objA); // retain count is 4
CCASSERT(objA->getReferenceCount() == 4, "");
array1.eraseObject(objA, true); // Remove all occurrences in the Vector.
CCASSERT(objA->getReferenceCount() == 1, "");
array1.pushBack(objA); // retain count is 2
array1.pushBack(objA); // retain count is 3
array1.pushBack(objA); // retain count is 4
array1.eraseObject(objA, false);
CCASSERT(objA->getReferenceCount() == 3, ""); // Only remove the first occurrence in the Vector.
}
// Check the retain count in vec7
CCASSERT(vec7.size() == 20, "");

View File

@ -1 +1 @@
dd9aa6e60b1d16d112113a950f81e7ab98f71eb6
4424247ae9eeee1aa36e04fe3b2ece70024a8987