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("\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 }

下面是使用纹理渲染了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 }

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

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 }

时间: 2024-10-16 02:59:46

Stage3D学习笔记(七):动态纹理的相关文章

CCNA学习笔记七——路由概述

静态路由协议: 动态路由协议:AS(自治系统):执行统一路由策略的一组设备的集合 EGP(外部网关协议): BGP:边界网关协议 IGP(内部网关协议): 距离矢量协议: RIP:V1,V2 IGRP EIGRP 链路状态路由协议: OSPF IS-IS 静态路由: 特点: 路由表是手工设置的 除非网络管理员干预,否则静态路由不会发生变化 路由表的形成不需要占用网络资源 适合环境 一般用于网络规模很小,拓扑结构固定的网络中 默认路由: 特点: 在所有路由类型中,默认路由优先级最低 适用环境: 一

第十七篇:博采众长--初探WDDM驱动学习笔记(七)

基于WDDM驱动的DirectX视频加速重定向框架设计与实现 现在的研究生的论文, 真正质量高的, 少之又少, 开题开得特别大, 动不动就要搞个大课题, 从绪论开始到真正自己所做的内容之间, 是东拼西凑地抄概念, 抄公式, 达到字数篇幅的要求, 而自己正真做了什么, 有哪些实际感受, 做出的内容, 相比前面的东拼西凑就几点内容, 之后就草草结束, 步入感谢的段落. 原因不光只有学生自己, 所谓的读研, 如果没有一个环境, 学生有再大的愿望, 再强的毅力, 到头来也只是空无奈. 有些导师要写书,

马哥学习笔记七——LAMP编译安装之MYSQL

1.准备数据存放的文件系统 新建一个逻辑卷,并将其挂载至特定目录即可.这里不再给出过程. 这里假设其逻辑卷的挂载目录为/mydata,而后需要创建/mydata/data目录做为mysql数据的存放目录. 2.新建用户以安全方式运行进程: # groupadd -r mysql # useradd -g mysql -r -s /sbin/nologin -M -d /mydata/data mysql # chown -R mysql:mysql /mydata/data 3.安装并初始化my

Lua学习笔记(七):迭代器与泛型for

1.迭代器与闭包 迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素.在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素. 迭代器需要保留上一次成功调用的状态和下一次成功调用的状态,也就是他知道来自于哪里和将要前往哪里.闭包提供的机制可以很容易实现这个任务.记住:闭包是一个内部函数,它可以访问一个或者多个外部函数的外部局部变量.每次闭包的成功调用后这些外部局部变量都保存他们的值(状态).当然如果要创建一个闭包必须要创建其外部局部变量.所以一个典型的闭包的结构包含

python学习笔记七:条件&循环语句

1.print/import更多信息 print打印多个表达式,使用逗号隔开 >>> print 'Age:',42 Age: 42   #注意个结果之间有一个空格符 import:从模块导入函数 import 模块 from 模块 import 函数 from 模块 import * 如果两个模块都有open函数的时候, 1)使用下面方法使用: module1.open()... module2.open()... 2)语句末尾增加as子句 >>> import ma

swift学习笔记(七)自动引用计数

与Object-c一样,swift使用自动引用计数来跟踪并管理应用使用的内存.当实例不再被使用时,及retainCount=0时,会自动释放是理所占用的内存空间. 注:引用计数仅适用于类的实例,因为struct和enumeration属于值类型,也就不牵涉引用,所以其存储和管理方式并不是引用计数. 当一个实例被初始化时,系统会自动分配一定的内存空间,用于管理属性和方法.当实例对象不再被使用时,其内存空间被收回. swift中的引用类型分为三种,即Strong强引用,weak弱引用和无主引用unw

Web Service学习笔记:动态调用WebService

原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我们可能需要在程序运行期间动态调用一个未知的服务.在 .NET Framework 的 System.Web.Services.Description 命名空间中有我们需要的东西. 具体步骤: 1. 从目标 URL 下载 WSDL 数据. 2. 使用 ServiceDescription 创建和格式化 WSDL

Swift学习笔记七:闭包

闭包可以 捕获 和存储其所在上下文中任意常量和变量的引用. Swift 会为您管理在 捕获 过程中涉及到的内存操作. 在 函数 章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一: 1. 全局函数是一个有名字但不会捕获任何值的闭包 2. 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包 3. 闭包表达式是一个可以捕获其上下文中变量或常量值的没有名字的闭包 一.闭包表达式 闭包函数类似于Objective-C中的block.下面我们用事实说话: let counts =

Linux System Programming 学习笔记(七) 线程

1. Threading is the creation and management of multiple units of execution within a single process 二进制文件是驻留在存储介质上,已被编译成操作系统可以使用,准备执行但没有正运行的休眠程序 进程是操作系统对 正在执行中的二进制文件的抽象:已加载的二进制.虚拟内存.内核资源 线程是进程内的执行单元 processes are running binaries, threads are the smal