diff --git a/cocos2dx/actions/CCActionInterval.cpp b/cocos2dx/actions/CCActionInterval.cpp index 0e0ad4778f..71fce8088f 100644 --- a/cocos2dx/actions/CCActionInterval.cpp +++ b/cocos2dx/actions/CCActionInterval.cpp @@ -1616,6 +1616,7 @@ FadeIn* FadeIn::clone() const { // no copy constructor auto a = new FadeIn(); + a->initWithDuration(_duration); a->autorelease(); return a; } diff --git a/cocos2dx/sprite_nodes/CCSprite.cpp b/cocos2dx/sprite_nodes/CCSprite.cpp index 9614f9eaa2..a20cbf3461 100644 --- a/cocos2dx/sprite_nodes/CCSprite.cpp +++ b/cocos2dx/sprite_nodes/CCSprite.cpp @@ -550,25 +550,12 @@ void Sprite::draw(void) CCAssert(!_batchNode, "If Sprite is being rendered by SpriteBatchNode, Sprite#draw SHOULD NOT be called"); + CC_NODE_DRAW_SETUP(); + ccGLBlendFunc( _blendFunc.src, _blendFunc.dst ); - if (_texture != NULL) - { - CC_NODE_DRAW_SETUP(); - ccGLBindTexture2D( _texture->getName() ); - ccGLEnableVertexAttribs( kVertexAttribFlag_PosColorTex ); - } - else - { - // If the texture is invalid, uses the PositionColor shader instead. - // TODO: PostionTextureColor shader should support empty texture. In that way, we could get rid of next three lines. - GLProgram* prog = ShaderCache::sharedShaderCache()->programForKey(kShader_PositionColor); - prog->use(); - prog->setUniformsForBuiltins(); - - ccGLBindTexture2D(0); - ccGLEnableVertexAttribs( kVertexAttribFlag_Position | kVertexAttribFlag_Color ); - } + ccGLBindTexture2D( _texture->getName() ); + ccGLEnableVertexAttribs( kVertexAttribFlag_PosColorTex ); #define kQuadSize sizeof(_quad.bl) #ifdef EMSCRIPTEN @@ -582,12 +569,9 @@ void Sprite::draw(void) int diff = offsetof( V3F_C4B_T2F, vertices); glVertexAttribPointer(kVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*) (offset + diff)); - if (_texture != NULL) - { - // texCoods - diff = offsetof( V3F_C4B_T2F, texCoords); - glVertexAttribPointer(kVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); - } + // texCoods + diff = offsetof( V3F_C4B_T2F, texCoords); + glVertexAttribPointer(kVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff)); // color diff = offsetof( V3F_C4B_T2F, colors); @@ -1083,6 +1067,26 @@ void Sprite::updateBlendFunc(void) } } +/* + * This array is the data of a white image with 2 by 2 dimension. + * It's used for creating a default texture when sprite's texture is set to NULL. + * Supposing codes as follows: + * + * auto sp = new Sprite(); + * sp->init(); // Texture was set to NULL, in order to make opacity and color to work correctly, we need to create a 2x2 white texture. + * + * The test is in "TestCpp/SpriteTest/Sprite without texture". + */ +static unsigned char cc_2x2_white_image[] = { + // RGBA8888 + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF +}; + +#define CC_2x2_WHITE_IMAGE_KEY "cc_2x2_white_image" + void Sprite::setTexture(Texture2D *texture) { // If batchnode, then texture id should be the same @@ -1090,6 +1094,24 @@ void Sprite::setTexture(Texture2D *texture) // accept texture==nil as argument CCAssert( !texture || dynamic_cast(texture), "setTexture expects a Texture2D. Invalid argument"); + if (NULL == texture) + { + // Gets the texture by key firstly. + texture = TextureCache::sharedTextureCache()->textureForKey(CC_2x2_WHITE_IMAGE_KEY); + + // If texture wasn't in cache, create it from RAW data. + if (NULL == texture) + { + Image* image = new Image(); + bool isOK = image->initWithImageData(cc_2x2_white_image, sizeof(cc_2x2_white_image), Image::kFmtRawData, 2, 2, 8); + if (isOK) { + texture = TextureCache::sharedTextureCache()->addUIImage(image, CC_2x2_WHITE_IMAGE_KEY); + } + + CC_SAFE_RELEASE(image); + } + } + if (!_batchNode && _texture != texture) { CC_SAFE_RETAIN(texture); diff --git a/cocos2dx/textures/CCTextureCache.cpp b/cocos2dx/textures/CCTextureCache.cpp index 8aee499d15..4e5e1081eb 100644 --- a/cocos2dx/textures/CCTextureCache.cpp +++ b/cocos2dx/textures/CCTextureCache.cpp @@ -597,7 +597,7 @@ void TextureCache::removeTextureForKey(const char *textureKeyName) Texture2D* TextureCache::textureForKey(const char* key) { - return (Texture2D*)_textures->objectForKey(FileUtils::sharedFileUtils()->fullPathForFilename(key)); + return static_cast(_textures->objectForKey(FileUtils::sharedFileUtils()->fullPathForFilename(key))); } void TextureCache::reloadAllTextures()