mirror of https://github.com/axmolengine/axmol.git
Merge pull request #440 from flyingpacer/savecrash
fixed #649 the user could save any domain of the render texture
This commit is contained in:
commit
b9374663cd
|
@ -86,14 +86,28 @@ public:
|
|||
|
||||
/** saves the texture into a file */
|
||||
// para szFilePath the absolute path to save
|
||||
bool saveBuffer(const char *szFilePath);
|
||||
/** saves the texture into a file. The format can be JPG or PNG */
|
||||
bool saveBuffer(const char *name, int format);
|
||||
// para x,y the lower left corner coordinates of the buffer to save
|
||||
// pare nWidth,nHeight the size of the buffer to save
|
||||
// when nWidth = 0 and nHeight = 0, the image size to save equals to buffer texture size
|
||||
bool saveBuffer(const char *szFilePath, int x = 0, int y = 0, int nWidth = 0, int nHeight = 0);
|
||||
|
||||
/** saves the texture into a file.
|
||||
// para name the file name to save
|
||||
// para format the image format to save, here it supports kCCImageFormatPNG and kCCImageFormatJPG */
|
||||
// para x,y the lower left corner coordinates of the buffer to save
|
||||
// pare nWidth,nHeight the size of the buffer to save
|
||||
// when nWidth = 0 and nHeight = 0, the image size to save equals to buffer texture size
|
||||
bool saveBuffer(int format, const char *name, int x = 0, int y = 0, int nWidth = 0, int nHeight = 0);
|
||||
|
||||
/* get buffer as UIImage, can only save a render buffer which has a RGBA8888 pixel format */
|
||||
CCData *getUIImageAsDataFromBuffer(int format);
|
||||
|
||||
bool getUIImageFromBuffer(CCImage *pImage);
|
||||
/** save the buffer data to a CCImage */
|
||||
// para pImage the CCImage to save
|
||||
// para x,y the lower left corner coordinates of the buffer to save
|
||||
// pare nWidth,nHeight the size of the buffer to save
|
||||
// when nWidth = 0 and nHeight = 0, the image size to save equals to buffer texture size
|
||||
bool getUIImageFromBuffer(CCImage *pImage, int x = 0, int y = 0, int nWidth = 0, int nHeight = 0);
|
||||
|
||||
protected:
|
||||
GLuint m_uFBO;
|
||||
|
|
|
@ -216,12 +216,12 @@ void CCRenderTexture::clear(float r, float g, float b, float a)
|
|||
this->end();
|
||||
}
|
||||
|
||||
bool CCRenderTexture::saveBuffer(const char *szFilePath)
|
||||
bool CCRenderTexture::saveBuffer(const char *szFilePath, int x, int y, int nWidth, int nHeight)
|
||||
{
|
||||
bool bRet = false;
|
||||
|
||||
CCImage *pImage = new CCImage();
|
||||
if (pImage != NULL && getUIImageFromBuffer(pImage))
|
||||
if (pImage != NULL && getUIImageFromBuffer(pImage, x, y, nWidth, nHeight))
|
||||
{
|
||||
bRet = pImage->saveToFile(szFilePath);
|
||||
}
|
||||
|
@ -229,14 +229,14 @@ bool CCRenderTexture::saveBuffer(const char *szFilePath)
|
|||
CC_SAFE_DELETE(pImage);
|
||||
return bRet;
|
||||
}
|
||||
bool CCRenderTexture::saveBuffer(const char *fileName, int format)
|
||||
bool CCRenderTexture::saveBuffer(int format, const char *fileName, int x, int y, int nWidth, int nHeight)
|
||||
{
|
||||
bool bRet = false;
|
||||
CCAssert(format == kCCImageFormatJPG || format == kCCImageFormatPNG,
|
||||
"the image can only be saved as JPG or PNG format");
|
||||
|
||||
CCImage *pImage = new CCImage();
|
||||
if (pImage != NULL && getUIImageFromBuffer(pImage))
|
||||
if (pImage != NULL && getUIImageFromBuffer(pImage, x, y, nWidth, nHeight))
|
||||
{
|
||||
std::string fullpath = CCFileUtils::getWriteablePath() + fileName;
|
||||
if (kCCImageFormatPNG == format)
|
||||
|
@ -257,13 +257,46 @@ bool CCRenderTexture::saveBuffer(const char *fileName, int format)
|
|||
}
|
||||
|
||||
/* get buffer as UIImage */
|
||||
bool CCRenderTexture::getUIImageFromBuffer(CCImage *pImage)
|
||||
bool CCRenderTexture::getUIImageFromBuffer(CCImage *pImage, int x, int y, int nWidth, int nHeight)
|
||||
{
|
||||
if (NULL == pImage)
|
||||
if (NULL == pImage || NULL == m_pTexture)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CCSize s = m_pTexture->getContentSizeInPixels();
|
||||
int tx = (int)s.width;
|
||||
int ty = (int)s.height;
|
||||
|
||||
if (x < 0 || x >= tx || y < 0 || y >= ty)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nWidth < 0
|
||||
|| nHeight < 0
|
||||
|| (0 == nWidth && 0 != nHeight)
|
||||
|| (0 == nHeight && 0 != nWidth))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// to get the image size to save
|
||||
// if the saving image domain exeeds the buffer texture domain,
|
||||
// it should be cut
|
||||
int nSavedBufferWidth = nWidth;
|
||||
int nSavedBufferHeight = nHeight;
|
||||
if (0 == nWidth)
|
||||
{
|
||||
nSavedBufferWidth = tx;
|
||||
}
|
||||
if (0 == nHeight)
|
||||
{
|
||||
nSavedBufferHeight = ty;
|
||||
}
|
||||
nSavedBufferWidth = x + nSavedBufferWidth > tx ? (tx - x): nSavedBufferWidth;
|
||||
nSavedBufferHeight = y + nSavedBufferHeight > ty ? (ty - y): nSavedBufferHeight;
|
||||
|
||||
GLubyte *pBuffer = NULL;
|
||||
GLubyte *pTempData = NULL;
|
||||
bool bRet = false;
|
||||
|
@ -272,12 +305,7 @@ bool CCRenderTexture::getUIImageFromBuffer(CCImage *pImage)
|
|||
{
|
||||
CCAssert(m_ePixelFormat == kCCTexture2DPixelFormat_RGBA8888, "only RGBA8888 can be saved as image");
|
||||
|
||||
CCSize s = m_pTexture->getContentSizeInPixels();
|
||||
int tx = (int)s.width;
|
||||
int ty = (int)s.height;
|
||||
|
||||
CC_BREAK_IF(! (pBuffer = new GLubyte[tx * ty * 4]));
|
||||
CC_BREAK_IF(! (pTempData = new GLubyte[tx * ty * 4]));
|
||||
CC_BREAK_IF(! (pBuffer = new GLubyte[nSavedBufferWidth * nSavedBufferHeight * 4]));
|
||||
|
||||
// On some machines, like Samsung i9000, Motorola Defy,
|
||||
// the dimension need to be a power of 2
|
||||
|
@ -301,14 +329,14 @@ bool CCRenderTexture::getUIImageFromBuffer(CCImage *pImage)
|
|||
|
||||
// to get the actual texture data
|
||||
// #640 the image read from rendertexture is upseted
|
||||
for (int i = 0; i < ty; ++i)
|
||||
for (int i = 0; i < nSavedBufferHeight; ++i)
|
||||
{
|
||||
memcpy(&pBuffer[i * tx * 4],
|
||||
&pTempData[(ty - i - 1) * nReadBufferWidth * 4],
|
||||
tx * 4);
|
||||
memcpy(&pBuffer[i * nSavedBufferWidth * 4],
|
||||
&pTempData[(y + nSavedBufferHeight - i - 1) * nReadBufferWidth * 4 + x * 4],
|
||||
nSavedBufferWidth * 4);
|
||||
}
|
||||
|
||||
bRet = pImage->initWithImageData(pBuffer, tx * ty * 4, CCImage::kFmtRawData, tx, ty, 8);
|
||||
bRet = pImage->initWithImageData(pBuffer, nSavedBufferWidth * nSavedBufferHeight * 4, CCImage::kFmtRawData, nSavedBufferWidth, nSavedBufferHeight, 8);
|
||||
} while (0);
|
||||
|
||||
CC_SAFE_DELETE_ARRAY(pBuffer);
|
||||
|
|
Loading…
Reference in New Issue