Compressed Textures in WebGL?

Is it possible to run compressed image in OpenFl ?
The decompressed image data can be RGB ( 24 bits ) or RGBA ( 32 bits ) , for each color channel takes 1 byte.
This mean , when I use image atlas with size :
2048 x 2048 * 4 = 16 MB Ram ( the image itself is about 1.5 Mb size on disk)

At the other side , WebGL provide support for a number of compressed texture formats such as :

  • DXT : desktop devices and some Android devices
  • PVR : all iOS devices / some Android
  • ETC1 : most Android devices

Which give about > 80% less in memory size i.e. if JPG use 30 MB ram, DXT will use only 5 MB.

Not currently, but I’d be happy to work with anyone interested in helping add this support

Not directly, but with ATF-Files you can read DXT1/DXT5 compressed textures. You can create them via

png2atf -n 0,0 -c d -i texture.png -o compressed_texture.atf

If you need PVRTC or ETC1 I could try to add some support for these formats over the weekend.

1 Like

I never think about ATF. Is this available only for Stage3D / flash target ? My goal is to use it for HTML5 / 2d game.

Also just at example Phaser support many texture formats and have a fallback to png ( ) . If OpenFL have such feature will be great . I’m not sure if OpenFL can add pixijs-textures ( ) or will be more appropriate to use ATF texutre support , if it’s not connected to Stage3D an flash only.

It is also available for HTML5 and native targets, but currently only DTX1 and DXT5. I guess with a bit of work, mobile Web with PVRTC and ETC1 should also work.

1 Like


Do you know how can I use it without Starling ? I would like to use it with Tilemap.

You could create and use the openfl.display3D.textures.Texture directly without Starling on a Context3D (also for 2D games). Not sure if the Tilemap class support Textures, maybe you need to adjust it or create your own Tilemap class.

Tilemap supports BitmapData only so I tried to hack it like this without success (it renders a black rectangle):

var context:Context3D = this.stage.stage3Ds[0].context3D;
context.configureBackBuffer(1000, 500, 2, true);
//upload texture
var tex:Texture = context.createTexture(4096, 4096, Context3DTextureFormat.COMPRESSED_ALPHA, false);
tex.uploadCompressedTextureFromByteArray(Assets.getBytes('assets/atlas/atf.atf'), 0);
//hack empty bitmapData
var bm2:BitmapData = new BitmapData(0, 0);
@:privateAccess bm2.__texture = @:privateAccess tex.__textureID;
@:privateAccess bm2.__isValid = false;
@:privateAccess bm2.width = 4096;
@:privateAccess bm2.height = 4096;
//EDIT: solution is var bm2 = BitmapData.fromTexture(tex);
var tile1:TilesetEx = new SpriterTileset(bm2, Assets.getText('assets/atlas/atf.xml'));//
var map:Tilemap = new Tilemap(1000, 500, tile1);
map.addTile(new Tile(tile1.getImageID("tile01.png")));

No need to hack with privateAccess

We can create the BitmapData from the texture like that :slight_smile: :

var bm2 = BitmapData.fromTexture(tex);

Also open to other improvements to BitmapData to support compressed textures, we should already support BitmapData without an image object (using disposeImage()) which means the image can only be used with hardware rendering. Then the texture we use could be a compressed texture, but I forget if we would need to use different values when we go to render that texture in GL, or if its all wrapped up in the texture creation

I think support for PVRTC and ETC1 will be awesome.

I will give it a try next weekend and see if I can create a pull request for PVRTC and ETC1

PVRTC and ETC1 support has been merged now:


Hi! ETC1 not working on android. I’ve tested basic away3d app with atf texture. It works fine on html targets in google chrome, mozilla, ie edge and on windows native. But nothing is showing on android platform. OES_compressed_ETC1_RGB8_texture is supported (I’ve add traces to check it) but texture is not showing and there is no errors.

I have not setup Android compilation successfully, only tested via WebGL. Can you therefore try to add some trace like below into openfl/_internal/stage3D/opengl/GLTexture.hx in uploadCompressedTextureFromByteArray?

var format = GLTextureBase.__compressedTextureFormats.toTextureFormat(alpha, gpuFormat); if (format == 0) return;
var format = GLTextureBase.__compressedTextureFormats.toTextureFormat(alpha, gpuFormat); trace("gpuFormat: " + gpuFormat + " format: "+ format); if (format == 0) return;