move the utility from Renderer to UtilsHelper

This commit is contained in:
vision 2014-05-14 16:25:47 +08:00
parent 6213747c41
commit dfb016dde3
6 changed files with 144 additions and 98 deletions

View File

@ -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 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"
namespace cocos2d { NS_CC_BEGIN
int ccNextPOT(int x) int ccNextPOT(int x)
{ {
@ -37,4 +43,110 @@ 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

View File

@ -24,12 +24,15 @@ 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 "math/CCGeometry.h"
#include "renderer/CCCustomCommand.h"
/** @file ccUtils.h /** @file ccUtils.h
Misc free functions Misc free functions
*/ */
namespace cocos2d { NS_CC_BEGIN
/* /*
ccNextPOT function is licensed under the same license that is used in Texture2D.m. ccNextPOT function is licensed under the same license that is used in Texture2D.m.
*/ */
@ -46,6 +49,27 @@ 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
#endif // __SUPPORT_CC_UTILS_H__ #endif // __SUPPORT_CC_UTILS_H__

View File

@ -236,6 +236,7 @@ THE SOFTWARE.
#include "2d/ccUTF8.h" #include "2d/ccUTF8.h"
#include "2d/CCUserDefault.h" #include "2d/CCUserDefault.h"
#include "2d/CCVertex.h" #include "2d/CCVertex.h"
#include "2d/ccUtils.h"
// text_input_node // text_input_node
#include "2d/CCIMEDelegate.h" #include "2d/CCIMEDelegate.h"

View File

@ -37,9 +37,6 @@
#include "base/CCEventDispatcher.h" #include "base/CCEventDispatcher.h"
#include "base/CCEventListenerCustom.h" #include "base/CCEventListenerCustom.h"
#include "base/CCEventType.h" #include "base/CCEventType.h"
#include "2d/platform/CCImage.h"
#include "2d/platform/CCFileUtils.h"
#include "CCGLView.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -538,81 +535,4 @@ bool Renderer::checkVisibility(const Matrix &transform, const Size &size)
return ret; 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 NS_CC_END

View File

@ -28,7 +28,6 @@
#include "base/CCPlatformMacros.h" #include "base/CCPlatformMacros.h"
#include "CCRenderCommand.h" #include "CCRenderCommand.h"
#include "CCCustomCommand.h"
#include "renderer/CCGLProgram.h" #include "renderer/CCGLProgram.h"
#include "CCGL.h" #include "CCGL.h"
#include <vector> #include <vector>
@ -118,9 +117,6 @@ public:
/** returns whether or not a rectangle is visible or not */ /** returns whether or not a rectangle is visible or not */
bool checkVisibility(const Matrix& transform, const Size& size); 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: protected:
void setupIndices(); void setupIndices();
@ -139,8 +135,6 @@ protected:
void convertToWorldCoordinates(V3F_C4B_T2F_Quad* quads, ssize_t quantity, const Matrix& modelView); 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::stack<int> _commandGroupStack;
std::vector<RenderQueue> _renderGroups; std::vector<RenderQueue> _renderGroups;
@ -166,8 +160,6 @@ protected:
GroupCommandManager* _groupCommandManager; GroupCommandManager* _groupCommandManager;
CustomCommand _captureScreen;
#if CC_ENABLE_CACHE_TEXTURE_DATA #if CC_ENABLE_CACHE_TEXTURE_DATA
EventListenerCustom* _cacheTextureListener; EventListenerCustom* _cacheTextureListener;
#endif #endif

View File

@ -611,10 +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";
Director::getInstance()->getRenderer()->captureScreen( UtilsHelper::getInstance()->captureScreen(CC_CALLBACK_2(CaptureScreenTest::afterCaptured, this), _filename, rect);
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)
@ -630,6 +627,6 @@ void CaptureScreenTest::afterCaptured(bool succeed, const std::string& outputFil
} }
else else
{ {
log("Something went wrong"); log("Captrue screen failed.");
} }
} }