We introduced Stage3D last year and the momentum behind has never stopped growing but there is one area we did not give all the details. The ATF file format, it is mentioned here and there, so what’s up with this? Some of you may have seen it in the documentation for Stage3D referred as the compressed texture file format, but we never shared any tools to create those famous ATF textures.

Before we package the ATF tools with the AIR SDK, I am happy to share here in advance the ATF tools so that you guys can start leveraging the ATF format now!

So what is it?

First, let’s start by talking about what compressed textures are.

When doing GPU programming with any technology, you have two options for how you handle your textures. You can go compressed or uncompressed, very simple. So, what is the difference?

  1. When using uncompressed textures, a good old uncompressed file format like PNG is used and uploaded to the GPU.
  2. Because GPUs don’t support such a file format natively, your texture is actually stored in CPU memory, when it could actually be stored on the GPU memory!
  3. Same thing applies for JPEG images, make no mistake, graphics chipsets don’t know anything about JPEG which would also be decoded on CPU memory.
  4. Of course, each platform has different support for compressed textures depending on the hardware chipset being used.
Now get ready for the fun! Here is below a little table to illustrate it:
Platform Format
ImgTech (iOS) PVRTC
Qualcom (Android) ETC1
Mali (Android) ETC1
NVidia (Android) ETC1/DXT1/DXT5
Android (PowerVR) PVRTC/ETC1
Windows DXT1/DXT5
MacOS DXT1/DXT5

 

Why ATF?

As you can imagine, if you would develop a game targeting iOS, Android and desktop, you would need to supply your textures compressed to each format for each platform. Which would look like this:

  1. leaf.png encoded to DXT for Windows and MacOS
  2. leaf.png encoded to ETC1 or DXT for Android (Nvidia)
  3. leaf.png encoded to PVRTC for iOS (ImgTech)

Of course it is a pain to provide all the different versions of the textures, detect at runtime which platform you are running on and upload the corresponding texture. Wouldn’t it be cool if you could just rely on one single container, that would wrap all the textures for each platform and Flash Player or AIR would extract automatically the texture required depending on the platform? So here comes ATF.

The ATF internals

Really, think about the ATF format as a container for lossy images. Here is below a little figure showing very sinply the structure of a default compressed ATF file:

01

By default, all textures format (PVRTC (4bpp), ETC1, and DXT1/5) are embedded in the ATF file so that for each platform, AIR or Flash Player automatically extracts the appropriate texture. But in some cases, you may want to target mobile only and why should you embed desktop related textures or Android if you are targeting iOS only? To cover this, you can also embed the PVRTC textures only inside the ATF file, making your assets smaller.

The figure below illustrate the idea:

02

As you can imagine, the same applies to ETC1 if you are targeting Android:

03

If you know about ETC1, you may wonder how we handle transparency then? We use a dual ETC1 approach with two textures, one for the alpha channel and one for the colors.

And finally on desktop only, where only the DXT texture can be provided:

04

The difference between DXT1 and DXT5 resides in alpha support. DXT1 does not support transparency, DXT5 does. Automatically the ATF tools will detect if your images have transparency and select the proper DXT version for you. Also note that ATF is not alpha pre-multiplied.

Now, if you want to store uncompressed textures inside an ATF file, you can also do that:

05

Why would you do that you may ask? Well, you may want to use uncompressed textures but still want to leverage cubemap, automatic mipmap support or even texture streaming.

Ok, now apart from the fact that hardware requires those textures to be compressed, what is the value for your content?

Yes, what does it bring you?

  • Faster rendering
  • Lower texture memory requirements (extremely important on devices like the iPad1 where memory is very limited)
  • Faster texture uploads into texture memory
  • Automatic generation of all required mip-maps (note that you can disable this if needed).
  • Additionally, the use of compress textures allows the application to utilize higher resolution textures with the same memory footprint.
Now the question is, how do you create such ATF files? It is very easy, we provide a few command line tools for that. Let’s have a look at how it works.

How to use the tools

The main tool you need to know about is png2atf , which as you can guess, takes a png and gives you an ATF file:

