From 7a105ce1e19e5dc704d9e15bdf294977db59823c Mon Sep 17 00:00:00 2001 From: Vincent Yang Date: Wed, 15 Jul 2015 12:09:08 +0800 Subject: [PATCH] fixed #11310 : multiple camera case utils::captureScreen bug. --- cocos/base/ccUtils.cpp | 23 ++++++-- .../Classes/Scene3DTest/Scene3DTest.cpp | 52 ++++++++++++++++++- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/cocos/base/ccUtils.cpp b/cocos/base/ccUtils.cpp index 078739e6a968..fa17247f8449 100644 --- a/cocos/base/ccUtils.cpp +++ b/cocos/base/ccUtils.cpp @@ -29,6 +29,7 @@ THE SOFTWARE. #include "base/CCDirector.h" #include "base/CCAsyncTaskPool.h" +#include "base/CCEventDispatcher.h" #include "renderer/CCCustomCommand.h" #include "renderer/CCRenderer.h" #include "platform/CCImage.h" @@ -151,14 +152,26 @@ void onCaptureScreen(const std::function& afterC /* * Capture screen interface */ +static EventListenerCustom* s_captureScreenListener; +static CustomCommand s_captureScreenCommand; void captureScreen(const std::function& afterCaptured, const std::string& filename) { - static CustomCommand captureScreenCommand; - captureScreenCommand.init(std::numeric_limits::max()); - captureScreenCommand.func = std::bind(onCaptureScreen, afterCaptured, filename); - Director::getInstance()->getRenderer()->addCommand(&captureScreenCommand); + if (s_captureScreenListener) + { + CCLOG("Warning: CaptureScreen has been caled yet, don't call more than once in one frame."); + return; + } + s_captureScreenCommand.init(std::numeric_limits::max()); + s_captureScreenCommand.func = std::bind(onCaptureScreen, afterCaptured, filename); + s_captureScreenListener = Director::getInstance()->getEventDispatcher()->addCustomEventListener(Director::EVENT_AFTER_DRAW, [](EventCustom *event) { + auto director = Director::getInstance(); + director->getEventDispatcher()->removeEventListener((EventListener*)(s_captureScreenListener)); + s_captureScreenListener = nullptr; + director->getRenderer()->addCommand(&s_captureScreenCommand); + director->getRenderer()->render(); + }); } - + std::vector findChildren(const Node &node, const std::string &name) { std::vector vec; diff --git a/tests/cpp-tests/Classes/Scene3DTest/Scene3DTest.cpp b/tests/cpp-tests/Classes/Scene3DTest/Scene3DTest.cpp index a1c13be83ab5..83bd663d5cf6 100644 --- a/tests/cpp-tests/Classes/Scene3DTest/Scene3DTest.cpp +++ b/tests/cpp-tests/Classes/Scene3DTest/Scene3DTest.cpp @@ -105,6 +105,10 @@ class Scene3DTestScene : public TestCase std::vector _skins[(int)SkinType::MAX_TYPE]; //all skins int _curSkin[(int)SkinType::MAX_TYPE]; //current skin index cocos2d::Sprite3D* _reskinGirl; + + // for capture screen + static const int SNAPSHOT_TAG = 119; + std::string _snapshotFile; }; /** Define the sub scenes in test. */ @@ -651,6 +655,50 @@ void Scene3DTestScene::createDetailDlg() auto title = Label::createWithTTF("Detail Dialog","fonts/arial.ttf",16); title->setPosition(dlgSize.width / 2, dlgSize.height - margin * 2); _detailDlg->addChild(title); + + + // add capture screen buttons + ui::Button* capture = ui::Button::create("cocosui/animationbuttonnormal.png", + "cocosui/animationbuttonpressed.png"); + capture->setScale(0.5); + capture->setAnchorPoint(Vec2(0.5, 0)); + capture->setPosition(Vec2(dlgSize.width / 3, margin)); + capture->addClickEventListener([this](Ref* sender) + { + Director::getInstance()->getTextureCache()->removeTextureForKey(_snapshotFile); + _osdScene->removeChildByTag(SNAPSHOT_TAG); + _snapshotFile = "CaptureScreenTest.png"; + utils::captureScreen([this](bool succeed, const std::string& outputFile) + { + if (!succeed) + { + log("Capture screen failed."); + return; + } + auto sp = Sprite::create(outputFile); + _osdScene->addChild(sp, 0, SNAPSHOT_TAG); + Size s = Director::getInstance()->getWinSize(); + sp->setPosition(s.width / 2, s.height / 2); + sp->setScale(0.25); + _snapshotFile = outputFile; + }, _snapshotFile); + }); + capture->setTitleText("Take Snapshot"); + capture->setName("Take Snapshot"); + _detailDlg->addChild(capture); + + ui::Button* remove = ui::Button::create("cocosui/animationbuttonnormal.png", + "cocosui/animationbuttonpressed.png"); + remove->setScale(0.5); + remove->setAnchorPoint(Vec2(0.5, 0)); + remove->setPosition(Vec2(dlgSize.width * 2 / 3, margin)); + remove->addClickEventListener([this](Ref* sender) + { + _osdScene->removeChildByTag(SNAPSHOT_TAG); + }); + remove->setTitleText("Del Snapshot"); + remove->setName("Del Snapshot"); + _detailDlg->addChild(remove); // add a spine ffd animation on it auto skeletonNode = @@ -662,7 +710,7 @@ void Scene3DTestScene::createDetailDlg() skeletonNode->setScale(0.25); Size windowSize = Director::getInstance()->getWinSize(); - skeletonNode->setPosition(Vec2(dlgSize.width / 2, 20)); + skeletonNode->setPosition(Vec2(dlgSize.width / 2, remove->getContentSize().height / 2 + 2 * margin)); _detailDlg->addChild(skeletonNode); } @@ -706,7 +754,7 @@ void Scene3DTestScene::createDescDlg() "- OSD scene contains description dialog.\n" "\n" "Click \"Description\" button to hide this dialog.\n"); - auto text = Label::createWithSystemFont(desc, "Helvetica", 9, textSize); + auto text = Label::createWithSystemFont(desc, "", 9, textSize); text->setAnchorPoint(Vec2(0, 1)); text->setPosition(textPos); _descDlg->addChild(text);