OGRE Manual
***********

Copyright © The OGRE Team

This work is licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported License. To view a copy of this licence, visit http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Introduction
************

This chapter is intended to give you an overview of the main components of OGRE and why they have been put together that way.

Object Orientation - more than just a buzzword
==============================================

The name is a dead giveaway. It says Object-Oriented Graphics Rendering Engine, and that's exactly what it is. Ok, but why? Why did I choose to make such a big deal about this?

Well, nowadays graphics engines are like any other large software system. They start small, but soon they balloon into monstrously complex beasts which just can't be all understood at once. It's pretty hard to manage systems of this size, and even harder to make changes to them reliably, and that's pretty important in a field where new techniques and approaches seem to appear every other week. Designing systems around huge files full of C function calls just doesn't cut it anymore - even if the whole thing is written by one person (not likely) they will find it hard to locate that elusive bit of code after a few months and even harder to work out how it all fits together.

Object orientation is a very popular approach to addressing the complexity problem. It's a step up from decomposing your code into separate functions, it groups function and state data together in classes which are designed to represent real concepts. It allows you to hide complexity inside easily recognised packages with a conceptually simple interface so they are easy to recognise and have a feel of 'building blocks' which you can plug together again later. You can also organise these blocks so that some of them look the same on the outside, but have very different ways of achieving their objectives on the inside, again reducing the complexity for the developers because they only have to learn one interface.

I'm not going to teach you OO here, that's a subject for many other books, but suffice to say I'd seen enough benefits of OO in business systems that I was surprised most graphics code seemed to be written in C function style. I was interested to see whether I could apply my design experience in other types of software to an area which has long held a place in my heart - 3D graphics engines. Some people I spoke to were of the opinion that using full C++ wouldn't be fast enough for a real-time graphics engine, but others (including me) were of the opinion that, with care, and object-oriented framework can be performant. We were right.

In summary, here's the benefits an object-oriented approach brings to OGRE:

Abstraction
     Common interfaces hide the nuances between different implementations of 3D API and operating systems

Encapsulation
     There is a lot of state management and context-specific actions to be done in a graphics engine - encapsulation allows me to put the code and data nearest to where it is used which makes the code cleaner and easier to understand, and more reliable because duplication is avoided

Polymorphism
     The behaviour of methods changes depending on the type of object you are using, even if you only learn one interface, e.g. a class specialised for managing indoor levels behaves completely differently from the standard scene manager, but looks identical to other classes in the system and has the same methods called on it

Multi-everything
================

I wanted to do more than create a 3D engine that ran on one 3D API, on one platform, with one type of scene (indoor levels are most popular). I wanted OGRE to be able to extend to any kind of scene (but yet still implement scene-specific optimisations under the surface), any platform and any 3D API.

Therefore all the 'visible' parts of OGRE are completely independent of platform, 3D API and scene type. There are no dependencies on Windows types, no assumptions about the type of scene you are creating, and the principles of the 3D aspects are based on core maths texts rather than one particular API implementation.

Now of course somewhere OGRE has to get down to the nitty-gritty of the specifics of the platform, API and scene, but it does this in subclasses specially designed for the environment in question, but which still expose the same interface as the abstract versions.

For example, there is a 'Win32Window' class which handles all the details about rendering windows on a Win32 platform - however the application designer only has to manipulate it via the superclass interface 'RenderWindow', which will be the same across all platforms.

Similarly the 'SceneManager' class looks after the arrangement of objects in the scene and their rendering sequence. Applications only have to use this interface, but there is a 'BspSceneManager' class which optimises the scene management for indoor levels, meaning you get both performance and an easy to learn interface. All applications have to do is hint about the kind of scene they will be creating and let OGRE choose the most appropriate implementation - this is covered in a later tutorial.

OGRE's object-oriented nature makes all this possible. Currently OGRE runs on Windows, Linux and Mac OSX using plugins to drive the underlying rendering API (currently Direct3D or OpenGL). Applications use OGRE at the abstract level, thus ensuring that they automatically operate on all platforms and rendering subsystems that OGRE provides without any need for platform or API specific code.

The Core Objects
****************

Introduction
============

This tutorial gives you a quick summary of the core objects that you will use in OGRE and what they are used for.

A Word About Namespaces
=======================

OGRE uses a C++ feature called namespaces. This lets you put classes, enums, structures, anything really within a 'namespace' scope which is an easy way to prevent name clashes, i.e. situations where you have 2 things called the same thing. Since OGRE is designed to be used inside other applications, I wanted to be sure that name clashes would not be a problem. Some people prefix their classes/types with a short code because some compilers don't support namespaces, but I chose to use them because they are the 'right' way to do it. Sorry if you have a non-compliant compiler, but hey, the C++ standard has been defined for years, so compiler writers really have no excuse anymore. If your compiler doesn't support namespaces then it's probably because it's sh*t - get a better one. ;)

This means every class, type etc should be prefixed with 'Ogre::', e.g. 'Ogre::Camera', 'Ogre::Vector3' etc which means if elsewhere in your application you have used a Vector3 type you won't get name clashes. To avoid lots of extra typing you can add a 'using namespace Ogre;' statement to your code which means you don't have to type the 'Ogre::' prefix unless there is ambiguity (in the situation where you have another definition with the same name).

Overview from 10,000 feet
=========================

Shown below is a diagram of some of the core objects and where they 'sit' in the grand scheme of things. This is not all the classes by a long shot, just a few examples of the more more significant ones to give you an idea of how it slots together.

At the very top of the diagram is the Root object. This is your 'way in' to the OGRE system, and it's where you tend to create the top-level objects that you need to deal with, like scene managers, rendering systems and render windows, loading plugins, all the fundamental stuff. If you don't know where to start, Root is it for almost everything, although often it will just give you another object which will actually do the detail work, since Root itself is more of an organiser and facilitator object.

The majority of rest of OGRE's classes fall into one of 3 roles:

Scene Management
     This is about the contents of your scene, how it's structured, how it's viewed from cameras, etc. Objects in this area are responsible for giving you a natural declarative interface to the world you're building; i.e. you don't tell OGRE "set these render states and then render 3 polygons", you tell it "I want an object here, here and here, with these materials on them, rendered from this view", and let it get on with it.

Resource Management
     All rendering needs resources, whether it's geometry, textures, fonts, whatever. It's important to manage the loading, re-use and unloading of these things carefully, so that's what classes in this area do.

Rendering
     Finally, there's getting the visuals on the screen - this is about the lower-level end of the rendering pipeline, the specific rendering system API objects like buffers, render states and the like and pushing it all down the pipeline. Classes in the Scene Management subsystem use this to get their higher-level scene information onto the screen.

You'll notice that scattered around the edge are a number of plugins. OGRE is designed to be extended, and plugins are the usual way to go about it. Many of the classes in OGRE can be subclassed and extended, whether it's changing the scene organisation through a custom SceneManager, adding a new render system implementation (e.g. Direct3D or OpenGL), or providing a way to load resources from another source (say from a web location or a database). Again this is just a small smattering of the kinds of things plugins can do, but as you can see they can plug in to almost any aspect of the system. This way, OGRE isn't just a solution for one narrowly defined problem, it can extend to pretty much anything you need it to do.

The Root object
===============

The 'Root' object is the entry point to the OGRE system. This object MUST be the first one to be created, and the last one to be destroyed. In the example applications I chose to make an instance of Root a member of my application object which ensured that it was created as soon as my application object was, and deleted when the application object was deleted.

The root object lets you configure the system, for example through the showConfigDialog() method which is an extremely handy method which performs all render system options detection and shows a dialog for the user to customise resolution, colour depth, full screen options etc. It also sets the options the user selects so that you can initialise the system directly afterwards.

The root object is also your method for obtaining pointers to other objects in the system, such as the SceneManager, RenderSystem and various other resource managers. See below for details.

Finally, if you run OGRE in continuous rendering mode, i.e. you want to always refresh all the rendering targets as fast as possible (the norm for games and demos, but not for windowed utilities), the root object has a method called startRendering, which when called will enter a continuous rendering loop which will only end when all rendering windows are closed, or any FrameListener objects indicate that they want to stop the cycle (see below for details of FrameListener objects).

The RenderSystem object
=======================

The RenderSystem object is actually an abstract class which defines the interface to the underlying 3D API. It is responsible for sending rendering operations to the API and setting all the various rendering options. This class is abstract because all the implementation is rendering API specific - there are API-specific subclasses for each rendering API (e.g. D3DRenderSystem for Direct3D). After the system has been initialised through Root::initialise, the RenderSystem object for the selected rendering API is available via the Root::getRenderSystem() method.

However, a typical application should not normally need to manipulate the RenderSystem object directly - everything you need for rendering objects and customising settings should be available on the SceneManager, Material and other scene-oriented classes. It's only if you want to create multiple rendering windows (completely separate windows in this case, not multiple viewports like a split-screen effect which is done via the RenderWindow class) or access other advanced features that you need access to the RenderSystem object.

For this reason I will not discuss the RenderSystem object further in these tutorials. You can assume the SceneManager handles the calls to the RenderSystem at the appropriate times.

The SceneManager object
=======================

Apart from the Root object, this is probably the most critical part of the system from the application's point of view. Certainly it will be the object which is most used by the application. The SceneManager is in charge of the contents of the scene which is to be rendered by the engine. It is responsible for organising the contents using whatever technique it deems best, for creating and managing all the cameras, movable objects (entities), lights and materials (surface properties of objects), and for managing the 'world geometry' which is the sprawling static geometry usually used to represent the immovable parts of a scene.

It is to the SceneManager that you go when you want to create a camera for the scene. It's also where you go to retrieve or to remove a light from the scene. There is no need for your application to keep lists of objects, the SceneManager keeps a named set of all of the scene objects for you to access, should you need them. Look in the main documentation under the getCamera, getLight, getEntity etc methods.

The SceneManager also sends the scene to the RenderSystem object when it is time to render the scene. You never have to call the SceneManager::_renderScene method directly though - it is called automatically whenever a rendering target is asked to update.

So most of your interaction with the SceneManager is during scene setup. You're likely to call a great number of methods (perhaps driven by some input file containing the scene data) in order to set up your scene. You can also modify the contents of the scene dynamically during the rendering cycle if you create your own FrameListener object (see later).

Because different scene types require very different algorithmic approaches to deciding which objects get sent to the RenderSystem in order to attain good rendering performance, the SceneManager class is designed to be subclassed for different scene types. The default SceneManager object will render a scene, but it does little or no scene organisation and you should not expect the results to be high performance in the case of large scenes. The intention is that specialisations will be created for each type of scene such that under the surface the subclass will optimise the scene organisation for best performance given assumptions which can be made for that scene type. An example is the BspSceneManager which optimises rendering for large indoor levels based on a Binary Space Partition (BSP) tree.

The application using OGRE does not have to know which subclasses are available. The application simply calls Root::createSceneManager(..) passing as a parameter one of a number of scene types (e.g. ST_GENERIC, ST_INTERIOR etc). OGRE will automatically use the best SceneManager subclass available for that scene type, or default to the basic SceneManager if a specialist one is not available. This allows the developers of OGRE to add new scene specialisations later and thus optimise previously unoptimised scene types without the user applications having to change any code.

The ResourceGroupManager Object
===============================

The ResourceGroupManager class is actually a 'hub' for loading of reusable resources like textures and meshes. It is the place that you define groups for your resources, so they may be unloaded and reloaded when you want. Servicing it are a number of ResourceManagers which manage the individual types of resource, like TextureManager or MeshManager. In this context, resources are sets of data which must be loaded from somewhere to provide OGRE with the data it needs.

ResourceManagers ensure that resources are only loaded once and shared throughout the OGRE engine. They also manage the memory requirements of the resources they look after. They can also search in a number of locations for the resources they need, including multiple search paths and compressed archives (ZIP files).

Most of the time you won't interact with resource managers directly. Resource managers will be called by other parts of the OGRE system as required, for example when you request for a texture to be added to a Material, the TextureManager will be called for you. If you like, you can call the appropriate resource manager directly to preload resources (if for example you want to prevent disk access later on) but most of the time it's ok to let OGRE decide when to do it.

One thing you will want to do is to tell the resource managers where to look for resources. You do this via Root::getSingleton().addResourceLocation, which actually passes the information on to ResourceGroupManager.

Because there is only ever 1 instance of each resource manager in the engine, if you do want to get a reference to a resource manager use the following syntax:

     TextureManager::getSingleton().someMethod()
     MeshManager::getSingleton().someMethod()

The Mesh Object
===============

A Mesh object represents a discrete model, a set of geometry which is self-contained and is typically fairly small on a world scale. Mesh objects are assumed to represent movable objects and are not used for the sprawling level geometry typically used to create backgrounds.

Mesh objects are a type of resource, and are managed by the MeshManager resource manager. They are typically loaded from OGRE's custom object format, the '.mesh' format. Mesh files are typically created by exporting from a modelling tool see Exporters and can be manipulated through various Mesh Tools

You can also create Mesh objects manually by calling the MeshManager::createManual method. This way you can define the geometry yourself, but this is outside the scope of this manual.

Mesh objects are the basis for the individual movable objects in the world, which are called Entities.

Mesh objects can also be animated using see Skeletal Animation.

Entities
========

An entity is an instance of a movable object in the scene. It could be a car, a person, a dog, a shuriken, whatever. The only assumption is that it does not necessarily have a fixed position in the world.

Entities are based on discrete meshes, i.e. collections of geometry which are self-contained and typically fairly small on a world scale, which are represented by the Mesh object. Multiple entities can be based on the same mesh, since often you want to create multiple copies of the same type of object in a scene.

You create an entity by calling the SceneManager::createEntity method, giving it a name and specifying the name of the mesh object which it will be based on (e.g. 'muscleboundhero.mesh'). The SceneManager will ensure that the mesh is loaded by calling the MeshManager resource manager for you. Only one copy of the Mesh will be loaded.

Entities are not deemed to be a part of the scene until you attach them to a SceneNode (see the section below). By attaching entities to SceneNodes, you can create complex hierarchical relationships between the positions and orientations of entities. You then modify the positions of the nodes to indirectly affect the entity positions.

When a Mesh is loaded, it automatically comes with a number of materials defined. It is possible to have more than one material attached to a mesh - different parts of the mesh may use different materials. Any entity created from the mesh will automatically use the default materials. However, you can change this on a per-entity basis if you like so you can create a number of entities based on the same mesh but with different textures etc.

To understand how this works, you have to know that all Mesh objects are actually composed of SubMesh objects, each of which represents a part of the mesh using one Material. If a Mesh uses only one Material, it will only have one SubMesh.

When an Entity is created based on this Mesh, it is composed of (possibly) multiple SubEntity objects, each matching 1 for 1 with the SubMesh objects from the original Mesh. You can access the SubEntity objects using the Entity::getSubEntity method. Once you have a reference to a SubEntity, you can change the material it uses by calling it's setMaterialName method. In this way you can make an Entity deviate from the default materials and thus create an individual looking version of it.

Materials
=========

The Material object controls how objects in the scene are rendered. It specifies what basic surface properties objects have such as reflectance of colours, shininess etc, how many texture layers are present, what images are on them and how they are blended together, what special effects are applied such as environment mapping, what culling mode is used, how the textures are filtered etc.

Materials can either be set up programmatically, by calling SceneManager::createMaterial and tweaking the settings, or by specifying it in a 'script' which is loaded at runtime. See Material Scripts for more info.

Basically everything about the appearance of an object apart from it's shape is controlled by the Material class.

The SceneManager class manages the master list of materials available to the scene. The list can be added to by the application by calling SceneManager::createMaterial, or by loading a Mesh (which will in turn load material properties). Whenever materials are added to the SceneManager, they start off with a default set of properties; these are defined by OGRE as the following:

  * ambient reflectance = ColourValue::White (full)

  * diffuse reflectance = ColourValue::White (full)

  * specular reflectance = ColourValue::Black (none)

  * emmissive = ColourValue::Black (none)

  * shininess = 0 (not shiny)

  * No texture layers (& hence no textures)

  * SourceBlendFactor = SBF_ONE, DestBlendFactor = SBF_ZERO (opaque)

  * Depth buffer checking on

  * Depth buffer writing on

  * Depth buffer comparison function = CMPF_LESS_EQUAL

  * Culling mode = CULL_CLOCKWISE

  * Ambient lighting in scene = ColourValue(0.5, 0.5, 0.5) (mid-grey)

  * Dynamic lighting enabled

  * Gourad shading mode

  * Solid polygon mode

  * Bilinear texture filtering

You can alter these settings by calling SceneManager::getDefaultMaterialSettings() and making the required changes to the Material which is returned.

Entities automatically have Material's associated with them if they use a Mesh object, since the Mesh object typically sets up it's required materials on loading. You can also customise the material used by an entity as described in Entities. Just create a new Material, set it up how you like (you can copy an existing material into it if you like using a standard assignment statement) and point the SubEntity entries at it using SubEntity::setMaterialName().

Overlays
========

Overlays allow you to render 2D and 3D elements on top of the normal scene contents to create effects like heads-up displays (HUDs), menu systems, status panels etc. The frame rate statistics panel which comes as standard with OGRE is an example of an overlay. Overlays can contain 2D or 3D elements. 2D elements are used for HUDs, and 3D elements can be used to create cockpits or any other 3D object which you wish to be rendered on top of the rest of the scene.

You can create overlays either through the SceneManager::createOverlay method, or you can define them in an .overlay script. In reality the latter is likely to be the most practical because it is easier to tweak (without the need to recompile the code). Note that you can define as many overlays as you like: they all start off life hidden, and you display them by calling their 'show()' method. You can also show multiple overlays at once, and their Z order is determined by the Overlay::setZOrder() method.

Creating 2D Elements
====================

The OverlayElement class abstracts the details of 2D elements which are added to overlays. All items which can be added to overlays are derived from this class. It is possible (and encouraged) for users of OGRE to define their own custom subclasses of OverlayElement in order to provide their own user controls. The key common features of all OverlayElements are things like size, position, basic material name etc. Subclasses extend this behaviour to include more complex properties and behaviour.

An important built-in subclass of OverlayElement is OverlayContainer. OverlayContainer is the same as a OverlayElement, except that it can contain other OverlayElements, grouping them together (allowing them to be moved together for example) and providing them with a local coordinate origin for easier lineup.

The third important class is OverlayManager. Whenever an application wishes to create a 2D element to add to an overlay (or a container), it should call OverlayManager::createOverlayElement. The type of element you wish to create is identified by a string, the reason being that it allows plugins to register new types of OverlayElement for you to create without you having to link specifically to those libraries. For example, to create a panel (a plain rectangular area which can contain other OverlayElements) you would call OverlayManager::getSingleton().createOverlayElement("Panel", "myNewPanel");

Adding 2D Elements to the Overlay
=================================

Only OverlayContainers can be added direct to an overlay. The reason is that each level of container establishes the Zorder of the elements contained within it, so if you nest several containers, inner containers have a higher Zorder than outer ones to ensure they are displayed correctly. To add a container (such as a Panel) to the overlay, simply call Overlay::add2D.

If you wish to add child elements to that container, call OverlayContainer::addChild. Child elements can be OverlayElements or OverlayContainer instances themselves. Remember that the position of a child element is relative to the top-left corner of it's parent.

A word about 2D coordinates
===========================

OGRE allows you to place and size elements based on 2 coordinate systems: relative and pixel based.

Pixel Mode
     This mode is useful when you want to specify an exact size for your overlay items, and you don't mind if those items get smaller on the screen if you increase the screen resolution (in fact you might want this). In this mode the only way to put something in the middle or at the right or bottom of the screen reliably in any resolution is to use the aligning options, whilst in relative mode you can do it just by using the right relative coordinates. This mode is very simple, the top-left of the screen is (0,0) and the bottom-right of the screen depends on the resolution. As mentioned above, you can use the aligning options to make the horizontal and vertical coordinate origins the right, bottom or center of the screen if you want to place pixel items in these locations without knowing the resolution.

Relative Mode
     This mode is useful when you want items in the overlay to be the same size on the screen no matter what the resolution. In relative mode, the top-left of the screen is (0,0) and the bottom-right is (1,1). So if you place an element at (0.5, 0.5), it's top-left corner is placed exactly in the center of the screen, no matter what resolution the application is running in. The same principle applies to sizes; if you set the width of an element to 0.5, it covers half the width of the screen. Note that because the aspect ratio of the screen is typically 1.3333 : 1 (width : height), an element with dimensions (0.25, 0.25) will not be square, but it will take up exactly 1/16th of the screen in area terms. If you want square-looking areas you will have to compensate using the typical aspect ratio e.g. use (0.1875, 0.25) instead.

Transforming Overlays
=====================

Another nice feature of overlays is being able to rotate, scroll and scale them as a whole. You can use this for zooming in / out menu systems, dropping them in from off screen and other nice effects. See the Overlay::scroll, Overlay::rotate and Overlay::scale methods for more information.

Scripting overlays
==================

Overlays can also be defined in scripts. See Overlay Scripts for details.

GUI systems
===========

