Creating multiple resource sets

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.

Using build styles

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

sw

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 IW_USE_LEGACY_MODULES define in our MKB file in order to make the software renderer available for use.

gles1

Builds resources without any form of texture compression. This is the default if no build style is specified.

gles1-pvrtc

Same as gles1, but uses the PVRTC format for texture compression on images where this type of compression works well. Typically this just means images with no alpha channel, as PVRTC tends to perform badly on such textures.

gles-atitc

Same as gles1, but uses the ATITC texture compression format where possible.

gles1-dxt

Same as gles1, but uses the DXT format for texture compression.

gles2-etc

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"
}

Adding extra resource directories

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.

Supported build style platforms

The platform field of a CIwResBuildStyle instance can take one of the following values:

Platform value

Description

SW

Build resources optimized for use with Marmalade's legacy software renderer. Again, we must be using the IW_USE_LEGACY_MODULES define in our MKB in order to use this.

GLES1

This is the default option if none is specified and builds resources that can be rendered efficiently using OpenGL ES.

IMG_MBX

Same as GLES1, but uses the PVRTC format for texture compression on images where this type of compression works well.

IMG_MBX_VGP

Currently the same as IMG_MBX.

ATI_IMAGEON

Same as GLES1, but uses the ATITC format for texture compression where possible.

NVIDIA_GOFORCE

Currently performs the same as GLES1.

ARM_MALI

Currently performs the same as GLES1.

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:

Value

Description

PVRTC_2

Uses 2-bit PVR texture compression. Not normally recommended, as it tends to produce poor-quality results. Can be used on devices featuring an Imagination-produced chipset, such as iOS devices.

PVRTC_4

Uses 4-bit PVR texture compression. This type generally yields good results for textures with no alpha channel, but can be quite poor when compressing transparent textures. By default Marmalade will not perform this type of compression on any source texture with an alpha component. This type of compression is supported by devices using an Imagination GPU, for example iOS devices.

ATITC

Will compress textures using ATI compression. Automatically uses 4-bit compression on textures with no alpha channel, or 8-bit compression on textures with transparency. Supported on ATI/Qualcomm chipsets typically used in many Android devices.

ETC

Uses 4-bit Ericsson texture compression on textures with no alpha channel. Transparent textures cannot be compressed. Supported on ATI/Qualcomm chipsets and most chipsets that support OpenGL ES 2.x.

DXT1,

DXT3, and

DXT5

DXT1 compression is a 4-bit format used for non-transparent textures. DXT3 is an 8-bit format that allows transparent textures to be compressed. DXT5 is another 8-bit format that has better support for gradients in the alpha channel. If DXT3 or DXT5 is specified and an opaque texture is encountered, Marmalade will automatically use DXT1 compression instead. Available on NVidia Tegra2 chipset devices.

Specifying which build style to use

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.

Using resource templates

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"
}

Defining material templates

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:

Parameter

Description

colAmbient ,

colDiffuse ,

colEmissive , and

colSpecular

Allows a default RGBA color to be specified for the ambient, diffuse, emissive, and specular lighting components. For example: colAmbient { 255, 255, 255, 255 }.

cullMode

Specifies the back-face culling method to use for the material. Can be one of BACK, FRONT, or NONE.

alphaMode

Specifies a default transparency mode. Can be one of NONE, ADD, SUB, HALF, or BLEND.

blendMode

Specifies the blending type that will be used when drawing. Possible values are MODULATE, MODULATE_2X, MODULATE_4X, DECAL, ADD, REPLACE, and BLEND.

alphaTest

Specifies the type of alpha test to use when drawing pixels. Consists of a test type followed by an alpha value. Valid test types are DISABLED, NEVER, LESS, EQUAL, LEQUAL, GREATER, GEQUAL, NOTEQUAL, and ALWAYS. For example: alphaTest GEQUAL 128.

zDepthOfs and

zDepthOfsHW

Allows this material to have an offset added to the z component of vertices when they are rendered, to force drawing backwards or forwards. Useful for drawing glowing effects so they can be forced to appear behind or in front of a 3D model. zDepthOfs is used in the software renderer and zDepthOfsHW is used when rendering with OpenGL ES.

filtering

Set to true to use bilinear filtering when rendering.

clampUV

If true, the UV coordinates are clamped within the bounds of the texture. This helps avoid the problems caused by bilinear filtering when rendering the edges of a texture, as bilinear filtering will attempt to blend between texels on the left and right or top and bottom of the image as it will assume the texture can be tiled otherwise.

Defining image templates

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:

Parameter

Description

formatSW and

formatHW

Converts any image to the requested format. The two versions of this parameter allow a format to be defined for the software renderer and another format for OpenGL ES rendering.

For a complete list of texture formats, take a look at the Marmalade documentation for the CIwImage class, but bear in mind that some of these formats apply only to software or hardware rendering. For example, OpenGL ES does not support any of the palette-based formats, while the software renderer does not support compressed formats such as PVRTC or ATITC.

compressForDiskSpace

When true, converting textures using the formatSW and formatHW parameters will only store the converted version in the binary version of the GROUP file if it is smaller (in memory terms) than the image in its original format. Defaults to false.

mipMapping

When true, mipmaps will automatically be generated for the image. It can be very useful to set this to false for images that will form part of the UI, since these generally want to be drawn at their native size and mipmaps will not be needed.

allowLowQualityCompression

If using a hardware compressed format, Marmalade will not use the requested compression if the resulting texture is likely to be of low quality, for example, when using PVRTC on an image with an alpha channel. Setting this parameter to true allows you to force Marmalade to perform the requested compression.

ignoreImages

If set to true, images will be ignored and a 2 x 2 checkerboard texture will be used instead. Can be useful when debugging to speed up loading time.

Defining model templates

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:

Parameter

Description

scale

Allows a floating point value that will be used to scale all the vertices of the model, to be specified. Can be useful to allow 3D models to be created in a modeling package with one scale and used at a different scale in the game.

buildCols ,

buildNorms ,

buildUVs , and

buildUV1s

If set to true, the processed model data will include vertex colors, normals, and UV information, assuming it exists in the exported model. This can be useful to save memory in the game if lighting or textures are not required on the model.

triStrip

If set to true, a model will be conditioned for rendering using triangle strips. The default is false, which will cause triangle lists to be generated. Only takes effect if the model is being conditioned for rendering with OpenGL ES.

calculateNorms

If set to true, the model builder will attempt to generate vertex normals for lighting purposes. Useful if the source model was exported without normals for any reason.

chunked

If set to true, the model will be subdivided into smaller "chunks" for rendering using binary space partitioning. This can be useful when rendering a model much larger than screen size, as it allows whole sections of the model which are off-screen to be ignored.

maxPrimsPerChunk

Used in conjunction with the chunked parameter to specify the maximum number of polygons each chunk of the model should contain.

Defining animation templates

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

zeroMotionTolerance

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.

transformPrecision

Another floating point value that specifies the precision to be used when animating. The default value is 4.0, meaning that the animation mathematics are calculated at four times the world space resolution. If you have an animation with lots of subtle movements, you may want to consider increasing this value so that those movements are not lost.

Defining GROUP file templates

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.

Producing binary versions of resources

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.

Note

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.173.238