mirror of https://github.com/axmolengine/axmol.git
move the utility from Renderer to UtilsHelper
This commit is contained in:
parent
6213747c41
commit
dfb016dde3
|
@ -22,9 +22,15 @@ 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"
|
||||
|
||||
namespace cocos2d {
|
||||
NS_CC_BEGIN
|
||||
|
||||
int ccNextPOT(int x)
|
||||
{
|
||||
|
@ -36,5 +42,111 @@ 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
|
|
@ -24,12 +24,15 @@ THE SOFTWARE.
|
|||
****************************************************************************/
|
||||
#ifndef __SUPPORT_CC_UTILS_H__
|
||||
#define __SUPPORT_CC_UTILS_H__
|
||||
#include <functional>
|
||||
#include "math/CCGeometry.h"
|
||||
#include "renderer/CCCustomCommand.h"
|
||||
|
||||
/** @file ccUtils.h
|
||||
Misc free functions
|
||||
*/
|
||||
|
||||
namespace cocos2d {
|
||||
NS_CC_BEGIN
|
||||
/*
|
||||
ccNextPOT function is licensed under the same license that is used in Texture2D.m.
|
||||
*/
|
||||
|
@ -45,7 +48,28 @@ 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
|
||||
|
||||
#endif // __SUPPORT_CC_UTILS_H__
|
||||
|
|
|
@ -236,6 +236,7 @@ THE SOFTWARE.
|
|||
#include "2d/ccUTF8.h"
|
||||
#include "2d/CCUserDefault.h"
|
||||
#include "2d/CCVertex.h"
|
||||
#include "2d/ccUtils.h"
|
||||
|
||||
// text_input_node
|
||||
#include "2d/CCIMEDelegate.h"
|
||||
|
|
|
@ -37,9 +37,6 @@
|
|||
#include "base/CCEventDispatcher.h"
|
||||
#include "base/CCEventListenerCustom.h"
|
||||
#include "base/CCEventType.h"
|
||||
#include "2d/platform/CCImage.h"
|
||||
#include "2d/platform/CCFileUtils.h"
|
||||
#include "CCGLView.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -538,81 +535,4 @@ bool Renderer::checkVisibility(const Matrix &transform, const Size &size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Renderer::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(Renderer::onCaptureScreen, this, afterCaptured, filename, true, rect);
|
||||
addCommand(&_captureScreen);
|
||||
}
|
||||
|
||||
void Renderer::onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename, bool flipped, 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)
|
||||
{
|
||||
CC_SAFE_DELETE_ARRAY(buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(originx, originy, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
|
||||
if (flipped)
|
||||
{
|
||||
GLubyte* flippedBuffer = new GLubyte[width * height * 4];
|
||||
if (!flippedBuffer)
|
||||
{
|
||||
CC_SAFE_DELETE(flippedBuffer);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int row = 0; row < height; ++row)
|
||||
{
|
||||
memcpy(flippedBuffer + (height - row - 1) * width * 4, buffer + row * width * 4, width * 4);
|
||||
}
|
||||
memcpy(buffer, flippedBuffer, width * height * 4);
|
||||
CC_SAFE_DELETE_ARRAY(flippedBuffer);
|
||||
}
|
||||
|
||||
Image* image = new Image();
|
||||
if (image)
|
||||
{
|
||||
image->initWithRawData(buffer, width * height * 4, width, height, 8);
|
||||
CC_SAFE_DELETE_ARRAY(buffer);
|
||||
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
|
||||
image->saveToFile(outputFile);
|
||||
succeed = true;
|
||||
}
|
||||
CC_SAFE_DELETE(image);
|
||||
}while(0);
|
||||
|
||||
afterCaptured(succeed, outputFile);
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "base/CCPlatformMacros.h"
|
||||
#include "CCRenderCommand.h"
|
||||
#include "CCCustomCommand.h"
|
||||
#include "renderer/CCGLProgram.h"
|
||||
#include "CCGL.h"
|
||||
#include <vector>
|
||||
|
@ -118,9 +117,6 @@ public:
|
|||
/** returns whether or not a rectangle is visible or not */
|
||||
bool checkVisibility(const Matrix& transform, const Size& size);
|
||||
|
||||
/** capture screen */
|
||||
void captureScreen(const std::function<void(bool, const std::string&)>& afterCaptued, const std::string& filename, const Rect& rect = Rect::ZERO);
|
||||
|
||||
protected:
|
||||
|
||||
void setupIndices();
|
||||
|
@ -139,8 +135,6 @@ protected:
|
|||
|
||||
void convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Matrix& modelView);
|
||||
|
||||
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptued, const std::string& fileanme, bool flipped, const Rect& rect);
|
||||
|
||||
std::stack<int> _commandGroupStack;
|
||||
|
||||
std::vector<RenderQueue> _renderGroups;
|
||||
|
@ -165,8 +159,6 @@ protected:
|
|||
bool _isRendering;
|
||||
|
||||
GroupCommandManager* _groupCommandManager;
|
||||
|
||||
CustomCommand _captureScreen;
|
||||
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
EventListenerCustom* _cacheTextureListener;
|
||||
|
|
|
@ -611,10 +611,7 @@ void CaptureScreenTest::onCaptured(Ref*, const Rect& rect)
|
|||
Director::getInstance()->getTextureCache()->removeTextureForKey(_filename);
|
||||
removeChildByTag(ChildTag);
|
||||
_filename = "CaptureScreenTest.png";
|
||||
Director::getInstance()->getRenderer()->captureScreen(
|
||||
CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this),
|
||||
_filename,
|
||||
rect);
|
||||
UtilsHelper::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename, rect);
|
||||
}
|
||||
|
||||
void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFile)
|
||||
|
@ -630,6 +627,6 @@ void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFil
|
|||
}
|
||||
else
|
||||
{
|
||||
log("Something went wrong");
|
||||
log("Captrue screen failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue