zoukankan      html  css  js  c++  java
  • 如果将纹理的内存使用减半

    ATF纹理能明显降低纹理的内存使用,但是有时候你可能不会用到它。如果你是动态生成纹理或者从第三方加载,那就不需要使用压缩的ATF纹理了。今天此文主要讲述如果在不使用ATF的情况下节省内存。


    首先,确保你的应用时运行在Flash Player11.7或者AIR3.7下,可以通过Capabilities.version快速查看下。编译的时候也需要将Player11.7设为目标Flash player,可以用如下参数:-target-player=11.7.0,-swf-version=20.输入上面参数可以解锁郎中类型的纹理,这两种纹理都是每个像素是用16位来表示,而不是平常的24位或者32位。


    当然需要将Context3DTextureFormat.BGR_PACKED或者Context3DTextureFormat.BGRA_PACKED传递给Context3D.createTexture,这样就可以获得16位/像素的纹理了。


    Context3DTextureFormat.BGR_PACKED这种纹理的红色通道需要5位,绿色为6为,蓝色为5位。因为人眼睛对绿色的识别要好于红色跟蓝色。我们可以用RGB565来简化记忆。如果需要alpha值,那就使用Context3DTextureFormat.BGRA_PACKED,每个颜色都有一个4位的alpha值。虽然颜色不怎么精确,但是那就是支持alpha付出的代价。


    建立纹理后,只需像以前那样调用Texture.uploadFromBitmapData,BitmapData就会自动样式化为16位/像素。这样在不需要透明度的图片上就减少了33%内存使用,需要透明度的减少了50%的内存使用。


    试试这个。我只做了一个小的应用,此应用显示了一个512*512不透明土地纹理和一个128*128的带有一点透明的Flash标志。点击下面的按钮来改变不同的纹理类型。

      1 package
      2 {
      3 import com.adobe.utils.AGALMiniAssembler;
      4 
      5 import flash.display.Bitmap;
      6 import flash.display.BitmapData;
      7 import flash.display.Sprite;
      8 import flash.display.Stage3D;
      9 import flash.display.StageAlign;
     10 import flash.display.StageScaleMode;
     11 import flash.display3D.Context3D;
     12 import flash.display3D.Context3DBlendFactor;
     13 import flash.display3D.Context3DProgramType;
     14 import flash.display3D.Context3DRenderMode;
     15 import flash.display3D.Context3DTextureFormat;
     16 import flash.display3D.Context3DVertexBufferFormat;
     17 import flash.display3D.IndexBuffer3D;
     18 import flash.display3D.Program3D;
     19 import flash.display3D.VertexBuffer3D;
     20 import flash.display3D.textures.Texture;
     21 import flash.events.Event;
     22 import flash.events.MouseEvent;
     23 import flash.text.TextField;
     24 import flash.text.TextFieldAutoSize;
     25 import flash.text.TextFormat;
     26 import flash.utils.ByteArray;
     27 
     28 public class Texture16BPP extends Sprite
     29 {
     30 private static const PAD:Number = 5;
     31 
     32 [Embed(source="earth.jpg")]
     33 private static const TEXTURE_RGB:Class;
     34 
     35 [Embed(source="flash_logo_alpha.png")]
     36 private static const TEXTURE_RGBA:Class;
     37 
     38 private var program:Program3D;
     39 private var posUV:VertexBuffer3D;
     40 private var tris:IndexBuffer3D;
     41 private var textureRGB888:Texture;
     42 private var textureRGB565:Texture;
     43 private var textureRGBA8888:Texture;
     44 private var textureRGBA4444:Texture;
     45 private var curTexture:Texture;
     46 private var context3D:Context3D;
     47 
     48 private var modeDisplay:TextField;
     49 
     50 public function Texture16BPP()
     51 {
     52 stage.align = StageAlign.TOP_LEFT;
     53 stage.scaleMode = StageScaleMode.NO_SCALE;
     54 stage.frameRate = 60;
     55 
     56 var stage3D:Stage3D = stage.stage3Ds[0];
     57 stage3D.addEventListener(Event.CONTEXT3D_CREATE, onContextCreated);
     58 stage3D.requestContext3D(Context3DRenderMode.AUTO);
     59 }
     60 
     61 protected function onContextCreated(ev:Event): void
     62 {
     63 var stage3D:Stage3D = stage.stage3Ds[0];
     64 stage3D.removeEventListener(Event.CONTEXT3D_CREATE, onContextCreated);
     65 context3D = stage3D.context3D; 
     66 context3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 0);
     67 context3D.enableErrorChecking = true;
     68 
     69 makeButtons("RGB888", "RGB565", "RGBA8888", "RGBA4444");
     70 
     71 var assembler:AGALMiniAssembler = new AGALMiniAssembler();
     72 assembler.assemble(
     73 Context3DProgramType.VERTEX,
     74 "mov op, va0\n" +
     75 "mov v0, va1"
     76 );
     77 var vertexProgram:ByteArray = assembler.agalcode;
     78 
     79 assembler.assemble(
     80 Context3DProgramType.FRAGMENT,
     81 "tex oc, v0, fs0 <2d,linear,mipnone,clamp,dxt1>"
     82 );
     83 var fragmentProgram:ByteArray = assembler.agalcode;
     84 
     85 program = context3D.createProgram();
     86 program.upload(vertexProgram, fragmentProgram);
     87 
     88 posUV = context3D.createVertexBuffer(4, 5);
     89 posUV.uploadFromVector(
     90 new <Number>[
     91 // X, Y, Z, U, V
     92 -1, -1, 0, 0, 1,
     93 -1, 1, 0, 0, 0,
     94 1, 1, 0, 1, 0,
     95 1, -1, 0, 1, 1
     96 ], 0, 4
     97 );
     98 
     99 // Create the triangles index buffer
    100 tris = context3D.createIndexBuffer(6);
    101 tris.uploadFromVector(
    102 new <uint>[
    103 0, 1, 2,
    104 2, 3, 0
    105 ], 0, 6
    106 );
    107 
    108 var opaque:BitmapData = (new TEXTURE_RGB() as Bitmap).bitmapData;
    109 var alpha:BitmapData = (new TEXTURE_RGBA() as Bitmap).bitmapData;
    110 
    111 textureRGB888 = context3D.createTexture(
    112 opaque.width,
    113 opaque.height,
    114 Context3DTextureFormat.BGRA,
    115 false
    116 );
    117 textureRGB888.uploadFromBitmapData(opaque);
    118 
    119 textureRGB565 = context3D.createTexture(
    120 opaque.width,
    121 opaque.height,
    122 Context3DTextureFormat.BGR_PACKED,
    123 false
    124 );
    125 textureRGB565.uploadFromBitmapData(opaque);
    126 
    127 textureRGBA8888 = context3D.createTexture(
    128 alpha.width,
    129 alpha.height,
    130 Context3DTextureFormat.BGRA,
    131 false
    132 );
    133 textureRGBA8888.uploadFromBitmapData(alpha);
    134 
    135 textureRGBA4444 = context3D.createTexture(
    136 alpha.width,
    137 alpha.height,
    138 Context3DTextureFormat.BGRA_PACKED,
    139 false
    140 );
    141 textureRGBA4444.uploadFromBitmapData(alpha);
    142 
    143 curTexture = textureRGB888;
    144 
    145 modeDisplay = new TextField();
    146 modeDisplay.autoSize = TextFieldAutoSize.LEFT;
    147 modeDisplay.defaultTextFormat = new TextFormat("_sans", 36);
    148 modeDisplay.text = "RGB888";
    149 addChild(modeDisplay);
    150 
    151 addEventListener(Event.ENTER_FRAME, onEnterFrame);
    152 }
    153 
    154 private function makeButtons(...labels): Number
    155 {
    156 var curX:Number = PAD;
    157 var curY:Number = stage.stageHeight - PAD;
    158 for each (var label:String in labels)
    159 {
    160 var tf:TextField = new TextField();
    161 tf.mouseEnabled = false;
    162 tf.selectable = false;
    163 tf.defaultTextFormat = new TextFormat("_sans");
    164 tf.autoSize = TextFieldAutoSize.LEFT;
    165 tf.text = label;
    166 tf.name = "lbl";
    167 
    168 var button:Sprite = new Sprite();
    169 button.buttonMode = true;
    170 button.graphics.beginFill(0xF5F5F5);
    171 button.graphics.drawRect(0, 0, tf.width+PAD, tf.height+PAD);
    172 button.graphics.endFill();
    173 button.graphics.lineStyle(1);
    174 button.graphics.drawRect(0, 0, tf.width+PAD, tf.height+PAD);
    175 button.addChild(tf);
    176 button.addEventListener(MouseEvent.CLICK, onButton);
    177 if (curX + button.width > stage.stageWidth - PAD)
    178 {
    179 curX = PAD;
    180 curY -= button.height + PAD;
    181 }
    182 button.x = curX;
    183 button.y = curY - button.height;
    184 addChild(button);
    185 
    186 curX += button.width + PAD;
    187 }
    188 
    189 return curY - button.height;
    190 }
    191 
    192 private function onButton(ev:MouseEvent): void
    193 {
    194 var mode:String = ev.target.getChildByName("lbl").text;
    195 switch (mode)
    196 {
    197 case "RGB888":
    198 curTexture = textureRGB888;
    199 modeDisplay.text = "RGB888";
    200 break;
    201 case "RGB565":
    202 curTexture = textureRGB565;
    203 modeDisplay.text = "RGB565";
    204 break;
    205 case "RGBA8888":
    206 curTexture = textureRGBA8888;
    207 modeDisplay.text = "RGBA8888";
    208 break;
    209 case "RGBA4444":
    210 curTexture = textureRGBA4444;
    211 modeDisplay.text = "RGBA4444";
    212 break;
    213 }
    214 }
    215 
    216 private function onEnterFrame(ev:Event): void
    217 {
    218 context3D.clear(0.5, 0.5, 0.5);
    219 context3D.setProgram(program);
    220 context3D.setBlendFactors(
    221 Context3DBlendFactor.SOURCE_ALPHA,
    222 Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA
    223 );
    224 
    225 // Draw selected texture
    226 context3D.setTextureAt(0, curTexture);
    227 context3D.setVertexBufferAt(0, posUV, 0, Context3DVertexBufferFormat.FLOAT_3);
    228 context3D.setVertexBufferAt(1, posUV, 3, Context3DVertexBufferFormat.FLOAT_2);
    229 context3D.drawTriangles(tris);
    230 
    231 context3D.present();
    232 }
    233 }
    234 }

    结果会根据你先则的纹理图片而又稍微的不同。土地纹理使用16位的与24位的相比没多大区别,但是内存却能节省不少。Flash 标志则看起来要糟糕点。即使是阴影模式,图片的网格还是看起来很糟糕, 这可能不是一个降低内存的好例子,但是你还是降低了50%的内存消耗。

    原文链接:如果将纹理的内存使用减半

  • 相关阅读:
    LeetCode对撞指针汇总
    167. Two Sum II
    215. Kth Largest Element in an Array
    2018Action Recognition from Skeleton Data via Analogical Generalization over Qualitative Representations
    题解 Educational Codeforces Round 84 (Rated for Div. 2) (CF1327)
    题解 JZPKIL
    题解 八省联考2018 / 九省联考2018
    题解 六省联考2017
    题解 Codeforces Round #621 (Div. 1 + Div. 2) (CF1307)
    题解Codeforces Round #620 (Div. 2)
  • 原文地址:https://www.cnblogs.com/atong/p/3107901.html
Copyright © 2011-2022 走看看