I've read the doc here:
http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d5b.html
Flash Player 11.4 and AIR 3.4 support runtime texture compression,
which is useful in certain situations, such as when rendering dynami
textures from vector art. To use runtime texture compression, perform
the following steps:
Create the texture object by calling the Context3D.createTexture()
method, passing either
flash.display3D.Context3DTextureFormat.COMPRESSED
orflash.display3D.Context3DTextureFormat.COMPRESSED_ALPHA in the third
parameter. Using the flash.display3D.textures.Texture instance
returned by createTexture(), call either
flash.display3D.textures.Texture.uploadFromBitmapData()
orflash.display3D.textures.Texture.uploadFromByteArray(). These
methods upload and compress the texture in one step.
I tried to follow the steps but get an error:
Error: Error #3763: Sampler 0 binds a texture that that does not match
the read mode specified in AGAL. Reading compressed or single/dual
channel textures must be explicitly declared.
at flash.display3D::Context3D/drawTriangles()
should I put some instructions on agal side also?
here is the full code:
NOTE: I didn't use the embedded png for texture after I tried it and failed, just a empty bitmapdata created runtime not gonna work on my macos flash player 11.8
grabbed the AGALMiniAssembler.as from here :
https://github.com/PrimaryFeather/Starling-Framework/blob/master/starling/src/com/adobe/utils/AGALMiniAssembler.as
package sandbox
{
import com.adobe.utils.AGALMiniAssembler;
import com.adobe.utils.PerspectiveMatrix3D;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
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.Event;
import flash.geom.Matrix3D;
import core.Scene3D;
[SWF(width="600",height="800",frameRate="60")]
public class TestCompressedTexture extends Sprite
{
[Embed(source="../../assets/tex_cube.png")]
private var TexCube:Class;
private var _swfHeight:int;
private var _swfWidth:int;
public var context3D:Context3D;
public var viewMatrix:Matrix3D = new Matrix3D();
public var projectionMatrix:PerspectiveMatrix3D = new PerspectiveMatrix3D();
public var meshIndexData:Vector.<uint> = Vector.<uint>
([
0, 1, 2, 0, 2, 3,
]);
public var meshVertexData:Vector.<Number> = Vector.<Number>([
//x,y,z u,v nx,ny,nz
-1, -1, 1, 0, 0, 0, 0, 1,
1, -1, 1, 1, 0, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1,
-1, 1, 1, 0, 1, 0, 0, 1,
]);
private var indexBuffer:IndexBuffer3D;
private var vertexBuffer:VertexBuffer3D;
private var program:Program3D;
private var _modelViewProjection:Matrix3D = new Matrix3D();
private var modelMatrix:Matrix3D = new Matrix3D();
private var texture:Texture;
private var uvBuffer:VertexBuffer3D;
public function TestCompressedTexture()
{
_swfHeight = 600;
_swfWidth = 800;
if (stage!=null){
init();
}else{
addEventListener(Event.ADDED_TO_STAGE,init);
}
projectionMatrix.identity();
projectionMatrix.perspectiveFieldOfViewRH(45.0,_swfWidth/_swfHeight,0.001,100.0);
modelMatrix.identity();
viewMatrix.identity();
viewMatrix.prependTranslation(0,0,-5);
super();
}
private function init(e:Event=null):void{
if (hasEventListener(Event.ADDED_TO_STAGE))
removeEventListener(Event.ADDED_TO_STAGE,init);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE,onContext3DCreate);
stage.stage3Ds[0].requestContext3D(Context3DRenderMode.AUTO,Context3DProfile.BASELINE_EXTENDED);
}
protected function onContext3DCreate(e:Event):void
{
removeEventListener(Event.ENTER_FRAME,enterFrame);
var t:Stage3D = e.target as Stage3D;
context3D = t.context3D;
if (context3D == null){
return;
}
context3D.enableErrorChecking = true;
context3D.configureBackBuffer(_swfWidth,_swfHeight,0,true);
dispatchEvent(new Event(Scene3D.SCENE3D_CREATED));
createProgram();
createTexture();
createBuffer();
addEventListener(Event.ENTER_FRAME,enterFrame);
}
public function createProgram():void{
var vsa:AGALMiniAssembler = new AGALMiniAssembler();
var vs:String =
"m44 op, va0, vc0\n" +
"mov v0, va1\n" //uv
;
var fs:String =
"tex ft0, v0, fs0 <2d,repeat,nomip>\n"+
"mov oc ft0 \n"
;
program = vsa.assemble2(context3D,1,vs,fs);
context3D.setProgram(program);
}
public function createBuffer():void{
indexBuffer = context3D.createIndexBuffer(meshIndexData.length);
indexBuffer.uploadFromVector(meshIndexData,0,meshIndexData.length);
vertexBuffer = context3D.createVertexBuffer(meshVertexData.length/8,8);
vertexBuffer.uploadFromVector(meshVertexData,0,meshVertexData.length /8);
}
public function createTexture():void{
// texture = context3D.createTexture(512, 512, Context3DTextureFormat.BGRA, false);
texture = context3D.createTexture(512, 512, Context3DTextureFormat.COMPRESSED, false);
// var texCube:BitmapData = new TexCube().bitmapData;
// trace(texCube.height,texCube.width);
var bmd:BitmapData = new BitmapData(512,512);
texture.uploadFromBitmapData(bmd);
}
protected function enterFrame(event:Event):void
{
context3D.clear();
_modelViewProjection.identity();
_modelViewProjection.append(modelMatrix);
_modelViewProjection.append(viewMatrix);
_modelViewProjection.append(projectionMatrix);
// pass our matrix data to the shader program
context3D.setProgramConstantsFromMatrix(
Context3DProgramType.VERTEX,
0, _modelViewProjection, true );
context3D.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
context3D.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
context3D.setTextureAt(0,texture);
context3D.drawTriangles(indexBuffer);
context3D.present();
}
}
}