Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

how to implement the runtime compression of texture?

Explorer ,
Jul 30, 2013 Jul 30, 2013

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?

TOPICS
ActionScript
2.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 30, 2013 Jul 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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 01, 2013 Aug 01, 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/AGALMi...

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

                    }

          }

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 05, 2013 Aug 05, 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?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 05, 2013 Aug 05, 2013

Thanks again,

By your oppion this compressed mode should work or not? I know there's few example codes I can found on web, and I managed to find a thread of Starling project here:

https://github.com/PrimaryFeather/Starling-Framework/issues/153

The picture I embed is 512 * 512 png, with rgb no alpha

here is the pic:

https://lh6.googleusercontent.com/-uxjTCZXBnOg/Uf_InL7Wq3I/AAAAAAAACdY/tgHtg_fptr8/s512-no/tex_cube....

can you try this pic with compressed mode, or I just used a wrong png file?

I traced the h/w it gives me the right value:

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

                              trace(texCube.height,texCube.width);//512 512

yes, using Context3DTextureFormat.BGRA worked, but no luck with compressed

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 05, 2013 Aug 05, 2013

As long as the bitmap is valid the next question is are you trying to do this on a device? That currently isn't supported. See Daniel's comment in your issues/153 link above about getting that official word from Adobe on only supporting COMPRESSED with desktop:

Indeed, this feature is only available on Desktop right now! I just received a confirmation about this.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 05, 2013 Aug 05, 2013

Sadlly No, I test it on my macos and I run the generated swf target for web player on windows 7 get the same problem.

I changed the code to a runtime generated bmd but still no work, it's strange

                              texture = context3D.createTexture(512, 512, Context3DTextureFormat.COMPRESSED, false);

                              var bmd:BitmapData = new BitmapData(512,512);

                              texture.uploadFromBitmapData(bmd);

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 06, 2013 Aug 06, 2013

That's another good question that's very on target because I'm not sure if it's implemented in both desktops. I only have development tools on the Windows side myself. Perhaps you should ask in that same thread if the Desktop pertains to Windows-only or both.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 06, 2013 Aug 06, 2013

So is this means the code above does works on your windows computer?

I tested on both mac and windows , the result is the same

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 06, 2013 Aug 06, 2013

What is core.Scene3D?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 06, 2013 Aug 06, 2013

sinious wrote:

What is core.Scene3D?

Sorry, my bad. This line of code totally useless you can safely delete the import part and the event.dispatch part, the cleaned up code should like this:

I also remove the embed pic, which leads to another direction

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;

 

 

          [SWF(width="600",height="800",frameRate="60")]

          public class TestCompressedTexture extends Sprite

          {

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

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

                    }

          }

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Aug 06, 2013 Aug 06, 2013

I can verify Windows also gives the same error. Oddly I remember Starling in a thread requesting adding BRGA_PACKED support for ATF. I made the PNG an ATF and tried it even though the sample code even said to use Context3DTextureFormat.COMPRESSED (I did compress it). Neither of those worked either. I did make sure to keep all the mips in there as somewhere in my trails I remembered reading it would expect the mipmaps to be generated:

texcube.jpg

Starling loads it just fine. If you haven't already I'd wander over there and look around their loading codes which just got an ATF Async mod today even.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 07, 2013 Aug 07, 2013
LATEST

Thanks so much for your test, I haven't try starling yet, but I will try it later. Also I wanna file a bug on this, I believe this is either lack of document or incomplete feature

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines