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
THE SOFTWARE.
****************************************************************************/
#include "CCGLView.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
@ -42,111 +36,5 @@ int ccNextPOT(int x)
x = x | (x >>16);
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

View File

@ -24,9 +24,7 @@ THE SOFTWARE.
****************************************************************************/
#ifndef __SUPPORT_CC_UTILS_H__
#define __SUPPORT_CC_UTILS_H__
#include <functional>
#include "math/CCGeometry.h"
#include "renderer/CCCustomCommand.h"
#include "base/ccMacros.h"
/** @file ccUtils.h
Misc free functions
@ -48,27 +46,6 @@ Examples:
*/
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

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
**************************************************/

View File

@ -38,6 +38,7 @@ THE SOFTWARE.
#include "2d/CCLabelAtlas.h"
#include <stack>
#include "math/CCMath.h"
#include "renderer/CCCustomCommand.h"
NS_CC_BEGIN
@ -403,6 +404,11 @@ public:
* get Frame Rate
*/
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:
void purgeDirector();
@ -421,6 +427,9 @@ protected:
//textureCache creation or release
void initTextureCache();
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
@since v2.0
@ -502,6 +511,9 @@ protected:
/* Renderer for the Director */
Renderer *_renderer;
/* Capture screen command */
CustomCommand _captureScreen;
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT)
/* Console for the director */

View File

@ -611,7 +611,7 @@ void CaptureScreenTest::onCaptured(Ref*, const Rect& rect)
Director::getInstance()->getTextureCache()->removeTextureForKey(_filename);
removeChildByTag(ChildTag);
_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)