Pass.cs :  » Game » RealmForge » Axiom » Graphics » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » RealmForge 
RealmForge » Axiom » Graphics » Pass.cs
#region LGPL License
/*
Axiom Game Engine Library
Copyright (C) 2003  Axiom Project Team

The overall design, and a majority of the core engine and rendering code 
contained within this library is a derivative of the open source Object Oriented 
Graphics Engine OGRE, which can be found at http://ogre.sourceforge.net.  
Many thanks to the OGRE team for maintaining such a high quality project.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#endregion

using System;
using System.Collections;
using System.Diagnostics;
using Axiom.Configuration;
using Axiom.Core;

namespace Axiom.Graphics{
  /// <summary>
  ///   Class defining a single pass of a Technique (of a Material), ie
  ///    a single rendering call. 
  /// </summary>
  /// <remarks>
  ///    Rendering can be repeated with many passes for more complex effects.
  ///    Each pass is either a fixed-function pass (meaning it does not use
  ///    a vertex or fragment program) or a programmable pass (meaning it does
  ///    use either a vertex or a fragment program, or both). 
  ///    <p/>
  ///    Programmable passes are complex to define, because they require custom
  ///    programs and you have to set all constant inputs to the programs (like
  ///    the position of lights, any base material colors you wish to use etc), but
  ///    they do give you much total flexibility over the algorithms used to render your
  ///    pass, and you can create some effects which are impossible with a fixed-function pass.
  ///    On the other hand, you can define a fixed-function pass in very little time, and
  ///    you can use a range of fixed-function effects like environment mapping very
  ///    easily, plus your pass will be more likely to be compatible with older hardware.
  ///    There are pros and cons to both, just remember that if you use a programmable
  ///    pass to create some great effects, allow more time for definition and testing.
  /// </remarks>
  public class Pass {
    #region Fields

    /// <summary>
    ///    A reference to the technique that owns this Pass.
    /// </summary>
    protected Technique parent;
    /// <summary>
    ///    Index of this rendering pass.
    /// </summary>
    protected int index;
    /// <summary>
    ///    Pass hash, used for sorting passes.
    /// </summary>
    protected int hashCode;
    /// <summary>
    ///    Ambient color in fixed function passes.
    /// </summary>
    protected ColorEx ambient;
    /// <summary>
    ///    Diffuse color in fixed function passes.
    /// </summary>
    protected ColorEx diffuse;
    /// <summary>
    ///    Specular color in fixed function passes.
    /// </summary>
    protected ColorEx specular;
    /// <summary>
    ///    Emissive color in fixed function passes.
    /// </summary>
    protected ColorEx emissive;
    /// <summary>
    ///    Shininess of the object's surface in fixed function passes.
    /// </summary>
    protected float shininess;
    /// <summary>
    ///    Source blend factor.
    /// </summary>
    protected SceneBlendFactor sourceBlendFactor;
    /// <summary>
    ///    Destination blend factor.
    /// </summary>
    protected SceneBlendFactor destBlendFactor;
    /// <summary>
    ///    Depth buffer checking setting for this pass.
    /// </summary>
    protected bool depthCheck;
    /// <summary>
    ///    Depth write setting for this pass.
    /// </summary>
    protected bool depthWrite;
    /// <summary>
    ///    Depth comparison function for this pass.
    /// </summary>
    protected CompareFunction depthFunc;
    /// <summary>
    ///    Depth bias for this pass.
    /// </summary>
    protected int depthBias;
    /// <summary>
    ///    Color write setting for this pass.
    /// </summary>
    protected bool colorWrite;
    /// <summary>
    ///    Hardware culling mode for this pass.
    /// </summary>
    protected CullingMode cullMode;
    /// <summary>
    ///    Software culling mode for this pass.
    /// </summary>
    protected ManualCullingMode manualCullMode;
    /// <summary>
    ///    Is lighting enabled for this pass?
    /// </summary>
    protected bool lightingEnabled;
    /// <summary>
    ///    Max number of simultaneous lights that can be used for this pass.
    /// </summary>
    protected int maxLights;
    /// <summary>
    ///    Run this pass once per light? 
    /// </summary>
    protected bool runOncePerLight; 
    /// <summary>
    ///     Should it only be run for a certain light type? 
    /// </summary>
    protected bool runOnlyForOneLightType; 
    /// <summary>
    ///    Type of light for a programmable pass that supports only one particular type of light.
    /// </summary>
    protected LightType onlyLightType; 
    /// <summary>
    ///    Shading options for this pass.
    /// </summary>
    protected Shading shadeOptions;
    /// <summary>
    ///    Texture anisotropy level.
    /// </summary>
    protected int maxAniso;
    /// <summary>
    ///    Does this pass override global fog settings?
    /// </summary>
    protected bool fogOverride;
    /// <summary>
    ///    Fog mode to use for this pass (if overriding).
    /// </summary>
    protected FogMode fogMode;
    /// <summary>
    ///    Color of the fog used for this pass (if overriding).
    /// </summary>
    protected ColorEx fogColor;
    /// <summary>
    ///    Starting point of the fog for this pass (if overriding).
    /// </summary>
    protected float fogStart;
    /// <summary>
    ///    Ending point of the fog for this pass (if overriding).
    /// </summary>
    protected float fogEnd;
    /// <summary>
    ///    Density of the fog for this pass (if overriding).
    /// </summary>
    protected float fogDensity;
    /// <summary>
    ///    List of fixed function texture unit states for this pass.
    /// </summary>
    protected TextureUnitStateList textureUnitStates = new TextureUnitStateList();
    /// <summary>
    ///    Details on the vertex program to be used for this pass.
    /// </summary>
    protected GpuProgramUsage vertexProgramUsage;
    /// <summary>
    ///    Details on the fragment program to be used for this pass.
    /// </summary>
    protected GpuProgramUsage fragmentProgramUsage;
    /// <summary>
    ///    Is this pass queued for deletion?
    /// </summary>
    protected bool queuedForDeletion;

    /// <summary>
    ///    List of passes with dirty hashes.
    /// </summary>
    protected static PassList dirtyHashList = new PassList();
    /// <summary>
    ///    List of passes queued for deletion.
    /// </summary>
    protected static PassList graveyardList = new PassList();

    #endregion
    
    #region Constructors
    
    /// <summary>
    ///    Default constructor.
    /// </summary>
    /// <param name="parent">Technique that owns this Pass.</param>
    /// <param name="index">Index of this pass.</param>
    public Pass(Technique parent, int index) {
      this.parent = parent;
      this.index = index;

      // color defaults
      ambient = ColorEx.White;
      diffuse = ColorEx.White;
      specular = ColorEx.Black;
      emissive = ColorEx.Black;

      // by default, don't override the scene's fog settings
      fogOverride = false;
      fogMode = FogMode.None;
      fogColor = ColorEx.White;
      fogStart = 0;
      fogEnd = 1;
      fogDensity = 0.001f;

      // default blending (overwrite)
      sourceBlendFactor = SceneBlendFactor.One;
      destBlendFactor = SceneBlendFactor.Zero;



      // depth buffer settings
      depthCheck = true;
      depthWrite = true;
      colorWrite = true;
      depthFunc = CompareFunction.LessEqual;

      // cull settings
      cullMode = CullingMode.Clockwise;
      manualCullMode = ManualCullingMode.Back;

      // light settings
      lightingEnabled = true;
      runOnlyForOneLightType = true;
      onlyLightType = LightType.Point;
      shadeOptions = Shading.Gouraud;

      // Default max lights to the global max
      maxLights = Config.MaxSimultaneousLights;

      DirtyHash();
    }
    
    #endregion
    
    #region Methods

    /// <summary>
    ///    Adds the passed in TextureUnitState, to the existing Pass.
    /// </summary>
    /// <param name="state">TextureUnitState to add to this pass.</param>
    public void AddTextureUnitState(TextureUnitState state) {
      textureUnitStates.Add(state);

      // needs recompilation
      parent.NotifyNeedsRecompile();
      DirtyHash();
    }

    /// <summary>
    ///    Method for cloning a Pass object.
    /// </summary>
    /// <param name="parent">Parent technique that will own this cloned Pass.</param>
    /// <returns></returns>
    public Pass Clone(Technique parent, int index) {
      Pass newPass = new Pass(parent, index);

      CopyTo(newPass);

      // dirty the hash on the new pass
      newPass.DirtyHash();

      return newPass;
    }

    /// <summary>
    ///    Copy the details of this pass to the target pass.
    /// </summary>
    /// <param name="target">Destination pass to copy this pass's attributes to.</param>
    public void CopyTo(Pass target) {
      // surface
      target.ambient = ambient.Clone();
      target.diffuse = diffuse.Clone();
      target.specular = specular.Clone();
      target.emissive = emissive.Clone();
      target.shininess = shininess;

      // fog
      target.fogOverride = fogOverride;
      target.fogMode = fogMode;
      target.fogColor = fogColor.Clone();
      target.fogStart = fogStart;
      target.fogEnd = fogEnd;
      target.fogDensity = fogDensity;

      // default blending
      target.sourceBlendFactor = sourceBlendFactor;
      target.destBlendFactor = destBlendFactor;

      target.depthCheck = depthCheck;
      target.depthWrite = depthWrite;
      target.colorWrite = colorWrite;
      target.depthFunc = depthFunc;
      target.depthBias = depthBias;
      target.cullMode = cullMode;
      target.manualCullMode = manualCullMode;
      target.lightingEnabled = lightingEnabled;
      target.maxLights = maxLights;
      target.runOncePerLight = runOncePerLight;
      target.runOnlyForOneLightType = runOnlyForOneLightType;
      target.onlyLightType = onlyLightType;
      target.shadeOptions = shadeOptions;

      // vertex program
      if(vertexProgramUsage != null) {
                target.vertexProgramUsage = vertexProgramUsage.Clone();
            }
      else {
                target.vertexProgramUsage = null;
            }

      // fragment program
      if(fragmentProgramUsage != null) {
                target.fragmentProgramUsage = fragmentProgramUsage.Clone();
            }
      else {
                target.fragmentProgramUsage = null;
            }

      // TODO: Shadow caster/receiver program usage

      // texture units
      target.RemoveAllTextureUnitStates();

      for(int i = 0; i < textureUnitStates.Count; i++) {
        TextureUnitState newState = new TextureUnitState(target);
        TextureUnitState src = (TextureUnitState)textureUnitStates[i];
        src.CopyTo(newState);

        target.textureUnitStates.Add(newState);
      }

      target.DirtyHash();
    }

    /// <summary>
    ///    Overloaded method.
    /// </summary>
    /// <param name="textureName">The basic name of the texture (i.e. brickwall.jpg)</param>
    /// <returns></returns>
    public TextureUnitState CreateTextureUnitState() {
      TextureUnitState state = new TextureUnitState(this);
      textureUnitStates.Add(state);
      // needs recompilation
      parent.NotifyNeedsRecompile();
      DirtyHash();
      return state;
    }  

    /// <summary>
    ///    Overloaded method.
    /// </summary>
    /// <param name="textureName">The basic name of the texture (i.e. brickwall.jpg)</param>
    /// <returns></returns>
    public TextureUnitState CreateTextureUnitState(string textureName) {
      return CreateTextureUnitState(textureName, 0);
    }

    /// <summary>
    ///    Inserts a new TextureUnitState object into the Pass.
    /// </summary>
    /// <remarks>
    ///    This unit is is added on top of all previous texture units.
    ///    <p/>
    ///    Applies to both fixed-function and programmable passes.
    /// </remarks>
    /// <param name="textureName">The basic name of the texture (i.e. brickwall.jpg)</param>
    /// <param name="texCoordSet">The index of the texture coordinate set to use.</param>
    /// <returns></returns>
    public TextureUnitState CreateTextureUnitState(string textureName, int texCoordSet) {
      TextureUnitState state = new TextureUnitState(this);
      state.SetTextureName(textureName);
      state.TextureCoordSet = texCoordSet;
      textureUnitStates.Add(state);
      // needs recompilation
      parent.NotifyNeedsRecompile();
      DirtyHash();
      return state;
    }

    /// <summary>
    ///    Gets a reference to the TextureUnitState for this pass at the specified indx.
    /// </summary>
    /// <param name="index">Index of the state to retreive.</param>
    /// <returns>TextureUnitState at the specified index.</returns>
    public TextureUnitState GetTextureUnitState(int index) {
      Debug.Assert(index < textureUnitStates.Count, "index < textureUnitStates.Count");

      return (TextureUnitState)textureUnitStates[index];
    }

    /// <summary>
    ///    Internal method for loading this pass.
    /// </summary>
    internal void Load() {
      // it is assumed this is only being called when the Material is being loaded

      // load each texture unit state
      for(int i = 0; i < textureUnitStates.Count; i++) {
        ((TextureUnitState)textureUnitStates[i]).Load();
      }

      // load programs
      if(this.HasVertexProgram) {
        // load vertex program
        vertexProgramUsage.Load();
      }

      if(this.HasFragmentProgram) {
        // load vertex program
        fragmentProgramUsage.Load();
      }

      // recalculate hash code
      DirtyHash();
    }

    /// <summary>
    ///    Tells the pass that it needs recompilation.
    /// </summary>
    internal void NotifyNeedsRecompile() {
      parent.NotifyNeedsRecompile();
    }

    /// <summary>
    ///    Internal method for recalculating the hash code used for sorting passes.
    /// </summary>
    internal void RecalculateHash() {
      /* Hash format is 32-bit, divided as follows (high to low bits)
         bits   purpose
        4     Pass index (i.e. max 16 passes!)
         14     Hashed texture name from unit 0
         14     Hashed texture name from unit 1

         Note that at the moment we don't sort on the 3rd texture unit plus
         on the assumption that these are less frequently used; sorting on 
         the first 2 gives us the most benefit for now.
       */
      hashCode = (index << 28);
      int count = NumTextureUnitStages;

      if(count > 0 && !((TextureUnitState)textureUnitStates[0]).IsBlank) {
        hashCode += (((TextureUnitState)textureUnitStates[0]).TextureName.GetHashCode() % (1 << 14)) << 14;
      }
      if(count > 1 && !((TextureUnitState)textureUnitStates[1]).IsBlank) {
        hashCode += (((TextureUnitState)textureUnitStates[1]).TextureName.GetHashCode() % (1 << 14));
      }
    }

    /// <summary>
    ///    Removes all texture unit settings from this pass.
    /// </summary>
    public void RemoveAllTextureUnitStates() {
      textureUnitStates.Clear();

      if(!queuedForDeletion) {
        // needs recompilation
        parent.NotifyNeedsRecompile();
      }

      DirtyHash();
    }

    /// <summary>
    ///    Removes the specified TextureUnitState from this pass.
    /// </summary>
    /// <param name="state">A reference to the TextureUnitState to remove from this pass.</param>
    public void RemoveTextureUnitState(TextureUnitState state) {
      textureUnitStates.Remove(state);

      if(!queuedForDeletion) {
        // needs recompilation
        parent.NotifyNeedsRecompile();
      }

      DirtyHash();
    }

    /// <summary>
    ///    Removes the specified TextureUnitState from this pass.
    /// </summary>
    /// <param name="state">Index of the TextureUnitState to remove from this pass.</param>
    public void RemoveTextureUnitState(int index) {
      TextureUnitState state = (TextureUnitState) textureUnitStates[index];

      if (state != null)
        RemoveTextureUnitState(state);
    }

    /// <summary>
    ///    Sets the fogging mode applied to this pass.
    /// </summary>
    /// <remarks>
    ///    Fogging is an effect that is applied as polys are rendered. Sometimes, you want
    ///    fog to be applied to an entire scene. Other times, you want it to be applied to a few
    ///    polygons only. This pass-level specification of fog parameters lets you easily manage
    ///    both.
    ///    <p/>
    ///    The SceneManager class also has a SetFog method which applies scene-level fog. This method
    ///    lets you change the fog behavior for this pass compared to the standard scene-level fog.
    /// </remarks>
    /// <param name="overrideScene">
    ///    If true, you authorise this pass to override the scene's fog params with it's own settings.
    ///    If you specify false, so other parameters are necessary, and this is the default behaviour for passs.
    /// </param>
    /// <param name="mode">
    ///    Only applicable if <paramref cref="overrideScene"/> is true. You can disable fog which is turned on for the
    ///    rest of the scene by specifying FogMode.None. Otherwise, set a pass-specific fog mode as
    ///    defined in the enum FogMode.
    /// </param>
    /// <param name="color">
    ///    The color of the fog. Either set this to the same as your viewport background color,
    ///    or to blend in with a skydome or skybox.
    /// </param>
    /// <param name="density">
    ///    The density of the fog in FogMode.Exp or FogMode.Exp2 mode, as a value between 0 and 1. 
    ///    The default is 0.001.
    /// </param>
    /// <param name="start">
    ///    Distance in world units at which linear fog starts to encroach. 
    ///    Only applicable if mode is FogMode.Linear.
    /// </param>
    /// <param name="end">
    ///    Distance in world units at which linear fog becomes completely opaque.
    ///    Only applicable if mode is FogMode.Linear.
    /// </param>
    public void SetFog(bool overrideScene, FogMode mode, ColorEx color, float density, float start, float end) {
      fogOverride = overrideScene;

      // set individual params if overriding scene level fog
      if(overrideScene) {
        fogMode = mode;
        fogColor = color;
        fogDensity = density;
        fogStart = start;
        fogEnd = end;
      }
    }

    /// <summary>
    ///    Overloaded method.
    /// </summary>
    /// <param name="overrideScene">
    ///    If true, you authorise this pass to override the scene's fog params with it's own settings.
    ///    If you specify false, so other parameters are necessary, and this is the default behaviour for passs.
    /// </param>
    public void SetFog(bool overrideScene) {
      SetFog(overrideScene, FogMode.None, ColorEx.White, 0.001f, 0.0f, 1.0f);
    }

    /// <summary>
    ///    Overloaded method.
    /// </summary>
    /// <param name="overrideScene">
    ///    If true, you authorise this pass to override the scene's fog params with it's own settings.
    ///    If you specify false, so other parameters are necessary, and this is the default behaviour for passs.
    /// </param>
    /// <param name="mode">
    ///    Only applicable if <paramref cref="overrideScene"/> is true. You can disable fog which is turned on for the
    ///    rest of the scene by specifying FogMode.None. Otherwise, set a pass-specific fog mode as
    ///    defined in the enum FogMode.
    /// </param>
    public void SetFog(bool overrideScene, FogMode mode) {
      SetFog(overrideScene, mode, ColorEx.White, 0.001f, 0.0f, 1.0f);
    }

    /// <summary>
    ///    Overloaded method.
    /// </summary>
    /// <param name="overrideScene">
    ///    If true, you authorise this pass to override the scene's fog params with it's own settings.
    ///    If you specify false, so other parameters are necessary, and this is the default behaviour for passs.
    /// </param>
    /// <param name="mode">
    ///    Only applicable if <paramref cref="overrideScene"/> is true. You can disable fog which is turned on for the
    ///    rest of the scene by specifying FogMode.None. Otherwise, set a pass-specific fog mode as
    ///    defined in the enum FogMode.
    /// </param>
    /// <param name="color">
    ///    The color of the fog. Either set this to the same as your viewport background color,
    ///    or to blend in with a skydome or skybox.
    /// </param>
    public void SetFog(bool overrideScene, FogMode mode, ColorEx color) {
      SetFog(overrideScene, mode, color, 0.001f, 0.0f, 1.0f);
    }

    /// <summary>
    ///    Overloaded method.
    /// </summary>
    /// <param name="overrideScene">
    ///    If true, you authorise this pass to override the scene's fog params with it's own settings.
    ///    If you specify false, so other parameters are necessary, and this is the default behaviour for passs.
    /// </param>
    /// <param name="mode">
    ///    Only applicable if <paramref cref="overrideScene"/> is true. You can disable fog which is turned on for the
    ///    rest of the scene by specifying FogMode.None. Otherwise, set a pass-specific fog mode as
    ///    defined in the enum FogMode.
    /// </param>
    /// <param name="color">
    ///    The color of the fog. Either set this to the same as your viewport background color,
    ///    or to blend in with a skydome or skybox.
    /// </param>
    /// <param name="density">
    ///    The density of the fog in FogMode.Exp or FogMode.Exp2 mode, as a value between 0 and 1. 
    ///    The default is 0.001.
    /// </param>
    public void SetFog(bool overrideScene, FogMode mode, ColorEx color, float density) {
      SetFog(overrideScene, mode, color, density, 0.0f, 1.0f);
    }

    /// <summary>
    ///    Sets whether or not this pass should be run once per light which 
    ///    can affect the object being rendered.
    /// </summary>
    /// <remarks>
    ///    The default behavior for a pass (when this option is 'false'), is 
    ///    for a pass to be rendered only once, with all the lights which could 
    ///    affect this object set at the same time (up to the maximum lights 
    ///    allowed in the render system, which is typically 8). 
    ///    <p/>
    ///    Setting this option to 'true' changes this behavior, such that 
    ///    instead of trying to issue render this pass once per object, it 
    ///    is run once <b>per light</b> which can affect this object. In 
    ///    this case, only light index 0 is ever used, and is a different light 
    ///    every time the pass is issued, up to the total number of lights 
    ///    which is affecting this object. This has 2 advantages: 
    ///    <ul><li>There is no limit on the number of lights which can be 
    ///    supported</li> 
    ///    <li>It's easier to write vertex / fragment programs for this because 
    ///    a single program can be used for any number of lights</li> 
    ///    </ul> 
    ///    However, this technique is a lot more expensive, and typically you 
    ///    will want an additional ambient pass, because if no lights are 
    ///    affecting the object it will not be rendered at all, which will look 
    ///    odd even if ambient light is zero (imagine if there are lit objects 
    ///    behind it - the objects silhouette would not show up). Therefore, 
    ///    use this option with care, and you would be well advised to provide 
    ///    a less expensive fallback technique for use in the distance. 
    ///    <p/>
    ///    Note: The number of times this pass runs is still limited by the maximum 
    ///    number of lights allowed as set in MaxLights, so 
    ///    you will never get more passes than this. 
    /// </remarks>
    /// <param name="enabled">Whether this feature is enabled.</param>
    /// <param name="onlyForOneLightType">
    ///    If true, the pass will only be run for a single type of light, other light types will be ignored. 
    /// </param>
    /// <param name="lightType">The single light type which will be considered for this pass.</param>
    public void SetRunOncePerLight(bool enabled, bool onlyForOneLightType, LightType lightType) {
      runOncePerLight = enabled;
      runOnlyForOneLightType = onlyForOneLightType;
      onlyLightType = lightType;
    }

    public void SetRunOncePerLight(bool enabled, bool onlyForOneLightType) {
      SetRunOncePerLight(enabled, onlyForOneLightType, LightType.Point);
    }

    public void SetRunOncePerLight(bool enabled) {
      SetRunOncePerLight(enabled, true);
    }

    /// <summary>
    ///    Sets the kind of blending this pass has with the existing contents of the scene.
    /// </summary>
    /// <remarks>
    ///    Whereas the texture blending operations seen in the TextureUnitState class are concerned with
    ///    blending between texture layers, this blending is about combining the output of the Pass
    ///    as a whole with the existing contents of the rendering target. This blending therefore allows
    ///    object transparency and other special effects. If all passes in a technique have a scene
    ///    blend, then the whole technique is considered to be transparent.
    ///    <p/>
    ///    This method allows you to select one of a number of predefined blending types. If you require more
    ///    control than this, use the alternative version of this method which allows you to specify source and
    ///    destination blend factors.
    ///    <p/>
    ///    This method is applicable for both the fixed-function and programmable pipelines.
    /// </remarks>
    /// <param name="type">One of the predefined SceneBlendType blending types.</param>
    public void SetSceneBlending(SceneBlendType type) {
      // convert canned blending types into blending factors
      switch(type) {
        case SceneBlendType.Add:
          SetSceneBlending(SceneBlendFactor.One, SceneBlendFactor.One);
          break;
        case SceneBlendType.TransparentAlpha:
          SetSceneBlending(SceneBlendFactor.SourceAlpha, SceneBlendFactor.OneMinusSourceAlpha);
          break;
        case SceneBlendType.TransparentColor:
          SetSceneBlending(SceneBlendFactor.SourceColor, SceneBlendFactor.OneMinusSourceColor);
          break;
      }
    }

    /// <summary>
    ///    Allows very fine control of blending this Pass with the existing contents of the scene.
    /// </summary>
    /// <remarks>
    ///    Wheras the texture blending operations seen in the TextureUnitState class are concerned with
    ///    blending between texture layers, this blending is about combining the output of the material
    ///    as a whole with the existing contents of the rendering target. This blending therefore allows
    ///    object transparency and other special effects.
    ///    <p/>
    ///    This version of the method allows complete control over the blending operation, by specifying the
    ///    source and destination blending factors. The result of the blending operation is:
    ///    <span align="center">
    ///    final = (texture * sourceFactor) + (pixel * destFactor)
    ///    </span>
    ///    <p/>
    ///    Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor
    ///    enumerated type.
    ///    <p/>
    ///    This method is applicable for both the fixed-function and programmable pipelines.
    /// </remarks>
    /// <param name="src">The source factor in the above calculation, i.e. multiplied by the texture color components.</param>
    /// <param name="dest">The destination factor in the above calculation, i.e. multiplied by the pixel color components.</param>
    public void SetSceneBlending(SceneBlendFactor src, SceneBlendFactor dest) {
      // copy settings
      sourceBlendFactor = src;
      destBlendFactor = dest;
    }

    /// <summary>
    ///    
    /// </summary>
    /// <param name="name"></param>
    public void SetFragmentProgram(string name) {
      SetFragmentProgram(name, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="resetParams"></param>
    public void SetFragmentProgram(string name, bool resetParams) {
      // turn off fragment programs when the name is set to null
      if(name.Length == 0) {
        fragmentProgramUsage = null;
      }
      else {
        // create a new usage object
        if(!this.HasFragmentProgram) {
          fragmentProgramUsage = new GpuProgramUsage(GpuProgramType.Fragment);
        }

        fragmentProgramUsage.ProgramName = name;
      }

      // needs recompilation
      parent.NotifyNeedsRecompile();
    }

    /// <summary>
    ///    
    /// </summary>
    /// <param name="name"></param>
    public void SetVertexProgram(string name) {
      SetVertexProgram(name, true);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="resetParams"></param>
    public void SetVertexProgram(string name, bool resetParams) {
      // turn off vertex programs when the name is set to null
      if(name.Length == 0) {
        vertexProgramUsage = null;
      }
      else {
        // create a new usage object
        if(!this.HasVertexProgram) {
          vertexProgramUsage = new GpuProgramUsage(GpuProgramType.Vertex);
        }

        vertexProgramUsage.ProgramName = name;
      }

      // needs recompilation
      parent.NotifyNeedsRecompile();
    }

    /// <summary>
    ///    Splits this Pass to one which can be handled in the number of
    ///    texture units specified.
    /// </summary>
    /// <param name="numUnits">
    ///    The target number of texture units.
    /// </param>
    /// <returns>
    ///    A new Pass which contains the remaining units, and a scene_blend
    ///    setting appropriate to approximate the multitexture. This Pass will be 
    ///    attached to the parent Technique of this Pass.
    /// </returns>
    public Pass Split(int numUnits) {
      // can't split programmable passes
      if(fragmentProgramUsage != null) {
        throw new Exception("Passes with fragment programs cannot be automatically split.  Define a fallback technique instead");
      }

      if(textureUnitStates.Count > numUnits) {
        int start = textureUnitStates.Count - numUnits;

        Pass newPass = parent.CreatePass();

        // get a reference ot the texture unit state at the split position
        TextureUnitState state = (TextureUnitState)textureUnitStates[start];

        // set the new pass to fallback using scene blending
        newPass.SetSceneBlending(state.ColorBlendFallbackSource, state.ColorBlendFallbackDest);

        // add the rest of the texture units to the new pass
        for(int i = start; i < textureUnitStates.Count; i++) {
          state = (TextureUnitState)textureUnitStates[i];
          newPass.AddTextureUnitState(state);
        }

        // remove the extra texture units from this pass
        textureUnitStates.RemoveRange(start, textureUnitStates.Count - start);

        return newPass;
      }

      return null;
    }

    /// <summary>
    ///    Internal method for unloaded this pass.
    /// </summary>
    internal void Unload() {
      // load each texture unit state
      for(int i = 0; i < textureUnitStates.Count; i++) {
        ((TextureUnitState)textureUnitStates[i]).Unload();
      }
    }

    /// <summary>
    ///    Update any automatic light parameters on this pass.
    /// </summary>
    /// <param name="renderable">Current object being rendered.</param>
    /// <param name="camera">Current being being used for rendering.</param>
    internal void UpdateAutoParamsLightsOnly(AutoParamDataSource source) {
      // auto update vertex program parameters
      if(this.HasVertexProgram) {
        vertexProgramUsage.Params.UpdateAutoParamsLightsOnly(source);
      }

      // auto update fragment program parameters
      if(this.HasFragmentProgram) {
        fragmentProgramUsage.Params.UpdateAutoParamsLightsOnly(source);
      }
    }

    /// <summary>
    ///    Update any automatic parameters (except lights) on this pass.
    /// </summary>
    /// <param name="renderable">Current object being rendered.</param>
    /// <param name="camera">Current being being used for rendering.</param>
    internal void UpdateAutoParamsNoLights(AutoParamDataSource source) {
      // auto update vertex program parameters
      if(this.HasVertexProgram) {
        vertexProgramUsage.Params.UpdateAutoParamsNoLights(source);
      }

      // auto update fragment program parameters
      if(this.HasFragmentProgram) {
        fragmentProgramUsage.Params.UpdateAutoParamsNoLights(source);
      }
    }

    /// <summary>
    ///    Mark the hash for this pass as dirty.  
    /// </summary>
    public void DirtyHash() {
      dirtyHashList.Add(this);
    }

    /// <summary>
    ///    Queue this pass for deletion when appropriate.
    /// </summary>
    public void QueueForDeletion() {
      queuedForDeletion = true;

      RemoveAllTextureUnitStates();

      // remove from the dirty list
      dirtyHashList.Remove(this);

      graveyardList.Add(this);
    }

    /// <summary>
    ///    Process all dirty and pending deletion passes.
    /// </summary>
    public static void ProcessPendingUpdates() {
      // clear the graveyard
      graveyardList.Clear();

      // recalc the hashcode for each pass
      for(int i = 0; i < dirtyHashList.Count; i++) {
        Pass pass = (Pass)dirtyHashList[i];
        pass.RecalculateHash();
      }

      // clear out the dirty list
      dirtyHashList.Clear();
    }
    
    #endregion

    #region Object overrides

    /// <summary>
    ///    Gets the 'hash' of this pass, ie a precomputed number to use for sorting.
    /// </summary>
    /// <remarks>
    ///    This hash is used to sort passes, and for this reason the pass is hashed
    ///    using firstly its index (so that all passes are rendered in order), then
    ///    by the textures which it's TextureUnitState instances are using.
    /// </remarks>
    /// <returns></returns>
    public override int GetHashCode() {
      return hashCode;
    }

    #endregion Object overrides
    
    #region Properties
        
    /// <summary>
    ///    Sets the ambient color reflectance properties of this pass.
    /// </summary>
    /// <remarks>
    ///    The base color of a pass is determined by how much red, green and blue light is reflects
    ///    (provided texture layer #0 has a blend mode other than LayerBlendOperation.Replace). 
    ///    This property determines how much ambient light (directionless global light) is reflected. 
    ///    The default is full white, meaning objects are completely globally illuminated. Reduce this 
    ///    if you want to see diffuse or specular light effects, or change the blend of colors to make 
    ///    the object have a base color other than white.
    ///    <p/>
    ///    This setting has no effect if dynamic lighting is disabled (see <see cref="Pass.LightingEnabled"/>),
    ///    or if this is a programmable pass.
    /// </remarks>
    public ColorEx Ambient {
      get {
        return ambient;
      }
      set {
        ambient = value;
      }
    }

    /// <summary>
    ///    Sets whether or not color buffer writing is enabled for this Pass.
    /// </summary>
    /// <remarks>
    ///    For some effects, you might wish to turn off the color write operation
    ///    when rendering geometry; this means that only the depth buffer will be
    ///    updated (provided you have depth buffer writing enabled, which you 
    ///    probably will do, although you may wish to only update the stencil
    ///    buffer for example - stencil buffer state is managed at the RenderSystem
    ///    level only, not the Material since you are likely to want to manage it 
    ///    at a higher level).
    /// </remarks>
    public bool ColorWrite {
      get {
        return colorWrite;
      }
      set {
        colorWrite = value;
      }
    }

    /// <summary>
    ///    Sets the culling mode for this pass based on the 'vertex winding'.
    /// </summary>
    /// <remarks>
    ///    A typical way for the 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
    ///    counterclockwise. The default is Clockwise i.e. that only triangles whose vertices are passed/indexed in 
    ///    counter-clockwise order are rendered - this is a common approach and is used in 3D studio models for example. 
    ///    You can alter this culling mode if you wish but it is not advised unless you know what you are doing.
    ///    <p/>
    ///    You may wish to use the CullingMode.None option for mesh data that you cull yourself where the vertex
    ///    winding is uncertain.
    /// </remarks>
    public CullingMode CullMode {
      get {
        return cullMode;
      }
      set {
        cullMode = value;
      }
    }
        
    /// <summary>
    ///    Sets the depth bias to be used for this Pass.
    /// </summary>
    /// <remarks>
    ///    When polygons are coplanar, you can get problems with 'depth fighting' (or 'z fighting') where
    ///    the pixels from the two polys compete for the same screen pixel. This is particularly
    ///    a problem for decals (polys attached to another surface to represent details such as
    ///    bulletholes etc.).
    ///    <p/>
    ///    A way to combat this problem is to use a depth bias to adjust the depth buffer value
    ///    used for the decal such that it is slightly higher than the true value, ensuring that
    ///    the decal appears on top.
    /// </remarks>
    /// <value>
    ///    The bias value, should be between 0 and 16.
    /// </value>
    public int DepthBias {
      get {
        return depthBias;
      }
      set {
        Debug.Assert(value <= 16, "Depth bias must be between 0 and 16.");
        depthBias = value;
      }
    }

    /// <summary>
    ///    Gets/Sets whether or not this pass renders with depth-buffer checking on or not.
    /// </summary>
    /// <remarks>
    ///    If depth-buffer checking is on, whenever a pixel is about to be written to the frame buffer
    ///    the depth buffer is checked to see if the pixel is in front of all other pixels written at that
    ///    point. If not, the pixel is not written.
    ///    <p/>
    ///    If depth checking is off, pixels are written no matter what has been rendered before.
    ///    Also see <see cref="DepthFunction"/> for more advanced depth check configuration.
    /// </remarks>
    public bool DepthCheck {
      get {
        return depthCheck;
      }
      set {
        depthCheck = value;
      }
    }

    /// <summary>
    ///    Gets/Sets the function used to compare depth values when depth checking is on.
    /// </summary>
    /// <remarks>
    ///    If depth checking is enabled (see <see cref="DepthCheck"/>) a comparison occurs between the depth
    ///    value of the pixel to be written and the current contents of the buffer. This comparison is
    ///    normally CompareFunction.LessEqual, i.e. the pixel is written if it is closer (or at the same distance)
    ///    than the current contents. If you wish, you can change this comparison using this method.
    /// </remarks>
    public CompareFunction DepthFunction {
      get {
        return depthFunc;
      }
      set {
        depthFunc = value;
      }
    }
        
    /// <summary>
    ///    Gets/Sets whether or not this pass renders with depth-buffer writing on or not.
    /// </summary>
    /// <remarks>
    ///    If depth-buffer writing is on, whenever a pixel is written to the frame buffer
    ///    the depth buffer is updated with the depth value of that new pixel, thus affecting future
    ///    rendering operations if future pixels are behind this one.
    ///    <p/>
    ///    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.
    /// </remarks>
    public bool DepthWrite {
      get {
        return depthWrite;
      }
      set {
        depthWrite = value;
      }
    }

    /// <summary>
    ///    Retrieves the destination blending factor for the material (as set using SetSceneBlending).
    /// </summary>
    public SceneBlendFactor DestBlendFactor {
      get {
        return destBlendFactor;
      }
    }

    /// <summary>
    ///    Sets the diffuse color reflectance properties of this pass.
    /// </summary>
    /// <remarks>
    ///    The base color of a pass is determined by how much red, green and blue light is reflects
    ///    (provided texture layer #0 has a blend mode other than LayerBlendOperation.Replace). This property determines how
    ///    much diffuse light (light from instances of the Light class in the scene) is reflected. The default
    ///    is full white, meaning objects reflect the maximum white light they can from Light objects.
    ///    <p/>
    ///    This setting has no effect if dynamic lighting is disabled (see <see cref="Pass.LightingEnabled"/>),
    ///    or if this is a programmable pass.
    /// </remarks>
    public ColorEx Diffuse {
      get {
        return diffuse;
      }
      set {
        diffuse = value;
      }
    }
        
    /// <summary>
    /// 
    /// </summary>
    public ColorEx Emissive {
      get {
        return emissive;
      }
      set {
        emissive = value;
      }
    }
        
    /// <summary>
    ///    Returns the fog color for the scene.
    /// </summary>
    /// <remarks>
    ///    Only valid if FogOverride is true.
    /// </remarks>
    public ColorEx FogColor {
      get {
        return fogColor;
      }
    }
        
    /// <summary>
    ///    Returns the fog density for this pass.
    /// </summary>
    /// <remarks>
    ///    Only valid if FogOverride is true.
    /// </remarks>
    public float FogDensity {
      get {
        return fogDensity;
      }
    }

    /// <summary>
    ///    Returns the fog end distance for this pass.
    /// </summary>
    /// <remarks>
    ///    Only valid if FogOverride is true.
    /// </remarks>
    public float FogEnd {
      get {
        return fogEnd;
      }
    }
        
    /// <summary>
    ///    Returns the fog mode for this pass.
    /// </summary>
    /// <remarks>
    ///    Only valid if FogOverride is true.
    /// </remarks>
    public FogMode FogMode {
      get {
        return fogMode;
      }
    }

    /// <summary>
    ///    Returns true if this pass is to override the scene fog settings.
    /// </summary>
    public bool FogOverride {
      get {
        return fogOverride;
      }
    }

    /// <summary>
    ///    Returns the fog start distance for this pass.
    /// </summary>
    /// <remarks>
    ///    Only valid if FogOverride is true.
    /// </remarks>
    public float FogStart {
      get {
        return fogStart;
      }
    }

    /// <summary>
    ///    Gets the vertex program used by this pass.
    /// </summary>
    /// <remarks>
    ///    Only available after Load() has been called.
    /// </remarks>
    public GpuProgram FragmentProgram {
      get {
        Debug.Assert(this.HasFragmentProgram, "This pass does not contain a fragment program!");
        return fragmentProgramUsage.Program;
      }
    }

    /// <summary>
    ///    Gets/Sets the name of the fragment program to use.
    /// </summary>
    /// <remarks>
    ///    Only applicable to programmable passes, and this particular call is
    ///    designed for low-level programs; use the named parameter methods
    ///    for setting high-level programs.
    ///    <p/>
    ///    This must have been created using GpuProgramManager by the time that 
    ///    this Pass is loaded.
    /// </remarks>
    public string FragmentProgramName {
      get {
        // return blank if there is no fragment program in this pass
        if(this.HasFragmentProgram) {
          return fragmentProgramUsage.ProgramName;
        }
        else {
          return String.Empty;
        }
      }
    }

    /// <summary>
    ///    Gets/Sets the fragment program parameters used by this pass.
    /// </summary>
    /// <remarks>
    ///    Only applicable to programmable passes, and this particular call is
    ///    designed for low-level programs; use the named parameter methods
    ///    for setting high-level program parameters.
    /// </remarks>
    public GpuProgramParameters FragmentProgramParameters {
      get {
        Debug.Assert(this.HasFragmentProgram, "This pass does not contain a fragment program!");
        return fragmentProgramUsage.Params;
      }
      set {
        Debug.Assert(this.HasFragmentProgram, "This pass does not contain a fragment program!");
        fragmentProgramUsage.Params = value;
      }
    }

    /// <summary>
    ///    Returns true if this Pass uses the programmable fragment pipeline.
    /// </summary>
    public bool HasFragmentProgram {
      get {
        return fragmentProgramUsage != null;
      }
    }

    /// <summary>
    ///    Returns true if this Pass uses the programmable vertex pipeline.
    /// </summary>
    public bool HasVertexProgram {
      get {
        return vertexProgramUsage != null;
      }
    }

    /// <summary>
    ///    Gets the index of this Pass in the parent Technique.
    /// </summary>
    public int Index {
      get {
        return index;
      }
    }

    /// <summary>
    ///    Gets a flag indicating whether this pass is ambient only.
    /// </summary>
    public bool IsAmbientOnly {
      get {
        // treat as ambient if lighting is off, or color write is off, 
        // or all non-ambient (& emissive) colors are black
        // NB a vertex program could override this, but passes using vertex
        // programs are expected to indicate they are ambient only by 
        // setting the state so it matches one of the conditions above, even 
        // though this state is not used in rendering.
        return (!lightingEnabled || !colorWrite ||
          (diffuse == ColorEx.Black && specular == ColorEx.Black));
      }
    }

    /// <summary>
    ///    Returns true if this pass is loaded.
    /// </summary>
    public bool IsLoaded {
      get {
        return parent.IsLoaded;
      }
    }

    /// <summary>
    ///    Returns true if this pass is programmable ie includes either a vertex or fragment program.
    /// </summary>
    public bool IsProgrammable {
      get {
        return vertexProgramUsage != null || fragmentProgramUsage != null;
      }
    }

    /// <summary>
    ///    Returns true if this pass has some element of transparency.
    /// </summary>
    public bool IsTransparent {
      get {
        // Transparent if any of the destination color is taken into account
        return (destBlendFactor != SceneBlendFactor.Zero);
      }
    }

    /// <summary>
    ///    Sets whether or not dynamic lighting is enabled.
    /// </summary>
    /// <remarks>
    ///    If true, dynamic lighting is performed on geometry with normals supplied, geometry without
    ///    normals will not be displayed.
    ///    If false, no lighting is applied and all geometry will be full brightness.
    /// </remarks>
    public bool LightingEnabled {
      get {
        return lightingEnabled;
      }
      set {
        lightingEnabled = value;
      }
    }

    /// <summary>
    ///    Sets the manual culling mode, performed by CPU rather than hardware.
    /// </summary>
    /// <remarks>
    ///    In some situations you want to use manual culling of triangles rather than sending the
    ///    triangles to the hardware and letting it cull them. 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.
    /// </remarks>
    /// <value>
    ///    The default for this setting is ManualCullingMode.Back.
    /// </value>
    public ManualCullingMode ManualCullMode {
      get {
        return manualCullMode;
      }
      set {
        manualCullMode = value;
      }
    }

    /// <summary>
    ///    Sets the maximum number of lights to be used by this pass. 
    /// </summary>
    /// <remarks>
    ///    During rendering, if lighting is enabled (or if the pass uses an automatic
    ///    program parameter based on a light) the engine will request the nearest lights 
    ///    to the object being rendered in order to work out which ones to use. This
    ///    parameter sets the limit on the number of lights which should apply to objects 
    ///    rendered with this pass. 
    /// </remarks>
    public int MaxLights {
      get {
        return maxLights;
      }
      set {
        maxLights = value;
      }
    }

    /// <summary>
    ///    Gets the number of fixed function texture unit states for this Pass.
    /// </summary>
    public int NumTextureUnitStages {
      get {
        return textureUnitStates.Count;
      }
    }

    /// <summary>
    ///     Gets the single light type this pass runs for if RunOncePerLight and 
    ///     RunOnlyForOneLightType are both true. 
    /// </summary>
    public LightType OnlyLightType {
      get {
        return onlyLightType;
      }
    }

    /// <summary>
    ///    Gets a reference to the Technique that owns this pass.
    /// </summary>
    public Technique Parent {
      get {
        return parent;
      }
    }

    /// <summary>
    ///    Does this pass run once for every light in range?
    /// </summary>
    public bool RunOncePerLight {
      get {
        return runOncePerLight;
      }
    }

    /// <summary>
    ///    Does this pass run only for a single light type (if RunOncePerLight is true). 
    /// </summary>
    public bool RunOnlyOncePerLightType {
      get {
        return runOnlyForOneLightType;
      }
    }
        
    /// <summary>
    ///    Sets the type of light shading required.
    /// </summary>
    /// <value>
    ///    The default shading method is Gouraud shading.
    /// </value>
    public Shading ShadingMode {
      get {
        return shadeOptions;
      }
      set {
        shadeOptions = value;
      }
    }
        
    /// <summary>
    ///    Sets the shininess of the pass, affecting the size of specular highlights.
    /// </summary>
    /// <remarks>
    ///    This setting has no effect if dynamic lighting is disabled (see Pass::setLightingEnabled),
    ///    or if this is a programmable pass.
    /// </remarks>
    public float Shininess {
      get {
        return shininess;
      }
      set {
        shininess = value;
      }
    }

    /// <summary>
    ///    Retrieves the source blending factor for the material (as set using SetSceneBlending).
    /// </summary>
    public SceneBlendFactor SourceBlendFactor {
      get {
        return sourceBlendFactor;
      }
    }

    /// <summary>
    ///    Sets the specular color reflectance properties of this pass.
    /// </summary>
    /// <remarks>
    ///    The base color of a pass is determined by how much red, green and blue light is reflects
    ///    (provided texture layer #0 has a blend mode other than LBO_REPLACE). This property determines how
    ///    much specular light (highlights from instances of the Light class in the scene) is reflected.
    ///    The default is to reflect no specular light.
    ///    <p/>
    ///    The size of the specular highlights is determined by the separate Shininess property.
    ///    <p/>
    ///    This setting has no effect if dynamic lighting is disabled (see <see cref="Pass.LightingEnabled"/>),
    ///    or if this is a programmable pass.
    /// </remarks>
    public ColorEx Specular {
      get {
        return specular;
      }
      set {
        specular = value;
      }
    }

    /// <summary>
    ///    Sets the anisotropy level to be used for all textures.
    /// </summary>
    /// <remarks>
    ///    This property has been moved to the TextureUnitState class, which is accessible via the 
    ///    Technique and Pass. For simplicity, this method allows you to set these properties for 
    ///    every current TeextureUnitState, If you need more precision, retrieve the Technique, 
    ///    Pass and TextureUnitState instances and set the property there.
    /// </remarks>
    public int TextureAnisotropy {
      set {
        for(int i = 0; i < textureUnitStates.Count; i++) {
          ((TextureUnitState)textureUnitStates[i]).TextureAnisotropy = value;
        }
      }
    }

    /// <summary>
    ///    Set texture filtering for every texture unit.
    /// </summary>
    /// <remarks>
    ///    This property actually exists on the TextureUnitState class
    ///    For simplicity, this method allows you to set these properties for 
    ///    every current TeextureUnitState, If you need more precision, retrieve the  
    ///    TextureUnitState instance and set the property there.
    /// </remarks>
    public TextureFiltering TextureFiltering {
      set {
        for(int i = 0; i < textureUnitStates.Count; i++) {
          ((TextureUnitState)textureUnitStates[i]).SetTextureFiltering(value);
        }
      }
    }

    /// <summary>
    ///    Gets the vertex program used by this pass.
    /// </summary>
    /// <remarks>
    ///    Only available after Load() has been called.
    /// </remarks>
    public GpuProgram VertexProgram {
      get {
        Debug.Assert(this.HasVertexProgram, "This pass does not contain a vertex program!");
        return vertexProgramUsage.Program;
      }
    }

    /// <summary>
    ///    Gets/Sets the name of the vertex program to use.
    /// </summary>
    /// <remarks>
    ///    Only applicable to programmable passes, and this particular call is
    ///    designed for low-level programs; use the named parameter methods
    ///    for setting high-level programs.
    ///    <p/>
    ///    This must have been created using GpuProgramManager by the time that 
    ///    this Pass is loaded.
    /// </remarks>
    public string VertexProgramName {
      get {
        if(this.HasVertexProgram) {
          return vertexProgramUsage.ProgramName;
        }
        else {
          return String.Empty;
        }
      }
    }

    /// <summary>
    ///    Gets/Sets the vertex program parameters used by this pass.
    /// </summary>
    /// <remarks>
    ///    Only applicable to programmable passes, and this particular call is
    ///    designed for low-level programs; use the named parameter methods
    ///    for setting high-level program parameters.
    /// </remarks>
    public GpuProgramParameters VertexProgramParameters {
      get {
        Debug.Assert(this.HasVertexProgram, "This pass does not contain a vertex program!");
        return vertexProgramUsage.Params;
      }
      set {
        Debug.Assert(this.HasVertexProgram, "This pass does not contain a vertex program!");
        vertexProgramUsage.Params = value;
      }
    }

    /// <summary>
    ///    Gets a list of dirty passes.
    /// </summary>
    internal static PassList DirtyList {
      get {
        return dirtyHashList;
      }
    }
        
    /// <summary>
    ///    Gets a list of passes queued for deletion.
    /// </summary>
    internal static PassList GraveyardList {
      get {
        return graveyardList;
      }
    }

    #endregion
  }

  /// <summary>
  ///    Struct recording a pass which can be used for a specific illumination stage.
  /// </summary>
  /// <remarks>
  ///    This structure is used to record categorized passes which fit into a 
  ///    number of distinct illumination phases - ambient, diffuse / specular 
  ///    (per-light) and decal (post-lighting texturing).
  ///    An original pass may fit into one of these categories already, or it
  ///    may require splitting into its component parts in order to be categorized 
  ///    properly.
  /// </remarks>
  public struct IlluminationPass {
    /// <summary>
    ///    The stage at which this pass is relevant.
    /// </summary>
    public IlluminationStage Stage;
    /// <summary>
    ///    The pass to use in this stage.
    /// </summary>
    public Pass Pass;
    /// <summary>
    ///    Whether this pass is one which should be deleted itself.
    /// </summary>
    public bool DestroyOnShutdown;
    /// <summary>
    ///    The original pass which spawned this one.
    /// </summary>
    public Pass OriginalPass;
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.