Я работал над созданием класса активов, который может генерировать динамические объекты TextureAtlas
всякий раз, когда они мне нужны. Конкретный метод - Assets.generateTextureAtlas()
, и я пытаюсь максимально оптимизировать его, поскольку мне довольно часто приходится регенерировать атлас текстур, и я надеялся получить лучшее время, чем мои средние 53 мс.
53 мс в настоящее время обходятся мне примерно в 3 кадра, которые могут складываться быстрее, чем больше элементов мне нужно упаковать в мой атлас текстур, и частота, с которой мне нужно их генерировать. Так что ответ на все ловушки в моем коде был бы замечательным.
Весь код класса доступен здесь в кратком виде на github.
Класс RectanglePacker
просто используется для упаковки прямоугольников как можно ближе друг к другу (аналогично упаковщику текстур), и его можно найти здесь.
Для справки, вот метод:
public static function generateTextureAtlas(folder:String):void
{
if (!_initialised) throw new Error("Assets class not initialised.");
if (_renderTextureAtlases[folder] != null)
{
(_renderTextureAtlases[folder] as TextureAtlas).dispose();
}
var i:int;
var image:Image = new Image(_blankTexture);
var itemName:String;
var itemNames:Vector.<String> = Assets.getNames(folder + "/");
var itemsTexture:RenderTexture;
var itemTexture:Texture;
var itemTextures:Vector.<Texture> = Assets.getTextures(folder + "/");
var noOfRectangles:int;
var rect:Rectangle;
var rectanglePacker:RectanglePacker = new RectanglePacker();
var texture:Texture;
noOfRectangles = itemTextures.length;
if (noOfRectangles == 0)
{
return;
}
for (i = 0; i < noOfRectangles; i++)
{
rectanglePacker.insertRectangle(Math.round(itemTextures[i].width), Math.round(itemTextures[i].height), i);
}
rectanglePacker.packRectangles();
if (rectanglePacker.rectangleCount != noOfRectangles)
{
throw new Error("Only " + rectanglePacker.rectangleCount + " out of " + noOfRectangles + " rectangles packed for folder: " + folder);
}
itemsTexture = new RenderTexture(rectanglePacker.width, rectanglePacker.height);
itemsTexture.drawBundled(function():void
{
for (i = 0; i < noOfRectangles; i++)
{
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i, rect);
image.texture = itemTexture;
image.readjustSize();
image.x = rect.x + itemTexture.frame.x;
image.y = rect.y + itemTexture.frame.y;
itemsTexture.draw(image);
}
});
_renderTextureAtlases[folder] = new TextureAtlas(itemsTexture);
for (i = 0; i < noOfRectangles; i++)
{
itemName = itemNames[rectanglePacker.getRectangleId(i)];
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i);
(_renderTextureAtlases[folder] as TextureAtlas).addRegion(itemName, rect, itemTexture.frame);
}
}
generateTextureAtlas()
. Для завершения требуется в среднем 53 мс, и я ищу любые способы ускорить его. Он использует другие методы внутри этого метода, которые можно увидеть в сущности класса Assets на github. Я пытался оптимизировать столько, сколько мог, но я все еще застрял с нездоровым временем выполнения 53 мс. - person xLite   schedule 25.01.2013