mirror of https://github.com/axmolengine/axmol.git
move the capturen screen interface from Director to ccUtils
This commit is contained in:
parent
c72ae9e3c5
commit
363fd8dc2a
|
@ -1225,71 +1225,6 @@ void Director::setEventDispatcher(EventDispatcher* dispatcher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Director::captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
|
|
||||||
{
|
|
||||||
_captureScreenCommand.init(std::numeric_limits<float>::max());
|
|
||||||
_captureScreenCommand.func = CC_CALLBACK_0(Director::onCaptureScreen, this, afterCaptured, filename);
|
|
||||||
Director::getInstance()->getRenderer()->addCommand(&_captureScreenCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Director::onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
|
|
||||||
{
|
|
||||||
Size frameSize = _openGLView->getFrameSize();
|
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
|
||||||
frameSize = frameSize * _openGLView->getFrameZoomFactor() * _openGLView->getRetinaFactor();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int width = static_cast<int>(frameSize.width);
|
|
||||||
int height = static_cast<int>(frameSize.height);
|
|
||||||
|
|
||||||
bool succeed = false;
|
|
||||||
std::string outputFile = "";
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
std::shared_ptr<GLubyte> buffer(new GLubyte[width * height * 4], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); });
|
|
||||||
if (!buffer)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
||||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
|
|
||||||
|
|
||||||
std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); });
|
|
||||||
if (!flippedBuffer)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int row = 0; row < height; ++row)
|
|
||||||
{
|
|
||||||
memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Image> image(new Image);
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8);
|
|
||||||
if (FileUtils::getInstance()->isAbsolutePath(filename))
|
|
||||||
{
|
|
||||||
outputFile = filename;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CCASSERT(filename.find("/") == std::string::npos, "The existence of a relative path is not guaranteed!");
|
|
||||||
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
|
|
||||||
}
|
|
||||||
succeed = image->saveToFile(outputFile);
|
|
||||||
}
|
|
||||||
}while(0);
|
|
||||||
|
|
||||||
if (afterCaptured)
|
|
||||||
{
|
|
||||||
afterCaptured(succeed, outputFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************
|
/***************************************************
|
||||||
* implementation of DisplayLinkDirector
|
* implementation of DisplayLinkDirector
|
||||||
**************************************************/
|
**************************************************/
|
||||||
|
|
|
@ -405,11 +405,6 @@ 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);
|
|
||||||
|
|
||||||
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()
|
||||||
|
@ -428,9 +423,6 @@ 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);
|
|
||||||
|
|
||||||
/** Scheduler associated with this director
|
/** Scheduler associated with this director
|
||||||
@since v2.0
|
@since v2.0
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,6 +24,12 @@ THE SOFTWARE.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "base/ccUtils.h"
|
#include "base/ccUtils.h"
|
||||||
|
#include "base/CCDirector.h"
|
||||||
|
#include "renderer/CCCustomCommand.h"
|
||||||
|
#include "renderer/CCRenderer.h"
|
||||||
|
#include "platform/CCImage.h"
|
||||||
|
#include "platform/CCFileUtils.h"
|
||||||
|
#include "CCGLView.h"
|
||||||
|
|
||||||
NS_CC_BEGIN
|
NS_CC_BEGIN
|
||||||
|
|
||||||
|
@ -38,4 +44,74 @@ int ccNextPOT(int x)
|
||||||
return x + 1;
|
return x + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Utilities
|
||||||
|
{
|
||||||
|
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
|
||||||
|
{
|
||||||
|
static CustomCommand captureScreenCommand;
|
||||||
|
captureScreenCommand.init(std::numeric_limits<float>::max());
|
||||||
|
captureScreenCommand.func = std::bind(onCaptureScreen, afterCaptured, filename);
|
||||||
|
Director::getInstance()->getRenderer()->addCommand(&captureScreenCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
|
||||||
|
{
|
||||||
|
auto glView = Director::getInstance()->getOpenGLView();
|
||||||
|
auto frameSize = glView->getFrameSize();
|
||||||
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||||
|
frameSize = frameSize * glView->getFrameZoomFactor() * glView->getRetinaFactor();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int width = static_cast<int>(frameSize.width);
|
||||||
|
int height = static_cast<int>(frameSize.height);
|
||||||
|
|
||||||
|
bool succeed = false;
|
||||||
|
std::string outputFile = "";
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
std::shared_ptr<GLubyte> buffer(new GLubyte[width * height * 4], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); });
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
|
||||||
|
|
||||||
|
std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); });
|
||||||
|
if (!flippedBuffer)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int row = 0; row < height; ++row)
|
||||||
|
{
|
||||||
|
memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Image> image(new Image);
|
||||||
|
if (image)
|
||||||
|
{
|
||||||
|
image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8);
|
||||||
|
if (FileUtils::getInstance()->isAbsolutePath(filename))
|
||||||
|
{
|
||||||
|
outputFile = filename;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCASSERT(filename.find("/") == std::string::npos, "The existence of a relative path is not guaranteed!");
|
||||||
|
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
|
||||||
|
}
|
||||||
|
succeed = image->saveToFile(outputFile);
|
||||||
|
}
|
||||||
|
}while(0);
|
||||||
|
|
||||||
|
if (afterCaptured)
|
||||||
|
{
|
||||||
|
afterCaptured(succeed, outputFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
|
@ -47,7 +47,19 @@ Examples:
|
||||||
|
|
||||||
int ccNextPOT(int value);
|
int ccNextPOT(int value);
|
||||||
|
|
||||||
|
namespace Utilities
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Capture screen interface
|
||||||
|
*/
|
||||||
|
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The implementation of capturing screen
|
||||||
|
*/
|
||||||
|
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename);
|
||||||
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
||||||
#endif // __SUPPORT_CC_UTILS_H__
|
#endif // __SUPPORT_CC_UTILS_H__
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ THE SOFTWARE.
|
||||||
#include "base/CCUserDefault.h"
|
#include "base/CCUserDefault.h"
|
||||||
#include "base/CCIMEDelegate.h"
|
#include "base/CCIMEDelegate.h"
|
||||||
#include "base/CCIMEDispatcher.h"
|
#include "base/CCIMEDispatcher.h"
|
||||||
|
#include "base/ccUtils.h"
|
||||||
|
|
||||||
// EventDispatcher
|
// EventDispatcher
|
||||||
#include "base/CCEventType.h"
|
#include "base/CCEventType.h"
|
||||||
|
|
|
@ -609,7 +609,7 @@ void CaptureScreenTest::onCaptured(Ref*)
|
||||||
Director::getInstance()->getTextureCache()->removeTextureForKey(_filename);
|
Director::getInstance()->getTextureCache()->removeTextureForKey(_filename);
|
||||||
removeChildByTag(childTag);
|
removeChildByTag(childTag);
|
||||||
_filename = "CaptureScreenTest.png";
|
_filename = "CaptureScreenTest.png";
|
||||||
Director::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename);
|
Utilities::captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile)
|
void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile)
|
||||||
|
|
Loading…
Reference in New Issue