move the method from ccUtils to Director

This commit is contained in:
vision 2014-05-14 19:42:24 +08:00
parent dfb016dde3
commit 90e2b8a4af
5 changed files with 95 additions and 137 deletions

View File

@ -22,13 +22,7 @@ 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#include "CCGLView.h"
#include "2d/ccUtils.h" #include "2d/ccUtils.h"
#include "2d/platform/CCImage.h"
#include "2d/platform/CCFileUtils.h"
#include "base/ccMacros.h"
#include "base/CCDirector.h"
#include "renderer/CCRenderer.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -43,110 +37,4 @@ int ccNextPOT(int x)
return x + 1; return x + 1;
} }
UtilsHelper* UtilsHelper::s_sharedHelper = nullptr;
UtilsHelper::UtilsHelper()
{
}
UtilsHelper::~UtilsHelper()
{
}
UtilsHelper* UtilsHelper::getInstance()
{
if (!s_sharedHelper)
{
s_sharedHelper = new UtilsHelper();
}
return s_sharedHelper;
}
void UtilsHelper::destroyInstance()
{
CC_SAFE_DELETE(s_sharedHelper);
}
void UtilsHelper::captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename, const Rect& rect)
{
_captureScreen.init(std::numeric_limits<float>::max());
_captureScreen.func = CC_CALLBACK_0(UtilsHelper::onCaptureScreen, this, afterCaptured, filename, rect);
Director::getInstance()->getRenderer()->addCommand(&_captureScreen);
}
void UtilsHelper::onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename, const Rect& rect)
{
// Generally the user specifiy the rect with design resolution, thus we have to convert it
// into a significant value which is metered by pixel.
Size frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();
int originx = 0;
int originy = 0;
int width = (int)frameSize.width;
int height = (int)frameSize.height;
bool succeed = false;
std::string outputFile = "";
if (!rect.equals(Rect::ZERO))
{
originx = (int)rect.origin.x;
originy = (int)rect.origin.y;
width = (int)rect.size.width * Director::getInstance()->getOpenGLView()->getScaleX();
height = (int)rect.size.height * Director::getInstance()->getOpenGLView()->getScaleY();
auto clip = [](int in, int min, int max) { return std::max(std::min(in, max), min); };
originx = clip(originx, 0, (int)frameSize.width);
originy = clip(originy, 0, (int)frameSize.height);
width = clip(width, 0, frameSize.width - originx);
height = clip(height, 0, frameSize.height - originy);
}
do
{
GLubyte* buffer = new GLubyte[width * height * 4];
if (!buffer)
{
break;
}
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(originx, originy, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
GLubyte* flippedBuffer = new GLubyte[width * height * 4];
if (!flippedBuffer)
{
break;
}
for (int row = 0; row < height; ++row)
{
memcpy(flippedBuffer + (height - row - 1) * width * 4, buffer + row * width * 4, width * 4);
}
CC_SAFE_DELETE_ARRAY(buffer);
Image* image = new Image();
if (image)
{
image->initWithRawData(flippedBuffer, width * height * 4, width, height, 8);
if (FileUtils::getInstance()->isAbsolutePath(filename))
{
outputFile = filename;
}
else
{
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
}
image->saveToFile(outputFile);
succeed = true;
}
CC_SAFE_DELETE_ARRAY(flippedBuffer);
CC_SAFE_DELETE(image);
}while(0);
if (afterCaptured)
{
afterCaptured(succeed, outputFile);
}
}
NS_CC_END NS_CC_END

View File

@ -24,9 +24,7 @@ THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#ifndef __SUPPORT_CC_UTILS_H__ #ifndef __SUPPORT_CC_UTILS_H__
#define __SUPPORT_CC_UTILS_H__ #define __SUPPORT_CC_UTILS_H__
#include <functional> #include "base/ccMacros.h"
#include "math/CCGeometry.h"
#include "renderer/CCCustomCommand.h"
/** @file ccUtils.h /** @file ccUtils.h
Misc free functions Misc free functions
@ -49,27 +47,6 @@ Examples:
int ccNextPOT(int value); int ccNextPOT(int value);
class CC_DLL UtilsHelper
{
public:
static UtilsHelper* getInstance();
static void destroyInstance();
/** capture screen */
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptued, const std::string& filename, const Rect& rect = Rect::ZERO);
protected:
UtilsHelper();
virtual ~UtilsHelper();
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptued, const std::string& fileanme, const Rect& rect);
static UtilsHelper* s_sharedHelper;
CustomCommand _captureScreen;
};
NS_CC_END NS_CC_END
#endif // __SUPPORT_CC_UTILS_H__ #endif // __SUPPORT_CC_UTILS_H__

