1

我正在尝试测试 Stage3D 的 setRenderToTexture 函数,但我的测试代码没有提供任何输出。我希望有人能告诉我为什么 - 我几乎已经尝试了一切来让它工作。我创建的代码如下:

import flash.events.Event;
import flash.display.*;
import flash.display3D.*;
import flash.display3D.textures.Texture;
import AGALMiniAssembler;

//using stage size in several locations for simplicity - needs to be square, 2^n
[SWF(width='512', height='512', backgroundColor='0x000000', frameRate='60')]

//vars
var context0:Context3D;
var vBuff:VertexBuffer3D;
var iBuff:IndexBuffer3D;
var tex0:Texture;
var tex1:Texture;
var vShader:AGALMiniAssembler = new AGALMiniAssembler();
var fShader:AGALMiniAssembler = new AGALMiniAssembler();
var program:Program3D;

//create a square
var square:Shape = new Shape();
square.graphics.beginFill(0xaa00ff,1);
square.graphics.drawRect(10, 10, stage.stageWidth - 20, stage.stageHeight - 20);

//draw square to bitmapdata and create one blank bitmapdata
var tex0data:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false,0);
tex0data.draw(square);
var tex1data:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false,0);

//initialize stage3d
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, initStage3D);
stage.stage3Ds[0].requestContext3D();

function initStage3D(e:Event):void {
    context0 = stage.stage3Ds[0].context3D;
    context0.configureBackBuffer(stage.stageWidth, stage.stageHeight, 0);

    //create buffers - simple quad
    var vBuff_vec:Vector.<Number> = new <Number>[-1, -1, 0, 0, 1,
                                                 -1, 1, 0, 0, 0,
                                                 1, 1, 0, 1, 0,
                                                 1, -1, 0, 1, 1];
    var iBuff_vec:Vector.<uint> = new <uint>[0, 1, 2, 0, 2, 3]
    vBuff = context0.createVertexBuffer(4, 5);
    vBuff.uploadFromVector(vBuff_vec, 0, 4);
    iBuff = context0.createIndexBuffer(6);
    iBuff.uploadFromVector(iBuff_vec, 0, 6);

    //load bitmapdata into textures - square to tex0 and blank to tex1
    tex0 = context0.createTexture(tex0data.width,tex0data.height,'bgra',false);
    tex0.uploadFromBitmapData(tex0data);    
    tex1 = context0.createTexture(tex1data.width, tex1data.height,'bgra',true);
    tex1.uploadFromBitmapData(tex1data);

    //create and upload simple shader program
    vShader.assemble('vertex', 'mov v0, va1 \n'+ //uv coords to v0
                                 'mov op, va0'); //output xyz coords
    fShader.assemble('fragment', 'tex oc, v0, fs0 <2d, linear, nomip>'); //output texture at fs0
    program = context0.createProgram();
    program.upload(vShader.agalcode, fShader.agalcode);
    context0.setProgram(program);

    //set buffers
    context0.setVertexBufferAt(0, vBuff, 0, 'float3');
    context0.setVertexBufferAt(1, vBuff, 3, 'float2');

    //prep rendering
    addEventListener(Event.ENTER_FRAME, render);
}

function render(e:Event):void {
    context0.clear();

    //render tex0 onto tex1
    context0.setRenderToTexture(tex1);
    context0.setTextureAt(0, tex0);
    context0.drawTriangles(iBuff);

    //render tex1 to back buffer and present
    context0.setTextureAt(0, tex1);
    context0.setRenderToBackBuffer();
    context0.drawTriangles(iBuff);
    context0.present();
}

编辑:我注意到更改空白位图的颜色确实会改变最终输出的颜色 - 它正在显示,但正方形并未呈现给它。

4

1 回答 1

1

终于想通了!在纹理可用作渲染目标之前,必须采取一个微妙但重要的步骤 - 必须在切换渲染目标后清除它。如下修改渲染函数会使程序按预期运行:

function render(e:Event):void {
    //render tex0 onto tex1
    context0.setRenderToTexture(tex1);
    context0.clear();
    context0.setTextureAt(0, tex0);
    context0.drawTriangles(iBuff);

    //render tex1 to back buffer and present
    context0.setTextureAt(0, tex1);
    context0.setRenderToBackBuffer();
    context0.clear();
    context0.drawTriangles(iBuff);
    context0.present();
}
于 2014-03-20T19:12:30.170 回答