issue #536, integrate the CCTexturePVR to project, update from 0.99.5 to 1.0.0, compile successfully on ios & android. Haven't test on other platforms yet.

This commit is contained in:
Walzer 2011-07-19 15:14:59 +08:00
parent 0817d59edf
commit bc44855091
14 changed files with 891 additions and 582 deletions

View File

@ -89,6 +89,7 @@ text_input_node/CCTextFieldTTF.cpp \
textures/CCTexture2D.cpp \
textures/CCTextureAtlas.cpp \
textures/CCTextureCache.cpp \
textures/CCTexturePVR.cpp \
tileMap_parallax_nodes/CCParallaxNode.cpp \
tileMap_parallax_nodes/CCTMXLayer.cpp \
tileMap_parallax_nodes/CCTMXObjectGroup.cpp \

View File

@ -1,73 +0,0 @@
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#if 0 // PVR TEXTURE CANNOT CROSS PLATFORM
#ifndef __CCPVRTEXTURE_H__
#define __CCPVRTEXTURE_H__
#include <string>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include "CCObject.h"
#include "CCMutableArray.h"
namespace cocos2d {
class CCData;
class CCPVRTexture : public CCObject
{
protected:
CCMutableArray<CCData*> * m_pImageData;
public:
CCPVRTexture();
virtual ~CCPVRTexture();
CCPVRTexture * initWithContentsOfFile(const char* path);
// @todo CCPVRTexture * initWithContentsOfURL(NSURL *url);
static CCPVRTexture * pvrTextureWithContentsOfFile(const char* path);
// @todo static CCPVRTexture * pvrTextureWithContentsOfURL(NSURL *url);
CC_PROPERTY_READONLY(GLuint, m_uName, Name)
CC_PROPERTY_READONLY(unsigned int, m_uWidth, Width)
CC_PROPERTY_READONLY(unsigned int, m_uHeight, Height)
CC_PROPERTY_READONLY(GLenum, m_uInternalFormat, InternalFormat)
CC_PROPERTY_READONLY(bool, m_bHasAlpha, HasAlpha)
// cocos2d integration
CC_PROPERTY(bool, m_bRetainName, RetainName);
private:
bool unpackPVRData(CCData *data);
bool createGLTexture();
};
}//namespace cocos2d
#endif //__CCPVRTEXTURE_H__
#endif

View File

