-<?xml version="1.0" encoding="utf-8">
-<!--
- An effect consists of parameters and techniques. The "parameters"
- section of an effect is a tree of values that describe, abstractly,
- the graphical appearence of objects that use the effect. Techniques
- refer to these parameters and use them to set OpenGL state or to
- set parameters for shader programs. Parameters can be declared to
- have a dynamic variance, which means that if their value is changed
- the corresponding value in the technique will be changed too.
-
- A technique can contain a predicate that describes the OpenGL
- functionality required to support the technique. The first
- technique with a valid predicate in the list of techniques is used
- to set up the graphics state of the effect. A technique with no
- predicate is always assumed to be valid.
-
- A technique can consist of several passes, which are run in
- sequence.
-
- One feature not fully illustrated in the sample below is that
- effects can inherit from each other. The parent effect is listed in
- the "inherits-from" form. The child effect's property tree is
- overlaid over that of the parent. This means that effects that
- inherit from the example "default effect" below could be very
- short, listing just new parameters and adding nothing to the
- techniques section; alternatively, a technique could be altered or
- customized in a child, listing (for example) a different shader
- program. Terrain materials work in this way: for each material type
- in materials.xml an effect is created that inherits from a single
- default terrain effect. The parameters section of the effect is
- filled in using the ambient, diffuse, etc. fields of the material.
-
- Material animations will be implemented by creating a new effect
- that inherits from one in a model, overriding the parameters that
- will be animated.
-
- Ultimately all OpenGL state will be setable in a technique. These
- attributes and modes are currently implemented:
- lighting - true, false
- shade-model - flat, smooth
- cull-face - front, back, front-back
- rendering-hint - (OSG) opaque, transparent
- render-bin - children: bin-number, bin-name
- material - children: ambient, ambient-front, ambient-back, diffuse,
- diffuse-front, diffuse-back, specular, specular-front,
- specular-back, emissive, emissive-front, emissive-back, shininess,
- shininess-front, shininess-back, color-mode
- blend - true, false
- alpha-test - true, false
- texture-unit -
- unit
- texture2d
- image (file name)
- filter
- mag-filter
- wrap-s
- wrap-t
- wrap-r
- environment
- mode
- color
- program
- vertex-shader
- fragment-shader
- uniform
- name
- type - float, float-vec3, float-vec4, sampler-1d, sampler-2d,
- sampler-3d
- polygon-mode
- front - fill, line, point
- back - fill, line, point
- -->
-<PropertyList>
- <effect>
- <name>city</name>
- <!-- <inherits-from>another-effect</inherits-from> -->
- <parameters>
- <material>
- <ambient type="vec4d">
- 0.0 0.0 0.0 1.0
- </ambient>
- <diffuse type="vec4d">
- .5 .5 .5 1.0
- </diffuse>
- <specular type="vec4d">
- 0.3 0.3 0.3 1.0
- </specular>
- <emissive type="vec4d" variance="dynamic">
- 0.0 0.0 0.0 1.0
- </emissive>
- <shininess>1.2</shininess>
- </material>
- <texture n="0">
- <texture2d>
- <image>city.png</image>
- <filter>linear-mipmap-linear</filter>
- <!-- also repeat -->
- <wrap-s>clamp</wrap-s>
- <wrap-t>clamp-to-edge</wrap-t>
- <!--
- <wrap-r>clamp-to-border</wrap-r>
- -->
- <!-- float, signed-integer, integer -->
- <internal-format>normalized</internal-format>
- </texture2d>
- </texture>
- <texture n="1">
- <texture2d>
- <image>detail.png</image>
- <filter>linear-mipmap-linear</filter>
- <!-- also repeat -->
- <wrap-s>clamp</wrap-s>
- <wrap-t>clamp-to-edge</wrap-t>
- <!--
- <wrap-r>clamp-to-border</wrap-r>
- -->
- <!-- float, signed-integer, integer -->
- <internal-format>normalized</internal-format>
- </texture2d>
- </texture>
- <bump-height type="double">.05</bump-height>
- <pattern-rotation type="vec4d">0 0 1 1.5708</pattern-rotation>
- </parameters>
- <technique>
- <predicate>
- <!-- This is the general way to test for shader support -->
- <or>
- <less-equal>
- <value type="float">2.0</value>
- <glversion/>
- </less-equal>
- <and>
- <extension-supported>GL_ARB_shader_objects</extension-supported>
- <extension-supported>GL_ARB_shading_language_100</extension-supported>
- <extension-supported>GL_ARB_vertex_shader</extension-supported>
- <extension-supported>GL_ARB_fragment_shader</extension-supported>
- </and>
- </or>
- </predicate>
- <pass>
- <lighting>true</lighting>
- <material>
- <ambient><use>material/ambient</use></ambient>
- <diffuse><use>material/diffuse</use></diffuse>
- <specular><use>material/specular</use></specular>
- <shininess><use>material/shininess</use></shininess>
- </material>
- <texture-unit>
- <texture2d><use>texture[0]/texture2d</use></texture2d>
- </texture-unit>
- <texture-unit>
- <texture2d><use>texture[1]/texture2d</use></texture2d>
- </texture-unit>
- <uniform>
- <name>bumpHeight</name>
- <type>float</type>
- <use>bump-height</use>
- </uniform>
- <uniform>
- <name>patternRotation</name>
- <type>float-vec4</type>
- <use>pattern-rotation</use>
- </uniform>
- <uniform>
- <name>baseTexture</name>
- <type>sampler-2d</type>
- <value>0</value>
- </uniform>
- <uniform>
- <name>detailTexture</name>
- <type>sampler-2d</type>
- <value>1</value>
- </uniform>
- <shader-program>
- <!-- These two vertex shaders are linked together -->
- <vertex-shader>
- "Shaders/util.vert"
- </vertex-shader>
- <vertex-shader>
- "Shaders/foo.vert"
- </vertex-shader>
- <fragment-shader>
- "Shaders/foo.frag"
- </fragment-shader>
- </shader-program>
- </pass>
- </technique>
- <!-- This technique is always valid -->
- <technique>
- <pass>
- <lighting>true</lighting>
- <material>
- <ambient><use>material/ambient</use></ambient>
- <diffuse><use>material/diffuse</use></diffuse>
- <specular><use>material/specular</use></specular>
- </material>
- <texture-unit>
- <texture2d><use>texture[0]/texture2d</use></texture2d>
- </texture-unit>
- </pass>
- </technique>
- </effect>
-</PropertyList>
+Effects
+-------
+
+Effects describe the graphical appearance of 3d objects and scenery in
+FlightGear. The main motivation for effects is to support OpenGL
+shaders and to provide different implementations for graphics hardware
+of varying capabilities. Effects are similar to DirectX effects files
+and Ogre3D material scripts.
+
+An effect is a property list. The property list syntax is extended
+with new "vec3d" and "vec4d" types to support common computer graphics
+values. Effects are read from files with a ".eff" extension or can be
+created on-the-fly by FlightGear at runtime. An effect consists of a
+"parameters" section followed by "technique" descriptions. The
+"parameters" section is a tree of values that describe, abstractly,
+the graphical characteristics of objects that use the effect. Techniques
+refer to these parameters and use them to set OpenGL state or to set
+parameters for shader programs. The names of properties in the
+parameter section can be whatever the effects author chooses, although
+some standard parameters are set by FlightGear itself. On the other
+hand, the properties in the techniques section are all defined by the
+FlightGear.
+
+Techniques
+----------
+
+A technique can contain a predicate that describes the OpenGL
+functionality required to support the technique. The first
+technique with a valid predicate in the list of techniques is used
+to set up the graphics state of the effect. A technique with no
+predicate is always assumed to be valid. The predicate is written in a
+little expression language that supports the following primitives:
+
+and, or, equal, less, less-equal
+glversion - returns the version number of OpenGL
+extension-supported - returns true if an OpenGL extension is supported
+property - returns the boolean value of a property
+float-property - returns the float value of a property, useful inside equal, less or less-equal nodes
+shader-language - returns the version of GLSL supported, or 0 if there is none.
+
+The proper way to test whether to enable a shader-based technique is:
+ <predicate>
+ <and>
+ <property>/sim/rendering/shader-effects</property>
+ <less-equal>
+ <value type="float">1.0</value>
+ <shader-language/>
+ </less-equal>
+ </and>
+ </predicate>
+
+There is also a property set by the user to indicate what is the level
+of quality desired. This level of quality can be checked in the predicate
+like this :
+ <predicate>
+ <and>
+ <property>/sim/rendering/shader-effects</property>
+ <less-equal>
+ <value type="float">2.0</value>
+ <float-property>/sim/rendering/quality-level</float-property>
+ </less-equal>
+ <!-- other predicate conditions -->
+ </and>
+ </predicate>
+
+The range of /sim/rendering/quality-level is [0..5]
+ * 2.0 is the threshold for relief mapping effects,
+ * 4.0 is the threshold for geometry shader usage.
+
+A technique can consist of several passes. A pass is basically an Open
+Scene Graph StateSet. Ultimately all OpenGL and OSG modes and state
+attributes will be accessable in techniques. State attributes -- that
+is, technique properties that have children and are not just boolean
+modes -- have an <active> parameter which enables or disables the
+attribute. In this way a technique can declare parameters it needs,
+but not enable the attribute at all if it is not needed; the decision
+can be based on a parameter in the parameters section of the
+effect. For example, effects that support transparent and opaque
+geometry could have as part of a technique:
+
+ <blend>
+ <active><use>blend/active</use></active>
+ <source>src-alpha</source>
+ <destination>one-minus-src-alpha</destination>
+ </blend>
+
+So if the blend/active parameter is true blending will be activated
+using the usual blending equation; otherwise blending is disabled.
+
+Values of Technique Attributes
+------------------------------
+
+Values are assigned to technique properties in several ways:
+
+ * They can appear directly in the techniques section as a
+ constant. For example:
+ <uniform>
+ <name>ColorsTex</name>
+ <type>sampler-1d</type>
+ <value type="int">2</value>
+ </uniform>
+ * The name of a property in the parameters section can be
+ referenced using a "use" clause. For example, in the technique
+ section:
+ <material>
+ <ambient><use>material/ambient</use></ambient>
+ </material>
+ Then, in the parameters section of the effect:
+ <parameters>
+ <material>
+ <ambient type="vec4d">0.2 0.2 0.2 1.0</ambient>
+ </material>
+ </parameters>
+
+ It's worth pointing out that the "material" property in a
+ technique specifies part of OpenGL's state, whereas "material"
+ in the parameters section is just a name, part of a
+ hierarchical namespace.
+
+ * A property in the parameters section doesn't need to contain
+ a constant value; it can also contain a "use" property. Here
+ the value of the use clause is the name of a node in an
+ external property tree which will be used as the source of a
+ value. If the name begins with '/', the node is in
+ FlightGear's global property tree; otherwise, it is in a local
+ property tree, usually belonging to a model [NOT IMPLEMENTED
+ YET]. For example:
+ <parameters>
+ <chrome-light><use>/rendering/scene/chrome-light</use></chrome-light>
+ </parameters>
+ The type is determined by what is expected by the technique
+ attribute that will ultimately receive the value. [There is
+ no way to get vector values out of the main property system
+ yet; this will be fixed shortly.] Values that are declared
+ this way are dynamically updated if the property node
+ changes.
+
+OpenGL Attributes
+-----------------
+
+The following attributes are currently implemented in techiques:
+alpha-test - children: active, comparison, reference
+ Valid values for comparision:
+ never, less, equal, lequal, greater, notequal, gequal,
+ always
+
+blend - children: active, source, destination, source-rgb,
+ source-alpha, destination-rgb, destination-alpha
+ Each operand can have the following values:
+ dst-alpha, dst-color, one, one-minus-dst-alpha,
+ one-minus-dst-color, one-minus-src-alpha,
+ one-minus-src-color, src-alpha, src-alpha-saturate,
+ src-color, constant-color, one-minus-constant-color,
+ constant-alpha, one-minus-constant-alpha, zero
+
+cull-face - front, back, front-back
+
+lighting - true, false
+
+material - children: active, ambient, ambient-front, ambient-back, diffuse,
+ diffuse-front, diffuse-back, specular, specular-front,
+ specular-back, emissive, emissive-front, emissive-back, shininess,
+ shininess-front, shininess-back, color-mode
+
+polygon-mode - children: front, back
+ Valid values:
+ fill, line, point
+
+program
+ vertex-shader
+ geometry-shader
+ fragment-shader
+ attribute
+ geometry-vertices-out: integer, max number of vertices emitted by geometry shader
+ geometry-input-type - points, lines, lines-adjacency, triangles, triangles-adjacency
+ geometry-output-type - points, line-strip, triangle-strip
+
+render-bin - (OSG) children: bin-number, bin-name
+
+rendering-hint - (OSG) opaque, transparent
+
+shade-model - flat, smooth
+
+texture-unit - has several child properties:
+ unit - The number of an OpenGL texture unit
+ type - This is either an OpenGL texture type or the name of a
+ builtin texture. Currently supported OpenGL types are 1d, 2d,
+ 3d which have the following common parameters:
+ image (file name)
+ filter
+ mag-filter
+ wrap-s
+ wrap-t
+ wrap-r
+ mipmap-control - controls how the mipmap levels are computed.
+ Each color channel can be computed with different functions
+ among average, sum, product, min and max. For example :
+ <function-r>average</function-r>
+ <function-a>min</function-a>
+ function-r - function for red
+ function-g - function for green
+ function-b - function for blue
+ function-a - function for alpha
+ The following built-in types are supported:
+ white - 1 pixel white texture
+ noise - a 3d noise texture
+ environment
+ mode
+ color
+uniform
+ name
+ type - float, float-vec3, float-vec4, sampler-1d, sampler-2d,
+ sampler-3d
+
+vertex-program-two-side - true, false
+
+vertex-program-point-size - true, false
+
+Inheritance
+-----------
+
+One feature not fully illustrated in the sample below is that
+effects can inherit from each other. The parent effect is listed in
+the "inherits-from" form. The child effect's property tree is
+overlaid over that of the parent. Nodes that have the same name and
+property index -- set by the "n=" attribute in the property tag --
+are recursively merged. Leaf property nodes from the child have
+precedence. This means that effects that inherit from the example
+effect below could be very short, listing just new
+parameters and adding nothing to the techniques section;
+alternatively, a technique could be altered or customized in a
+child, listing (for example) a different shader program. An example
+showing inheritance Effects/crop.eff, which inherits some if its
+values from Effects/terrain-default.eff.
+
+FlightGear directly uses effects inheritance to assign effects to 3D
+models and terrain. As described below, at runtime small effects are
+created that contain material and texture values in a "parameters"
+section. These effects inherit from another effect which references
+those parameters in its "techniques" section. The derived effect
+overrides any default values that might be in the base effect's
+parameters section.
+
+Generate
+--------
+
+Often shader effects need tangent vectors to work properly. These
+tangent vectors, usually called tangent and binormal, are computed
+on the CPU and given to the shader as vertex attributes. These
+vectors are computed on demand on the geometry using the effect if
+the 'generate' clause is present in the effect file. Exemple :
+
+ <generate>
+ <tangent type="int">6</tangent>
+ <binormal type="int">7</binormal>
+ <normal type="int">8</normal>
+ </generate>
+
+Valid subnodes of 'generate' are 'tangent', 'binormal' or 'normal'.
+The integer value of these subnode is the index of the attribute
+that will hold the value of the vec3 vector.
+
+The generate clause is located under PropertyList in the xml file.
+
+In order to be available for the vertex shader, these data should
+be bound to an attribute in the program clause, like this :
+
+ <program>
+ <vertex-shader>my_vertex_shader</vertex-shader>
+ <attribute>
+ <name>my_tangent_attribute</name>
+ <index>6</index>
+ </attribute>
+ <attribute>
+ <name>my_binormal_attribute</name>
+ <index>7</index>
+ </attribute>
+ </program>
+
+attribute names are whatever the shader use. The index is the one
+declared in the 'generate' clause. So because generate/tangent has
+value 6 and my_tangent_attribute has index 6, my_tangent_attribute
+holds the tangent value for the vertex.
+
+Default Effects in Terrain Materials and Models
+-----------------------------------------------
+
+Effects for terrain work in this way: for each material type in
+materials.xml an effect is created that inherits from a single default
+terrain effect, Effects/terrain-default.eff. The parameters section of
+the effect is filled in using the ambient, diffuse, specular,
+emissive, shininess, and transparent fields of the material. The
+parameters image, filter, wrap-s, and wrap-t are also initialized from
+the material xml. Seperate effects are created for each texture
+variant of a material.
+
+Model effects are created by walking the OpenSceneGraph scene graph
+for a model and replacing nodes (osg::Geode) that have state sets with
+node that uses an effect instead. Again, a small effect is created
+with parameters extracted from OSG objects; this effect inherits, by
+default, from Effects/model-default.eff. A larger set of parameters is
+created for model effects than for terrain because there is more
+variation possible from the OSG model loaders than from the terrain
+system. The parameters created are:
+
+ * material active, ambient, diffuse, specular, emissive,
+ shininess, color mode
+ * blend active, source, destination
+ * shade-model
+ * cull-face
+ * rendering-hint
+ * texture type, image, filter, wrap-s, wrap-t
+
+Specifying Custom Effects
+-------------------------
+
+You can specify the effects that will be used by FlightGear as the
+base effect when it creates terrain and model effects.
+
+In the terrain materials.xml, an "effect" property specifies the name
+of the model to use.
+
+In model .xml files, A richer syntax is supported. [TO BE DETERMINED]
+
+Material animations will be implemented by creating a new effect
+that inherits from one in a model, overriding the parameters that
+will be animated.
+
+Examples
+--------
+
+The Effects directory contains the effects definitions; look there for
+examples. Effects/crop.eff is a good example of a complex effect.
+
+Application
+-----------
+
+To apply an effect to a model or part of a model use:
+
+ <effect>
+ <inherits-from>Effects/light-cone</inherits-from>
+ <object-name>Cone</object-name>
+ </effect>
+
+where <inherits-from> </inherits-from> contains the path to the effect you want to apply.
+The effect does not need the file extension.
+
+NOTE:
+
+Chrome, although now implemented as an effect, still retains the old method of application:
+
+ <animation>
+ <type>shader</type>
+ <shader>chrome</shader>
+ <texture>glass_shader.png</texture>
+ <object-name>windscreen</object-name>
+ </animation>
+
+in order to maintain backward compatibility.
+