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

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

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

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

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

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

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

先看看正常渲染的情况:

 package
{
import com.adobe.utils.AGALMiniAssembler; import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.events.ErrorEvent;
import flash.events.Event; [SWF(width=400, height=400, frameRate=60)]
public class FilterDemo extends Sprite
{
[Embed(source="img.png")]
private var IMG_CLASS:Class; private var _stage3D:Stage3D;
private var _context3D:Context3D;
private var _vertexBuffer:VertexBuffer3D;
private var _indexBuffer:IndexBuffer3D;
private var _texture:Texture;
private var _program3D:Program3D; //会被作为目标渲染的纹理
private var _filterTexture1:Texture;
private var _filterTexture2:Texture; public function FilterDemo()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
} private function addedToStageHandler(event:Event):void
{
if(stage.stage3Ds.length > 0)
{
_stage3D = stage.stage3Ds[0];
_stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
_stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
_stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
} private function stage3DErrorHandler(event:ErrorEvent):void
{
trace("Context3D对象请求失败:", event.text);
} private function context3DCreateHandler(event:Event):void
{
initContext3D();
initBuffer();
initTexture();
normalRander();
// filterRander1();
// filterRander2();
// finallyRander();
} private function initContext3D():void
{
_context3D = _stage3D.context3D;
_context3D.configureBackBuffer(400, 400, 2);
} private function initBuffer():void
{
var vertexData:Vector.<Number> = Vector.<Number>(
[
-0.5, -0.5, 0, 0, 1,
0.5, -0.5, 0, 1, 1,
0.5, 0.5, 0, 1, 0,
-0.5, 0.5, 0, 0, 0
]); _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
_vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); var indexData:Vector.<uint> = Vector.<uint>(
[
0, 3, 1,
1, 2, 3
]); _indexBuffer = _context3D.createIndexBuffer(indexData.length);
_indexBuffer.uploadFromVector(indexData, 0, indexData.length);
} private function initTexture():void
{
var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
_texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
_texture.uploadFromBitmapData(bitmap.bitmapData, 0);
} /**
* 正常渲染.
*/
private function normalRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
} /**
* 使用灰色滤镜渲染到纹理.
*/
private function filterRander1():void
{
_filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,linear,clamp>",
"add ft1.x, ft0.x, ft0.y",
"add ft1.x, ft1.x, ft0.z",
"div ft1.x, ft1.x, fc0.w",
"mov ft0.xyz, ft1.xxx",
"mov oc ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture1);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//传递到灰色滤镜的设定值
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
} /**
* 使用波浪滤镜再一次渲染到纹理.
*/
private function filterRander2():void
{
_filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0,v0,fs0<2d,clamp,linear>",
"sub ft0.x,v0.x,fc0.w",
"mul ft0.x,ft0.x,ft0.x",
"sub ft0.y,v0.y,fc0.w",
"mul ft0.y,ft0.y,ft0.y",
"add ft0.z,ft0.x,ft0.y",
"sqt ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.x",
"sub ft0.z,ft0.z,fc0.z",
"sin ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.y",
"add ft0,v0,ft0.zzz",
"tex oc,ft0,fs0<2d,clamp,linear>"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture2);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//设置波浪的常量
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
_context3D.setTextureAt(0, _filterTexture1);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer); //还原后台缓冲区为渲染目标
_context3D.setRenderToBackBuffer();
} /**
* 把最终的结果渲染到舞台.
*/
private function finallyRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _filterTexture2);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
}
}
}

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

 package
{
import com.adobe.utils.AGALMiniAssembler; import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.events.ErrorEvent;
import flash.events.Event; [SWF(width=400, height=400, frameRate=60)]
public class FilterDemo extends Sprite
{
[Embed(source="img.png")]
private var IMG_CLASS:Class; private var _stage3D:Stage3D;
private var _context3D:Context3D;
private var _vertexBuffer:VertexBuffer3D;
private var _indexBuffer:IndexBuffer3D;
private var _texture:Texture;
private var _program3D:Program3D; //会被作为目标渲染的纹理
private var _filterTexture1:Texture;
private var _filterTexture2:Texture; public function FilterDemo()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
} private function addedToStageHandler(event:Event):void
{
if(stage.stage3Ds.length > 0)
{
_stage3D = stage.stage3Ds[0];
_stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
_stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
_stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
} private function stage3DErrorHandler(event:ErrorEvent):void
{
trace("Context3D对象请求失败:", event.text);
} private function context3DCreateHandler(event:Event):void
{
initContext3D();
initBuffer();
initTexture();
// normalRander();
filterRander1();
filterRander2();
finallyRander();
} private function initContext3D():void
{
_context3D = _stage3D.context3D;
_context3D.configureBackBuffer(400, 400, 2);
} private function initBuffer():void
{
var vertexData:Vector.<Number> = Vector.<Number>(
[
-0.5, -0.5, 0, 0, 1,
0.5, -0.5, 0, 1, 1,
0.5, 0.5, 0, 1, 0,
-0.5, 0.5, 0, 0, 0
]); _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
_vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); var indexData:Vector.<uint> = Vector.<uint>(
[
0, 3, 1,
1, 2, 3
]); _indexBuffer = _context3D.createIndexBuffer(indexData.length);
_indexBuffer.uploadFromVector(indexData, 0, indexData.length);
} private function initTexture():void
{
var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
_texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
_texture.uploadFromBitmapData(bitmap.bitmapData, 0);
} /**
* 正常渲染.
*/
private function normalRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
} /**
* 使用灰色滤镜渲染到纹理.
*/
private function filterRander1():void
{
_filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,linear,clamp>",
"add ft1.x, ft0.x, ft0.y",
"add ft1.x, ft1.x, ft0.z",
"div ft1.x, ft1.x, fc0.w",
"mov ft0.xyz, ft1.xxx",
"mov oc ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture1);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//传递到灰色滤镜的设定值
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
} /**
* 使用波浪滤镜再一次渲染到纹理.
*/
private function filterRander2():void
{
_filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0,v0,fs0<2d,clamp,linear>",
"sub ft0.x,v0.x,fc0.w",
"mul ft0.x,ft0.x,ft0.x",
"sub ft0.y,v0.y,fc0.w",
"mul ft0.y,ft0.y,ft0.y",
"add ft0.z,ft0.x,ft0.y",
"sqt ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.x",
"sub ft0.z,ft0.z,fc0.z",
"sin ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.y",
"add ft0,v0,ft0.zzz",
"tex oc,ft0,fs0<2d,clamp,linear>"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture2);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//设置波浪的常量
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
_context3D.setTextureAt(0, _filterTexture1);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer); //还原后台缓冲区为渲染目标
_context3D.setRenderToBackBuffer();
} /**
* 把最终的结果渲染到舞台.
*/
private function finallyRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _filterTexture2);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
}
}
}

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

 var vertexData:Vector.<Number> = Vector.<Number>(
[
-0.5, -0.5, 0, 0, 1,
0.5, -0.5, 0, 1, 1,
0.5, 0.5, 0, 1, 0,
-0.5, 0.5, 0, 0, 0
]);

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

