Although it is quite often and more convenient to embed resources into the SWF file, there are times when this is not desirable. Away3D includes a number of classes to aid in loading external resources.
There are some considerations to be aware of when accessing external resources. One of the issues is that the loading process is asynchronous, which means that the actual process of downloading an external resource is done in the background. Normally, you would deal with the data once it has been retrieved by way of a call-back function, which is called when the Event.COMPLETE
event is dispatched.
For a simple bitmap material, the BitmapFileMaterial
class deals with this background loading for you. You supply the URL of the external texture image, and the BitmapFileMaterial
class takes care of all the asynchronous loading process.
Other material types don't have an equivalent of the BitmapFileMaterial
to handle loading of external textures. For this Away3D supplies the TextureLoadQueue
class, which will load a number of external resources as a group and notify you when they are all ready.
As you can see, the BitmapFileMaterial
is very straightforward to use. By hiding the details of the asynchronous loading process, the BitmapFileMaterial
class allows us to simply apply it like any other material. All we need to do is supply the location of the texture file to load.
protected function applyBitmapFileMaterial():void { initSphere(); materialText.text = "BitmapFileMaterial"; var newMaterial:BitmapFileMaterial = new BitmapFileMaterial("earth_diffuse.jpg"); currentPrimitive.material = newMaterial; }
The BitmapFileMaterial
class extends the BitmapMaterial
class, which means the init object parameters listed for the BitmapMaterial
class also apply to the BitmapFileMaterial
class.
The process becomes a little more complicated when you need to load several textures to create one material. Take the Dot3BitmapMaterial
class as an example. It requires both diffuse texture and normal map.
The TextureLoadQueue
can be used to load multiple external resources as a group. This allows us to initiate the loading of all the textures required by a class like Dot3BitmapMaterial
, and then create a new instance of the class when all are loaded.
protected function applyExternalDot3BitmapMaterial():void { initSphere(); initDirectionalLight(); materialText.text = "External Dot3BitmapMaterial";
First, we create a new instance of the TextureLoadQueue
class.
var textureLoadQueue:TextureLoadQueue = new TextureLoadQueue();
We then need to create two additional objects for each file to be loaded. The first is a URLRequest
object, whose constructor takes the URL of the external file as the first parameter.
var req:URLRequest = new URLRequest("earth_diffuse.jpg");
The second is a TextureLoader
object.
var loader:TextureLoader = new TextureLoader();
We then pass both of these objects to the TextureLoadQueue
addItem()
function.
textureLoadQueue.addItem(loader, req);
This process is repeated for the normal map texture file.
req = new URLRequest("earth_normal.jpg") loader = new TextureLoader(); textureLoadQueue.addItem(loader, req);
The Event.COMPLETE
event will be dispatched by the TextureLoaderQueue
object once all of the external files have been loaded. Once this event has been dispatched, we can get access to the bitmap data required to create the material. For convenience, we will create an anonymous function to respond to this event.
textureLoadQueue.addEventListener( Event.COMPLETE, function(event:Event):void {
We create two BitmapData
variables, which will be assigned to the data contained in the two external files we have just loaded.
var diffuse:BitmapData; var normal:BitmapData;
Unfortunately, the TextureLoaderQueue
does not index the loaded images in a way that is easy to access. Instead, it provides an array of TextureLoader
objects, and each individual TextureLoader
object can then be identified and then processed. This involves iterating over the whole array to find out which TextureLoader
objects relate to which external files.
for each (var image:TextureLoader in textureLoadQueue.images) {
Regardless of which external file the current TextureLoader
object obtained its data from, we first create a new BitmapData
object and draw the contents of the TextureLoader
into it.
var bitmapData:BitmapData = new BitmapData(image.width, image.height); bitmapData.draw(image);
Using the filename
property of the current TextureLoader
object, we can work out which external file it obtained its data from. This allows us to reference the new BitmapData
object we just created with either the diffuse
or normal
variable.
if (image.filename == "earth_diffuse.jpg") diffuse = bitmapData; else if (image.filename == "earth_normal.jpg") normal = bitmapData; }
Now that we have a reference to the diffuse and normal-map bitmaps, we can go ahead and create the Dot3BitmapMaterial
object.
currentPrimitive.material = new Dot3BitmapMaterial(diffuse, normal); } );
Finally, with the anonymous call back function in place we can now request that the TextureLoaderQueue
start loading the files by calling its start()
function.
textureLoadQueue.start(); } } }