mirror of https://github.com/axmolengine/axmol.git
move the method from ccUtils to Director
This commit is contained in:
parent
dfb016dde3
commit
90e2b8a4af
|
@ -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
|
|
@ -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__
|
||||||
|
|
|
@ -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
|
||||||
**************************************************/
|
**************************************************/
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue