Stage3D学习笔记(七):动态纹理
本章用来作为Starling的滤镜实现原理的一个补充,但是为了了解原理,我们会使用原生API进行编码。
我们知道,当我们调用drawTriangles方法时,我们的图像是绘制到后台缓冲区的,只有调用present方法时才会把图像呈现到屏幕。
我们先来看看Context3D的两个方法:
- setRenderToTexture:我们默认的渲染都是在后台缓冲区进行的,使用该方法可以把渲染修改到一个纹理上,调用该方法后,Context3D对象的渲染操作(clear、drawTriangles等)都会渲染到指定的纹理上而不是后台缓冲区。
- 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学习笔记(七):动态纹理的更多相关文章
- Stage3D学习笔记(五):通过矩阵操作纹理
虽然我们上一节已经实现了正交矩阵的显示,但是可以明显的感觉到要调整显示纹理的坐标和尺寸是相当复杂的,需要对每个顶点进行操作,如果还要加上注册点和旋转的话,用上一节的方法来做是会让人发疯的! 所以我们距 ...
- 【Stage3D学习笔记续】山寨Starling(八):核心优化(批处理)的实现
批处理是使GPU进行高效绘制的一种技术手段,也是整个渲染流程中最核心的技术,到目前为止我们并没有使用到这种技术手段,下面我们看看我们现在的渲染机制. 先想一想我们最开始是怎么向GPU绘制一幅图像的,可 ...
- 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整
今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...
- go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)
目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...
- (转)Qt Model/View 学习笔记 (七)——Delegate类
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
- Web Service学习笔记:动态调用WebService
原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- Typescript 学习笔记七:泛型
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- python3.4学习笔记(七) 学习网站博客推荐
python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...
- Go语言学习笔记七: 函数
Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...
随机推荐
- Django admin site(一)ModelAdmin Options
Admin管理界面是django的杀手级应用.它读取你模式中的元数据,然后提供给你一个强大而且可以使用的界面,网站管理者可以用它立即向网站中添加内容. 要使用admin,可以按照下面的步骤: 将'dj ...
- laravel Authentication and Security
Creating the user modelFirst of all, we need to define the model that is going to be used to represe ...
- JNDI和在tomcat中配置DBCP连接池 元数据的使用 DBUtils框架的使用 多表操作
1 JNDI和在tomcat中配置DBCP连接池 JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.namin ...
- Zookeeper安装和配置
Zookeeper的安装和配置,可以配置成单机模式.伪集群模式.集群模式. 参考http://coolxing.iteye.com/blog/1871009 一. 单机模式 (1)zookeeper下 ...
- (转载)关于gcd的8题
发现其实有关gcd的题目还是挺多的,这里根据做题顺序写出8题. [bzoj2818: Gcd] gcd(x,y)=质数, 1<=x,y<=n的对数 做这题的时候,懂得了一个非常重要的转化: ...
- OK335xS tmp75 Qt 温度读取
/******************************************************************* * OK335xS tmp75 Qt 温度读取 * 说明: * ...
- UVA 11082 Matrix Decompressing 矩阵解压(最大流,经典)
题意: 知道矩阵的前i行之和,和前j列之和(任意i和j都可以).求这个矩阵.每个格子中的元素必须在1~20之间.矩阵大小上限20*20. 思路: 这么也想不到用网络流解决,这个模型很不错.假设这个矩阵 ...
- Jquery拖拽原理
/* onmousedown : 选择元素 onmousemove : 移动元素 onmouseup : 释放元素 */ 查看Demo:拖拽图片 function drag(obj) { obj.on ...
- 3.2版uploadify详细例子(含FF和IE SESSION问题)
最近做项目中碰到上传需要显示进度的问题,通过uploadfiy很好的解决了这个问题不过(IE9出现了按钮不能点击的问题,至今仍找不到良策) 在使用uploadfiy3.2版本时需要下载jquery.t ...
- InstallShield高级应用--检查是否安装ORACLE或SQL Server
InstallShield高级应用--检查是否安装ORACLE或SQL Server 实现原理:判断是否存在,是通过查找注册表是否含有相应标识来判断的. 注意:XP与WIN7系统注册表保存方式不一 ...