Overlays are only really designed for non-interactive screen elements, although you can use them as a crude GUI. For a far more complete GUI solution, we recommend CEGui (http://www.cegui.org.uk), as demonstrated in the sample Demo_Gui.

Scripts
*******

OGRE drives many of its features through scripts in order to make it easier to set up. The scripts are simply plain text files which can be edited in any standard text editor, and modifying them immediately takes effect on your OGRE-based applications, without any need to recompile. This makes prototyping a lot faster. Here are the items that OGRE lets you script:

  * Material Scripts

  * Compositor Scripts

  * Particle Scripts

  * Overlay Scripts

  * Font Definition Scripts

Material Scripts
================

Material scripts offer you the ability to define complex materials in a script which can be reused easily. Whilst you could set up all materials for a scene in code using the methods of the Material and TextureLayer classes, in practice it's a bit unwieldy. Instead you can store material definitions in text files which can then be loaded whenever required.

Loading scripts
===============

Material scripts are loaded when resource groups are initialised: OGRE looks in all resource locations associated with the group (see Root::addResourceLocation) for files with the '.material' extension and parses them. If you want to parse files manually, use MaterialSerializer::parseScript.

It's important to realise that materials are not loaded completely by this parsing process: only the definition is loaded, no textures or other resources are loaded. This is because it is common to have a large library of materials, but only use a relatively small subset of them in any one scene. To load every material completely in every script would therefore cause unnecessary memory overhead. You can access a 'deferred load' Material in the normal way (MaterialManager::getSingleton().getByName()), but you must call the 'load' method before trying to use it. Ogre does this for you when using the normal material assignment methods of entities etc.

Another important factor is that material names must be unique throughout ALL scripts loaded by the system, since materials are always identified by name.

Format
======

Several materials may be defined in a single script. The script format is pseudo-C++, with sections delimited by curly braces ('', ''), and comments indicated by starting a line with '//' (note, no nested form comments allowed). The general format is shown below in the example below (note that to start with, we only consider fixed-function materials which don't use vertex, geometry or fragment programs, these are covered later):

     // This is a comment
     material walls/funkywall1
     {
         // first, preferred technique
         technique
         {
             // first pass
             pass
             {
                 ambient 0.5 0.5 0.5
                 diffuse 1.0 1.0 1.0

                 // Texture unit 0
                 texture_unit
                 {
                     texture wibbly.jpg
                     scroll_anim 0.1 0.0
                     wave_xform scale sine 0.0 0.7 0.0 1.0
                 }
                 // Texture unit 1 (this is a multitexture pass)
                 texture_unit
                 {
                     texture wobbly.png
                     rotate_anim 0.25
                     colour_op add
                 }
             }
         }

         // Second technique, can be used as a fallback or LOD level
         technique
         {
             // .. and so on
         }

     }

Every material in the script must be given a name, which is the line 'material <blah>' before the first opening ''. This name must be globally unique. It can include path characters (as in the example) to logically divide up your materials, and also to avoid duplicate names, but the engine does not treat the name as hierarchical, just as a string. If you include spaces in the name, it must be enclosed in double quotes.

 NOTE: ':' is the delimiter for specifying material copy in the script so it can't be used as part of the material name.

A material can inherit from a previously defined material by using a colon : after the material name followed by the name of the reference material to inherit from. You can in fact even inherit just parts of a material from others; all this is covered in see Script Inheritance). You can also use variables in your script which can be replaced in inheriting versions, see Script Variables.

A material can be made up of many techniques (see Techniques)- a technique is one way of achieving the effect you are looking for. You can supply more than one technique in order to provide fallback approaches where a card does not have the ability to render the preferred technique, or where you wish to define lower level of detail versions of the material in order to conserve rendering power when objects are more distant.

Each technique can be made up of many passes (see Passes), that is a complete render of the object can be performed multiple times with different settings in order to produce composite effects. Ogre may also split the passes you have defined into many passes at runtime, if you define a pass which uses too many texture units for the card you are currently running on (note that it can only do this if you are not using a fragment program). Each pass has a number of top-level attributes such as 'ambient' to set the amount & colour of the ambient light reflected by the material. Some of these options do not apply if you are using vertex programs, see Passes for more details.

Within each pass, there can be zero or many texture units in use (see Texture Units). These define the texture to be used, and optionally some blending operations (which use multitexturing) and texture effects.

You can also reference vertex and fragment programs (or vertex and pixel shaders, if you want to use that terminology) in a pass with a given set of parameters. Programs themselves are declared in separate .program scripts (see Declaring Vertex/Geometry/Fragment Programs) and are used as described in Using Vertex/Geometry/Fragment Programs in a Pass.

Top-level material attributes
-----------------------------

The outermost section of a material definition does not have a lot of attributes of its own (most of the configurable parameters are within the child sections. However, it does have some, and here they are:

lod_distances (deprecated)
--------------------------

This option is deprecated in favour of lod_values now.

lod_strategy
------------

Sets the name of the LOD strategy to use. Defaults to 'Distance' which means LOD changes based on distance from the camera. Also supported is 'PixelCount' which changes LOD based on an estimate of the screen-space pixels affected.

Format: lod_strategy <name>

Default: lod_strategy Distance

lod_values
----------

This attribute defines the values used to control the LOD transition for this material. By setting this attribute, you indicate that you want this material to alter the Technique that it uses based on some metric, such as the distance from the camera, or the approximate screen space coverage. The exact meaning of these values is determined by the option you select for lod_strategy - it is a list of distances for the 'Distance' strategy, and a list of pixel counts for the 'PixelCount' strategy, for example. You must give it a list of values, in order from highest LOD value to lowest LOD value, each one indicating the point at which the material will switch to the next LOD. Implicitly, all materials activate LOD index 0 for values less than the first entry, so you do not have to specify '0' at the start of the list. You must ensure that there is at least one Technique with a lod_index value for each value in the list (so if you specify 3 values, you must have techniques for LOD indexes 0, 1, 2 and 3). Note you must always have at least one Technique at lod_index 0.

Format: lod_values <value0> <value1> <value2> ...

Default: none

Example:

lod_strategy Distance lod_values 300.0 600.5 1200

The above example would cause the material to use the best Technique at lod_index 0 up to a distance of 300 world units, the best from lod_index 1 from 300 up to 600, lod_index 2 from 600 to 1200, and lod_index 3 from 1200 upwards.

receive_shadows
---------------

This attribute controls whether objects using this material can have shadows cast upon them.

Format: receive_shadows <on|off>

Default: on

Whether or not an object receives a shadow is the combination of a number of factors, see Shadows for full details; however this allows you to make a material opt-out of receiving shadows if required. Note that transparent materials never receive shadows so this option only has an effect on solid materials.

transparency_casts_shadows
--------------------------

This attribute controls whether transparent materials can cast certain kinds of shadow.

Format: transparency_casts_shadows <on|off>

Default: off

Whether or not an object casts a shadow is the combination of a number of factors, see Shadows for full details; however this allows you to make a transparent material cast shadows, when it would otherwise not. For example, when using texture shadows, transparent materials are normally not rendered into the shadow texture because they should not block light. This flag overrides that.

set_texture_alias
-----------------

This attribute associates a texture alias with a texture name.

Format: set_texture_alias <alias name> <texture name>

This attribute can be used to set the textures used in texture unit states that were inherited from another material.(see Texture Aliases)

Techniques
----------

A "technique" section in your material script encapsulates a single method of rendering an object. The simplest of material definitions only contains a single technique, however since PC hardware varies quite greatly in it's capabilities, you can only do this if you are sure that every card for which you intend to target your application will support the capabilities which your technique requires. In addition, it can be useful to define simpler ways to render a material if you wish to use material LOD, such that more distant objects use a simpler, less performance-hungry technique.

When a material is used for the first time, it is 'compiled'. That involves scanning the techniques which have been defined, and marking which of them are supportable using the current rendering API and graphics card. If no techniques are supportable, your material will render as blank white. The compilation examines a number of things, such as:

  * The number of texture_unit entries in each pass
     Note that if the number of texture_unit entries exceeds the number of texture units in the current graphics card, the technique may still be supportable so long as a fragment program is not being used. In this case, Ogre will split the pass which has too many entries into multiple passes for the less capable card, and the multitexture blend will be turned into a multipass blend (see colour_op_multipass_fallback).

  * Whether vertex, geometry or fragment programs are used, and if so which syntax they use (e.g. vs_1_1, ps_2_x, arbfp1 etc.)

  * Other effects like cube mapping and dot3 blending

  * Whether the vendor or device name of the current graphics card matches some user-specified rules

In a material script, techniques must be listed in order of preference, i.e. the earlier techniques are preferred over the later techniques. This normally means you will list your most advanced, most demanding techniques first in the script, and list fallbacks afterwards.

To help clearly identify what each technique is used for, the technique can be named but its optional.  Techniques not named within the script will take on a name that is the technique index number.  For example: the first technique in a material is index 0, its name would be "0" if it was not given a name in the script.  The technique name must be unique within the material or else the final technique is the resulting merge of all techniques with the same name in the material.  A warning message is posted in the Ogre.log if this occurs.  Named techniques can help when inheriting a material and modifying an existing technique: (see Script Inheritance)

Format: technique name

Techniques have only a small number of attributes of their own:

  * scheme

  * lod_index (and also see lod_distances in the parent material)

  * shadow_caster_material

  * shadow_receiver_material

  * gpu_vendor_rule

  * gpu_device_rule

scheme
------

Sets the 'scheme' this Technique belongs to. Material schemes are used to control top-level switching from one set of techniques to another. For example, you might use this to define 'high', 'medium' and 'low' complexity levels on materials to allow a user to pick a performance / quality ratio. Another possibility is that you have a fully HDR-enabled pipeline for top machines, rendering all objects using unclamped shaders, and a simpler pipeline for others; this can be implemented using schemes. The active scheme is typically controlled at a viewport level, and the active one defaults to 'Default'.

Format: scheme <name>

Example: scheme hdr

Default: scheme Default

lod_index
---------

Sets the level-of-detail (LOD) index this Technique belongs to.

Format: lod_index <number>

NB Valid values are 0 (highest level of detail) to 65535, although this is unlikely. You should not leave gaps in the LOD indexes between Techniques.

Example: lod_index 1

All techniques must belong to a LOD index, by default they all belong to index 0, i.e. the highest LOD. Increasing indexes denote lower levels of detail. You can (and often will) assign more than one technique to the same LOD index, what this means is that OGRE will pick the best technique of the ones listed at the same LOD index. For readability, it is advised that you list your techniques in order of LOD, then in order of preference, although the latter is the only prerequisite (OGRE determines which one is 'best' by which one is listed first). You must always have at least one Technique at lod_index 0.

The distance at which a LOD level is applied is determined by the lod_distances attribute of the containing material, see lod_distances for details.

Default: lod_index 0

Techniques also contain one or more passes (and there must be at least one), see Passes.

shadow_caster_material
----------------------

When using see Texture-based Shadows you can specify an alternate material to use when rendering the object using this material into the shadow texture. This is like a more advanced version of using shadow_caster_vertex_program, however note that for the moment you are expected to render the shadow in one pass, i.e. only the first pass is respected.

shadow_receiver_material
------------------------

When using see Texture-based Shadows you can specify an alternate material to use when performing the receiver shadow pass. Note that this explicit 'receiver' pass is only done when you're not using Integrated Texture Shadows - i.e. the shadow rendering is done separately (either as a modulative pass, or a masked light pass). This is like a more advanced version of using shadow_receiver_vertex_program and shadow_receiver_fragment_program, however note that for the moment you are expected to render the shadow in one pass, i.e. only the first pass is respected.

gpu_vendor_rule and gpu_device_rule
-----------------------------------

Although Ogre does a good job of detecting the capabilities of graphics cards and setting the supportability of techniques from that, occasionally card-specific behaviour exists which is not necessarily detectable and you may want to ensure that your materials go down a particular path to either use or avoid that behaviour. This is what these rules are for - you can specify matching rules so that a technique will be considered supportable only on cards from a particular vendor, or which match a device name pattern, or will be considered supported only if they don't fulfill such matches.

The format of the rules are as follows:

gpu_vendor_rule <include|exclude> <vendor_name>

gpu_device_rule <include|exclude> <device_pattern> [case_sensitive]

An 'include' rule means that the technique will only be supported if one of the include rules is matched (if no include rules are provided, anything will pass). An 'exclude' rules means that the technique is considered unsupported if any of the exclude rules are matched. You can provide as many rules as you like, although <vendor_name> and <device_pattern> must obviously be unique. The valid list of <vendor_name> values is currently 'nvidia', 'ati', 'intel', 's3', 'matrox' and '3dlabs'. <device_pattern> can be any string, and you can use wildcards ('*') if you need to match variants. Here's an example:

gpu_vendor_rule include nvidia

gpu_vendor_rule include intel

gpu_device_rule exclude *950*

These rules, if all included in one technique, will mean that the technique will only be considered supported on graphics cards made by NVIDIA and Intel, and so long as the device name doesn't have '950' in it.

Note that these rules can only mark a technique 'unsupported' when it would otherwise be considered 'supported' judging by the hardware capabilities. Even if a technique passes these rules, it is still subject to the usual hardware support tests.

Passes
------

A pass is a single render of the geometry in question; a single call to the rendering API with a certain set of rendering properties. A technique can have between one and 16 passes, although clearly the more passes you use, the more expensive the technique will be to render.

To help clearly identify what each pass is used for, the pass can be named but its optional.  Passes not named within the script will take on a name that is the pass index number.  For example: the first pass in a technique is index 0 so its name would be "0" if it was not given a name in the script.  The pass name must be unique within the technique or else the final pass is the resulting merge of all passes with the same name in the technique.  A warning message is posted in the Ogre.log if this occurs.  Named passes can help when inheriting a material and modifying an existing pass: (see Script Inheritance)

Passes have a set of global attributes (described below), zero or more nested texture_unit entries (see Texture Units), and optionally a reference to a vertex and / or a fragment program (see Using Vertex/Geometry/Fragment Programs in a Pass).

Here are the attributes you can use in a 'pass' section of a .material script:

  * ambient

  * diffuse

  * specular

  * emissive

  * scene_blend

  * separate_scene_blend

  * scene_blend_op

  * separate_scene_blend_op

  * depth_check

  * depth_write

  * depth_func

  * depth_bias

  * iteration_depth_bias

  * alpha_rejection

  * alpha_to_coverage

  * light_scissor

  * light_clip_planes

  * illumination_stage

  * transparent_sorting

  * normalise_normals

  * cull_hardware

  * cull_software

  * lighting

  * shading

  * polygon_mode

  * polygon_mode_overrideable

  * fog_override

  * colour_write

  * max_lights

  * start_light

  * iteration

  * point_size

  * point_sprites

  * point_size_attenuation

  * point_size_min

  * point_size_max

Attribute Descriptions
======================

ambient
-------

Sets the ambient colour reflectance properties of this pass. This attribute has no effect if a asm, CG, or HLSL shader program is used.  With GLSL, the shader can read the OpenGL material state.

Format: ambient (<red> <green> <blue> [<alpha>]| vertexcolour)

NB valid colour values are between 0.0 and 1.0.

Example: ambient 0.0 0.8 0.0

The base colour of a pass is determined by how much red, green and blue light is reflects at each vertex. This property determines how much ambient light (directionless global light) is reflected. It is also possible to make the ambient reflectance track the vertex colour as defined in the mesh by using the keyword vertexcolour instead of the colour values. The default is full white, meaning objects are completely globally illuminated. Reduce this if you want to see diffuse or specular light effects, or change the blend of colours to make the object have a base colour other than white. This setting has no effect if dynamic lighting is disabled using the 'lighting off' attribute, or if any texture layer has a 'colour_op replace' attribute.

Default: ambient 1.0 1.0 1.0 1.0

diffuse
-------

Sets the diffuse colour reflectance properties of this pass. This attribute has no effect if a asm, CG, or HLSL shader program is used.  With GLSL, the shader can read the OpenGL material state.

Format: diffuse (<red> <green> <blue> [<alpha>]| vertexcolour)

NB valid colour values are between 0.0 and 1.0.

Example: diffuse 1.0 0.5 0.5

The base colour of a pass is determined by how much red, green and blue light is reflects at each vertex. This property determines how much diffuse light (light from instances of the Light class in the scene) is reflected. It is also possible to make the diffuse reflectance track the vertex colour as defined in the mesh by using the keyword vertexcolour instead of the colour values. The default is full white, meaning objects reflect the maximum white light they can from Light objects. This setting has no effect if dynamic lighting is disabled using the 'lighting off' attribute, or if any texture layer has a 'colour_op replace' attribute.

Default: diffuse 1.0 1.0 1.0 1.0

specular
--------

Sets the specular colour reflectance properties of this pass. This attribute has no effect if a asm, CG, or HLSL shader program is used.  With GLSL, the shader can read the OpenGL material state.

Format: specular (<red> <green> <blue> [<alpha>]| vertexcolour) <shininess>

NB valid colour values are between 0.0 and 1.0. Shininess can be any value greater than 0.

Example: specular 1.0 1.0 1.0 12.5

The base colour of a pass is determined by how much red, green and blue light is reflects at each vertex. This property determines how much specular light (highlights from instances of the Light class in the scene) is reflected. It is also possible to make the diffuse reflectance track the vertex colour as defined in the mesh by using the keyword vertexcolour instead of the colour values. The default is to reflect no specular light. The colour of the specular highlights is determined by the colour parameters, and the size of the highlights by the separate shininess parameter.. The higher the value of the shininess parameter, the sharper the highlight ie the radius is smaller.  Beware of using shininess values in the range of 0 to 1 since this causes the the specular colour to be applied to the whole surface that has the material applied to it.  When the viewing angle to the surface changes, ugly flickering will also occur when shininess is in the range of 0 to 1.  Shininess values between 1 and 128 work best in both DirectX and OpenGL renderers.  This setting has no effect if dynamic lighting is disabled using the 'lighting off' attribute, or if any texture layer has a 'colour_op replace' attribute.

Default: specular 0.0 0.0 0.0 0.0 0.0

emissive
--------

Sets the amount of self-illumination an object has. This attribute has no effect if a asm, CG, or HLSL shader program is used.  With GLSL, the shader can read the OpenGL material state.

Format: emissive (<red> <green> <blue> [<alpha>]| vertexcolour)

NB valid colour values are between 0.0 and 1.0.

Example: emissive 1.0 0.0 0.0

If an object is self-illuminating, it does not need external sources to light it, ambient or otherwise. It's like the object has it's own personal ambient light. Unlike the name suggests, this object doesn't act as a light source for other objects in the scene (if you want it to, you have to create a light which is centered on the object). It is also possible to make the emissive colour track the vertex colour as defined in the mesh by using the keyword vertexcolour instead of the colour values. This setting has no effect if dynamic lighting is disabled using the 'lighting off' attribute, or if any texture layer has a 'colour_op replace' attribute.

Default: emissive 0.0 0.0 0.0 0.0

scene_blend
-----------

Sets the kind of blending this pass has with the existing contents of the scene. Whereas the texture blending operations seen in the texture_unit entries are concerned with blending between texture layers, this blending is about combining the output of this pass as a whole with the existing contents of the rendering target. This blending therefore allows object transparency and other special effects. There are 2 formats, one using predefined blend types, the other allowing a roll-your-own approach using source and destination factors.

Format1: scene_blend <add|modulate|alpha_blend|colour_blend>

Example: scene_blend add

This is the simpler form, where the most commonly used blending modes are enumerated using a single parameter. Valid <blend_type> parameters are:

add
     The colour of the rendering output is added to the scene. Good for explosions, flares, lights, ghosts etc. Equivalent to 'scene_blend one one'.

modulate
     The colour of the rendering output is multiplied with the scene contents. Generally colours and darkens the scene, good for smoked glass, semi-transparent objects etc. Equivalent to 'scene_blend dest_colour zero'.

colour_blend
     Colour the scene based on the brightness of the input colours, but don't darken. Equivalent to 'scene_blend src_colour one_minus_src_colour'

alpha_blend
     The alpha value of the rendering output is used as a mask. Equivalent to 'scene_blend src_alpha one_minus_src_alpha'

Format2: scene_blend <src_factor> <dest_factor>

Example: scene_blend one one_minus_dest_alpha

This version of the method allows complete control over the blending operation, by specifying the source and destination blending factors. The resulting colour which is written to the rendering target is (texture * sourceFactor) + (scene_pixel * destFactor). Valid values for both parameters are:

one
     Constant value of 1.0

zero
     Constant value of 0.0

dest_colour
     The existing pixel colour

src_colour
     The texture pixel (texel) colour

one_minus_dest_colour
     1 - (dest_colour)

one_minus_src_colour
     1 - (src_colour)

dest_alpha
     The existing pixel alpha value

src_alpha
     The texel alpha value

one_minus_dest_alpha
     1 - (dest_alpha)

one_minus_src_alpha
     1 - (src_alpha)

Default: scene_blend one zero (opaque) Also see separate_scene_blend.

separate_scene_blend
--------------------

This option operates in exactly the same way as scene_blend, except that it allows you to specify the operations to perform between the rendered pixel and the frame buffer separately for colour and alpha components. By nature this option is only useful when rendering to targets which have an alpha channel which you'll use for later processing, such as a render texture.

Format1: separate_scene_blend <simple_colour_blend> <simple_alpha_blend>

Example: separate_scene_blend add modulate

This example would add colour components but multiply alpha components. The blend modes available are as in scene_blend. The more advanced form is also available:

Format2: separate_scene_blend <colour_src_factor> <colour_dest_factor> <alpha_src_factor> <alpha_dest_factor>

Example: separate_scene_blend one one_minus_dest_alpha one one

Again the options available in the second format are the same as those in the second format of scene_blend.

scene_blend_op
--------------

This directive changes the operation which is applied between the two components of the scene blending equation, which by default is 'add' (sourceFactor * source + destFactor * dest). You may change this to 'add', 'subtract', 'reverse_subtract', 'min' or 'max'.

Format: scene_blend_op <add|subtract|reverse_subtract|min|max>

Default: scene_blend_op add

separate_scene_blend_op
-----------------------

This directive is as scene_blend_op, except that you can set the operation for colour and alpha separately.

Format: separate_scene_blend_op <colourOp> <alphaOp>

Default: separate_scene_blend_op add add

depth_check
-----------

Sets whether or not this pass renders with depth-buffer checking on or not.

Format: depth_check <on|off>

If depth-buffer checking is on, whenever a pixel is about to be written to the frame buffer the depth buffer is checked to see if the pixel is in front of all other pixels written at that point. If not, the pixel is not written. If depth checking is off, pixels are written no matter what has been rendered before. Also see depth_func for more advanced depth check configuration.

Default: depth_check on

depth_write
-----------

Sets whether or not this pass renders with depth-buffer writing on or not.

Format: depth_write <on|off>

If depth-buffer writing is on, whenever a pixel is written to the frame buffer the depth buffer is updated with the depth value of that new pixel, thus affecting future rendering operations if future pixels are behind this one. If depth writing is off, pixels are written without updating the depth buffer. Depth writing should normally be on but can be turned off when rendering static backgrounds or when rendering a collection of transparent objects at the end of a scene so that they overlap each other correctly.

Default: depth_write on

depth_func
----------

Sets the function used to compare depth values when depth checking is on.

Format: depth_func <func>

If depth checking is enabled (see depth_check) a comparison occurs between the depth value of the pixel to be written and the current contents of the buffer. This comparison is normally less_equal, i.e. the pixel is written if it is closer (or at the same distance) than the current contents. The possible functions are:

always_fail
     Never writes a pixel to the render target

always_pass
     Always writes a pixel to the render target

less
     Write if (new_Z < existing_Z)

less_equal
     Write if (new_Z <= existing_Z)

equal
     Write if (new_Z == existing_Z)

not_equal
     Write if (new_Z != existing_Z)

greater_equal
     Write if (new_Z >= existing_Z)

greater
     Write if (new_Z >existing_Z)

Default: depth_func less_equal

depth_bias
----------

Sets the bias applied to the depth value of this pass. Can be used to make coplanar polygons appear on top of others e.g. for decals.

Format: depth_bias <constant_bias> [<slopescale_bias>]

The final depth bias value is constant_bias * minObservableDepth + maxSlope * slopescale_bias. Slope scale biasing is relative to the angle of the polygon to the camera, which makes for a more appropriate bias value, but this is ignored on some older hardware. Constant biasing is expressed as a factor of the minimum depth value, so a value of 1 will nudge the depth by one 'notch' if you will. Also see iteration_depth_bias

iteration_depth_bias
--------------------

Sets an additional bias derived from the number of times a given pass has been iterated. Operates just like depth_bias except that it applies an additional bias factor to the base depth_bias value, multiplying the provided value by the number of times this pass has been iterated before, through one of the iteration variants. So the first time the pass will get the depth_bias value, the second time it will get depth_bias + iteration_depth_bias, the third time it will get depth_bias + iteration_depth_bias * 2, and so on. The default is zero.

Format: iteration_depth_bias <bias_per_iteration>

alpha_rejection
---------------

Sets the way the pass will have use alpha to totally reject pixels from the pipeline.

Format: alpha_rejection <function> <value>

Example: alpha_rejection greater_equal 128

The function parameter can be any of the options listed in the material depth_function attribute. The value parameter can theoretically be any value between 0 and 255, but is best limited to 0 or 128 for hardware compatibility.

Default: alpha_rejection always_pass

alpha_to_coverage
-----------------

Sets whether this pass will use 'alpha to coverage', a way to multisample alpha texture edges so they blend more seamlessly with the background. This facility is typically only available on cards from around 2006 onwards, but it is safe to enable it anyway - Ogre will just ignore it if the hardware does not support it. The common use for alpha to coverage is foliage rendering and chain-link fence style textures.

Format: alpha_to_coverage <on|off>

Default: alpha_to_coverage off

light_scissor
-------------

Sets whether when rendering this pass, rendering will be limited to a screen-space scissor rectangle representing the coverage of the light(s) being used in this pass, derived from their attenuation ranges.

Format: light_scissor <on|off>

Default: light_scissor off

This option is usually only useful if this pass is an additive lighting pass, and is at least the second one in the technique. Ie areas which are not affected by the current light(s) will never need to be rendered. If there is more than one light being passed to the pass, then the scissor is defined to be the rectangle which covers all lights in screen-space. Directional lights are ignored since they are infinite.

This option does not need to be specified if you are using a standard additive shadow mode, i.e. SHADOWTYPE_STENCIL_ADDITIVE or SHADOWTYPE_TEXTURE_ADDITIVE, since it is the default behaviour to use a scissor for each additive shadow pass. However, if you're not using shadows, or you're using Integrated Texture Shadows where passes are specified in a custom manner, then this could be of use to you.

light_clip_planes
-----------------

Sets whether when rendering this pass, triangle setup will be limited to clipping volume covered by the light. Directional lights are ignored, point lights clip to a cube the size of the attenuation range or the light, and spotlights clip to a pyramid bounding the spotlight angle and attenuation range.

Format: light_clip_planes <on|off>

Default: light_clip_planes off

This option will only function if there is a single non-directional light being used in this pass. If there is more than one light, or only directional lights, then no clipping will occur. If there are no lights at all then the objects won't be rendered at all.

When using a standard additive shadow mode, ie SHADOWTYPE_STENCIL_ADDITIVE or SHADOWTYPE_TEXTURE_ADDITIVE, you have the option of enabling clipping for all light passes by calling SceneManager::setShadowUseLightClipPlanes regardless of this pass setting, since rendering is done lightwise anyway. This is off by default since using clip planes is not always faster - it depends on how much of the scene the light volumes cover. Generally the smaller your lights are the more chance you'll see a benefit rather than a penalty from clipping. If you're not using shadows, or you're using Integrated Texture Shadows where passes are specified in a custom manner, then specify the option per-pass using this attribute.

A specific note about OpenGL: user clip planes are completely ignored when you use an ARB vertex program. This means light clip planes won't help much if you use ARB vertex programs on GL, although OGRE will perform some optimisation of its own, in that if it sees that the clip volume is completely off-screen, it won't perform a render at all. When using GLSL, user clipping can be used but you have to use glClipVertex in your shader, see the GLSL documentation for more information. In Direct3D user clip planes are always respected.

illumination_stage
------------------

When using an additive lighting mode (SHADOWTYPE_STENCIL_ADDITIVE or SHADOWTYPE_TEXTURE_ADDITIVE), the scene is rendered in 3 discrete stages, ambient (or pre-lighting), per-light (once per light, with shadowing) and decal (or post-lighting). Usually OGRE figures out how to categorise your passes automatically, but there are some effects you cannot achieve without manually controlling the illumination. For example specular effects are muted by the typical sequence because all textures are saved until the 'decal' stage which mutes the specular effect. Instead, you could do texturing within the per-light stage if it's possible for your material and thus add the specular on after the decal texturing, and have no post-light rendering.

If you assign an illumination stage to a pass you have to assign it to all passes in the technique otherwise it will be ignored. Also note that whilst you can have more than one pass in each group, they cannot alternate, ie all ambient passes will be before all per-light passes, which will also be before all decal passes. Within their categories the passes will retain their ordering though.

Format: illumination_stage <ambient|per_light|decal>

Default: none (autodetect)

normalise_normals
-----------------

Sets whether or not this pass renders with all vertex normals being automatically re-normalised.

Format: normalise_normals <on|off>

Scaling objects causes normals to also change magnitude, which can throw off your lighting calculations. By default, the SceneManager detects this and will automatically re-normalise normals for any scaled object, but this has a cost. If you'd prefer to control this manually, call SceneManager::setNormaliseNormalsOnScale(false) and then use this option on materials which are sensitive to normals being resized.

Default: normalise_normals off

transparent_sorting
-------------------

Sets if transparent textures should be sorted by depth or not.

Format: transparent_sorting <on|off|force>

By default all transparent materials are sorted such that renderables furthest away from the camera are rendered first. This is usually the desired behaviour but in certain cases this depth sorting may be unnecessary and undesirable. If for example it is necessary to ensure the rendering order does not change from one frame to the next. In this case you could set the value to 'off' to prevent sorting.

You can also use the keyword 'force' to force transparent sorting on, regardless of other circumstances. Usually sorting is only used when the pass is also transparent, and has a depth write or read which indicates it cannot reliably render without sorting. By using 'force', you tell OGRE to sort this pass no matter what other circumstances are present.

Default: transparent_sorting on

cull_hardware
-------------

Sets the hardware culling mode for this pass.

Format: cull_hardware <clockwise|anticlockwise|none>

A typical way for the hardware rendering engine to cull triangles is based on the 'vertex winding' of triangles. Vertex winding refers to the direction in which the vertices are passed or indexed to in the rendering operation as viewed from the camera, and will wither be clockwise or anticlockwise (that's 'counterclockwise' for you Americans out there ;). If the option 'cull_hardware clockwise' is set, all triangles whose vertices are viewed in clockwise order from the camera will be culled by the hardware. 'anticlockwise' is the reverse (obviously), and 'none' turns off hardware culling so all triagles are rendered (useful for creating 2-sided passes).

Default: cull_hardware clockwise

NB this is the same as OpenGL's default but the opposite of Direct3D's default (because Ogre uses a right-handed coordinate system like OpenGL).

cull_software
-------------

Sets the software culling mode for this pass.

Format: cull_software <back|front|none>

In some situations the engine will also cull geometry in software before sending it to the hardware renderer. This setting only takes effect on SceneManager's that use it (since it is best used on large groups of planar world geometry rather than on movable geometry since this would be expensive), but if used can cull geometry before it is sent to the hardware. In this case the culling is based on whether the 'back' or 'front' of the triangle is facing the camera - this definition is based on the face normal (a vector which sticks out of the front side of the polygon perpendicular to the face). Since Ogre expects face normals to be on anticlockwise side of the face, 'cull_software back' is the software equivalent of 'cull_hardware clockwise' setting, which is why they are both the default. The naming is different to reflect the way the culling is done though, since most of the time face normals are pre-calculated and they don't have to be the way Ogre expects - you could set 'cull_hardware none' and completely cull in software based on your own face normals, if you have the right SceneManager which uses them.

Default: cull_software back

lighting
--------

Sets whether or not dynamic lighting is turned on for this pass or not. If lighting is turned off, all objects rendered using the pass will be fully lit. This attribute has no effect if a vertex program is used.

Format: lighting <on|off>

Turning dynamic lighting off makes any ambient, diffuse, specular, emissive and shading properties for this pass redundant. When lighting is turned on, objects are lit according to their vertex normals for diffuse and specular light, and globally for ambient and emissive.

Default: lighting on

shading
-------

Sets the kind of shading which should be used for representing dynamic lighting for this pass.

Format: shading <flat|gouraud|phong>

When dynamic lighting is turned on, the effect is to generate colour values at each vertex. Whether these values are interpolated across the face (and how) depends on this setting.

flat
     No interpolation takes place. Each face is shaded with a single colour determined from the first vertex in the face.

gouraud
     Colour at each vertex is linearly interpolated across the face.

phong
     Vertex normals are interpolated across the face, and these are used to determine colour at each pixel. Gives a more natural lighting effect but is more expensive and works better at high levels of tessellation. Not supported on all hardware.

Default: shading gouraud

polygon_mode
------------

Sets how polygons should be rasterised, i.e. whether they should be filled in, or just drawn as lines or points.

Format: polygon_mode <solid|wireframe|points>

solid
     The normal situation - polygons are filled in.

wireframe
     Polygons are drawn in outline only.

points
     Only the points of each polygon are rendered.

Default: polygon_mode solid

polygon_mode_overrideable
-------------------------

Sets whether or not the polygon_mode set on this pass can be downgraded by the camera, if the camera itself is set to a lower polygon mode. If set to false, this pass will always be rendered at its own chosen polygon mode no matter what the camera says. The default is true.

Format: polygon_mode_overrideable <true|false>

fog_override
------------

Tells the pass whether it should override the scene fog settings, and enforce it's own. Very useful for things that you don't want to be affected by fog when the rest of the scene is fogged, or vice versa. Note that this only affects fixed-function fog - the original scene fog parameters are still sent to shaders which use the fog_params parameter binding (this allows you to turn off fixed function fog and calculate it in the shader instead; if you want to disable shader fog you can do that through shader parameters anyway).

Format: fog_override <override?> [<type> <colour> <density> <start> <end>]

Default: fog_override false

If you specify 'true' for the first parameter and you supply the rest of the parameters, you are telling the pass to use these fog settings in preference to the scene settings, whatever they might be. If you specify 'true' but provide no further parameters, you are telling this pass to never use fogging no matter what the scene says. Here is an explanation of the parameters:

type
     none = No fog, equivalent of just using 'fog_override true'

     linear = Linear fog from the <start> and <end> distances

     exp = Fog increases exponentially from the camera (fog = 1/e^(distance * density)), use <density> param to control it

     exp2 = Fog increases at the square of FOG_EXP, i.e. even quicker (fog = 1/e^(distance * density)^2), use <density> param to control it

colour
     Sequence of 3 floating point values from 0 to 1 indicating the red, green and blue intensities

density
     The density parameter used in the 'exp' or 'exp2' fog types. Not used in linear mode but param must still be there as a placeholder

start
     The start distance from the camera of linear fog. Must still be present in other modes, even though it is not used.

end
     The end distance from the camera of linear fog. Must still be present in other modes, even though it is not used.

Example: fog_override true exp 1 1 1 0.002 100 10000

colour_write
------------

Sets whether or not this pass renders with colour writing on or not.

Format: colour_write <on|off>

If colour writing is off no visible pixels are written to the screen during this pass. You might think this is useless, but if you render with colour writing off, and with very minimal other settings, you can use this pass to initialise the depth buffer before subsequently rendering other passes which fill in the colour data. This can give you significant performance boosts on some newer cards, especially when using complex fragment programs, because if the depth check fails then the fragment program is never run.

Default: colour_write on

start_light
-----------

Sets the first light which will be considered for use with this pass.

Format: start_light <number>

You can use this attribute to offset the starting point of the lights for this pass. In other words, if you set start_light to 2 then the first light to be processed in that pass will be the third actual light in the applicable list. You could use this option to use different passes to process the first couple of lights versus the second couple of lights for example, or use it in conjunction with the iteration option to start the iteration from a given point in the list (e.g. doing the first 2 lights in the first pass, and then iterating every 2 lights from then on perhaps).

Default: start_light 0

max_lights
----------

Sets the maximum number of lights which will be considered for use with this pass.

Format: max_lights <number>

The maximum number of lights which can be used when rendering fixed-function materials is set by the rendering system, and is typically set at 8. When you are using the programmable pipeline (see Using Vertex/Geometry/Fragment Programs in a Pass) this limit is dependent on the program you are running, or, if you use 'iteration once_per_light' or a variant (see iteration), it effectively only bounded by the number of passes you are willing to use. If you are not using pass iteration, the light limit applies once for this pass. If you are using pass iteration, the light limit applies across all iterations of this pass - for example if you have 12 lights in range with an 'iteration once_per_light' setup but your max_lights is set to 4 for that pass, the pass will only iterate 4 times.

Default: max_lights 8

iteration
---------

Sets whether or not this pass is iterated, i.e. issued more than once.

Format 1: iteration <once | once_per_light> [lightType]

Format 2: iteration <number> [<per_light> [lightType]]

Format 3: iteration <number> [<per_n_lights> <num_lights> [lightType]]

Examples:

iteration once
     The pass is only executed once which is the default behaviour.

iteration once_per_light point
     The pass is executed once for each point light.

iteration 5
     The render state for the pass will be setup and then the draw call will execute 5 times.

iteration 5 per_light point
     The render state for the pass will be setup and then the draw call will execute 5 times.  This will be done for each point light.

iteration 1 per_n_lights 2 point
     The render state for the pass will be setup and the draw call executed once for every 2 lights.

By default, passes are only issued once. However, if you use the programmable pipeline, or you wish to exceed the normal limits on the number of lights which are supported, you might want to use the once_per_light option. In this case, only light index 0 is ever used, and the pass is issued multiple times, each time with a different light in light index 0. Clearly this will make the pass more expensive, but it may be the only way to achieve certain effects such as per-pixel lighting effects which take into account 1..n lights.

Using a number instead of "once" instructs the pass to iterate more than once after the render state is setup.  The render state is not changed after the initial setup so repeated draw calls are very fast and ideal for passes using programmable shaders that must iterate more than once with the same render state i.e. shaders that do fur, motion blur, special filtering.

If you use once_per_light, you should also add an ambient pass to the technique before this pass, otherwise when no lights are in range of this object it will not get rendered at all; this is important even when you have no ambient light in the scene, because you would still want the objects silhouette to appear.

The lightType parameter to the attribute only applies if you use once_per_light, per_light, or per_n_lights and restricts the pass to being run for lights of a single type (either 'point', 'directional' or 'spot'). In the example, the pass will be run once per point light. This can be useful because when you're writing a vertex / fragment program it is a lot easier if you can assume the kind of lights you'll be dealing with. However at least point and directional lights can be dealt with in one way. Default: iteration once

Example: Simple Fur shader material script that uses a second pass with 10 iterations to grow the fur:

     // GLSL simple Fur
     vertex_program GLSLDemo/FurVS glsl
     {
       source fur.vert
       default_params
       {
         param_named_auto lightPosition light_position_object_space 0
         param_named_auto eyePosition camera_position_object_space
         param_named_auto passNumber pass_number
         param_named_auto multiPassNumber pass_iteration_number
         param_named furLength float 0.15
       }
     }

     fragment_program GLSLDemo/FurFS glsl
     {
       source fur.frag
       default_params
       {
         param_named Ka float 0.2
         param_named Kd float 0.5
         param_named Ks float 0.0
         param_named furTU int 0
       }
     }

     material Fur
     {
       technique GLSL
       {
         pass base_coat
         {
           ambient 0.7 0.7 0.7
           diffuse 0.5 0.8 0.5
           specular 1.0 1.0 1.0 1.5

           vertex_program_ref GLSLDemo/FurVS
           {
           }

           fragment_program_ref GLSLDemo/FurFS
           {
           }

           texture_unit
           {
             texture Fur.tga
             tex_coord_set 0
             filtering trilinear
           }

         }

         pass grow_fur
         {
           ambient 0.7 0.7 0.7
           diffuse 0.8 1.0 0.8
           specular 1.0 1.0 1.0 64
           depth_write off

           scene_blend src_alpha one
           iteration 10

           vertex_program_ref GLSLDemo/FurVS
           {
           }

           fragment_program_ref GLSLDemo/FurFS
           {
           }

           texture_unit
           {
             texture Fur.tga
             tex_coord_set 0
             filtering trilinear
           }
         }
       }
     }

Note: use gpu program auto parameters pass_number and pass_iteration_number to tell the vertex, geometry or fragment program the pass number and iteration number.

point_size
----------

This setting allows you to change the size of points when rendering a point list, or a list of point sprites. The interpretation of this command depends on the point_size_attenuation option - if it is off (the default), the point size is in screen pixels, if it is on, it expressed as normalised screen coordinates (1.0 is the height of the screen) when the point is at the origin.

NOTE: Some drivers have an upper limit on the size of points they support - this can even vary between APIs on the same card! Don't rely on point sizes that cause the points to get very large on screen, since they may get clamped on some cards. Upper sizes can range from 64 to 256 pixels.

Format: point_size <size>

Default: point_size 1.0

point_sprites
-------------

This setting specifies whether or not hardware point sprite rendering is enabled for this pass. Enabling it means that a point list is rendered as a list of quads rather than a list of dots. It is very useful to use this option if you're using a BillboardSet and only need to use point oriented billboards which are all of the same size. You can also use it for any other point list render.

Format: point_sprites <on|off>

Default: point_sprites off

point_size_attenuation
----------------------

Defines whether point size is attenuated with view space distance, and in what fashion. This option is especially useful when you're using point sprites (see point_sprites) since it defines how they reduce in size as they get further away from the camera. You can also disable this option to make point sprites a constant screen size (like points), or enable it for points so they change size with distance.

You only have to provide the final 3 parameters if you turn attenuation on. The formula for attenuation is that the size of the point is multiplied by 1 / (constant + linear * dist + quadratic * d^2); therefore turning it off is equivalent to (constant = 1, linear = 0, quadratic = 0) and standard perspective attenuation is (constant = 0, linear = 1, quadratic = 0). The latter is assumed if you leave out the final 3 parameters when you specify 'on'.

Note that the resulting attenuated size is clamped to the minimum and maximum point size, see the next section.

Format: point_size_attenuation <on|off> [constant linear quadratic] Default: point_size_attenuation off

point_size_min
--------------

Sets the minimum point size after attenuation (point_size_attenuation). For details on the size metrics, see point_size.

Format: point_size_min <size> Default: point_size_min 0

point_size_max
--------------

Sets the maximum point size after attenuation (point_size_attenuation). For details on the size metrics, see point_size. A value of 0 means the maximum is set to the same as the max size reported by the current card.

Format: point_size_max <size> Default: point_size_max 0

Texture Units
-------------

Here are the attributes you can use in a 'texture_unit' section of a .material script:

Available Texture Layer Attributes
==================================

  * texture_alias

  * texture

  * anim_texture

  * cubic_texture

  * tex_coord_set

  * tex_address_mode

  * tex_border_colour

  * filtering

  * max_anisotropy

  * mipmap_bias

  * colour_op

  * colour_op_ex

  * colour_op_multipass_fallback

  * alpha_op_ex

  * env_map

  * scroll

  * scroll_anim

  * rotate

  * rotate_anim

  * scale

  * wave_xform

  * transform

  * binding_type

  * content_type

You can also use a nested 'texture_source' section in order to use a special add-in as a source of texture data, see External Texture Sources for details.

Attribute Descriptions
======================

texture_alias
-------------

Sets the alias name for this texture unit.

Format: texture_alias <name>

Example: texture_alias NormalMap

Setting the texture alias name is useful if this material is to be inherited by other other materials and only the textures will be changed in the new material.(see Texture Aliases)

Default: If a texture_unit has a name then the texture_alias defaults to the texture_unit name.

texture
-------

Sets the name of the static texture image this layer will use.

Format: texture <texturename> [<type>] [unlimited | numMipMaps] [alpha] [<PixelFormat>] [gamma]

Example: texture funkywall.jpg

This setting is mutually exclusive with the anim_texture attribute. Note that the texture file cannot include spaces. Those of you Windows users who like spaces in filenames, please get over it and use underscores instead.

The 'type' parameter allows you to specify a the type of texture to create - the default is '2d', but you can override this; here's the full list:

1d
     A 1-dimensional texture; that is, a texture which is only 1 pixel high. These kinds of textures can be useful when you need to encode a function in a texture and use it as a simple lookup, perhaps in a fragment program. It is important that you use this setting when you use a fragment program which uses 1-dimensional texture coordinates, since GL requires you to use a texture type that matches (D3D will let you get away with it, but you ought to plan for cross-compatibility). Your texture widths should still be a power of 2 for best compatibility and performance.

2d
     The default type which is assumed if you omit it, your texture has a width and a height, both of which should preferably be powers of 2, and if you can, make them square because this will look best on the most hardware. These can be addressed with 2D texture coordinates.

3d
     A 3 dimensional texture i.e. volume texture. Your texture has a width, a height, both of which should be powers of 2, and has depth. These can be addressed with 3d texture coordinates i.e. through a pixel shader.

cubic
     This texture is made up of 6 2D textures which are pasted around the inside of a cube. Can be addressed with 3D texture coordinates and are useful for cubic reflection maps and normal maps.

The 'numMipMaps' option allows you to specify the number of mipmaps to generate for this texture. The default is 'unlimited' which means mips down to 1x1 size are generated. You can specify a fixed number (even 0) if you like instead. Note that if you use the same texture in many material scripts, the number of mipmaps generated will conform to the number specified in the first texture_unit used to load the texture - so be consistent with your usage.

The 'alpha' option allows you to specify that a single channel (luminance) texture should be loaded as alpha, rather than the default which is to load it into the red channel. This can be helpful if you want to use alpha-only textures in the fixed function pipeline.

Default: none

The <PixelFormat> option allows you to specify the desired pixel format of the texture to create, which may be different to the pixel format of the texture file being loaded. Bear in mind that the final pixel format will be constrained by hardware capabilities so you may not get exactly what you ask for. The available options are:

PF_L8
     8-bit pixel format, all bits luminance.

PF_L16
     16-bit pixel format, all bits luminance.

PF_A8
     8-bit pixel format, all bits alpha.

PF_A4L4
     8-bit pixel format, 4 bits alpha, 4 bits luminance.

PF_BYTE_LA
     2 byte pixel format, 1 byte luminance, 1 byte alpha

PF_R5G6B5
     16-bit pixel format, 5 bits red, 6 bits green, 5 bits blue.

PF_B5G6R5
     16-bit pixel format, 5 bits blue, 6 bits green, 5 bits red.

PF_R3G3B2
     8-bit pixel format, 3 bits red, 3 bits green, 2 bits blue.

PF_A4R4G4B4
     16-bit pixel format, 4 bits for alpha, red, green and blue.

PF_A1R5G5B5
     16-bit pixel format, 1 bit for alpha, 5 bits for red, green and blue.

PF_R8G8B8
     24-bit pixel format, 8 bits for red, green and blue.

PF_B8G8R8
     24-bit pixel format, 8 bits for blue, green and red.

PF_A8R8G8B8
     32-bit pixel format, 8 bits for alpha, red, green and blue.

PF_A8B8G8R8
     32-bit pixel format, 8 bits for alpha, blue, green and red.

PF_B8G8R8A8
     32-bit pixel format, 8 bits for blue, green, red and alpha.

PF_R8G8B8A8
     32-bit pixel format, 8 bits for red, green, blue and alpha.

PF_X8R8G8B8
     32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue like PF_A8R8G8B8, but alpha will get discarded

PF_X8B8G8R8
     32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red like PF_A8B8G8R8, but alpha will get discarded

PF_A2R10G10B10
     32-bit pixel format, 2 bits for alpha, 10 bits for red, green and blue.

PF_A2B10G10R10
     32-bit pixel format, 2 bits for alpha, 10 bits for blue, green and red.

PF_FLOAT16_R
     16-bit pixel format, 16 bits (float) for red

PF_FLOAT16_RGB
     48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue

PF_FLOAT16_RGBA
     64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue, 16 bits (float) for alpha

PF_FLOAT32_R
     16-bit pixel format, 16 bits (float) for red

PF_FLOAT32_RGB
     96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue

PF_FLOAT32_RGBA
     128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, 32 bits (float) for alpha

PF_SHORT_RGBA
     64-bit pixel format, 16 bits for red, green, blue and alpha

The 'gamma' option informs the renderer that you want the graphics hardware to perform gamma correction on the texture values as they are sampled for rendering. This is only applicable for textures which have 8-bit colour channels (e.g.PF_R8G8B8). Often, 8-bit per channel textures will be stored in gamma space in order to increase the precision of the darker colours (http://en.wikipedia.org/wiki/Gamma_correction) but this can throw out blending and filtering calculations since they assume linear space colour values. For the best quality shading, you may want to enable gamma correction so that the hardware converts the texture values to linear space for you automatically when sampling the texture, then the calculations in the pipeline can be done in a reliable linear colour space. When rendering to a final 8-bit per channel display, you'll also want to convert back to gamma space which can be done in your shader (by raising to the power 1/2.2) or you can enable gamma correction on the texture being rendered to or the render window. Note that the 'gamma' option on textures is applied on loading the texture so must be specified consistently if you use this texture in multiple places.

anim_texture
------------

Sets the images to be used in an animated texture layer. In this case an animated texture layer means one which has multiple frames, each of which is a separate image file. There are 2 formats, one for implicitly determined image names, one for explicitly named images.

Format1 (short): anim_texture <base_name> <num_frames> <duration>

Example: anim_texture flame.jpg 5 2.5

This sets up an animated texture layer made up of 5 frames named flame_0.jpg, flame_1.jpg, flame_2.jpg etc, with an animation length of 2.5 seconds (2fps). If duration is set to 0, then no automatic transition takes place and frames must be changed manually in code.

Format2 (long): anim_texture <frame1> <frame2> ... <duration>

Example: anim_texture flamestart.jpg flamemore.png flameagain.jpg moreflame.jpg lastflame.tga 2.5

This sets up the same duration animation but from 5 separately named image files. The first format is more concise, but the second is provided if you cannot make your images conform to the naming standard required for it.

Default: none

cubic_texture
-------------

Sets the images used in a cubic texture, i.e. one made up of 6 individual images making up the faces of a cube. These kinds of textures are used for reflection maps (if hardware supports cubic reflection maps) or skyboxes. There are 2 formats, a brief format expecting image names of a particular format and a more flexible but longer format for arbitrarily named textures.

Format1 (short): cubic_texture <base_name> <combinedUVW|separateUV>

The base_name in this format is something like 'skybox.jpg', and the system will expect you to provide skybox_fr.jpg, skybox_bk.jpg, skybox_up.jpg, skybox_dn.jpg, skybox_lf.jpg, and skybox_rt.jpg for the individual faces.

Format2 (long): cubic_texture <front> <back> <left> <right> <up> <down> separateUV

In this case each face is specified explicitly, incase you don't want to conform to the image naming standards above. You can only use this for the separateUV version since the combinedUVW version requires a single texture name to be assigned to the combined 3D texture (see below).

In both cases the final parameter means the following:

combinedUVW
     The 6 textures are combined into a single 'cubic' texture map which is then addressed using 3D texture coordinates with U, V and W components. Necessary for reflection maps since you never know which face of the box you are going to need. Note that not all cards support cubic environment mapping.

separateUV
     The 6 textures are kept separate but are all referenced by this single texture layer. One texture at a time is active (they are actually stored as 6 frames), and they are addressed using standard 2D UV coordinates. This type is good for skyboxes since only one face is rendered at one time and this has more guaranteed hardware support on older cards.

Default: none

binding_type
------------

Tells this texture unit to bind to either the fragment processing unit or the vertex processing unit (for Vertex Texture Fetch).

Format: binding_type <vertex|fragment> Default: binding_type fragment

content_type
------------

Tells this texture unit where it should get its content from. The default is to get texture content from a named texture, as defined with the texture, cubic_texture, anim_texture attributes. However you can also pull texture information from other automated sources. The options are:

named
     The default option, this derives texture content from a texture name, loaded by ordinary means from a file or having been manually created with a given name.

shadow
     This option allows you to pull in a shadow texture, and is only valid when you use texture shadows and one of the 'custom sequence' shadowing types (see Shadows). The shadow texture in question will be from the 'n'th closest light that casts shadows, unless you use light-based pass iteration or the light_start option which may start the light index higher. When you use this option in multiple texture units within the same pass, each one references the next shadow texture. The shadow texture index is reset in the next pass, in case you want to take into account the same shadow textures again in another pass (e.g. a separate specular / gloss pass). By using this option, the correct light frustum projection is set up for you for use in fixed-function, if you use shaders just reference the texture_viewproj_matrix auto parameter in your shader.

compositor
     This option allows you to reference a texture from a compositor, and is only valid when the pass is rendered within a compositor sequence. This can be either in a render_scene directive inside a compositor script, or in a general pass in a viewport that has a compositor attached. Note that this is a reference only, meaning that it does not change the render order. You must make sure that the order is reasonable for what you are trying to achieve (for example, texture pooling might cause the referenced texture to be overwritten by something else by the time it is referenced).

     The extra parameters for the content_type are only required for this type:

     The first is the name of the compositor being referenced. (Required)

     The second is the name of the texture to reference in the compositor. (Required)

     The third is the index of the texture to take, in case of an MRT. (Optional)

Format: content_type <named|shadow|compositor> [<Referenced Compositor Name>] [<Referenced Texture Name>] [<Referenced MRT Index>]

Default: content_type named

Example: content_type compositor DepthCompositor OutputTexture

tex_coord_set
-------------

Sets which texture coordinate set is to be used for this texture layer. A mesh can define multiple sets of texture coordinates, this sets which one this material uses.

Format: tex_coord_set <set_num>

Example: tex_coord_set 2

Default: tex_coord_set 0

tex_address_mode
----------------

Defines what happens when texture coordinates exceed 1.0 for this texture layer.You can use the simple format to specify the addressing mode for all 3 potential texture coordinates at once, or you can use the 2/3 parameter extended format to specify a different mode per texture coordinate.

Simple Format: tex_address_mode <uvw_mode>

Extended Format: tex_address_mode <u_mode> <v_mode> [<w_mode>]

wrap
     Any value beyond 1.0 wraps back to 0.0. Texture is repeated.

clamp
     Values beyond 1.0 are clamped to 1.0. Texture 'streaks' beyond 1.0 since last line of pixels is used across the rest of the address space. Useful for textures which need exact coverage from 0.0 to 1.0 without the 'fuzzy edge' wrap gives when combined with filtering.

mirror
     Texture flips every boundary, meaning texture is mirrored every 1.0 u or v

border
     Values outside the range [0.0, 1.0] are set to the border colour, you might also set the tex_border_colour attribute too.

Default: tex_address_mode wrap

tex_border_colour
-----------------

Sets the border colour of border texture address mode (see tex_address_mode).

Format: tex_border_colour <red> <green> <blue> [<alpha>]

NB valid colour values are between 0.0 and 1.0.

Example: tex_border_colour 0.0 1.0 0.3

Default: tex_border_colour 0.0 0.0 0.0 1.0

filtering
---------

Sets the type of texture filtering used when magnifying or minifying a texture. There are 2 formats to this attribute, the simple format where you simply specify the name of a predefined set of filtering options, and the complex format, where you individually set the minification, magnification, and mip filters yourself.

Simple Format

Format: filtering <none|bilinear|trilinear|anisotropic>

Default: filtering bilinear

With this format, you only need to provide a single parameter which is one of the following:

none
     No filtering or mipmapping is used. This is equivalent to the complex format 'filtering point point none'.

bilinear
     2x2 box filtering is performed when magnifying or reducing a texture, and a mipmap is picked from the list but no filtering is done between the levels of the mipmaps. This is equivalent to the complex format 'filtering linear linear point'.

trilinear
     2x2 box filtering is performed when magnifying and reducing a texture, and the closest 2 mipmaps are filtered together. This is equivalent to the complex format 'filtering linear linear linear'.

anisotropic
     This is the same as 'trilinear', except the filtering algorithm takes account of the slope of the triangle in relation to the camera rather than simply doing a 2x2 pixel filter in all cases. This makes triangles at acute angles look less fuzzy. Equivalent to the complex format 'filtering anisotropic anisotropic linear'. Note that in order for this to make any difference, you must also set the max_anisotropy attribute too.

Complex Format

Format: filtering <minification> <magnification> <mip>

Default: filtering linear linear point

This format gives you complete control over the minification, magnification, and mip filters. Each parameter can be one of the following:

none
     Nothing - only a valid option for the 'mip' filter , since this turns mipmapping off completely. The lowest setting for min and mag is 'point'.

point
     Pick the closet pixel in min or mag modes. In mip mode, this picks the closet matching mipmap.

linear
     Filter a 2x2 box of pixels around the closest one. In the 'mip' filter this enables filtering between mipmap levels.

anisotropic
     Only valid for min and mag modes, makes the filter compensate for camera-space slope of the triangles. Note that in order for this to make any difference, you must also set the max_anisotropy attribute too.

max_anisotropy
--------------

Sets the maximum degree of anisotropy that the renderer will try to compensate for when filtering textures. The degree of anisotropy is the ratio between the height of the texture segment visible in a screen space region versus the width - so for example a floor plane, which stretches on into the distance and thus the vertical texture coordinates change much faster than the horizontal ones, has a higher anisotropy than a wall which is facing you head on (which has an anisotropy of 1 if your line of sight is perfectly perpendicular to it). You should set the max_anisotropy value to something greater than 1 to begin compensating; higher values can compensate for more acute angles. The maximum value is determined by the hardware, but it is usually 8 or 16.

In order for this to be used, you have to set the minification and/or the magnification filtering option on this texture to anisotropic.

Format: max_anisotropy <value>

Default: max_anisotropy 1

mipmap_bias
-----------

Sets the bias value applied to the mipmapping calculation, thus allowing you to alter the decision of which level of detail of the texture to use at any distance. The bias value is applied after the regular distance calculation, and adjusts the mipmap level by 1 level for each unit of bias. Negative bias values force larger mip levels to be used, positive bias values force smaller mip levels to be used. The bias is a floating point value so you can use values in between whole numbers for fine tuning.

In order for this option to be used, your hardware has to support mipmap biasing (exposed through the render system capabilities), and your minification filtering has to be set to point or linear.

Format: mipmap_bias <value>

Default: mipmap_bias 0

colour_op
---------

Determines how the colour of this texture layer is combined with the one below it (or the lighting effect on the geometry if this is the first layer).

Note: Only applies to the fixed-function pipeline, if you're using a fragment program this will have no effect.

Format: colour_op <replace|add|modulate|alpha_blend>

This method is the simplest way to blend texture layers, because it requires only one parameter, gives you the most common blending types, and automatically sets up 2 blending methods: one for if single-pass multitexturing hardware is available, and another for if it is not and the blending must be achieved through multiple rendering passes. It is, however, quite limited and does not expose the more flexible multitexturing operations, simply because these can't be automatically supported in multipass fallback mode. If want to use the fancier options, use colour_op_ex, but you'll either have to be sure that enough multitexturing units will be available, or you should explicitly set a fallback using colour_op_multipass_fallback.

replace
     Replace all colour with texture with no adjustment.

add
     Add colour components together.

modulate
     Multiply colour components together.

alpha_blend
     Blend based on texture alpha.

Default: colour_op modulate

colour_op_ex
------------

This is an extended version of the colour_op attribute which allows extremely detailed control over the blending applied between this and earlier layers. Multitexturing hardware can apply more complex blending operations that multipass blending, but you are limited to the number of texture units which are available in hardware.

Note: Only applies to the fixed-function pipeline, if you're using a fragment program this will have no effect.

Format: colour_op_ex <operation> <source1> <source2> [<manual_factor>] [<manual_colour1>] [<manual_colour2>]

Example colour_op_ex add_signed src_manual src_current 0.5

See the IMPORTANT note below about the issues between multipass and multitexturing that using this method can create. Texture colour operations determine how the final colour of the surface appears when rendered. Texture units are used to combine colour values from various sources (e.g. the diffuse colour of the surface from lighting calculations, combined with the colour of the texture). This method allows you to specify the 'operation' to be used, i.e. the calculation such as adds or multiplies, and which values to use as arguments, such as a fixed value or a value from a previous calculation.

Operation options

     source1
          Use source1 without modification

     source2
          Use source2 without modification

     modulate
          Multiply source1 and source2 together.

     modulate_x2
          Multiply source1 and source2 together, then by 2 (brightening).

     modulate_x4
          Multiply source1 and source2 together, then by 4 (brightening).

     add
          Add source1 and source2 together.

     add_signed
          Add source1 and source2 then subtract 0.5.

     add_smooth
          Add source1 and source2, subtract the product

     subtract
          Subtract source2 from source1

     blend_diffuse_alpha
          Use interpolated alpha value from vertices to scale source1, then add source2 scaled by (1-alpha).

     blend_texture_alpha
          As blend_diffuse_alpha but use alpha from texture

     blend_current_alpha
          As blend_diffuse_alpha but use current alpha from previous stages (same as blend_diffuse_alpha for first layer)

     blend_manual
          As blend_diffuse_alpha but use a constant manual alpha value specified in <manual>

     dotproduct
          The dot product of source1 and source2

     blend_diffuse_colour
          Use interpolated colour value from vertices to scale source1, then add source2 scaled by (1-colour).

Source1 and source2 options

     src_current
          The colour as built up from previous stages.

     src_texture
          The colour derived from the texture assigned to this layer.

     src_diffuse
          The interpolated diffuse colour from the vertices (same as 'src_current' for first layer).

     src_specular
          The interpolated specular colour from the vertices.

     src_manual
          The manual colour specified at the end of the command.

For example 'modulate' takes the colour results of the previous layer, and multiplies them with the new texture being applied. Bear in mind that colours are RGB values from 0.0-1.0 so multiplying them together will result in values in the same range, 'tinted' by the multiply. Note however that a straight multiply normally has the effect of darkening the textures - for this reason there are brightening operations like modulate_x2. Note that because of the limitations on some underlying APIs (Direct3D included) the 'texture' argument can only be used as the first argument, not the second.

Note that the last parameter is only required if you decide to pass a value manually into the operation. Hence you only need to fill these in if you use the 'blend_manual' operation.

IMPORTANT: Ogre tries to use multitexturing hardware to blend texture layers together. However, if it runs out of texturing units (e.g. 2 of a GeForce2, 4 on a GeForce3) it has to fall back on multipass rendering, i.e. rendering the same object multiple times with different textures. This is both less efficient and there is a smaller range of blending operations which can be performed. For this reason, if you use this method you really should set the colour_op_multipass_fallback attribute to specify which effect you want to fall back on if sufficient hardware is not available (the default is just 'modulate' which is unlikely to be what you want if you're doing swanky blending here). If you wish to avoid having to do this, use the simpler colour_op attribute which allows less flexible blending options but sets up the multipass fallback automatically, since it only allows operations which have direct multipass equivalents.

Default: none (colour_op modulate)

colour_op_multipass_fallback
----------------------------

Sets the multipass fallback operation for this layer, if you used colour_op_ex and not enough multitexturing hardware is available.

Format: colour_op_multipass_fallback <src_factor> <dest_factor>

Example: colour_op_multipass_fallback one one_minus_dest_alpha

Because some of the effects you can create using colour_op_ex are only supported under multitexturing hardware, if the hardware is lacking the system must fallback on multipass rendering, which unfortunately doesn't support as many effects. This attribute is for you to specify the fallback operation which most suits you.

The parameters are the same as in the scene_blend attribute; this is because multipass rendering IS effectively scene blending, since each layer is rendered on top of the last using the same mechanism as making an object transparent, it's just being rendered in the same place repeatedly to get the multitexture effect. If you use the simpler (and less flexible) colour_op attribute you don't need to call this as the system sets up the fallback for you.

alpha_op_ex
-----------

Behaves in exactly the same away as colour_op_ex except that it determines how alpha values are combined between texture layers rather than colour values.The only difference is that the 2 manual colours at the end of colour_op_ex are just single floating-point values in alpha_op_ex. Note: Only applies to the fixed-function pipeline, if you're using a fragment program this will have no effect.

env_map
-------

Turns on/off texture coordinate effect that makes this layer an environment map.

Note: Only applies to the fixed-function pipeline, if you're using a vertex program this will have no effect.

Format: env_map <off|spherical|planar|cubic_reflection|cubic_normal>

Environment maps make an object look reflective by using automatic texture coordinate generation depending on the relationship between the objects vertices or normals and the eye.

spherical
     A spherical environment map. Requires a single texture which is either a fish-eye lens view of the reflected scene, or some other texture which looks good as a spherical map (a texture of glossy highlights is popular especially in car sims). This effect is based on the relationship between the eye direction and the vertex normals of the object, so works best when there are a lot of gradually changing normals, i.e. curved objects.

planar
     Similar to the spherical environment map, but the effect is based on the position of the vertices in the viewport rather than vertex normals. This effect is therefore useful for planar geometry (where a spherical env_map would not look good because the normals are all the same) or objects without normals.

cubic_reflection
     A more advanced form of reflection mapping which uses a group of 6 textures making up the inside of a cube, each of which is a view if the scene down each axis. Works extremely well in all cases but has a higher technical requirement from the card than spherical mapping. Requires that you bind a cubic_texture to this texture unit and use the 'combinedUVW' option.

cubic_normal
     Generates 3D texture coordinates containing the camera space normal vector from the normal information held in the vertex data. Again, full use of this feature requires a cubic_texture with the 'combinedUVW' option.

Default: env_map off

scroll
------

Sets a fixed scroll offset for the texture.

Note: Only applies to the fixed-function pipeline, if you're using a vertex program this will have no effect unless you use the texture_matrix auto-param.

Format: scroll <x> <y>

This method offsets the texture in this layer by a fixed amount. Useful for small adjustments without altering texture coordinates in models. However if you wish to have an animated scroll effect, see the scroll_anim attribute.

scroll_anim
-----------

Sets up an animated scroll for the texture layer. Useful for creating fixed-speed scrolling effects on a texture layer (for varying scroll speeds, see wave_xform).

Note: Only applies to the fixed-function pipeline, if you're using a vertex program this will have no effect unless you use the texture_matrix auto-param.

Format: scroll_anim <xspeed> <yspeed>

rotate
------

Rotates a texture to a fixed angle. This attribute changes the rotational orientation of a texture to a fixed angle, useful for fixed adjustments. If you wish to animate the rotation, see rotate_anim.

Note: Only applies to the fixed-function pipeline, if you're using a vertex program this will have no effect unless you use the texture_matrix auto-param.

Format: rotate <angle>

The parameter is a anti-clockwise angle in degrees.

Note: Only applies to the fixed-function pipeline, if you're using a vertex shader this will have no effect unless you use the texture_matrix auto-param.

rotate_anim
-----------

Sets up an animated rotation effect of this layer. Useful for creating fixed-speed rotation animations (for varying speeds, see wave_xform).

Note: Only applies to the fixed-function pipeline, if you're using a vertex program this will have no effect unless you use the texture_matrix auto-param.

Format: rotate_anim <revs_per_second>

The parameter is a number of anti-clockwise revolutions per second.

scale
-----

Adjusts the scaling factor applied to this texture layer. Useful for adjusting the size of textures without making changes to geometry. This is a fixed scaling factor, if you wish to animate this see wave_xform.

Note: Only applies to the fixed-function pipeline, if you're using a vertex program this will have no effect unless you use the texture_matrix auto-param.

Format: scale <x_scale> <y_scale>

Valid scale values are greater than 0, with a scale factor of 2 making the texture twice as big in that dimension etc.

wave_xform
----------

Sets up a transformation animation based on a wave function. Useful for more advanced texture layer transform effects. You can add multiple instances of this attribute to a single texture layer if you wish.

Note: Only applies to the fixed-function pipeline, if you're using a vertex program this will have no effect unless you use the texture_matrix auto-param.

Format: wave_xform <xform_type> <wave_type> <base> <frequency> <phase> <amplitude>

Example: wave_xform scale_x sine 1.0 0.2 0.0 5.0

xform_type

     scroll_x
          Animate the x scroll value

     scroll_y
          Animate the y scroll value

     rotate
          Animate the rotate value

     scale_x
          Animate the x scale value

     scale_y
          Animate the y scale value

wave_type

     sine
          A typical sine wave which smoothly loops between min and max values

     triangle
          An angled wave which increases & decreases at constant speed, changing instantly at the extremes

     square
          Max for half the wavelength, min for the rest with instant transition between

     sawtooth
          Gradual steady increase from min to max over the period with an instant return to min at the end.

     inverse_sawtooth
          Gradual steady decrease from max to min over the period, with an instant return to max at the end.

base
     The base value, the minimum if amplitude > 0, the maximum if amplitude < 0

frequency
     The number of wave iterations per second, i.e. speed

phase
     Offset of the wave start

amplitude
     The size of the wave

The range of the output of the wave will be base, base+amplitude. So the example above scales the texture in the x direction between 1 (normal size) and 5 along a sine wave at one cycle every 5 second (0.2 waves per second).

transform
---------

This attribute allows you to specify a static 4x4 transformation matrix for the texture unit, thus replacing the individual scroll, rotate and scale attributes mentioned above.

Note: Only applies to the fixed-function pipeline, if you're using a vertex program this will have no effect unless you use the texture_matrix auto-param.

Format: transform m00 m01 m02 m03 m10 m11 m12 m13 m20 m21 m22 m23 m30 m31 m32 m33

The indexes of the 4x4 matrix value above are expressed as m<row><col>.

Declaring Vertex/Geometry/Fragment Programs
-------------------------------------------

In order to use a vertex, geometry or fragment program in your materials (see Using Vertex/Geometry/Fragment Programs in a Pass), you first have to define them. A single program definition can be used by any number of materials, the only prerequisite is that a program must be defined before being referenced in the pass section of a material.

The definition of a program can either be embedded in the .material script itself (in which case it must precede any references to it in the script), or if you wish to use the same program across multiple .material files, you can define it in an external .program script. You define the program in exactly the same way whether you use a .program script or a .material script, the only difference is that all .program scripts are guaranteed to have been parsed before all .material scripts, so you can guarantee that your program has been defined before any .material script that might use it. Just like .material scripts, .program scripts will be read from any location which is on your resource path, and you can define many programs in a single script.

Vertex, geometry and fragment programs can be low-level (i.e. assembler code written to the specification of a given low level syntax such as vs_1_1 or arbfp1) or high-level such as DirectX9 HLSL, Open GL Shader Language, or nVidia's Cg language (see High-level Programs). High level languages give you a number of advantages, such as being able to write more intuitive code, and possibly being able to target multiple architectures in a single program (for example, the same Cg program might be able to be used in both D3D and GL, whilst the equivalent low-level programs would require separate techniques, each targeting a different API). High-level programs also allow you to use named parameters instead of simply indexed ones, although parameters are not defined here, they are used in the Pass.

Here is an example of a definition of a low-level vertex program:

     vertex_program myVertexProgram asm
     {
         source myVertexProgram.asm
         syntax vs_1_1
     }

As you can see, that's very simple, and defining a fragment or geometry program is exactly the same, just with vertex_program replaced with fragment_program or geometry_program, respectively. You give the program a name in the header, followed by the word 'asm' to indicate that this is a low-level program. Inside the braces, you specify where the source is going to come from (and this is loaded from any of the resource locations as with other media), and also indicate the syntax being used. You might wonder why the syntax specification is required when many of the assembler syntaxes have a header identifying them anyway - well the reason is that the engine needs to know what syntax the program is in before reading it, because during compilation of the material, we want to skip programs which use an unsupportable syntax quickly, without loading the program first.

The current supported syntaxes are:

vs_1_1
     This is one of the DirectX vertex shader assembler syntaxes.

     Supported on cards from: ATI Radeon 8500, nVidia GeForce 3

vs_2_0
     Another one of the DirectX vertex shader assembler syntaxes.

     Supported on cards from: ATI Radeon 9600, nVidia GeForce FX 5 series

vs_2_x
     Another one of the DirectX vertex shader assembler syntaxes.

     Supported on cards from: ATI Radeon X series, nVidia GeForce FX 6 series

vs_3_0
     Another one of the DirectX vertex shader assembler syntaxes.

     Supported on cards from: ATI Radeon HD 2000+, nVidia GeForce FX 6 series

arbvp1
     This is the OpenGL standard assembler format for vertex programs. It's roughly equivalent to DirectX vs_1_1.

vp20
     This is an nVidia-specific OpenGL vertex shader syntax which is a superset of vs 1.1. ATI Radeon HD 2000+ also supports it.

vp30
     Another nVidia-specific OpenGL vertex shader syntax. It is a superset of vs 2.0, which is supported on nVidia GeForce FX 5 series and higher. ATI Radeon HD 2000+ also supports it.

vp40
     Another nVidia-specific OpenGL vertex shader syntax. It is a superset of vs 3.0, which is supported on nVidia GeForce FX 6 series and higher.

ps_1_1, ps_1_2, ps_1_3
     DirectX pixel shader (ie fragment program) assembler syntax.

     Supported on cards from: ATI Radeon 8500, nVidia GeForce 3

     NOTE: for ATI 8500, 9000, 9100, 9200 hardware, this profile can also be used in OpenGL.  The ATI 8500 to 9200 do not support arbfp1 but do support atifs extension in OpenGL which is very similar in function to ps_1_4 in DirectX.  Ogre has a built in ps_1_x to atifs compiler that is automatically invoked when ps_1_x is used in OpenGL on ATI hardware.

ps_1_4
     DirectX pixel shader (ie fragment program) assembler syntax.

     Supported on cards from: ATI Radeon 8500, nVidia GeForce FX 5 series

     NOTE: for ATI 8500, 9000, 9100, 9200 hardware, this profile can also be used in OpenGL.  The ATI 8500 to 9200 do not support arbfp1 but do support atifs extension in OpenGL which is very similar in function to ps_1_4 in DirectX.  Ogre has a built in ps_1_x to atifs compiler that is automatically invoked when ps_1_x is used in OpenGL on ATI hardware.

ps_2_0
     DirectX pixel shader (ie fragment program) assembler syntax.

     Supported cards: ATI Radeon 9600, nVidia GeForce FX 5 series

ps_2_x
     DirectX pixel shader (ie fragment program) assembler syntax. This is basically ps_2_0 with a higher number of instructions.

     Supported cards: ATI Radeon X series, nVidia GeForce FX 6 series

ps_3_0
     DirectX pixel shader (ie fragment program) assembler syntax.

     Supported cards: ATI Radeon HD 2000+, nVidia GeForce FX6 series

ps_3_x
     DirectX pixel shader (ie fragment program) assembler syntax.

     Supported cards: nVidia GeForce FX7 series

arbfp1
     This is the OpenGL standard assembler format for fragment programs. It's roughly equivalent to ps_2_0, which means that not all cards that support basic pixel shaders under DirectX support arbfp1 (for example neither the GeForce3 or GeForce4 support arbfp1, but they do support ps_1_1).

fp20
     This is an nVidia-specific OpenGL fragment syntax which is a superset of ps 1.3. It allows you to use the 'nvparse' format for basic fragment programs. It actually uses NV_texture_shader and NV_register_combiners to provide functionality equivalent to DirectX's ps_1_1 under GL, but only for nVidia cards. However, since ATI cards adopted arbfp1 a little earlier than nVidia, it is mainly nVidia cards like the GeForce3 and GeForce4 that this will be useful for. You can find more information about nvparse at http://developer.nvidia.com/object/nvparse.html.

fp30
     Another nVidia-specific OpenGL fragment shader syntax. It is a superset of ps 2.0, which is supported on nVidia GeForce FX 5 series and higher. ATI Radeon HD 2000+ also supports it.

fp40
     Another nVidia-specific OpenGL fragment shader syntax. It is a superset of ps 3.0, which is supported on nVidia GeForce FX 6 series and higher.

gpu_gp, gp4_gp
     An nVidia-specific OpenGL geometry shader syntax.

     Supported cards: nVidia GeForce FX8 series

glsles
     OpenGL Shading Language for Embedded Systems. It is a variant of GLSL, streamlined for low power devices. Supported cards: PowerVR SGX series

You can get a definitive list of the syntaxes supported by the current card by calling GpuProgramManager::getSingleton().getSupportedSyntax().

Specifying Named Constants for Assembler Shaders
------------------------------------------------

Assembler shaders don't have named constants (also called uniform parameters) because the language does not support them - however if you for example decided to precompile your shaders from a high-level language down to assembler for performance or obscurity, you might still want to use the named parameters. Well, you actually can - GpuNamedConstants which contains the named parameter mappings has a 'save' method which you can use to write this data to disk, where you can reference it later using the manual_named_constants directive inside your assembler program declaration, e.g.

     vertex_program myVertexProgram asm
     {
         source myVertexProgram.asm
         syntax vs_1_1
     	manual_named_constants myVertexProgram.constants
     }

In this case myVertexProgram.constants has been created by calling highLevelGpuProgram->getNamedConstants().save("myVertexProgram.constants"); sometime earlier as preparation, from the original high-level program. Once you've used this directive, you can use named parameters here even though the assembler program itself has no knowledge of them.

Default Program Parameters
--------------------------

While defining a vertex, geometry or fragment program, you can also specify the default parameters to be used for materials which use it, unless they specifically override them. You do this by including a nested 'default_params' section, like so:

     vertex_program Ogre/CelShadingVP cg
     {
     	source Example_CelShading.cg
     	entry_point main_vp
     	profiles vs_1_1 arbvp1

     	default_params
     	{
     		param_named_auto lightPosition light_position_object_space 0
     		param_named_auto eyePosition camera_position_object_space
     		param_named_auto worldViewProj worldviewproj_matrix
     		param_named shininess float 10
     	}
     }

The syntax of the parameter definition is exactly the same as when you define parameters when using programs, see Program Parameter Specification. Defining default parameters allows you to avoid rebinding common parameters repeatedly (clearly in the above example, all but 'shininess' are unlikely to change between uses of the program) which makes your material declarations shorter.

Declaring Shared Parameters
---------------------------

Often, not every parameter you want to pass to a shader is unique to that program, and perhaps you want to give the same value to a number of different programs, and a number of different materials using that program. Shared parameter sets allow you to define a 'holding area' for shared parameters that can then be referenced when you need them in particular shaders, while keeping the definition of that value in one place. To define a set of shared parameters, you do this:

     shared_params YourSharedParamsName
     {
     	shared_param_named mySharedParam1 float4 0.1 0.2 0.3 0.4
     	...
     }

As you can see, you need to use the keyword 'shared_params' and follow it with the name that you will use to identify these shared parameters. Inside the curly braces, you can define one parameter per line, in a way which is very similar to the param_named syntax. The definition of these lines is:

Format: shared_param_name <param_name> <param_type> [<[array_size]>] [<initial_values>]

The param_name must be unique within the set, and the param_type can be any one of float, float2, float3, float4, int, int2, int3, int4, matrix2x2, matrix2x3, matrix2x4, matrix3x2, matrix3x3, matrix3x4, matrix4x2, matrix4x3 and matrix4x4. The array_size option allows you to define arrays of param_type should you wish, and if present must be a number enclosed in square brackets (and note, must be separated from the param_type with whitespace). If you wish, you can also initialise the parameters by providing a list of values.

Once you have defined the shared parameters, you can reference them inside default_params and params blocks using shared_params_ref. You can also obtain a reference to them in your code via GpuProgramManager::getSharedParameters, and update the values for all instances using them.

High-level Programs
===================

Support for high level vertex and fragment programs is provided through plugins; this is to make sure that an application using OGRE can use as little or as much of the high-level program functionality as they like. OGRE currently supports 3 high-level program types, Cg (Cg) (an API- and card-independent, high-level language which lets you write programs for both OpenGL and DirectX for lots of cards), DirectX 9 High-Level Shader Language (HLSL), and OpenGL Shader Language (GLSL). HLSL can only be used with the DirectX rendersystem, and GLSL can only be used with the GL rendersystem. Cg can be used with both, although experience has shown that more advanced programs, particularly fragment programs which perform a lot of texture fetches, can produce better code in the rendersystem-specific shader language.

One way to support both HLSL and GLSL is to include separate techniques in the material script, each one referencing separate programs. However, if the programs are basically the same, with the same parameters, and the techniques are complex this can bloat your material scripts with duplication fairly quickly. Instead, if the only difference is the language of the vertex & fragment program you can use OGRE's Unified High-level Programs to automatically pick a program suitable for your rendersystem whilst using a single technique.

Skeletal Animation in Vertex Programs
-------------------------------------

You can implement skeletal animation in hardware by writing a vertex program which uses the per-vertex blending indices and blending weights, together with an array of world matrices (which will be provided for you by Ogre if you bind the automatic parameter 'world_matrix_array_3x4'). However, you need to communicate this support to Ogre so it does not perform skeletal animation in software for you. You do this by adding the following attribute to your vertex_program definition:

     	includes_skeletal_animation true

When you do this, any skeletally animated entity which uses this material will forgo the usual animation blend and will expect the vertex program to do it, for both vertex positions and normals. Note that ALL submeshes must be assigned a material which implements this, and that if you combine skeletal animation with vertex animation (see Animation) then all techniques must be hardware accelerated for any to be.

Morph Animation in Vertex Programs
----------------------------------

You can implement morph animation in hardware by writing a vertex program which linearly blends between the first and second position keyframes passed as positions and the first free texture coordinate set, and by binding the animation_parametric value to a parameter (which tells you how far to interpolate between the two). However, you need to communicate this support to Ogre so it does not perform morph animation in software for you. You do this by adding the following attribute to your vertex_program definition:

     	includes_morph_animation true

When you do this, any skeletally animated entity which uses this material will forgo the usual software morph and will expect the vertex program to do it. Note that if your model includes both skeletal animation and morph animation, they must both be implemented in the vertex program if either is to be hardware acceleration. Note that ALL submeshes must be assigned a material which implements this, and that if you combine skeletal animation with vertex animation (see Animation) then all techniques must be hardware accelerated for any to be.

Pose Animation in Vertex Programs
---------------------------------

You can implement pose animation (blending between multiple poses based on weight) in a vertex program by pulling in the original vertex data (bound to position), and as many pose offset buffers as you've defined in your 'includes_pose_animation' declaration, which will be in the first free texture unit upwards. You must also use the animation_parametric parameter to define the starting point of the constants which will contain the pose weights; they will start at the parameter you define and fill 'n' constants, where 'n' is the max number of poses this shader can blend, i.e. the parameter to includes_pose_animation.

     	includes_pose_animation 4

Note that ALL submeshes must be assigned a material which implements this, and that if you combine skeletal animation with vertex animation (see Animation) then all techniques must be hardware accelerated for any to be.

Vertex texture fetching in vertex programs
------------------------------------------

If your vertex program makes use of Vertex Texture Fetch, you should declare that with the 'uses_vertex_texture_fetch' directive. This is enough to tell Ogre that your program uses this feature and that hardware support for it should be checked.

     	uses_vertex_texture_fetch true

Adjacency information in Geometry Programs
------------------------------------------

Some geometry programs require adjacency information from the geometry. It means that a geometry shader doesn't only get the information of the primitive it operates on, it also has access to its neighbors (in the case of lines or triangles). This directive will tell Ogre to send the information to the geometry shader.

     	uses_adjacency_information true

Vertex Programs With Shadows
----------------------------

When using shadows (see Shadows), the use of vertex programs can add some additional complexities, because Ogre can only automatically deal with everything when using the fixed-function pipeline. If you use vertex programs, and you are also using shadows, you may need to make some adjustments.

If you use stencil shadows, then any vertex programs which do vertex deformation can be a problem, because stencil shadows are calculated on the CPU, which does not have access to the modified vertices. If the vertex program is doing standard skeletal animation, this is ok (see section above) because Ogre knows how to replicate the effect in software, but any other vertex deformation cannot be replicated, and you will either have to accept that the shadow will not reflect this deformation, or you should turn off shadows for that object.

If you use texture shadows, then vertex deformation is acceptable; however, when rendering the object into a shadow texture (the shadow caster pass), the shadow has to be rendered in a solid colour (linked to the ambient colour for modulative shadows, black for additive shadows). You must therefore provide an alternative vertex program, so Ogre provides you with a way of specifying one to use when rendering the caster, see Shadows and Vertex Programs.

Cg programs
-----------

In order to define Cg programs, you have to have to load Plugin_CgProgramManager.so/.dll at startup, either through plugins.cfg or through your own plugin loading code. They are very easy to define:

     fragment_program myCgFragmentProgram cg
     {
         source myCgFragmentProgram.cg
         entry_point main
         profiles ps_2_0 arbfp1
     }

There are a few differences between this and the assembler program - to begin with, we declare that the fragment program is of type 'cg' rather than 'asm', which indicates that it's a high-level program using Cg. The 'source' parameter is the same, except this time it's referencing a Cg source file instead of a file of assembler.

Here is where things start to change. Firstly, we need to define an 'entry_point', which is the name of a function in the Cg program which will be the first one called as part of the fragment program. Unlike assembler programs, which just run top-to-bottom, Cg programs can include multiple functions and as such you must specify the one which start the ball rolling.

Next, instead of a fixed 'syntax' parameter, you specify one or more 'profiles'; profiles are how Cg compiles a program down to the low-level assembler. The profiles have the same names as the assembler syntax codes mentioned above; the main difference is that you can list more than one, thus allowing the program to be compiled down to more low-level syntaxes so you can write a single high-level program which runs on both D3D and GL. You are advised to just enter the simplest profiles under which your programs can be compiled in order to give it the maximum compatibility. The ordering also matters; if a card supports more than one syntax then the one listed first will be used.

Lastly, there is a final option called 'compile_arguments', where you can specify arguments exactly as you would to the cgc command-line compiler, should you wish to.

DirectX9 HLSL
-------------

DirectX9 HLSL has a very similar language syntax to Cg but is tied to the DirectX API. The only benefit over Cg is that it only requires the DirectX 9 render system plugin, not any additional plugins. Declaring a DirectX9 HLSL program is very similar to Cg. Here's an example:

     vertex_program myHLSLVertexProgram hlsl
     {
         source myHLSLVertexProgram.txt
         entry_point main
         target vs_2_0
     }

As you can see, the main syntax is almost identical, except that instead of 'profiles' with a list of assembler formats, you have a 'target' parameter which allows a single assembler target to be specified - obviously this has to be a DirectX assembler format syntax code.

Important Matrix Ordering Note: One thing to bear in mind is that HLSL allows you to use 2 different ways to multiply a vector by a matrix - mul(v,m) or mul(m,v). The only difference between them is that the matrix is effectively transposed. You should use mul(m,v) with the matrices passed in from Ogre - this agrees with the shaders produced from tools like RenderMonkey, and is consistent with Cg too, but disagrees with the Dx9 SDK and FX Composer which use mul(v,m) - you will have to switch the parameters to mul() in those shaders.

Note that if you use the float3x4 / matrix3x4 type in your shader, bound to an OGRE auto-definition (such as bone matrices) you should use the column_major_matrices = false option (discussed below) in your program definition. This is because OGRE passes float3x4 as row-major to save constant space (3 float4's rather than 4 float4's with only the top 3 values used) and this tells OGRE to pass all matrices like this, so that you can use mul(m,v) consistently for all calculations. OGRE will also to tell the shader to compile in row-major form (you don't have to set the /Zpr compile option or #pragma pack(row-major) option, OGRE does this for you). Note that passing bones in float4x3 form is not supported by OGRE, but you don't need it given the above.

Advanced options

preprocessor_defines <defines>
     This allows you to define symbols which can be used inside the HLSL shader code to alter the behaviour (through #ifdef or #if clauses). Definitions are separated by ';' or ',' and may optionally have a '=' operator within them to specify a definition value. Those without an '=' will implicitly have a definition of 1.

column_major_matrices <true|false>
     The default for this option is 'true' so that OGRE passes matrices auto-bound matrices in a form where mul(m,v) works. Setting this option to false does 2 things - it transpose auto-bound 4x4 matrices and also sets the /Zpr (row-major) option on the shader compilation. This means you can still use mul(m,v), but the matrix layout is row-major instead. This is only useful if you need to use bone matrices (float3x4) in a shader since it saves a float4 constant for every bone involved.

optimisation_level <opt>
     Set the optimisation level, which can be one of 'default', 'none', '0', '1', '2', or '3'. This corresponds to the /O parameter of fxc.exe, except that in 'default' mode, optimisation is disabled in debug mode and set to 1 in release mode (fxc.exe uses 1 all the time). Unsurprisingly the default value is 'default'. You may want to change this if you want to tweak the optimisation, for example if your shader gets so complex that it will not longer compile without some minimum level of optimisation.

     [file glsl.inc not included]

Unified High-level Programs
---------------------------

As mentioned above, it can often be useful to write both HLSL and GLSL programs to specifically target each platform, but if you do this via multiple material techniques this can cause a bloated material definition when the only difference is the program language. Well, there is another option. You can 'wrap' multiple programs in a 'unified' program definition, which will automatically choose one of a series of 'delegate' programs depending on the rendersystem and hardware support.

     vertex_program myVertexProgram unified
     {
     	delegate realProgram1
     	delegate realProgram2
     	... etc
     }

This works for both vertex and fragment programs, and you can list as many delegates as you like - the first one to be supported by the current rendersystem & hardware will be used as the real program. This is almost like a mini-technique system, but for a single program and with a much tighter purpose. You can only use this where the programs take all the same inputs, particularly textures and other pass / sampler state. Where the only difference between the programs is the language (or possibly the target in HLSL - you can include multiple HLSL programs with different targets in a single unified program too if you want, or indeed any number of other high-level programs), this can become a very powerful feature. For example, without this feature here's how you'd have to define a programmable material which supported HLSL and GLSL:

     vertex_program myVertexProgramHLSL hlsl
     {
     	source prog.hlsl
     	entry_point main_vp
     	target vs_2_0
     }
     fragment_program myFragmentProgramHLSL hlsl
     {
     	source prog.hlsl
     	entry_point main_fp
     	target ps_2_0
     }
     vertex_program myVertexProgramGLSL glsl
     {
     	source prog.vert
     }
     fragment_program myFragmentProgramGLSL glsl
     {
     	source prog.frag
     	default_params
     	{
     		param_named tex int 0
     	}
     }
     material SupportHLSLandGLSLwithoutUnified
     {
     	// HLSL technique
     	technique
     	{
     		pass
     		{
     			vertex_program_ref myVertexProgramHLSL
     			{
     				param_named_auto worldViewProj world_view_proj_matrix
     				param_named_auto lightColour light_diffuse_colour 0
     				param_named_auto lightSpecular light_specular_colour 0
     				param_named_auto lightAtten light_attenuation 0
     			}
     			fragment_program_ref myFragmentProgramHLSL
     			{
     			}
     		}
     	}
     	// GLSL technique
     	technique
     	{
     		pass
     		{
     			vertex_program_ref myVertexProgramHLSL
     			{
     				param_named_auto worldViewProj world_view_proj_matrix
     				param_named_auto lightColour light_diffuse_colour 0
     				param_named_auto lightSpecular light_specular_colour 0
     				param_named_auto lightAtten light_attenuation 0
     			}
     			fragment_program_ref myFragmentProgramHLSL
     			{
     			}
     		}
     	}
     }

And that's a really small example. Everything you added to the HLSL technique, you'd have to duplicate in the GLSL technique too. So instead, here's how you'd do it with unified program definitions:

     vertex_program myVertexProgramHLSL hlsl
     {
     	source prog.hlsl
     	entry_point main_vp
     	target vs_2_0
     }
     fragment_program myFragmentProgramHLSL hlsl
     {
     	source prog.hlsl
     	entry_point main_fp
     	target ps_2_0
     }
     vertex_program myVertexProgramGLSL glsl
     {
     	source prog.vert
     }
     fragment_program myFragmentProgramGLSL glsl
     {
     	source prog.frag
     	default_params
     	{
     		param_named tex int 0
     	}
     }
     // Unified definition
     vertex_program myVertexProgram unified
     {
     	delegate myVertexProgramGLSL
     	delegate myVertexProgramHLSL
     }
     fragment_program myFragmentProgram unified
     {
     	delegate myFragmentProgramGLSL
     	delegate myFragmentProgramHLSL
     }
     material SupportHLSLandGLSLwithUnified
     {
     	// HLSL technique
     	technique
     	{
     		pass
     		{
     			vertex_program_ref myVertexProgram
     			{
     				param_named_auto worldViewProj world_view_proj_matrix
     				param_named_auto lightColour light_diffuse_colour 0
     				param_named_auto lightSpecular light_specular_colour 0
     				param_named_auto lightAtten light_attenuation 0
     			}
     			fragment_program_ref myFragmentProgram
     			{
     			}
     		}
     	}
     }

At runtime, when myVertexProgram or myFragmentProgram are used, OGRE automatically picks a real program to delegate to based on what's supported on the current hardware / rendersystem. If none of the delegates are supported, the entire technique referencing the unified program is marked as unsupported and the next technique in the material is checked fro fallback, just like normal. As your materials get larger, and you find you need to support HLSL and GLSL specifically (or need to write multiple interface-compatible versions of a program for whatever other reason), unified programs can really help reduce duplication.

Using Vertex/Geometry/Fragment Programs in a Pass
-------------------------------------------------

Within a pass section of a material script, you can reference a vertex, geometry and / or a fragment program which is been defined in a .program script (see Declaring Vertex/Geometry/Fragment Programs). The programs are defined separately from the usage of them in the pass, since the programs are very likely to be reused between many separate materials, probably across many different .material scripts, so this approach lets you define the program only once and use it many times.

As well as naming the program in question, you can also provide parameters to it. Here's a simple example:

     vertex_program_ref myVertexProgram
     {
     	param_indexed_auto 0 worldviewproj_matrix
     	param_indexed      4 float4  10.0 0 0 0
     }

In this example, we bind a vertex program called 'myVertexProgram' (which will be defined elsewhere) to the pass, and give it 2 parameters, one is an 'auto' parameter, meaning we do not have to supply a value as such, just a recognised code (in this case it's the world/view/projection matrix which is kept up to date automatically by Ogre). The second parameter is a manually specified parameter, a 4-element float. The indexes are described later.

The syntax of the link to a vertex program and a fragment or geometry program are identical, the only difference is that 'fragment_program_ref' and 'geometry_program_ref' are used respectively instead of 'vertex_program_ref'.

For many situations vertex, geometry and fragment programs are associated with each other in a pass but this is not cast in stone.  You could have a vertex program that can be used by several different fragment programs.  Another situation that arises is that you can mix fixed pipeline and programmable pipeline (shaders) together. You could use the non-programmable vertex fixed function pipeline and then provide a fragment_program_ref in a pass i.e. there would be no vertex_program_ref section in the pass.  The fragment program referenced in the pass must meet the requirements as defined in the related API in order to read from the outputs of the vertex fixed pipeline.  You could also just have a vertex program that outputs to the fragment fixed function pipeline.

The requirements to read from or write to the fixed function pipeline are similar between rendering API's (DirectX and OpenGL) but how its actually done in each type of shader (vertex, geometry or fragment) depends on the shader language.  For HLSL (DirectX API) and associated asm consult MSDN at http://msdn.microsoft.com/library/. For GLSL (OpenGL), consult section 7.6 of the GLSL spec 1.1 available at http://developer.3dlabs.com/documents/index.htm.  The built in varying variables provided in GLSL allow your program to read/write to the fixed function pipeline varyings.  For Cg consult the Language Profiles section in CgUsersManual.pdf that comes with the Cg Toolkit available at http://developer.nvidia.com/object/cg_toolkit.html.  For HLSL and Cg its the varying bindings that allow your shader programs to read/write to the fixed function pipeline varyings.

Parameter specification
-----------------------

Parameters can be specified using one of 4 commands as shown below. The same syntax is used whether you are defining a parameter just for this particular use of the program, or when specifying the Default Program Parameters. Parameters set in the specific use of the program override the defaults.

  * param_indexed

  * param_indexed_auto

  * param_named

  * param_named_auto

  * shared_params_ref

param_indexed
-------------

This command sets the value of an indexed parameter.

format: param_indexed <index> <type> <value>

example: param_indexed 0 float4 10.0 0 0 0

The 'index' is simply a number representing the position in the parameter list which the value should be written, and you should derive this from your program definition. The index is relative to the way constants are stored on the card, which is in 4-element blocks. For example if you defined a float4 parameter at index 0, the next index would be 1. If you defined a matrix4x4 at index 0, the next usable index would be 4, since a 4x4 matrix takes up 4 indexes.

The value of 'type' can be float4, matrix4x4, float<n>, int4, int<n>. Note that 'int' parameters are only available on some more advanced program syntaxes, check the D3D or GL vertex / fragment program documentation for full details. Typically the most useful ones will be float4 and matrix4x4. Note that if you use a type which is not a multiple of 4, then the remaining values up to the multiple of 4 will be filled with zeroes for you (since GPUs always use banks of 4 floats per constant even if only one is used).

'value' is simply a space or tab-delimited list of values which can be converted into the type you have specified.

param_indexed_auto
------------------

This command tells Ogre to automatically update a given parameter with a derived value. This frees you from writing code to update program parameters every frame when they are always changing.

format: param_indexed_auto <index> <value_code> <extra_params>

example: param_indexed_auto 0 worldviewproj_matrix

'index' has the same meaning as param_indexed; note this time you do not have to specify the size of the parameter because the engine knows this already. In the example, the world/view/projection matrix is being used so this is implicitly a matrix4x4.

'value_code' is one of a list of recognised values:

world_matrix
     The current world matrix.

inverse_world_matrix
     The inverse of the current world matrix.

transpose_world_matrix
     The transpose of the world matrix

inverse_transpose_world_matrix
     The inverse transpose of the world matrix

world_matrix_array_3x4
     An array of world matrices, each represented as only a 3x4 matrix (3 rows of 4columns) usually for doing hardware skinning. You should make enough entries available in your vertex program for the number of bones in use, ie an array of numBones*3 float4's.

view_matrix
     The current view matrix.

inverse_view_matrix
     The inverse of the current view matrix.

transpose_view_matrix
     The transpose of the view matrix

inverse_transpose_view_matrix
     The inverse transpose of the view matrix

projection_matrix
     The current projection matrix.

inverse_projection_matrix
     The inverse of the projection matrix

transpose_projection_matrix
     The transpose of the projection matrix

inverse_transpose_projection_matrix
     The inverse transpose of the projection matrix

worldview_matrix
     The current world and view matrices concatenated.

inverse_worldview_matrix
     The inverse of the current concatenated world and view matrices.

transpose_worldview_matrix
     The transpose of the world and view matrices

inverse_transpose_worldview_matrix
     The inverse transpose of the current concatenated world and view matrices.

viewproj_matrix
     The current view and projection matrices concatenated.

inverse_viewproj_matrix
     The inverse of the view & projection matrices

transpose_viewproj_matrix
     The transpose of the view & projection matrices

inverse_transpose_viewproj_matrix
     The inverse transpose of the view & projection matrices

worldviewproj_matrix
     The current world, view and projection matrices concatenated.

inverse_worldviewproj_matrix
     The inverse of the world, view and projection matrices

transpose_worldviewproj_matrix
     The transpose of the world, view and projection matrices

inverse_transpose_worldviewproj_matrix
     The inverse transpose of the world, view and projection matrices

texture_matrix
     The transform matrix of a given texture unit, as it would usually be seen in the fixed-function pipeline. This requires an index in the 'extra_params' field, and relates to the 'nth' texture unit of the pass in question. NB if the given index exceeds the number of texture units available for this pass, then the parameter will be set to Matrix4::IDENTITY.

render_target_flipping
     The value use to adjust transformed y position if bypassed projection matrix transform. It's -1 if the render target requires texture flipping, +1 otherwise.

vertex_winding
     Indicates what vertex winding mode the render state is in at this point; +1 for standard, -1 for inverted (e.g. when processing reflections).

light_diffuse_colour
     The diffuse colour of a given light; this requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light - note that directional lights are always first in the list and always present). NB if there are no lights this close, then the parameter will be set to black.

light_specular_colour
     The specular colour of a given light; this requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to black.

light_attenuation
     A float4 containing the 4 light attenuation variables for a given light. This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to all zeroes. The order of the parameters is range, constant attenuation, linear attenuation, quadric attenuation.

spotlight_params
     A float4 containing the 3 spotlight parameters and a control value. The order of the parameters is cos(inner angle /2 ), cos(outer angle / 2), falloff, and the final w value is 1.0f. For non-spotlights the value is float4(1,0,0,1). This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). If there are less lights than this, the details are like a non-spotlight.

light_position
     The position of a given light in world space. This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to all zeroes. Note that this property will work with all kinds of lights, even directional lights, since the parameter is set as a 4D vector. Point lights will be (pos.x, pos.y, pos.z, 1.0f) whilst directional lights will be (-dir.x, -dir.y, -dir.z, 0.0f). Operations like dot products will work consistently on both.

light_direction
     The direction of a given light in world space. This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to all zeroes. DEPRECATED - this property only works on directional lights, and we recommend that you use light_position instead since that returns a generic 4D vector.

light_position_object_space
     The position of a given light in object space (i.e. when the object is at (0,0,0)). This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to all zeroes.  Note that this property will work with all kinds of lights, even directional lights, since the parameter is set as a 4D vector. Point lights will be (pos.x, pos.y, pos.z, 1.0f) whilst directional lights will be (-dir.x, -dir.y, -dir.z, 0.0f). Operations like dot products will work consistently on both.

light_direction_object_space
     The direction of a given light in object space (i.e. when the object is at (0,0,0)). This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to all zeroes.  DEPRECATED, except for spotlights - for directional lights we recommend that you use light_position_object_space instead since that returns a generic 4D vector.

light_distance_object_space
     The distance of a given light from the centre of the object - this is a useful approximation to per-vertex distance calculations for relatively small objects. This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to all zeroes.

light_position_view_space
     The position of a given light in view space (i.e. when the camera is at (0,0,0)). This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to all zeroes.  Note that this property will work with all kinds of lights, even directional lights, since the parameter is set as a 4D vector. Point lights will be (pos.x, pos.y, pos.z, 1.0f) whilst directional lights will be (-dir.x, -dir.y, -dir.z, 0.0f). Operations like dot products will work consistently on both.

light_direction_view_space
     The direction of a given light in view space (i.e. when the camera is at (0,0,0)). This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to all zeroes.  DEPRECATED, except for spotlights - for directional lights we recommend that you use light_position_view_space instead since that returns a generic 4D vector.

light_power
     The 'power' scaling for a given light, useful in HDR rendering. This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light).

light_diffuse_colour_power_scaled
     As light_diffuse_colour, except the RGB channels of the passed colour have been pre-scaled by the light's power scaling as given by light_power.

light_specular_colour_power_scaled
     As light_specular_colour, except the RGB channels of the passed colour have been pre-scaled by the light's power scaling as given by light_power.

light_number
     When rendering, there is generally a list of lights available for use by all of the passes for a given object, and those lights may or may not be referenced in one or more passes. Sometimes it can be useful to know where in that overall list a given light light (as seen from a pass) is. For example if you use iterate once_per_light, the pass always sees the light as index 0, but in each iteration the actual light referenced is different. This binding lets you pass through the actual index of the light in that overall list. You just need to give it a parameter of the pass-relative light number and it will map it to the overall list index.

light_diffuse_colour_array
     As light_diffuse_colour, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_specular_colour_array
     As light_specular_colour, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_diffuse_colour_power_scaled_array
     As light_diffuse_colour_power_scaled, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_specular_colour_power_scaled_array
     As light_specular_colour_power_scaled, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_attenuation_array
     As light_attenuation, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

spotlight_params_array
     As spotlight_params, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_position_array
     As light_position, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_direction_array
     As light_direction, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_position_object_space_array
     As light_position_object_space, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_direction_object_space_array
     As light_direction_object_space, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_distance_object_space_array
     As light_distance_object_space, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_position_view_space_array
     As light_position_view_space, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_direction_view_space_array
     As light_direction_view_space, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_power_array
     As light_power, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

light_count
     The total number of lights active in this pass.

light_casts_shadows
     Sets an integer parameter to 1 if the given light casts shadows, 0 otherwise, Requires a light index parameter.

ambient_light_colour
     The colour of the ambient light currently set in the scene.

surface_ambient_colour
     The ambient colour reflectance properties of the pass (see ambient). This allows you access to fixed-function pipeline property handily.

surface_diffuse_colour
     The diffuse colour reflectance properties of the pass (see diffuse). This allows you access to fixed-function pipeline property handily.

surface_specular_colour
     The specular colour reflectance properties of the pass (see specular). This allows you access to fixed-function pipeline property handily.

surface_emissive_colour
     The amount of self-illumination of the pass (see emissive). This allows you access to fixed-function pipeline property handily.

surface_shininess
     The shininess of the pass, affecting the size of specular highlights (see specular). This allows you bind to fixed-function pipeline property handily.

derived_ambient_light_colour
     The derived ambient light colour, with 'r', 'g', 'b' components filled with product of surface_ambient_colour and ambient_light_colour, respectively, and 'a' component filled with surface ambient alpha component.

derived_scene_colour
     The derived scene colour, with 'r', 'g' and 'b' components filled with sum of derived_ambient_light_colour and surface_emissive_colour, respectively, and 'a' component filled with surface diffuse alpha component.

derived_light_diffuse_colour
     The derived light diffuse colour, with 'r', 'g' and 'b' components filled with product of surface_diffuse_colour, light_diffuse_colour and light_power, respectively, and 'a' component filled with surface diffuse alpha component. This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light).

derived_light_specular_colour
     The derived light specular colour, with 'r', 'g' and 'b' components filled with product of surface_specular_colour and light_specular_colour, respectively, and 'a' component filled with surface specular alpha component. This requires an index in the 'extra_params' field, and relates to the 'nth' closest light which could affect this object (i.e. 0 refers to the closest light).

derived_light_diffuse_colour_array
     As derived_light_diffuse_colour, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

derived_light_specular_colour_array
     As derived_light_specular_colour, except that this populates an array of parameters with a number of lights, and the 'extra_params' field refers to the number of 'nth closest' lights to be processed. This parameter is not compatible with light-based pass_iteration options but can be used for single-pass lighting.

fog_colour
     The colour of the fog currently set in the scene.

fog_params
     The parameters of the fog currently set in the scene. Packed as (exp_density, linear_start, linear_end, 1.0 / (linear_end - linear_start)).

camera_position
     The current cameras position in world space.

camera_position_object_space
     The current cameras position in object space (i.e. when the object is at (0,0,0)).

lod_camera_position
     The current LOD camera position in world space. A LOD camera is a separate camera associated with the rendering camera which allows LOD calculations to be calculated separately. The classic example is basing the LOD of the shadow texture render on the position of the main camera, not the shadow camera.

lod_camera_position_object_space
     The current LOD camera position in object space (i.e. when the object is at (0,0,0)).

time
     The current time, factored by the optional parameter (or 1.0f if not supplied).

time_0_x
     Single float time value, which repeats itself based on "cycle time" given as an 'extra_params' field

costime_0_x
     Cosine of time_0_x

sintime_0_x
     Sine of time_0_x

tantime_0_x
     Tangent of time_0_x

time_0_x_packed
     4-element vector of time0_x, sintime0_x, costime0_x, tantime0_x

time_0_1
     As time0_x but scaled to [0..1]

costime_0_1
     As costime0_x but scaled to [0..1]

sintime_0_1
     As sintime0_x but scaled to [0..1]

tantime_0_1
     As tantime0_x but scaled to [0..1]

time_0_1_packed
     As time0_x_packed but all values scaled to [0..1]

time_0_2pi
     As time0_x but scaled to [0..2*Pi]

costime_0_2pi
     As costime0_x but scaled to [0..2*Pi]

sintime_0_2pi
     As sintime0_x but scaled to [0..2*Pi]

tantime_0_2pi
     As tantime0_x but scaled to [0..2*Pi]

time_0_2pi_packed
     As time0_x_packed but scaled to [0..2*Pi]

frame_time
     The current frame time, factored by the optional parameter (or 1.0f if not supplied).

fps
     The current frames per second

viewport_width
     The current viewport width in pixels

viewport_height
     The current viewport height in pixels

inverse_viewport_width
     1.0/the current viewport width in pixels

inverse_viewport_height
     1.0/the current viewport height in pixels

viewport_size
     4-element vector of viewport_width, viewport_height, inverse_viewport_width, inverse_viewport_height

texel_offsets
     Provides details of the rendersystem-specific texture coordinate offsets required to map texels onto pixels. float4(horizontalOffset, verticalOffset, horizontalOffset / viewport_width, verticalOffset / viewport_height).

view_direction
     View direction vector in object space

view_side_vector
     View local X axis

view_up_vector
     View local Y axis

fov
     Vertical field of view, in radians

near_clip_distance
     Near clip distance, in world units

far_clip_distance
     Far clip distance, in world units (may be 0 for infinite view projection)

texture_viewproj_matrix
     Applicable to vertex programs which have been specified as the 'shadow receiver' vertex program alternative, or where a texture unit is marked as content_type shadow; this provides details of the view/projection matrix for the current shadow projector. The optional 'extra_params' entry specifies which light the projector refers to (for the case of content_type shadow where more than one shadow texture may be present in a single pass), where 0 is the default and refers to the first light referenced in this pass.

texture_viewproj_matrix_array
     As texture_viewproj_matrix, except an array of matrices is passed, up to the number that you specify as the 'extra_params' value.

texture_worldviewproj_matrix
     As texture_viewproj_matrix except it also includes the world matrix.

texture_worldviewproj_matrix_array
     As texture_worldviewproj_matrix, except an array of matrices is passed, up to the number that you specify as the 'extra_params' value.

spotlight_viewproj_matrix
     Provides a view / projection matrix which matches the set up of a given spotlight (requires an 'extra_params' entry to indicate the light index, which must be a spotlight). Can be used to project a texture from a given spotlight.

spotlight_viewproj_matrix_array
     As spotlight_viewproj_matrix, except an array of matrices is passed, up to the number that you specify as the 'extra_params' value.

spotlight_worldviewproj_matrix
     As spotlight_viewproj_matrix except it also includes the world matrix.

scene_depth_range
     Provides information about the depth range as viewed from the current camera being used to render. Provided as float4(minDepth, maxDepth, depthRange, 1 / depthRange).

shadow_scene_depth_range
     Provides information about the depth range as viewed from the shadow camera relating to a selected light. Requires a light index parameter. Provided as float4(minDepth, maxDepth, depthRange, 1 / depthRange).

shadow_colour
     The shadow colour (for modulative shadows) as set via SceneManager::setShadowColour.

shadow_extrusion_distance
     The shadow extrusion distance as determined by the range of a non-directional light or set via SceneManager::setShadowDirectionalLightExtrusionDistance for directional lights.

texture_size
     Provides texture size of the selected texture unit. Requires a texture unit index parameter. Provided as float4(width, height, depth, 1). For 2D-texture, depth sets to 1, for 1D-texture, height and depth sets to 1.

inverse_texture_size
     Provides inverse texture size of the selected texture unit. Requires a texture unit index parameter. Provided as float4(1 / width, 1 / height, 1 / depth, 1). For 2D-texture, depth sets to 1, for 1D-texture, height and depth sets to 1.

packed_texture_size
     Provides packed texture size of the selected texture unit. Requires a texture unit index parameter. Provided as float4(width, height, 1 / width, 1 / height). For 3D-texture, depth is ignored, for 1D-texture, height sets to 1.

pass_number
     Sets the active pass index number in a gpu parameter.  The first pass in a technique has an index of 0, the second an index of 1 and so on.  This is useful for multipass shaders (i.e. fur or blur shader) that need to know what pass it is.  By setting up the auto parameter in a Default Program Parameters list in a program definition, there is no requirement to set the pass number parameter in each pass and lose track. (see fur_example)

pass_iteration_number
     Useful for GPU programs that need to know what the current pass iteration number is. The first iteration of a pass is numbered 0.  The last iteration number is one less than what is set for the pass iteration number.  If a pass has its iteration attribute set to 5 then the last iteration number (5th execution of the pass) is 4.(see iteration)

animation_parametric
     Useful for hardware vertex animation. For morph animation, sets the parametric value (0..1) representing the distance between the first position keyframe (bound to positions) and the second position keyframe (bound to the first free texture coordinate) so that the vertex program can interpolate between them. For pose animation, indicates a group of up to 4 parametric weight values applying to a sequence of up to 4 poses (each one bound to x, y, z and w of the constant), one for each pose. The original positions are held in the usual position buffer, and the offsets to take those positions to the pose where weight == 1.0 are in the first 'n' free texture coordinates; 'n' being determined by the value passed to includes_pose_animation. If more than 4 simultaneous poses are required, then you'll need more than 1 shader constant to hold the parametric values, in which case you should use this binding more than once, referencing a different constant entry; the second one will contain the parametrics for poses 5-8, the third for poses 9-12, and so on.

custom
     This allows you to map a custom parameter on an individual Renderable (see Renderable::setCustomParameter) to a parameter on a GPU program. It requires that you complete the 'extra_params' field with the index that was used in the Renderable::setCustomParameter call, and this will ensure that whenever this Renderable is used, it will have it's custom parameter mapped in. It's very important that this parameter has been defined on all Renderables that are assigned the material that contains this automatic mapping, otherwise the process will fail.

param_named
-----------

This is the same as param_indexed, but uses a named parameter instead of an index. This can only be used with high-level programs which include parameter names; if you're using an assembler program then you have no choice but to use indexes. Note that you can use indexed parameters for high-level programs too, but it is less portable since if you reorder your parameters in the high-level program the indexes will change.

format: param_named <name> <type> <value>

example: param_named shininess float4 10.0 0 0 0

The type is required because the program is not compiled and loaded when the material script is parsed, so at this stage we have no idea what types the parameters are. Programs are only loaded and compiled when they are used, to save memory.

param_named_auto
----------------

This is the named equivalent of param_indexed_auto, for use with high-level programs.

Format: param_named_auto <name> <value_code> <extra_params>

Example: param_named_auto worldViewProj WORLDVIEWPROJ_MATRIX

The allowed value codes and the meaning of extra_params are detailed in param_indexed_auto.

shared_params_ref
-----------------

This option allows you to reference shared parameter sets as defined in Declaring Shared Parameters.

Format: shared_params_ref <shared_set_name>

Example: shared_params_ref mySharedParams

The only required parameter is a name, which must be the name of an already defined shared parameter set. All named parameters which are present in the program that are also present in the shared parameter set will be linked, and the shared parameters used as if you had defined them locally. This is dependent on the definitions (type and array size) matching between the shared set and the program.

Shadows and Vertex Programs
---------------------------

When using shadows (see Shadows), the use of vertex programs can add some additional complexities, because Ogre can only automatically deal with everything when using the fixed-function pipeline. If you use vertex programs, and you are also using shadows, you may need to make some adjustments.

If you use stencil shadows, then any vertex programs which do vertex deformation can be a problem, because stencil shadows are calculated on the CPU, which does not have access to the modified vertices. If the vertex program is doing standard skeletal animation, this is ok (see section above) because Ogre knows how to replicate the effect in software, but any other vertex deformation cannot be replicated, and you will either have to accept that the shadow will not reflect this deformation, or you should turn off shadows for that object.

If you use texture shadows, then vertex deformation is acceptable; however, when rendering the object into the shadow texture (the shadow caster pass), the shadow has to be rendered in a solid colour (linked to the ambient colour). You must therefore provide an alternative vertex program, so Ogre provides you with a way of specifying one to use when rendering the caster. Basically you link an alternative vertex program, using exactly the same syntax as the original vertex program link:

     shadow_caster_vertex_program_ref myShadowCasterVertexProgram
     {
     	param_indexed_auto 0 worldviewproj_matrix
     	param_indexed_auto 4 ambient_light_colour
     }

When rendering a shadow caster, Ogre will automatically use the alternate program. You can bind the same or different parameters to the program - the most important thing is that you bind ambiend_light_colour, since this determines the colour of the shadow in modulative texture shadows. If you don't supply an alternate program, Ogre will fall back on a fixed-function material which will not reflect any vertex deformation you do in your vertex program.

In addition, when rendering the shadow receivers with shadow textures, Ogre needs to project the shadow texture. It does this automatically in fixed function mode, but if the receivers use vertex programs, they need to have a shadow receiver program which does the usual vertex deformation, but also generates projective texture coordinates. The additional program linked into the pass like this:

     shadow_receiver_vertex_program_ref myShadowReceiverVertexProgram
     {
     	param_indexed_auto 0 worldviewproj_matrix
     	param_indexed_auto 4 texture_viewproj_matrix
     }

For the purposes of writing this alternate program, there is an automatic parameter binding of 'texture_viewproj_matrix' which provides the program with texture projection parameters. The vertex program should do it's normal vertex processing, and generate texture coordinates using this matrix and place them in texture coord sets 0 and 1, since some shadow techniques use 2 texture units. The colour of the vertices output by this vertex program must always be white, so as not to affect the final colour of the rendered shadow.

When using additive texture shadows, the shadow pass render is actually the lighting render, so if you perform any fragment program lighting you also need to pull in a custom fragment program. You use the shadow_receiver_fragment_program_ref for this:

     shadow_receiver_fragment_program_ref myShadowReceiverFragmentProgram
     {
     	param_named_auto lightDiffuse light_diffuse_colour 0
     }

You should pass the projected shadow coordinates from the custom vertex program. As for textures, texture unit 0 will always be the shadow texture. Any other textures which you bind in your pass will be carried across too, but will be moved up by 1 unit to make room for the shadow texture. Therefore your shadow receiver fragment program is likely to be the same as the bare lighting pass of your normal material, except that you insert an extra texture sampler at index 0, which you will use to adjust the result by (modulating diffuse and specular components).

Vertex Texture Fetch
--------------------

Introduction
------------

More recent generations of video card allow you to perform a read from a texture in the vertex program rather than just the fragment program, as is traditional. This allows you to, for example, read the contents of a texture and displace vertices based on the intensity of the colour contained within.

Declaring the use of vertex texture fetching
--------------------------------------------

Since hardware support for vertex texture fetching is not ubiquitous, you should use the uses_vertex_texture_fetch (see Vertex texture fetching in vertex programs) directive when declaring your vertex programs which use vertex textures, so that if it is not supported, technique fallback can be enabled. This is not strictly necessary for DirectX-targeted shaders, since vertex texture fetching is only supported in vs_3_0, which can be stated as a required syntax in your shader definition, but for OpenGL (GLSL), there are cards which support GLSL but not vertex textures, so you should be explicit about your need for them.

Render system texture binding differences
-----------------------------------------

Unfortunately the method for binding textures so that they are available to a vertex program is not well standardised. As at the time of writing, Shader Model 3.0 (SM3.0) hardware under DirectX9 include 4 separate sampler bindings for the purposes of vertex textures. OpenGL, on the other hand, is able to access vertex textures in GLSL (and in assembler through NV_vertex_program_3, although this is less popular), but the textures are shared with the fragment pipeline. I expect DirectX to move to the GL model with the advent of DirectX10, since a unified shader architecture implies sharing of texture resources between the two stages. As it is right now though, we're stuck with an inconsistent situation.

To reflect this, you should use the binding_type attribute in a texture unit to indicate which unit you are targeting with your texture - 'fragment' (the default) or 'vertex'. For render systems that don't have separate bindings, this actually does nothing. But for those that do, it will ensure your texture gets bound to the right processing unit.

Note that whilst DirectX9 has separate bindings for the vertex and fragment pipelines, binding a texture to the vertex processing unit still uses up a 'slot' which is then not available for use in the fragment pipeline. I didn't manage to find this documented anywhere, but the nVidia samples certainly avoid binding a texture to the same index on both vertex and fragment units, and when I tried to do it, the texture did not appear correctly in the fragment unit, whilst it did as soon as I moved it into the next unit.

Texture format limitations
--------------------------

Again as at the time of writing, the types of texture you can use in a vertex program are limited to 1- or 4-component, full precision floating point formats. In code that equates to PF_FLOAT32_R or PF_FLOAT32_RGBA. No other formats are supported. In addition, the textures must be regular 2D textures (no cube or volume maps) and mipmapping and filtering is not supported, although you can perform filtering in your vertex program if you wish by sampling multiple times.

Hardware limitations
--------------------

As at the time of writing (early Q3 2006), ATI do not support texture fetch in their current crop of cards (Radeon X1n00). nVidia do support it in both their 6n00 and 7n00 range. ATI support an alternative called 'Render to Vertex Buffer', but this is not standardised at this time and is very much different in its implementation, so cannot be considered to be a drop-in replacement. This is the case even though the Radeon X1n00 cards claim to support vs_3_0 (which requires vertex texture fetch).

     [file MaterialScriptCopy.inc not included]

     [file CompositorScript.inc not included]

Particle Scripts
================

Particle scripts allow you to define particle systems to be instantiated in your code without having to hard-code the settings themselves in your source code, allowing a very quick turnaround on any changes you make. Particle systems which are defined in scripts are used as templates, and multiple actual systems can be created from them at runtime.

Loading scripts
===============

Particle system scripts are loaded at initialisation time by the system: by default it looks in all common resource locations (see Root::addResourceLocation) for files with the '.particle' extension and parses them. If you want to parse files with a different extension, use the ParticleSystemManager::getSingleton().parseAllSources method with your own extension, or if you want to parse an individual file, use ParticleSystemManager::getSingleton().parseScript.

Once scripts have been parsed, your code is free to instantiate systems based on them using the SceneManager::createParticleSystem() method which can take both a name for the new system, and the name of the template to base it on (this template name is in the script).

Format
======

Several particle systems may be defined in a single script. The script format is pseudo-C++, with sections delimited by curly braces (), and comments indicated by starting a line with '//' (note, no nested form comments allowed). The general format is shown below in a typical example:

     // A sparkly purple fountain
     particle_system Examples/PurpleFountain
     {
         material Examples/Flare2
         particle_width 20
         particle_height 20
         cull_each false
         quota 10000
         billboard_type oriented_self

         // Area emitter
         emitter Point
         {
             angle 15
             emission_rate 75
             time_to_live 3
             direction 0 1 0
             velocity_min 250
             velocity_max 300
             colour_range_start 1 0 0
             colour_range_end 0 0 1
         }

         // Gravity
         affector LinearForce
         {
             force_vector 0 -100 0
             force_application add
         }

         // Fader
         affector ColourFader
         {
             red -0.25
             green -0.25
             blue -0.25
         }
     }

Every particle system in the script must be given a name, which is the line before the first opening '', in the example this is 'Examples/PurpleFountain'. This name must be globally unique. It can include path characters (as in the example) to logically divide up your particle systems, and also to avoid duplicate names, but the engine does not treat the name as hierarchical, just as a string.

A system can have top-level attributes set using the scripting commands available, such as 'quota' to set the maximum number of particles allowed in the system. Emitters (which create particles) and affectors (which modify particles) are added as nested definitions within the script. The parameters available in the emitter and affector sections are entirely dependent on the type of emitter / affector.

For a detailed description of the core particle system attributes, see the list below:

Available Particle System Attributes
------------------------------------

  * quota

  * material

  * particle_width

  * particle_height

  * cull_each

  * billboard_type

  * billboard_origin

  * billboard_rotation_type

  * common_direction

  * common_up_vector

  * renderer

  * sorted

  * local_space

  * point_rendering

  * accurate_facing

  * iteration_interval

  * nonvisible_update_timeout

See also: Particle Emitters, Particle Affectors

Particle System Attributes
--------------------------

This section describes to attributes which you can set on every particle system using scripts. All attributes have default values so all settings are optional in your script.

quota
-----

Sets the maximum number of particles this system is allowed to contain at one time. When this limit is exhausted, the emitters will not be allowed to emit any more particles until some destroyed (e.g. through their time_to_live running out). Note that you will almost always want to change this, since it defaults to a very low value (particle pools are only ever increased in size, never decreased).

format: quota <max_particles>

example: quota 10000

default: 10

material
--------

Sets the name of the material which all particles in this system will use. All particles in a system use the same material, although each particle can tint this material through the use of it's colour property.

format: material <material_name>

example: material Examples/Flare

default: none (blank material)

particle_width
--------------

Sets the width of particles in world coordinates. Note that this property is absolute when billboard_type (see below) is set to 'point' or 'perpendicular_self', but is scaled by the length of the direction vector when billboard_type is 'oriented_common', 'oriented_self' or 'perpendicular_common'.

format: particle_width <width>

example: particle_width 20

default: 100

particle_height
---------------

Sets the height of particles in world coordinates. Note that this property is absolute when billboard_type (see below) is set to 'point' or 'perpendicular_self', but is scaled by the length of the direction vector when billboard_type is 'oriented_common', 'oriented_self' or 'perpendicular_common'.

format: particle_height <height>

example: particle_height 20

default: 100

cull_each
---------

All particle systems are culled by the bounding box which contains all the particles in the system. This is normally sufficient for fairly locally constrained particle systems where most particles are either visible or not visible together. However, for those that spread particles over a wider area (e.g. a rain system), you may want to actually cull each particle individually to save on time, since it is far more likely that only a subset of the particles will be visible. You do this by setting the cull_each parameter to true.

format: cull_each <true|false>

example: cull_each true

default: false

renderer
--------

Particle systems do not render themselves, they do it through ParticleRenderer classes. Those classes are registered with a manager in order to provide particle systems with a particular 'look'. OGRE comes configured with a default billboard-based renderer, but more can be added through plugins. Particle renders are registered with a unique name, and you can use that name in this attribute to determine the renderer to use. The default is 'billboard'.

Particle renderers can have attributes, which can be passed by setting them on the root particle system.

format: renderer <renderer_name>

default: billboard

sorted
------

By default, particles are not sorted. By setting this attribute to 'true', the particles will be sorted with respect to the camera, furthest first. This can make certain rendering effects look better at a small sorting expense.

format: sorted <true|false>

default: false

local_space
-----------

By default, particles are emitted into world space, such that if you transform the node to which the system is attached, it will not affect the particles (only the emitters). This tends to give the normal expected behaviour, which is to model how real world particles travel independently from the objects they are emitted from. However, to create some effects you may want the particles to remain attached to the local space the emitter is in and to follow them directly. This option allows you to do that.

format: local_space <true|false>

default: false

billboard_type
--------------

This is actually an attribute of the 'billboard' particle renderer (the default), and is an example of passing attributes to a particle renderer by declaring them directly within the system declaration. Particles using the default renderer are rendered using billboards, which are rectangles formed by 2 triangles which rotate to face the given direction. However, there is more than 1 way to orient a billboard. The classic approach is for the billboard to directly face the camera: this is the default behaviour. However this arrangement only looks good for particles which are representing something vaguely spherical like a light flare. For more linear effects like laser fire, you actually want the particle to have an orientation of it's own.

format: billboard_type <point|oriented_common|oriented_self|perpendicular_common|perpendicular_self>

example: billboard_type oriented_self

default: point

The options for this parameter are:

point
     The default arrangement, this approximates spherical particles and the billboards always fully face the camera.

oriented_common
     Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below).

oriented_self
     Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction.

perpendicular_common
     Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below).

perpendicular_self
     Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for rings stack etc where the particles will perpendicular to their traveling direction.

billboard_origin
----------------

Specifying the point which acts as the origin point for all billboard particles, controls the fine tuning of where a billboard particle appears in relation to it's position.

format: billboard_origin <top_left|top_center|top_right|center_left|center|center_right|bottom_left|bottom_center|bottom_right>

example: billboard_origin top_right

default: center

The options for this parameter are:

top_left
     The billboard origin is the top-left corner.

top_center
     The billboard origin is the center of top edge.

top_right
     The billboard origin is the top-right corner.

center_left
     The billboard origin is the center of left edge.

center
     The billboard origin is the center.

center_right
     The billboard origin is the center of right edge.

bottom_left
     The billboard origin is the bottom-left corner.

bottom_center
     The billboard origin is the center of bottom edge.

bottom_right
     The billboard origin is the bottom-right corner.

billboard_rotation_type
-----------------------

By default, billboard particles will rotate the texture coordinates to according with particle rotation. But rotate texture coordinates has some disadvantage, e.g. the corners of the texture will lost after rotate, and the corners of the billboard will fill with unwanted texture area when using wrap address mode or sub-texture sampling. This settings allow you specifying other rotation type.

format: billboard_rotation_type <vertex|texcoord>

example: billboard_rotation_type vertex

default: texcoord

The options for this parameter are:

vertex
     Billboard particles will rotate the vertices around their facing direction to according with particle rotation. Rotate vertices guarantee texture corners exactly match billboard corners, thus has advantage mentioned above, but should take more time to generate the vertices.

texcoord
     Billboard particles will rotate the texture coordinates to according with particle rotation. Rotate texture coordinates is faster than rotate vertices, but has some disadvantage mentioned above.

common_direction
----------------

Only required if billboard_type is set to oriented_common or perpendicular_common, this vector is the common direction vector used to orient all particles in the system.

format: common_direction <x> <y> <z>

example: common_direction 0 -1 0

default: 0 0 1

See also: Particle Emitters, Particle Affectors

common_up_vector
----------------

Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.

format: common_up_vector <x> <y> <z>

example: common_up_vector 0 1 0

default: 0 1 0

See also: Particle Emitters, Particle Affectors

point_rendering
---------------

This is actually an attribute of the 'billboard' particle renderer (the default), and sets whether or not the BillboardSet will use point rendering rather than manually generated quads.

By default a BillboardSet is rendered by generating geometry for a textured quad in memory, taking into account the size and orientation settings, and uploading it to the video card. The alternative is to use hardware point rendering, which means that	only one position needs to be sent per billboard rather than 4 and	the hardware sorts out how this is rendered based on the render	state.

Using point rendering is faster than generating quads manually, but	is more restrictive. The following restrictions apply:

  * Only the 'point' orientation type is supported

  * Size and appearance of each particle is controlled by the material pass (point_size, point_size_attenuation, point_sprites)

  * Per-particle size is not supported (stems from the above)

  * Per-particle rotation is not supported, and this can only be controlled through texture unit rotation in the material definition

  * Only 'center' origin is supported

  * Some drivers have an upper limit on the size of points they support - this can even vary between APIs on the same card! Don't rely on point sizes that cause the point sprites to get very large on screen, since they may get clamped on some cards. Upper sizes can range from 64 to 256 pixels.

You will almost certainly want to enable in your material pass both point attenuation and point sprites if you use this option.

accurate_facing
---------------

This is actually an attribute of the 'billboard' particle renderer (the default), and sets whether or not the BillboardSet will use a slower but more accurate calculation for facing the billboard to the camera. Bt default it uses the camera direction, which is faster but means the billboards don't stay in the same orientation as you rotate the camera. The 'accurate_facing true' option makes the calculation based on a vector from each billboard to the camera, which means the orientation is constant even whilst the camera rotates.

format: accurate_facing on|off

default: accurate_facing off 0

iteration_interval
------------------

Usually particle systems are updated based on the frame rate; however this can give variable results with more extreme frame rate ranges, particularly at lower frame rates. You can use this option to make the update frequency a fixed interval, whereby at lower frame rates, the particle update will be repeated at the fixed interval until the frame time is used up. A value of 0 means the default frame time iteration.

format: iteration_interval <secs>

example: iteration_interval 0.01

default: iteration_interval 0

nonvisible_update_timeout
-------------------------

Sets when the particle system should stop updating after it hasn't been visible for a while. By default, visible particle systems update all the time, even when not in view. This means that they are guaranteed to be consistent when they do enter view. However, this comes at a cost, updating particle systems can be expensive, especially if they are perpetual. This option lets you set a 'timeout' on the particle system, so that if it isn't visible for this amount of time, it will stop updating	until it is next visible. A value of 0 disables the timeout and always updates.

format: nonvisible_update_timeout <secs>

example: nonvisible_update_timeout 10

default: nonvisible_update_timeout 0

Particle Emitters
-----------------

Particle emitters are classified by 'type' e.g. 'Point' emitters emit from a single point whilst 'Box' emitters emit randomly from an area. New emitters can be added to Ogre by creating plugins. You add an emitter to a system by nesting another section within it, headed with the keyword 'emitter' followed by the name of the type of emitter (case sensitive). Ogre currently supports 'Point', 'Box', 'Cylinder', 'Ellipsoid', 'HollowEllipsoid' and 'Ring' emitters.

It is also possible to 'emit emitters' - that is, have new emitters spawned based on the position of particles. See Emitting Emitters

Particle Emitter Universal Attributes
-------------------------------------

  * angle

  * colour

  * colour_range_start

  * colour_range_end

  * direction

  * emission_rate

  * position

  * velocity

  * velocity_min

  * velocity_max

  * time_to_live

  * time_to_live_min

  * time_to_live_max

  * duration

  * duration_min

  * duration_max

  * repeat_delay

  * repeat_delay_min

  * repeat_delay_max

See also: Particle Scripts, Particle Affectors

Particle Emitter Attributes
---------------------------

This section describes the common attributes of all particle emitters. Specific emitter types may also support their own extra attributes.

angle
-----

Sets the maximum angle (in degrees) which emitted particles may deviate from the direction of the emitter (see direction). Setting this to 10 allows particles to deviate up to 10 degrees in any direction away from the emitter's direction. A value of 180 means emit in any direction, whilst 0 means emit always exactly in the direction of the emitter.

format: angle <degrees>

example: angle 30

default: 0

colour
------

Sets a static colour for all particle emitted. Also see the colour_range_start and colour_range_end attributes for setting a range of colours. The format of the colour parameter is "r g b a", where each component is a value from 0 to 1, and the alpha value is optional (assumes 1 if not specified).

format: colour <r> <g> <b> [<a>]

example: colour 1 0 0 1

default: 1 1 1 1

colour_range_start & colour_range_end
-------------------------------------

As the 'colour' attribute, except these 2 attributes must be specified together, and indicate the range of colours available to emitted particles. The actual colour will be randomly chosen between these 2 values.

format: as colour

example (generates random colours between red and blue):

    colour_range_start 1 0 0

    colour_range_end 0 0 1

default: both 1 1 1 1

direction
---------

Sets the direction of the emitter. This is relative to the SceneNode which the particle system is attached to, meaning that as with other movable objects changing the orientation of the node will also move the emitter.

format: direction <x> <y> <z>

example: direction 0 1 0

default: 1 0 0

emission_rate
-------------

Sets how many particles per second should be emitted. The specific emitter does not have to emit these in a continuous burst - this is a relative parameter and the emitter may choose to emit all of the second's worth of particles every half-second for example, the behaviour depends on the emitter. The emission rate will also be limited by the particle system's 'quota' setting.

format: emission_rate <particles_per_second>

example: emission_rate 50

default: 10

position
--------

Sets the position of the emitter relative to the SceneNode the particle system is attached to.

format: position <x> <y> <z>

example: position 10 0 40

default: 0 0 0

velocity
--------

Sets a constant velocity for all particles at emission time. See also the velocity_min and velocity_max attributes which allow you to set a range of velocities instead of a fixed one.

format: velocity <world_units_per_second>

example: velocity 100

default: 1

velocity_min & velocity_max
---------------------------

As 'velocity' except these attributes set a velocity range and each particle is emitted with a random velocity within this range.

format: as velocity

example:

    velocity_min 50

    velocity_max 100

default: both 1

time_to_live
------------

Sets the number of seconds each particle will 'live' for before being destroyed. NB it is possible for particle affectors to alter this in flight, but this is the value given to particles on emission. See also the time_to_live_min and time_to_live_max attributes which let you set a lifetime range instead of a fixed one.

format: time_to_live <seconds>

example: time_to_live 10

default: 5

time_to_live_min & time_to_live_max
-----------------------------------

As time_to_live, except this sets a range of lifetimes and each particle gets a random value in-between on emission.

format: as time_to_live

example:

    time_to_live_min 2

    time_to_live_max 5

default: both 5

duration
--------

Sets the number of seconds the emitter is active. The emitter can be started again, see repeat_delay. A value of 0 means infinite duration. See also the duration_min and duration_max attributes which let you set a duration range instead of a fixed one.

format: duration <seconds>

example:

    duration 2.5

default: 0

duration_min & duration_max
---------------------------

As duration, except these attributes set a variable time range between the min and max values each time the emitter is started.

format: as duration

example:

    duration_min 2

    duration_max 5

default: both 0

repeat_delay
------------

Sets the number of seconds to wait before the emission is repeated when stopped by a limited duration. See also the repeat_delay_min and repeat_delay_max attributes which allow you to set a range of repeat_delays instead of a fixed one.

format: repeat_delay <seconds>

example:

    repeat_delay 2.5

default: 0

repeat_delay_min & repeat_delay_max
-----------------------------------

As repeat_delay, except this sets a range of repeat delays and each time the emitter is started it gets a random value in-between.

format: as repeat_delay

example:

    repeat_delay 2

    repeat_delay 5

default: both 0

See also: Standard Particle Emitters, Particle Scripts, Particle Affectors

Standard Particle Emitters
--------------------------

Ogre comes preconfigured with a few particle emitters. New ones can be added by creating plugins: see the Plugin_ParticleFX project as an example of how you would do this (this is where these emitters are implemented).

  * Point Emitter

  * Box Emitter

  * Cylinder Emitter

  * Ellipsoid Emitter

  * Hollow Ellipsoid Emitter

  * Ring Emitter

Point Emitter
-------------

This emitter emits particles from a single point, which is it's position. This emitter has no additional attributes over an above the standard emitter attributes.

To create a point emitter, include a section like this within your particle system script:

     emitter Point
     {
         // Settings go here
     }

Please note that the name of the emitter ('Point') is case-sensitive.

Box Emitter
-----------

This emitter emits particles from a random location within a 3-dimensional box. It's extra attributes are:

width
     Sets the width of the box (this is the size of the box along it's local X axis, which is dependent on the 'direction' attribute which forms the box's local Z).

     format: width <units>

     example: width 250

     default: 100

height
     Sets the height of the box (this is the size of the box along it's local Y axis, which is dependent on the 'direction' attribute which forms the box's local Z).

     format: height <units>

     example: height 250

     default: 100

depth
     Sets the depth of the box (this is the size of the box along it's local Z axis, which is the same as the 'direction' attribute).

     format: depth <units>

     example: depth 250

     default: 100

To create a box emitter, include a section like this within your particle system script:

     emitter Box
     {
         // Settings go here
     }

Cylinder Emitter
----------------

This emitter emits particles in a random direction from within a cylinder area, where the cylinder is oriented along the Z-axis. This emitter has exactly the same parameters as the Box Emitter so there are no additional parameters to consider here - the width and height determine the shape of the cylinder along it's axis (if they are different it is an ellipsoid cylinder), the depth determines the length of the cylinder.

Ellipsoid Emitter
-----------------

This emitter emits particles from within an ellipsoid shaped area, i.e. a sphere or squashed-sphere area. The parameters are again identical to the Box Emitter, except that the dimensions describe the widest points along each of the axes.

Hollow Ellipsoid Emitter
------------------------

This emitter is just like Ellipsoid Emitter except that there is a hollow area in the centre of the ellipsoid from which no particles are emitted. Therefore it has 3 extra parameters in order to define this area:

inner_width
     The width of the inner area which does not emit any particles.

inner_height
     The height of the inner area which does not emit any particles.

inner_depth
     The depth of the inner area which does not emit any particles.

Ring Emitter
------------

This emitter emits particles from a ring-shaped area, i.e. a little like Hollow Ellipsoid Emitter except only in 2 dimensions.

inner_width
     The width of the inner area which does not emit any particles.

inner_height
     The height of the inner area which does not emit any particles.

See also: Particle Scripts, Particle Emitters

Emitting Emitters
-----------------

It is possible to spawn new emitters on the expiry of particles, for example to product 'firework' style effects. This is controlled via the following directives:

emit_emitter_quota
     This parameter is a system-level parameter telling the system how many emitted emitters may be in use at any one time. This is just to allow for the space allocation process.

name
     This parameter is an emitter-level parameter, giving a name to an emitter. This can then be referred to in another emitter as the new emitter type to spawn when an emitted particle dies.

emit_emitter
     This is an emitter-level parameter, and if specified, it means that when particles emitted by this emitter die, they spawn a new emitter of the named type.

Particle Affectors
------------------

Particle affectors modify particles over their lifetime. They are classified by 'type' e.g. 'LinearForce' affectors apply a force to all particles, whilst 'ColourFader' affectors alter the colour of particles in flight. New affectors can be added to Ogre by creating plugins. You add an affector to a system by nesting another section within it, headed with the keyword 'affector' followed by the name of the type of affector (case sensitive). Ogre currently supports 'LinearForce' and 'ColourFader' affectors.

Particle affectors actually have no universal attributes; they are all specific to the type of affector.

See also: Standard Particle Affectors, Particle Scripts, Particle Emitters

Standard Particle Affectors
---------------------------

Ogre comes preconfigured with a few particle affectors. New ones can be added by creating plugins: see the Plugin_ParticleFX project as an example of how you would do this (this is where these affectors are implemented).

  * Linear Force Affector

  * ColourFader Affector

  * ColourFader2 Affector

  * Scaler Affector

  * Rotator Affector

  * ColourInterpolator Affector

  * ColourImage Affector

  * DeflectorPlane Affector

  * DirectionRandomiser Affector

Linear Force Affector
---------------------

This affector applies a force vector to all particles to modify their trajectory. Can be used for gravity, wind, or any other linear force. It's extra attributes are:

force_vector
     Sets the vector for the force to be applied to every particle. The magnitude of this vector determines how strong the force is.

         format: force_vector <x> <y> <z>

         example: force_vector 50 0 -50

         default: 0 -100 0 (a fair gravity effect)

force_application

     Sets the way in which the force vector is applied to particle momentum.

         format: force_application <add|average>

         example: force_application average

         default: add

     The options are:

     average
          The resulting momentum is the average of the force vector and the particle's current motion. Is self-stabilising but the speed at which the particle changes direction is non-linear.

     add
          The resulting momentum is the particle's current motion plus the force vector. This is traditional force acceleration but can potentially result in unlimited velocity.

To create a linear force affector, include a section like this within your particle system script:

     affector LinearForce
     {
         // Settings go here
     }

Please note that the name of the affector type ('LinearForce') is case-sensitive.

ColourFader Affector
--------------------

This affector modifies the colour of particles in flight. It's extra attributes are:

red
     Sets the adjustment to be made to the red component of the particle colour per second.

         format: red <delta_value>

         example: red -0.1

         default: 0

green
     Sets the adjustment to be made to the green component of the particle colour per second.

         format: green <delta_value>

         example: green -0.1

         default: 0

blue
     Sets the adjustment to be made to the blue component of the particle colour per second.

         format: blue <delta_value>

         example: blue -0.1

         default: 0

alpha
     Sets the adjustment to be made to the alpha component of the particle colour per second.

         format: alpha <delta_value>

     example: alpha -0.1

     default: 0

To create a colour fader affector, include a section like this within your particle system script:

     affector ColourFader
     {
         // Settings go here
     }

ColourFader2 Affector
---------------------

This affector is similar to the ColourFader Affector, except it introduces two states of colour changes as opposed to just one. The second colour change state is activated once a specified amount of time remains in the particles life.

red1
     Sets the adjustment to be made to the red component of the particle colour per second for the first state.

         format: red <delta_value>

         example: red -0.1

         default: 0

green1
     Sets the adjustment to be made to the green component of the particle colour per second for the first state.

         format: green <delta_value>

         example: green -0.1

         default: 0

blue1
     Sets the adjustment to be made to the blue component of the particle colour per second for the first state.

         format: blue <delta_value>

         example: blue -0.1

         default: 0

alpha1
     Sets the adjustment to be made to the alpha component of the particle colour per second for the first state.

         format: alpha <delta_value>

     example: alpha -0.1

     default: 0

red2
     Sets the adjustment to be made to the red component of the particle colour per second for the second state.

         format: red <delta_value>

         example: red -0.1

         default: 0

green2
     Sets the adjustment to be made to the green component of the particle colour per second for the second state.

         format: green <delta_value>

         example: green -0.1

         default: 0

blue2
     Sets the adjustment to be made to the blue component of the particle colour per second for the second state.

         format: blue <delta_value>

         example: blue -0.1

         default: 0

alpha2
     Sets the adjustment to be made to the alpha component of the particle colour per second for the second state.

         format: alpha <delta_value>

     example: alpha -0.1

     default: 0

state_change
     When a particle has this much time left to live, it will switch to state 2.

         format: state_change <seconds>

     example: state_change 2

     default: 1

To create a ColourFader2 affector, include a section like this within your particle system script:

     affector ColourFader2
     {
         // Settings go here
     }

Scaler Affector
---------------

This affector scales particles in flight. It's extra attributes are:

rate
     The amount by which to scale the particles in both the x and y direction per second.

To create a scale affector, include a section like this within your particle system script:

     affector Scaler
     {
         // Settings go here
     }

Rotator Affector
----------------

This affector rotates particles in flight. This is done by rotating the texture. It's extra attributes are:

rotation_speed_range_start
     The start of a range of rotation speeds to be assigned to emitted particles.

         format: rotation_speed_range_start <degrees_per_second>

     example: rotation_speed_range_start 90

     default: 0

rotation_speed_range_end
     The end of a range of rotation speeds to be assigned to emitted particles.

         format: rotation_speed_range_end <degrees_per_second>

     example: rotation_speed_range_end 180

     default: 0

rotation_range_start
     The start of a range of rotation angles to be assigned to emitted particles.

         format: rotation_range_start <degrees>

     example: rotation_range_start 0

     default: 0

rotation_range_end
     The end of a range of rotation angles to be assigned to emitted particles.

         format: rotation_range_end <degrees>

     example: rotation_range_end 360

     default: 0

To create a rotate affector, include a section like this within your particle system script:

     affector Rotator
     {
         // Settings go here
     }

ColourInterpolator Affector
---------------------------

Similar to the ColourFader and ColourFader2 Affector?s, this affector modifies the colour of particles in flight, except it has a variable number of defined stages. It swaps the particle colour for several stages in the life of a particle and interpolates between them. It's extra attributes are:

time0
     The point in time of stage 0.

         format: time0 <0-1 based on lifetime>

     example: time0 0

     default: 1

colour0
     The colour at stage 0.

         format: colour0 <r> <g> <b> [<a>]

     example: colour0 1 0 0 1

     default: 0.5 0.5 0.5 0.0

time1
     The point in time of stage 1.

         format: time1 <0-1 based on lifetime>

     example: time1 0.5

     default: 1

colour1
     The colour at stage 1.

         format: colour1 <r> <g> <b> [<a>]

     example: colour1 0 1 0 1

     default: 0.5 0.5 0.5 0.0

time2
     The point in time of stage 2.

         format: time2 <0-1 based on lifetime>

     example: time2 1

     default: 1

colour2
     The colour at stage 2.

         format: colour2 <r> <g> <b> [<a>]

     example: colour2 0 0 1 1

     default: 0.5 0.5 0.5 0.0

[...]

The number of stages is variable. The maximal number of stages is 6; where time5 and colour5 are the last possible parameters. To create a colour interpolation affector, include a section like this within your particle system script:

     affector ColourInterpolator
     {
         // Settings go here
     }

ColourImage Affector
--------------------

This is another affector that modifies the colour of particles in flight, but instead of programmatically defining colours, the colours are taken from a specified image file. The range of colour values begins from the left side of the image and move to the right over the lifetime of the particle, therefore only the horizontal dimension of the image is used. Its extra attributes are:

image
     The start of a range of rotation speed to be assigned to emitted particles.

         format: image <image_name>

     example: image rainbow.png

     default: none

To create a ColourImage affector, include a section like this within your particle system script:

     affector ColourImage
     {
         // Settings go here
     }

DeflectorPlane Affector
-----------------------

This affector defines a plane which deflects particles which collide with it. The attributes are:

plane_point
     A point on the deflector plane. Together with the normal vector it defines the plane.

     default: plane_point 0 0 0

plane_normal
     The normal vector of the deflector plane. Together with the point it defines the plane.

     default: plane_normal 0 1 0

bounce
     The amount of bouncing when a particle is deflected. 0 means no deflection and 1 stands for 100 percent reflection.

     default: bounce 1.0

DirectionRandomiser Affector
----------------------------

This affector applies randomness to the movement of the particles. Its extra attributes are:

randomness
     The amount of randomness to introduce in each axial direction.

     example: randomness 5

     default: randomness 1

scope
     The percentage of particles affected in each run of the affector.

     example: scope 0.5

     default: scope 1.0

keep_velocity
     Determines whether the velocity of particles is unchanged.

     example: keep_velocity true

     default: keep_velocity false

Overlay Scripts
===============

Overlay scripts offer you the ability to define overlays in a script which can be reused easily. Whilst you could set up all overlays for a scene in code using the methods of the SceneManager, Overlay and OverlayElement classes, in practice it's a bit unwieldy. Instead you can store overlay definitions in text files which can then be loaded whenever required.

Loading scripts
===============

Overlay scripts are loaded at initialisation time by the system: by default it looks in all common resource locations (see Root::addResourceLocation) for files with the '.overlay' extension and parses them. If you want to parse files with a different extension, use the OverlayManager::getSingleton().parseAllSources method with your own extension, or if you want to parse an individual file, use OverlayManager::getSingleton().parseScript.

Format
======

Several overlays may be defined in a single script. The script format is pseudo-C++, with sections delimited by curly braces (), comments indicated by starting a line with '//' (note, no nested form comments allowed), and inheritance through the use of templates. The general format is shown below in a typical example:

     // The name of the overlay comes first
     MyOverlays/ANewOverlay
     {
         zorder 200

         container Panel(MyOverlayElements/TestPanel)
         {
             // Center it horizontally, put it at the top
             left 0.25
             top 0
             width 0.5
             height 0.1
             material MyMaterials/APanelMaterial

             // Another panel nested in this one
             container Panel(MyOverlayElements/AnotherPanel)
             {
                  left 0
                  top 0
                  width 0.1
                  height 0.1
                  material MyMaterials/NestedPanel
             }
         }

     }

The above example defines a single overlay called 'MyOverlays/ANewOverlay', with 2 panels in it, one nested under the other. It uses relative metrics (the default if no metrics_mode option is found).

Every overlay in the script must be given a name, which is the line before the first opening ''. This name must be globally unique. It can include path characters (as in the example) to logically divide up your overlays, and also to avoid duplicate names, but the engine does not treat the name a hierarchical, just as a string. Within the braces are the properties of the overlay, and any nested elements. The overlay itself only has a single property 'zorder' which determines how 'high' it is in the stack of overlays if more than one is displayed at the same time. Overlays with higher zorder values are displayed on top.

Adding elements to the overlay
==============================

Within an overlay, you can include any number of 2D or 3D elements. You do this by defining a nested block headed by:

'element'
     if you want to define a 2D element which cannot have children of it's own

'container'
     if you want to define a 2D container object (which may itself have nested containers or elements)

The element and container blocks are pretty identical apart from their ability to store nested blocks.

'container' / 'element' blocks
==============================

These are delimited by curly braces. The format for the header preceding the first brace is:

[container | element] <type_name> ( <instance_name>) [: <template_name>]

 ...

type_name
     Must resolve to the name of a OverlayElement type which has been registered with the OverlayManager. Plugins register with the OverlayManager to advertise their ability to create elements, and at this time advertise the name of the type. OGRE comes preconfigured with types 'Panel', 'BorderPanel' and 'TextArea'.

instance_name
     Must be a name unique among all other elements / containers by which to identify the element. Note that you can obtain a pointer to any named element by calling OverlayManager::getSingleton().getOverlayElement(name).

template_name
     Optional template on which to base this item. See templates.

The properties which can be included within the braces depend on the custom type. However the following are always valid:

  * metrics_mode

  * horz_align

  * vert_align

  * left

  * top

  * width

  * height

  * material

  * caption

Templates
=========

You can use templates to create numerous elements with the same properties. A template is an abstract element and it is not added to an overlay. It acts as a base class that elements can inherit and get its default properties. To create a template, the keyword 'template' must be the first word in the element definition (before container or element). The template element is created in the topmost scope - it is NOT specified in an Overlay. It is recommended that you define templates in a separate overlay though this is not essential. Having templates defined in a separate file will allow different look & feels to be easily substituted.

Elements can inherit a template in a similar way to C++ inheritance - by using the : operator on the element definition. The : operator is placed after the closing bracket of the name (separated by a space). The name of the template to inherit is then placed after the : operator (also separated by a space).

A template can contain template children which are created when the template is subclassed and instantiated. Using the template keyword for the children of a template is optional but recommended for clarity, as the children of a template are always going to be templates themselves.

     template container BorderPanel(MyTemplates/BasicBorderPanel)
     {
         left 0
         top 0
         width 1
         height 1

     // setup the texture UVs for a borderpanel

     // do this in a template so it doesn't need to be redone everywhere
         material Core/StatsBlockCenter
         border_size 0.05 0.05 0.06665 0.06665
         border_material Core/StatsBlockBorder
         border_topleft_uv 0.0000 1.0000 0.1914 0.7969
         border_top_uv 0.1914 1.0000 0.8086 0.7969
         border_topright_uv 0.8086 1.0000 1.0000 0.7969
         border_left_uv 0.0000 0.7969 0.1914 0.2148
         border_right_uv 0.8086 0.7969 1.0000 0.2148
         border_bottomleft_uv 0.0000 0.2148 0.1914 0.0000
         border_bottom_uv 0.1914 0.2148 0.8086 0.0000
         border_bottomright_uv 0.8086 0.2148 1.0000 0.0000
     }
     template container Button(MyTemplates/BasicButton) : MyTemplates/BasicBorderPanel
     {
         left 0.82
         top 0.45
         width 0.16
         height 0.13
         material Core/StatsBlockCenter
         border_up_material Core/StatsBlockBorder/Up
         border_down_material Core/StatsBlockBorder/Down
     }
     template element TextArea(MyTemplates/BasicText)
     {
         font_name Ogre
         char_height 0.08
         colour_top 1 1 0
         colour_bottom 1 0.2 0.2
         left 0.03
         top 0.02
         width 0.12
         height 0.09
     }

     MyOverlays/AnotherOverlay
     {
         zorder 490
         container BorderPanel(MyElements/BackPanel) : MyTemplates/BasicBorderPanel
         {
             left 0
             top 0
             width 1
             height 1

             container Button(MyElements/HostButton) : MyTemplates/BasicButton
             {
                 left 0.82
                 top 0.45
                 caption MyTemplates/BasicText HOST
             }

             container Button(MyElements/JoinButton) : MyTemplates/BasicButton
             {
                 left 0.82
                 top 0.60
                 caption MyTemplates/BasicText JOIN
             }
         }
     }

The above example uses templates to define a button. Note that the button template inherits from the borderPanel template. This reduces the number of attributes needed to instantiate a button.

Also note that the instantiate of a Button needs a template name for the caption attribute. So templates can also be used by elements that need dynamic creation of children elements (the button creates a TextAreaElement in this case for its caption).

See OverlayElement Attributes, Standard OverlayElements

OverlayElement Attributes
-------------------------

These attributes are valid within the braces of a 'container' or 'element' block in an overlay script. They must each be on their own line. Ordering is unimportant.

metrics_mode
------------

Sets the units which will be used to size and position this element.

Format: metrics_mode <pixels|relative>

Example: metrics_mode pixels

This can be used to change the way that all measurement attributes in the rest of this element are interpreted. In relative mode, they are interpreted as being a parametric value from 0 to 1, as a proportion of the width / height of the screen. In pixels mode, they are simply pixel offsets.

Default: metrics_mode relative

horz_align
----------

Sets the horizontal alignment of this element, in terms of where the horizontal origin is.

Format: horz_align <left|center|right>

Example: horz_align center

This can be used to change where the origin is deemed to be for the purposes of any horizontal positioning attributes of this element. By default the origin is deemed to be the left edge of the screen, but if you change this you can center or right-align your elements. Note that setting the alignment to center or right does not automatically force your elements to appear in the center or the right edge, you just have to treat that point as the origin and adjust your coordinates appropriately. This is more flexible because you can choose to position your element anywhere relative to that origin. For example, if your element was 10 pixels wide, you would use a 'left' property of -10 to align it exactly to the right edge, or -20 to leave a gap but still make it stick to the right edge.

Note that you can use this property in both relative and pixel modes, but it is most useful in pixel mode.

Default: horz_align left

vert_align
----------

Sets the vertical alignment of this element, in terms of where the vertical origin is.

Format: vert_align <top|center|bottom>

Example: vert_align center

This can be used to change where the origin is deemed to be for the purposes of any vertical positioning attributes of this element. By default the origin is deemed to be the top edge of the screen, but if you change this you can center or bottom-align your elements. Note that setting the alignment to center or bottom does not automatically force your elements to appear in the center or the bottom edge, you just have to treat that point as the origin and adjust your coordinates appropriately. This is more flexible because you can choose to position your element anywhere relative to that origin. For example, if your element was 50 pixels high, you would use a 'top' property of -50 to align it exactly to the bottom edge, or -70 to leave a gap but still make it stick to the bottom edge.

Note that you can use this property in both relative and pixel modes, but it is most useful in pixel mode.

Default: vert_align top

left
----

Sets the horizontal position of the element relative to it's parent.

Format: left <value>

Example: left 0.5

Positions are relative to the parent (the top-left of the screen if the parent is an overlay, the top-left of the parent otherwise) and are expressed in terms of a proportion of screen size. Therefore 0.5 is half-way across the screen.

Default: left 0

top
---

Sets the vertical position of the element relative to it's parent.

Format: top <value>

Example: top 0.5

Positions are relative to the parent (the top-left of the screen if the parent is an overlay, the top-left of the parent otherwise) and are expressed in terms of a proportion of screen size. Therefore 0.5 is half-way down the screen.

Default: top 0

width
-----

Sets the width of the element as a proportion of the size of the screen.

Format: width <value>

Example: width 0.25

Sizes are relative to the size of the screen, so 0.25 is a quarter of the screen. Sizes are not relative to the parent; this is common in windowing systems where the top and left are relative but the size is absolute.

Default: width 1

height
------

Sets the height of the element as a proportion of the size of the screen.

Format: height <value>

Example: height 0.25

Sizes are relative to the size of the screen, so 0.25 is a quarter of the screen. Sizes are not relative to the parent; this is common in windowing systems where the top and left are relative but the size is absolute.

Default: height 1

material
--------

Sets the name of the material to use for this element.

Format: material <name>

Example: material Examples/TestMaterial

This sets the base material which this element will use. Each type of element may interpret this differently; for example the OGRE element 'Panel' treats this as the background of the panel, whilst 'BorderPanel' interprets this as the material for the center area only. Materials should be defined in .material scripts.

Note that using a material in an overlay element automatically disables lighting and depth checking on this material. Therefore you should not use the same material as is used for real 3D objects for an overlay.

Default: none

caption
-------

Sets a text caption for the element.

Format: caption <string>

Example: caption This is a caption

Not all elements support captions, so each element is free to disregard this if it wants. However, a general text caption is so common to many elements that it is included in the generic interface to make it simpler to use. This is a common feature in GUI systems.

Default: blank

rotation
--------

Sets the rotation of the element.

Format: rotation <angle_in_degrees> <axis_x> <axis_y> <axis_z> Example: rotation 30 0 0 1

Default: none

Standard OverlayElements
------------------------

Although OGRE's OverlayElement and OverlayContainer classes are designed to be extended by applications developers, there are a few elements which come as standard with Ogre. These include:

  * Panel

  * BorderPanel

  * TextArea

This section describes how you define their custom attributes in an .overlay script, but you can also change these custom properties in code if you wish. You do this by calling setParameter(paramname, value). You may wish to use the StringConverter class to convert your types to and from strings.

Panel (container)
-----------------

This is the most bog-standard container you can use. It is a rectangular area which can contain other elements (or containers) and may or may not have a background, which can be tiled however you like. The background material is determined by the material attribute, but is only displayed if transparency is off.

Attributes:

transparent <true | false>
     If set to 'true' the panel is transparent and is not rendered itself, it is just used as a grouping level for it's children.

tiling <layer> <x_tile> <y_tile>
     Sets the number of times the texture(s) of the material are tiled across the panel in the x and y direction. <layer> is the texture layer, from 0 to the number of texture layers in the material minus one. By setting tiling per layer you can create some nice multitextured backdrops for your panels, this works especially well when you animate one of the layers.

uv_coords <topleft_u> <topleft_v> <bottomright_u> <bottomright_v>
     Sets the texture coordinates to use for this panel.

BorderPanel (container)
-----------------------

This is a slightly more advanced version of Panel, where instead of just a single flat panel, the panel has a separate border which resizes with the panel. It does this by taking an approach very similar to the use of HTML tables for bordered content: the panel is rendered as 9 square areas, with the center area being rendered with the main material (as with Panel) and the outer 8 areas (the 4 corners and the 4 edges) rendered with a separate border material. The advantage of rendering the corners separately from the edges is that the edge textures can be designed so that they can be stretched without distorting them, meaning the single texture can serve any size panel.

Attributes:

border_size <left> <right> <top> <bottom>
     The size of the border at each edge, as a proportion of the size of the screen. This lets you have different size borders at each edge if you like, or you can use the same value 4 times to create a constant size border.

border_material <name>
     The name of the material to use for the border. This is normally a different material to the one used for the center area, because the center area is often tiled which means you can't put border areas in there. You must put all the images you need for all the corners and the sides into a single texture.

border_topleft_uv <u1> <v1> <u2> <v2>
     [also border_topright_uv, border_bottomleft_uv, border_bottomright_uv]; The texture coordinates to be used for the corner areas of the border. 4 coordinates are required, 2 for the top-left corner of the square, 2 for the bottom-right of the square.

border_left_uv <u1> <v1> <u2> <v2>
     [also border_right_uv, border_top_uv, border_bottom_uv]; The texture coordinates to be used for the edge areas of the border. 4 coordinates are required, 2 for the top-left corner, 2 for the bottom-right. Note that you should design the texture so that the left & right edges can be stretched / squashed vertically and the top and bottom edges can be stretched / squashed horizontally without detrimental effects.

TextArea (element)
------------------

This is a generic element that you can use to render text. It uses fonts which can be defined in code using the FontManager and Font classes, or which have been predefined in .fontdef files. See the font definitions section for more information.

Attributes:

font_name <name>
     The name of the font to use. This font must be defined in a .fontdef file to ensure it is available at scripting time.

char_height <height>
     The height of the letters as a proportion of the screen height. Character widths may vary because OGRE supports proportional fonts, but will be based on this constant height.

colour <red> <green> <blue>
     A solid colour to render the text in. Often fonts are defined in monochrome, so this allows you to colour them in nicely and use the same texture for multiple different coloured text areas. The colour elements should all be expressed as values between 0 and 1. If you use predrawn fonts which are already full colour then you don't need this.

colour_bottom <red> <green> <blue> / colour_top <red> <green> <blue>
     As an alternative to a solid colour, you can colour the text differently at the top and bottom to create a gradient colour effect which can be very effective.

alignment <left | center | right>
     Sets the horizontal alignment of the text. This is different from the horz_align parameter.

space_width <width>
     Sets the width of a space in relation to the screen.

Font Definition Scripts
=======================

Ogre uses texture-based fonts to render the TextAreaOverlayElement. You can also use the Font object for your own purpose if you wish. The final form of a font is a Material object generated by the font, and a set of 'glyph' (character) texture coordinate information.

There are 2 ways you can get a font into OGRE:

 1. Design a font texture yourself using an art package or font generator tool

 2. Ask OGRE to generate a font texture based on a truetype font

The former gives you the most flexibility and the best performance (in terms of startup times), but the latter is convenient if you want to quickly use a font without having to generate the texture yourself. I suggest prototyping using the latter and change to the former for your final solution.

All font definitions are held in .fontdef files, which are parsed by the system at startup time. Each .fontdef file can contain multiple font definitions. The basic format of an entry in the .fontdef file is:

     <font_name>
     {
         type <image | truetype>
         source <image file | truetype font file>
         ...
         ... custom attributes depending on type
     }

Using an existing font texture
==============================

If you have one or more artists working with you, no doubt they can produce you a very nice font texture. OGRE supports full colour font textures, or alternatively you can keep them monochrome / greyscale and use TextArea's colouring feature. Font textures should always have an alpha channel, preferably an 8-bit alpha channel such as that supported by TGA and PNG files, because it can result in much nicer edges. To use an existing texture, here are the settings you need:

type image
     This just tells OGRE you want a pre-drawn font.

source <filename>
     This is the name of the image file you want to load. This will be loaded from the standard TextureManager resource locations and can be of any type OGRE supports, although JPEG is not recommended because of the lack of alpha and the lossy compression. I recommend PNG format which has both good lossless compression and an 8-bit alpha channel.

glyph <character> <u1> <v1> <u2> <v2>
     This provides the texture coordinates for the specified character. You must repeat this for every character you have in the texture. The first 2 numbers are the x and y of the top-left corner, the second two are the x and y of the bottom-right corner. Note that you really should use a common height for all characters, but widths can vary because of proportional fonts.

     'character' is either an ASCII character for non-extended 7-bit ASCII, or for extended glyphs, a unicode decimal value, which is identified by preceding the number with a 'u' - e.g. 'u0546' denotes unicode value 546.

A note for Windows users: I recommend using BitmapFontBuilder (http://www.lmnopc.com/bitmapfontbuilder/), a free tool which will generate a texture and export character widths for you, you can find a tool for converting the binary output from this into 'glyph' lines in the Tools folder.

Generating a font texture
=========================

You can also generate font textures on the fly using truetype fonts. I don't recommend heavy use of this in production work because rendering the texture can take a several seconds per font which adds to the loading times. However it is a very nice way of quickly getting text output in a font of your choice.

Here are the attributes you need to supply:

type truetype
     Tells OGRE to generate the texture from a font

source <ttf file>
     The name of the ttf file to load. This will be searched for in the common resource locations and in any resource locations added to FontManager.

size <size_in_points>
     The size at which to generate the font, in standard points. Note this only affects how big the characters are in the font texture, not how big they are on the screen. You should tailor this depending on how large you expect to render the fonts because generating a large texture will result in blurry characters when they are scaled very small (because of the mipmapping), and conversely generating a small font will result in blocky characters if large text is rendered.

resolution <dpi>
     The resolution in dots per inch, this is used in conjunction with the point size to determine the final size. 72 / 96 dpi is normal.

antialias_colour <true|false>
     This is an optional flag, which defaults to 'false'. The generator will antialias the font by default using the alpha component of the texture, which will look fine if you use alpha blending to render your text (this is the default assumed by TextAreaOverlayElement for example). If, however you wish to use a colour based blend like add or modulate in your own code, you should set this to 'true' so the colour values are anti-aliased too. If you set this to true and use alpha blending, you'll find the edges of your font are antialiased too quickly resulting in a 'thin' look to your fonts, because not only is the alpha blending the edges, the colour is fading too. Leave this option at the default if in doubt.

code_points nn-nn [nn-nn] ..
     This directive allows you to specify which unicode code points should be generated as glyphs into the font texture. If you don't specify this, code points 33-166 will be generated by default which covers the basic Latin 1 glyphs. If you use this flag, you should specify a space-separated list of inclusive code point ranges of the form 'start-end'. Numbers must be decimal.

You can also create new fonts at runtime by using the FontManager if you wish.

Mesh Tools
**********

There are a number of mesh tools available with OGRE to help you manipulate your meshes.

Exporters
     For getting data out of modellers and into OGRE.

XmlConverter
     For converting meshes and skeletons to/from XML.

MeshUpgrader
     For upgrading binary meshes from one version of OGRE to another.

Exporters
=========

Exporters are plugins to 3D modelling tools which write meshes and skeletal animation to file formats which OGRE can use for realtime rendering. The files the exporters write end in .mesh and .skeleton respectively.

Each exporter has to be written specifically for the modeller in question, although they all use a common set of facilities provided by the classes MeshSerializer and SkeletonSerializer. They also normally require you to own the modelling tool.

All the exporters here can be built from the source code, or you can download precompiled versions from the OGRE web site.

A Note About Modelling / Animation For OGRE
===========================================

There are a few rules when creating an animated model for OGRE:

  * You must have no more than 4 weighted bone assignments per vertex. If you have more, OGRE will eliminate the lowest weighted assignments and re-normalise the other weights. This limit is imposed by hardware blending limitations.

  * All vertices must be assigned to at least one bone - assign static vertices to the root bone.

  * At the very least each bone must have a keyframe at the beginning and end of the animation.

If you're creating unanimated meshes, then you do not need to be concerned with the above.

Full documentation for each exporter is provided along with the exporter itself, and there is a list of the currently supported modelling tools in the OGRE Wiki at http://www.ogre3d.org/wiki/index.php/Exporters.

XmlConverter
============

The OgreXmlConverter tool can converter binary .mesh and .skeleton files to XML and back again - this is a very useful tool for debugging the contents of meshes, or for exchanging mesh data easily - many of the modeller mesh exporters export to XML because it is simpler to do, and OgreXmlConverter can then produce a binary from it. Other than simplicity, the other advantage is that OgreXmlConverter can generate additional information for the mesh, like bounding regions and level-of-detail reduction.

Syntax:

     Usage: OgreXMLConverter sourcefile [destfile]
     sourcefile = name of file to convert
     destfile   = optional name of file to write to. If you don't
                  specify this OGRE works it out through the extension
                  and the XML contents if the source is XML. For example
                  test.mesh becomes test.xml, test.xml becomes test.mesh
                  if the XML document root is <mesh> etc.

When converting XML to .mesh, you will be prompted to (re)generate level-of-detail(LOD) information for the mesh - you can choose to skip this part if you wish, but doing it will allow you to make your mesh reduce in detail automatically when it is loaded into the engine. The engine uses a complex algorithm to determine the best parts of the mesh to reduce in detail depending on many factors such as the curvature of the surface, the edges of the mesh and seams at the edges of textures and smoothing groups - taking advantage of it is advised to make your meshes more scalable in real scenes.

MeshUpgrader
============

This tool is provided to allow you to upgrade your meshes when the binary format changes - sometimes we alter it to add new features and as such you need to keep your own assets up to date. This tools has a very simple syntax:

     OgreMeshUpgrade <oldmesh> <newmesh>

The OGRE release notes will notify you when this is necessary with a new release.

     [file vbos.inc not included]
     [file texturesource.inc not included]
     [file shadows.inc not included]
     [file animation.inc not included]