How to load and render 3D models

Working with our World Space

We provide support for the loading the PowerVR POD Format and rendering it in the world.

In this section:

Creating a POD model

The PowerVR SDK features a collection of tools named PVRGeoPOD used for exporting 3D models in the POD format from popular modelling packages such as Autodesk 3DS Max, Maya and Blender, plus tools to convert from the COLLADA format. When exporting your model you will be presented with the following screens. Ensure the export options match the following to ensure correct exporting:

Geometry Options

Exporting a POD File: Geometry options

Material Options

Exporting a POD File: Material options

Transformation Options

Exporting a POD File: Transformation options

User Options

Exporting a POD File: User options

When all the settings are correct, click ‘export’.

Viewing an exported POD file

After exporting a POD file, you can view it using another PowerVR Tool named PVRShaman. This can be used to validate that the POD file model and its animation & materials look correct before loading it into eeGeo 3D Maps. Note that PVRShaman requires the textures to be in PVR Format to display correctly.

Viewing an animated POD in PVRShaman

Loading a POD model

Once you’ve created your .POD model and its associated textures, you can load it from your project’s local resources into a runtime SceneModel instance with the following code.

In this case we are loading the POD file from a file in the local app resources so we provide a IFileIO that will be used to load the file.

We also provide an IAsyncTextureRequestor that will be used to load the textures referenced by the model.

Here, we’ve used the LocalAsyncTextureLoader implementation of IAsyncTextureRequestor which loads textures from local app resources.

The SceneModelFactory will load all textures, materials & meshes of the pod model, build up a hierarchy with (optional) animated data and return the container for that scene graph in the form of the SceneModel type.

Alternative methods for creating a POD Model

Loading from local app resources is just one way to load POD files. The SceneModelFactory class also provides a variety of Create*() methods to load Scene Models via a preloaded podScene & also optionally store the textures, materials & meshes in custom repositories. PodScenes themselves can be loaded from buffers or streams via the PodFileParser type.

In order to keep the initial download size of your app small, you might want to consider loading textures from an HTTP server as they are required. This can be achieved with the Eegeo::IO::AsyncModels::HttpAsyncModelLoader class, an instance of which is provided by the AsyncTextureLoadersModule::GetHttpAsyncModelLoader() method.

Loading textures

Typically the materials in a POD model will reference a number of textures. When you load a POD model, you’ll usually want these textures to be loaded as well. Just as POD models can be loaded from a variety of different places (local resources, HTTP servers etc.), the same is true for textures.

Loading the textures referenced by a POD model is the responsibility of the IAsyncTextureRequestor instance that is provided to the Model::Create*() methods.

The platform provides implementations of IAsyncTextureRequestor for loading textures from both local app resources and HTTP servers. These are LocalAsyncTextureLoader and HttpAsyncTextureLoader respectively. Instances of these are provided by the EegeoWorld object.

Both of these texture loaders need to be provided with a path under which to look for texture files. When loading from local app resources this is typically an empty string, as in the example above. When loading textures via HTTP, the path is the URL under which textures can be found.

Preparing textures

Texture Formats

In order to prepare textures for use with the platform you will need to convert them into the appropriate format. In the majority of cases this will be a compressed that can be directly consumed by the graphics processing unit (GPU) of the mobile device you are working on. By using a compressed format that the GPU can use directly you can both reduce the runtime memory footprint of your app and, in some cases, even improve rendering performance.

The format that you need to convert your textures into depends on the operating system that your app will be running on:

  • On Apple IOS devices, you need to store textures in PVR format, using the PVRTC1_4 compression technique. By convention, files in this format have “.pvr” as their file extension.
  • On Android devices textures are stored in the KTX file format, using the ETC1 compression technique. By convention, files in this format have “.ktx” as their file extension.

Converting Textures

You can use PVRTexTool from the PowerVR SDK to convert images into PVR and KTX formats. This tool can also create MipMap chains to enable your texture to be rendered faithfully at a range of different scales.

The PowerVR SDK provides a command line version of PVRTexTool that you can use to convert images. The PVRTexTool command line to convert to convert images into PVR format for Apple IOS is as follows:

In order to convert images into KTX files for use on Android platforms, you can use the following command:

Automating Texture Conversion

If you’re interested in setting up an automated build process to convert images into the correct formats, our environment-themes repository is a good starting point. This repository shows how a set of images can be automatically converted and uploaded to an Amazon S3 bucket for serving over the Internet. The environment-themes repository is publically available on

Textures with pre-pixel transparency.

If your texture contains per-pixel transparency information that needs to faithfully reproduced during rendering, it is usually best to store the texture as a PNG file with an alpha channel rather than using the compressed formats above.

See the section below on texture names to learn how PNG files should be named.

Texture Names

Texture Name Fix-up

Before the platform can load a texture referenced in a POD file it needs to fix up the texture name to ensure that the correct texture file is loaded. The name of file varies based on the operating system that your app is running on and whether the texture contains per-pixel transparency (alpha) information.

Why fix-up texture names?

As we saw above, Apple IOS platforms use textures in PowerVR (PVR) format whereas Android platforms use textures in KTX format. Furthermore, some textures contain fine grained transparency (alpha) information and consequently they need to be stored as PNG files in order to be displayed faithfully.

Fix-up rules

The platform works out what file name to load the texture from by applying fix-up rules to the texture name found in the POD file.

The fix-up rules that the platform applies are as follows:

  1. Take the texture file name as specified in the POD file. (e.g. my_texture.pvr)
  2. Apply extension re-writing rules to adjust for the operating system that your app is running on. These rules work as follows:

    • If the texture name contains the string “-alpha” its extension is not modified, irrespective of the operating system platform. This allows textures containing an alpha channel to be specified as PNG files which are portable across operating system platforms.
    • If the operating system is Android and the texture doesn’t contain “alpha”, then change its extension to “ktx”.
    • If the operating system is Apple IOS and the texture doesn’t contain “alpha”, then change its extension to “pvr”.
  3. Prefix the resulting re-written texture name with the texture path.

Example: Opaque Texture

The full path for each texture is formed by concatenating the texture path with the rewritten texture name. For example a texture named “mytexture.pvr” in the POD file, when loaded with a texture path of “” would be requested as:

  • “” on an Apple IOS device.
  • “” on an Android device.

Example: Translucent Texture

By way of contrast, a texture named “mytexture-alpha.png” would be requested as
“” on both Apple IOS and Android devices.

Example: Loading textures via HTTP

The code example below shows how a POD model can be loaded from a byte array, with its textures being loaded from an HTTP server.

It should be noted that textures loaded via HTTP are automatically cached on the device. This usually means that they can be loaded more quickly after the first time they have been used. Textures shared between POD files will be cached and reference counted by the POD resources repositories the factory uses.

Rendering a POD Model

Rendering a model in the world requires you to provide an ECEF position & local transform matrix, and to enqueue it to the SDK’s rendering system via a filter . This is done with the following code:

For more information on creating an EegeoWorld object and setting up an application, see the Example SDK App.

For more information on generating transforms for working in the ECEF coordinate system so your models are positioned and orientated correctly, see Working with our World Space

Example Application

Our example application includes a number of examples with source provided for loading and rendering POD models. You can find this code at the Mobile SDK Harness Git repository