Skip to main content
Known Participant
July 30, 2013
Question

how to implement the runtime compression of texture?

  • July 30, 2013
  • 1 reply
  • 2836 views

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 instruction on agal side also?

This topic has been closed for replies.

1 reply

sinious
Legend
July 30, 2013

Which method are you using, uploadFromBitmapData() or uploadFromByteArray() and where is the data coming from? Are you doing something like creating a new BMD object and draw()ing something into it for uploadFromBitmapData()?

Please make sure you're using an up to date AGALMiniAssembler.as.

Known Participant
August 2, 2013

thanks for the reply, and sorry for late response. Here's the whole code for the test, and I grabbed the AGALMiniAssembler.as from here :

https://github.com/PrimaryFeather/Starling-Framework/blob/master/starling/src/com/adobe/utils/AGALMiniAssembler.as

I don't know where else to find an up to date one, please give me a link, thanks

here's the full code, I embed a png file and try to uploadFromBitmapData, which gives me 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()

          at sandbox::TestCompressedTexture/enterFrame()[/Volumes/MacintoshHD/Users/dawn/Documents/workspace/work/dev/smodel/src/sandbox/TestCompressedTexture.as:150]

package sandbox

{

          import com.adobe.utils.AGALMiniAssembler;

          import com.adobe.utils.PerspectiveMatrix3D;

 

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

                    }

 

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

                              texture.uploadFromBitmapData(new TexCube().bitmapData);

                    }

 

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

                    }

          }

}

sinious
Legend
August 5, 2013

Nothing immediately jumps out at me. Can you try making that BMD before sending it as a parameter to createTexture just to verify validity. Check any property on it and make sure it's what you expect, like height/width as you know the mips won't be generated if it's odd, or if those properties are 0'd something is wrong with the PNG, etc.

e.g. just

var vmd:BitmapData = new TexCube().bitmapData;

trace('height:' + bmd.height + ', width:' + bmd.width); // 512, 512 or at least power of 2?

texture.uploadFromBitmapData(bmd);

Does using Context3DTextureFormat.BGRA work?

I see you mention COMPRESSED was available in AIR/FP 3.4 but in the docs I can filter it all the way back to 3.0 and it exists. What version are you targeting?