最终效果:

 package
{
import com.adobe.utils.AGALMiniAssembler; import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.events.ErrorEvent;
import flash.events.Event; [SWF(width=400, height=400, frameRate=60)]
public class FilterDemo extends Sprite
{
[Embed(source="img.png")]
private var IMG_CLASS:Class; private var _stage3D:Stage3D;
private var _context3D:Context3D;
private var _vertexBuffer:VertexBuffer3D;
private var _indexBuffer:IndexBuffer3D;
private var _texture:Texture;
private var _program3D:Program3D; //会被作为目标渲染的纹理
private var _filterTexture1:Texture;
private var _filterTexture2:Texture; public function FilterDemo()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
} private function addedToStageHandler(event:Event):void
{
if(stage.stage3Ds.length > 0)
{
_stage3D = stage.stage3Ds[0];
_stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
_stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
_stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
} private function stage3DErrorHandler(event:ErrorEvent):void
{
trace("Context3D对象请求失败:", event.text);
} private function context3DCreateHandler(event:Event):void
{
initContext3D();
initBuffer();
initTexture();
// normalRander();
filterRander1();
filterRander2();
finallyRander();
} private function initContext3D():void
{
_context3D = _stage3D.context3D;
_context3D.configureBackBuffer(400, 400, 2);
} private function initBuffer():void
{
var vertexData:Vector.<Number> = Vector.<Number>(
[
-1, -1, 0, 0, 1,
1, -1, 0, 1, 1,
1, 1, 0, 1, 0,
-1, 1, 0, 0, 0
]); _vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 5, 5);
_vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 5); var indexData:Vector.<uint> = Vector.<uint>(
[
0, 3, 1,
1, 2, 3
]); _indexBuffer = _context3D.createIndexBuffer(indexData.length);
_indexBuffer.uploadFromVector(indexData, 0, indexData.length);
} private function initTexture():void
{
var bitmap:Bitmap = new IMG_CLASS() as Bitmap;
_texture = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true);
_texture.uploadFromBitmapData(bitmap.bitmapData, 0);
} /**
* 正常渲染.
*/
private function normalRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
} /**
* 使用灰色滤镜渲染到纹理.
*/
private function filterRander1():void
{
_filterTexture1 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,linear,clamp>",
"add ft1.x, ft0.x, ft0.y",
"add ft1.x, ft1.x, ft0.z",
"div ft1.x, ft1.x, fc0.w",
"mov ft0.xyz, ft1.xxx",
"mov oc ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture1);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//传递到灰色滤镜的设定值
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0.299, 0.587, 0.114, 3]));
_context3D.setTextureAt(0, _texture);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
} /**
* 使用波浪滤镜再一次渲染到纹理.
*/
private function filterRander2():void
{
_filterTexture2 = _context3D.createTexture(128, 128, Context3DTextureFormat.BGRA, true); var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0,v0,fs0<2d,clamp,linear>",
"sub ft0.x,v0.x,fc0.w",
"mul ft0.x,ft0.x,ft0.x",
"sub ft0.y,v0.y,fc0.w",
"mul ft0.y,ft0.y,ft0.y",
"add ft0.z,ft0.x,ft0.y",
"sqt ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.x",
"sub ft0.z,ft0.z,fc0.z",
"sin ft0.z,ft0.z",
"mul ft0.z,ft0.z,fc0.y",
"add ft0,v0,ft0.zzz",
"tex oc,ft0,fs0<2d,clamp,linear>"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); //设定渲染目标为我们的纹理
_context3D.setRenderToTexture(_filterTexture2);
_context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
//设置波浪的常量
_context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[100, 0.01, 0, 0.5]);
_context3D.setTextureAt(0, _filterTexture1);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer); //还原后台缓冲区为渲染目标
_context3D.setRenderToBackBuffer();
} /**
* 把最终的结果渲染到舞台.
*/
private function finallyRander():void
{
var vertexArr:Array =
[
"mov op, va0",
"mov v0, va1"
]; var fragmentArr:Array =
[
"tex ft0, v0, fs0 <2d,repeat,linear,nomip>",
"mov oc, ft0"
]; var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n")); _context3D.clear();
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
_context3D.setTextureAt(0, _filterTexture2);
_context3D.setProgram(_program3D);
_context3D.drawTriangles(_indexBuffer);
_context3D.present();
}
}
}

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

  1. Stage3D学习笔记(五):通过矩阵操作纹理

    虽然我们上一节已经实现了正交矩阵的显示,但是可以明显的感觉到要调整显示纹理的坐标和尺寸是相当复杂的,需要对每个顶点进行操作,如果还要加上注册点和旋转的话,用上一节的方法来做是会让人发疯的! 所以我们距 ...

  2. 【Stage3D学习笔记续】山寨Starling(八):核心优化(批处理)的实现

    批处理是使GPU进行高效绘制的一种技术手段,也是整个渲染流程中最核心的技术,到目前为止我们并没有使用到这种技术手段,下面我们看看我们现在的渲染机制. 先想一想我们最开始是怎么向GPU绘制一幅图像的,可 ...

  3. 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  4. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  5. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

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

    原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  8. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. python3.4学习笔记(七) 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

  10. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