View File

@ -1216,6 +1216,87 @@ void Director::setEventDispatcher(EventDispatcher* dispatcher)
} }
} }
void Director::captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename, const Rect& rect)
{
_captureScreen.init(std::numeric_limits<float>::max());
_captureScreen.func = CC_CALLBACK_0(Director::onCaptureScreen, this, afterCaptured, filename, rect);
Director::getInstance()->getRenderer()->addCommand(&_captureScreen);
}
void Director::onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename, const Rect& rect)
{
// Generally the user specifiy the rect with design resolution, thus we have to convert it
// into a significant value which is metered by pixel.
Size frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();
int originx = 0;
int originy = 0;
int width = (int)frameSize.width;
int height = (int)frameSize.height;
bool succeed = false;
std::string outputFile = "";
if (!rect.equals(Rect::ZERO))
{
originx = (int)rect.origin.x;
originy = (int)rect.origin.y;
width = (int)rect.size.width * Director::getInstance()->getOpenGLView()->getScaleX();
height = (int)rect.size.height * Director::getInstance()->getOpenGLView()->getScaleY();
auto clip = [](int in, int min, int max) { return std::max(std::min(in, max), min); };
originx = clip(originx, 0, (int)frameSize.width);
originy = clip(originy, 0, (int)frameSize.height);
width = clip(width, 0, frameSize.width - originx);
height = clip(height, 0, frameSize.height - originy);
}
do
{
GLubyte* buffer = new GLubyte[width * height * 4];
if (!buffer)
{
break;
}
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(originx, originy, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
GLubyte* flippedBuffer = new GLubyte[width * height * 4];
if (!flippedBuffer)
{
break;
}
for (int row = 0; row < height; ++row)
{
memcpy(flippedBuffer + (height - row - 1) * width * 4, buffer + row * width * 4, width * 4);
}
CC_SAFE_DELETE_ARRAY(buffer);
Image* image = new Image();
if (image)
{
image->initWithRawData(flippedBuffer, width * height * 4, width, height, 8);
if (FileUtils::getInstance()->isAbsolutePath(filename))
{
outputFile = filename;
}
else
{
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
}
image->saveToFile(outputFile);
succeed = true;
}
CC_SAFE_DELETE_ARRAY(flippedBuffer);
CC_SAFE_DELETE(image);
}while(0);
if (afterCaptured)
{
afterCaptured(succeed, outputFile);
}
}
/*************************************************** /***************************************************
* implementation of DisplayLinkDirector * implementation of DisplayLinkDirector
**************************************************/ **************************************************/

View File

@ -38,6 +38,7 @@ THE SOFTWARE.
#include "2d/CCLabelAtlas.h" #include "2d/CCLabelAtlas.h"
#include <stack> #include <stack>
#include "math/CCMath.h" #include "math/CCMath.h"
#include "renderer/CCCustomCommand.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -404,6 +405,11 @@ public:
*/ */
float getFrameRate() const { return _frameRate; } float getFrameRate() const { return _frameRate; }
/**
* Capture screen
*/
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptued, const std::string& filename, const Rect& rect = Rect::ZERO);
protected: protected:
void purgeDirector(); void purgeDirector();
bool _purgeDirectorInNextLoop; // this flag will be set to true in end() bool _purgeDirectorInNextLoop; // this flag will be set to true in end()
@ -422,6 +428,9 @@ protected:
void initTextureCache(); void initTextureCache();
void destroyTextureCache(); void destroyTextureCache();
/* Captrue screen implementation */
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptued, const std::string& fileanme, const Rect& rect);
/** Scheduler associated with this director /** Scheduler associated with this director
@since v2.0 @since v2.0
*/ */
@ -503,6 +512,9 @@ protected:
/* Renderer for the Director */ /* Renderer for the Director */
Renderer *_renderer; Renderer *_renderer;
/* Capture screen command */
CustomCommand _captureScreen;
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) #if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
/* Console for the director */ /* Console for the director */
Console *_console; Console *_console;

View File

@ -611,7 +611,7 @@ void CaptureScreenTest::onCaptured(Ref*, const Rect& rect)
Director::getInstance()->getTextureCache()->removeTextureForKey(_filename); Director::getInstance()->getTextureCache()->removeTextureForKey(_filename);
removeChildByTag(ChildTag); removeChildByTag(ChildTag);
_filename = "CaptureScreenTest.png"; _filename = "CaptureScreenTest.png";
UtilsHelper::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename, rect); Director::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename, rect);
} }
void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile) void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile)