source: OGRE/trunk/ogrenew/Docs/src/manual.texi @ 657

Revision 657, 173.5 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1\input texinfo   @c -*-texinfo-*-
2@c %**start of header
3@setfilename manual.info
4@settitle OGRE Manual v1.0.7
5@c %**end of header
6   
7@titlepage
8@title OGRE Manual
9@author Steve Streeting
10@page
11@vskip 0pt plus 1filll
12Copyright @copyright{} The OGRE Team@*@*
13
14Permission is granted to make and distribute verbatim
15copies of this manual provided the copyright notice and
16this permission notice are preserved on all copies.@*@*
17
18Permission is granted to copy and distribute modified
19versions of this manual under the conditions for verbatim
20copying, provided that the entire resulting derived work is
21distributed under the terms of a permission notice
22identical to this one.@*@*
23@end titlepage
24
25@node Top
26@top OGRE Manual
27Copyright @copyright{} The OGRE Team@*@*
28
29
30This work is licenced under the Creative Commons Attribution-ShareAlike 2.5 License. To view a copy of this licence, visit @url{http://creativecommons.org/licenses/by-sa/2.5/} or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.@*@*
31
32@ifinfo
33@menu
34* Introduction::
35* The Core Objects::
36* Scripts::
37* Mesh Tools::
38* Hardware Buffers::
39* External Texture Sources::
40* Shadows::
41@detailmenu
42@end detailmenu
43@end menu
44@end ifinfo
45
46@c -------------------------------------------
47@node Introduction
48@chapter Introduction
49This chapter is intended to give you an overview of the main components of OGRE and why they have been put together that way.
50@c -------------------------------------------
51@node Object Orientation - more than just a buzzword
52@section Object Orientation - more than just a buzzword
53The 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?@*@*
54
55Well, 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.@*@*
56
57Object 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.@*@*
58
59I'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 stylee. 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.
60
61In summary, here's the benefits an object-oriented approach brings to OGRE:
62@table @asis
63@item Abstraction
64Common interfaces hide the nuances between different implementations of 3D API and operating systems
65@item Encapsulation
66There 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
67@item Polymorphism
68The 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
69@end table
70@c -------------------------------------------
71@node Multi-everything
72@section Multi-everything
73I 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.@*@*
74
75Therefore 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.@*@*
76
77Now 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.@*@*
78
79For 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.
80
81Similarly 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.@*@*
82
83OGRE's object-oriented nature makes all this possible. Currently OGRE runs on both Windows and Linux, 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.@*@*
84
85@node The Core Objects
86@chapter The Core Objects
87@heading Introduction
88
89This tutorial gives you a quick summary of the core objects that you will use in OGRE and what they are used for.
90
91@heading A Word About Namespaces
92
93OGRE 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. ;)
94
95This 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).
96
97@heading UML Diagram
98
99Shown below is a UML diagram of the core objects and how they relate to each other. Even if you don't know UML I'm sure you can work out the gist...
100
101@image{images/uml-overview}
102
103More details on these objects can be found in the following sections.
104
105@node The Root Object
106@section The Root object
107The '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.@*@*
108
109The 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.@*@*
110
111The 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.@*@*
112
113Finally, 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).@*@*
114
115@node The RenderSystem object
116@section The RenderSystem object
117
118The 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.@*@*
119
120However, 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.@*@*
121
122For 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.@*@*
123
124@node The SceneManager object
125@section The SceneManager object
126
127Apart 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.@*@*
128
129It 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 a material which is used by an object, 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, getMaterial, getLight etc methods.@*@*
130
131The 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.@*@*
132
133So 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).@*@*
134
135Because 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.@*@*
136
137The application using OGRE does not have to know which subclasses are available. The application simply calls Root::getSceneManager(..) 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.@*@*
138
139
140@node The ResourceManager Objects
141@section The ResourceManager Objects
142
143The ResourceManager class is actually just a base class for a number of other classes which are used to manage resources. In this context, resources are sets of data which must be loaded from somewhere to provide OGRE with the data it needs. Examples are textures, meshes and maps. There is a subclass of ResourceManager to manage each of the types of resources, e.g. TextureManager for loading textures, MeshManager for loading mesh objects.@*@*
144
145ResourceManager's 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).@*@*
146
147Most 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.@*@*
148
149Probably the only time you will need to call a ResourceManager is when you want to tell it where to look for resources. You can do this by calling the addSearchPath and addArchive methods of the resource manager, which will cause it to also look in the folder/archive you specify next time it searches for files.@*@*
150
151The above methods only affect the particular resource manager you call (e.g. it will only affect texture loading if you call it on TextureManager). Alternatively you can also call the static method ResourceManager::addCommonSearchPath or ResourceManager::addCommonArchive if you want ALL resource managers to look in the folder/archive you specify.@*@*
152
153Because 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:
154@example
155TextureManager::getSingleton().someMethod()
156MeshManager::getSingleton().someMethod()
157@end example
158@*@*
159
160@node The Mesh Object
161@section The Mesh Object
162
163A 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.@*@*
164
165Mesh 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 @xref{Exporters} and can be maipulated through various @ref{Mesh Tools}@*@*
166
167You 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.@*@*
168
169Mesh objects are the basis for the individual movable objects in the world, which are called @ref{Entities}.@*@*
170
171Mesh objects can also be animated using @xref{Skeletal Animation}.
172
173@node Entities
174@section Entities
175
176An 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.@*@*
177
178Entities 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.@*@*
179
180You 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.@*@*
181
182Entities 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.@*@*
183
184When 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.@*@*
185
186To 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.@*@*
187
188When 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.@*@*
189
190@node Materials
191@section Materials
192
193The 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.@*@*
194
195Materials 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. @xref{Material Scripts} for more info.@*@*
196
197Basically everything about the appearance of an object apart from it's shape is controlled by the Material class.@*@*
198
199The 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:@*@*
200
201@itemize @bullet
202@item
203ambient reflectance = ColourValue::White (full)
204@item
205diffuse reflectance = ColourValue::White (full)
206@item
207specular reflectance = ColourValue::Black (none)
208@item
209emmissive = ColourValue::Black (none)
210@item
211shininess = 0 (not shiny)
212@item
213No texture layers (& hence no textures)
214@item
215SourceBlendFactor = SBF_ONE, DestBlendFactor = SBF_ZERO (opaque)
216@item
217Depth buffer checking on
218@item
219Depth buffer writing on
220@item
221Depth buffer comparison function = CMPF_LESS_EQUAL
222@item
223Culling mode = CULL_CLOCKWISE
224@item
225Ambient lighting in scene = ColourValue(0.5, 0.5, 0.5) (mid-grey)
226@item
227Dynamic lighting enabled
228@item
229Gourad shading mode
230@item
231Bilinear texture filtering
232@end itemize
233
234You can alter these settings by calling SceneManager::getDefaultMaterialSettings() and making the required changes to the Material which is returned.
235
236Entities 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 @ref{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().
237
238
239@node Overlays
240@section Overlays
241
242Overlays 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.@*@*
243
244You 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.@*@*
245
246@heading Creating 2D Elements
247
248The 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.@*@*
249
250An 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.@*@*
251
252The 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");@*@*
253
254@heading Adding 2D Elements to the Overlay
255
256Only 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.@*@*
257
258If 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.@*@*
259
260@heading A word about 2D coordinates
261
262OGRE allows you to place and size elements based on 2 coordinate systems: @strong{relative} and @strong{pixel} based.
263@table @asis
264@item Pixel Mode
265This 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.
266@item Relative Mode
267This 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 eg use (0.1875, 0.25) instead.
268@end table
269
270@heading Transforming Overlays
271
272Another 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.
273
274@heading Scripting overlays
275Overlays can also be defined in scripts. @xref{Overlay Scripts} for details.
276
277@heading GUI systems
278Overlays 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 (@url{http://www.cegui.org.uk}), as demonstrated in the sample Demo_Gui.
279
280@node Skeletal Animation
281@section Skeletal Animation
282
283Skeletal animation is a process of animating a mesh by moving a set of hierarchical bones within the mesh, which in turn moves the vertices of the model according to the bone assignments stored in each vertex. An alternative term for this approach is 'skinning'. The usual way of creating these animations is with a modelling tool such as Milkshape 3D, Blender, 3D Studio or Maya. OGRE provides exporters to allow you to get the data out of these modellers and into the engine @xref{Exporters}.@*@*
284
285There are many grades of skeletal animation, and not all engines (or modellers for that matter) support all of them. OGRE supports the following features:
286@itemize @bullet
287@item Each mesh can be linked to a single skeleton
288@item Unlimited bones per skeleton
289@item Hierarchical forward-kinematics on bones
290@item Multiple named animations per skeleton (e.g. 'Walk', 'Run', 'Jump', 'Shoot' etc)
291@item Unlimited keyframes per animation
292@item Linear or spline-based interpolation between keyframes
293@item A vertex can be assigned to multiple bones and assigned weightings for smoother skinning
294@item Multiple animations can be applied to a mesh at the same time, again with a blend weighting
295@end itemize
296@*
297Skeletons and the animations which go with them are held in .skeleton files, which are produced by the OGRE exporters. These files are loaded automatically when you create an Entity based on a Mesh which is linked to the skeleton in question. The entity is then given an 'animation state' object per animation on the skeleton to allow you to specify the animation state of that single entity (you can animate multiple entities using the same skeleton, OGRE sorts the reuse out internally).@*@*
298
299You can retrieve a pointer to the AnimationState object by calling Entity::getAnimationState. You can then call methods on this returned object to update the animation, probably in the frameStarted event. AnimationState has a very simple method 'addTime' which allows you to alter the animation position incrementally, and it will automatically loop for you. addTime can take positive or negative values (so you can reverse the animation if you want).@*@*
300
301@node Scripts
302@chapter Scripts
303OGRE 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 modiying 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:
304@itemize @bullet
305@item
306@ref{Material Scripts}
307@item
308@ref{Particle Scripts}
309@item
310@ref{Overlay Scripts}
311@item
312@ref{Font Definition Scripts}
313@end itemize
314@node Material Scripts
315@section Material Scripts
316
317Material 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.@*@*
318
319You can also use this facility to replace existing material definitions which get loaded in from resource files. For example, if you have a .3ds model which you converted using 3ds2oof, it contains a number of material definitions. You can replace any of the material definitions from the .3ds file with your own just by adding a material definition with the same name to a script (remember you can also rename materials in a .3ds file with the 3ds2oof utility with the -matnames option), which will override the one loaded from the .3ds file.@*@*
320
321@heading Loading scripts
322
323Material 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 '.material' extension and parses them. If you want to parse files with a different extension, use the MaterialManager::getSingleton().parseAllSources method with your own extension, or if you want to parse an individual file, use MaterialManager::getSingleton().parseScript.@*@*
324
325It'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 (getMaterial() from SceneManager, or 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.@*@*
326
327Another important factor is that material names must be unique throughout ALL scripts loaded by the system, since materials are always identified by name.@*@*
328
329@heading Format
330
331Several 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 or fragment programs, these are covered later):@*@*
332@example
333// This is a comment
334material walls/funkywall1
335{
336    // first, preferred technique
337    technique
338    {
339        // first pass
340        pass
341        {
342            ambient 0.5 0.5 0.5
343            diffuse 1.0 1.0 1.0
344                       
345            // Texture unit 0
346            texture_unit
347            {
348                texture wibbly.jpg
349                scroll_anim 0.1 0.0
350                wave_xform scale sine 0.0 0.7 0.0 1.0
351            }
352            // Texture unit 1 (this is a multitexture pass)
353            texture_unit
354            {
355                texture wobbly.png
356                rotate_anim 0.25
357                colour_op add
358            }
359        }
360    }
361
362    // Second technique, can be used as a fallback or LOD level
363    technique
364    {
365        // .. and so on
366    }
367               
368}
369@end example
370
371Every 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.@*@*
372
373A material can be made up of many techniques (@xref{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. @*@*
374
375Each technique can be made up of many passes (@xref{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, @xref{Passes} for more details. @*@*
376
377Within each pass, there can be zero or many texture units in use (@xref{Texture Units}). These define the texture to be used, and optionally some blending operations (which use multitexturing) and texture effects.@*@*
378
379You 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 (@xref{Declaring Vertex and Fragment Programs}) and are used as described in @ref{Using Vertex and Fragment Programs in a Pass}.
380
381@subheading Top-level material attributes
382The 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:@*@*
383@anchor{lod_distances}
384@subheading lod_distances
385This attribute controls the distances at which different Techniques can come into effect. @xref{Techniques} for a full discussion of this option.
386@*@*
387@anchor{receive_shadows}
388@subheading receive_shadows
389This attribute controls whether objects using this material can have shadows cast upon them.@*@*
390
391Format: receive_shadows <on|off>@*
392Default: on@*@*
393
394Whether or not an object receives a shadow is the combination of a number of factors, @xref{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.
395
396@anchor{transparency_casts_shadows}
397@subheading transparency_casts_shadows
398This attribute controls whether transparent materials can cast certain kinds of shadow.@*@*
399
400Format: transparency_casts_shadows <on|off>@*
401Default: off@*@*
402Whether or not an object casts a shadow is the combination of a number of factors, @xref{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.
403
404@node Techniques
405@subsection Techniques
406
407A "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.@*@*
408
409When 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:
410@itemize @bullet
411@item The number of texture_unit entries in each pass@*
412Note 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 (@xref{colour_op_multipass_fallback}).
413@item Whether vertex or fragment programs are used, and if so which syntax they use (e.g. vs_1_1, ps_2_x, arbfp1 etc)
414@item Other effects like cube mapping and dot3 blending
415@end itemize
416@*
417In 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.@*@*
418
419Techniques have only one attribute of their own, which indicates which LOD index they belong to (@xref{lod_index}). We also mention an extra Material attribute called @ref{lod_distances} which isn't a Technique attribute but is directly related to the lod_index attribute, so it's listed here for convenience.@*@*
420
421@anchor{lod_index}
422@subheading lod_index
423
424Sets the level-of-detail (LOD) index this Technique belongs to. @*@*
425
426Format: lod_index <number>@*
427NB 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.@*@*
428
429Example: lod_index 1@*@*
430
431All techniques must belong to a LOD index, by default they all belong to index 0, ie 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.@*@*
432The distance at which a LOD level is applied is determined by the lod_distances attribute of the containing material, @xref{lod_distances} for details.@*@*
433
434Default: lod_index 0@*@*
435
436@anchor{lod_distances}
437@subheading lod_distances
438@strong{Note: this attribute must be specified in the outer material section (ie the parent of all the techniques), but it's specified here since it is most relevant to this section.}@*@*
439
440By setting this attribute, you indicate that you want this material to alter the Technique that it uses based on distance from the camera. You must give it a list of distances, in ascending order, each one indicating the distance at which the material will switch to the next LOD. Implicitly, all materials activate LOD index 0 for distances less than the smallest of these. You must ensure that there is at least one Technique with a @ref{lod_index} value for each distance in the list (so if you specify 3 distances, you must have techniques for indexes 1, 2 and 3). Note you must always have at least one Technique at lod_index 0.@*@*
441
442Format: lod_distances <distance_1> [<distance_2> ... <distance_n>]@*
443
444Example: lod_distances 300.0 600.5 1200@*@*
445
446The 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.@*@*
447
448Techniques also contain one or more passes (and there must be at least one), @xref{Passes}.
449
450
451
452@node Passes
453@subsection Passes
454A 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.@*@*
455Passes have a set of global attributes (described below), zero or more nested texture_unit entries (@xref{Texture Units}), and optionally a reference to a vertex and / or a fragment program (@xref{Using Vertex and Fragment Programs in a Pass}).
456
457@*@*
458Here are the attributes you can use in a 'pass' section of a .material script:
459
460@itemize @bullet
461@item
462@ref{ambient}
463@item
464@ref{diffuse}
465@item
466@ref{specular}
467@item
468@ref{emissive}
469@item
470@ref{scene_blend}
471@item
472@ref{depth_check}
473@item
474@ref{depth_write}
475@item
476@ref{depth_func}
477@item
478@ref{depth_bias}
479@item
480@ref{alpha_rejection}
481@item
482@ref{cull_hardware}
483@item
484@ref{cull_software}
485@item
486@ref{lighting}
487@item
488@ref{shading}
489@item
490@ref{fog_override}
491@item
492@ref{colour_write}
493@item
494@ref{max_lights}
495@item
496@ref{iteration}
497@end itemize
498
499@heading Attribute Descriptions
500@anchor{ambient}
501@subheading ambient
502
503Sets the ambient colour reflectance properties of this pass. @strong{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.} @*@*
504
505Format: ambient (<red> <green> <blue> [<alpha>]| vertexcolour)@*
506NB valid colour values are between 0.0 and 1.0.@*@*
507
508Example: ambient 0.0 0.8 0.0@*@*
509
510The 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.
511It 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.
512The 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.@*@*
513
514Default: ambient 1.0 1.0 1.0 1.0@*@*
515
516@anchor{diffuse}
517@subheading diffuse
518
519Sets the diffuse colour reflectance properties of this pass. @strong{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.}@*@*
520
521Format: diffuse (<red> <green> <blue> [<alpha>]| vertexcolour)@*
522NB valid colour values are between 0.0 and 1.0.@*@*
523
524Example: diffuse 1.0 0.5 0.5@*@*
525
526The 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.
527It 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.
528The 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.@*@*
529
530Default: diffuse 1.0 1.0 1.0 1.0@*@*
531
532@anchor{specular}
533@subheading specular
534
535Sets the specular colour reflectance properties of this pass. @strong{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.}@*@*
536
537Format: specular (<red> <green> <blue> [<alpha>]| vertexcolour) <shininess>@*
538NB valid colour values are between 0.0 and 1.0. Shininess can be any value greater than 0.@*@*
539
540Example: specular 1.0 1.0 1.0 12.5@*@*
541
542The 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.
543It 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.
544The 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.@*@*
545
546Default: specular 0.0 0.0 0.0 0.0 0.0@*@*
547
548@anchor{emissive}
549@subheading emissive
550
551Sets the amount of self-illumination an object has. @strong{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.}@*@*
552
553Format: emissive (<red> <green> <blue> [<alpha>]| vertexcolour)@*
554NB valid colour values are between 0.0 and 1.0.@*@*
555
556Example: emissive 1.0 0.0 0.0@*@*
557
558If 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).
559It 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.
560This 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.@*@*
561
562Default: emissive 0.0 0.0 0.0 0.0@*@*
563
564@anchor{scene_blend}
565@subheading scene_blend
566
567Sets the kind of blending this pass has with the existing contents of the scene. Wheras 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.@*@*
568
569Format1: scene_blend <add|modulate|alpha_blend|colour_blend>@*@*
570
571Example: scene_blend add@*@*
572
573This is the simpler form, where the most commonly used blending modes are enumerated using a single parameter. Valid <blend_type> parameters are:
574@table @asis
575@item add
576The colour of the rendering output is added to the scene. Good for exposions, flares, lights, ghosts etc. Equivalent to 'scene_blend one one'.
577@item modulate
578The 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'.
579@item colour_blend
580Colour the scene based on the brightness of the input colours, but don't darken. Equivalent to 'scene_blend src_colour one_minus_src_colour'
581@item alpha_blend
582The alpha value of the rendering output is used as a mask. Equivalent to 'scene_blend src_alpha one_minus_src_alpha'
583@end table
584@*
585Format2: scene_blend <src_factor> <dest_factor>@*@*
586
587Example: scene_blend one one_minus_dest_alpha@*@*
588
589This 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:
590@table @asis
591@item one
592Constant value of 1.0
593@item zero
594Constant value of 0.0
595@item dest_colour
596The existing pixel colour
597@item src_colour
598The texture pixel (texel) colour
599@item one_minus_dest_colour
6001 - (dest_colour)
601@item one_minus_src_colour
6021 - (src_colour)
603@item dest_alpha
604The existing pixel alpha value
605@item src_alpha
606The texel alpha value
607@item one_minus_dest_alpha
6081 - (dest_alpha)
609@item one_minus_src_alpha
6101 - (src_alpha)
611@end table
612@*
613Default: scene_blend one zero (opaque)
614@*
615@anchor{depth_check}
616@subheading depth_check
617
618Sets whether or not this pass renders with depth-buffer checking on or not.@*@*
619
620Format: depth_check <on|off>@*@*
621
622If 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.@*@*
623
624Default: depth_check on@*@*
625
626@anchor{depth_write}
627@subheading depth_write
628
629Sets whether or not this pass renders with depth-buffer writing on or not.@*
630
631Format: depth_write <on|off>@*@*
632
633If 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.@*@*
634
635Default: depth_write on@*
636
637@anchor{depth_func}
638@subheading depth_func
639
640Sets the function used to compare depth values when depth checking is on.@*@*
641
642Format: depth_func <func>@*@*
643
644If 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:
645@table @asis
646@item always_fail
647Never writes a pixel to the render target
648@item always_pass
649Always writes a pixel to the render target
650@item less
651Write if (new_Z < existing_Z)
652@item less_equal
653Write if (new_Z <= existing_Z)
654@item equal
655Write if (new_Z == existing_Z)
656@item not_equal
657Write if (new_Z != existing_Z)
658@item greater_equal
659Write if (new_Z >= existing_Z)
660@item greater
661Write if (new_Z >existing_Z)
662@end table
663@*
664Default: depth_func less_equal
665
666@anchor{depth_bias}
667@subheading depth_bias
668
669Sets 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. @*@*
670
671Format: depth_bias <value>@*@*
672
673Where <value> is between 0 and 16, the default being 0. The higher the value, the greater the offset (for if you want to do multiple overlapping decals).@*@*
674
675@anchor{alpha_rejection}
676@subheading alpha_rejection
677
678Sets the way the pass will have use alpha to totally reject pixels from the pipeline.@*@*
679
680Format: alpha_rejection <function> <value>@*@*
681
682Example: alpha_rejection greater_equal 128@*@*
683
684The 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.@*@*
685
686Default: alpha_rejection always_pass@*@*
687
688@anchor{cull_hardware}
689@subheading cull_hardware
690
691Sets the hardware culling mode for this pass.@*@*
692
693Format: cull_hardware <clockwise|anticlockwise|none>@*@*
694
695A 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).@*@*
696
697Default: cull_hardware clockwise@*
698NB 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).
699
700@anchor{cull_software}
701@subheading cull_software
702
703Sets the software culling mode for this pass.@*@*
704
705Format: cull_software <back|front|none>@*@*
706
707In 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 traingle 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 precalculated 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.@*@*
708
709Default: cull_software back@*@*
710
711@anchor{lighting}
712@subheading lighting
713
714Sets 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. @strong{This attribute has no effect if a vertex program is used.}@*@*
715
716Format: lighting <on|off>@*@*
717
718Turning 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.@*@*
719
720Default: lighting on@*@*
721
722@anchor{shading}
723@subheading shading
724
725Sets the kind of shading which should be used for representing dynamic lighting for this pass.@*@*
726
727Format: shading <flat|gouraud|phong>@*@*
728
729When 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.@*@*
730@table @asis
731@item flat
732        No interpolation takes place. Each face is shaded with a single colour determined from the first vertex in the face.
733@item gouraud
734        Colour at each vertex is linearly interpolated across the face.
735@item phong
736        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 tesselation. Not supported on all hardware.
737@end table
738Default: shading gouraud@*@*
739
740@anchor{fog_override}
741@subheading fog_override
742
743Tells 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.@*@*
744
745Format: fog_override <override?> [<type> <colour> <density> <start> <end>]@*@*
746
747Default: fog_override false@*@*
748
749If 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:@*
750@table @asis
751@item type
752@strong{none} = No fog, equivalent of just using 'fog_override true'@*
753@strong{linear} = Linear fog from the <start> and <end> distances@*
754@strong{exp} = Fog increases exponentially from the camera (fog = 1/e^(distance * density)), use <density> param to control it@*
755@strong{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
756@item colour
757        Sequence of 3 floating point values from 0 to 1 indicating the red, green and blue intensities
758@item density
759        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
760@item start
761        The start distance from the camera of linear fog. Must still be present in other modes, even though it is not used.
762@item end
763        The end distance from the camera of linear fog. Must still be present in other modes, even though it is not used.
764@end table
765@*
766Example: fog_override true exp 1 1 1 0.002 100 10000
767
768@anchor{colour_write}
769@subheading colour_write
770
771Sets whether or not this pass renders with colour writing on or not.@*
772
773Format: colour_write <on|off>@*@*
774
775If 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. @*@*
776
777Default: colour_write on@*
778
779@anchor{max_lights}
780@subheading max_lights
781
782Sets the maximum number of lights which will be considered for use with this pass.@*@*
783Format: max_lights <number>@*@*
784
785The 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 (@xref{Using Vertex and Fragment Programs in a Pass}) this limit is dependent on the program you are running, or, if you use 'iteration once_per_light' (@xref{iteration}), it effectively only bounded by the number of passes you are willing to use. Whichever method you use, however, the max_lights limit applies.@*@*
786
787Default: max_lights 8@*
788
789@anchor{iteration}
790@subheading iteration
791
792Sets whether or not this pass is iterated, ie issued more than once.@*@*
793
794Format: iteration <once | once_per_light> [lightType]@*@*
795Example: iteration once_per_light point
796
797By 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.@*@*
798
799If 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 sihouette to appear.@*@*
800
801The second parameter to the attribute only applies if you use once_per_light, 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 better if you can assume the kind of lights you'll be dealing with.
802@*@*
803Default: iteration once
804
805@node Texture Units
806@subsection Texture Units
807
808Here are the attributes you can use in a 'texture_unit' section of a .material script:
809
810@heading Available Texture Layer Attributes
811@itemize @bullet
812@item
813@ref{texture}
814@item
815@ref{anim_texture}
816@item
817@ref{cubic_texture}
818@item
819@ref{tex_coord_set}
820@item
821@ref{tex_address_mode}
822@item
823@ref{filtering}
824@item
825@ref{max_anisotropy}
826@item
827@ref{colour_op}
828@item
829@ref{colour_op_ex}
830@item
831@ref{colour_op_multipass_fallback}
832@item
833@ref{alpha_op_ex}
834@item
835@ref{env_map}
836@item
837@ref{scroll}
838@item
839@ref{scroll_anim}
840@item
841@ref{rotate}
842@item
843@ref{rotate_anim}
844@item
845@ref{scale}
846@item
847@ref{wave_xform}
848@item
849@ref{transform}
850@end itemize
851
852You can also use a nested 'texture_source' section in order to use a special add-in as a source of texture data, @xref{External Texture Sources} for details.
853
854@heading Attribute Descriptions
855@anchor{texture}
856@subheading texture
857
858Sets the name of the static texture image this layer will use.@*@*
859
860Format: texture <texturename> [<type>]@*@*
861
862Example: texture funkywall.jpg@*@*
863
864This 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.@*@*
865The '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:
866@table @asis
867@item 1d
868A 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.
869@item 2d
870The 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.
871@item 3d
872A 3 dimensional texture ie 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 ie through a pixel shader.
873@item cubic
874This 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.
875@end table
876
877Default: none@*@*
878
879@anchor{anim_texture}
880@subheading anim_texture
881
882Sets 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.@*@*
883
884Format1 (short): anim_texture <base_name> <num_frames> <duration>@*@*
885
886Example: anim_texture flame.jpg 5 2.5@*@*
887
888This 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.@*@*
889
890Format2 (long): anim_texture <frame1> <frame2> ... <duration>@*@*
891
892Example: anim_texture flamestart.jpg flamemore.png flameagain.jpg moreflame.jpg lastflame.tga 2.5@*@*
893
894This 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. @*@*
895
896Default: none@*@*
897
898@anchor{cubic_texture}
899@subheading cubic_texture
900
901Sets 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.@*@*
902
903Format1 (short): cubic_texture <base_name> <combinedUVW|separateUV>@*@*
904
905The 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.@*@*
906
907Format2 (long): cubic_texture <front> <back> <left> <right> <up> <down> separateUV@*@*
908
909In 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).@*@*
910
911In both cases the final parameter means the following:
912@table @asis
913@item combinedUVW
914        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.
915@item separateUV
916        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.
917@end table
918@*
919Default: none
920
921@anchor{tex_coord_set}
922@subheading tex_coord_set
923
924Sets 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.@*@*
925
926Format: tex_coord_set <set_num>@*@*
927
928Example: tex_coord_set 2@*@*
929
930Default: tex_coord_set 0@*@*
931
932@anchor{tex_address_mode}
933@subheading tex_address_mode
934Defines what happens when texture coordinates exceed 1.0 for this texture layer.@*@*
935
936Format: tex_address_mode <wrap|clamp|mirror>
937@table @asis
938@item wrap
939        Any value beyond 1.0 wraps back to 0.0. Texture is repeated.
940@item clamp
941        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.
942@item mirror
943        Texture flips every boundary, meaning texture is mirrored every 1.0 u or v
944@end table
945@*
946Default: tex_address_mode wrap@*@*
947
948@anchor{filtering}
949@subheading filtering
950
951Sets 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.@*@*
952@strong{Simple Format}@*
953Format: filtering <none|bilinear|trilinear|anisotropic>@*
954Default: filtering bilinear@*@*
955With this format, you only need to provide a single parameter which is one of the following:
956@table @asis
957@item none
958        No filtering or mipmapping is used. This is equivalent to the complex format 'filtering point point none'.
959@item bilinear
960        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'.
961@item trilinear
962        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'.
963@item anisotropic
964        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 @ref{max_anisotropy} attribute too.
965@end table
966@*@*
967@strong{Complex Format}@*
968Format: filtering <minification> <magnification> <mip>@*
969Default: filtering linear linear point@*@*
970This format gives you complete control over the minification, magnification, and mip filters. Each parameter can be one of the following:
971@table @asis
972@item none
973        Nothing - only a valid option for the 'mip' filter , since this turns mipmapping off completely. The lowest setting for min and mag is 'point'.
974@item point
975        Pick the closet pixel in min or mag modes. In mip mode, this picks the closet matching mipmap.
976@item linear
977        Filter a 2x2 box of pixels around the closest one. In the 'mip' filter this enables filtering between mipmap levels.
978@item anisotropic
979        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 @ref{max_anisotropy} attribute too.
980@end table
981
982@anchor{max_anisotropy}
983@subheading max_anisotropy
984
985Sets 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.@*@*
986In order for this to be used, you have to set the minification and/or the magnification @ref{filtering} option on this texture to anisotropic.
987
988Format: max_anisotropy <value>@*
989Default: max_anisotropy 1
990
991@anchor{colour_op}
992@subheading colour_op
993
994Determines 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).@*@*
995
996Format: colour_op <replace|add|modulate|alpha_blend>@*@*
997
998This 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 @ref{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 @ref{colour_op_multipass_fallback}.@*
999@table @asis
1000@item replace
1001        Replace all colour with texture with no adjustment.
1002@item add
1003        Add colour components together.
1004@item modulate
1005        Multiply colour components together.
1006@item alpha_blend
1007        Blend based on texture alpha.
1008@end table
1009@*
1010Default: colour_op modulate
1011
1012@anchor{colour_op_ex}
1013@subheading colour_op_ex
1014
1015This is an extended version of the @ref{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 blendind, but you are limited to the number of texture units which are available in hardware.@*@*
1016
1017Format: colour_op_ex <operation> <source1> <source2> [<manual_factor>] [<manual_colour1>] [<manual_colour2>]@*@*
1018
1019Example colour_op_ex add_signed src_manual src_current 0.5@*@*
1020
1021See the IMPORTANT note below about the issues between mulitpass 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.@*@*
1022
1023@table @asis
1024@item Operation options
1025@table @asis
1026@item source1
1027        Use source1 without modification
1028@item source2
1029        Use source2 without modification
1030@item modulate
1031        Multiply source1 and source2 together.
1032@item modulate_x2
1033        Multiply source1 and source2 together, then by 2 (brightening).
1034@item modulate_x4
1035        Multiply source1 and source2 together, then by 4 (brightening).
1036@item add
1037        Add source1 and source2 together.
1038@item add_signed
1039        Add source1 and source2 then subtract 0.5.
1040@item add_smooth
1041        Add source1 and source2, subtract the product
1042@item subtract
1043        Subtract source2 from source1
1044@item blend_diffuse_alpha
1045        Use interpolated alpha value from vertices to scale source1, then add source2 scaled by (1-alpha).
1046@item blend_texture_alpha
1047        As blend_diffuse_alpha but use alpha from texture
1048@item blend_current_alpha
1049        As blend_diffuse_alpha but use current alpha from previous stages (same as blend_diffuse_alpha for first layer)
1050@item blend_manual
1051        As blend_diffuse_alpha but use a constant manual alpha value specified in <manual>
1052@item dotproduct
1053        The dot product of source1 and source2
1054@end table
1055@item Source1 and source2 options
1056@table @asis
1057@item src_current
1058        The colour as built up from previous stages.
1059@item src_texture
1060        The colour derived from the texture assigned to this layer.
1061@item src_diffuse
1062        The interpolated diffuse colour from the vertices (same as 'src_current' for first layer).
1063@item src_specular
1064        The interpolated specular colour from the vertices.
1065@item src_manual
1066        The manual colour specified at the end of the command.
1067@end table
1068@end table
1069@*
1070For 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. @*@*
1071
1072Note 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.@*@*
1073
1074IMPORTANT: 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.@*@*
1075
1076Default: none (colour_op modulate)@*
1077
1078@anchor{colour_op_multipass_fallback}
1079@subheading colour_op_multipass_fallback
1080
1081Sets the multipass fallback operation for this layer, if you used colour_op_ex and not enough multitexturing hardware is available.@*@*
1082
1083Format: colour_op_multipass_fallback <src_factor> <dest_factor>@*@*
1084
1085Example: colour_op_mulitpass_fallback one one_minus_dest_alpha@*@*
1086
1087Because 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.@*@*
1088
1089The 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.@*@*
1090
1091@anchor{alpha_op_ex}
1092@subheading alpha_op_ex
1093
1094Behaves in exactly the same away as @ref{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.
1095
1096@anchor{env_map}
1097@subheading env_map
1098
1099Turns on/off texture coordinate effect that makes this layer an environment map.@*@*
1100
1101Format: env_map <off|spherical|planar|cubic_reflection|cubic_normal>@*@*
1102
1103Environment 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.@*@*
1104@table @asis
1105@item spherical
1106        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.
1107@item planar
1108        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.
1109@item cubic_reflection
1110        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 @ref{cubic_texture} to this texture unit and use the 'combinedUVW' option.
1111@item cubic_normal
1112        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 @ref{cubic_texture} with the 'combinedUVW' option.
1113       
1114@end table
1115@*
1116Default: env_map off@*
1117
1118@anchor{scroll}
1119@subheading scroll
1120
1121
1122Sets a fixed scroll offset for the texture.@*@*
1123
1124Format: scroll <x> <y>@*@*
1125
1126This 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 @ref{scroll_anim} attribute.@*@*
1127
1128@anchor{scroll_anim}
1129@subheading scroll_anim
1130
1131Sets up an animated scroll for the texture layer. Useful for creating fixed-speed scrolling effects on a texture layer (for varying scroll speeds, see @ref{wave_xform}).@*@*
1132
1133Format: scroll_anim <xspeed> <yspeed>@*
1134
1135@anchor{rotate}
1136@subheading rotate
1137
1138Rotates 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 @ref{rotate_anim}.@*@*
1139
1140Format: rotate <angle>@*@*
1141
1142The parameter is a anticlockwise angle in degrees.@*@*
1143
1144@anchor{rotate_anim}
1145@subheading rotate_anim
1146
1147Sets up an animated rotation effect of this layer. Useful for creating fixed-speed rotation animations (for varying speeds, see @ref{wave_xform}).@*@*
1148
1149Format: rotate_anim <revs_per_second>@*@*
1150
1151The parameter is a number of anticlockwise revolutions per second.@*@*
1152
1153@anchor{scale}
1154@subheading scale
1155
1156Adjusts 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 @ref{wave_xform}.@*@*
1157
1158Format: scale <x_scale> <y_scale>@*@*
1159
1160Valid scale values are greater than 0, with a scale factor of 2 making the texture twice as big in that dimension etc.@*@*
1161
1162@anchor{wave_xform}
1163@subheading wave_xform
1164
1165Sets 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.@*@*
1166
1167Format: wave_xform <xform_type> <wave_type> <base> <frequency> <phase> <amplitude>@*@*
1168
1169Example: wave_xform scale_x sine 1.0 0.2 0.0 5.0@*@*
1170@table @asis
1171@item xform_type
1172@table @asis
1173@item scroll_x
1174        Animate the x scroll value
1175@item scroll_y
1176        Animate the y scroll value
1177@item rotate
1178        Animate the rotate value
1179@item scale_x
1180        Animate the x scale value
1181@item scale_y
1182        Animate the y scale value
1183@end table
1184@item wave_type
1185@table @asis
1186@item sine
1187        A typical sine wave which smoothly loops between min and max values
1188@item triangle
1189        An angled wave which increases & decreases at constant speed, changing instantly at the extremes
1190@item square
1191        Max for half the wavelength, min for the rest with instant transition between
1192@item sawtooth
1193        Gradual steady increase from min to max over the period with an instant return to min at the end.
1194@item inverse_sawtooth
1195        Gradual steady decrease from max to min over the period, with an instant return to max at the end.
1196@end table
1197@item base
1198        The base value, the minimum if amplitude > 0, the maximum if amplitdue < 0
1199@item frequency
1200        The number of wave iterations per second, i.e. speed
1201@item phase
1202        Offset of the wave start
1203@item amplitude
1204        The size of the wave
1205@end table
1206@*
1207The 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).@*@*
1208
1209@anchor{transform}
1210@subheading transform
1211
1212This 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. @*@*
1213
1214Format: transform m00 m01 m02 m03 m10 m11 m12 m13 m20 m21 m22 m23 m30 m31 m32 m33@*@*
1215
1216The indexes of the 4x4 matrix value above are expressed as m<row><col>.
1217
1218@node Declaring Vertex and Fragment Programs
1219@subsection Declaring Vertex and Fragment Programs
1220
1221In order to use a vertex or fragment program in your materials (@xref{Using Vertex and 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.@*@*
1222
1223The 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 @strong{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.@*@*
1224
1225Vertex 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 nVidia's Cg language (@xref{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 targetting 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.@*@*
1226
1227Here is an example of a definition of a low-level vertex program:
1228@example
1229vertex_program myVertexProgram asm
1230{
1231    source myVertexProgram.asm
1232    syntax vs_1_1
1233}
1234@end example
1235As you can see, that's very simple, and defining a fragment program is exactly the same, just with vertex_program replaced with fragment_program. 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 progams which use an unsupportable syntax quickly, without loading the program first.@*@*
1236
1237The current supported syntaxes are:
1238@table @asis
1239@item vs_1_1
1240This is one of the DirectX vertex shader assembler syntaxes. @*
1241Supported on cards from: ATI Radeon 8500, nVidia GeForce 3 @*
1242@item vs_2_0
1243Another one of the DirectX vertex shader assembler syntaxes. @*
1244Supported on cards from: ATI Radeon 9600, nVidia GeForce FX 5 series @*
1245@item vs_2_x
1246Another one of the DirectX vertex shader assembler syntaxes. @*
1247Supported on cards from: ATI Radeon X series, nVidia GeForce FX 6 series @*
1248@item vs_3_0
1249Another one of the DirectX vertex shader assembler syntaxes. @*
1250Supported on cards from: nVidia GeForce FX 6 series
1251@item arbvp1
1252This is the OpenGL standard assembler format for vertex programs. It's roughly equivalent to DirectX vs_1_1.
1253@item vp20
1254This is an nVidia-specific OpenGL vertex shader syntax which is a superset of vs 1.1.
1255@item vp30
1256Another 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.
1257@item vp40
1258Another 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.
1259@item ps_1_1, ps_1_2, ps_1_3
1260DirectX pixel shader (ie fragment program) assembler syntax. @*
1261Supported on cards from: ATI Radeon 8500, nVidia GeForce 3 @*
1262NOTE: 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.
1263@item ps_1_4
1264DirectX pixel shader (ie fragment program) assembler syntax. @*
1265Supported on cards from: ATI Radeon 8500, nVidia GeForce FX 5 series @*
1266NOTE: 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.
1267@item ps_2_0
1268DirectX pixel shader (ie fragment program) assembler syntax. @*
1269Supported cards: ATI Radeon 9600, nVidia GeForce FX 5 series@*
1270@item ps_2_x
1271DirectX pixel shader (ie fragment program) assembler syntax. This is basically
1272ps_2_0 with a higher number of instructions. @*
1273Supported cards: ATI Radeon X series, nVidia GeForce FX 6 series@*
1274@item ps_3_0
1275DirectX pixel shader (ie fragment program) assembler syntax. @*
1276Supported cards: nVidia GeForce FX6 series@*
1277@item ps_3_x
1278DirectX pixel shader (ie fragment program) assembler syntax. @*
1279Supported cards: nVidia GeForce FX7 series@*
1280@item arbfp1
1281This 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).
1282@item fp20
1283This 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.
1284@item fp30
1285Another 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.
1286@item fp40
1287Another 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.
1288
1289@end table
1290
1291You can get a definitive list of the syntaxes supported by the current card by calling GpuProgramManager::getSingleton().getSupportedSyntax().@*@*
1292
1293@anchor{Default Program Parameters}
1294@subheading Default Program Parameters
1295While defining a vertex 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:
1296@example
1297vertex_program Ogre/CelShadingVP cg
1298{
1299        source Example_CelShading.cg
1300        entry_point main_vp
1301        profiles vs_1_1 arbvp1
1302
1303        default_params
1304        {
1305                param_named_auto lightPosition light_position_object_space 0
1306                param_named_auto eyePosition camera_position_object_space
1307                param_named_auto worldViewProj worldviewproj_matrix
1308                param_named shininess float 10
1309        }
1310}
1311@end example
1312The syntax of the parameter definition is exactly the same as when you define parameters when using programs, @xref{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.
1313
1314@node High-level Programs
1315@heading High-level Programs
1316Support 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 (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 is provided for people who only want to deploy in DirectX, or who don't want to include the Cg plugin for whatever reason. GLSL is only for the OpenGL API and can not be used with the DirectX api.  To support both DirectX and OpenGL you could write your shaders in both HLSL and GLSL along with having seperate techniques in the material script.  To be honest, Cg is a better bet because it lets you stay API independent - and don't be put off by the fact that it's made by nVidia, it will happily compile programs down to vendor-independent standards like DirectX and OpenGL's assembler formats, so you're not limited to nVidia cards.@*@*
1317
1318@subheading Cg programs
1319In 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:
1320@example
1321fragment_program myCgFragmentProgram cg
1322{
1323    source myCgFragmentProgram.cg
1324    entry_point main
1325    profiles ps_2_0 arbfp1
1326}
1327@end example
1328There 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. @*@*
1329Here 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.@*@*
1330Next, 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.
1331
1332@subheading DirectX9 HLSL
1333DirectX9 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:
1334@example
1335vertex_program myHLSLVertexProgram hlsl
1336{
1337    source myHLSLVertexProgram.txt
1338    entry_point main
1339    target vs_2_0
1340}
1341@end example
1342As you can see, the 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.@*@*
1343
1344@include glsl.inc
1345
1346@subheading Skeletal Animation in Vertex Programs
1347You 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:
1348@example
1349        includes_skeletal_animation true
1350@end example
1351When 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.
1352
1353@subheading Vertex Programs With Shadows
1354When using shadows (@xref{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. @*@*
1355
1356If you use @strong{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. @*@*
1357
1358If you use @strong{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, @xref{Shadows and Vertex Programs}.
1359
1360
1361@node Using Vertex and Fragment Programs in a Pass
1362@subsection Using Vertex and Fragment Programs in a Pass
1363
1364Within a pass section of a material script, you can reference a vertex and / or a fragment program which is been defined in a .program script (@xref{Declaring Vertex and 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.@*@*
1365
1366As well as naming the program in question, you can also provide parameters to it. Here's a simple example:
1367@example
1368vertex_program_ref myVertexProgram
1369{
1370        param_indexed_auto 0 worldviewproj_matrix
1371        param_indexed      4 float4  10.0 0 0 0
1372}
1373@end example
1374In 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.@*@*
1375
1376The syntax of the link to a vertex program and a fragment program are identical, the only difference is that 'fragment_program_ref' is used instead of 'vertex_program_ref'.
1377@anchor{Program Parameter Specification}
1378@subheading Parameter specification
1379Parameters 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 @ref{Default Program Parameters}. Parameters set in the specific use of the program override the defaults.
1380@itemize @bullet
1381@item @ref{param_indexed}
1382@item @ref{param_indexed_auto}
1383@item @ref{param_named}
1384@item @ref{param_named_auto}
1385@end itemize
1386
1387@anchor{param_indexed}
1388@subheading param_indexed
1389This command sets the value of an indexed parameter. @*@*
1390
1391format: param_indexed <index> <type> <value>@*@*
1392example: param_indexed 0 float4 10.0 0 0 0@*@*
1393
1394The '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.@*@*
1395
1396The 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).@*@*
1397
1398'value' is simply a space or tab-delimited list of values which can be converted into the type you have specified.
1399
1400@anchor{param_indexed_auto}
1401@subheading param_indexed_auto
1402
1403This 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.@*@*
1404
1405format: param_indexed_auto <index> <value_code> <extra_params>@*@*
1406example: param_indexed_auto 0 worldviewproj_matrix@*@*
1407
1408'index' has the same meaning as @ref{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.@*@*
1409
1410'value_code' is one of a list of recognised values:@*
1411@table @asis
1412@item world_matrix
1413The current world matrix.
1414@item world_matrix_array_3x4
1415An 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.
1416@item view_matrix
1417The current view matrix.
1418@item projection_matrix
1419The current projection matrix.
1420@item worldview_matrix
1421The current world and view matrices concatenated.
1422@item viewproj_matrix
1423The current view and projection matrices concatenated.
1424@item worldviewproj_matrix
1425The current world, view and projection matrices concatenated.
1426@item inverse_world_matrix
1427The inverse of the current world matrix.
1428@item inverse_view_matrix
1429The inverse of the current view matrix.
1430@item inverse_worldview_matrix
1431The inverse of the current concatenated world and view matrices.
1432@item inverse_transpose_world_matrix
1433The inverse transpose of the current world matrix.
1434@item inverse_transpose_worldview_matrix
1435The inverse transpose of the current concatenated world and view matrices.
1436@item inverse_viewproj_matrix
1437The inverse of the view & projection matrices
1438@item inverse_transpose_viewproj_matrix
1439The inverse transpose of the view & projection matrices
1440@item transpose_viewproj_matrix
1441The transpose of the view & projection matrices
1442@item transpose_view_matrix
1443The transpose of the view matrix
1444@item inverse_transpose_view_matrix
1445The inverse transpose of the view matrix
1446@item transpose_projection_matrix
1447The transpose of the projection matrix
1448@item inverse_projection_matrix
1449The inverse of the projection matrix
1450@item inverse_transpose_projection_matrix
1451The inverse transpose of the projection matrix
1452@item transpose_worldviewproj_matrix
1453The transpose of the world, view and projection matrices
1454@item inverse_worldviewproj_matrix
1455The inverse of the world, view and projection matrices
1456@item inverse_transpose_worldviewproj_matrix
1457The inverse transpose of the world, view and projection matrices
1458@item transpose_worldview_matrix
1459The transpose of the world and view matrices
1460@item inverse_transpose_worldview_matrix
1461The inverse transpose of the world and view matrices
1462@item transpose_world_matrix
1463The transpose of the world matrix
1464@item inverse_transpose_world_matrix
1465The inverse transpose of the world matrix
1466@item light_diffuse_colour
1467The 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 (ie 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.
1468@item light_specular_colour
1469The 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 (ie 0 refers to the closest light). NB if there are no lights this close, then the parameter will be set to black.
1470@item light_attenuation
1471A 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 (ie 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.
1472@item light_position
1473The 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 (ie 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.
1474@item light_direction
1475The 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 (ie 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.
1476@item light_position_object_space
1477The position of a given light in object space (ie 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 (ie 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.
1478@item light_direction_object_space
1479The direction of a given light in object space (ie 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 (ie 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_object_space instead since that returns a generic 4D vector.
1480@item ambient_light_colour
1481The colour of the ambient light currently set in the scene.
1482@item camera_position
1483The current cameras position in world space.
1484@item camera_position_object_space
1485The current cameras position in object space (ie when the object is at (0,0,0)).
1486@item time
1487The current time, factored by the optional parameter (or 1.0f if not supplied).
1488@item time_0_x
1489Single float time value, which repeats itself based on "cycle time" given as an 'extra_params' field
1490@item costime_0_x
1491Cosine of time_0_x
1492@item sintime_0_x
1493Sine of time_0_x
1494@item tantime_0_x
1495Tangent of time_0_x
1496@item time_0_x_packed
14974-element vector of time0_x, sintime0_x, costime0_x, tantime0_x
1498@item time_0_1
1499As time0_x but scaled to [0..1]
1500@item costime_0_1
1501As costime0_x but scaled to [0..1]
1502@item sintime_0_1
1503As sintime0_x but scaled to [0..1]
1504@item tantime_0_1
1505As tantime0_x but scaled to [0..1]
1506@item time_0_1_packed
1507As time0_x_packed but all values scaled to [0..1]
1508@item time_0_2pi
1509As time0_x but scaled to [0..2*Pi]
1510@item costime_0_2pi
1511As costime0_x but scaled to [0..2*Pi]
1512@item sintime_0_2pi
1513As sintime0_x but scaled to [0..2*Pi]
1514@item tantime_0_2pi
1515As tantime0_x but scaled to [0..2*Pi]
1516@item time_0_2pi_packed
1517As time0_x_packed but scaled to [0..2*Pi]
1518@item fps
1519The current frames per second
1520@item viewport_width
1521The current viewport width in pixels
1522@item viewport_height
1523The current viewport height in pixels
1524@item inverse_viewport_width
15251.0/the current viewport width in pixels
1526@item inverse_viewport_height
15271.0/the current viewport height in pixels
1528@item view_direction
1529View direction vector in object space
1530@item view_side_vector
1531View local X axis
1532@item view_up_vector
1533View local Y axis
1534@item fov
1535Vertical field of view, in radians
1536@item near_clip_distance
1537Near clip distance, in world units
1538@item far_clip_distance
1539Far clip distance, in world units (may be 0 for infinite view projection)
1540@item texture_viewproj_matrix
1541Only applicable to vertex programs which have been specified as the 'shadow receiver' vertex program alternative; this provides details of the view/projection matrix for the current shadow projector.
1542@item custom
1543This 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.
1544@end table
1545
1546@anchor{param_named}
1547@subheading param_named
1548This 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.@*@*
1549format: param_named <name> <type> <value>@*@*
1550example: param_named shininess float4 10.0 0 0 0@*@*
1551The 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.
1552
1553@anchor{param_named_auto}
1554@subheading param_named_auto
1555
1556This is the named equivalent of param_indexed_auto, for use with high-level programs.@*@*
1557Format: param_named_auto <name> <value_code> <extra_params>@*@*
1558Example: param_named_auto worldViewProj WORLDVIEWPROJ_MATRIX@*@*
1559
1560The allowed value codes and the meaning of extra_params are detailed in @ref{param_indexed_auto}.
1561
1562@anchor{Shadows and Vertex Programs}
1563@subheading Shadows and Vertex Programs
1564When using shadows (@xref{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. @*@*
1565
1566If you use @strong{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. @*@*
1567
1568If you use @strong{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:
1569
1570@example
1571shadow_caster_vertex_program_ref myShadowCasterVertexProgram
1572{
1573        param_indexed_auto 0 worldviewproj_matrix
1574        param_indexed_auto 4 ambient_light_colour
1575}
1576@end example
1577
1578When 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 @strong{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. @*@*
1579
1580In 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:
1581
1582@example
1583shadow_receiver_vertex_program_ref myShadowReceiverVertexProgram
1584{
1585        param_indexed_auto 0 worldviewproj_matrix
1586        param_indexed_auto 4 texture_viewproj_matrix
1587}
1588@end example
1589
1590For 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.
1591
1592
1593@node Particle Scripts
1594@section Particle Scripts
1595
1596Particle 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.@*@*
1597
1598@heading Loading scripts
1599
1600Particle 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.@*@*
1601
1602Once scripts have been parsed, your code is free to instantiate systems based on them using the ParticleSystemManager::getSingleton().createSystem() 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).@*@*
1603
1604@heading Format
1605
1606Several 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:
1607@example
1608// A sparkly purple fountain
1609Examples/PurpleFountain
1610{
1611    material Examples/Flare2
1612    particle_width 20
1613    particle_height 20
1614    cull_each false
1615    quota 10000
1616    billboard_type oriented_self
1617
1618    // Area emitter
1619    emitter Point
1620    {
1621        angle 15
1622        emission_rate 75
1623        time_to_live 3
1624        direction 0 1 0
1625        velocity_min 250
1626        velocity_max 300
1627        colour_range_start 1 0 0
1628        colour_range_end 0 0 1
1629    }
1630
1631    // Gravity
1632    affector LinearForce
1633    {
1634        force_vector 0 -100 0
1635        force_application add
1636    }
1637
1638    // Fader
1639    affector ColourFader
1640    {
1641        red -0.25
1642        green -0.25
1643        blue -0.25
1644    }
1645}
1646@end example
1647@*@*
1648Every 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.@*@*
1649
1650A 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.@*@*
1651
1652For a detailed description of the core particle system attributes, see the list below:
1653
1654@subheading Available Particle System Attributes
1655@itemize @bullet
1656@item
1657@ref{quota}
1658@item
1659@ref{particle_material, material}
1660@item
1661@ref{particle_width}
1662@item
1663@ref{particle_height}
1664@item
1665@ref{cull_each}
1666@item
1667@ref{billboard_type}
1668@item
1669@ref{common_direction}
1670@end itemize
1671See also: @ref{Particle Emitters}, @ref{Particle Affectors}
1672
1673@node Particle System Attributes
1674@subsection Particle System Attributes
1675This section describes to attributes which you can set on every particle system using scripts. All atributes have default values so all settings are optional in your script.@*@*
1676
1677@anchor{quota}
1678@subheading quota
1679
1680Sets 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).@*@*
1681
1682format: quota <max_particles>@*
1683example: quota 10000@*
1684default: 10@*
1685
1686@anchor{particle_material}
1687@subheading material
1688
1689Sets the name of the material which all particles in this system will use. All paticles in a system use the same material, although each particle can tint this material through the use of it's colour property.@*@*
1690
1691format: material <material_name>@*
1692example: material Examples/Flare@*
1693default: none (blank material)@*
1694
1695@anchor{particle_width}
1696@subheading particle_width
1697
1698Sets the width of particles in world coordinates. Note that this property is absolute when billboard_type (see below) is set to 'point', but is scaled by the length of the direction vector when billboard_type is 'oriented_common' or 'oriented_self'.@*
1699
1700format: particle_width <width>@*
1701example: particle_width 20@*
1702default: 100@*
1703
1704@anchor{particle_height}
1705@subheading particle_height
1706
1707Sets the height of particles in world coordinates. Note that this property is absolute when billboard_type (see below) is set to 'point', but is scaled by the length of the direction vector when billboard_type is 'oriented_common' or 'oriented_self'.@*
1708
1709format: particle_height <height>@*
1710example: particle_height 20@*
1711default: 100@*
1712
1713@anchor{cull_each}
1714@subheading cull_each
1715
1716All 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.@*@*
1717
1718format: cull_each <true|false>@*
1719example: cull_each true@*
1720default: false@*
1721
1722@anchor{billboard_type}
1723@subheading billboard_type
1724
1725Particles are rendered using billboards, which are rectangles formed by 2 triangles which rotate to face the camera. 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 effectd like laser fire, you actually want the particle to have an orientation of it's own.@*@*
1726
1727format: billboard_type <point|oriented_common|oriented_self>@*
1728example: billboard_type oriented_self@*
1729default: point@*
1730
1731The options for this parameter are:
1732@table @asis
1733@item point
1734        The default arrangement, this approximates spherical particles and the billboards always fully face the camera.
1735@item oriented_common
1736        Particles are oriented around a common, typically fixed direction vector (see @ref{common_direction}), which acts as their local Y axis. The billboard roatates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will travelling in one direction - this is slightly faster than oriented_self (see below).
1737@item oriented_self
1738        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 travelling in their own direction.
1739@end table
1740
1741@anchor{common_direction}
1742@subheading common_direction
1743
1744Only required if @ref{billboard_type} is set to oriented_common, this vector is the common direction vector used to orient all particles in the system.@*@*
1745
1746format: common_direction <x> <y> <z>@*
1747example: common_direction 0 -1 0@*
1748default: none@*
1749@*@*
1750See also: @ref{Particle Emitters}, @ref{Particle Affectors}
1751
1752@node Particle Emitters
1753@subsection Particle Emitters
1754Particle 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.
1755
1756@subheading Particle Emitter Universal Attributes
1757@itemize @bullet
1758@item
1759@ref{angle}
1760@item
1761@ref{colour}
1762@item
1763@ref{colour_range_start}
1764@item
1765@ref{colour_range_end}
1766@item
1767@ref{direction}
1768@item
1769@ref{emission_rate}
1770@item
1771@ref{position}
1772@item
1773@ref{velocity}
1774@item
1775@ref{velocity_min}
1776@item
1777@ref{velocity_max}
1778@item
1779@ref{time_to_live}
1780@item
1781@ref{time_to_live_min}
1782@item
1783@ref{time_to_live_max}
1784@item
1785@ref{duration}
1786@item
1787@ref{duration_min}
1788@item
1789@ref{duration_max}
1790@item
1791@ref{repeat_delay}
1792@item
1793@ref{repeat_delay_min}
1794@item
1795@ref{repeat_delay_max}
1796@end itemize
1797@*@*
1798See also: @ref{Particle Scripts}, @ref{Particle Affectors}
1799
1800
1801@node Particle Emitter Attributes
1802@subsection Particle Emitter Attributes
1803This section describes the common attributes of all particle emitters. Specific emitter types may also support their own extra attributes.@*@*
1804
1805@anchor{angle}
1806@subheading angle
1807
1808Sets 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.@*@*
1809
1810format: angle <degrees>@*
1811example: angle 30@*
1812default: 0@*
1813
1814@anchor{colour}
1815@subheading colour
1816
1817Sets 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).@*@*
1818
1819format: colour <r> <g> <b> [<a>]@*
1820example: colour 1 0 0 1@*
1821default: 1 1 1 1@*
1822
1823@anchor{colour_range_start} @anchor{colour_range_end}
1824@subheading colour_range_start & colour_range_end
1825
1826As 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.@*@*
1827
1828format: as colour@*
1829example (generates random colours between red and blue):@*
1830@ @ @ @ colour_range_start 1 0 0@*
1831@ @ @ @ colour_range_end 0 0 1@*
1832default: both 1 1 1 1@*
1833
1834@anchor{direction}
1835@subheading direction
1836
1837Sets 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.@*@*
1838
1839format: direction <x> <y> <z>@*
1840example: direction 0 1 0@*
1841default: 1 0 0@*
1842
1843@anchor{emission_rate}
1844@subheading emission_rate
1845
1846Sets 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
1847and 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.@*@*
1848
1849format: emission_rate <particles_per_second>@*
1850example: emission_rate 50@*
1851default: 10@*
1852
1853@anchor{position}
1854@subheading position
1855
1856Sets the position of the emitter relative to the SceneNode the particle system is attached to.@*@*
1857
1858format: position <x> <y> <z>@*
1859example: position 10 0 40@*
1860default: 0 0 0@*
1861
1862@anchor{velocity}
1863@subheading velocity
1864
1865Sets 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.@*@*
1866
1867format: velocity <world_units_per_second>@*
1868example: velocity 100@*
1869default: 1@*
1870
1871@anchor{velocity_min} @anchor{velocity_max}
1872@subheading velocity_min & velocity_max
1873
1874As 'velocity' except these attributes set a velocity range and each particle is emitted with a random velocity within this range.@*@*
1875
1876format: as velocity@*
1877example:@*
1878@ @ @ @ velocity_min 50@*
1879@ @ @ @ velocity_max 100@*
1880default: both 1@*
1881
1882@anchor{time_to_live}
1883@subheading time_to_live
1884
1885Sets 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.@*@*
1886
1887format: time_to_live <seconds>@*
1888example: time_to_live 10@*
1889default: 5@*
1890
1891@anchor{time_to_live_min} @anchor{time_to_live_max}
1892@subheading time_to_live_min & time_to_live_max
1893As time_to_live, except this sets a range of lifetimes and each particle gets a random value inbetween on emission.@*@*
1894
1895format: as time_to_live@*
1896example:@*
1897@ @ @ @ time_to_live_min 2@*
1898@ @ @ @ time_to_live_max 5@*
1899default: both 5@*
1900@*
1901
1902@anchor{duration}
1903@subheading duration
1904
1905Sets the number of seconds the emitter is active. The emitter can be started again, see @ref{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.@*@*
1906
1907format: duration <seconds>@*
1908example:@*
1909@ @ @ @ duration 2.5@*
1910default: 0@*
1911@*
1912
1913@anchor{duration_min} @anchor{duration_max}
1914@subheading duration_min & duration_max
1915
1916As duration, except these attributes set a variable time range between the min and max values each time the emitter is started.@*@*
1917
1918format: as duration@*
1919example:@*
1920@ @ @ @ duration_min 2@*
1921@ @ @ @ duration_max 5@*
1922default: both 0@*
1923@*
1924
1925@anchor{repeat_delay}
1926@subheading repeat_delay
1927
1928Sets the number of seconds to wait before the emission is repeated when stopped by a limited @ref{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.@*@*
1929
1930format: repeat_delay <seconds>@*
1931example:@*
1932@ @ @ @ repeat_delay 2.5@*
1933default: 0@*
1934@*
1935
1936@anchor{repeat_delay_min} @anchor{repeat_delay_max}
1937@subheading repeat_delay_min & repeat_delay_max
1938
1939As repeat_delay, except this sets a range of repeat delays and each time the emitter is started it gets a random value inbetween.@*@*
1940
1941format: as repeat_delay@*
1942example:@*
1943@ @ @ @ repeat_delay 2@*
1944@ @ @ @ repeat_delay 5@*
1945default: both 0@*
1946@*
1947
1948See also: @ref{Standard Particle Emitters}, @ref{Particle Scripts}, @ref{Particle Affectors}
1949
1950
1951@node Standard Particle Emitters
1952@subsection Standard Particle Emitters
1953Ogre 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).
1954
1955@itemize @bullet
1956@item
1957@ref{Point Emitter}
1958@item
1959@ref{Box Emitter}
1960@item
1961@ref{Cylinder Emitter}
1962@item
1963@ref{Ellipsoid Emitter}
1964@item
1965@ref{Hollow Ellipsoid Emitter}
1966@item
1967@ref{Ring Emitter}
1968@end itemize
1969@*@*
1970@anchor{Point Emitter}
1971@subheading Point Emitter
1972
1973This 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.@*@*
1974
1975To create a point emitter, include a section like this within your particle system script:
1976@example
1977
1978emitter Point
1979{
1980    // Settings go here
1981}
1982@end example
1983@*
1984Please note that the name of the emitter ('Point') is case-sensitive.
1985
1986@anchor{Box Emitter}
1987@subheading Box Emitter
1988
1989This emitter emits particles from a random location within a 3-dimensional box. It's extra attributes are:@*@*
1990@table @asis
1991@item width
1992Sets 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).@*
1993format: width <units>@*
1994example: width 250@*
1995default: 100@*
1996@item height
1997Sets 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).@*
1998format: height <units>@*
1999example: height 250@*
2000default: 100@*
2001@item depth
2002Sets 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).@*
2003format: depth <units>@*
2004example: depth 250@*
2005default: 100@*
2006@end table
2007@*
2008To create a box emitter, include a section like this within your particle system script:
2009@example
2010emitter Box
2011{
2012    // Settings go here
2013}
2014@end example
2015
2016@anchor{Cylinder Emitter}
2017@subheading Cylinder Emitter
2018
2019This 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 @ref{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.
2020
2021@anchor{Ellipsoid Emitter}
2022@subheading Ellipsoid Emitter
2023This emitter emits particles from within an ellipsoid shaped area, ie a sphere or squashed-sphere area. The parameters are again identical to the @ref{Box Emitter}, except that the dimensions describe the widest points along each of the axes.
2024
2025@anchor{Hollow Ellipsoid Emitter}
2026@subheading Hollow Ellipsoid Emitter
2027This emitter is just like @ref{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:
2028
2029@table @asis
2030@item inner_width
2031The width of the inner area which does not emit any particles.
2032@item inner_height
2033The height of the inner area which does not emit any particles.
2034@item inner_depth
2035The depth of the inner area which does not emit any particles.
2036@end table
2037
2038@anchor{Ring Emitter}
2039@subheading Ring Emitter
2040This emitter emits particles from a ring-shaped area, ie a little like @ref{Hollow Ellipsoid Emitter} except only in 2 dimensions.
2041
2042@table @asis
2043@item inner_width
2044The width of the inner area which does not emit any particles.
2045@item inner_height
2046The height of the inner area which does not emit any particles.
2047@end table
2048@*@*
2049
2050See also: @ref{Particle Scripts}, @ref{Particle Emitters}
2051
2052@node Particle Affectors
2053@subsection Particle Affectors
2054
2055Particle 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.@*@*
2056
2057Particle affectors actually have no universal attributes; they are all specific to the type of affector.@*@*
2058
2059See also: @ref{Standard Particle Affectors}, @ref{Particle Scripts}, @ref{Particle Emitters}
2060
2061@node Standard Particle Affectors
2062@subsection Standard Particle Affectors
2063Ogre 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).
2064
2065@itemize @bullet
2066@item
2067@ref{Linear Force Affector}
2068@item
2069@ref{ColourFader Affector}
2070@item
2071@ref{ColourFader2 Affector}
2072@item
2073@ref{Scaler Affector}
2074@item
2075@ref{Rotator Affector}
2076@item
2077@ref{ColourInterpolator Affector}
2078@item
2079@ref{ColourImage Affector}
2080@end itemize
2081
2082@anchor{Linear Force Affector}
2083@subheading Linear Force Affector
2084
2085This 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:@*@*
2086@table @asis
2087@item force_vector
2088Sets the vector for the force to be applied to every particle. The magnitude of this vector determines how strong the force is.@*
2089@ @ @ @ format: force_vector <x> <y> <z>@*
2090@ @ @ @ example: force_vector 50 0 -50@*
2091@ @ @ @ default: 0 -100 0 (a fair gravity effect)@*
2092@item force_application
2093
2094Sets the way in which the force vector is applied to particle momentum.@*
2095@ @ @ @ format: force_application <add|average>@*
2096@ @ @ @ example: force_application average@*
2097@ @ @ @ default: add@*
2098The options are:
2099@table @asis
2100@item average
2101        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.
2102@item add
2103        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.
2104@end table
2105@end table
2106@*
2107To create a linear force affector, include a section like this within your particle system script:
2108@example
2109affector LinearForce
2110{
2111    // Settings go here
2112}
2113@end example
2114Please note that the name of the affector type ('LinearForce') is case-sensitive.
2115
2116@anchor{ColourFader Affector}
2117@subheading ColourFader Affector
2118
2119This affector modifies the colour of particles in flight. It's extra attributes are:
2120@table @asis
2121@item red
2122Sets the adjustment to be made to the red component of the particle colour per second.@*
2123@ @ @ @ format: red <delta_value>@*
2124@ @ @ @ example: red -0.1@*
2125@ @ @ @ default: 0@*
2126@item green
2127Sets the adjustment to be made to the green component of the particle colour per second.@*
2128@ @ @ @ format: green <delta_value>@*
2129@ @ @ @ example: green -0.1@*
2130@ @ @ @ default: 0@*
2131@item blue
2132Sets the adjustment to be made to the blue component of the particle colour per second.@*
2133@ @ @ @ format: blue <delta_value>@*
2134@ @ @ @ example: blue -0.1@*
2135@ @ @ @ default: 0@*
2136@item alpha
2137Sets the adjustment to be made to the alpha component of the particle colour per second.@*
2138@ @ @ @ format: alpha <delta_value>@*
2139example: alpha -0.1@*
2140default: 0@*
2141@end table
2142To create a colour fader affector, include a section like this within your particle system script:
2143@example
2144affector ColourFader
2145{
2146    // Settings go here
2147}
2148@end example
2149
2150@anchor{ColourFader2 Affector}
2151@subheading ColourFader2 Affector
2152
2153This affector is similar to the @ref{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.
2154@table @asis
2155@item red1
2156Sets the adjustment to be made to the red component of the particle colour per second for the first state.@*
2157@ @ @ @ format: red <delta_value>@*
2158@ @ @ @ example: red -0.1@*
2159@ @ @ @ default: 0@*
2160@item green1
2161Sets the adjustment to be made to the green component of the particle colour per second for the first state.@*
2162@ @ @ @ format: green <delta_value>@*
2163@ @ @ @ example: green -0.1@*
2164@ @ @ @ default: 0@*
2165@item blue1
2166Sets the adjustment to be made to the blue component of the particle colour per second for the first state.@*
2167@ @ @ @ format: blue <delta_value>@*
2168@ @ @ @ example: blue -0.1@*
2169@ @ @ @ default: 0@*
2170@item alpha1
2171Sets the adjustment to be made to the alpha component of the particle colour per second for the first state.@*
2172@ @ @ @ format: alpha <delta_value>@*
2173example: alpha -0.1@*
2174default: 0@*
2175@item red2
2176Sets the adjustment to be made to the red component of the particle colour per second for the second state.@*
2177@ @ @ @ format: red <delta_value>@*
2178@ @ @ @ example: red -0.1@*
2179@ @ @ @ default: 0@*
2180@item green2
2181Sets the adjustment to be made to the green component of the particle colour per second for the second state.@*
2182@ @ @ @ format: green <delta_value>@*
2183@ @ @ @ example: green -0.1@*
2184@ @ @ @ default: 0@*
2185@item blue2
2186Sets the adjustment to be made to the blue component of the particle colour per second for the second state.@*
2187@ @ @ @ format: blue <delta_value>@*
2188@ @ @ @ example: blue -0.1@*
2189@ @ @ @ default: 0@*
2190@item alpha2
2191Sets the adjustment to be made to the alpha component of the particle colour per second for the second state.@*
2192@ @ @ @ format: alpha <delta_value>@*
2193example: alpha -0.1@*
2194default: 0@*
2195@item state_change
2196When a particle has this much time left to live, it will switch to state 2.@*
2197@ @ @ @ format: state_change <seconds>@*
2198example: state_change 2@*
2199default: 1@*
2200@end table
2201To create a ColourFader2 affector, include a section like this within your particle system script:
2202@example
2203affector ColourFader2
2204{
2205    // Settings go here
2206}
2207@end example
2208
2209@anchor{Scaler Affector}
2210@subheading Scaler Affector
2211
2212This affector scales particles in flight. It's extra attributes are:
2213@table @asis
2214@item rate
2215The amount by which to scale the particles in both the x and y direction per second.
2216@end table
2217To create a scale affector, include a section like this within your particle system script:
2218@example
2219affector Scaler
2220{
2221    // Settings go here
2222}
2223@end example
2224
2225@anchor{Rotator Affector}
2226@subheading Rotator Affector
2227
2228This affector rotates particles in flight. This is done by rotating the texture. It's extra attributes are:
2229@table @asis
2230@item rotation_speed_range_start
2231The start of a range of rotation speeds to be assigned to emitted particles.@*
2232@ @ @ @ format: rotation_speed_range_start <degrees_per_second>@*
2233example: rotation_speed_range_start 90@*
2234default: 0@*
2235@item rotation_speed_range_end
2236The end of a range of rotation speeds to be assigned to emitted particles.@*
2237@ @ @ @ format: rotation_speed_range_end <degrees_per_second>@*
2238example: rotation_speed_range_end 180@*
2239default: 0@*
2240@item rotation_range_start
2241The start of a range of rotation angles to be assigned to emitted particles.@*
2242@ @ @ @ format: rotation_range_start <degrees>@*
2243example: rotation_range_start 0@*
2244default: 0@*
2245@item rotation_range_end
2246The end of a range of rotation angles to be assigned to emitted particles.@*
2247@ @ @ @ format: rotation_range_end <degrees>@*
2248example: rotation_range_end 360@*
2249default: 0@*
2250@end table
2251To create a rotate affector, include a section like this within your particle system script:
2252@example
2253affector Rotator
2254{
2255    // Settings go here
2256}
2257@end example
2258
2259@anchor{ColourInterpolator Affector}
2260@subheading ColourInterpolator Affector
2261
2262Similar 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:
2263@table @asis
2264@item time0
2265The point in time of stage 0.@*
2266@ @ @ @ format: time0 <0-1 based on lifetime>@*
2267example: time0 0@*
2268default: 1@*
2269@item colour0
2270The colour at stage 0.@*
2271@ @ @ @ format: colour0 <r> <g> <b> [<a>]@*
2272example: colour0 1 0 0 1@*
2273default: 0.5 0.5 0.5 0.0@*
2274@item time1
2275The point in time of stage 1.@*
2276@ @ @ @ format: time1 <0-1 based on lifetime>@*
2277example: time1 0.5@*
2278default: 1@*
2279@item colour1
2280The colour at stage 1.@*
2281@ @ @ @ format: colour1 <r> <g> <b> [<a>]@*
2282example: colour1 0 1 0 1@*
2283default: 0.5 0.5 0.5 0.0@*
2284@item time2
2285The point in time of stage 2.@*
2286@ @ @ @ format: time2 <0-1 based on lifetime>@*
2287example: time2 1@*
2288default: 1@*
2289@item colour2
2290The colour at stage 2.@*
2291@ @ @ @ format: colour2 <r> <g> <b> [<a>]@*
2292example: colour2 0 0 1 1@*
2293default: 0.5 0.5 0.5 0.0@*
2294@item [...]
2295@end table
2296The number of stages is variable. The maximal number of stages is 6; where time5 and colour5 are the last possible parameters.
2297To create a colour interpolation affector, include a section like this within your particle system script:
2298@example
2299affector ColourInterpolator
2300{
2301    // Settings go here
2302}
2303@end example
2304
2305@anchor{ColourImage Affector}
2306@subheading ColourImage Affector
2307
2308This 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:
2309@table @asis
2310@item image
2311The start of a range of rotation speed to be assigned to emitted particles.@*
2312@ @ @ @ format: image <image_name>@*
2313example: image rainbow.png@*
2314default: none@*
2315@end table
2316To create a ColourImage affector, include a section like this within your particle system script:
2317@example
2318affector ColourImage
2319{
2320    // Settings go here
2321}
2322@end example
2323
2324
2325@node Overlay Scripts
2326@section Overlay Scripts
2327
2328Overlay 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.@*@*
2329
2330@heading Loading scripts
2331
2332Overlay 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.@*@*
2333
2334@heading Format
2335
2336Several 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:
2337@example
2338// The name of the overlay comes first
2339MyOverlays/ANewOverlay
2340{
2341    zorder 200
2342
2343    container Panel(MyOverlayElements/TestPanel)
2344    {
2345        // Center it horzontally, put it at the top
2346        left 0.25
2347        top 0
2348        width 0.5
2349        height 0.1
2350        material MyMaterials/APanelMaterial
2351
2352        // Another panel nested in this one
2353        container Panel(MyOverlayElements/AnotherPanel)
2354        {
2355             left 0
2356             top 0
2357             width 0.1
2358             height 0.1
2359             material MyMaterials/NestedPanel
2360        }
2361    }
2362
2363}
2364@end example
2365
2366The 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).@*@*
2367
2368Every 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.@*@*
2369
2370@heading Adding elements to the overlay
2371
2372Within an overlay, you can include any number of 2D or 3D elements. You do this by defining a nested block headed by:
2373@table @asis
2374@item 'element'
2375if you want to define a 2D element which cannot have children of it's own
2376@item 'container'
2377if you want to define a 2D container object (which may itself have nested containers or elements)
2378@item 'entity'
2379if you want to include a 3D element (can only occur directly under the overlay, not under a 2D element)
2380@end table
2381@*
2382The element and container blocks are pretty identical apart from their ability to store nested blocks.
2383
2384@heading 'container' / 'element' blocks
2385
2386These are delimited by curly braces. The format for the header preceding the first brace is:@*@*
2387
2388[container | element] <type_name> ( <instance_name>) [: <template_name>]@*
2389{ ...@*@*
2390@table @asis
2391@item type_name
2392Must 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'.
2393@item instance_name
2394Must 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).
2395@item template_name
2396Optional template on which to base this item. See templates.
2397@end table
2398
2399The properties which can be included within the braces depend on the custom type. However the following are always valid:
2400@itemize @bullet
2401@item
2402@ref{metrics_mode}
2403@item
2404@ref{horz_align}
2405@item
2406@ref{vert_align}
2407@item
2408@ref{left}
2409@item
2410@ref{top}
2411@item
2412@ref{width}
2413@item
2414@ref{height}
2415@item
2416@ref{overlay_material, material}
2417@item
2418@ref{caption}
2419@end itemize
2420
2421@subheading 'entity' blocks
2422
2423These are delimited by curly braces. The format for the header preceding the first brace is:@*@*
2424
2425entity <mesh_name> ( <entity_name>)@*
2426{ ...@*@*
2427
2428@table @asis
2429@item mesh_name
2430The name of a .mesh file defining the entity geometry
2431@item entity_name
2432The name to give the entity created, must be unique to this entity.
2433@item position
2434The position of the entity, as an x, y, z triple.
2435@item rotation
2436The rotation of the entity, expressed as <angle_in_degrees> <axis_x> <axis_y> <axis_z>
2437@end table
2438
2439This is treated like any other Entity, @xref{Entities}.
2440
2441@heading Templates
2442
2443You 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, element, or entity). 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.@*@*
2444
2445Elements 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).@*@*
2446
2447A 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.@*@*
2448@example
2449template container BorderPanel(MyTemplates/BasicBorderPanel)
2450{
2451    left 0
2452    top 0
2453    width 1
2454    height 1
2455
2456// setup the texture UVs for a borderpanel
2457
2458// do this in a template so it doesn't need to be redone everywhere
2459    material Core/StatsBlockCenter
2460    border_size 0.05 0.05 0.06665 0.06665
2461    border_material Core/StatsBlockBorder
2462    border_topleft_uv 0.0000 1.0000 0.1914 0.7969
2463    border_top_uv 0.1914 1.0000 0.8086 0.7969
2464    border_topright_uv 0.8086 1.0000 1.0000 0.7969
2465    border_left_uv 0.0000 0.7969 0.1914 0.2148
2466    border_right_uv 0.8086 0.7969 1.0000 0.2148
2467    border_bottomleft_uv 0.0000 0.2148 0.1914 0.0000
2468    border_bottom_uv 0.1914 0.2148 0.8086 0.0000
2469    border_bottomright_uv 0.8086 0.2148 1.0000 0.0000
2470}
2471template container Button(MyTemplates/BasicButton) : MyTemplates/BasicBorderPanel
2472{
2473    left 0.82
2474    top 0.45
2475    width 0.16
2476    height 0.13
2477    material Core/StatsBlockCenter
2478    border_up_material Core/StatsBlockBorder/Up
2479    border_down_material Core/StatsBlockBorder/Down
2480}
2481template element TextArea(MyTemplates/BasicText)
2482{
2483    font_name Ogre
2484    char_height 0.08
2485    colour_top 1 1 0
2486    colour_bottom 1 0.2 0.2
2487    left 0.03
2488    top 0.02
2489    width 0.12
2490    height 0.09
2491}
2492
2493MyOverlays/AnotherOverlay
2494{
2495    zorder 490
2496    container BorderPanel(MyElements/BackPanel) : MyTemplates/BasicBorderPanel
2497    {
2498        left 0
2499        top 0
2500        width 1
2501        height 1
2502
2503        container Button(MyElements/HostButton) : MyTemplates/BasicButton
2504        {
2505            left 0.82
2506            top 0.45
2507            caption MyTemplates/BasicText HOST
2508        }
2509
2510        container Button(MyElements/JoinButton) : MyTemplates/BasicButton
2511        {
2512            left 0.82
2513            top 0.60
2514            caption MyTemplates/BasicText JOIN
2515        }
2516    }
2517}
2518@end example
2519The 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.@*@*
2520
2521Also 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).@*@*
2522
2523@xref{OverlayElement Attributes}, @ref{Standard OverlayElements}
2524
2525@node OverlayElement Attributes
2526@subsection OverlayElement Attributes
2527
2528These 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.@*@*
2529
2530@anchor{metrics_mode}
2531@subheading metrics_mode
2532
2533Sets the units which will be used to size and position this element.@*@*
2534
2535Format: metrics_mode <pixels|relative>@*
2536Example: metrics_mode pixels@*
2537
2538This 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.@*@*
2539
2540Default: metrics_mode relative@*
2541
2542@anchor{horz_align}
2543@subheading horz_align
2544
2545Sets the horizontal alignment of this element, in terms of where the horizontal origin is.@*@*
2546
2547Format: horz_align <left|center|right>@*
2548Example: horz_align center@*@*
2549
2550This 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.@*@*
2551
2552Note that you can use this property in both relative and pixel modes, but it is most useful in pixel mode.@*@*
2553
2554Default: horz_align left@*
2555
2556@anchor{vert_align}
2557@subheading vert_align
2558
2559Sets the vertical alignment of this element, in terms of where the vertical origin is.@*@*
2560
2561Format: vert_align <top|center|bottom>@*
2562Example: vert_align center@*@*
2563
2564This 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.@*@*
2565
2566Note that you can use this property in both relative and pixel modes, but it is most useful in pixel mode.@*@*
2567
2568Default: vert_align top@*
2569
2570@anchor{left}
2571@subheading left
2572
2573Sets the horizontal position of the element relative to it's parent.@*@*
2574
2575Format: left <value>@*
2576Example: left 0.5@*@*
2577
2578Positions 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.@*@*
2579
2580Default: left 0@*
2581
2582@anchor{top}
2583@subheading top
2584
2585Sets the vertical position of the element relative to it's parent.@*@*
2586
2587Format: top <value>@*
2588Example: top 0.5@*@*
2589
2590Positions 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.@*@*
2591
2592Default: top 0@*
2593
2594@anchor{width}
2595@subheading width
2596
2597Sets the width of the element as a proportion of the size of the screen.@*@*
2598
2599Format: width <value>@*
2600Example: width 0.25@*@*
2601
2602Sizes 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.@*@*
2603
2604Default: width 1@*
2605
2606@anchor{height}
2607@subheading height
2608
2609Sets the height of the element as a proportion of the size of the screen.@*@*
2610
2611Format: height <value>@*
2612Example: height 0.25@*@*
2613
2614Sizes 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.@*@*
2615
2616Default: height 1@*
2617
2618@anchor{overlay_material}
2619@subheading material
2620
2621Sets the name of the material to use for this element.@*@*
2622
2623Format: material <name>@*
2624Example: material Examples/TestMaterial@*@*
2625
2626This 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.@*@*
2627
2628Default: none@*
2629
2630@anchor{caption}
2631@subheading caption
2632
2633Sets a text caption for the element.@*@*
2634
2635Format: caption <string>@*
2636Example: caption This is a caption@*@*
2637
2638Not 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.@*@*
2639
2640Default: blank@*
2641
2642
2643@anchor{rotation}
2644@subheading rotation
2645
2646Sets the rotation of the element.@*@*
2647
2648Format: rotation <angle_in_degrees> <axis_x> <axis_y> <axis_z>
2649Example: rotation 30 0 0 1
2650
2651Default: none
2652
2653@node Standard OverlayElements
2654@subsection Standard OverlayElements
2655
2656Although 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:
2657@itemize @bullet
2658@item
2659@ref{Panel}
2660@item
2661@ref{BorderPanel}
2662@item
2663@ref{TextArea}
2664@item
2665@ref{TextBox}
2666@end itemize
2667@*
2668This 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.
2669
2670@anchor{Panel}
2671@subheading Panel (container)
2672
2673This 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.@*@*
2674
2675Attributes:
2676@table @asis
2677@item transparent <true | false>
2678If set to 'true' the panel is transparent and is not rendered itself, it is just used as a grouping level for it's children.
2679@item tiling <layer> <x_tile> <y_tile>
2680Sets 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.
2681@end table
2682
2683@anchor{BorderPanel}
2684@subheading BorderPanel (container)
2685
2686This 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.@*@*
2687
2688Attributes:
2689@table @asis
2690@item border_size <left> <right> <top> <bottom>
2691The 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.
2692@item border_material <name>
2693The 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.
2694@item border_topleft_uv <u1> <v1> <u2> <v2>
2695[also border_topright_uv, border_bottomleft_uv, border_bottomright_uv];
2696The 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.
2697@item border_left_uv <u1> <v1> <u2> <v2>
2698[also border_right_uv, border_top_uv, border_bottom_uv];
2699The 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.
2700@end table
2701
2702
2703@anchor{TextArea}
2704@subheading TextArea (element)
2705
2706This 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.@*@*
2707
2708Attributes:
2709@table @asis
2710@item font_name <name>
2711The name of the font to use. This font must be defined in a .fontdef file to ensure it is available at scripting time.
2712@item char_height <height>
2713The 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.
2714@item colour <red> <green> <blue>
2715A 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.
2716@item colour_bottom <red> <green> <blue> / colour_top <red> <green> <blue>
2717As 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.
2718@end table
2719
2720@anchor{TextBox}
2721@subheading TextBox (element)
2722
2723This element is a box that allows text input. It is composed of 2 elements, a TextArea, which defines the size, colour etc of the text to be used when typed, and a back panel which is the box-element on which the text is written.@*@*
2724
2725Attributes:
2726@table @asis
2727@item text_area <template name> [<caption>]
2728The name of the TextArea template to be used as the basis for the TextBox font. The optional caption is the text the textbox is initialised with.
2729@item back_panel <template name>
2730The name of the back panel template (e.g. a @ref{BorderPanel}) to be used as the basis for the back panel on which the text is written. This needs to be a container.
2731@end table
2732
2733
2734@node Font Definition Scripts
2735@section Font Definition Scripts
2736
2737Ogre 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.@*@*
2738
2739There are 2 ways you can get a font into OGRE:
2740@enumerate
2741@item Design a font texture yourself using an art package or font generator tool
2742@item Ask OGRE to generate a font texture based on a truetype font
2743@end enumerate
2744
2745The 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.@*@*
2746
2747All 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 fomat of an entry in the .fontdef file is:
2748@example
2749<font_name>
2750{
2751    type <image | truetype>
2752    source <image file | truetype font file>
2753    ...
2754    ... custom attributes depending on type
2755}
2756@end example
2757
2758@heading Using an existing font texture
2759
2760If 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:
2761@table @asis
2762@item type image
2763This just tells OGRE you want a pre-drawn font.
2764@item source <filename>
2765This 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.
2766@item glyph <character> <u1> <v1> <u2> <v2>
2767This 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.
2768@end table
2769
2770A note for Windows users: I recommend using BitmapFontBuilder (@url{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.@*
2771
2772@heading Generating a font texture
2773
2774You 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.@*@*
2775
2776Here are the attributes you need to supply:
2777@table @asis
2778@item type truetype
2779Tells OGRE to generate the texture from a font
2780@item source <ttf file>
2781The 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.
2782@item size <size_in_points>
2783The 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.
2784@item resolution <dpi>
2785The resolution in dots per inch, this is used in conjunction with the point size to determine the final size. 72 / 96 dpi is normal.
2786@item antialias_colour <true|false>
2787This 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 anitaliased 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.
2788@end table
2789@*@*
2790You can also create new fonts at runtime by using the FontManager if you wish.
2791
2792@node Mesh Tools
2793@chapter Mesh Tools
2794There are a number of mesh tools available with OGRE to help you manipulate your meshes.
2795@table @asis
2796@item @ref{Exporters}
2797For getting data out of modellers and into OGRE.
2798@item @ref{XmlConverter}
2799For converting meshes and skeletons to/from XML.
2800@item @ref{MeshUpgrader}
2801For upgrading binary meshes from one version of OGRE to another.
2802@end table
2803
2804@node Exporters
2805@section Exporters
2806
2807Exporters 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.@*@*
2808
2809Each 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.@*@*
2810
2811All the exporters here can be built from the source code, or you can download precompiled versions from the OGRE web site.@*@*
2812
2813@heading A Note About Modelling / Animation For OGRE
2814There are a few rules when creating an animated model for OGRE:
2815@itemize @bullet
2816@item You must have no more than 4 weighted bone assignments per vertex. If you have more, OGRE will eliminate the lowest weighted assignments and renormalise the other weights. This limit is imposed by hardware blending limitations.
2817@item All vertices must be assigned to at least one bone - assign static vertices to the root bone.
2818@item At the very least each bone must have a keyframe at the beginning and end of the animation.
2819@end itemize
2820If you're creating unanimated meshes, then you do not need to be concerned with the above.
2821
2822@heading Milkshape3D
2823
2824Milkshape3D is a popular low-polygon editor, especially popular in the modding community because of it's low price and the fact that it supports many game file formats. Installation instructions are included with the exporter itself. The Milkshape exporter supports exporting of meshes and animations. An important tip: Make sure you are not in 'animation' mode when you do this, otherwise Milkshape gets confused as to what the 'reference' position of the mesh is. Just make sure the 'Anim' button in the bottom-right is NOT depressed.@*@*
2825
2826You then get a dialog box with several options:
2827@table @asis
2828@item Export Mesh
2829Obvious really - if checked this exports the geometry data (vertex positions, normals & texture coordinates) to a .mesh file.
2830@item Export Skeleton & Animation
2831If checked, the bones of the model and animation data is exported to a .skeleton file.
2832@item Split Keyframe Sequence Into Multiple Animations
2833You can check this to split the single timeline in Milkshape into multiple separate animations (this option has no effect if you are not exporting the skeleton). This is necessary because Milkshape doesn't have a concept of multiple separate animations, you just have to model them all in a single timeline and then use this feature to split them up. If you check this box you must supply a text file which tells OGRE how to split the animation up. This text file is very simple: each line is a single animation, and must contain comma-separated values indicating the start frame, end frame and name of the animation, e.g.:
2834@example
2835    1,30,Walk
2836    31,45,Run
2837    46,75,Die
2838    ...etc
2839@end example
2840@item Frame Rate
2841The Milkshape timeline is in frames, but OGRE likes to deal with animations in terms of seconds for simplicity. This value allows the exporter to do the conversion. Note there's nothing to stop you animating the mesh at a different frame rate in OGRE at runtime by scaling the amount you change the animation by each time, but this bakes a 'default animation speed' into the animation for simplicity.
2842@end table
2843
2844@heading 3D Studio Max R4/5
2845The 3D Studio exporter exports both mesh definitions and animations created with Biped and Physique. It requires no compilation because it is written in MaxScript, and exports data to XML before converting it using @ref{XmlConverter}. There are tutorials included with the exporter in it's Docs/ folder.
2846
2847@heading Other exporters
2848These other exporters are provided with OGRE, but are either still under development or are supported externally:
2849@itemize
2850@item Wings3D
2851@item Blender
2852@item Maya
2853@item Lightwave
2854@end itemize
2855
2856@node XmlConverter
2857@section XmlConverter
2858
2859The 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. @*@*
2860
2861Syntax:
2862@example
2863Usage: OgreXMLConverter sourcefile [destfile]
2864sourcefile = name of file to convert
2865destfile   = optional name of file to write to. If you don't
2866             specify this OGRE works it out through the extension
2867             and the XML contents if the source is XML. For example
2868             test.mesh becomes test.xml, test.xml becomes test.mesh
2869             if the XML document root is <mesh> etc.
2870@end example
2871When 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.
2872
2873@node MeshUpgrader
2874@section MeshUpgrader
2875This 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:
2876@example
2877OgreMeshUpgrade <oldmesh> <newmesh>
2878@end example
2879The OGRE release notes will notify you when this is necessary with a new release.
2880
2881@include vbos.inc
2882@include texturesource.inc
2883@include shadows.inc
2884
2885@bye
2886
Note: See TracBrowser for help on using the repository browser.