//package leaf.png with all 3 formats (DXT5, PVRTC and ETC1x2)
C:\png2atf.exe  -c  -i  leaf.png  -o  leaf.atf
[In 213KB][Out 213KB][Ratio 99.9703%][LZMA:0KB JPEG-XR:213KB]

//package specific range of mipmaps
C:\png2atf.exe  -c  -n  0,5  -i  leaf.png  -o  leaf0,5.atf
[In 213KB][Out 213KB][Ratio 99.8825%][LZMA:0KB JPEG-XR:213KB]

//package only DXT format
C:\png2atf.exe  -c d  -i  leaf.png  -o  leaf_dxt5.atf
[In 85KB][Out 85KB][Ratio 100.045%][LZMA:0KB JPEG-XR:85KB]

//package only ETC1 format
C:\png2atf.exe  -c e  -i  leaf.png  -o  leaf_etc1.atf
[In 85KB][Out 85KB][Ratio 100.045%][LZMA:0KB JPEG-XR:85KB]

//package only PVRTC format
C:\png2atf.exe  -c p  -i  leaf.png  -o  leaf_pvrtc.atf
[In 42KB][Out 42KB][Ratio 100.089%][LZMA:0KB JPEG-XR:42KB]

As mentioned earlier, what if you wanted to store uncompressed a uncompressed texture inside your ATF? For this, just don’t use the -c argument:

//package as uncompressed (RGBA) format
C:\png2atf.exe  -i  leaf.png  -o  leaf_rgba.atf
[In 341KB][Out 43KB][Ratio 12.8596%][LZMA:0KB JPEG-XR:43KB]

Another cool feature is that ATF can also be used with streaming, to generate 3 sub-files you can do this:

png2atf -m -n 0,0 -c -i cubecat0.png -o cubecat_c_high.atf
png2atf -m -n 1,2 -c -i cubecat0.png -o cubecat_c_med.atf
png2atf -m -n 3,20 -c -i cubecat0.png -o cubecat_c_low.atf

For info, texture support streaming shipped in Flash Player 11.3/AIR 3.3. Make sure to create the texture with streaming on, by using the streamingLevel arguments of the Texture.createTexture() API.

If you have used the texturetool from Apple to generate your PVR textures, this is the same approach. Another tool called pvr2atf , which is a command line utility converts PVR texture files to ATF files. The tool works similarly to png2atf except that you have to provide input files in the PVR texture format.

To convert a PVR file to an RGB or RGBA ATF file run the command as such:

C:\> pvr2atf -i test.pvr -o test.atf
[In 4096KB][Out 410KB][Ratio 10.0241%][LZMA:0KB JPEG-XR:410KB]

Also, you can use ATF for a cubemap texture:

//to create a ATF for cubemap texture,
//prepare png file for each side of the cube as:
// -X: cube0.png
//+X: cube1.png
// -Y: cube2.png
//+Y: cube3.png
// -Z: cube4.png
//+Z: cube5.png
C:\png2atf.exe  -c   -m  -i  cube0.png  -o  cube.atf

ATFViewer is a GUI tool which previews and inspects ATF files. The primary purpose is to audit DXT1, ETC1 and PVRTC compression artifacts. You can open and view ATF files by either using the ‘Open…’ menu item or by dragging a file from Explorer into the window. The Snippet preview area shows you an example of how to load a particular ATF file in raw ActionScript 3 Stage3D code.

Below is an example of a test file from Starling, you can preview the texture for each format and also have a little code snippet at the bottom which tells you how to use it in ActionScript 3 with Stage3D:

06

Note that when opening an ATF texture containing only specific compression, the ATFViewer will show this, below we opened an ATF file containing only the DXT textures, you can see that ETC1 and PVRTC in the texture types list are greyed out:

07

Let’s have a look now at how we can use compressed textures with the Stage3D APIs.

Using compressed textures with Stage3D

To use compressed textures with Stage3D, you need to use theTexture.uploadCompressedTextureFromByteArray API with one of the two relatedContext3DTextureFormat constants (Context3DTextureFormat.COMPRESSED_ALPHA andContext3DTextureFormat.COMPRESSED ):

class Example {
[Embed( source = "mytexture.atf", mimeType="application/octet-stream")]
public static const TextureAsset:Class;
public var context3D:Context3D;

public function init():void{
var texture:Texture = context3D.createTexture(256, 256, Context3DTextureFormat.COMPRESSED_ALPHA, false);
var textureAsset:ByteArray = new TextureAsset() as ByteArray;
texture.uploadCompressedTextureFromByteArray(textureAsset, 0);
}
};

In the context of a cubemap texture, you would write:

var texCubemap:CubeTexture = context3D.createCubeTexture(256, Context3DTextureFormat.COMPRESSED_ALPHA, false);
var textureAsset:ByteArray = new TextureAsset() as ByteArray;
texCubemap.uploadCompressedTextureFromByteArray(textureAsset, 0);

Also, depending on the format of the texture, “dxt1” or “dxt5” is needed in the texture sampler of your fragment shader:

  • Nothing needed for Context3DTextureFormat.BGRA , same as before
  • “dxt1” for Context3DTextureFormat.COMPRESSED (whatever the texture format used, DXT, PVRTC, or ETC1)
  • “dxt5” for Context3DTextureFormat.COMPRESSED_ALPHA  (whatever the texture format used, DXT, PVRTC, or ETC1)
You can also check the specific  Starling commit for ATF support  to see how it got integrated.

Integration with Starling

Great news, Starling already supports ATF textures through theTexture.uploadAtfData API. Find here all the details about ATF and Starling, but it is as simple as this:

[Embed(source="starling.atf", mimeType="application/octet-stream")]
public static const CompressedData:Class;

var data:ByteArray = new CompressedData();
var texture:Texture = Texture.fromAtfData(data);

var image:Image = new Image(texture);
addChild(image);

Yes, as simple as this .

Limitations

I want to highlight that even if ATF will be very useful for 2D content (like with Starling), ATF has been mainly designed for 3D textures purposes. So what does it mean?
The compression applied to the textures is lossy and may impact too much the quality of your assets. Things like RGBA8888 and RGBA4444 for PVR are not supported and could be an issue.
But we need your feedback and testing to see how we can improve ATF and add support for more compression types. So let us know!

Requirements

One thing to keep in mind is that to cover the entire set of capabilities for ATF textures, you need:

  • If you are using Starling, you need at least Starling 1.2. Just pull the latest version from Github .
  • If you are using Stage3D directly, you need to use the latestAGALMiniAssembler
  • You need at least the AIR SDK 3.4. Download Flash Builder 4.7 which comes out of the box with the AIR 3.4 SDK.
  • You need to target at least Flash Player 11.4/AIR 3.4
  • You need to add the following compiler argument: ”-swf-version=17”

Download

Download the ATF tools here . Which contains:

  • The ATF tools binaries (Linux, Mac, Windows).
  • ATF specification
  • ATF User Guide with some more details.

Enjoy!

 

link: http://www.tuicool.com/articles/Q3Ajay

第一种:
     修改 ccConfig.h   

将#define CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL 0 改为 #define CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL 1

/** @def CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
If enabled, the texture coordinates will be calculated by using this formula:
– texCoord.left = (rect.origin.x*2+1) / (texture.wide*2);
– texCoord.right = texCoord.left + (rect.size.width*2-2)/(texture.wide*2);

The same for bottom and top.

This formula prevents artifacts by using 99% of the texture.
The “correct” way to prevent artifacts is by using the spritesheet-artifact-fixer.py or a similar tool.

Affected nodes:
– CCSprite / CCSpriteBatchNode and subclasses: CCLabelBMFont, CCTMXTiledMap
– CCLabelAtlas
– CCQuadParticleSystem
– CCTileMap

To enabled set it to 1. Disabled by default.

@since v0.99.5
*/
#ifndef CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
#define CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL 1
#endif

 

第二种:     

调用瓦片地图对应CCTexture2D的setAliasTexParameters接口。     

若调用之后还有黑线,则还调用 CCDirector::sharedDirector()->setProjection(kCCDirectorProjection2D);