2010-08-02 10:58:00 +08:00
/****************************************************************************
2012-06-08 14:11:48 +08:00
Copyright ( c ) 2010 - 2012 cocos2d - x . org
2011-03-19 14:45:51 +08:00
Copyright ( c ) 2008 Apple Inc . All Rights Reserved .
2010-08-02 10:58:00 +08:00
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-15 18:15:00 +08:00
/*
* Support for RGBA_4_4_4_4 and RGBA_5_5_5_1 was copied from :
* https : //devforums.apple.com/message/37855#37855 by a1studmuffin
*/
2010-08-02 10:58:00 +08:00
# include "CCTexture2D.h"
2010-07-15 18:15:00 +08:00
# include "ccConfig.h"
# include "ccMacros.h"
2010-07-20 14:29:18 +08:00
# include "CCConfiguration.h"
2012-06-19 16:20:46 +08:00
# include "platform/CCImage.h"
2010-12-30 17:30:11 +08:00
# include "CCGL.h"
2013-10-14 14:01:00 +08:00
# include "ccUtils.h"
# include "CCPlatformMacros.h"
2011-11-28 17:28:43 +08:00
# include "CCDirector.h"
2013-10-14 14:01:00 +08:00
# include "CCGLProgram.h"
# include "ccGLStateCache.h"
# include "CCShaderCache.h"
2010-08-31 16:53:25 +08:00
2012-06-06 10:06:51 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
2011-04-06 16:29:58 +08:00
# include "CCTextureCache.h"
2011-01-10 17:54:44 +08:00
# endif
2012-04-18 18:43:45 +08:00
NS_CC_BEGIN
2010-07-15 18:15:00 +08:00
2013-08-02 14:10:23 +08:00
namespace {
typedef Texture2D : : PixelFormatInfoMap : : value_type PixelFormatInfoMapValue ;
static const PixelFormatInfoMapValue TexturePixelFormatInfoTablesValue [ ] =
{
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : BGRA8888 , Texture2D : : PixelFormatInfo ( GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE , 32 , false , true ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : RGBA8888 , Texture2D : : PixelFormatInfo ( GL_RGBA , GL_RGBA , GL_UNSIGNED_BYTE , 32 , false , true ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : RGBA4444 , Texture2D : : PixelFormatInfo ( GL_RGBA , GL_RGBA , GL_UNSIGNED_SHORT_4_4_4_4 , 16 , false , true ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : RGB5A1 , Texture2D : : PixelFormatInfo ( GL_RGBA , GL_RGBA , GL_UNSIGNED_SHORT_5_5_5_1 , 16 , false , true ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : RGB565 , Texture2D : : PixelFormatInfo ( GL_RGB , GL_RGB , GL_UNSIGNED_SHORT_5_6_5 , 16 , false , false ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : RGB888 , Texture2D : : PixelFormatInfo ( GL_RGB , GL_RGB , GL_UNSIGNED_BYTE , 24 , false , false ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : A8 , Texture2D : : PixelFormatInfo ( GL_ALPHA , GL_ALPHA , GL_UNSIGNED_BYTE , 8 , false , false ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : I8 , Texture2D : : PixelFormatInfo ( GL_LUMINANCE , GL_LUMINANCE , GL_UNSIGNED_BYTE , 8 , false , false ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : AI88 , Texture2D : : PixelFormatInfo ( GL_LUMINANCE_ALPHA , GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE , 16 , false , true ) ) ,
# ifdef GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : PVRTC2 , Texture2D : : PixelFormatInfo ( GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG , 0xFFFFFFFF , 0xFFFFFFFF , 2 , true , false ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : PVRTC2A , Texture2D : : PixelFormatInfo ( GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG , 0xFFFFFFFF , 0xFFFFFFFF , 2 , true , true ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : PVRTC4 , Texture2D : : PixelFormatInfo ( GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG , 0xFFFFFFFF , 0xFFFFFFFF , 4 , true , false ) ) ,
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : PVRTC4A , Texture2D : : PixelFormatInfo ( GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG , 0xFFFFFFFF , 0xFFFFFFFF , 4 , true , true ) ) ,
# endif
# ifdef GL_ETC1_RGB8_OES
2013-08-06 11:34:48 +08:00
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : ETC , Texture2D : : PixelFormatInfo ( GL_ETC1_RGB8_OES , 0xFFFFFFFF , 0xFFFFFFFF , 24 , true , false ) ) ,
2013-08-02 14:10:23 +08:00
# endif
2013-08-08 14:11:22 +08:00
# ifdef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
2013-08-09 12:54:05 +08:00
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : S3TC_DXT1 , Texture2D : : PixelFormatInfo ( GL_COMPRESSED_RGBA_S3TC_DXT1_EXT , 0xFFFFFFFF , 0xFFFFFFFF , 4 , true , false ) ) ,
2013-08-08 14:11:22 +08:00
# endif
# ifdef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
2013-08-09 12:54:05 +08:00
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : S3TC_DXT3 , Texture2D : : PixelFormatInfo ( GL_COMPRESSED_RGBA_S3TC_DXT3_EXT , 0xFFFFFFFF , 0xFFFFFFFF , 8 , true , false ) ) ,
2013-08-08 14:11:22 +08:00
# endif
# ifdef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
2013-08-09 12:54:05 +08:00
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : S3TC_DXT5 , Texture2D : : PixelFormatInfo ( GL_COMPRESSED_RGBA_S3TC_DXT5_EXT , 0xFFFFFFFF , 0xFFFFFFFF , 8 , true , false ) ) ,
2013-08-08 14:11:22 +08:00
# endif
2013-08-16 11:02:44 +08:00
# ifdef GL_ATC_RGB_AMD
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : ATC_RGB , Texture2D : : PixelFormatInfo ( GL_ATC_RGB_AMD ,
0xFFFFFFFF , 0xFFFFFFFF , 4 , true , false ) ) ,
# endif
# ifdef GL_ATC_RGBA_EXPLICIT_ALPHA_AMD
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : ATC_EXPLICIT_ALPHA , Texture2D : : PixelFormatInfo ( GL_ATC_RGBA_EXPLICIT_ALPHA_AMD ,
0xFFFFFFFF , 0xFFFFFFFF , 8 , true , false ) ) ,
# endif
# ifdef GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : ATC_INTERPOLATED_ALPHA , Texture2D : : PixelFormatInfo ( GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD ,
0xFFFFFFFF , 0xFFFFFFFF , 8 , true , false ) ) ,
# endif
2013-08-02 14:10:23 +08:00
} ;
}
2010-07-15 18:15:00 +08:00
//CLASS IMPLEMENTATIONS:
2013-08-02 14:10:23 +08:00
//The PixpelFormat corresponding information
const Texture2D : : PixelFormatInfoMap Texture2D : : _pixelFormatInfoTables ( TexturePixelFormatInfoTablesValue ,
TexturePixelFormatInfoTablesValue + sizeof ( TexturePixelFormatInfoTablesValue ) / sizeof ( TexturePixelFormatInfoTablesValue [ 0 ] ) ) ;
2010-07-15 18:15:00 +08:00
// If the image has alpha, you can create RGBA8 (32-bit) or RGBA4 (16-bit) or RGB5A1 (16-bit)
// Default is: RGBA8888 (32-bit textures)
2013-07-26 04:36:19 +08:00
static Texture2D : : PixelFormat g_defaultAlphaPixelFormat = Texture2D : : PixelFormat : : DEFAULT ;
2010-07-15 18:15:00 +08:00
2013-07-29 14:07:57 +08:00
static bool _PVRHaveAlphaPremultiplied = false ;
2011-12-20 14:59:15 +08:00
2013-07-17 17:12:04 +08:00
//////////////////////////////////////////////////////////////////////////
//conventer function
// IIIIIIII -> RRRRRRRRGGGGGGGGGBBBBBBBB
2013-11-05 08:31:36 +08:00
void Texture2D : : convertI8ToRGB888 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 ; i < dataLen ; + + i )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i ] ; //R
* outData + + = data [ i ] ; //G
* outData + + = data [ i ] ; //B
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIIIAAAAAAAA -> RRRRRRRRGGGGGGGGBBBBBBBB
2013-11-05 08:31:36 +08:00
void Texture2D : : convertAI88ToRGB888 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 1 ; i < l ; i + = 2 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i ] ; //R
* outData + + = data [ i ] ; //G
* outData + + = data [ i ] ; //B
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIII -> RRRRRRRRGGGGGGGGGBBBBBBBBAAAAAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertI8ToRGBA8888 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 ; i < dataLen ; + + i )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i ] ; //R
* outData + + = data [ i ] ; //G
* outData + + = data [ i ] ; //B
* outData + + = 0xFF ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIIIAAAAAAAA -> RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertAI88ToRGBA8888 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 1 ; i < l ; i + = 2 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i ] ; //R
* outData + + = data [ i ] ; //G
* outData + + = data [ i ] ; //B
* outData + + = data [ i + 1 ] ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIII -> RRRRRGGGGGGBBBBB
2013-11-05 08:31:36 +08:00
void Texture2D : : convertI8ToRGB565 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 ; i < dataLen ; + + i )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F8 ) < < 8 //R
| ( data [ i ] & 0x00FC ) < < 3 //G
| ( data [ i ] & 0x00F8 ) > > 3 ; //B
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIIIAAAAAAAA -> RRRRRGGGGGGBBBBB
2013-11-05 08:31:36 +08:00
void Texture2D : : convertAI88ToRGB565 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 , l = dataLen - 1 ; i < l ; i + = 2 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F8 ) < < 8 //R
| ( data [ i ] & 0x00FC ) < < 3 //G
| ( data [ i ] & 0x00F8 ) > > 3 ; //B
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIII -> RRRRGGGGBBBBAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertI8ToRGBA4444 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 ; i < dataLen ; + + i )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F0 ) < < 8 //R
| ( data [ i ] & 0x00F0 ) < < 4 //G
| ( data [ i ] & 0x00F0 ) //B
| 0x000F ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIIIAAAAAAAA -> RRRRGGGGBBBBAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertAI88ToRGBA4444 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 , l = dataLen - 1 ; i < l ; i + = 2 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F0 ) < < 8 //R
| ( data [ i ] & 0x00F0 ) < < 4 //G
| ( data [ i ] & 0x00F0 ) //B
| ( data [ i + 1 ] & 0x00F0 ) > > 4 ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIII -> RRRRRGGGGGBBBBBA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertI8ToRGB5A1 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 ; i < dataLen ; + + i )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F8 ) < < 8 //R
| ( data [ i ] & 0x00F8 ) < < 3 //G
| ( data [ i ] & 0x00F8 ) > > 2 //B
| 0x0001 ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIIIAAAAAAAA -> RRRRRGGGGGBBBBBA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertAI88ToRGB5A1 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 , l = dataLen - 1 ; i < l ; i + = 2 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F8 ) < < 8 //R
| ( data [ i ] & 0x00F8 ) < < 3 //G
| ( data [ i ] & 0x00F8 ) > > 2 //B
| ( data [ i + 1 ] & 0x0080 ) > > 7 ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIII -> IIIIIIIIAAAAAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertI8ToAI88 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 ; i < dataLen ; + + i )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = 0xFF00 //A
| data [ i ] ; //I
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIIIAAAAAAAA -> AAAAAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertAI88ToA8 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 1 ; i < dataLen ; i + = 2 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i ] ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// IIIIIIIIAAAAAAAA -> IIIIIIII
2013-11-05 08:31:36 +08:00
void Texture2D : : convertAI88ToI8 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 1 ; i < l ; i + = 2 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i ] ; //R
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBB -> RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGB888ToRGBA8888 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 2 ; i < l ; i + = 3 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i ] ; //R
* outData + + = data [ i + 1 ] ; //G
* outData + + = data [ i + 2 ] ; //B
* outData + + = 0xFF ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> RRRRRRRRGGGGGGGGBBBBBBBB
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGBA8888ToRGB888 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 3 ; i < l ; i + = 4 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i ] ; //R
* outData + + = data [ i + 1 ] ; //G
* outData + + = data [ i + 2 ] ; //B
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBB -> RRRRRGGGGGGBBBBB
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGB888ToRGB565 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 , l = dataLen - 2 ; i < l ; i + = 3 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F8 ) < < 8 //R
| ( data [ i + 1 ] & 0x00FC ) < < 3 //G
| ( data [ i + 2 ] & 0x00F8 ) > > 3 ; //B
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> RRRRRGGGGGGBBBBB
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGBA8888ToRGB565 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 , l = dataLen - 3 ; i < l ; i + = 4 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F8 ) < < 8 //R
| ( data [ i + 1 ] & 0x00FC ) < < 3 //G
| ( data [ i + 2 ] & 0x00F8 ) > > 3 ; //B
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBB -> IIIIIIII
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGB888ToI8 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 2 ; i < l ; i + = 3 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = ( data [ i ] * 299 + data [ i + 1 ] * 587 + data [ i + 2 ] * 114 + 500 ) / 1000 ; //I = (R*299 + G*587 + B*114 + 500) / 1000
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> IIIIIIII
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGBA8888ToI8 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 3 ; i < l ; i + = 4 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = ( data [ i ] * 299 + data [ i + 1 ] * 587 + data [ i + 2 ] * 114 + 500 ) / 1000 ; //I = (R*299 + G*587 + B*114 + 500) / 1000
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> AAAAAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGBA8888ToA8 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 3 ; i < l ; i + = 4 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = data [ i + 3 ] ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBB -> IIIIIIIIAAAAAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGB888ToAI88 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 2 ; i < l ; i + = 3 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = ( data [ i ] * 299 + data [ i + 1 ] * 587 + data [ i + 2 ] * 114 + 500 ) / 1000 ; //I = (R*299 + G*587 + B*114 + 500) / 1000
* outData + + = 0xFF ;
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> IIIIIIIIAAAAAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGBA8888ToAI88 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
for ( int i = 0 , l = dataLen - 3 ; i < l ; i + = 4 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* outData + + = ( data [ i ] * 299 + data [ i + 1 ] * 587 + data [ i + 2 ] * 114 + 500 ) / 1000 ; //I = (R*299 + G*587 + B*114 + 500) / 1000
* outData + + = data [ i + 3 ] ;
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBB -> RRRRGGGGBBBBAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGB888ToRGBA4444 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 , l = dataLen - 2 ; i < l ; i + = 3 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( ( data [ i ] & 0x00F0 ) < < 8 //R
| ( data [ i + 1 ] & 0x00F0 ) < < 4 //G
| ( data [ i + 2 ] & 0xF0 ) //B
| 0x0F ) ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> RRRRGGGGBBBBAAAA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGBA8888ToRGBA4444 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
for ( int i = 0 , l = dataLen - 3 ; i < l ; i + = 4 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F0 ) < < 8 //R
| ( data [ i + 1 ] & 0x00F0 ) < < 4 //G
| ( data [ i + 2 ] & 0xF0 ) //B
| ( data [ i + 3 ] & 0xF0 ) > > 4 ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBB -> RRRRRGGGGGBBBBBA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGB888ToRGB5A1 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
2013-11-05 08:31:36 +08:00
for ( long i = 0 , l = dataLen - 2 ; i < l ; i + = 3 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F8 ) < < 8 //R
| ( data [ i + 1 ] & 0x00F8 ) < < 3 //G
| ( data [ i + 2 ] & 0x00F8 ) > > 2 //B
| 0x01 ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// RRRRRRRRGGGGGGGGBBBBBBBB -> RRRRRGGGGGBBBBBA
2013-11-05 08:31:36 +08:00
void Texture2D : : convertRGBA8888ToRGB5A1 ( const unsigned char * data , long dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-08-01 15:53:52 +08:00
unsigned short * out16 = ( unsigned short * ) outData ;
2013-11-05 08:31:36 +08:00
for ( long i = 0 , l = dataLen - 2 ; i < l ; i + = 4 )
2013-07-19 15:37:54 +08:00
{
2013-08-01 15:53:52 +08:00
* out16 + + = ( data [ i ] & 0x00F8 ) < < 8 //R
| ( data [ i + 1 ] & 0x00F8 ) < < 3 //G
| ( data [ i + 2 ] & 0x00F8 ) > > 2 //B
| ( data [ i + 3 ] & 0x0080 ) > > 7 ; //A
2013-07-19 15:37:54 +08:00
}
2013-07-17 17:12:04 +08:00
}
// conventer function end
//////////////////////////////////////////////////////////////////////////
2013-06-20 14:13:12 +08:00
Texture2D : : Texture2D ( )
2013-07-29 14:07:57 +08:00
: _pixelFormat ( Texture2D : : PixelFormat : : DEFAULT )
2013-06-15 14:03:30 +08:00
, _pixelsWide ( 0 )
, _pixelsHigh ( 0 )
, _name ( 0 )
, _maxS ( 0.0 )
, _maxT ( 0.0 )
, _hasPremultipliedAlpha ( false )
, _hasMipmaps ( false )
, _shaderProgram ( NULL )
2010-07-15 18:15:00 +08:00
{
}
2013-06-20 14:13:12 +08:00
Texture2D : : ~ Texture2D ( )
2010-07-15 18:15:00 +08:00
{
2012-06-06 10:06:51 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
2013-11-08 16:47:33 +08:00
VolatileTextureMgr : : removeTexture ( this ) ;
2011-01-10 17:54:44 +08:00
# endif
2013-08-22 11:05:06 +08:00
CCLOGINFO ( " deallocing Texture2D: %p - id=%u " , this , _name ) ;
2013-06-15 14:03:30 +08:00
CC_SAFE_RELEASE ( _shaderProgram ) ;
2012-03-14 14:55:17 +08:00
2013-06-15 14:03:30 +08:00
if ( _name )
2012-04-19 14:35:52 +08:00
{
2013-07-26 09:42:53 +08:00
GL : : deleteTexture ( _name ) ;
2012-04-19 14:35:52 +08:00
}
2010-07-15 18:15:00 +08:00
}
2013-07-25 19:52:44 +08:00
Texture2D : : PixelFormat Texture2D : : getPixelFormat ( ) const
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
return _pixelFormat ;
2010-07-15 18:15:00 +08:00
}
2013-11-05 08:31:36 +08:00
long Texture2D : : getPixelsWide ( ) const
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
return _pixelsWide ;
2010-07-15 18:15:00 +08:00
}
2013-11-05 08:31:36 +08:00
long Texture2D : : getPixelsHigh ( ) const
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
return _pixelsHigh ;
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
GLuint Texture2D : : getName ( ) const
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
return _name ;
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
Size Texture2D : : getContentSize ( ) const
2010-07-15 18:15:00 +08:00
{
2013-06-20 14:13:12 +08:00
Size ret ;
2013-06-15 14:03:30 +08:00
ret . width = _contentSize . width / CC_CONTENT_SCALE_FACTOR ( ) ;
ret . height = _contentSize . height / CC_CONTENT_SCALE_FACTOR ( ) ;
2012-04-08 22:37:58 +08:00
return ret ;
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
const Size & Texture2D : : getContentSizeInPixels ( )
2010-12-30 17:30:11 +08:00
{
2013-06-15 14:03:30 +08:00
return _contentSize ;
2010-12-30 17:30:11 +08:00
}
2013-07-23 14:05:05 +08:00
GLfloat Texture2D : : getMaxS ( ) const
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
return _maxS ;
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
void Texture2D : : setMaxS ( GLfloat maxS )
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
_maxS = maxS ;
2010-07-15 18:15:00 +08:00
}
2013-07-23 14:05:05 +08:00
GLfloat Texture2D : : getMaxT ( ) const
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
return _maxT ;
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
void Texture2D : : setMaxT ( GLfloat maxT )
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
_maxT = maxT ;
2010-07-15 18:15:00 +08:00
}
2013-07-23 14:05:05 +08:00
GLProgram * Texture2D : : getShaderProgram ( ) const
2012-03-14 14:55:17 +08:00
{
2013-06-15 14:03:30 +08:00
return _shaderProgram ;
2012-03-14 14:55:17 +08:00
}
2013-06-20 14:13:12 +08:00
void Texture2D : : setShaderProgram ( GLProgram * pShaderProgram )
2012-03-14 14:55:17 +08:00
{
2012-04-19 14:35:52 +08:00
CC_SAFE_RETAIN ( pShaderProgram ) ;
2013-06-15 14:03:30 +08:00
CC_SAFE_RELEASE ( _shaderProgram ) ;
_shaderProgram = pShaderProgram ;
2012-03-14 14:55:17 +08:00
}
2013-06-20 14:13:12 +08:00
void Texture2D : : releaseData ( void * data )
2010-12-30 17:30:11 +08:00
{
free ( data ) ;
}
2013-06-20 14:13:12 +08:00
void * Texture2D : : keepData ( void * data , unsigned int length )
2010-12-30 17:30:11 +08:00
{
2011-06-10 17:51:37 +08:00
CC_UNUSED_PARAM ( length ) ;
2012-09-17 15:02:24 +08:00
//The texture data mustn't be saved because it isn't a mutable texture.
2012-04-19 14:35:52 +08:00
return data ;
2010-12-30 17:30:11 +08:00
}
2013-07-04 08:44:41 +08:00
bool Texture2D : : hasPremultipliedAlpha ( ) const
2010-07-15 18:15:00 +08:00
{
2013-06-15 14:03:30 +08:00
return _hasPremultipliedAlpha ;
2010-07-15 18:15:00 +08:00
}
2013-11-05 08:31:36 +08:00
bool Texture2D : : initWithData ( const void * data , long dataLen , Texture2D : : PixelFormat pixelFormat , long pixelsWide , long pixelsHigh , const Size & contentSize )
2013-07-25 21:35:00 +08:00
{
2013-11-05 08:31:36 +08:00
CCASSERT ( dataLen > 0 & & pixelsWide > 0 & & pixelsHigh > 0 , " Invalid size " ) ;
2013-07-25 21:35:00 +08:00
//if data has no mipmaps, we will consider it has only one mipmap
MipmapInfo mipmap ;
mipmap . address = ( unsigned char * ) data ;
mipmap . len = dataLen ;
return initWithMipmaps ( & mipmap , 1 , pixelFormat , pixelsWide , pixelsHigh ) ;
//update information
_contentSize = contentSize ;
_maxS = contentSize . width / ( float ) ( pixelsWide ) ;
_maxT = contentSize . height / ( float ) ( pixelsHigh ) ;
}
2013-11-05 08:31:36 +08:00
bool Texture2D : : initWithMipmaps ( MipmapInfo * mipmaps , int mipmapsNum , PixelFormat pixelFormat , long pixelsWide , long pixelsHigh )
2010-07-15 18:15:00 +08:00
{
2013-07-19 15:37:54 +08:00
//the pixelFormat must be a certain value
2013-11-05 08:31:36 +08:00
CCASSERT ( pixelFormat ! = PixelFormat : : NONE & & pixelFormat ! = PixelFormat : : AUTO , " the \" pixelFormat \" param must be a certain value! " ) ;
CCASSERT ( pixelsWide > 0 & & pixelsHigh > 0 , " Invalid size " ) ;
2013-07-19 15:37:54 +08:00
2013-07-25 21:35:00 +08:00
if ( mipmapsNum < = 0 )
2013-05-19 23:53:59 +08:00
{
2013-07-25 21:35:00 +08:00
CCLOG ( " cocos2d: WARNING: mipmap number is less than 1 " ) ;
return false ;
2013-05-19 23:53:59 +08:00
}
2013-07-25 21:35:00 +08:00
2013-08-02 14:10:23 +08:00
if ( _pixelFormatInfoTables . find ( pixelFormat ) = = _pixelFormatInfoTables . end ( ) )
2013-05-19 23:53:59 +08:00
{
2013-07-25 21:35:00 +08:00
CCLOG ( " cocos2d: WARNING: unsupported pixelformat: %lx " , ( unsigned long ) pixelFormat ) ;
return false ;
2013-05-19 23:53:59 +08:00
}
2013-08-02 14:10:23 +08:00
const PixelFormatInfo & info = _pixelFormatInfoTables . at ( pixelFormat ) ;
2013-05-12 23:08:33 +08:00
2013-08-06 11:19:45 +08:00
if ( info . compressed & & ! Configuration : : getInstance ( ) - > supportsPVRTC ( )
& & ! Configuration : : getInstance ( ) - > supportsETC ( )
2013-08-16 11:02:44 +08:00
& & ! Configuration : : getInstance ( ) - > supportsS3TC ( )
& & ! Configuration : : getInstance ( ) - > supportsATITC ( ) )
2013-05-19 20:12:39 +08:00
{
2013-07-26 17:34:44 +08:00
CCLOG ( " cocos2d: WARNING: PVRTC/ETC images are not supported " ) ;
2013-07-25 21:35:00 +08:00
return false ;
2013-05-12 23:08:33 +08:00
}
2013-07-25 21:35:00 +08:00
2013-07-26 17:34:44 +08:00
//Set the row align only when mipmapsNum == 1 and the data is uncompressed
if ( mipmapsNum = = 1 & & ! info . compressed )
2013-05-19 20:12:39 +08:00
{
2013-07-25 21:35:00 +08:00
unsigned int bytesPerRow = pixelsWide * info . bpp / 8 ;
if ( bytesPerRow % 8 = = 0 )
{
glPixelStorei ( GL_UNPACK_ALIGNMENT , 8 ) ;
}
else if ( bytesPerRow % 4 = = 0 )
{
glPixelStorei ( GL_UNPACK_ALIGNMENT , 4 ) ;
}
else if ( bytesPerRow % 2 = = 0 )
{
glPixelStorei ( GL_UNPACK_ALIGNMENT , 2 ) ;
}
else
{
glPixelStorei ( GL_UNPACK_ALIGNMENT , 1 ) ;
}
} else
2012-06-08 14:11:48 +08:00
{
2013-05-12 23:08:33 +08:00
glPixelStorei ( GL_UNPACK_ALIGNMENT , 1 ) ;
2012-06-08 14:11:48 +08:00
}
2013-07-25 21:35:00 +08:00
2012-06-08 14:11:48 +08:00
2013-05-19 20:17:48 +08:00
2013-06-15 14:03:30 +08:00
glGenTextures ( 1 , & _name ) ;
2013-07-26 09:42:53 +08:00
GL : : bindTexture2D ( _name ) ;
2012-04-19 14:35:52 +08:00
2013-07-25 21:35:00 +08:00
if ( mipmapsNum = = 1 )
{
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
} else
{
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_NEAREST ) ;
}
2012-06-13 16:20:58 +08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
2012-06-08 14:11:48 +08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
2012-04-19 14:35:52 +08:00
2013-07-25 21:35:00 +08:00
CHECK_GL_ERROR_DEBUG ( ) ; // clean possible GL error
2012-04-19 14:35:52 +08:00
// Specify OpenGL texture image
2013-11-13 11:22:34 +08:00
long width = pixelsWide ;
long height = pixelsHigh ;
2013-08-16 11:02:44 +08:00
2013-07-25 21:35:00 +08:00
for ( int i = 0 ; i < mipmapsNum ; + + i )
2012-04-19 14:35:52 +08:00
{
2013-07-25 21:35:00 +08:00
unsigned char * data = mipmaps [ i ] . address ;
GLsizei datalen = mipmaps [ i ] . len ;
if ( info . compressed )
{
glCompressedTexImage2D ( GL_TEXTURE_2D , i , info . internalFormat , ( GLsizei ) width , ( GLsizei ) height , 0 , datalen , data ) ;
}
else
{
glTexImage2D ( GL_TEXTURE_2D , i , info . internalFormat , ( GLsizei ) width , ( GLsizei ) height , 0 , info . format , info . type , data ) ;
}
if ( i > 0 & & ( width ! = height | | ccNextPOT ( width ) ! = width ) )
{
2013-11-13 11:22:34 +08:00
CCLOG ( " cocos2d: Texture2D. WARNING. Mipmap level %u is not squared. Texture won't render correctly. width=%ld != height=%ld " , i , width , height ) ;
2013-07-25 21:35:00 +08:00
}
GLenum err = glGetError ( ) ;
if ( err ! = GL_NO_ERROR )
{
2013-07-27 22:06:30 +08:00
CCLOG ( " cocos2d: Texture2D: Error uploading compressed texture level: %u . glError: 0x%04X " , i , err ) ;
2013-07-25 21:35:00 +08:00
return false ;
}
width = MAX ( width > > 1 , 1 ) ;
height = MAX ( height > > 1 , 1 ) ;
2012-04-19 14:35:52 +08:00
}
2013-07-25 21:35:00 +08:00
_contentSize = Size ( ( float ) pixelsWide , ( float ) pixelsHigh ) ;
2013-06-15 14:03:30 +08:00
_pixelsWide = pixelsWide ;
_pixelsHigh = pixelsHigh ;
_pixelFormat = pixelFormat ;
2013-07-25 21:35:00 +08:00
_maxS = 1 ;
_maxT = 1 ;
2012-04-19 14:35:52 +08:00
2013-06-15 14:03:30 +08:00
_hasPremultipliedAlpha = false ;
2013-07-25 21:35:00 +08:00
_hasMipmaps = mipmapsNum > 1 ;
2012-04-19 14:35:52 +08:00
2013-09-16 20:38:03 +08:00
setShaderProgram ( ShaderCache : : getInstance ( ) - > getProgram ( GLProgram : : SHADER_NAME_POSITION_TEXTURE ) ) ;
2012-04-19 14:35:52 +08:00
return true ;
2010-07-15 18:15:00 +08:00
}
2013-07-04 08:44:41 +08:00
const char * Texture2D : : description ( void ) const
2010-07-15 18:15:00 +08:00
{
2013-11-05 08:31:36 +08:00
return String : : createWithFormat ( " <Texture2D | Name = %u | Dimensions = %ld x %ld | Coordinates = (%.2f, %.2f)> " , _name , ( long ) _pixelsWide , ( long ) _pixelsHigh , _maxS , _maxT ) - > getCString ( ) ;
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
// implementation Texture2D (Image)
2013-07-27 22:06:30 +08:00
bool Texture2D : : initWithImage ( Image * image )
2013-07-25 21:35:00 +08:00
{
2013-07-27 22:06:30 +08:00
return initWithImage ( image , PixelFormat : : NONE ) ;
2013-07-25 21:35:00 +08:00
}
2012-04-08 14:16:29 +08:00
2013-07-27 22:06:30 +08:00
bool Texture2D : : initWithImage ( Image * image , PixelFormat format )
2010-07-15 18:15:00 +08:00
{
2013-07-27 22:06:30 +08:00
if ( image = = NULL )
2012-04-19 14:35:52 +08:00
{
2013-06-20 14:13:12 +08:00
CCLOG ( " cocos2d: Texture2D. Can't create Texture. UIImage is nil " ) ;
2012-04-19 14:35:52 +08:00
return false ;
}
2013-07-19 15:37:54 +08:00
2013-07-27 22:06:30 +08:00
int imageWidth = image - > getWidth ( ) ;
int imageHeight = image - > getHeight ( ) ;
2013-07-19 15:37:54 +08:00
2013-07-12 06:24:23 +08:00
Configuration * conf = Configuration : : getInstance ( ) ;
2013-07-19 15:37:54 +08:00
2013-07-25 21:35:00 +08:00
int maxTextureSize = conf - > getMaxTextureSize ( ) ;
2012-04-24 15:02:18 +08:00
if ( imageWidth > maxTextureSize | | imageHeight > maxTextureSize )
2012-04-19 14:35:52 +08:00
{
2012-04-24 15:02:18 +08:00
CCLOG ( " cocos2d: WARNING: Image (%u x %u) is bigger than the supported %u x %u " , imageWidth , imageHeight , maxTextureSize , maxTextureSize ) ;
2013-02-04 17:38:22 +08:00
return false ;
2012-04-19 14:35:52 +08:00
}
2013-07-19 15:37:54 +08:00
2013-07-27 22:06:30 +08:00
unsigned char * tempData = image - > getData ( ) ;
Size imageSize = Size ( ( float ) imageWidth , ( float ) imageHeight ) ;
PixelFormat pixelFormat = PixelFormat : : NONE ;
PixelFormat renderFormat = image - > getRenderFormat ( ) ;
size_t tempDataLen = image - > getDataLen ( ) ;
2013-07-19 15:37:54 +08:00
2013-07-27 22:06:30 +08:00
if ( image - > getNumberOfMipmaps ( ) > 1 )
2013-07-19 15:37:54 +08:00
{
2013-07-27 22:06:30 +08:00
if ( format ! = PixelFormat : : NONE )
2013-07-25 21:35:00 +08:00
{
2013-07-27 22:06:30 +08:00
CCLOG ( " cocos2d: WARNING: This image has more than 1 mipmaps and we will not convert the data format " ) ;
2013-07-25 21:35:00 +08:00
}
2013-07-27 22:06:30 +08:00
initWithMipmaps ( image - > getMipmaps ( ) , image - > getNumberOfMipmaps ( ) , image - > getRenderFormat ( ) , imageWidth , imageHeight ) ;
2013-08-06 11:19:45 +08:00
2013-07-25 21:35:00 +08:00
return true ;
}
2013-07-27 22:06:30 +08:00
else if ( image - > isCompressed ( ) )
2013-07-19 15:37:54 +08:00
{
2013-07-27 22:06:30 +08:00
if ( format ! = PixelFormat : : NONE )
2013-07-25 21:35:00 +08:00
{
2013-07-27 22:06:30 +08:00
CCLOG ( " cocos2d: WARNING: This image is compressed and we cann't convert it for now " ) ;
2013-07-25 21:35:00 +08:00
}
2013-07-27 22:06:30 +08:00
initWithData ( tempData , tempDataLen , image - > getRenderFormat ( ) , imageWidth , imageHeight , imageSize ) ;
2013-07-25 21:35:00 +08:00
return true ;
2013-07-19 15:37:54 +08:00
}
2013-07-25 21:35:00 +08:00
else
{
// compute pixel format
2013-07-27 22:06:30 +08:00
if ( format ! = PixelFormat : : NONE )
2013-07-25 21:35:00 +08:00
{
pixelFormat = format ;
} else
{
pixelFormat = g_defaultAlphaPixelFormat ;
}
2013-07-19 15:37:54 +08:00
2013-07-25 21:35:00 +08:00
unsigned char * outTempData = NULL ;
int outTempDataLen = 0 ;
2013-07-19 15:37:54 +08:00
2013-07-25 21:35:00 +08:00
pixelFormat = convertDataToFormat ( tempData , tempDataLen , renderFormat , pixelFormat , & outTempData , & outTempDataLen ) ;
2013-07-19 15:37:54 +08:00
2013-07-25 21:35:00 +08:00
initWithData ( outTempData , outTempDataLen , pixelFormat , imageWidth , imageHeight , imageSize ) ;
2013-07-19 15:37:54 +08:00
2013-07-25 21:35:00 +08:00
if ( outTempData ! = NULL & & outTempData ! = tempData )
{
2013-07-19 15:37:54 +08:00
2013-07-25 21:35:00 +08:00
delete [ ] outTempData ;
}
2013-07-19 15:37:54 +08:00
2013-07-30 11:10:05 +08:00
// set the premultiplied tag
if ( ! image - > hasPremultipliedAlpha ( ) )
2012-04-27 15:53:29 +08:00
{
2013-07-30 11:10:05 +08:00
if ( image - > getFileType ( ) = = Image : : Format : : PVR )
{
_hasPremultipliedAlpha = _PVRHaveAlphaPremultiplied ;
} else
2012-04-27 15:53:29 +08:00
{
2013-07-30 11:10:05 +08:00
CCLOG ( " wanning: We cann't find the data is premultiplied or not, we will assume it's false. " ) ;
_hasPremultipliedAlpha = false ;
2012-04-27 15:53:29 +08:00
}
2013-07-30 11:10:05 +08:00
} else
{
_hasPremultipliedAlpha = image - > isPremultipliedAlpha ( ) ;
}
2013-07-25 21:35:00 +08:00
return true ;
}
2010-07-15 18:15:00 +08:00
}
2012-08-08 18:39:33 +08:00
2013-11-05 08:31:36 +08:00
Texture2D : : PixelFormat Texture2D : : convertI8ToFormat ( const unsigned char * data , long dataLen , PixelFormat format , unsigned char * * outData , int * outDataLen )
2013-07-19 15:37:54 +08:00
{
switch ( format )
{
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGBA8888 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen * 4 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertI8ToRGBA8888 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB888 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen * 3 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertI8ToRGB888 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB565 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen * 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertI8ToRGB565 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : AI88 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen * 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertI8ToAI88 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGBA4444 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen * 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertI8ToRGBA4444 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB5A1 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen * 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-29 17:34:33 +08:00
convertI8ToRGB5A1 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
default :
// unsupport convertion or don't need to convert
2013-07-27 22:06:30 +08:00
if ( format ! = PixelFormat : : AUTO & & format ! = PixelFormat : : I8 )
2013-07-19 15:37:54 +08:00
{
2013-07-27 22:06:30 +08:00
CCLOG ( " Can not convert image format PixelFormat::I8 to format ID:%d, we will use it's origin format PixelFormat::I8 " , format ) ;
2013-07-19 15:37:54 +08:00
}
2013-07-25 21:35:00 +08:00
2013-07-19 15:37:54 +08:00
* outData = ( unsigned char * ) data ;
* outDataLen = dataLen ;
2013-07-27 22:06:30 +08:00
return PixelFormat : : I8 ;
2013-07-19 15:37:54 +08:00
}
return format ;
}
2013-11-05 08:31:36 +08:00
Texture2D : : PixelFormat Texture2D : : convertAI88ToFormat ( const unsigned char * data , long dataLen , PixelFormat format , unsigned char * * outData , int * outDataLen )
2013-07-19 15:37:54 +08:00
{
switch ( format )
{
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGBA8888 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen * 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertAI88ToRGBA8888 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB888 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 2 * 3 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertAI88ToRGB888 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB565 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertAI88ToRGB565 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : A8 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertAI88ToA8 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : I8 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertAI88ToI8 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGBA4444 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertAI88ToRGBA4444 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB5A1 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertAI88ToRGB5A1 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
default :
// unsupport convertion or don't need to convert
2013-07-27 22:06:30 +08:00
if ( format ! = PixelFormat : : AUTO & & format ! = PixelFormat : : AI88 )
2013-07-19 15:37:54 +08:00
{
2013-07-27 22:06:30 +08:00
CCLOG ( " Can not convert image format PixelFormat::AI88 to format ID:%d, we will use it's origin format PixelFormat::AI88 " , format ) ;
2013-07-19 15:37:54 +08:00
}
* outData = ( unsigned char * ) data ;
* outDataLen = dataLen ;
2013-07-27 22:06:30 +08:00
return PixelFormat : : AI88 ;
2013-07-19 15:37:54 +08:00
break ;
}
return format ;
}
2013-11-05 08:31:36 +08:00
Texture2D : : PixelFormat Texture2D : : convertRGB888ToFormat ( const unsigned char * data , long dataLen , PixelFormat format , unsigned char * * outData , int * outDataLen )
2013-07-19 15:37:54 +08:00
{
switch ( format )
{
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGBA8888 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 3 * 4 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGB888ToRGBA8888 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB565 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 3 * 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGB888ToRGB565 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : I8 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 3 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGB888ToI8 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : AI88 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 3 * 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGB888ToAI88 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGBA4444 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 3 * 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGB888ToRGBA4444 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB5A1 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGB888ToRGB5A1 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
default :
// unsupport convertion or don't need to convert
2013-07-27 22:06:30 +08:00
if ( format ! = PixelFormat : : AUTO & & format ! = PixelFormat : : RGB888 )
2013-07-19 15:37:54 +08:00
{
2013-07-27 22:06:30 +08:00
CCLOG ( " Can not convert image format PixelFormat::RGB888 to format ID:%d, we will use it's origin format PixelFormat::RGB888 " , format ) ;
2013-07-19 15:37:54 +08:00
}
* outData = ( unsigned char * ) data ;
* outDataLen = dataLen ;
2013-07-27 22:06:30 +08:00
return PixelFormat : : RGB888 ;
2013-07-19 15:37:54 +08:00
}
return format ;
}
2013-11-05 08:31:36 +08:00
Texture2D : : PixelFormat Texture2D : : convertRGBA8888ToFormat ( const unsigned char * data , long dataLen , PixelFormat format , unsigned char * * outData , int * outDataLen )
2013-07-19 15:37:54 +08:00
{
switch ( format )
{
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB888 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 4 * 3 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGBA8888ToRGB888 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB565 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGBA8888ToRGB565 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : A8 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 4 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGBA8888ToA8 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : I8 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 4 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGBA8888ToI8 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : AI88 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGBA8888ToAI88 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGBA4444 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGBA8888ToRGBA4444 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB5A1 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 2 ;
* outData = new unsigned char [ * outDataLen ] ;
2013-07-25 21:35:00 +08:00
convertRGBA8888ToRGB5A1 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
default :
// unsupport convertion or don't need to convert
2013-07-27 22:06:30 +08:00
if ( format ! = PixelFormat : : AUTO & & format ! = PixelFormat : : RGBA8888 )
2013-07-19 15:37:54 +08:00
{
2013-07-27 22:06:30 +08:00
CCLOG ( " Can not convert image format PixelFormat::RGBA8888 to format ID:%d, we will use it's origin format PixelFormat::RGBA8888 " , format ) ;
2013-07-19 15:37:54 +08:00
}
* outData = ( unsigned char * ) data ;
* outDataLen = dataLen ;
2013-07-27 22:06:30 +08:00
return PixelFormat : : RGBA8888 ;
2013-07-19 15:37:54 +08:00
}
return format ;
}
2013-07-17 17:12:04 +08:00
/*
convert map :
2013-07-27 22:06:30 +08:00
1. PixelFormat : : RGBA8888
2. PixelFormat : : RGB888
3. PixelFormat : : RGB565
4. PixelFormat : : A8
5. PixelFormat : : I8
6. PixelFormat : : AI88
7. PixelFormat : : RGBA4444
8. PixelFormat : : RGB5A1
2013-07-17 17:12:04 +08:00
gray ( 5 ) - > 1235678
gray alpha ( 6 ) - > 12345678
rgb ( 2 ) - > 1235678
rgba ( 1 ) - > 12345678
*/
2013-11-05 08:31:36 +08:00
Texture2D : : PixelFormat Texture2D : : convertDataToFormat ( const unsigned char * data , long dataLen , PixelFormat originFormat , PixelFormat format , unsigned char * * outData , int * outDataLen )
2013-07-19 15:37:54 +08:00
{
2013-07-25 21:35:00 +08:00
switch ( originFormat )
2013-07-19 15:37:54 +08:00
{
2013-07-27 22:06:30 +08:00
case PixelFormat : : I8 :
2013-07-25 21:35:00 +08:00
return convertI8ToFormat ( data , dataLen , format , outData , outDataLen ) ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : AI88 :
2013-07-25 21:35:00 +08:00
return convertAI88ToFormat ( data , dataLen , format , outData , outDataLen ) ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGB888 :
2013-07-25 21:35:00 +08:00
return convertRGB888ToFormat ( data , dataLen , format , outData , outDataLen ) ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : RGBA8888 :
2013-07-25 21:35:00 +08:00
return convertRGBA8888ToFormat ( data , dataLen , format , outData , outDataLen ) ;
default :
CCLOG ( " unsupport convert for format %d to format %d " , originFormat , format ) ;
* outData = ( unsigned char * ) data ;
* outDataLen = dataLen ;
return originFormat ;
2012-04-19 14:35:52 +08:00
}
2010-07-26 17:32:23 +08:00
}
2010-07-15 18:15:00 +08:00
2013-06-20 14:13:12 +08:00
// implementation Texture2D (Text)
2013-07-27 07:04:21 +08:00
bool Texture2D : : initWithString ( const char * text , const char * fontName , float fontSize , const Size & dimensions /* = Size(0, 0)*/ , TextHAlignment hAlignment /* = TextHAlignment::CENTER */ , TextVAlignment vAlignment /* = TextVAlignment::TOP */ )
2013-04-26 09:22:26 +08:00
{
2013-07-10 04:21:43 +08:00
FontDefinition tempDef ;
2013-05-01 07:36:14 +08:00
2013-07-10 04:21:43 +08:00
tempDef . _shadow . _shadowEnabled = false ;
tempDef . _stroke . _strokeEnabled = false ;
2013-05-01 07:36:14 +08:00
2013-07-10 04:21:43 +08:00
tempDef . _fontName = std : : string ( fontName ) ;
tempDef . _fontSize = fontSize ;
tempDef . _dimensions = dimensions ;
tempDef . _alignment = hAlignment ;
tempDef . _vertAlignment = vAlignment ;
tempDef . _fontFillColor = Color3B : : WHITE ;
return initWithString ( text , tempDef ) ;
2013-05-02 08:11:53 +08:00
}
2013-07-08 15:18:16 +08:00
bool Texture2D : : initWithString ( const char * text , const FontDefinition & textDefinition )
2013-05-02 08:11:53 +08:00
{
2013-07-16 16:47:35 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
// cache the texture data
2013-11-08 16:47:33 +08:00
VolatileTextureMgr : : addStringTexture ( this , text , textDefinition ) ;
2013-07-16 16:47:35 +08:00
# endif
2013-07-10 04:21:43 +08:00
bool bRet = false ;
2013-07-19 15:37:54 +08:00
Image : : TextAlign eAlign ;
2013-04-26 09:22:26 +08:00
2013-07-27 07:04:21 +08:00
if ( TextVAlignment : : TOP = = textDefinition . _vertAlignment )
2013-07-10 04:21:43 +08:00
{
2013-07-27 07:04:21 +08:00
eAlign = ( TextHAlignment : : CENTER = = textDefinition . _alignment ) ? Image : : TextAlign : : TOP
: ( TextHAlignment : : LEFT = = textDefinition . _alignment ) ? Image : : TextAlign : : TOP_LEFT : Image : : TextAlign : : TOP_RIGHT ;
2013-07-10 04:21:43 +08:00
}
2013-07-27 07:04:21 +08:00
else if ( TextVAlignment : : CENTER = = textDefinition . _vertAlignment )
2013-07-10 04:21:43 +08:00
{
2013-07-27 07:04:21 +08:00
eAlign = ( TextHAlignment : : CENTER = = textDefinition . _alignment ) ? Image : : TextAlign : : CENTER
: ( TextHAlignment : : LEFT = = textDefinition . _alignment ) ? Image : : TextAlign : : LEFT : Image : : TextAlign : : RIGHT ;
2013-07-10 04:21:43 +08:00
}
2013-07-27 07:04:21 +08:00
else if ( TextVAlignment : : BOTTOM = = textDefinition . _vertAlignment )
2013-07-10 04:21:43 +08:00
{
2013-07-27 07:04:21 +08:00
eAlign = ( TextHAlignment : : CENTER = = textDefinition . _alignment ) ? Image : : TextAlign : : BOTTOM
: ( TextHAlignment : : LEFT = = textDefinition . _alignment ) ? Image : : TextAlign : : BOTTOM_LEFT : Image : : TextAlign : : BOTTOM_RIGHT ;
2013-07-10 04:21:43 +08:00
}
else
{
2013-07-20 13:01:27 +08:00
CCASSERT ( false , " Not supported alignment format! " ) ;
2013-07-10 04:21:43 +08:00
return false ;
}
2013-04-27 07:34:10 +08:00
2013-07-16 16:47:35 +08:00
# if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
// handle shadow parameters
bool shadowEnabled = false ;
float shadowDX = 0.0f ;
float shadowDY = 0.0f ;
float shadowBlur = 0.0f ;
float shadowOpacity = 0.0f ;
2013-04-27 07:34:10 +08:00
2013-07-16 16:47:35 +08:00
if ( textDefinition . _shadow . _shadowEnabled )
{
shadowEnabled = true ;
shadowDX = textDefinition . _shadow . _shadowOffset . width ;
shadowDY = textDefinition . _shadow . _shadowOffset . height ;
shadowBlur = textDefinition . _shadow . _shadowBlur ;
shadowOpacity = textDefinition . _shadow . _shadowOpacity ;
}
2013-04-27 07:34:10 +08:00
2013-07-16 16:47:35 +08:00
// handle stroke parameters
bool strokeEnabled = false ;
float strokeColorR = 0.0f ;
float strokeColorG = 0.0f ;
float strokeColorB = 0.0f ;
float strokeSize = 0.0f ;
2013-04-27 07:34:10 +08:00
2013-07-16 16:47:35 +08:00
if ( textDefinition . _stroke . _strokeEnabled )
{
strokeEnabled = true ;
strokeColorR = textDefinition . _stroke . _strokeColor . r / 255.0f ;
strokeColorG = textDefinition . _stroke . _strokeColor . g / 255.0f ;
strokeColorB = textDefinition . _stroke . _strokeColor . b / 255.0f ;
strokeSize = textDefinition . _stroke . _strokeSize ;
}
2011-01-19 14:23:26 +08:00
2013-07-16 16:47:35 +08:00
Image * pImage = new Image ( ) ;
do
{
CC_BREAK_IF ( NULL = = pImage ) ;
2013-05-02 08:11:53 +08:00
2013-07-16 16:47:35 +08:00
bRet = pImage - > initWithStringShadowStroke ( text ,
( int ) textDefinition . _dimensions . width ,
( int ) textDefinition . _dimensions . height ,
eAlign ,
textDefinition . _fontName . c_str ( ) ,
textDefinition . _fontSize ,
textDefinition . _fontFillColor . r / 255.0f ,
textDefinition . _fontFillColor . g / 255.0f ,
textDefinition . _fontFillColor . b / 255.0f ,
shadowEnabled ,
shadowDX ,
shadowDY ,
shadowOpacity ,
shadowBlur ,
strokeEnabled ,
strokeColorR ,
strokeColorG ,
strokeColorB ,
strokeSize ) ;
2013-05-02 08:11:53 +08:00
2013-07-16 16:47:35 +08:00
CC_BREAK_IF ( ! bRet ) ;
bRet = initWithImage ( pImage ) ;
2013-05-02 08:11:53 +08:00
2013-07-16 16:47:35 +08:00
} while ( 0 ) ;
2013-05-02 08:11:53 +08:00
2013-07-16 16:47:35 +08:00
CC_SAFE_RELEASE ( pImage ) ;
2013-04-26 09:22:26 +08:00
2013-07-16 16:47:35 +08:00
return bRet ;
# else
bool requestUnsupported = textDefinition . _shadow . _shadowEnabled | | textDefinition . _stroke . _strokeEnabled ;
2013-07-20 13:01:27 +08:00
CCASSERT ( requestUnsupported = = false , " Currently shadow and stroke only supported on iOS and Android! " ) ;
2013-07-16 16:47:35 +08:00
Image * pImage = new Image ( ) ;
do
{
CC_BREAK_IF ( NULL = = pImage ) ;
bRet = pImage - > initWithString ( text , ( int ) textDefinition . _dimensions . width , ( int ) textDefinition . _dimensions . height , eAlign , textDefinition . _fontName . c_str ( ) , ( int ) textDefinition . _fontSize ) ;
CC_BREAK_IF ( ! bRet ) ;
bRet = initWithImage ( pImage ) ;
} while ( 0 ) ;
2013-04-26 09:22:26 +08:00
2013-07-16 16:47:35 +08:00
CC_SAFE_RELEASE ( pImage ) ;
return bRet ;
# endif
2010-08-11 18:09:10 +08:00
}
2010-07-15 18:15:00 +08:00
2013-06-20 14:13:12 +08:00
// implementation Texture2D (Drawing)
2010-07-15 18:15:00 +08:00
2013-06-20 14:13:12 +08:00
void Texture2D : : drawAtPoint ( const Point & point )
2010-07-15 18:15:00 +08:00
{
2013-07-10 04:21:43 +08:00
GLfloat coordinates [ ] = {
2013-06-15 14:03:30 +08:00
0.0f , _maxT ,
_maxS , _maxT ,
2012-04-19 14:35:52 +08:00
0.0f , 0.0f ,
2013-06-15 14:03:30 +08:00
_maxS , 0.0f } ;
2010-07-15 18:15:00 +08:00
2013-06-15 14:03:30 +08:00
GLfloat width = ( GLfloat ) _pixelsWide * _maxS ,
height = ( GLfloat ) _pixelsHigh * _maxT ;
2010-07-15 18:15:00 +08:00
2012-04-19 14:35:52 +08:00
GLfloat vertices [ ] = {
point . x , point . y ,
width + point . x , point . y ,
point . x , height + point . y ,
width + point . x , height + point . y } ;
2012-03-14 14:55:17 +08:00
2013-07-26 09:42:53 +08:00
GL : : enableVertexAttribs ( GL : : VERTEX_ATTRIB_FLAG_POSITION | GL : : VERTEX_ATTRIB_FLAG_TEX_COORDS ) ;
2013-06-15 14:03:30 +08:00
_shaderProgram - > use ( ) ;
_shaderProgram - > setUniformsForBuiltins ( ) ;
2012-03-21 11:07:31 +08:00
2013-07-26 09:42:53 +08:00
GL : : bindTexture2D ( _name ) ;
2012-03-21 11:07:31 +08:00
2013-04-09 12:08:34 +08:00
# ifdef EMSCRIPTEN
setGLBufferData ( vertices , 8 * sizeof ( GLfloat ) , 0 ) ;
2013-07-25 17:48:22 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_POSITION , 2 , GL_FLOAT , GL_FALSE , 0 , 0 ) ;
2013-04-09 12:08:34 +08:00
setGLBufferData ( coordinates , 8 * sizeof ( GLfloat ) , 1 ) ;
2013-07-25 17:48:22 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_TEX_COORDS , 2 , GL_FLOAT , GL_FALSE , 0 , 0 ) ;
2013-04-09 12:08:34 +08:00
# else
2013-07-25 17:48:22 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_POSITION , 2 , GL_FLOAT , GL_FALSE , 0 , vertices ) ;
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_TEX_COORDS , 2 , GL_FLOAT , GL_FALSE , 0 , coordinates ) ;
2013-04-09 12:08:34 +08:00
# endif // EMSCRIPTEN
2010-07-15 18:15:00 +08:00
2012-04-19 14:35:52 +08:00
glDrawArrays ( GL_TRIANGLE_STRIP , 0 , 4 ) ;
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
void Texture2D : : drawInRect ( const Rect & rect )
2010-07-15 18:15:00 +08:00
{
2012-04-19 14:35:52 +08:00
GLfloat coordinates [ ] = {
2013-06-15 14:03:30 +08:00
0.0f , _maxT ,
_maxS , _maxT ,
2012-04-19 14:35:52 +08:00
0.0f , 0.0f ,
2013-06-15 14:03:30 +08:00
_maxS , 0.0f } ;
2010-07-15 18:15:00 +08:00
2012-04-19 14:35:52 +08:00
GLfloat vertices [ ] = { rect . origin . x , rect . origin . y , /*0.0f,*/
rect . origin . x + rect . size . width , rect . origin . y , /*0.0f,*/
rect . origin . x , rect . origin . y + rect . size . height , /*0.0f,*/
rect . origin . x + rect . size . width , rect . origin . y + rect . size . height , /*0.0f*/ } ;
2010-07-15 18:15:00 +08:00
2013-07-26 09:42:53 +08:00
GL : : enableVertexAttribs ( GL : : VERTEX_ATTRIB_FLAG_POSITION | GL : : VERTEX_ATTRIB_FLAG_TEX_COORDS ) ;
2013-06-15 14:03:30 +08:00
_shaderProgram - > use ( ) ;
_shaderProgram - > setUniformsForBuiltins ( ) ;
2012-03-21 11:07:31 +08:00
2013-07-26 09:42:53 +08:00
GL : : bindTexture2D ( _name ) ;
2012-03-21 11:07:31 +08:00
2013-04-09 12:08:34 +08:00
# ifdef EMSCRIPTEN
setGLBufferData ( vertices , 8 * sizeof ( GLfloat ) , 0 ) ;
2013-07-25 17:48:22 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_POSITION , 2 , GL_FLOAT , GL_FALSE , 0 , 0 ) ;
2013-04-09 12:08:34 +08:00
setGLBufferData ( coordinates , 8 * sizeof ( GLfloat ) , 1 ) ;
2013-07-25 17:48:22 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_TEX_COORDS , 2 , GL_FLOAT , GL_FALSE , 0 , 0 ) ;
2013-04-09 12:08:34 +08:00
# else
2013-07-25 17:48:22 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_POSITION , 2 , GL_FLOAT , GL_FALSE , 0 , vertices ) ;
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_TEX_COORDS , 2 , GL_FLOAT , GL_FALSE , 0 , coordinates ) ;
2013-04-09 12:08:34 +08:00
# endif // EMSCRIPTEN
2012-04-19 14:35:52 +08:00
glDrawArrays ( GL_TRIANGLE_STRIP , 0 , 4 ) ;
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
void Texture2D : : PVRImagesHavePremultipliedAlpha ( bool haveAlphaPremultiplied )
2011-07-19 15:14:59 +08:00
{
2013-07-29 14:07:57 +08:00
_PVRHaveAlphaPremultiplied = haveAlphaPremultiplied ;
2010-07-15 18:15:00 +08:00
}
2011-07-19 15:14:59 +08:00
2010-07-15 18:15:00 +08:00
//
// Use to apply MIN/MAG filter
//
2013-06-20 14:13:12 +08:00
// implementation Texture2D (GLFilter)
2010-07-15 18:15:00 +08:00
2013-06-20 14:13:12 +08:00
void Texture2D : : generateMipmap ( )
2010-07-15 18:15:00 +08:00
{
2013-11-13 11:22:34 +08:00
CCASSERT ( static_cast < unsigned long > ( _pixelsWide ) = = ccNextPOT ( _pixelsWide ) & & static_cast < unsigned long > ( _pixelsHigh ) = = ccNextPOT ( _pixelsHigh ) , " Mipmap texture only works in POT textures " ) ;
2013-07-26 09:42:53 +08:00
GL : : bindTexture2D ( _name ) ;
2012-04-19 14:35:52 +08:00
glGenerateMipmap ( GL_TEXTURE_2D ) ;
2013-06-15 14:03:30 +08:00
_hasMipmaps = true ;
2010-07-15 18:15:00 +08:00
}
2013-07-04 08:44:41 +08:00
bool Texture2D : : hasMipmaps ( ) const
2012-06-15 15:10:40 +08:00
{
2013-06-15 14:03:30 +08:00
return _hasMipmaps ;
2012-06-15 15:10:40 +08:00
}
2013-08-01 15:53:52 +08:00
void Texture2D : : setTexParameters ( const TexParams & texParams )
2010-07-15 18:15:00 +08:00
{
2013-11-13 11:22:34 +08:00
CCASSERT ( ( static_cast < unsigned long > ( _pixelsWide ) = = ccNextPOT ( _pixelsWide ) | | texParams . wrapS = = GL_CLAMP_TO_EDGE ) & &
( static_cast < unsigned long > ( _pixelsHigh ) = = ccNextPOT ( _pixelsHigh ) | | texParams . wrapT = = GL_CLAMP_TO_EDGE ) ,
2012-06-08 14:11:48 +08:00
" GL_CLAMP_TO_EDGE should be used in NPOT dimensions " ) ;
2013-07-26 09:42:53 +08:00
GL : : bindTexture2D ( _name ) ;
2013-07-04 08:59:22 +08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , texParams . minFilter ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , texParams . magFilter ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , texParams . wrapS ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , texParams . wrapT ) ;
2012-08-31 03:02:05 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
2013-11-08 16:47:33 +08:00
VolatileTextureMgr : : setTexParameters ( this , texParams ) ;
2012-08-31 03:02:05 +08:00
# endif
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
void Texture2D : : setAliasTexParameters ( )
2010-07-15 18:15:00 +08:00
{
2013-07-26 09:42:53 +08:00
GL : : bindTexture2D ( _name ) ;
2012-06-13 16:20:58 +08:00
2013-06-15 14:03:30 +08:00
if ( ! _hasMipmaps )
2012-06-13 16:20:58 +08:00
{
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
}
else
{
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST_MIPMAP_NEAREST ) ;
}
2012-06-08 14:11:48 +08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
2012-08-31 03:02:05 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
2013-08-06 11:34:48 +08:00
TexParams texParams = { ( GLuint ) ( _hasMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST ) , GL_NEAREST , GL_NONE , GL_NONE } ;
2013-11-08 16:47:33 +08:00
VolatileTextureMgr : : setTexParameters ( this , texParams ) ;
2012-08-31 03:02:05 +08:00
# endif
2010-07-15 18:15:00 +08:00
}
2013-06-20 14:13:12 +08:00
void Texture2D : : setAntiAliasTexParameters ( )
2010-07-15 18:15:00 +08:00
{
2013-07-26 09:42:53 +08:00
GL : : bindTexture2D ( _name ) ;
2012-06-13 16:20:58 +08:00
2013-06-15 14:03:30 +08:00
if ( ! _hasMipmaps )
2012-06-13 16:20:58 +08:00
{
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
}
else
{
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_NEAREST ) ;
}
2012-06-08 14:11:48 +08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
2012-08-31 03:02:05 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
2013-08-06 11:34:48 +08:00
TexParams texParams = { ( GLuint ) ( _hasMipmaps ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR ) , GL_LINEAR , GL_NONE , GL_NONE } ;
2013-11-08 16:47:33 +08:00
VolatileTextureMgr : : setTexParameters ( this , texParams ) ;
2012-08-31 03:02:05 +08:00
# endif
2010-07-15 18:15:00 +08:00
}
2013-07-19 14:57:54 +08:00
const char * Texture2D : : getStringForFormat ( ) const
2012-06-13 16:20:58 +08:00
{
2013-06-15 14:03:30 +08:00
switch ( _pixelFormat )
2012-06-13 16:20:58 +08:00
{
2013-07-26 04:36:19 +08:00
case Texture2D : : PixelFormat : : RGBA8888 :
2012-06-13 16:20:58 +08:00
return " RGBA8888 " ;
2013-07-26 04:36:19 +08:00
case Texture2D : : PixelFormat : : RGB888 :
2012-06-13 16:20:58 +08:00
return " RGB888 " ;
2013-07-26 04:36:19 +08:00
case Texture2D : : PixelFormat : : RGB565 :
2012-06-13 16:20:58 +08:00
return " RGB565 " ;
2013-07-26 04:36:19 +08:00
case Texture2D : : PixelFormat : : RGBA4444 :
2012-06-13 16:20:58 +08:00
return " RGBA4444 " ;
2013-07-26 04:36:19 +08:00
case Texture2D : : PixelFormat : : RGB5A1 :
2012-06-13 16:20:58 +08:00
return " RGB5A1 " ;
2013-07-26 04:36:19 +08:00
case Texture2D : : PixelFormat : : AI88 :
2012-06-13 16:20:58 +08:00
return " AI88 " ;
2013-07-26 04:36:19 +08:00
case Texture2D : : PixelFormat : : A8 :
2012-06-13 16:20:58 +08:00
return " A8 " ;
2013-07-26 04:36:19 +08:00
case Texture2D : : PixelFormat : : I8 :
2012-06-13 16:20:58 +08:00
return " I8 " ;
2013-07-27 22:06:30 +08:00
case Texture2D : : PixelFormat : : PVRTC4 :
2012-06-13 16:20:58 +08:00
return " PVRTC4 " ;
2013-07-27 22:06:30 +08:00
case Texture2D : : PixelFormat : : PVRTC2 :
2012-06-13 16:20:58 +08:00
return " PVRTC2 " ;
default :
2013-07-20 13:01:27 +08:00
CCASSERT ( false , " unrecognized pixel format " ) ;
2013-06-15 14:03:30 +08:00
CCLOG ( " stringForFormat: %ld, cannot give useful result " , ( long ) _pixelFormat ) ;
2012-06-13 16:20:58 +08:00
break ;
}
return NULL ;
}
2012-06-11 21:58:04 +08:00
2010-07-15 18:15:00 +08:00
//
// Texture options for images that contains alpha
//
2013-06-20 14:13:12 +08:00
// implementation Texture2D (PixelFormat)
2010-07-15 18:15:00 +08:00
2013-07-25 19:52:44 +08:00
void Texture2D : : setDefaultAlphaPixelFormat ( Texture2D : : PixelFormat format )
2010-07-15 18:15:00 +08:00
{
2012-04-19 14:35:52 +08:00
g_defaultAlphaPixelFormat = format ;
2010-07-15 18:15:00 +08:00
}
2013-07-25 19:52:44 +08:00
Texture2D : : PixelFormat Texture2D : : getDefaultAlphaPixelFormat ( )
2010-07-15 18:15:00 +08:00
{
2012-04-19 14:35:52 +08:00
return g_defaultAlphaPixelFormat ;
2010-07-15 18:15:00 +08:00
}
2010-08-02 10:58:00 +08:00
2013-07-25 19:52:44 +08:00
unsigned int Texture2D : : getBitsPerPixelForFormat ( Texture2D : : PixelFormat format ) const
2012-06-13 16:20:58 +08:00
{
2013-07-27 22:06:30 +08:00
if ( format = = PixelFormat : : NONE )
2013-07-25 21:35:00 +08:00
{
return 0 ;
}
2013-08-02 14:10:23 +08:00
return _pixelFormatInfoTables . at ( format ) . bpp ;
2012-06-13 16:20:58 +08:00
}
2013-07-19 14:57:54 +08:00
unsigned int Texture2D : : getBitsPerPixelForFormat ( ) const
2012-06-13 16:20:58 +08:00
{
2013-07-19 14:57:54 +08:00
return this - > getBitsPerPixelForFormat ( _pixelFormat ) ;
2012-06-13 16:20:58 +08:00
}
2012-04-19 14:35:52 +08:00
2013-08-07 11:20:41 +08:00
const Texture2D : : PixelFormatInfoMap & Texture2D : : getPixelFormatInfoMap ( )
2013-08-02 14:10:23 +08:00
{
2013-08-07 11:20:41 +08:00
return _pixelFormatInfoTables ;
2013-08-02 14:10:23 +08:00
}
2011-07-05 10:47:25 +08:00
2012-04-18 18:43:45 +08:00
NS_CC_END