Since Marmalade allows us to target so many different devices, it seems a shame to limit ourselves to a subset of them just because our graphics are too low or too high resolution for certain devices, or some devices have less memory and therefore can't handle lots of high resolution textures.
Another issue we might face is that different devices support different file formats for audio or video clips. To improve render speed and memory usage we might also consider using hardware texture compression, which of course varies depending on the type of graphics processor a particular device has.
Marmalade provides a couple of solutions to these problems. The first, more global approach is to make use of build styles , which allow us to both load different sets of resource files when loading a GROUP file and specify the type of hardware texture compression to apply.
Build styles are then enhanced by the concept of resource templates, which allow us to more finely control the configuration of resources. Resource templates can be used to affect the final format of a texture or to modify the way a 3D model is converted for use in the game, among other things.
Marmalade comes with a number of built-in build styles that allow us to build resources for all the common GPU formats used across mobile devices. The build styles available are shown in the following table:
Build style |
Description |
---|---|
Build resources optimized for use with Marmalade's legacy software renderer. Resources built in this way cannot be rendered using hardware acceleration. This format is now only of use if we are using the | |
Builds resources without any form of texture compression. This is the default if no build style is specified. | |
Same as | |
Same as | |
Same as | |
Intended for use on devices that make use of OpenGL ES 2.x and support the ETC texture compression format. |
We can also define
our own custom build styles should the default ones not suffice. To do this we create a file in the data
directory called resbuildstyles.itx
. This file is automatically loaded by the resource manager when it is initialized in the call to IwResManagerInit
and it contains one or more instances of the CIwResBuildStyle
class.
To declare a build style instance we must give it a name so that it can be selected for use, an optional list of directories in which resource files can reside, and an indication of the platform this build style is targeting. Note that in the case of build styles, the platform does not refer to any particular operating system; instead it refers to the type of GPU the style targets, which for the most part means the type of hardware texture compression to be used.
Here's an example of a resbuildstyles.itx
file that will be used for discussion in the following sections:
CIwResBuildStyle { name "default" platform "GLES1" } CIwResBuildStyle { name "pvrtc" addReadPrefix "data-pvrtc" platform "IMG_MBX" } CIwResBuildStyle { name "atitc" addReadPrefix "data-atitc" platform "ATI_IMAGEON" }
The addReadPrefix
parameter allows us to add a new search path that will be checked whenever we attempt to load a file of any kind. A directory name is specified; this must be a subdirectory within the project's data
directory. If you want to add more than one extra search directory, just include further addReadPrefix
entries.
Whenever we try to open a file, Marmalade will first look in the list of extra directories specified by the build style in the order they were specified. If the requested file is found in one of these directories, it will be loaded from there; otherwise the resource manager will revert to looking in the data
directory.
The platform
field of a CIwResBuildStyle
instance can take one of the following values:
Platform value |
Description |
---|---|
Build resources optimized for use with Marmalade's legacy software renderer. Again, we must be using the | |
This is the default option if none is specified and builds resources that can be rendered efficiently using OpenGL ES. | |
Same as | |
Currently the same as | |
Same as | |
Currently performs the same as | |
Currently performs the same as |
While the platform identifier makes it easy to create resources for different types of GPU, it is also possible to be a little more specific about the type of texture compression to use. This can be done by specifying the platform as GLES1
and adding a textureFormat
setting. For example, the atitc
entry from the earlier example could be written as follows:
CIwResBuildStyle { name "atitc" addReadPrefix "data-atitc" platform "GLES1" textureFormat "ATITC" }
The following values can be used for the textureFormat
parameter:
With our build styles declared, we now just need to let Marmalade know which of them to use when loading resources. The easiest way of doing this is to use the ResBuildStyle
ICF setting, which we do by adding the following to our ICF file:
[RESMANAGER] ResBuildStyle=pvrtc
We can also switch between build styles at runtime as the resource manager provides methods for us to set and get the current build style. The following code snippets illustrate this:
// Discover the currently selected build style CIwStringL lCurrentStyle = IwGetResManager()-> GetBuildStyleCurrName(); // To change to a different build style IwGetResManager()->SetBuildStyle("atitc");
Bear in mind, however, that while it is easy to switch between build styles, this behavior is only supported in Windows debug builds. When we create a release build for devices, we will generally only provide the resources required for that device type in order to reduce the size of the installation package. We'll be looking at how to achieve this later in this chapter.
Build styles allow us to make decisions on how the resources for our game are processed on a global level; but sometimes we want a little more fine-grained control so we can treat different types of resources in different ways.
This is where resource templates come into play. Put simply, all a resource template allows us to do is alter the default settings that are applied when processing textures, materials, 3D models, animations, and GROUP files.
Resource templates can be defined in an ITX file that we parse before attempting to load any resources. Since these are only required in Windows debug builds, we do not need to load this file if we won't be building resources.
Marmalade provides a handy define, IW_BUILD_RESOURCES
, which is only defined in Windows debug builds. Using this define, we can reduce the size of our compiled code by excluding any resource processing code. For example, if our resource template definitions are contained in a file called restemplates.itx
, we could use the following code snippet to load the file:
#ifdef IW_BUILD_RESOURCES IwGetTextParserITX()->ParseFile("restemplates.itx"); #endif
The following code provides an example of what the restemplates.itx
file might look like. We'll discuss the different resource template types in greater detail in the coming sections; but notice how a template called default
is defined for each type. This is so we can revert to normal loading behavior should we want to.
CIwResTemplateImage { name "default" formatHW FORMAT_UNDEFINED formatSW FORMAT_UNDEFINED } CIwResTemplateImage { name "rgba4444_nomipmap" formatHW RGBA_4444 mipMapping false } CIwResTemplateMTL { name "default" } CIwResTemplateMTL { name "clamped_unfiltered" clampUV true filtering false }
Once a resource template has been defined, it can be invoked from within a GROUP file by using the useTemplate
parameter. This parameter takes the type and name of a resource template, searches for it and, if found, applies any settings defined in the template to any resource of the type that is loaded from then on. Here's an example:
CIwResGroup { name "images" useTemplate "image" "rgba4444_nomipmap" useTemplate "mtl" "clamped_unfiltered" "./materials.mtl" useTemplate "image" "default" useTemplate "mtl" "default" }
A material resource template is declared by an instance of the CIwResTemplateMTL
class and is used to provide a starting configuration for all instances of CIwMaterial
that are created while the template is in use.
We can specify any parameter in a material template that can be applied to a CIwMaterial
instance when processed from an ITX file. In the following table, a few of the more useful ones for template purposes are listed, but for a complete list take a look at the Marmalade documentation for CIwMaterial
:
We can also use the resource template system to specify how we want images to be processed, which includes the ability to specify what texture format is used. To define a resource template for images we have to declare an instance of CIwResTemplateImage
, which can be configured using the following parameters:
When loading a 3D model from a GEO file, we can use an instance of the CIwResTemplateGEO
resource template to control how the model is processed. Many of the options available allow us to increase rendering performance when we know that a particular model will be used under certain conditions; for example, it will only ever be rendered using OpenGL ES or it may have been exported with normals, which are not required as the model will never be rendered with lighting enabled.
Some of the more useful settings are shown in the following table, but there are a great many more, so check out the Marmalade documentation for CIwResTemplateGEO
for more details:
The CIwResTemplateANIM
class allows ANIM file data to be adjusted when being processed. It only provides a couple of options, which are listed in the following table:
Parameter |
Description |
---|---|
Allows a floating point value to be specified that will be used to filter the translation part of any key frame data. When animating a model it is possible that the artist may accidentally include some small movements to the bone positions, which yields a larger output data set. This value allows movements up to the specified value to be ignored, which can mean fewer key frames have to be output. | |
Another floating point value that specifies the precision to be used when animating. The default value is |
Finally, there is the CIwResTemplateGROUP
class that is used for creating a texture atlas. A texture atlas is simply a
collection of several smaller textures that are laid out within a much larger texture. This can improve rendering speed since fewer texture swaps are required when rendering.
We won't be looking at texture atlases in detail in this book, so if you want further information take a look at the Marmalade documentation page for the CIwResTemplateGROUP
class.
Previously in this book we've seen references to the fact that Marmalade produces binary versions of our resources, which are normally both smaller in size and quicker to load compared to the source assets.
Until now we've kind of glossed over this a little, but now that we know about build styles it's worth taking a closer look.
The binary versions of resources are generated automatically for us whenever we load a GROUP file, assuming we have the ICF setting ResBuild
set to 1
and we're running a Windows debug build of our game. These files are written out with the file extension .group.bin
into a directory called data-ram
, which lives alongside the regular data
directory where our source assets reside.
If we look inside the data-ram
directory for any project, we'll discover another set of subdirectories and these are what contain the binary versions of our resources. These subdirectories correspond to the extra prefix directories that we specify in our build styles.
When the .group.bin
files are written out, they will always be written to the prefix directory specified by the currently active build style, regardless of whether the source file was read from the standard data
directory or from the extra prefix directory.
The relative directory path from the data
directory will also be created in the output directory when writing out the binary versions of the files.
This makes it very easy for us to deploy different sets of resources to different platforms as we just need to include all the .group.bin
files from one of the subdirectories of data-ram
.
Let's illustrate this with a quick example. Suppose we have a file data/images/images.group
that loads in a number of textures. If no build style is specified, the default is the Marmalade-defined GLES1
style, which specifies a prefix directory called data-gles1
. The binary version of the file will be written to the file path data-ram/data-gles1/images/images.group.bin
.
If we now run our program again, with the pvrtc
build style selected (as defined in the section on build styles earlier in this chapter), the images will be converted to PVRTC format and instead written to the file path data-ram/data-pvrtc/images/images.group.bin
.
As it happens,
Marmalade does not just write out the binary versions of the GROUP files, it also creates a number of other files that can be useful for debugging purposes. We won't look at these in detail in this book, but you might find them useful to take a look at if you're having problems with some resource not being processed as expected. In particular, there is a file with the extension .group.bin.txt
that details all the classes encountered while processing a particular GROUP file.
There is one drawback to this approach, that is, you must load every single GROUP file that your game makes reference to in order to generate all the binary versions of them. This can particularly be a problem if your game has a large number of levels and you have a GROUP file for each level. A good way of solving this issue is to create a special mode for your game that can be given a list of all the required GROUP files (and potentially any dependencies between them) and will then load each file in turn to generate the binary version.
3.142.173.238