zoukankan      html  css  js  c++  java
  • Stage3D学习笔记(七):动态纹理

    本章用来作为Starling的滤镜实现原理的一个补充,但是为了了解原理,我们会使用原生API进行编码。

    我们知道,当我们调用drawTriangles方法时,我们的图像是绘制到后台缓冲区的,只有调用present方法时才会把图像呈现到屏幕。

    我们先来看看Context3D的两个方法:

    1. setRenderToTexture:我们默认的渲染都是在后台缓冲区进行的,使用该方法可以把渲染修改到一个纹理上,调用该方法后,Context3D对象的渲染操作(clear、drawTriangles等)都会渲染到指定的纹理上而不是后台缓冲区。
    2. setRenderToBackBuffer:配合setRenderToTexture的方法,可以将使用的缓冲区还原到后台缓冲区。

    如果本章看不明白可以看这篇文章进行补充:stage3D 搭建2d图形引擎 (八) 动态纹理

    先想一下我们的渲染过程:提交顶点数据和纹理,设定着色器和常量,最后调用drawTriangles配合索引缓冲进行绘制。

    对于绘制到后台缓冲区的模型,我们就不能再次进行操作了,如果我们想要对一个模型进行多次不同的渲染就需要使用setRenderToTexture方法了。

    先看看正常渲染的情况:

      1 package
      2 {
      3     import com.adobe.utils.AGALMiniAssembler;
      4     
      5     import flash.display.Bitmap;
      6     import flash.display.Sprite;
      7     import flash.display.Stage3D;
      8     import flash.display3D.Context3D;
      9     import flash.display3D.Context3DProfile;
     10     import flash.display3D.Context3DProgramType;
     11     import flash.display3D.Context3DRenderMode;
     12     import flash.display3D.Context3DTextureFormat;
     13     import flash.display3D.Context3DVertexBufferFormat;
     14     import flash.display3D.IndexBuffer3D;
     15     import flash.display3D.Program3D;
     16     import flash.display3D.VertexBuffer3D;
     17     import flash.display3D.textures.Texture;
     18     import flash.events.ErrorEvent;
     19     import flash.events.Event;
     20     
     21     [SWF(width=400, height=400, frameRate=60)]
     22     public class FilterDemo extends Sprite
     23     {
     24         [Embed(source="img.png")]
     25         private var IMG_CLASS:Class;
     26         
     27         private var _stage3D:Stage3D;
     28         private var _context3D:Context3D;
     29         private var _vertexBuffer:VertexBuffer3D;
     30         private var _indexBuffer:IndexBuffer3D;
     31         private var _texture:Texture;
     32         private var _program3D:Program3D;
     33         
     34         //会被作为目标渲染的纹理
     35         private var _filterTexture1:Texture;
     36         private var _filterTexture2:Texture;
     37         
     38         public function FilterDemo()
     39         {
     40             addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
     41         }
     42         
     43         private function addedToStageHandler(event:Event):void
     44         {
     45             if(stage.stage3Ds.length > 0)
     46             {
     47                 _stage3D = stage.stage3Ds[0];
     48                 _stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
     49                 _stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
     50                 _stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
     51             }
     52         }
     53         
     54         private function stage3DErrorHandler(event:ErrorEvent):void
     55         {
     56             trace("Context3D对象请求失败:", event.text);
     57         }
     58         
     59         private function context3DCreateHandler(event:Event):void
     60         {
     61             initContext3D();
     62             initBuffer();
     63             initTexture();
     64             normalRander();
     65 //            filterRander1();
     66 //            filterRander2();
     67 //            finallyRander();
     68         }
     69         
     70         private function initContext3D():void
     71         {
     72             _context3D = _stage3D.context3D;
     73             _context3D.configureBackBuffer(400, 400, 2);
     74         }
     75         
     76         private function initBuffer():void
     77         {
     78             var vertexData:Vector.<Number> = Vector.<Number>(
     79                     [
     80                         -0.5, -0.5, 0, 0, 1,
     81                         0.5,  -0.5, 0, 1, 1,
     82                         0.5,   0.5, 0, 1, 0,
     83                         -0.5,  0.5, 0, 0, 0
     84                     ]);
     85             
     86             _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
     87             _vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5);
     88             
     89             var indexData:Vector.<uint> = Vector.<uint>(
     90                     [
     91                         0, 3, 1,
     92                         1, 2, 3
     93                     ]);
     94             
     95             _indexBuffer = _context3D.createIndexBuffer(indexData.length);
     96             _indexBuffer.uploadFromVector(indexData, 0, indexData.length);
     97         }
     98         
     99         private function initTexture():void
    100         {
    101             var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
    102             _texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    103             _texture.uploadFromBitmapData(bitmap.bitmapData, 0);
    104         }
    105         
    106         /**
    107          * 正常渲染.
    108          */
    109         private function normalRander():void
    110         {
    111             var vertexArr:Array =
    112                     [
    113                         "mov op, va0",
    114                         "mov v0, va1"
    115                     ];
    116             
    117             var fragmentArr:Array =
    118                     [
    119                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
    120                         "mov oc, ft0"
    121                     ];
    122             
    123             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    124             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    125             
    126             _context3D.clear();
    127             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    128             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    129             _context3D.setTextureAt(0, _texture);
    130             _context3D.setProgram(_program3D);
    131             _context3D.drawTriangles(_indexBuffer);
    132             _context3D.present();
    133         }
    134         
    135         /**
    136          * 使用灰色滤镜渲染到纹理.
    137          */
    138         private function filterRander1():void
    139         {
    140             _filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    141             
    142             var vertexArr:Array =
    143                     [
    144                         "mov op, va0",
    145                         "mov v0, va1"
    146                     ];
    147             
    148             var fragmentArr:Array =
    149                     [
    150                         "tex ft0, v0, fs0 <2d,linear,clamp>",
    151                         "add ft1.x, ft0.x, ft0.y",
    152                         "add ft1.x, ft1.x, ft0.z",
    153                         "div ft1.x, ft1.x, fc0.w",
    154                         "mov ft0.xyz, ft1.xxx",
    155                         "mov oc ft0"
    156                     ];
    157             
    158             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    159             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    160             
    161             //设定渲染目标为我们的纹理
    162             _context3D.setRenderToTexture(_filterTexture1);
    163             _context3D.clear();
    164             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    165             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    166             //传递到灰色滤镜的设定值
    167             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
    168             _context3D.setTextureAt(0, _texture);
    169             _context3D.setProgram(_program3D);
    170             _context3D.drawTriangles(_indexBuffer);
    171         }
    172         
    173         /**
    174          * 使用波浪滤镜再一次渲染到纹理.
    175          */
    176         private function filterRander2():void
    177         {
    178             _filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    179             
    180             var vertexArr:Array =
    181                     [
    182                         "mov op, va0",
    183                         "mov v0, va1"
    184                     ];
    185             
    186             var fragmentArr:Array =
    187                     [
    188                         "tex ft0,v0,fs0<2d,clamp,linear>",
    189                         "sub ft0.x,v0.x,fc0.w",
    190                         "mul ft0.x,ft0.x,ft0.x",
    191                         "sub ft0.y,v0.y,fc0.w",
    192                         "mul ft0.y,ft0.y,ft0.y",
    193                         "add ft0.z,ft0.x,ft0.y",
    194                         "sqt ft0.z,ft0.z",
    195                         "mul ft0.z,ft0.z,fc0.x",
    196                         "sub ft0.z,ft0.z,fc0.z",
    197                         "sin ft0.z,ft0.z",
    198                         "mul ft0.z,ft0.z,fc0.y",
    199                         "add ft0,v0,ft0.zzz",
    200                         "tex oc,ft0,fs0<2d,clamp,linear>"
    201                     ];
    202             
    203             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    204             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    205             
    206             //设定渲染目标为我们的纹理
    207             _context3D.setRenderToTexture(_filterTexture2);
    208             _context3D.clear();
    209             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    210             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    211             //设置波浪的常量
    212             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
    213             _context3D.setTextureAt(0, _filterTexture1);
    214             _context3D.setProgram(_program3D);
    215             _context3D.drawTriangles(_indexBuffer);
    216             
    217             //还原后台缓冲区为渲染目标
    218             _context3D.setRenderToBackBuffer();
    219         }
    220         
    221         /**
    222          * 把最终的结果渲染到舞台.
    223          */
    224         private function finallyRander():void
    225         {
    226             var vertexArr:Array =
    227                     [
    228                         "mov op, va0",
    229                         "mov v0, va1"
    230                     ];
    231             
    232             var fragmentArr:Array =
    233                     [
    234                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
    235                         "mov oc, ft0"
    236                     ];
    237             
    238             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    239             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    240             
    241             _context3D.clear();
    242             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    243             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    244             _context3D.setTextureAt(0, _filterTexture2);
    245             _context3D.setProgram(_program3D);
    246             _context3D.drawTriangles(_indexBuffer);
    247             _context3D.present();
    248         }
    249     }
    250 }
    View Code

    下面是使用纹理渲染了2次滤镜的效果:

      1 package
      2 {
      3     import com.adobe.utils.AGALMiniAssembler;
      4     
      5     import flash.display.Bitmap;
      6     import flash.display.Sprite;
      7     import flash.display.Stage3D;
      8     import flash.display3D.Context3D;
      9     import flash.display3D.Context3DProfile;
     10     import flash.display3D.Context3DProgramType;
     11     import flash.display3D.Context3DRenderMode;
     12     import flash.display3D.Context3DTextureFormat;
     13     import flash.display3D.Context3DVertexBufferFormat;
     14     import flash.display3D.IndexBuffer3D;
     15     import flash.display3D.Program3D;
     16     import flash.display3D.VertexBuffer3D;
     17     import flash.display3D.textures.Texture;
     18     import flash.events.ErrorEvent;
     19     import flash.events.Event;
     20     
     21     [SWF(width=400, height=400, frameRate=60)]
     22     public class FilterDemo extends Sprite
     23     {
     24         [Embed(source="img.png")]
     25         private var IMG_CLASS:Class;
     26         
     27         private var _stage3D:Stage3D;
     28         private var _context3D:Context3D;
     29         private var _vertexBuffer:VertexBuffer3D;
     30         private var _indexBuffer:IndexBuffer3D;
     31         private var _texture:Texture;
     32         private var _program3D:Program3D;
     33         
     34         //会被作为目标渲染的纹理
     35         private var _filterTexture1:Texture;
     36         private var _filterTexture2:Texture;
     37         
     38         public function FilterDemo()
     39         {
     40             addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
     41         }
     42         
     43         private function addedToStageHandler(event:Event):void
     44         {
     45             if(stage.stage3Ds.length > 0)
     46             {
     47                 _stage3D = stage.stage3Ds[0];
     48                 _stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
     49                 _stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
     50                 _stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
     51             }
     52         }
     53         
     54         private function stage3DErrorHandler(event:ErrorEvent):void
     55         {
     56             trace("Context3D对象请求失败:", event.text);
     57         }
     58         
     59         private function context3DCreateHandler(event:Event):void
     60         {
     61             initContext3D();
     62             initBuffer();
     63             initTexture();
     64 //            normalRander();
     65             filterRander1();
     66             filterRander2();
     67             finallyRander();
     68         }
     69         
     70         private function initContext3D():void
     71         {
     72             _context3D = _stage3D.context3D;
     73             _context3D.configureBackBuffer(400, 400, 2);
     74         }
     75         
     76         private function initBuffer():void
     77         {
     78             var vertexData:Vector.<Number> = Vector.<Number>(
     79                     [
     80                         -0.5, -0.5, 0, 0, 1,
     81                         0.5,  -0.5, 0, 1, 1,
     82                         0.5,   0.5, 0, 1, 0,
     83                         -0.5,  0.5, 0, 0, 0
     84                     ]);
     85             
     86             _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
     87             _vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5);
     88             
     89             var indexData:Vector.<uint> = Vector.<uint>(
     90                     [
     91                         0, 3, 1,
     92                         1, 2, 3
     93                     ]);
     94             
     95             _indexBuffer = _context3D.createIndexBuffer(indexData.length);
     96             _indexBuffer.uploadFromVector(indexData, 0, indexData.length);
     97         }
     98         
     99         private function initTexture():void
    100         {
    101             var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
    102             _texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    103             _texture.uploadFromBitmapData(bitmap.bitmapData, 0);
    104         }
    105         
    106         /**
    107          * 正常渲染.
    108          */
    109         private function normalRander():void
    110         {
    111             var vertexArr:Array =
    112                     [
    113                         "mov op, va0",
    114                         "mov v0, va1"
    115                     ];
    116             
    117             var fragmentArr:Array =
    118                     [
    119                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
    120                         "mov oc, ft0"
    121                     ];
    122             
    123             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    124             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    125             
    126             _context3D.clear();
    127             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    128             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    129             _context3D.setTextureAt(0, _texture);
    130             _context3D.setProgram(_program3D);
    131             _context3D.drawTriangles(_indexBuffer);
    132             _context3D.present();
    133         }
    134         
    135         /**
    136          * 使用灰色滤镜渲染到纹理.
    137          */
    138         private function filterRander1():void
    139         {
    140             _filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    141             
    142             var vertexArr:Array =
    143                     [
    144                         "mov op, va0",
    145                         "mov v0, va1"
    146                     ];
    147             
    148             var fragmentArr:Array =
    149                     [
    150                         "tex ft0, v0, fs0 <2d,linear,clamp>",
    151                         "add ft1.x, ft0.x, ft0.y",
    152                         "add ft1.x, ft1.x, ft0.z",
    153                         "div ft1.x, ft1.x, fc0.w",
    154                         "mov ft0.xyz, ft1.xxx",
    155                         "mov oc ft0"
    156                     ];
    157             
    158             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    159             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    160             
    161             //设定渲染目标为我们的纹理
    162             _context3D.setRenderToTexture(_filterTexture1);
    163             _context3D.clear();
    164             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    165             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    166             //传递到灰色滤镜的设定值
    167             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
    168             _context3D.setTextureAt(0, _texture);
    169             _context3D.setProgram(_program3D);
    170             _context3D.drawTriangles(_indexBuffer);
    171         }
    172         
    173         /**
    174          * 使用波浪滤镜再一次渲染到纹理.
    175          */
    176         private function filterRander2():void
    177         {
    178             _filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    179             
    180             var vertexArr:Array =
    181                     [
    182                         "mov op, va0",
    183                         "mov v0, va1"
    184                     ];
    185             
    186             var fragmentArr:Array =
    187                     [
    188                         "tex ft0,v0,fs0<2d,clamp,linear>",
    189                         "sub ft0.x,v0.x,fc0.w",
    190                         "mul ft0.x,ft0.x,ft0.x",
    191                         "sub ft0.y,v0.y,fc0.w",
    192                         "mul ft0.y,ft0.y,ft0.y",
    193                         "add ft0.z,ft0.x,ft0.y",
    194                         "sqt ft0.z,ft0.z",
    195                         "mul ft0.z,ft0.z,fc0.x",
    196                         "sub ft0.z,ft0.z,fc0.z",
    197                         "sin ft0.z,ft0.z",
    198                         "mul ft0.z,ft0.z,fc0.y",
    199                         "add ft0,v0,ft0.zzz",
    200                         "tex oc,ft0,fs0<2d,clamp,linear>"
    201                     ];
    202             
    203             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    204             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    205             
    206             //设定渲染目标为我们的纹理
    207             _context3D.setRenderToTexture(_filterTexture2);
    208             _context3D.clear();
    209             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    210             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    211             //设置波浪的常量
    212             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
    213             _context3D.setTextureAt(0, _filterTexture1);
    214             _context3D.setProgram(_program3D);
    215             _context3D.drawTriangles(_indexBuffer);
    216             
    217             //还原后台缓冲区为渲染目标
    218             _context3D.setRenderToBackBuffer();
    219         }
    220         
    221         /**
    222          * 把最终的结果渲染到舞台.
    223          */
    224         private function finallyRander():void
    225         {
    226             var vertexArr:Array =
    227                     [
    228                         "mov op, va0",
    229                         "mov v0, va1"
    230                     ];
    231             
    232             var fragmentArr:Array =
    233                     [
    234                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
    235                         "mov oc, ft0"
    236                     ];
    237             
    238             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    239             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    240             
    241             _context3D.clear();
    242             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    243             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    244             _context3D.setTextureAt(0, _filterTexture2);
    245             _context3D.setProgram(_program3D);
    246             _context3D.drawTriangles(_indexBuffer);
    247             _context3D.present();
    248         }
    249     }
    250 }
    View Code

    我们发现最终的效果里我们的图像变小了很多,这是为啥呢?原因就是我们每次渲染时上传的顶点坐标是:

    1 var vertexData:Vector.<Number> = Vector.<Number>(
    2         [
    3             -0.5, -0.5, 0, 0, 1,
    4             0.5,  -0.5, 0, 1, 1,
    5             0.5,   0.5, 0, 1, 0,
    6             -0.5,  0.5, 0, 0, 0
    7         ]);

    这样的结果是每次绘制图像都是占屏幕的一半,而我们经过3次渲染所以图像就变成了很小,要让图像不变的话,只有把顶点数据的0.5都改为1即可。

    最终效果:

      1 package
      2 {
      3     import com.adobe.utils.AGALMiniAssembler;
      4     
      5     import flash.display.Bitmap;
      6     import flash.display.Sprite;
      7     import flash.display.Stage3D;
      8     import flash.display3D.Context3D;
      9     import flash.display3D.Context3DProfile;
     10     import flash.display3D.Context3DProgramType;
     11     import flash.display3D.Context3DRenderMode;
     12     import flash.display3D.Context3DTextureFormat;
     13     import flash.display3D.Context3DVertexBufferFormat;
     14     import flash.display3D.IndexBuffer3D;
     15     import flash.display3D.Program3D;
     16     import flash.display3D.VertexBuffer3D;
     17     import flash.display3D.textures.Texture;
     18     import flash.events.ErrorEvent;
     19     import flash.events.Event;
     20     
     21     [SWF(width=400, height=400, frameRate=60)]
     22     public class FilterDemo extends Sprite
     23     {
     24         [Embed(source="img.png")]
     25         private var IMG_CLASS:Class;
     26         
     27         private var _stage3D:Stage3D;
     28         private var _context3D:Context3D;
     29         private var _vertexBuffer:VertexBuffer3D;
     30         private var _indexBuffer:IndexBuffer3D;
     31         private var _texture:Texture;
     32         private var _program3D:Program3D;
     33         
     34         //会被作为目标渲染的纹理
     35         private var _filterTexture1:Texture;
     36         private var _filterTexture2:Texture;
     37         
     38         public function FilterDemo()
     39         {
     40             addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
     41         }
     42         
     43         private function addedToStageHandler(event:Event):void
     44         {
     45             if(stage.stage3Ds.length > 0)
     46             {
     47                 _stage3D = stage.stage3Ds[0];
     48                 _stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
     49                 _stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
     50                 _stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
     51             }
     52         }
     53         
     54         private function stage3DErrorHandler(event:ErrorEvent):void
     55         {
     56             trace("Context3D对象请求失败:", event.text);
     57         }
     58         
     59         private function context3DCreateHandler(event:Event):void
     60         {
     61             initContext3D();
     62             initBuffer();
     63             initTexture();
     64 //            normalRander();
     65             filterRander1();
     66             filterRander2();
     67             finallyRander();
     68         }
     69         
     70         private function initContext3D():void
     71         {
     72             _context3D = _stage3D.context3D;
     73             _context3D.configureBackBuffer(400, 400, 2);
     74         }
     75         
     76         private function initBuffer():void
     77         {
     78             var vertexData:Vector.<Number> = Vector.<Number>(
     79                     [
     80                         -1, -1, 0, 0, 1,
     81                         1,  -1, 0, 1, 1,
     82                         1,   1, 0, 1, 0,
     83                         -1,  1, 0, 0, 0
     84                     ]);
     85             
     86             _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
     87             _vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5);
     88             
     89             var indexData:Vector.<uint> = Vector.<uint>(
     90                     [
     91                         0, 3, 1,
     92                         1, 2, 3
     93                     ]);
     94             
     95             _indexBuffer = _context3D.createIndexBuffer(indexData.length);
     96             _indexBuffer.uploadFromVector(indexData, 0, indexData.length);
     97         }
     98         
     99         private function initTexture():void
    100         {
    101             var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
    102             _texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    103             _texture.uploadFromBitmapData(bitmap.bitmapData, 0);
    104         }
    105         
    106         /**
    107          * 正常渲染.
    108          */
    109         private function normalRander():void
    110         {
    111             var vertexArr:Array =
    112                     [
    113                         "mov op, va0",
    114                         "mov v0, va1"
    115                     ];
    116             
    117             var fragmentArr:Array =
    118                     [
    119                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
    120                         "mov oc, ft0"
    121                     ];
    122             
    123             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    124             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    125             
    126             _context3D.clear();
    127             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    128             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    129             _context3D.setTextureAt(0, _texture);
    130             _context3D.setProgram(_program3D);
    131             _context3D.drawTriangles(_indexBuffer);
    132             _context3D.present();
    133         }
    134         
    135         /**
    136          * 使用灰色滤镜渲染到纹理.
    137          */
    138         private function filterRander1():void
    139         {
    140             _filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    141             
    142             var vertexArr:Array =
    143                     [
    144                         "mov op, va0",
    145                         "mov v0, va1"
    146                     ];
    147             
    148             var fragmentArr:Array =
    149                     [
    150                         "tex ft0, v0, fs0 <2d,linear,clamp>",
    151                         "add ft1.x, ft0.x, ft0.y",
    152                         "add ft1.x, ft1.x, ft0.z",
    153                         "div ft1.x, ft1.x, fc0.w",
    154                         "mov ft0.xyz, ft1.xxx",
    155                         "mov oc ft0"
    156                     ];
    157             
    158             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    159             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    160             
    161             //设定渲染目标为我们的纹理
    162             _context3D.setRenderToTexture(_filterTexture1);
    163             _context3D.clear();
    164             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    165             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    166             //传递到灰色滤镜的设定值
    167             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
    168             _context3D.setTextureAt(0, _texture);
    169             _context3D.setProgram(_program3D);
    170             _context3D.drawTriangles(_indexBuffer);
    171         }
    172         
    173         /**
    174          * 使用波浪滤镜再一次渲染到纹理.
    175          */
    176         private function filterRander2():void
    177         {
    178             _filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
    179             
    180             var vertexArr:Array =
    181                     [
    182                         "mov op, va0",
    183                         "mov v0, va1"
    184                     ];
    185             
    186             var fragmentArr:Array =
    187                     [
    188                         "tex ft0,v0,fs0<2d,clamp,linear>",
    189                         "sub ft0.x,v0.x,fc0.w",
    190                         "mul ft0.x,ft0.x,ft0.x",
    191                         "sub ft0.y,v0.y,fc0.w",
    192                         "mul ft0.y,ft0.y,ft0.y",
    193                         "add ft0.z,ft0.x,ft0.y",
    194                         "sqt ft0.z,ft0.z",
    195                         "mul ft0.z,ft0.z,fc0.x",
    196                         "sub ft0.z,ft0.z,fc0.z",
    197                         "sin ft0.z,ft0.z",
    198                         "mul ft0.z,ft0.z,fc0.y",
    199                         "add ft0,v0,ft0.zzz",
    200                         "tex oc,ft0,fs0<2d,clamp,linear>"
    201                     ];
    202             
    203             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    204             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    205             
    206             //设定渲染目标为我们的纹理
    207             _context3D.setRenderToTexture(_filterTexture2);
    208             _context3D.clear();
    209             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    210             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    211             //设置波浪的常量
    212             _context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
    213             _context3D.setTextureAt(0, _filterTexture1);
    214             _context3D.setProgram(_program3D);
    215             _context3D.drawTriangles(_indexBuffer);
    216             
    217             //还原后台缓冲区为渲染目标
    218             _context3D.setRenderToBackBuffer();
    219         }
    220         
    221         /**
    222          * 把最终的结果渲染到舞台.
    223          */
    224         private function finallyRander():void
    225         {
    226             var vertexArr:Array =
    227                     [
    228                         "mov op, va0",
    229                         "mov v0, va1"
    230                     ];
    231             
    232             var fragmentArr:Array =
    233                     [
    234                         "tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
    235                         "mov oc, ft0"
    236                     ];
    237             
    238             var assembler:AGALMiniAssembler = new AGALMiniAssembler();
    239             _program3D = assembler.assemble2(_context3D, 1, vertexArr.join("
    "), fragmentArr.join("
    "));
    240             
    241             _context3D.clear();
    242             _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
    243             _context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
    244             _context3D.setTextureAt(0, _filterTexture2);
    245             _context3D.setProgram(_program3D);
    246             _context3D.drawTriangles(_indexBuffer);
    247             _context3D.present();
    248         }
    249     }
    250 }
    View Code
  • 相关阅读:
    IDEA生成可执行的jar文件
    Android ROM包定制(解包,增删模块,打包)
    frida的用法--Hook Java代码篇
    C语言sprintf和sscanf函数用法
    C语言memcpy函数的用法
    自己动手编译Android(LineageOS)源码
    j2ee高级开发技术课程第三周
    linux内核学习之全局描述符表(GDT)(二)
    螺旋队列顺时针方向 和逆时针方向的实现
    zigzag数组:输入n,求一个nXn矩阵,规定矩阵沿45度递增,形成一个zigzag数组
  • 原文地址:https://www.cnblogs.com/hammerc/p/4126986.html
Copyright © 2011-2022 走看看