|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Загрузка текстур в риалтайме
Здравствуйте.
Для большей гибкости при обновлении, реализовываю поддержку текстур в качестве отдельных png-файлов. override public function run():void { types = model.types; EmbeddedAssets.initialize(); var loader:Load = new Load(types.assetPath(types.logo)); loader.addEventListener(Event.COMPLETE, completeHandler ); loader.start(); } protected function completeHandler(event:Event):void { var loader:Load = event.currentTarget as Load; AssetManager.instance.uploadByteArray( types.logo, loader.data ); AssetManager.instance.loadQueue( release ); } package net.alexscript.worker.file { import flash.events.EventDispatcher; import flash.net.URLRequest; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.events.Event; import flash.events.ProgressEvent; import flash.events.IOErrorEvent; import flash.utils.ByteArray; public class Load extends EventDispatcher { private var _file:String; public function Load(file:String) { _file = file; } public var data:ByteArray = new ByteArray(); public function start():void{ trace('start load: '+_file); var request:URLRequest = new URLRequest(_file); var urlLoader:URLLoader = new URLLoader(request); urlLoader.dataFormat = URLLoaderDataFormat.BINARY; urlLoader.addEventListener(IOErrorEvent.IO_ERROR, completeError); urlLoader.addEventListener(ProgressEvent.PROGRESS, progressHandler ); urlLoader.addEventListener(Event.COMPLETE, onLoadedAndSave); } private function completeError(e:IOErrorEvent):void { trace('error load: '+_file); dispatchEvent(new Event(Event.COMPLETE)); } private function onLoadedAndSave(e:Event):void { data.writeBytes(e.currentTarget.data,0,e.currentTarget.data.length); trace('complete load: '+_file); dispatchEvent(new Event(Event.COMPLETE)); } private function progressHandler(e:ProgressEvent):void { dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS,false,false,e.bytesLoaded+data.length,e.bytesTotal)); } } } package com.state.model { import flash.events.EventDispatcher; import flash.utils.ByteArray; import starling.textures.Texture; import starling.utils.AssetManager; public class AssetManager extends EventDispatcher { public static function get instance():com.state.model.AssetManager { if (!_instance) _instance = new com.state.model.AssetManager(); return _instance; } private static var _instance:com.state.model.AssetManager; public function AssetManager() { if (!_instance) { super(); _instance = this; png = new PNGDecoder(); } } public function uploadByteArray( key:String, byteArray:ByteArray ):void { assetsMgr.addTexture( key, Texture.fromBitmapData(png.decode(byteArray)) ); } public function loadQueue(_callback:Function):void { assetsMgr.loadQueue(function(ratio:Number):void { Debug.log(' texture load '+ratio); if (ratio == 1.0) _callback(); }); } public function get assetsMgr():starling.utils.AssetManager { if (!assets) assets = new starling.utils.AssetManager(); return assets; } private var assets:starling.utils.AssetManager; private var png:PNGDecoder; } } package { import flash.display.BitmapData; import flash.utils.ByteArray; import flash.geom.Matrix; import flash.geom.Rectangle; /******************************* PNGDecoder Author: Jerion A class that decodes png byte arrays and generates a bitmapdata. This is my first attempt at decoding images, so there are a lot of things that are not implemented. So far, it can only decode truecolour with alpha png images with no interlacing, no filter, and bit depth of 8. ********************************/ public class PNGDecoder { private const IHDR:uint = 0x49484452; private const PLTE:uint = 0x504c5445; private const IDAT:uint = 0x49444154; private const IEND:uint = 0x49454e44; private var imgWidth:uint = 0; private var imgHeight:uint = 0; //file info, but not used yet. private var bitDepth:uint = 0; private var colourType:uint = 0; private var compressionMethod:uint = 0; private var filterMethod:uint = 0; private var interlaceMethod:uint = 0; private var chunks:Array; private var input:ByteArray; private var output:ByteArray; //recieves the bytearray and returns a bitmapdata public function decode(ba:ByteArray):BitmapData { chunks = new Array(); input = new ByteArray(); output = new ByteArray(); input = ba; input.position = 0; if (!readSignature()) throw new Error("wrong signature"); getChunks(); for (var i:int = 0; i < chunks.length; ++i) { switch(chunks[i].type) { case IHDR: processIHDR(i); break; //case PLTE: processPLTE(i); break; case IDAT: processIDAT(i); break; //case IEND: processIEND(i); break; } } //Since the image is inverted in x and y, I have to flip it using a Matrix object. There should be a better solution for this.. var bd0:BitmapData = new BitmapData(imgWidth, imgHeight); var bd1:BitmapData = new BitmapData(imgWidth, imgHeight, true, 0xffffff); if (output.length > 0 && (imgWidth * imgHeight * 4) == output.length) { output.position = 0; bd0.setPixels(new Rectangle(0,0,imgWidth,imgHeight), output); var mat:Matrix = new Matrix(); mat.scale(-1,-1); mat.translate(imgWidth, imgHeight); bd1.draw(bd0, mat); } return bd1; } //read the header of the image private function processIHDR(index:uint):void { input.position = chunks[index].position; imgWidth = input.readUnsignedInt(); imgHeight = input.readUnsignedInt(); //file info, but is not used yet bitDepth = input.readUnsignedByte(); colourType = input.readUnsignedByte(); compressionMethod = input.readUnsignedByte(); filterMethod = input.readUnsignedByte(); interlaceMethod = input.readUnsignedByte(); } //This can't handle multiple IDATs yet, and it can only decode filter 0 scanlines. private function processIDAT(index:uint):void { var tmp:ByteArray = new ByteArray(); var pixw:uint = imgWidth * 4; tmp.writeBytes(input, chunks[index].position, chunks[index].length); tmp.uncompress(); for (var i:int = tmp.length - 1; i > 0; --i) { if (i % (pixw + 1) != 0) { var a:uint = tmp[i]; var b:uint = tmp[i-1]; var g:uint = tmp[i-2]; var r:uint = tmp[i-3]; output.writeByte(a); output.writeByte(r); output.writeByte(g); output.writeByte(b); i -= 3; } } } private function getChunks():void { var pos:uint = 0; var len:uint = 0; var type:uint = 0; var loopEnd:int = input.length; while (input.position < loopEnd) { len = input.readUnsignedInt(); type = input.readUnsignedInt(); pos = input.position; input.position += len; input.position += 4; //crc block. It is ignored right now, but if you want to retrieve it, replace this line with "input.readUnsignedInt()" chunks.push({position: pos, length: len, type: type}); } } private function readSignature():Boolean { return (input.readUnsignedInt() == 0x89504e47 && input.readUnsignedInt() == 0x0D0A1A0A); } //transform the chunk type to a string representation private function fixType(num:uint):String { var ret:String = ""; var str:String = num.toString(16); while (str.length < 8) str = "0" + str; ret += String.fromCharCode(parseInt(str.substr(0,2), 16)); ret += String.fromCharCode(parseInt(str.substr(2,2), 16)); ret += String.fromCharCode(parseInt(str.substr(4,2), 16)); ret += String.fromCharCode(parseInt(str.substr(6,2), 16)); return ret; } } }
__________________
return this... |
|
|||||
Цитата:
По поводу вопроса: зачем вообще это нужно? Чем старлинговский ассет менеджер не устраивает? Отличная штука. Я всегда пользуюсь только им и все отлично. Так же можно хоть когда по запросу подгрузить нужную текстуру |
|
|||||
Lorem ipsum
|
ATF, если я не ошибаюсь (а я могу!), шикарен тем, что в GPU хранится сжатым(?).
Но если это не так (ответа в свое время в "ленивом режиме" я так и не нашел), то да, ATF — вообще какая-то лажа.
__________________
Поймай яблоко 2! |
|
|||||
Регистрация: Dec 2010
Адрес: Ярославль
Сообщений: 1,255
|
Цитата:
Цитата:
Также atf использует разные "родные" типы сжатия для разных платформ. Можно включить в файлы только версии для используемых платформ, что ещё уменьшит вес файла. |
|
|||||
Lorem ipsum
|
Вот! Если таки да, то гут. Иначе — фигня какая-то битая.
__________________
Поймай яблоко 2! |
|
|||||
Цитата:
Если оставлю png, байтеррей нужен не по прямому назначению. Есть какие-то особенности?
__________________
return this... |
|
|||||
Lorem ipsum
|
Выше написали про плюс — компактность размещения в памяти GPU.
Минус — как минимум джипежность. Целые семинары о том, как делать так, чтобы ATF-картинку мылом не покрыло.
__________________
Поймай яблоко 2! |
|
|||||
Lorem ipsum
|
В смысле "пустые места"?
__________________
Поймай яблоко 2! |
Часовой пояс GMT +4, время: 10:33. |
|
« Предыдущая тема | Следующая тема » |
|
|