@ -157,16 +157,17 @@ public:
/** returns the content size of the texture in points */
CCSize getContentSize(void);
#ifdef _POWERVR_SUPPORT_
#ifdef CC_SUPPORT_PVRTC
/**
Extensions to make it easy to create a CCTexture2D object from a PVRTC file
Note that the generated textures don't have their alpha premultiplied - use the blending mode (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
*/
/** Initializes a texture from a PVRTC buffer */
bool initWithPVRTCData(const void* data, int level, int bpp, bool hasAlpha, int length);
/** Initializes a texture from a PVRTC file */
bool initWithPVRTCFile(const char* file);
#endif
bool initWithPVRTCData(const void *data, int level, int bpp, bool hasAlpha, int length, CCTexture2DPixelFormat pixelFormat);
#endif // CC_SUPPORT_PVRTC
/** Initializes a texture from a PVR file */
bool initWithPVRFile(const char* file);
/** sets the min filter, mag filter, wrap s and wrap t texture parameters.
If the texture size is NPOT (non power of 2), then in can only use GL_CLAMP_TO_EDGE in GL_TEXTURE_WRAP_{S,T}.
@ -203,6 +204,8 @@ public:
unsigned int bitsPerPixelForFormat();
void setPVRImagesHavePremultipliedAlpha(bool haveAlphaPremultiplied);
/** sets the default pixel format for UIImages that contains alpha channel.
If the UIImage contains alpha channel, then the options are:
- generate 32-bit textures: kCCTexture2DPixelFormat_RGBA8888 (default one)
@ -228,6 +231,9 @@ public:
private:
bool initPremultipliedATextureWithImage(CCImage * image, unsigned int pixelsWide, unsigned int pixelsHigh);
// By default PVR images are treated as if they don't have the alpha channel premultiplied
bool m_bPVRHaveAlphaPremultiplied;
};
}//namespace cocos2d

View File

@ -142,7 +142,7 @@ public:
*/
void dumpCachedTextureInfo();
#if _POWERVR_SUPPORT_
#ifdef CC_SUPPORT_PVRTC
/** Returns a Texture2D object given an PVRTC RAW filename
* If the file image was not previously loaded, it will create a new CCTexture2D
* object and it will return it. Otherwise it will return a reference of a previosly loaded image
@ -152,13 +152,13 @@ public:
* hasAlpha: whether or not the image contains alpha channel
*/
CCTexture2D* addPVRTCImage(const char* fileimage, int bpp, bool hasAlpha, int width);
#endif // CC_SUPPORT_PVRTC
/** Returns a Texture2D object given an PVRTC filename
/** Returns a Texture2D object given an PVR filename
* If the file image was not previously loaded, it will create a new CCTexture2D
* object and it will return it. Otherwise it will return a reference of a previosly loaded image
*/
CCTexture2D* addPVRTCImage(const char* fileimage);
#endif
CCTexture2D* addPVRImage(const char* filename);
/** Reload all textures
It's only useful when the value of CC_ENABLE_CACHE_TEXTTURE_DATA is 1

139
cocos2dx/include/CCTexturePVR.h Executable file
View File

@ -0,0 +1,139 @@
/****************************************************************************
Copyright (c) 2011 Jirka Fajfr for cocos2d-x
Copyright (c) 2010 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCPVRTEXTURE_H__
#define __CCPVRTEXTURE_H__
#include <string>
#include <stdint.h>
#include "CCGL.h"
#include "CCObject.h"
#include "CCMutableArray.h"
namespace cocos2d {
//Forward definition for CCData
class CCData;
/**
@brief Structure which can tell where mimap begins and how long is it
*/
struct CCPVRMipmap {
unsigned char *address;
unsigned int len;
};
/**
@brief Detemine how many mipmaps can we have.
Its same as define but it respects namespaces
*/
enum {
CC_PVRMIPMAP_MAX = 16,
};
/** CCTexturePVR
Object that loads PVR images.
Supported PVR formats:
- RGBA8888
- BGRA8888
- RGBA4444
- RGBA5551
- RGB565
- A8
- I8
- AI88
- PVRTC 4BPP
- PVRTC 2BPP
Limitations:
Pre-generated mipmaps, such as PVR textures with mipmap levels embedded in file,
are only supported if all individual sprites are of _square_ size.
To use mipmaps with non-square textures, instead call CCTexture2D#generateMipmap on the sheet texture itself
(and to save space, save the PVR sprite sheet without mip maps included).
*/
class CCTexturePVR : public CCObject
{
public:
CCTexturePVR();
virtual ~CCTexturePVR();
/** initializes a CCTexturePVR with a path */
bool initWithContentsOfFile(const char* path);
/** creates and initializes a CCTexturePVR with a path */
static CCTexturePVR * pvrTextureWithContentsOfFile(const char* path);
CC_PROPERTY_READONLY(GLuint, m_uName, Name)
CC_PROPERTY_READONLY(unsigned int, m_uWidth, Width)
CC_PROPERTY_READONLY(unsigned int, m_uHeight, Height)
CC_PROPERTY_READONLY(CCTexture2DPixelFormat, m_eFormat, Format)
CC_PROPERTY_READONLY(bool, m_bHasAlpha, HasAlpha)
// cocos2d integration
CC_PROPERTY(bool, m_bRetainName, RetainName);
protected:
/*
Unpacks data (data of pvr texture file) and determine
how many mipmaps it uses (m_uNumberOfMipmaps). Adresses
of mimaps (m_asMipmaps). And basic data like size, format
and alpha presence
*/
bool unpackPVRData(unsigned char* data, unsigned int len);
/*
Binds all mipmaps to the GL state machine as separate
textures
*/
bool createGLTexture();
/*
Index to the tableFormats array. Which tells us what exact
format is file which initializes this object.
*/
unsigned int m_uTableFormatIndex;
/*
How many mipmaps do we have. It must be at least one
when proper initialization finishes
*/
unsigned int m_uNumberOfMipmaps;
/*
Makrs for mipmaps. Each entry contains position in file
and lenght of data which represents one mipmap.
*/
struct CCPVRMipmap m_asMipmaps[CC_PVRMIPMAP_MAX];
};
}//namespace cocos2d
#endif //__CCPVRTEXTURE_H__

View File

@ -77,7 +77,7 @@ THE SOFTWARE.
#include "CCActionPageTurn3D.h"
#include "CCTransitionPageTurn.h"
#include "CCTexture2D.h"
#include "CCPVRTexture.h"
#include "CCTexturePVR.h"
#include "CCTransitionRadial.h"
#include "CCActionProgressTimer.h"
#include "CCTouchDispatcher.h"

View File

@ -116,7 +116,7 @@ public:
///////////////////////////////////////////////////
// interfaces on ios
///////////////////////////////////////////////////
int ccLoadFileIntoMemory(const char *filename, unsigned char **out);
static int ccLoadFileIntoMemory(const char *filename, unsigned char **out);
};
class CCFileData

View File

@ -54,6 +54,7 @@ There are config below:
#define CC_TARGET_PLATFORM CC_PLATFORM_IOS
#define CC_SUPPORT_MULTITHREAD 0
#define CC_SUPPORT_UNICODE 0
#define CC_SUPPORT_PVRTC
#endif
// android

View File

