actionscript 3 - Render to texture not functioning


Question: 

I'm trying to test Stage3D's setRenderToTexture function, but my test code is not providing any output. I was hoping someone could tell me why - I've tried practically everything to get this working. The code I've created is below:

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();
}

EDIT: I have noticed that changing the color of the blank bitmap does change the color of the final output - it's being displayed, but the square isn't being rendered to it.




1 Answer: 

FINALLY figured this out! There is a subtle, but important, step that must be taken before a texture is viable as a render target - it must be cleared after the render target is switched. Revising the render function as follows causes the program to function as expected:

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();
}
 

More Articles


aborting Windows IME composition / clearing composition string

I'm having trouble aborting IME composition on Windows. I'm handling WM_IME_STARTCOMPOSITION and positioning my candidate window, and WM_IME_COMPOSITION as I press a key to start composing as you'd expect. I'm then handling WM_IME_ENDCOMPOSITION at the end and normal use cases are fine.However, my p

actionscript 3 - Image Effect with Dark Borders

I was creating an effects library for a PhotoBooth App. I have created effects like Black/White, Vintage, Sepia, Retro etc. etc.I wanted to create a few effects now in which I wanted to have a Dark Border at the edges which kind of form a frame for the image .. something like this -> Example EffectH

c++ - D3D12 unavoidable leak report

This program:#include <d3d12.h>#pragma comment(lib,"d3d12")int main(){ ID3D12Debug *pDebug = NULL; D3D12GetDebugInterface(__uuidof(ID3D12Debug),(void**)&pDebug); pDebug->EnableDebugLayer(); pDebug->Release(); ID3D12Device *pDev = NULL; D3D12CreateDevice(NULL,D3D_FEA


shader - HLSL Texture sample fine when directly returned, invalid if any operation is applied

I am new to shaders and HLSL, I hope I'm not doing anything seriously incorrect. I am trying to blend two textures in HLSL. I've got both of my textures and samplers set up:Texture2D<float4> First : register(t0);Texture2D<float4> Second : register(t1);uniform sampler FirstSampler : regis

c# - StackPanel in Grid: limit height

I have a big main grid with several rows and columns. I want to place in one of these cells a vertical stackpanel. In this stackpanel there is a textblock and a scrollviewer. My problem is, that the stackpanel doesn't get limited by the cell, instead the stackpanel gets big enough to fit the whole s

c# - How to dismiss splitView in windows 10 universal app?

I have a login page from which I go to another page with a splitview menu. In this menu there is an option for log out from the app. In this case, I want to go to the login page again, but I don't know how to charge that page in the full page (only charge the page in the content frame but the split


xna - Pixel Shader performance on xbox

I've got a pixelshader (below) that i'm using with XNA. On my laptop (crappy graphics card) it runs a little jerky, but ok. I've just tried running it on the xbox and it's horrible!There's nothing to the game (it's just a fractal renderer) so it's got to be the pixel shader causing the issues. I als

c# - Page command bar overlaps Splitview Pane

In my Page I have bottom command bar, and if that command bar is open and user clicks on SplitView menu than command bar is overlaying the menu.Below is the xaml of splitview page:<SplitView x:Name="NavigationSplitView" DisplayMode="CompactOverlay" IsPaneOpe

Java LibGDX drawing multiple shapes each with unique renderers

I'm creating a game with LibGDX using JAVA and I've hit a problem I can't solve even after a week's worth of trying. I have shapes being drawn with the ShapeRenderer class, and I have multiple classes and methods interacting with each other. A shape grows on the screen and when the user clicks the s

win universal app - Page inside UWP SplitView control has a limit to its Width

As described in this GitHub issue (https://github.com/eloekset/UWPSplitViewIssue/issues/1) I try to make an UWP calculator app that can be as tiny as the built-in calculator in Windows 10. However after adding a SplitView control to get a hamburger button and a side pane menu, the Page hosted inside