2010-08-02 10:58:00 +08:00
/****************************************************************************
2011-03-19 14:45:51 +08:00
Copyright ( c ) 2008 Apple Inc . All Rights Reserved .
2014-01-07 11:25:07 +08:00
Copyright ( c ) 2010 - 2012 cocos2d - x . org
2017-02-14 14:36:57 +08:00
Copyright ( c ) 2013 - 2017 Chukong Technologies Inc .
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
*/
2014-05-17 05:36:00 +08:00
# include "renderer/CCTexture2D.h"
2014-09-10 07:50:02 +08:00
# include "platform/CCGL.h"
2014-05-17 05:36:00 +08:00
# include "platform/CCImage.h"
# include "base/ccUtils.h"
# include "platform/CCDevice.h"
2014-04-30 08:37:36 +08:00
# include "base/ccConfig.h"
# include "base/ccMacros.h"
2016-06-15 15:01:26 +08:00
# include "base/ccUTF8.h"
2014-05-01 10:09:13 +08:00
# include "base/CCConfiguration.h"
2014-09-10 08:17:07 +08:00
# include "platform/CCPlatformMacros.h"
2014-04-30 08:37:36 +08:00
# include "base/CCDirector.h"
2014-05-09 09:01:48 +08:00
# include "renderer/CCGLProgram.h"
# include "renderer/ccGLStateCache.h"
2014-05-10 09:39:25 +08:00
# include "renderer/CCGLProgramCache.h"
2015-05-21 16:04:37 +08:00
# include "base/CCNinePatchImageParser.h"
2014-05-10 09:39:25 +08:00
2012-06-06 10:06:51 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
2014-05-17 05:36:00 +08:00
# include "renderer/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
2014-03-22 20:56:08 +08:00
2013-08-02 14:10:23 +08:00
namespace {
typedef Texture2D : : PixelFormatInfoMap : : value_type PixelFormatInfoMapValue ;
static const PixelFormatInfoMapValue TexturePixelFormatInfoTablesValue [ ] =
{
2014-06-30 20:58:26 +08:00
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : BGRA8888 , Texture2D : : PixelFormatInfo ( GL_BGRA , GL_BGRA , GL_UNSIGNED_BYTE , 32 , false , true ) ) ,
2013-08-02 14:10:23 +08:00
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
2014-06-26 02:44:20 +08:00
PixelFormatInfoMapValue ( Texture2D : : PixelFormat : : ETC , Texture2D : : PixelFormatInfo ( GL_ETC1_RGB8_OES , 0xFFFFFFFF , 0xFFFFFFFF , 4 , 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-17 17:12:04 +08:00
//////////////////////////////////////////////////////////////////////////
2015-09-22 16:08:23 +08:00
//convertor function
2013-07-17 17:12:04 +08:00
// IIIIIIII -> RRRRRRRRGGGGGGGGGBBBBBBBB
2013-12-05 17:19:01 +08:00
void Texture2D : : convertI8ToRGB888 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertAI88ToRGB888 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertI8ToRGBA8888 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertAI88ToRGBA8888 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertI8ToRGB565 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertAI88ToRGB565 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertI8ToRGBA4444 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertAI88ToRGBA4444 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertI8ToRGB5A1 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertAI88ToRGB5A1 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertI8ToAI88 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertAI88ToA8 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertAI88ToI8 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGB888ToRGBA8888 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGBA8888ToRGB888 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGB888ToRGB565 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGBA8888ToRGB565 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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
}
2016-02-12 22:23:56 +08:00
// RRRRRRRRGGGGGGGGBBBBBBBB -> AAAAAAAA
void Texture2D : : convertRGB888ToA8 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
{
for ( ssize_t i = 0 , l = dataLen - 2 ; i < l ; i + = 3 )
{
* outData + + = ( data [ i ] * 299 + data [ i + 1 ] * 587 + data [ i + 2 ] * 114 + 500 ) / 1000 ; //A = (R*299 + G*587 + B*114 + 500) / 1000
}
}
2013-07-17 17:12:04 +08:00
// RRRRRRRRGGGGGGGGBBBBBBBB -> IIIIIIII
2013-12-05 17:19:01 +08:00
void Texture2D : : convertRGB888ToI8 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGBA8888ToI8 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGBA8888ToA8 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGB888ToAI88 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGBA8888ToAI88 ( const unsigned char * data , ssize_t dataLen , unsigned char * outData )
2013-07-17 17:12:04 +08:00
{
2013-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGB888ToRGBA4444 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGBA8888ToRGBA4444 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGB888ToRGB5A1 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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-12-05 17:19:01 +08:00
void Texture2D : : convertRGBA8888ToRGB5A1 ( const unsigned char * data , ssize_t 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-12-05 17:19:01 +08:00
for ( ssize_t 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
}
2015-09-22 16:08:23 +08:00
// converter function end
2013-07-17 17:12:04 +08:00
//////////////////////////////////////////////////////////////////////////
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 )
2013-12-18 17:47:20 +08:00
, _shaderProgram ( nullptr )
2014-03-27 15:35:51 +08:00
, _antialiasEnabled ( true )
2015-05-21 16:04:37 +08:00
, _ninePatchInfo ( nullptr )
2015-12-02 11:26:05 +08:00
, _valid ( true )
2016-07-25 17:31:54 +08:00
, _alphaTexture ( nullptr )
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
2016-07-25 17:31:54 +08:00
CC_SAFE_RELEASE_NULL ( _alphaTexture ) ; // ETC1 ALPHA support.
2011-01-10 17:54:44 +08:00
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
2015-05-21 16:04:37 +08:00
CC_SAFE_DELETE ( _ninePatchInfo ) ;
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
}
2014-06-13 07:31:07 +08:00
void Texture2D : : releaseGLTexture ( )
{
if ( _name )
{
GL : : deleteTexture ( _name ) ;
}
_name = 0 ;
}
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-12-05 17:19:01 +08:00
int 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-12-05 17:19:01 +08:00
int 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
}
2016-07-25 17:31:54 +08:00
GLuint Texture2D : : getAlphaTextureName ( ) const
{
return _alphaTexture = = nullptr ? 0 : _alphaTexture - > getName ( ) ;
}
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
}
2014-05-09 07:42:36 +08:00
GLProgram * Texture2D : : getGLProgram ( ) 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
}
2014-05-09 07:42:36 +08:00
void Texture2D : : setGLProgram ( GLProgram * shaderProgram )
2012-03-14 14:55:17 +08:00
{
2013-12-18 17:47:20 +08:00
CC_SAFE_RETAIN ( shaderProgram ) ;
2013-06-15 14:03:30 +08:00
CC_SAFE_RELEASE ( _shaderProgram ) ;
2013-12-18 17:47:20 +08:00
_shaderProgram = shaderProgram ;
2012-03-14 14:55:17 +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
}
2016-11-16 09:48:37 +08:00
bool Texture2D : : initWithData ( const void * data , ssize_t dataLen , Texture2D : : PixelFormat pixelFormat , int pixelsWide , int 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 ;
2013-12-05 17:19:01 +08:00
mipmap . len = static_cast < int > ( dataLen ) ;
2013-07-25 21:35:00 +08:00
return initWithMipmaps ( & mipmap , 1 , pixelFormat , pixelsWide , pixelsHigh ) ;
}
2013-12-05 17:19:01 +08:00
bool Texture2D : : initWithMipmaps ( MipmapInfo * mipmaps , int mipmapsNum , PixelFormat pixelFormat , int pixelsWide , int pixelsHigh )
2010-07-15 18:15:00 +08:00
{
2014-06-13 07:31:07 +08:00
2014-03-25 06:09:24 +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
}
2014-06-13 07:31:07 +08:00
if ( _name ! = 0 )
{
GL : : deleteTexture ( _name ) ;
_name = 0 ;
}
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 )
{
2014-03-27 15:35:51 +08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , _antialiasEnabled ? GL_LINEAR : GL_NEAREST ) ;
2013-07-25 21:35:00 +08:00
} else
{
2014-03-27 15:35:51 +08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , _antialiasEnabled ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST ) ;
2013-07-25 21:35:00 +08:00
}
2014-03-27 15:35:51 +08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , _antialiasEnabled ? GL_LINEAR : GL_NEAREST ) ;
2012-06-13 16:20:58 +08:00
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
2014-03-27 15:35:51 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
if ( _antialiasEnabled )
{
TexParams texParams = { ( GLuint ) ( _hasMipmaps ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR ) , GL_LINEAR , GL_NONE , GL_NONE } ;
VolatileTextureMgr : : setTexParameters ( this , texParams ) ;
}
else
{
TexParams texParams = { ( GLuint ) ( _hasMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST ) , GL_NEAREST , GL_NONE , GL_NONE } ;
VolatileTextureMgr : : setTexParameters ( this , texParams ) ;
}
# endif
2015-03-19 16:10:49 +08:00
// clean possible GL error
GLenum err = glGetError ( ) ;
if ( err ! = GL_NO_ERROR )
{
cocos2d : : log ( " OpenGL error 0x%04X in %s %s %d \n " , err , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
2013-07-25 21:35:00 +08:00
2012-04-19 14:35:52 +08:00
// Specify OpenGL texture image
2013-12-05 17:19:01 +08:00
int width = pixelsWide ;
int 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-12-06 16:32:06 +08:00
CCLOG ( " cocos2d: Texture2D. WARNING. Mipmap level %u is not squared. Texture won't render correctly. width=%d != height=%d " , i , width , height ) ;
2013-07-25 21:35:00 +08:00
}
2015-07-14 15:28:36 +08:00
err = glGetError ( ) ;
2013-07-25 21:35:00 +08:00
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
2014-05-10 09:39:25 +08:00
// shader
setGLProgram ( GLProgramCache : : getInstance ( ) - > getGLProgram ( GLProgram : : SHADER_NAME_POSITION_TEXTURE ) ) ;
2012-04-19 14:35:52 +08:00
return true ;
2010-07-15 18:15:00 +08:00
}
2014-03-27 15:11:04 +08:00
bool Texture2D : : updateWithData ( const void * data , int offsetX , int offsetY , int width , int height )
{
if ( _name )
{
GL : : bindTexture2D ( _name ) ;
const PixelFormatInfo & info = _pixelFormatInfoTables . at ( _pixelFormat ) ;
glTexSubImage2D ( GL_TEXTURE_2D , 0 , offsetX , offsetY , width , height , info . format , info . type , data ) ;
return true ;
}
return false ;
}
2010-07-15 18:15:00 +08:00
2013-12-13 06:38:12 +08:00
std : : string Texture2D : : getDescription ( ) const
2010-07-15 18:15:00 +08:00
{
2013-12-25 11:00:27 +08:00
return StringUtils : : format ( " <Texture2D | Name = %u | Dimensions = %ld x %ld | Coordinates = (%.2f, %.2f)> " , _name , ( long ) _pixelsWide , ( long ) _pixelsHigh , _maxS , _maxT ) ;
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
{
2014-07-08 10:08:02 +08:00
return initWithImage ( image , g_defaultAlphaPixelFormat ) ;
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-12-18 17:47:20 +08:00
if ( image = = nullptr )
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 ( ) ;
2015-11-24 18:29:58 +08:00
this - > _filePath = image - > getFilePath ( ) ;
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 ) ;
2014-07-08 10:08:02 +08:00
PixelFormat pixelFormat = ( ( PixelFormat : : NONE = = format ) | | ( PixelFormat : : AUTO = = format ) ) ? image - > getRenderFormat ( ) : format ;
2013-07-27 22:06:30 +08:00
PixelFormat renderFormat = image - > getRenderFormat ( ) ;
2016-06-15 10:43:15 +08:00
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
{
2014-07-08 10:08:02 +08:00
if ( pixelFormat ! = image - > getRenderFormat ( ) )
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
2015-10-15 21:48:21 +08:00
// set the premultiplied tag
_hasPremultipliedAlpha = image - > hasPremultipliedAlpha ( ) ;
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
{
2014-07-08 10:08:02 +08:00
if ( pixelFormat ! = image - > getRenderFormat ( ) )
2013-07-25 21:35:00 +08:00
{
2016-07-25 01:53:22 +08:00
CCLOG ( " cocos2d: WARNING: This image is compressed and we can'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 ) ;
2015-10-15 21:48:21 +08:00
// set the premultiplied tag
_hasPremultipliedAlpha = image - > hasPremultipliedAlpha ( ) ;
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
{
2013-12-18 17:47:20 +08:00
unsigned char * outTempData = nullptr ;
2013-12-05 17:19:01 +08:00
ssize_t 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-12-18 17:47:20 +08:00
if ( outTempData ! = nullptr & & outTempData ! = tempData )
2013-07-25 21:35:00 +08:00
{
2013-07-19 15:37:54 +08:00
2014-02-18 11:14:02 +08:00
free ( outTempData ) ;
2013-07-25 21:35:00 +08:00
}
2013-07-19 15:37:54 +08:00
2013-07-30 11:10:05 +08:00
// set the premultiplied tag
2014-07-25 18:19:04 +08:00
_hasPremultipliedAlpha = image - > hasPremultipliedAlpha ( ) ;
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-12-05 17:19:01 +08:00
Texture2D : : PixelFormat Texture2D : : convertI8ToFormat ( const unsigned char * data , ssize_t dataLen , PixelFormat format , unsigned char * * outData , ssize_t * 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 :
2015-09-22 16:08:23 +08:00
// unsupported conversion 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
{
2016-04-18 17:52:58 +08:00
CCLOG ( " Can not convert image format PixelFormat::I8 to format ID:%d, we will use it's origin format PixelFormat::I8 " , static_cast < int > ( 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-12-05 17:19:01 +08:00
Texture2D : : PixelFormat Texture2D : : convertAI88ToFormat ( const unsigned char * data , ssize_t dataLen , PixelFormat format , unsigned char * * outData , ssize_t * 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 :
2015-09-22 16:08:23 +08:00
// unsupported conversion 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
{
2016-04-18 17:52:58 +08:00
CCLOG ( " Can not convert image format PixelFormat::AI88 to format ID:%d, we will use it's origin format PixelFormat::AI88 " , static_cast < int > ( 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-12-05 17:19:01 +08:00
Texture2D : : PixelFormat Texture2D : : convertRGB888ToFormat ( const unsigned char * data , ssize_t dataLen , PixelFormat format , unsigned char * * outData , ssize_t * 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( unsigned char ) * ( * outDataLen ) ) ;
2013-07-25 21:35:00 +08:00
convertRGB888ToRGB565 ( data , dataLen , * outData ) ;
2013-07-19 15:37:54 +08:00
break ;
2016-02-12 22:23:56 +08:00
case PixelFormat : : A8 :
* outDataLen = dataLen / 3 ;
* outData = ( unsigned char * ) malloc ( sizeof ( unsigned char ) * ( * outDataLen ) ) ;
convertRGB888ToA8 ( data , dataLen , * outData ) ;
break ;
2013-07-27 22:06:30 +08:00
case PixelFormat : : I8 :
2013-07-19 15:37:54 +08:00
* outDataLen = dataLen / 3 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 :
2015-09-22 16:08:23 +08:00
// unsupported conversion 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
{
2016-04-18 17:52:58 +08:00
CCLOG ( " Can not convert image format PixelFormat::RGB888 to format ID:%d, we will use it's origin format PixelFormat::RGB888 " , static_cast < int > ( 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-12-05 17:19:01 +08:00
Texture2D : : PixelFormat Texture2D : : convertRGBA8888ToFormat ( const unsigned char * data , ssize_t dataLen , PixelFormat format , unsigned char * * outData , ssize_t * 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 ;
2014-02-18 11:14:02 +08:00
* outData = ( unsigned char * ) malloc ( sizeof ( 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 :
2015-09-22 16:08:23 +08:00
// unsupported conversion 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
{
2016-04-18 17:52:58 +08:00
CCLOG ( " Can not convert image format PixelFormat::RGBA8888 to format ID:%d, we will use it's origin format PixelFormat::RGBA8888 " , static_cast < int > ( 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-12-05 17:19:01 +08:00
Texture2D : : PixelFormat Texture2D : : convertDataToFormat ( const unsigned char * data , ssize_t dataLen , PixelFormat originFormat , PixelFormat format , unsigned char * * outData , ssize_t * outDataLen )
2013-07-19 15:37:54 +08:00
{
2014-06-30 20:58:26 +08:00
// don't need to convert
if ( format = = originFormat | | format = = PixelFormat : : AUTO )
{
* outData = ( unsigned char * ) data ;
* outDataLen = dataLen ;
return originFormat ;
}
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 :
2016-04-18 17:52:58 +08:00
CCLOG ( " unsupported conversion from format %d to format %d " , static_cast < int > ( originFormat ) , static_cast < int > ( format ) ) ;
2013-07-25 21:35:00 +08:00
* 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)
2016-06-15 10:43:15 +08:00
bool Texture2D : : initWithString ( const char * text , const std : : string & fontName , float fontSize , const Size & dimensions /* = Size(0, 0)*/ , TextHAlignment hAlignment /* = TextHAlignment::CENTER */ , TextVAlignment vAlignment /* = TextVAlignment::TOP */ , bool enableWrap /* = false */ , int overflow /* = 0 */ )
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
2014-04-30 08:37:36 +08:00
tempDef . _fontName = fontName ;
2013-07-10 04:21:43 +08:00
tempDef . _fontSize = fontSize ;
tempDef . _dimensions = dimensions ;
tempDef . _alignment = hAlignment ;
tempDef . _vertAlignment = vAlignment ;
tempDef . _fontFillColor = Color3B : : WHITE ;
2016-06-15 10:43:15 +08:00
tempDef . _enableWrap = enableWrap ;
tempDef . _overflow = overflow ;
2013-07-10 04:21:43 +08:00
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
{
2014-02-13 21:08:43 +08:00
if ( ! text | | 0 = = strlen ( text ) )
2014-05-06 10:36:55 +08:00
{
2014-02-13 21:08:43 +08:00
return false ;
2014-05-06 10:36:55 +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
2013-12-18 17:47:20 +08:00
bool ret = false ;
2014-02-13 21:08:43 +08:00
Device : : TextAlign align ;
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
{
2014-02-13 21:08:43 +08:00
align = ( TextHAlignment : : CENTER = = textDefinition . _alignment ) ? Device : : TextAlign : : TOP
: ( TextHAlignment : : LEFT = = textDefinition . _alignment ) ? Device : : TextAlign : : TOP_LEFT : Device : : 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
{
2014-02-13 21:08:43 +08:00
align = ( TextHAlignment : : CENTER = = textDefinition . _alignment ) ? Device : : TextAlign : : CENTER
: ( TextHAlignment : : LEFT = = textDefinition . _alignment ) ? Device : : TextAlign : : LEFT : Device : : 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
{
2014-02-13 21:08:43 +08:00
align = ( TextHAlignment : : CENTER = = textDefinition . _alignment ) ? Device : : TextAlign : : BOTTOM
: ( TextHAlignment : : LEFT = = textDefinition . _alignment ) ? Device : : TextAlign : : BOTTOM_LEFT : Device : : 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
2014-02-13 21:08:43 +08:00
# if (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID) && (CC_TARGET_PLATFORM != CC_PLATFORM_IOS)
2014-03-26 14:11:40 +08:00
CCASSERT ( textDefinition . _stroke . _strokeEnabled = = false , " Currently stroke only supported on iOS and Android! " ) ;
2014-02-13 21:08:43 +08:00
# endif
2013-07-16 16:47:35 +08:00
2014-02-13 21:08:43 +08:00
PixelFormat pixelFormat = g_defaultAlphaPixelFormat ;
unsigned char * outTempData = nullptr ;
ssize_t outTempDataLen = 0 ;
2013-07-16 16:47:35 +08:00
2014-02-13 21:08:43 +08:00
int imageWidth ;
int imageHeight ;
2014-03-11 18:06:14 +08:00
auto textDef = textDefinition ;
auto contentScaleFactor = CC_CONTENT_SCALE_FACTOR ( ) ;
textDef . _fontSize * = contentScaleFactor ;
textDef . _dimensions . width * = contentScaleFactor ;
textDef . _dimensions . height * = contentScaleFactor ;
2014-03-24 16:54:16 +08:00
textDef . _stroke . _strokeSize * = contentScaleFactor ;
2014-03-26 14:11:40 +08:00
textDef . _shadow . _shadowEnabled = false ;
2014-03-24 16:54:16 +08:00
2014-05-29 10:26:07 +08:00
bool hasPremultipliedAlpha ;
Data outData = Device : : getTextureDataForText ( text , textDef , align , imageWidth , imageHeight , hasPremultipliedAlpha ) ;
2014-02-13 21:08:43 +08:00
if ( outData . isNull ( ) )
2014-05-06 10:36:55 +08:00
{
2014-02-13 21:08:43 +08:00
return false ;
2014-05-06 10:36:55 +08:00
}
2014-02-13 21:08:43 +08:00
Size imageSize = Size ( ( float ) imageWidth , ( float ) imageHeight ) ;
pixelFormat = convertDataToFormat ( outData . getBytes ( ) , imageWidth * imageHeight * 4 , PixelFormat : : RGBA8888 , pixelFormat , & outTempData , & outTempDataLen ) ;
ret = initWithData ( outTempData , outTempDataLen , pixelFormat , imageWidth , imageHeight , imageSize ) ;
if ( outTempData ! = nullptr & & outTempData ! = outData . getBytes ( ) )
{
2014-02-18 11:14:02 +08:00
free ( outTempData ) ;
2014-02-13 21:08:43 +08:00
}
2014-05-29 10:26:07 +08:00
_hasPremultipliedAlpha = hasPremultipliedAlpha ;
2014-05-06 10:36:55 +08:00
2014-02-13 21:08:43 +08:00
return ret ;
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
2014-05-15 01:07:09 +08:00
void Texture2D : : drawAtPoint ( const Vec2 & 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
2014-05-13 10:12:56 +08:00
GL : : enableVertexAttribs ( GL : : VERTEX_ATTRIB_FLAG_POSITION | GL : : VERTEX_ATTRIB_FLAG_TEX_COORD ) ;
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-07-25 17:48:22 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_POSITION , 2 , GL_FLOAT , GL_FALSE , 0 , vertices ) ;
2014-05-09 03:34:26 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_TEX_COORD , 2 , GL_FLOAT , GL_FALSE , 0 , coordinates ) ;
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
2014-05-13 10:12:56 +08:00
GL : : enableVertexAttribs ( GL : : VERTEX_ATTRIB_FLAG_POSITION | GL : : VERTEX_ATTRIB_FLAG_TEX_COORD ) ;
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-07-25 17:48:22 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_POSITION , 2 , GL_FLOAT , GL_FALSE , 0 , vertices ) ;
2014-05-09 03:34:26 +08:00
glVertexAttribPointer ( GLProgram : : VERTEX_ATTRIB_TEX_COORD , 2 , GL_FLOAT , GL_FALSE , 0 , coordinates ) ;
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
{
2014-07-28 10:38:22 +08:00
Image : : setPVRImagesHavePremultipliedAlpha ( haveAlphaPremultiplied ) ;
2010-07-15 18:15:00 +08:00
}
2014-07-25 18:19:04 +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-12-05 17:19:01 +08:00
CCASSERT ( _pixelsWide = = ccNextPOT ( _pixelsWide ) & & _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 ;
2014-03-25 16:19:34 +08:00
# if CC_ENABLE_CACHE_TEXTURE_DATA
VolatileTextureMgr : : setHasMipmaps ( this , _hasMipmaps ) ;
# endif
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-12-05 17:19:01 +08:00
CCASSERT ( ( _pixelsWide = = ccNextPOT ( _pixelsWide ) | | texParams . wrapS = = GL_CLAMP_TO_EDGE ) & &
( _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
{
2014-03-27 15:35:51 +08:00
if ( ! _antialiasEnabled )
{
return ;
}
_antialiasEnabled = false ;
if ( _name = = 0 )
{
return ;
}
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
{
2014-03-27 15:35:51 +08:00
if ( _antialiasEnabled )
{
return ;
}
_antialiasEnabled = true ;
if ( _name = = 0 )
{
return ;
}
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
{
2016-06-15 10:43:15 +08:00
switch ( _pixelFormat )
{
case Texture2D : : PixelFormat : : RGBA8888 :
return " RGBA8888 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : RGB888 :
return " RGB888 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : RGB565 :
return " RGB565 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : RGBA4444 :
return " RGBA4444 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : RGB5A1 :
return " RGB5A1 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : AI88 :
return " AI88 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : A8 :
return " A8 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : I8 :
return " I8 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : PVRTC4 :
return " PVRTC4 " ;
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
case Texture2D : : PixelFormat : : PVRTC2 :
return " PVRTC2 " ;
2012-06-13 16:20:58 +08:00
2016-02-13 00:04:30 +08:00
case Texture2D : : PixelFormat : : PVRTC2A :
return " PVRTC2A " ;
case Texture2D : : PixelFormat : : PVRTC4A :
return " PVRTC4A " ;
case Texture2D : : PixelFormat : : ETC :
return " ETC " ;
case Texture2D : : PixelFormat : : S3TC_DXT1 :
return " S3TC_DXT1 " ;
case Texture2D : : PixelFormat : : S3TC_DXT3 :
return " S3TC_DXT3 " ;
case Texture2D : : PixelFormat : : S3TC_DXT5 :
return " S3TC_DXT5 " ;
case Texture2D : : PixelFormat : : ATC_RGB :
return " ATC_RGB " ;
case Texture2D : : PixelFormat : : ATC_EXPLICIT_ALPHA :
return " ATC_EXPLICIT_ALPHA " ;
case Texture2D : : PixelFormat : : ATC_INTERPOLATED_ALPHA :
return " ATC_INTERPOLATED_ALPHA " ;
2016-06-15 10:43:15 +08:00
default :
CCASSERT ( false , " unrecognized pixel format " ) ;
CCLOG ( " stringForFormat: %ld, cannot give useful result " , ( long ) _pixelFormat ) ;
break ;
}
2012-06-13 16:20:58 +08:00
2016-06-15 10:43:15 +08:00
return nullptr ;
2012-06-13 16:20:58 +08:00
}
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
{
2014-10-15 05:21:02 +08:00
if ( format = = PixelFormat : : NONE | | format = = PixelFormat : : DEFAULT )
2013-07-25 21:35:00 +08:00
{
return 0 ;
}
2016-06-15 10:43:15 +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
{
2016-06-15 10:43:15 +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
}
2015-05-21 16:04:37 +08:00
void Texture2D : : addSpriteFrameCapInset ( SpriteFrame * spritframe , const Rect & capInsets )
{
if ( nullptr = = _ninePatchInfo )
{
2015-12-16 14:02:55 +08:00
_ninePatchInfo = new ( std : : nothrow ) NinePatchInfo ;
2015-05-21 16:04:37 +08:00
}
if ( nullptr = = spritframe )
{
_ninePatchInfo - > capInsetSize = capInsets ;
}
else
{
_ninePatchInfo - > capInsetMap [ spritframe ] = capInsets ;
}
}
bool Texture2D : : isContain9PatchInfo ( ) const
{
return nullptr ! = _ninePatchInfo ;
}
const Rect & Texture2D : : getSpriteFrameCapInset ( cocos2d : : SpriteFrame * spriteFrame ) const
{
CCASSERT ( _ninePatchInfo ! = nullptr ,
" Can't get the sprite frame capInset when the texture contains no 9-patch info. " ) ;
if ( nullptr = = spriteFrame )
{
return this - > _ninePatchInfo - > capInsetSize ;
}
else
{
2015-06-23 15:42:58 +08:00
auto & capInsetMap = this - > _ninePatchInfo - > capInsetMap ;
2015-05-21 16:04:37 +08:00
if ( capInsetMap . find ( spriteFrame ) ! = capInsetMap . end ( ) )
{
return capInsetMap . at ( spriteFrame ) ;
}
else
{
return this - > _ninePatchInfo - > capInsetSize ;
}
}
}
void Texture2D : : removeSpriteFrameCapInset ( SpriteFrame * spriteFrame )
{
if ( nullptr ! = this - > _ninePatchInfo )
{
auto capInsetMap = this - > _ninePatchInfo - > capInsetMap ;
if ( capInsetMap . find ( spriteFrame ) ! = capInsetMap . end ( ) )
{
capInsetMap . erase ( spriteFrame ) ;
}
}
}
2011-07-05 10:47:25 +08:00
2016-07-25 17:31:54 +08:00
/// halx99 spec, ANDROID ETC1 ALPHA supports.
void Texture2D : : setAlphaTexture ( Texture2D * alphaTexture )
{
if ( alphaTexture ! = nullptr ) {
this - > _alphaTexture = alphaTexture ;
this - > _alphaTexture - > retain ( ) ;
2016-10-17 10:12:54 +08:00
this - > _hasPremultipliedAlpha = true ; // PremultipliedAlpha should be true.
2016-07-25 17:31:54 +08:00
}
}
2017-02-04 18:00:21 +08:00
Texture2D * Texture2D : : getAlphaTexture ( ) const
{
return _alphaTexture ;
}
2012-04-18 18:43:45 +08:00
NS_CC_END