本章用来作为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. eclipse中的输入提示怎么设置

    对于大多数的开发人员来说,打代码是一件非常繁琐的事情,eclipse中为我们提供了自动提示的功能,但是默认的提示只有当我们输入小数点后才能出现提示框,那么我们如何设置eclipse,能够让它为我们提示 ...

  2. RedMine项目管理系统邮件推送设置(Windows环境)

    RedMine项目管理系统有邮箱推送功能,当Bug,安全漏洞等内容被修改.解决.评论的时候,系统会通过邮件 及时的通知你的团队和客户.邮件通知的环节.形式.时间.接受人均可定制,功能十分实用. 下面是 ...

  3. 如何在VS2010中使用Async功能?

    伴随C#5.0的发布,“异步”特性越来越深入人心:在VS2012中早就可以使用它大大简化异步编程的痛苦,那么在VS2010中呢?我们无法尝鲜么?答案是“No”!,其实我们可以这样做: 1)必须把你的V ...

  4. R12 - OM改进了对成本与收入确认的流程

    我们知道在企业经营活动中,根据财务制度的要求,对于收入与成本确认有很复杂的原则,这里就不去细讨论这些原则了,要了解的话可以看纵横四海的BLOG: 中也有,但11中是灰的. 这个科目什么时候发挥作用呢? ...

  5. Android 之 内存管理-查看内存泄露(三)

    概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在 ...

  6. 基于邻接矩阵的深度优先搜索(DFS)

    题目:http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2107&cid=1186 #include<stdio.h> #incl ...

  7. HNOI2004打鼹鼠(LIS)

    大水题…… 不过通过这题我们应该养成一个好习惯:好好看清题…… 竟然没有看到时限 10sec…… var i,j,n,m,ans:longint; f,time,x,y:..] of longint; ...

  8. Can not perform pod install under el capitan (15A279b)

    这个问题在stackoverflow上面有过讨论: Can not perform pod install under el capitan (15A279b) 被采纳的答案为:sudo gem in ...

  9. mysql CMAKE 参数说明

    MySQL自5.5版本以后,就开始使用CMake编译工具了,因此,你在安装源文件中找不到configure文件是正常的.很多人下到了新版的MySQL,因为找不到configure文件,不知道该怎么继续 ...

  10. FirstOrDefault

    FirstOrDefault:取序列中满足条件的第一个元素,如果没有元素满足条件,则返回默认值(对于可以为null的对象,默认值为null,对于不能为null的对象,如int,默认值为0)