随机推荐

  1. MySQL 5.6 安装配置

    mysql 5.6.17下载安装图解_百度经验 http://jingyan.baidu.com/article/4b07be3c67853c48b380f311.html windows 8 系统将 ...

  2. C#获取cpu序列号 硬盘ID 网卡硬地址以及操作注册表 .

    转:http://blog.csdn.net/smartsmile2012/article/details/8682295 #region 获取cpu序列号 硬盘ID 网卡硬地址 /**/ /// & ...

  3. Java API ——Object类

    1.Object类概述 1)类层次结构的根类.       2)所有类都直接或者间接的继承自该类. 3)构造方法            · public Object()            · 子 ...

  4. WCF 传输的序列化

    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService”.[ServiceContract]public interface IService{ [O ...

  5. poj2月题解

    竟然生日前一天poj破百,不错不错,加速前进! poj2437 由于泥泞不重叠,所以按其实左边排个序再统计一遍即可(如果不是刚好盖满就尽量往后盖) poj2435 细节bfs poj2230 求欧拉回 ...

  6. iScroll-5拉动刷新功能实现与iScroll-4上拉刷新的一点改进

    近来在学习移动设备的应用开发,接触了jQuery mobile,在网上查阅相关资料时发现一个叫”iScroll“的小插件.其实这个iScroll插件跟jQuery mobile没有多大关系,并不是基于 ...

  7. [.NET MVC进阶系列03] Views 视图基础

    [注:此文对应Chapter 3:Views] 一.View的功能: 1.View用来呈现页面UI,通过Controller来指定View: 要注意的是,MVC和以前基于文件的Web应用不同,URL指 ...

  8. PhpStorm快捷键设置/个性化设置,

    #常用快捷键 设置快捷键:File -> Settings -> IDE Settings -> Keymap -> 选择“Eclipse” -> 然后“Copy”一份 ...

  9. linux测试题

    http://www.2cto.com/os/201307/225399.html  2013最新linux运维面试题 在对linux基本知识的归纳总结之后,这里是一份linux的测试题.希望能帮助大 ...

  10. servlet规范

    Servlet规范 一个最基本的 Java Web 项目所需的 jar 包只需要一个 servlet-api.jar ,这个 jar 包中的类大部分都是接口,还有一些工具类,共有 2 个包,分别是 j ...