@ -256,7 +256,7 @@ namespace cocos2d {
int CCFileUtils::ccLoadFileIntoMemory(const char *filename, unsigned char **out)
{
CCAssert( out, "ccLoadFileIntoMemory: invalid 'out' parameter");
CCAssert( &*out, "ccLoadFileIntoMemory: invalid 'out' parameter");
CCAssert( &*out, "ccLoadFileIntoMemory: invalid 'out' parameter");
size_t size = 0;
FILE *f = fopen(filename, "rb");

View File

@ -1,294 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008 Apple Inc. All Rights Reserved.
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.
****************************************************************************/
#if 0 // PVR TEXTURE CANNOT CROSS PLATFORM
#include "CCPVRTexture.h"
#include "ccMacros.h"
#include "CCData.h"
namespace cocos2d {
#define PVR_TEXTURE_FLAG_TYPE_MASK 0xff
static char* gPVRTexIdentifier[] = {"PVR!"};
enum
{
kPVRTextureFlagTypePVRTC_2 = 24,
kPVRTextureFlagTypePVRTC_4
};
typedef struct _PVRTexHeader
{
unsigned int headerLength;
unsigned int height;
unsigned int width;
unsigned int numMipmaps;
unsigned int flags;
unsigned int dataLength;
unsigned int bpp;
unsigned int bitmaskRed;
unsigned int bitmaskGreen;
unsigned int bitmaskBlue;
unsigned int bitmaskAlpha;
unsigned int pvrTag;
unsigned int numSurfs;
} PVRTexHeader;
CCPVRTexture::CCPVRTexture()
{
}
CCPVRTexture::~CCPVRTexture()
{
CCLOGINFO( "cocos2d: deallocing CCPVRTexture" );
m_pImageData->removeAllObjects();
CC_SAFE_DELETE(m_pImageData)
if (m_uName != 0 && ! m_bRetainName )
glDeleteTextures(1, &m_uName);
}
GLuint CCPVRTexture::getName()
{
return m_uName;
}
unsigned int CCPVRTexture::getWidth()
{
return m_uWidth;
}
unsigned int CCPVRTexture::getHeight()
{
return m_uHeight;
}
GLenum CCPVRTexture::getInternalFormat()
{
return m_uInternalFormat;
}
bool CCPVRTexture::getHasAlpha()
{
return m_bHasAlpha;
}
bool CCPVRTexture::getRetainName()
{
return m_bRetainName;
}
void CCPVRTexture::setRetainName(bool var)
{
m_bRetainName = var;
}
/** @todo CCData uint8_t
- (BOOL)unpackPVRData:(CCData *)data
{
BOOL success = FALSE;
PVRTexHeader *header = NULL;
uint32_t flags, pvrTag;
uint32_t dataLength = 0, dataOffset = 0, dataSize = 0;
uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0;
uint32_t width = 0, height = 0, bpp = 4;
uint8_t *bytes = NULL;
uint32_t formatFlags;
header = (PVRTexHeader *)[data bytes];
pvrTag = CFSwapInt32LittleToHost(header->pvrTag);
if ((uint32_t)gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) ||
(uint32_t)gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) ||
(uint32_t)gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) ||
(uint32_t)gPVRTexIdentifier[3] != ((pvrTag >> 24) & 0xff))
{
return FALSE;
}
flags = CFSwapInt32LittleToHost(header->flags);
formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
if (formatFlags == kPVRTextureFlagTypePVRTC_4 || formatFlags == kPVRTextureFlagTypePVRTC_2)
{
[_imageData removeAllObjects];
if (formatFlags == kPVRTextureFlagTypePVRTC_4)
_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
else if (formatFlags == kPVRTextureFlagTypePVRTC_2)
_internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
_width = width = CFSwapInt32LittleToHost(header->width);
_height = height = CFSwapInt32LittleToHost(header->height);
if (CFSwapInt32LittleToHost(header->bitmaskAlpha))
_hasAlpha = TRUE;
else
_hasAlpha = FALSE;
dataLength = CFSwapInt32LittleToHost(header->dataLength);
bytes = ((uint8_t *)[data bytes]) + sizeof(PVRTexHeader);
// Calculate the data size for each texture level and respect the minimum number of blocks
while (dataOffset < dataLength)
{
if (formatFlags == kPVRTextureFlagTypePVRTC_4)
{
blockSize = 4 * 4; // Pixel by pixel block size for 4bpp
widthBlocks = width / 4;
heightBlocks = height / 4;
bpp = 4;
}
else
{
blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
widthBlocks = width / 8;
heightBlocks = height / 4;
bpp = 2;
}
// Clamp to minimum number of blocks
if (widthBlocks < 2)
widthBlocks = 2;
if (heightBlocks < 2)
heightBlocks = 2;
dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8);
[_imageData addObject:[CCData dataWithBytes:bytes+dataOffset length:dataSize]];
dataOffset += dataSize;
width = MAX(width >> 1, 1);
height = MAX(height >> 1, 1);
}
success = TRUE;
}
return success;
}*/
bool CCPVRTexture::createGLTexture()
{
int width = m_uWidth;
int height = m_uHeight;
/// @todo CCData *data;
GLenum err;
if (m_pImageData->count() > 0)
{
if (m_uName != 0)
glDeleteTextures(1, &m_uName);
glGenTextures(1, &m_uName);
glBindTexture(GL_TEXTURE_2D, m_uName);
}
for (unsigned int i=0; i < m_pImageData->count(); i++)
{
/// @todo CCData data = m_pImageData->getObjectAtIndex(i);
/// @todo CCData glCompressedTexImage2D(GL_TEXTURE_2D, i, m_uInternalFormat, width, height, 0, [data length], [data bytes]);
err = glGetError();
if (err != GL_NO_ERROR)
{
CCLOG("Error uploading compressed texture level: %u. glError: %u", i, err);
return false;
}
width = MAX(width >> 1, 1);
height = MAX(height >> 1, 1);
}
m_pImageData->removeAllObjects();
return true;
}
CCPVRTexture * CCPVRTexture::initWithContentsOfFile(const char* path)
{
/** @todo CCData*/
CCData *data = CCData::dataWithContentsOfFile(path);
m_pImageData = new CCMutableArray<CCData*>(10);
m_uName = 0;
m_uWidth = m_uHeight = 0;
m_uInternalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
m_bHasAlpha = false;
m_bRetainName = false; // cocos2d integration
/// @todo
// if (!data || ![self unpackPVRData:data] || ![self createGLTexture])
// {
// [self release];
// self = nil;
// }
return this;
}
/** @todo NSURL
- (id)initWithContentsOfURL:(NSURL *)url
{
if (![url isFileURL])
{
CCLOG(@"cocos2d: CCPVRTexture: Only files are supported");
[self release];
return nil;
}
return [self initWithContentsOfFile:[url path]];
}*/
CCPVRTexture * CCPVRTexture::pvrTextureWithContentsOfFile(const char* path)
{
CCPVRTexture * pTexture = new CCPVRTexture();
pTexture->initWithContentsOfFile(path);
pTexture->autorelease();
return pTexture;
}
/** @todo NSURL
+ (id)pvrTextureWithContentsOfURL:(NSURL *)url
{
if (![url isFileURL])
return nil;
return [CCPVRTexture pvrTextureWithContentsOfFile:[url path]];
}*/
}//namespace cocos2d
#endif

View File

@ -40,10 +40,7 @@ THE SOFTWARE.
#include "CCGL.h"
#include "support/ccUtils.h"
#include "platform/CCPlatformMacros.h"
#ifdef _POWERVR_SUPPORT_
#include "CCPVRTexture.h"
#endif
#include "CCTexturePVR.h"
#if CC_ENABLE_CACHE_TEXTTURE_DATA
#include "CCTextureCache.h"
@ -68,6 +65,7 @@ CCTexture2D::CCTexture2D()
, m_fMaxS(0.0)
, m_fMaxT(0.0)
, m_bHasPremultipliedAlpha(false)
, m_bPVRHaveAlphaPremultiplied(true)
{
}
@ -506,12 +504,11 @@ void CCTexture2D::drawInRect(CCRect rect)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
// implementation CCTexture2D (PVRTC)
#ifdef _POWERVR_SUPPORT_
bool CCTexture2D::initWithPVRTCData(const void *data, int level, int bpp, bool hasAlpha, int length)
#ifdef CC_SUPPORT_PVRTC
// implementation CCTexture2D (PVRTC);
bool CCTexture2D::initWithPVRTCData(const void *data, int level, int bpp, bool hasAlpha, int length, CCTexture2DPixelFormat pixelFormat)
{
if( !(CCPlatformConfiguration::sharedConfiguration()->isSupportsPVRTC()) )
if( !(CCConfiguration::sharedConfiguration()->isSupportsPVRTC()) )
{
CCLOG("cocos2d: WARNING: PVRTC images is not supported.");
this->release();
@ -540,46 +537,52 @@ bool CCTexture2D::initWithPVRTCData(const void *data, int level, int bpp, bool h
m_uPixelsHigh = length;
m_fMaxS = 1.0f;
m_fMaxT = 1.0f;
m_bHasPremultipliedAlpha = m_bPVRHaveAlphaPremultiplied;
m_ePixelFormat = pixelFormat;
return true;
}
#endif // CC_SUPPORT_PVRTC
CCTexture2D * CCTexture2D::initWithPVRTCFile(const char* file)
bool CCTexture2D::initWithPVRFile(const char* file)
{
if (! CCPlatformConfiguration::sharedConfiguration()->isSupportsPVRTC())
{
CCLOG("cocos2d: WARNING: PVRTC images is not supported");
this->release();
return false;
}
bool bRet = false;
// nothing to do with CCObject::init
CCPVRTexture *pvr = new CCPVRTexture();
pvr = pvr->initWithContentsOfFile(file);
if( pvr )
{
pvr->setRetainName(true); // don't dealloc texture on release
CCTexturePVR *pvr = new CCTexturePVR;
bRet = pvr->initWithContentsOfFile(file);
m_uName = pvr->getName(); // texture id
m_fMaxS = 1.0f;
m_fMaxT = 1.0f;
m_uPixelsWide = pvr->getWidth(); // width
m_uPixelsHigh = pvr->getHeight(); // height
/// be careful : unsigned int to float
m_tContentSize = CCSizeMake((float)(m_uPixelsWide), (float)(m_uPixelsHigh));
if (bRet)
{
pvr->setRetainName(true); // don't dealloc texture on release
pvr->release();
m_uName = pvr->getName();
m_fMaxS = 1.0f;
m_fMaxT = 1.0f;
m_uPixelsWide = pvr->getWidth();
m_uPixelsHigh = pvr->getHeight();
m_tContentSize = CCSizeMake(m_uPixelsWide, m_uPixelsHigh);
m_bHasPremultipliedAlpha = m_bPVRHaveAlphaPremultiplied;
m_ePixelFormat = pvr->getFormat();
this->setAntiAliasTexParameters();
}
else
{
CCLOG("cocos2d: Couldn't load PVR image %s", file);
}
pvr->release();
return bRet;
this->setAntiAliasTexParameters();
}
else
{
CCLOG("cocos2d: Couldn't load PVR image");
this->release();
return false;
}
return true;
}
#endif
void CCTexture2D::setPVRImagesHavePremultipliedAlpha(bool haveAlphaPremultiplied)
{
m_bPVRHaveAlphaPremultiplied = haveAlphaPremultiplied;
}
//
// Use to apply MIN/MAG filter

View File

@ -197,14 +197,11 @@ CCTexture2D * CCTextureCache::addImage(const char * path)
lowerCase[i] = tolower(lowerCase[i]);
}
// all images are handled by UIImage except PVR extension that is handled by our own handler
// if ( [[path lowercaseString] hasSuffix:@".pvr"] )
do
{
if (std::string::npos != lowerCase.find(".pvr"))
{
#ifdef _POWERVR_SUPPORT_
texture = this->addPVRTCImage(fullpath.c_str());
#endif
texture = this->addPVRImage(fullpath.c_str());
}
// Issue #886: TEMPORARY FIX FOR TRANSPARENT JPEGS IN IOS4
else if (std::string::npos != lowerCase.find(".jpg") || std::string::npos != lowerCase.find(".jpeg"))
@ -269,15 +266,17 @@ CCTexture2D * CCTextureCache::addImage(const char * path)
return texture;
}
#ifdef _POWERVR_SUPPORT_
#ifdef CC_SUPPORT_PVRTC
CCTexture2D* CCTextureCache::addPVRTCImage(const char* path, int bpp, bool hasAlpha, int width)
{
CCAssert(path != NULL, "TextureCache: fileimage MUST not be nill");
CCAssert( bpp==2 || bpp==4, "TextureCache: bpp must be either 2 or 4");
CCTexture2D * texture;
std::string temp(path);
CCFileUtils::ccRemoveHDSuffixFromFile(temp);
if ( (texture = m_pTextures->objectForKey(temp)) )
{
return texture;
@ -288,8 +287,9 @@ CCTexture2D* CCTextureCache::addPVRTCImage(const char* path, int bpp, bool hasAl
CCData * data = CCData::dataWithContentsOfFile(fullpath);
texture = new CCTexture2D();
texture->initWithPVRTCData(data->bytes(), 0, bpp, hasAlpha, width);
if( texture )
if( texture->initWithPVRTCData(data->bytes(), 0, bpp, hasAlpha, width,
(bpp==2 ? kCCTexture2DPixelFormat_PVRTC2 : kCCTexture2DPixelFormat_PVRTC4)))
{
m_pTextures->setObject(texture, temp);
texture->autorelease();
@ -302,33 +302,37 @@ CCTexture2D* CCTextureCache::addPVRTCImage(const char* path, int bpp, bool hasAl
return texture;
}
#endif // CC_SUPPORT_PVRTC
CCTexture2D * CCTextureCache::addPVRTCImage(const char* fileimage)
CCTexture2D * CCTextureCache::addPVRImage(const char* path)
{
CCAssert(fileimage != NULL, "TextureCache: fileimage MUST not be nill");
CCAssert(path != NULL, "TextureCache: fileimage MUST not be nill");
CCTexture2D * texture;
std::string key(fileimage);
if( (texture = m_pTextures->objectForKey(key)) )
CCTexture2D * tex;
std::string key(path);
// remove possible -HD suffix to prevent caching the same image twice (issue #1040)
CCFileUtils::ccRemoveHDSuffixFromFile(key);
if( (tex = m_pTextures->objectForKey(key)) )
{
return texture;
return tex;
}
texture = new CCTexture2D();
texture = texture->initWithPVRTCFile(fileimage);
if( texture )
// Split up directory and filename
std::string fullpath = CCFileUtils::fullPathFromRelativePath(key.c_str());
tex = new CCTexture2D();
if( tex->initWithPVRFile(fullpath.c_str()) )
{
m_pTextures-> setObject( texture, key);
texture->autorelease();
m_pTextures->setObject(tex, key);
tex->autorelease();
}
else
{
CCLOG("cocos2d: Couldn't add PVRTCImage:%s in CCTextureCache",fileimage);
CCLOG("cocos2d: Couldn't add PVRImage:%s in CCTextureCache",key);
}
return texture;
return tex;
}
#endif
/* @todo CGImageRef
-(CCTexture2D*) addCGImage: (CGImageRef) imageref forKey: (string & )key

View File

@ -0,0 +1,522 @@
/****************************************************************************
Copyright (c) 2011 Jirka Fajfr for cocos2d-x
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008 Apple Inc. All Rights Reserved.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCTexture2D.h"
#include "CCTexturePVR.h"
#include "ccMacros.h"
#include "CCData.h"
#include "CCConfiguration.h"
#include "support/ccUtils.h"
#include "CCStdC.h"
#include "CCFileUtils.h"
#include "support/zip_support/ZipUtils.h"
#include <cctype>
namespace cocos2d {
/*
When define returns true it means that our architecture
uses big endiant
NOTE: this should be placed somewhere in macros
*/
#define CC_HOST_IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
/*
Helper function which converts 4-byte little endian
integral number to the machine native number representation
It should work same as apples CFSwapInt32LittleToHost(..)
*/
static unsigned int CCSwapInt32LittleToHost(unsigned int i)
{
/*
When architecture is big endian (ARM) reorder bytes
otherwise return same numbeer
*/
if (CC_HOST_IS_BIG_ENDIAN == true)
{
return ((i&0xff)<<24) + ((i&0xff00)<<8) + ((i&0xff0000)>>8) + ((i>>24)&0xff);
}
else
{
return i;
}
}
#define PVR_TEXTURE_FLAG_TYPE_MASK 0xff
#define PVR_TEXTURE_FLAG_FLIPPED_MASK 0x10000
// Values taken from PVRTexture.h from http://www.imgtec.com
enum {
kPVRTextureFlagMipmap = (1<<8), // has mip map levels
kPVRTextureFlagTwiddle = (1<<9), // is twiddled
kPVRTextureFlagBumpmap = (1<<10), // has normals encoded for a bump map
kPVRTextureFlagTiling = (1<<11), // is bordered for tiled pvr
kPVRTextureFlagCubemap = (1<<12), // is a cubemap/skybox
kPVRTextureFlagFalseMipCol = (1<<13), // are there false coloured MIP levels
kPVRTextureFlagVolume = (1<<14), // is this a volume texture
kPVRTextureFlagAlpha = (1<<15), // v2.1 is there transparency info in the texture
kPVRTextureFlagVerticalFlip = (1<<16), // v2.1 is the texture vertically flipped
};
/*
PVR header contains special field called PVRTag. This tag
is used only to determine that passed file is really pvrt.
Its set of 4 numbers. Each number casted to the char
must correspond to the "PVR!" string
*/
static unsigned int gPVRTexIdentifier[] = { 'P', 'V', 'R', '!'};
/*
List of formats in pvr container
*/
enum
{
kPVRTextureFlagTypeRGBA_4444= 0x10,
kPVRTextureFlagTypeRGBA_5551,
kPVRTextureFlagTypeRGBA_8888,
kPVRTextureFlagTypeRGB_565,
kPVRTextureFlagTypeRGB_555, // unsupported
kPVRTextureFlagTypeRGB_888, // unsupported
kPVRTextureFlagTypeI_8,
kPVRTextureFlagTypeAI_88,
kPVRTextureFlagTypePVRTC_2,
kPVRTextureFlagTypePVRTC_4,
kPVRTextureFlagTypeBGRA_8888,
kPVRTextureFlagTypeA_8,
};
/*
Helps us to convert pvr format to the gl compatible bitspaces
WARNING!! OpenGL ES 1.1. does not support GL_BGRA format. Its PowerVR
extension and it will work only on PowerVR chipsets. It means that
kPVRTextureFlagTypeBGRA_8888 can be used only on apple devices (or PowerVR compatible)
*/
static const unsigned int tableFormats[][7] = {
// - PVR texture format
// - OpenGL internal format
// - OpenGL format
// - OpenGL type
// - bpp
// - compressed
// - Cocos2d texture format constant
{ kPVRTextureFlagTypeRGBA_4444, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 16, false, kCCTexture2DPixelFormat_RGBA4444 },
{ kPVRTextureFlagTypeRGBA_5551, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 16, false, kCCTexture2DPixelFormat_RGB5A1 },
{ kPVRTextureFlagTypeRGBA_8888, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 32, false, kCCTexture2DPixelFormat_RGBA8888 },
{ kPVRTextureFlagTypeRGB_565, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 16, false, kCCTexture2DPixelFormat_RGB565 },
{ kPVRTextureFlagTypeA_8, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, 8, false, kCCTexture2DPixelFormat_A8 },
{ kPVRTextureFlagTypeI_8, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 8, false, kCCTexture2DPixelFormat_I8 },
{ kPVRTextureFlagTypeAI_88, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 16, false, kCCTexture2DPixelFormat_AI88 },
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
{ kPVRTextureFlagTypePVRTC_2, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, -1, -1, 2, true, kCCTexture2DPixelFormat_PVRTC2 },
{ kPVRTextureFlagTypePVRTC_4, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, -1, -1, 4, true, kCCTexture2DPixelFormat_PVRTC4 },
{ kPVRTextureFlagTypeBGRA_8888, GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE, 32, false, kCCTexture2DPixelFormat_RGBA8888 },
#endif
};
//Tells How large is tableFormats
#define MAX_TABLE_ELEMENTS (sizeof(tableFormats) / sizeof(tableFormats[0]))
/*
Helper enum to traverse tableFormats
*/
enum {
kCCInternalPVRTextureFormat,
kCCInternalOpenGLInternalFormat,
kCCInternalOpenGLFormat,
kCCInternalOpenGLType,
kCCInternalBPP,
kCCInternalCompressedImage,
kCCInternalCCTexture2DPixelFormat,
};
/*
Official PVRT header
*/
typedef struct _PVRTexHeader
{
unsigned int headerLength;
unsigned int height;
unsigned int width;
unsigned int numMipmaps;
unsigned int flags;
unsigned int dataLength;
unsigned int bpp;
unsigned int bitmaskRed;
unsigned int bitmaskGreen;
unsigned int bitmaskBlue;
unsigned int bitmaskAlpha;
unsigned int pvrTag;
unsigned int numSurfs;
} PVRTexHeader;
CCTexturePVR::CCTexturePVR() :
m_uTableFormatIndex(0),
m_uNumberOfMipmaps(0)
{
}
CCTexturePVR::~CCTexturePVR()
{
CCLOGINFO( "cocos2d: deallocing CCTexturePVR" );
if (m_uName != 0 && ! m_bRetainName )
glDeleteTextures(1, &m_uName);
}
GLuint CCTexturePVR::getName()
{
return m_uName;
}
unsigned int CCTexturePVR::getWidth()
{
return m_uWidth;
}
unsigned int CCTexturePVR::getHeight()
{
return m_uHeight;
}
CCTexture2DPixelFormat CCTexturePVR::getFormat()
{
return m_eFormat;
}
bool CCTexturePVR::getHasAlpha()
{
return m_bHasAlpha;
}
bool CCTexturePVR::getRetainName()
{
return m_bRetainName;
}
void CCTexturePVR::setRetainName(bool var)
{
m_bRetainName = var;
}
bool CCTexturePVR::unpackPVRData(unsigned char* data, unsigned int len)
{
bool success = false;
PVRTexHeader *header = NULL;
unsigned int flags, pvrTag;
unsigned int dataLength = 0, dataOffset = 0, dataSize = 0;
unsigned int blockSize = 0, widthBlocks = 0, heightBlocks = 0;
unsigned int width = 0, height = 0, bpp = 4;
uint8_t *bytes = NULL;
unsigned int formatFlags;
//Cast first sizeof(PVRTexHeader) bytes of data stream as PVRTexHeader
header = (PVRTexHeader *)data;
//Make sure that tag is in correct formatting
pvrTag = CCSwapInt32LittleToHost(header->pvrTag);
/*
Check that given data really represents pvrtexture
[0] = 'P'
[1] = 'V'
[2] = 'R'
[3] = '!'
*/
if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) ||
gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) ||
gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) ||
gPVRTexIdentifier[3] != ((pvrTag >> 24) & 0xff))
{
return false;
}
CCConfiguration *configuration = CCConfiguration::sharedConfiguration();
//Get file flags (in correct byte order)
flags = CCSwapInt32LittleToHost(header->flags);
//Trim to only bites which are needed. Resulting flag is image format
formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
/*
When flags combined with flipped mask is not empty (zero).
It means that image is compressed as flipped. We don't
support automatic flipping.
*/
bool flipped = flags & kPVRTextureFlagVerticalFlip;
if ( flipped )
{
CCLOG("cocos2d: WARNING: Image is flipped. Regenerate it using PVRTexTool");
}
if ( ! configuration->isSupportsNPOT() &&
(header->width != ccNextPOT(header->width) || header->height != ccNextPOT(header->height)))
{
CCLOG("cocos2d: ERROR: Loding an NPOT texture (%dx%d) but is not supported on this device", header->width, header->height);
return false;
}
//Check that sides of texture are power of two
if(header->width != ccNextPOT(header->width) || header->height != ccNextPOT(header->height))
{
CCLOG("cocos2d: WARNING: PVR NPOT textures are not supported. Regenerate it.");
return false;
}
//Go thru format array
for (m_uTableFormatIndex = 0; m_uTableFormatIndex < (unsigned int)MAX_TABLE_ELEMENTS; m_uTableFormatIndex++)
{
//Does image format in table fits to the one parsed from header?
if (tableFormats[m_uTableFormatIndex][kCCInternalPVRTextureFormat] == formatFlags)
{
//Reset num of mipmaps
m_uNumberOfMipmaps = 0;
//Get size of maimap
m_uWidth = width = CCSwapInt32LittleToHost(header->width);
m_uHeight = height = CCSwapInt32LittleToHost(header->height);
//Do we use alpha ?
if (CCSwapInt32LittleToHost(header->bitmaskAlpha))
m_bHasAlpha = true;
else
m_bHasAlpha = false;
//Get ptr to where data starts..
dataLength = CCSwapInt32LittleToHost(header->dataLength);
//Move by size of header
bytes = ((unsigned char *)data) + sizeof(PVRTexHeader);
m_eFormat = (CCTexture2DPixelFormat)( tableFormats[m_uTableFormatIndex][kCCInternalCCTexture2DPixelFormat] );
bpp = tableFormats[m_uTableFormatIndex][kCCInternalBPP];
// Calculate the data size for each texture level and respect the minimum number of blocks
while (dataOffset < dataLength)
{
switch (formatFlags) {
case kPVRTextureFlagTypePVRTC_2:
blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
widthBlocks = width / 8;
heightBlocks = height / 4;
bpp = 2;
break;
case kPVRTextureFlagTypePVRTC_4:
blockSize = 4 * 4; // Pixel by pixel block size for 4bpp
widthBlocks = width / 4;
heightBlocks = height / 4;
bpp = 4;
break;
case kPVRTextureFlagTypeBGRA_8888:
if (CCConfiguration::sharedConfiguration()->isSupportsBGRA8888() == false)
{
CCLOG("cocos2d: TexturePVR. BGRA8888 not supported on this device");
return false;
}
default:
blockSize = 1;
widthBlocks = width;
heightBlocks = height;
bpp = tableFormats[m_uTableFormatIndex][kCCInternalBPP];
break;
}
// Clamp to minimum number of blocks
if (widthBlocks < 2)
widthBlocks = 2;
if (heightBlocks < 2)
heightBlocks = 2;
dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8);
float packetLength = (dataLength-dataOffset);
packetLength = packetLength > dataSize ? dataSize : packetLength;
//Make record to the mipmaps array and increment coutner
m_asMipmaps[m_uNumberOfMipmaps].address = bytes+dataOffset;
m_asMipmaps[m_uNumberOfMipmaps].len = packetLength;
m_uNumberOfMipmaps++;
//Check that we didn't overflow
CCAssert(m_uNumberOfMipmaps < CC_PVRMIPMAP_MAX,
"TexturePVR: Maximum number of mimpaps reached. Increate the CC_PVRMIPMAP_MAX value");
dataOffset += packetLength;
//Update width and height to the next lower power of two
width = MAX(width >> 1, 1);
height = MAX(height >> 1, 1);
}
//Mark pass as success
success = true;
break;
}
}
if (false == success)
{
CCLOG("cocos2d: WARNING: Unssupported PVR Pixel Format: 0x%2x", formatFlags);
}
return success;
}
bool CCTexturePVR::createGLTexture()
{
unsigned int width = m_uWidth;
unsigned int height = m_uHeight;
GLenum err;
if (m_uNumberOfMipmaps > 0)
{
if (m_uName != 0)
{
glDeleteTextures(1, &m_uName);
}
glGenTextures(1, &m_uName);
glBindTexture(GL_TEXTURE_2D, m_uName);
}
// Generate textures with mipmaps
for (unsigned int i = 0; i < m_uNumberOfMipmaps; ++i)
{
GLenum internalFormat = tableFormats[m_uTableFormatIndex][kCCInternalOpenGLInternalFormat];
GLenum format = tableFormats[m_uTableFormatIndex][kCCInternalOpenGLFormat];
GLenum type = tableFormats[m_uTableFormatIndex][kCCInternalOpenGLType];
bool compressed = tableFormats[m_uTableFormatIndex][kCCInternalCompressedImage] == 1;
if (compressed == true && CCConfiguration::sharedConfiguration()->isSupportsPVRTC() == false)
{
CCLOG("cocos2d: WARNING: PVRTC images are not supported");
return false;
}
unsigned char *data = m_asMipmaps[i].address;
unsigned int datalen = m_asMipmaps[i].len;
if (compressed == true)
{
glCompressedTexImage2D(GL_TEXTURE_2D, i, internalFormat, width, height, 0, datalen, data);
}
else
{
glTexImage2D(GL_TEXTURE_2D, i, internalFormat, width, height, 0, format, type, data);
}
if(i > 0 && (width != height || ccNextPOT(width) != width ) )
{
CCLOG("cocos2d: TexturePVR. WARNING. Mipmap level %lu is not squared. Texture won't render correctly. width=%lu != height=%lu", i, width, height);
}
err = glGetError();
if (err != GL_NO_ERROR)
{
CCLOG("cocos2d: TexturePVR: Error uploading compressed texture level: %u . glError: 0x%04X", (unsigned int)i, err);
return false;
}
//Update width and height to the next lower power of two
width = MAX(width >> 1, 1);
height = MAX(height >> 1, 1);
}
return true;
}
bool CCTexturePVR::initWithContentsOfFile(const char* path)
{
unsigned char* pvrdata = NULL;
int pvrlen = 0;
std::string lowerCase(path);
for (unsigned int i = 0; i < lowerCase.length(); ++i)
{
lowerCase[i] = tolower(lowerCase[i]);
}
if (lowerCase.find(".ccz") != -1)
{
pvrlen = ZipUtils::ccInflateCCZFile(path, &pvrdata);
}
else if (lowerCase.find(".gz") != -1)
{
pvrlen = ZipUtils::ccInflateGZipFile(path, &pvrdata);
}
else
{
pvrlen = CCFileUtils::ccLoadFileIntoMemory(path, &pvrdata);
}
if (pvrlen < 0)
{
this->release();
return false;
}
m_uNumberOfMipmaps = 0;
m_uName = 0;
m_uWidth = m_uHeight = 0;
m_bHasAlpha = false;
m_bRetainName = false; // cocos2d integration
if ( !unpackPVRData(pvrdata, pvrlen) || !createGLTexture() )
{
free(pvrdata);
this->release();
return false;
}
free(pvrdata);
return true;
}
CCTexturePVR * CCTexturePVR::pvrTextureWithContentsOfFile(const char* path)
{
CCTexturePVR * pTexture = new CCTexturePVR();
if(true == pTexture->initWithContentsOfFile(path))
{
pTexture->autorelease();
return pTexture;
}
else
{
return NULL;
}
}
}//namespace cocos2d

View File

@ -1 +1 @@
c129ba52ba1803a75b0f1b1b7a6d95092a8b67b5
ee629ad852ffaadaaf47f1d39c96f7daf670f9be