代码改变世界

Stage3D学习笔记(七):动态纹理

2014-11-28 14:24  阿诚de窝  阅读(638)  评论(0编辑  收藏  举报

本章用来作为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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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("\n"), fragmentArr.join("\n"));
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