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%的内存消耗。

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

  • 相关阅读:
    0diff算法参考资料
    js 对象属性值
    一些带有设计模式的优秀代码
    vue 配置多页面
    cms 管理系统
    网络技术:EtherChannel 链路汇聚
    网络技术:VLAN 中继协议(VTP)
    网络管理:管理信息库
    网络管理:抽象语法表示 ASN.1
    网络管理:基本编码规则(BER)
  • 原文地址:https://www.cnblogs.com/atong/p/3107901.html
Copyright © 2011-2022 走看看