2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2012 cocos2d-x.org
|
|
|
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2022-05-13 21:06:17 +08:00
|
|
|
Copyright (c) 2020 C4games Ltd.
|
|
|
|
Copyright (c) 2021-2022 Bytedance Inc.
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2022-10-01 16:24:52 +08:00
|
|
|
https://axmolengine.github.io/
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
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 "SpriteFrameCacheTest.h"
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
|
2021-08-13 14:52:58 +08:00
|
|
|
#include "CCNinePatchImageParser.h"
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
USING_NS_AX;
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
SpriteFrameCacheTests::SpriteFrameCacheTests()
|
|
|
|
{
|
|
|
|
ADD_TEST_CASE(SpriteFrameCachePixelFormatTest);
|
|
|
|
ADD_TEST_CASE(SpriteFrameCacheLoadMultipleTimes);
|
|
|
|
ADD_TEST_CASE(SpriteFrameCacheFullCheck);
|
2021-08-13 14:52:58 +08:00
|
|
|
ADD_TEST_CASE(SpriteFrameCacheJsonAtlasTest);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SpriteFrameCachePixelFormatTest::SpriteFrameCachePixelFormatTest()
|
|
|
|
{
|
|
|
|
const Size screenSize = Director::getInstance()->getWinSize();
|
|
|
|
|
|
|
|
infoLabel = Label::create();
|
|
|
|
infoLabel->setAnchorPoint(Point(0.5f, 1.0f));
|
2022-07-11 17:50:21 +08:00
|
|
|
infoLabel->setAlignment(axis::TextHAlignment::CENTER);
|
2019-11-23 20:27:39 +08:00
|
|
|
infoLabel->setPosition(screenSize.width * 0.5f, screenSize.height * 0.7f);
|
|
|
|
addChild(infoLabel);
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
// load atlas definition with specified PixelFormat and check that it matches to expected format
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_A8.plist", backend::PixelFormat::A8);
|
2020-09-25 11:07:56 +08:00
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGBA8888.plist", backend::PixelFormat::RGBA8);
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_AI88.plist", backend::PixelFormat::LA8);
|
2019-11-23 20:27:39 +08:00
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGB565.plist", backend::PixelFormat::RGB565);
|
2020-09-25 11:07:56 +08:00
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGB888.plist", backend::PixelFormat::RGB8);
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGBA4444.plist", backend::PixelFormat::RGBA4);
|
2019-11-23 20:27:39 +08:00
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGBA5551.plist", backend::PixelFormat::RGB5A1);
|
2021-08-19 13:43:18 +08:00
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
if (Configuration::getInstance()->supportsPVRTC())
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_PVRTC2.plist", backend::PixelFormat::PVRTC2A);
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_PVRTC4.plist", backend::PixelFormat::PVRTC4A);
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_PVRTC2_NOALPHA.plist", backend::PixelFormat::PVRTC2);
|
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
// test loading atlases without PixelFormat specified
|
|
|
|
Texture2D::setDefaultAlphaPixelFormat(backend::PixelFormat::RGB5A1);
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_NoFormat.plist", backend::PixelFormat::RGB5A1);
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
// restore default alpha pixel format
|
2020-09-25 11:07:56 +08:00
|
|
|
Texture2D::setDefaultAlphaPixelFormat(backend::PixelFormat::RGBA8);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void SpriteFrameCachePixelFormatTest::loadSpriteFrames(std::string_view file,
|
2022-07-11 17:50:21 +08:00
|
|
|
axis::backend::PixelFormat expectedFormat)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(file);
|
2021-12-31 12:12:40 +08:00
|
|
|
SpriteFrame* spriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("sprite_frames_test/grossini.png");
|
|
|
|
Texture2D* texture = spriteFrame->getTexture();
|
|
|
|
const ssize_t bitsPerKB = 8 * 1024;
|
|
|
|
const double memorySize = 1.0 * texture->getBitsPerPixelForFormat() * texture->getContentSizeInPixels().width *
|
|
|
|
texture->getContentSizeInPixels().height / bitsPerKB;
|
2022-07-16 10:43:05 +08:00
|
|
|
#ifndef AX_USE_METAL
|
|
|
|
AX_ASSERT(texture->getPixelFormat() == expectedFormat);
|
2019-11-23 20:27:39 +08:00
|
|
|
#endif
|
2021-12-31 12:12:40 +08:00
|
|
|
const std::string textureInfo = StringUtils::format("%s%s: %.2f KB\r\n", infoLabel->getString().data(),
|
|
|
|
texture->getStringForFormat(), memorySize);
|
|
|
|
infoLabel->setString(textureInfo);
|
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
SpriteFrameCache::getInstance()->removeSpriteFramesFromFile(file);
|
|
|
|
Director::getInstance()->getTextureCache()->removeTexture(texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
SpriteFrameCacheLoadMultipleTimes::SpriteFrameCacheLoadMultipleTimes()
|
|
|
|
{
|
|
|
|
const Size screenSize = Director::getInstance()->getWinSize();
|
|
|
|
|
|
|
|
// load atlas definition with specified PixelFormat and check that it matches to expected format
|
2020-09-25 11:07:56 +08:00
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGBA8888.plist", backend::PixelFormat::RGBA8);
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGBA8888.plist", backend::PixelFormat::RGBA8);
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGBA8888.plist", backend::PixelFormat::RGBA8);
|
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGBA8888.plist", backend::PixelFormat::RGBA8);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void SpriteFrameCacheLoadMultipleTimes::loadSpriteFrames(std::string_view file,
|
2022-07-11 17:50:21 +08:00
|
|
|
axis::backend::PixelFormat expectedFormat)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(file);
|
2021-12-31 12:12:40 +08:00
|
|
|
SpriteFrame* spriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("sprite_frames_test/grossini.png");
|
|
|
|
Texture2D* texture = spriteFrame->getTexture();
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_ASSERT(texture->getPixelFormat() == expectedFormat);
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2021-08-19 13:43:18 +08:00
|
|
|
SpriteFrameCache::getInstance()->removeSpriteFrameByName("sprite_frames_test/grossini.png");
|
2019-11-23 20:27:39 +08:00
|
|
|
Director::getInstance()->getTextureCache()->removeTexture(texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
SpriteFrameCacheFullCheck::SpriteFrameCacheFullCheck()
|
|
|
|
{
|
|
|
|
const Size screenSize = Director::getInstance()->getWinSize();
|
|
|
|
// load atlas definition with specified PixelFormat and check that it matches to expected format
|
2020-09-25 11:07:56 +08:00
|
|
|
loadSpriteFrames("Images/test_polygon.plist", backend::PixelFormat::RGBA8);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
void SpriteFrameCacheFullCheck::loadSpriteFrames(std::string_view file, axis::backend::PixelFormat expectedFormat)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
auto cache = SpriteFrameCache::getInstance();
|
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(cache->isSpriteFramesWithFileLoaded("plist which not exists") == false, "Plist not exists");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
cache->addSpriteFramesWithFile(file);
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(cache->isSpriteFramesWithFileLoaded(file) == true, "Plist should be full after loaded");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
cache->removeSpriteFrameByName("not_exists_grossinis_sister.png");
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(cache->isSpriteFramesWithFileLoaded(file) == true, "Plist should not be still full");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
cache->removeSpriteFrameByName("grossinis_sister1.png");
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(cache->isSpriteFramesWithFileLoaded(file) == false, "Plist should not be full after remove any sprite");
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
cache->addSpriteFramesWithFile(file);
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(cache->isSpriteFramesWithFileLoaded(file) == true, "Plist should be full after reloaded");
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
class GenericJsonArraySpriteSheetLoader : public SpriteSheetLoader
|
|
|
|
{
|
|
|
|
public:
|
2021-08-17 12:04:45 +08:00
|
|
|
static constexpr uint32_t FORMAT = SpriteSheetFormat::CUSTOM + 1;
|
2021-08-13 14:52:58 +08:00
|
|
|
|
2021-08-17 12:04:45 +08:00
|
|
|
uint32_t getFormat() override { return FORMAT; }
|
2021-08-13 14:52:58 +08:00
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void load(std::string_view filePath, SpriteFrameCache& cache) override
|
2021-08-13 14:52:58 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(!filePath.empty(), "atlas filename should not be nullptr");
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
const auto fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
|
|
|
if (fullPath.empty())
|
|
|
|
{
|
|
|
|
// return if plist file doesn't exist
|
2022-07-16 10:43:05 +08:00
|
|
|
AXLOG("GenericJsonArraySpriteSheetLoader: can not find %s", filePath.data());
|
2021-08-13 14:52:58 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto data = FileUtils::getInstance()->getStringFromFile(fullPath);
|
|
|
|
|
|
|
|
rapidjson::Document jDoc;
|
|
|
|
jDoc.Parse(data.c_str());
|
|
|
|
|
|
|
|
std::string texturePath;
|
|
|
|
|
|
|
|
auto&& metaItr = jDoc.FindMember("meta");
|
|
|
|
if (metaItr != jDoc.MemberEnd())
|
|
|
|
{
|
|
|
|
texturePath = metaItr->value["image"].GetString();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!texturePath.empty())
|
|
|
|
{
|
|
|
|
// build texture path relative to plist file
|
|
|
|
texturePath = FileUtils::getInstance()->fullPathFromRelativeFile(texturePath, filePath);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// build texture path by replacing file extension
|
|
|
|
texturePath = filePath;
|
|
|
|
|
|
|
|
// remove .xxx
|
|
|
|
const auto startPos = texturePath.find_last_of('.');
|
|
|
|
if (startPos != std::string::npos)
|
|
|
|
{
|
|
|
|
texturePath = texturePath.erase(startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
// append .png
|
|
|
|
texturePath = texturePath.append(".png");
|
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
AXLOG("GenericJsonArraySpriteSheetLoader::load: Trying to use file %s as texture", texturePath.c_str());
|
2021-08-13 14:52:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
addSpriteFramesWithJson(jDoc, texturePath, filePath, cache);
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void load(std::string_view filePath, Texture2D* texture, SpriteFrameCache& cache) override
|
2021-08-13 14:52:58 +08:00
|
|
|
{
|
|
|
|
const auto fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
|
|
|
rapidjson::Document jDoc;
|
|
|
|
const auto data = FileUtils::getInstance()->getStringFromFile(fullPath);
|
|
|
|
jDoc.Parse(data.c_str());
|
|
|
|
|
|
|
|
addSpriteFramesWithJson(jDoc, texture, filePath, cache);
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void load(std::string_view filePath, std::string_view textureFileName, SpriteFrameCache& cache) override
|
2021-08-13 14:52:58 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXASSERT(!textureFileName.empty(), "texture name should not be null");
|
2021-08-13 14:52:58 +08:00
|
|
|
const auto fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
|
|
|
rapidjson::Document jDoc;
|
|
|
|
const auto data = FileUtils::getInstance()->getStringFromFile(fullPath);
|
|
|
|
jDoc.Parse(data.c_str());
|
|
|
|
addSpriteFramesWithJson(jDoc, textureFileName, filePath, cache);
|
|
|
|
}
|
|
|
|
|
|
|
|
void load(const Data& content, Texture2D* texture, SpriteFrameCache& cache) override
|
|
|
|
{
|
|
|
|
if (content.isNull())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rapidjson::Document jDoc;
|
|
|
|
const auto* text = (char*)content.getBytes();
|
|
|
|
jDoc.Parse(text);
|
|
|
|
addSpriteFramesWithJson(jDoc, texture, "by#addSpriteFramesWithFileContent()", cache);
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void reload(std::string_view filePath, SpriteFrameCache& cache) override
|
2021-08-13 14:52:58 +08:00
|
|
|
{
|
|
|
|
const auto fullPath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
|
|
|
rapidjson::Document doc;
|
|
|
|
const auto data = FileUtils::getInstance()->getStringFromFile(fullPath);
|
|
|
|
doc.Parse(data.c_str());
|
|
|
|
|
|
|
|
std::string texturePath;
|
|
|
|
|
|
|
|
auto&& metaItr = doc.FindMember("meta");
|
|
|
|
if (metaItr != doc.MemberEnd())
|
|
|
|
{
|
|
|
|
texturePath = metaItr->value["image"].GetString();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!texturePath.empty())
|
|
|
|
{
|
|
|
|
// build texture path relative to plist file
|
|
|
|
texturePath = FileUtils::getInstance()->fullPathFromRelativeFile(texturePath, filePath);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// build texture path by replacing file extension
|
|
|
|
texturePath = filePath;
|
|
|
|
|
|
|
|
// remove .xxx
|
|
|
|
const auto startPos = texturePath.find_last_of('.');
|
|
|
|
if (startPos != std::string::npos)
|
|
|
|
{
|
|
|
|
texturePath = texturePath.erase(startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
// append .png
|
|
|
|
texturePath = texturePath.append(".png");
|
|
|
|
}
|
|
|
|
|
|
|
|
Texture2D* texture = nullptr;
|
|
|
|
if (Director::getInstance()->getTextureCache()->reloadTexture(texturePath))
|
|
|
|
{
|
|
|
|
texture = Director::getInstance()->getTextureCache()->getTextureForKey(texturePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (texture)
|
|
|
|
{
|
|
|
|
reloadSpriteFramesWithDictionary(doc, texture, filePath, cache);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXLOG("GenericJsonArraySpriteSheetLoader::reload: Couldn't load texture");
|
2021-08-13 14:52:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2021-12-31 12:12:40 +08:00
|
|
|
void addSpriteFramesWithJson(const rapidjson::Document& doc,
|
|
|
|
std::string_view texturePath,
|
|
|
|
std::string_view atlasPath,
|
|
|
|
SpriteFrameCache& cache)
|
2021-08-13 14:52:58 +08:00
|
|
|
{
|
|
|
|
std::string pixelFormatName;
|
|
|
|
auto&& metaItr = doc.FindMember("meta");
|
|
|
|
if (metaItr != doc.MemberEnd())
|
|
|
|
{
|
|
|
|
auto&& pixelFormatItr = metaItr->value.FindMember("format");
|
|
|
|
if (pixelFormatItr != metaItr->value.MemberEnd())
|
|
|
|
{
|
|
|
|
pixelFormatName = pixelFormatItr->value.GetString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
Texture2D* texture = nullptr;
|
2021-08-13 14:52:58 +08:00
|
|
|
static std::unordered_map<std::string, backend::PixelFormat> pixelFormats = {
|
|
|
|
{"RGBA8888", backend::PixelFormat::RGBA8},
|
|
|
|
{"RGBA4444", backend::PixelFormat::RGBA4},
|
|
|
|
{"RGB5A1", backend::PixelFormat::RGB5A1},
|
|
|
|
{"RGBA5551", backend::PixelFormat::RGB5A1},
|
|
|
|
{"RGB565", backend::PixelFormat::RGB565},
|
|
|
|
{"A8", backend::PixelFormat::A8},
|
|
|
|
{"ALPHA", backend::PixelFormat::A8},
|
|
|
|
{"I8", backend::PixelFormat::L8},
|
|
|
|
{"AI88", backend::PixelFormat::LA8},
|
|
|
|
{"ALPHA_INTENSITY", backend::PixelFormat::LA8},
|
|
|
|
//{"BGRA8888", backend::PixelFormat::BGRA8888}, no Image conversion RGBA -> BGRA
|
2021-12-31 12:12:40 +08:00
|
|
|
{"RGB888", backend::PixelFormat::RGB8}};
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
const auto pixelFormatIt = pixelFormats.find(pixelFormatName);
|
|
|
|
if (pixelFormatIt != pixelFormats.end())
|
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
const backend::PixelFormat pixelFormat = (*pixelFormatIt).second;
|
2022-05-13 21:06:17 +08:00
|
|
|
texture = Director::getInstance()->getTextureCache()->addImage(texturePath, pixelFormat);
|
2021-08-13 14:52:58 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
texture = Director::getInstance()->getTextureCache()->addImage(texturePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (texture)
|
|
|
|
{
|
|
|
|
addSpriteFramesWithJson(doc, texture, atlasPath, cache);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXLOG("GenericJsonArraySpriteSheetLoader::addSpriteFramesWithJson: Couldn't load texture");
|
2021-08-13 14:52:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void addSpriteFramesWithJson(const rapidjson::Document& doc,
|
|
|
|
Texture2D* texture,
|
|
|
|
std::string_view atlasPath,
|
|
|
|
SpriteFrameCache& cache)
|
2021-08-13 14:52:58 +08:00
|
|
|
{
|
|
|
|
auto&& framesItr = doc.FindMember("frames");
|
|
|
|
if (framesItr == doc.MemberEnd())
|
|
|
|
return;
|
|
|
|
|
|
|
|
const auto spriteSheet = std::make_shared<SpriteSheet>();
|
2021-12-31 12:12:40 +08:00
|
|
|
spriteSheet->format = getFormat();
|
|
|
|
spriteSheet->path = atlasPath;
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
const auto textureFileName = Director::getInstance()->getTextureCache()->getTextureFilePath(texture);
|
2021-12-31 12:12:40 +08:00
|
|
|
Image* image = nullptr;
|
2021-08-13 14:52:58 +08:00
|
|
|
NinePatchImageParser parser;
|
|
|
|
|
|
|
|
for (auto&& frameItr : framesItr->value.GetArray())
|
|
|
|
{
|
|
|
|
if (!frameItr.IsObject())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto spriteFrameName = frameItr["filename"].GetString();
|
2021-12-31 12:12:40 +08:00
|
|
|
auto* spriteFrame = cache.findFrame(spriteFrameName);
|
2021-08-13 14:52:58 +08:00
|
|
|
if (spriteFrame)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto frameX = frameItr["frame"]["x"].GetFloat();
|
|
|
|
const auto frameY = frameItr["frame"]["y"].GetFloat();
|
|
|
|
const auto frameW = frameItr["frame"]["w"].GetFloat();
|
|
|
|
const auto frameH = frameItr["frame"]["h"].GetFloat();
|
2021-08-13 14:52:58 +08:00
|
|
|
const auto textureRect = Rect(frameX, frameY, frameW, frameH);
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto originalWidth = frameItr["sourceSize"]["w"].GetInt();
|
2021-08-13 14:52:58 +08:00
|
|
|
const auto originalHeight = frameItr["sourceSize"]["w"].GetInt();
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto originalSize = Size(originalWidth, originalHeight);
|
2021-08-13 14:52:58 +08:00
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto trimmedWidth = frameItr["spriteSourceSize"]["w"].GetInt();
|
2021-08-13 14:52:58 +08:00
|
|
|
const auto trimmedHeight = frameItr["spriteSourceSize"]["h"].GetInt();
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto trimmedSize = Size(trimmedWidth, trimmedHeight);
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
const auto textureRotated = frameItr["rotated"].GetBool();
|
|
|
|
|
|
|
|
// create frame
|
2021-12-31 12:12:40 +08:00
|
|
|
spriteFrame = SpriteFrame::createWithTexture(
|
|
|
|
texture, Rect(textureRect.origin.x, textureRect.origin.y, trimmedSize.width, trimmedSize.height),
|
|
|
|
textureRotated, Vec2(), originalSize);
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
const auto flag = NinePatchImageParser::isNinePatchImage(spriteFrameName);
|
|
|
|
if (flag)
|
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
if (image == nullptr)
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
image = new Image();
|
2021-08-13 14:52:58 +08:00
|
|
|
image->initWithImageFile(textureFileName);
|
|
|
|
}
|
|
|
|
parser.setSpriteFrameInfo(image, spriteFrame->getRectInPixels(), spriteFrame->isRotated());
|
|
|
|
cache.addSpriteFrameCapInset(spriteFrame, parser.parseCapInset(), texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
// add sprite frame
|
|
|
|
cache.insertFrame(spriteSheet, spriteFrameName, spriteFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
spriteSheet->full = true;
|
|
|
|
|
2022-07-16 10:43:05 +08:00
|
|
|
AX_SAFE_DELETE(image);
|
2021-08-13 14:52:58 +08:00
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void reloadSpriteFramesWithDictionary(const rapidjson::Document& doc,
|
|
|
|
Texture2D* texture,
|
|
|
|
std::string_view atlasPath,
|
|
|
|
SpriteFrameCache& cache)
|
2021-08-13 14:52:58 +08:00
|
|
|
{
|
|
|
|
auto&& framesItr = doc.FindMember("frames");
|
|
|
|
if (framesItr == doc.MemberEnd())
|
|
|
|
return;
|
|
|
|
|
|
|
|
const auto spriteSheet = std::make_shared<SpriteSheet>();
|
2021-12-31 12:12:40 +08:00
|
|
|
spriteSheet->format = getFormat();
|
|
|
|
spriteSheet->path = atlasPath;
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
for (auto&& frameItr : framesItr->value.GetArray())
|
|
|
|
{
|
|
|
|
if (!frameItr.IsObject())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto spriteFrameName = frameItr["filename"].GetString();
|
2021-12-31 12:12:40 +08:00
|
|
|
auto* spriteFrame = cache.findFrame(spriteFrameName);
|
2021-08-13 14:52:58 +08:00
|
|
|
if (spriteFrame)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto frameX = frameItr["frame"]["x"].GetFloat();
|
|
|
|
const auto frameY = frameItr["frame"]["y"].GetFloat();
|
|
|
|
const auto frameW = frameItr["frame"]["w"].GetFloat();
|
|
|
|
const auto frameH = frameItr["frame"]["h"].GetFloat();
|
2021-08-13 14:52:58 +08:00
|
|
|
const auto textureRect = Rect(frameX, frameY, frameW, frameH);
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto originalWidth = frameItr["sourceSize"]["w"].GetInt();
|
2021-08-13 14:52:58 +08:00
|
|
|
const auto originalHeight = frameItr["sourceSize"]["w"].GetInt();
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto originalSize = Size(originalWidth, originalHeight);
|
2021-08-13 14:52:58 +08:00
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto trimmedWidth = frameItr["spriteSourceSize"]["w"].GetInt();
|
2021-08-13 14:52:58 +08:00
|
|
|
const auto trimmedHeight = frameItr["spriteSourceSize"]["h"].GetInt();
|
2021-12-31 12:12:40 +08:00
|
|
|
const auto trimmedSize = Size(trimmedWidth, trimmedHeight);
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
const auto textureRotated = frameItr["rotated"].GetBool();
|
|
|
|
|
|
|
|
// create frame
|
2021-12-31 12:12:40 +08:00
|
|
|
spriteFrame = SpriteFrame::createWithTexture(
|
|
|
|
texture, Rect(textureRect.origin.x, textureRect.origin.y, trimmedSize.width, trimmedSize.height),
|
|
|
|
textureRotated, Vec2(), originalSize);
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
// add sprite frame
|
|
|
|
cache.insertFrame(spriteSheet, spriteFrameName, spriteFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
SpriteFrameCacheJsonAtlasTest::SpriteFrameCacheJsonAtlasTest()
|
|
|
|
{
|
|
|
|
auto* cache = SpriteFrameCache::getInstance();
|
|
|
|
cache->registerSpriteSheetLoader(std::make_unique<GenericJsonArraySpriteSheetLoader>());
|
|
|
|
|
|
|
|
const Size screenSize = Director::getInstance()->getWinSize();
|
|
|
|
|
|
|
|
infoLabel = Label::create();
|
|
|
|
infoLabel->setAnchorPoint(Point(0.5f, 1.0f));
|
2022-07-11 17:50:21 +08:00
|
|
|
infoLabel->setAlignment(axis::TextHAlignment::CENTER);
|
2021-08-13 14:52:58 +08:00
|
|
|
infoLabel->setPosition(screenSize.width * 0.5f, screenSize.height * 0.7f);
|
|
|
|
addChild(infoLabel);
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
loadSpriteFrames("Images/sprite_frames_test/test_RGB8888_generic.json"sv, backend::PixelFormat::RGBA8);
|
2021-08-13 14:52:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SpriteFrameCacheJsonAtlasTest::~SpriteFrameCacheJsonAtlasTest()
|
|
|
|
{
|
|
|
|
auto* cache = SpriteFrameCache::getInstance();
|
2021-08-17 12:04:45 +08:00
|
|
|
cache->deregisterSpriteSheetLoader(GenericJsonArraySpriteSheetLoader::FORMAT);
|
2021-08-13 14:52:58 +08:00
|
|
|
}
|
|
|
|
|
2021-12-31 12:12:40 +08:00
|
|
|
void SpriteFrameCacheJsonAtlasTest::loadSpriteFrames(std::string_view file,
|
2022-07-11 17:50:21 +08:00
|
|
|
axis::backend::PixelFormat expectedFormat)
|
2021-08-13 14:52:58 +08:00
|
|
|
{
|
2021-08-17 12:04:45 +08:00
|
|
|
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(file, GenericJsonArraySpriteSheetLoader::FORMAT);
|
2021-12-31 12:12:40 +08:00
|
|
|
SpriteFrame* spriteFrame =
|
|
|
|
SpriteFrameCache::getInstance()->getSpriteFrameByName("sprite_frames_test/grossini.png"sv);
|
|
|
|
Texture2D* texture = spriteFrame->getTexture();
|
2021-12-29 19:31:28 +08:00
|
|
|
const ssize_t bitsPerKB = 8 * 1024;
|
2021-12-31 12:12:40 +08:00
|
|
|
const double memorySize = 1.0 * texture->getBitsPerPixelForFormat() * texture->getContentSizeInPixels().width *
|
|
|
|
texture->getContentSizeInPixels().height / bitsPerKB;
|
2022-07-16 10:43:05 +08:00
|
|
|
#ifndef AX_USE_METAL
|
|
|
|
AX_ASSERT(texture->getPixelFormat() == expectedFormat);
|
2021-08-13 14:52:58 +08:00
|
|
|
#endif
|
2021-12-31 12:12:40 +08:00
|
|
|
const std::string textureInfo = StringUtils::format("%s%s: %.2f KB\r\n", infoLabel->getString().data(),
|
|
|
|
texture->getStringForFormat(), memorySize);
|
|
|
|
infoLabel->setString(textureInfo);
|
2021-08-13 14:52:58 +08:00
|
|
|
|
|
|
|
SpriteFrameCache::getInstance()->removeSpriteFramesFromFile(file);
|
|
|
|
Director::getInstance()->getTextureCache()->removeTexture(texture);
|
|
|
|
}
|