Class representing the state of a single texture unit during a Pass of a Technique, of a Material.
Texture units are pipelines for retrieving texture data for rendering onto your objects in the world. Using them is common to both the fixed-function and the programmable (vertex and fragment program) pipeline, but some of the settings will only have an effect in the fixed-function pipeline (for example, setting a texture rotation will have no effect if you use the programmable pipeline, because this is overridden by the fragment program). The effect of each setting as regards the 2 pipelines is commented in each setting.

When I use the term 'fixed-function pipeline' I mean traditional rendering where you do not use vertex or fragment programs (shaders). Programmable pipeline means that for this pass you are using vertex or fragment programs.

Ejemplo n.º 1
0
		public virtual SubRenderState CreateInstance( ScriptCompiler compiler, PropertyAbstractNode prop,
		                                              TextureUnitState texState, SGScriptTranslator translator )
		{
			return null;
		}
Ejemplo n.º 2
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;
		}
Ejemplo n.º 3
0
			public TextureUnitTranslator()
				: base()
			{
				_textureunit = null;
			}
Ejemplo n.º 4
0
		/// <summary>
		/// 
		/// </summary>
		protected void Initialize()
		{
			// Create geometry
			int nvertices = this.slices*4; // n+1 planes
			int elemsize = 3*3;
			int dsize = elemsize*nvertices;
			int x;

			var indexData = new IndexData();
			var vertexData = new VertexData();
			var vertices = new float[dsize];

			var coords = new float[4,2]
			             {
			             	{
			             		0.0f, 0.0f
			             	}, {
			             	   	0.0f, 1.0f
			             	   }, {
			             	      	1.0f, 0.0f
			             	      }, {
			             	         	1.0f, 1.0f
			             	         }
			             };

			for ( x = 0; x < this.slices; x++ )
			{
				for ( int y = 0; y < 4; y++ )
				{
					float xcoord = coords[ y, 0 ] - 0.5f;
					float ycoord = coords[ y, 1 ] - 0.5f;
					float zcoord = -( (float)x/(float)( this.slices - 1 ) - 0.5f );
					// 1.0f .. a/(a+1)
					// coordinate
					vertices[ x*4*elemsize + y*elemsize + 0 ] = xcoord*( this.size/2.0f );
					vertices[ x*4*elemsize + y*elemsize + 1 ] = ycoord*( this.size/2.0f );
					vertices[ x*4*elemsize + y*elemsize + 2 ] = zcoord*( this.size/2.0f );
					// normal
					vertices[ x*4*elemsize + y*elemsize + 3 ] = 0.0f;
					vertices[ x*4*elemsize + y*elemsize + 4 ] = 0.0f;
					vertices[ x*4*elemsize + y*elemsize + 5 ] = 1.0f;
					// tex
					vertices[ x*4*elemsize + y*elemsize + 6 ] = xcoord*Utility.Sqrt( 3.0f );
					vertices[ x*4*elemsize + y*elemsize + 7 ] = ycoord*Utility.Sqrt( 3.0f );
					vertices[ x*4*elemsize + y*elemsize + 8 ] = zcoord*Utility.Sqrt( 3.0f );
				}
			}

			var faces = new short[this.slices*6];
			for ( x = 0; x < this.slices; x++ )
			{
				faces[ x*6 + 0 ] = (short)( x*4 + 0 );
				faces[ x*6 + 1 ] = (short)( x*4 + 1 );
				faces[ x*6 + 2 ] = (short)( x*4 + 2 );
				faces[ x*6 + 3 ] = (short)( x*4 + 1 );
				faces[ x*6 + 4 ] = (short)( x*4 + 2 );
				faces[ x*6 + 5 ] = (short)( x*4 + 3 );
			}

			//setup buffers
			vertexData.vertexStart = 0;
			vertexData.vertexCount = nvertices;

			VertexDeclaration decl = vertexData.vertexDeclaration;
			VertexBufferBinding bind = vertexData.vertexBufferBinding;
			int offset = 0;
			offset += decl.AddElement( 0, 0, VertexElementType.Float3, VertexElementSemantic.Position ).Size;
			offset += decl.AddElement( 0, offset, VertexElementType.Float3, VertexElementSemantic.Normal ).Size;
			offset += decl.AddElement( 0, offset, VertexElementType.Float3, VertexElementSemantic.TexCoords ).Size;

			HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl, nvertices,
			                                                                                       BufferUsage.StaticWriteOnly );

			bind.SetBinding( 0, vertexBuffer );

			HardwareIndexBuffer indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer( IndexType.Size16, this.slices*6,
			                                                                                    BufferUsage.StaticWriteOnly );

			indexData.indexBuffer = indexBuffer;
			indexData.indexCount = this.slices*6;
			indexData.indexStart = 0;

			indexBuffer.WriteData( 0, indexBuffer.Size, faces, true );
			vertexBuffer.WriteData( 0, vertexBuffer.Size, vertices );
			vertices = null;
			faces = null;

			// Now make the render operation
			renderOperation.operationType = OperationType.TriangleList;
			renderOperation.indexData = indexData;
			renderOperation.vertexData = vertexData;
			renderOperation.useIndices = true;

			// Create a brand new private material
			if ( !ResourceGroupManager.Instance.GetResourceGroups().Contains( "VolumeRendable" ) )
			{
				ResourceGroupManager.Instance.CreateResourceGroup( "VolumeRendable" );
			}

			var material = (Material)MaterialManager.Instance.Create( this.texture, "VolumeRendable" );
			// Remove pre-created technique from defaults
			material.RemoveAllTechniques();

			// Create a techinique and a pass and a texture unit
			Technique technique = material.CreateTechnique();
			Pass pass = technique.CreatePass();
			TextureUnitState textureUnit = pass.CreateTextureUnitState();

			// Set pass parameters
			pass.SetSceneBlending( SceneBlendType.TransparentAlpha );
			pass.DepthWrite = false;
			pass.CullingMode = CullingMode.None;
			pass.LightingEnabled = false;
			textureUnit.SetTextureAddressingMode( TextureAddressing.Clamp );
			textureUnit.SetTextureName( this.texture, TextureType.ThreeD );
			textureUnit.SetTextureFiltering( TextureFiltering.Trilinear );

			this.unit = textureUnit;
			base.material = material;
		}
Ejemplo n.º 5
0
		/// <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 )
		{
			target._name = _name;
			target._hashCode = _hashCode;

			// surface
			target._ambient = _ambient.Clone();
			target._diffuse = _diffuse.Clone();
			target._specular = _specular.Clone();
			target._emissive = _emissive.Clone();
			target._shininess = _shininess;
			target._tracking = _tracking;

			// 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._destinationBlendFactor = _destinationBlendFactor;

			target._depthCheck = _depthCheck;
			target._depthWrite = _depthWrite;
			target._alphaRejectFunction = _alphaRejectFunction;
			target._alphaRejectValue = _alphaRejectValue;
			target._colorWriteEnabled = _colorWriteEnabled;
			target._depthFunction = _depthFunction;
			target._depthBiasConstant = _depthBiasConstant;
			target._depthBiasSlopeScale = _depthBiasSlopeScale;
			target._cullingMode = _cullingMode;
			target._manualCullingMode = _manualCullingMode;
			target._lightingEnabled = _lightingEnabled;
			target._maxSimultaneousLights = _maxSimultaneousLights;
			target._iteratePerLight = _iteratePerLight;
			target._runOnlyForOneLightType = _runOnlyForOneLightType;
			target._onlyLightType = _onlyLightType;
			target._shadingMode = _shadingMode;
			target._polygonMode = _polygonMode;
			target.IterationCount = IterationCount;

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

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

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

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

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

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


			// Clear texture units but doesn't notify need recompilation in the case
			// we are cloning, The parent material will take care of this.
			target.textureUnitStates.Clear();

			// Copy texture units

			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();
		}
Ejemplo n.º 6
0
		/// <summary>
		///     Creates a basic time-based texture coordinate modifier designed for creating rotating textures.
		/// </summary>
		/// <remarks>
		///     This simple method allows you to easily create constant-speed rotating textures. If you want more
		///     control, look up the ControllerManager.CreateTextureWaveTransformer for more complex wave-based
		///     scrollers / stretchers / rotaters.
		/// </remarks>
		/// <param name="layer">The texture unit to animate.</param>
		/// <param name="speed">Speed of the rotation, in counter-clockwise revolutions per second.</param>
		/// <returns>A newly created controller object that will be updated during the main render loop.</returns>
		public Controller<Real> CreateTextureRotator( TextureUnitState layer, Real speed )
		{
			IControllerValue<Real> val = new TexCoordModifierControllerValue( layer, false, false, false, false, true );
			IControllerFunction<Real> func = new MultipyControllerFunction( -speed, true );

			return CreateController( val, func );
		}
Ejemplo n.º 7
0
		/// <summary>
		///     Creates a basic time-based texture v coordinate modifier designed for creating scrolling textures.
		/// </summary>
		/// <remarks>
		///     This simple method allows you to easily create constant-speed scrolling textures. If you want more
		///     control, look up the <see cref="CreateTextureWaveTransformer"/> for more complex wave-based
		///     scrollers / stretchers / rotaters.
		/// </remarks>
		/// <param name="layer">The texture unit to animate.</param>
		/// <param name="speed">speed, in wraps per second.</param>
		/// <returns>A newly created controller object that will be updated during the main render loop.</returns>
		public Controller<Real> CreateTextureVScroller( TextureUnitState layer, Real speed )
		{
			IControllerValue<Real> val = null;
			IControllerFunction<Real> func = null;
			Controller<Real> controller = null;

			// if both u and v speeds are the same, we can use a single controller for it
			if ( speed != 0 )
			{
				// create the value and function
				val = new TexCoordModifierControllerValue( layer, false, true );
				func = new MultipyControllerFunction( -speed, true );

				// create the controller (uses FrameTime for source by default)
				controller = CreateController( val, func );
			}

			return controller;
		}
Ejemplo n.º 8
0
		/// <summary>
		///		Used to clone a texture layer.  Mainly used during a call to Clone on a Material or Pass.
		/// </summary>
		/// <returns></returns>
		public TextureUnitState Clone( Pass parent )
		{
			var newState = new TextureUnitState( parent );

			CopyTo( newState );

			newState.parent.DirtyHash();

			return newState;
		}
Ejemplo n.º 9
0
 /// <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)
 {
     Debug.Assert(state != null, "state is null in Pass.AddTextureUnitState()");
     if (state != null) {
         // only attach TUS to pass if TUS does not belong to another pass
         if ((state.Parent == null) || (state.Parent == this)) {
             textureUnitStates.Add(state);
             // Notify state
             state.Parent = this;
             // if texture unit state name is empty then give it a default name based on its index
             if (state.Name == null || state.Name == "") {
                 // its the last entry in the container so its index is size - 1
                 int idx = textureUnitStates.Count - 1;
                 state.Name = idx.ToString();
                 // since the name was never set and a default one has been made, clear the alias name
                 // so that when the texture unit name is set by the user, the alias name will be set to
                 // that name
                 state.TextureNameAlias = null;
             }
             // needs recompilation
             parent.NotifyNeedsRecompile();
             DirtyHash();
         }
         else
             throw new AxiomException("TextureUnitState already attached to another pass" +
                 "  In Pass.AddTextureUnitState");
         contentTypeLookupBuilt = false;
     }
 }
Ejemplo n.º 10
0
		private bool NeedsTextureMatrix( TextureUnitState textureUnitState )
		{
			for ( int i = 0; i < textureUnitState.NumEffects; i++ )
			{
				TextureEffect effi = textureUnitState.GetEffect( i );

				switch ( effi.type )
				{
					case TextureEffectType.EnvironmentMap:
					case TextureEffectType.ProjectiveTexture:
					case TextureEffectType.Rotate:
					case TextureEffectType.Transform:
					case TextureEffectType.UScroll:
					case TextureEffectType.UVScroll:
					case TextureEffectType.VScroll:
						return true;
				}
			}
			//TODO
			var matTexture = new Matrix4(); //textureUnitState.getTextureTransform();

			//Resolve texture matrix parameter
			if ( matTexture != Matrix4.Identity )
			{
				return true;
			}

			return false;
		}
Ejemplo n.º 11
0
		/// <summary>
		///		Used to clone a texture layer.  Mainly used during a call to Clone on a Material.
		/// </summary>
		/// <returns></returns>
		public void CopyTo( TextureUnitState target )
		{
			var props = target.GetType().GetFields( BindingFlags.NonPublic | BindingFlags.Instance );

			// save parent from target, since it will be overwritten by the following loop
			var tmpParent = target.parent;

			for ( var i = 0; i < props.Length; i++ )
			{
				var prop = props[ i ];

				var srcVal = prop.GetValue( this );
				prop.SetValue( target, srcVal );
			}

			// restore correct parent
			target.parent = tmpParent;

			target.frames = new string[MaxAnimationFrames];

			// copy over animation frame texture names
			for ( var i = 0; i < MaxAnimationFrames; i++ )
			{
				target.frames[ i ] = this.frames[ i ];
			}

			// must clone these references
			target.colorBlendMode = this.colorBlendMode.Clone();
			target.alphaBlendMode = this.alphaBlendMode.Clone();

			target.effectList = new TextureEffectList();

			// copy effects
			foreach ( var effect in this.effectList )
			{
				target.effectList.Add( effect.Clone() );
			}

			// dirty the hash of the parent pass
			target.parent.DirtyHash();
		}
Ejemplo n.º 12
0
		private TexCoordCalcMethod GetCalcMethod( TextureUnitState textureUnitState )
		{
			TexCoordCalcMethod texCoordCalcMethod = TexCoordCalcMethod.None;
			var effectMap = new List<TextureEffect>();
			for ( int i = 0; i < textureUnitState.NumEffects; i++ )
			{
				effectMap.Add( textureUnitState.GetEffect( i ) );
			}

			foreach ( var effi in effectMap )
			{
				switch ( effi.type )
				{
					case TextureEffectType.EnvironmentMap:
						//TODO
						//if (effi.subtype == Curved)
						//{
						//    texCoordCalcMethod = TexCoordCalcMethod.EnvironmentMap;
						//}
						//else if (effi.subtype == Planar)
						//{
						//    texCoordCalcMethod = TexCoordCalcMethod.EnvironmentMapPlanar;
						//}
						//else if (effi.subtype == Reflection)
						//{
						//    texCoordCalcMethod = TexCoordCalcMethod.EnvironmentMapReflection;
						//}
						//else if (effi.subtype == Normal)
						//{
						//    texCoordCalcMethod = TexCoordCalcMethod.EnvironmentMapNormal;
						//}

						break;
					case TextureEffectType.ProjectiveTexture:
						texCoordCalcMethod = TexCoordCalcMethod.ProjectiveTexture;
						break;
					case TextureEffectType.Rotate:
					case TextureEffectType.Transform:
					case TextureEffectType.UScroll:
					case TextureEffectType.UVScroll:
					case TextureEffectType.VScroll:
						break;
				}
			}

			return texCoordCalcMethod;
		}
Ejemplo n.º 13
0
		private void SetTextureUnit( int index, TextureUnitState textureUnitState )
		{
			if ( index >= this.textureUnitParamsList.Count )
			{
				throw new AxiomException( "FFPTexturing unit index out of bounds !!!" );
			}
			if ( textureUnitState.BindingType == TextureBindingType.Vertex )
			{
				throw new AxiomException( "FFP Texture unit does not support vertex texture fetch !!!" );
			}

			TextureUnitParams curParams = this.textureUnitParamsList[ index ];

			curParams.TextureSamplerIndex = index;
			curParams.TextureUnitState = textureUnitState;

			switch ( curParams.TextureUnitState.TextureType )
			{
				case TextureType.CubeMap:
					curParams.TextureSamplerType = GpuProgramParameters.GpuConstantType.SamplerCube;
					curParams.VSInTextureCoordinateType = GpuProgramParameters.GpuConstantType.Float3;
					break;
				case TextureType.OneD:
					curParams.TextureSamplerType = GpuProgramParameters.GpuConstantType.Sampler1D;
					curParams.VSInTextureCoordinateType = GpuProgramParameters.GpuConstantType.Float1;
					break;
				case TextureType.ThreeD:
					curParams.TextureSamplerType = GpuProgramParameters.GpuConstantType.Sampler3D;
					curParams.VSInTextureCoordinateType = GpuProgramParameters.GpuConstantType.Float3;
					break;
				case TextureType.TwoD:
					curParams.TextureSamplerType = GpuProgramParameters.GpuConstantType.Sampler2D;
					curParams.VSInTextureCoordinateType = GpuProgramParameters.GpuConstantType.Float2;
					break;
			}

			curParams.VSOutTextureCoordinateType = curParams.VSInTextureCoordinateType;
			curParams.TexCoordCalcMethod = GetCalcMethod( curParams.TextureUnitState );

			if ( curParams.TexCoordCalcMethod == TexCoordCalcMethod.ProjectiveTexture )
			{
				curParams.VSOutTextureCoordinateType = GpuProgramParameters.GpuConstantType.Float3;
			}
		}
Ejemplo n.º 14
0
		protected virtual bool IsProcessingNeeded( TextureUnitState texUnitState )
		{
			return texUnitState.BindingType == TextureBindingType.Fragment;
		}
        private void CreateProceduralTextureMods(int p, TextureUnitState t)
        {
            // Procedural mods
            // Custom - don't use mod if generating environment
            // Because I do env a different way it look horrible
            if(pass[p].texGen != ShaderTextureGen.Environment)
            {
                if(pass[p].tcModRotate != 0.0f)
                    t.SetRotateAnimation(pass[p].tcModRotate);

                if((pass[p].tcModScroll[0] != 0.0f) || (pass[p].tcModScroll[1] != 0.0f))
                {
                    if(pass[p].tcModTurbOn)
                    {
                        // Turbulent scroll
                        if(pass[p].tcModScroll[0] != 0.0f)
                        {
                            t.SetTransformAnimation(TextureTransform.TranslateU, WaveformType.Sine,
                                                    pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]);
                        }
                        if(pass[p].tcModScroll[1] != 0.0f)
                        {
                            t.SetTransformAnimation(TextureTransform.TranslateV, WaveformType.Sine,
                                                    pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]);
                        }
                    }
                    else
                    {
                        // Constant scroll
                        t.SetScrollAnimation(pass[p].tcModScroll[0], pass[p].tcModScroll[1]);
                    }
                }

                if(pass[p].tcModStretchWave != ShaderWaveType.None)
                {
                    WaveformType wft = WaveformType.Sine;
                    switch(pass[p].tcModStretchWave)
                    {
                        case ShaderWaveType.Sin:
                            wft = WaveformType.Sine;
                            break;
                        case ShaderWaveType.Triangle:
                            wft = WaveformType.Triangle;
                            break;
                        case ShaderWaveType.Square:
                            wft = WaveformType.Square;
                            break;
                        case ShaderWaveType.SawTooth:
                            wft = WaveformType.Sawtooth;
                            break;
                        case ShaderWaveType.InverseSawtooth:
                            wft = WaveformType.InverseSawtooth;
                            break;
                    }

                    // Create wave-based stretcher
                    t.SetTransformAnimation(TextureTransform.ScaleU, wft, pass[p].tcModStretchParams[3],
                                            pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]);
                    t.SetTransformAnimation(TextureTransform.ScaleV, wft, pass[p].tcModStretchParams[3],
                                            pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]);
                }
            }
        }
Ejemplo n.º 16
0
        /// <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)
        {
            target.name = name;
            target.hashCode = hashCode;

            // surface
            target.ambient = ambient.Clone();
            target.diffuse = diffuse.Clone();
            target.specular = specular.Clone();
            target.emissive = emissive.Clone();
            target.shininess = shininess;
            target.tracking = tracking;

            // 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.alphaRejectFunction = alphaRejectFunction;
            target.alphaRejectValue = alphaRejectValue;
            target.colorWrite = colorWrite;
            target.depthFunc = depthFunc;
            target.depthBiasConstant = depthBiasConstant;
            target.depthBiasSlopeScale = depthBiasSlopeScale;
            target.cullMode = cullMode;
            target.manualCullMode = manualCullMode;
            target.lightingEnabled = lightingEnabled;
            target.maxLights = maxLights;
            target.startLight = startLight;
            target.runOncePerLight = runOncePerLight;
            target.lightsPerIteration = lightsPerIteration;
            target.runOnlyForOneLightType = runOnlyForOneLightType;
            target.onlyLightType = onlyLightType;
            target.shadeOptions = shadeOptions;
            target.sceneDetail = sceneDetail;
            target.passIterationCount = passIterationCount;
            target.pointSize = pointSize;
            target.pointMinSize = pointMinSize;
            target.pointMaxSize = pointMaxSize;
            target.pointSpritesEnabled = pointSpritesEnabled;
            target.pointAttenuationEnabled = pointAttenuationEnabled;
            target.pointAttenuationConstant = pointAttenuationConstant;
            target.pointAttenuationLinear = pointAttenuationLinear;
            target.pointAttenuationQuadratic = pointAttenuationQuadratic;
            target.contentTypeLookupBuilt = contentTypeLookupBuilt;

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

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

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

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

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

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

            // 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();
        }
Ejemplo n.º 17
0
		/// <summary>
		///     Creates a texture layer animator controller.
		/// </summary>
		/// <remarks>
		///     This helper method creates the Controller, IControllerValue and IControllerFunction classes required
		///     to animate a texture.
		/// </remarks>
		/// <param name="texUnit">The texture unit to animate.</param>
		/// <param name="sequenceTime">Length of the animation (in seconds).</param>
		/// <returns>A newly created controller object that will be updated during the main render loop.</returns>
		public Controller<Real> CreateTextureAnimator( TextureUnitState texUnit, Real sequenceTime )
		{
			IControllerValue<Real> val = new TextureFrameControllerValue( texUnit );
			IControllerFunction<Real> func = new AnimationControllerFunction( sequenceTime );

			return CreateController( val, func );
		}
Ejemplo n.º 18
0
 /// <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);
     AddTextureUnitState(state);
     contentTypeLookupBuilt = false;
     return state;
 }
Ejemplo n.º 19
0
		/// <summary>
		///     Creates a basic time-based texture u coordinate modifier designed for creating scrolling textures.
		/// </summary>
		/// <remarks>
		///     This simple method allows you to easily create constant-speed scrolling textures. If you want more
		///     control, look up the <see cref="CreateTextureWaveTransformer"/> for more complex wave-based
		///     scrollers / stretchers / rotaters.
		/// </remarks>
		/// <param name="layer">The texture unit to animate.</param>
		/// <param name="speed">speed, in wraps per second.</param>
		/// <returns>A newly created controller object that will be updated during the main render loop.</returns>
		public Controller<Real> CreateTextureUScroller( TextureUnitState layer, Real speed )
		{
			IControllerValue<Real> val = null;
			IControllerFunction<Real> func = null;
			Controller<Real> controller = null;

			// Don't create a controller if the speed is zero
			if ( speed != 0 )
			{
				// create the value and function
				val = new TexCoordModifierControllerValue( layer, true );
				func = new MultipyControllerFunction( -speed, true );

				// create the controller (uses FrameTime for source by default)
				controller = CreateController( val, func );
			}

			return controller;
		}
Ejemplo n.º 20
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;
     AddTextureUnitState(state);
     contentTypeLookupBuilt = false;
     return state;
 }
Ejemplo n.º 21
0
		/// <summary>
		///	    Creates a very flexible time-based texture transformation which can alter the scale, position or
		///	    rotation of a texture based on a wave function.	
		/// </summary>
		/// <param name="layer">The texture unit to effect.</param>
		/// <param name="type">The type of transform, either translate (scroll), scale (stretch) or rotate (spin).</param>
		/// <param name="waveType">The shape of the wave, see WaveformType enum for details.</param>
		/// <param name="baseVal">The base value of the output.</param>
		/// <param name="frequency">The speed of the wave in cycles per second.</param>
		/// <param name="phase">The offset of the start of the wave, e.g. 0.5 to start half-way through the wave.</param>
		/// <param name="amplitude">Scales the output so that instead of lying within 0..1 it lies within 0..(1 * amplitude) for exaggerated effects</param>
		/// <returns>A newly created controller object that will be updated during the main render loop.</returns>
		public Controller<Real> CreateTextureWaveTransformer( TextureUnitState layer, TextureTransform type,
		                                                      WaveformType waveType, Real baseVal, Real frequency, Real phase,
		                                                      Real amplitude )
		{
			IControllerValue<Real> val = null;
			IControllerFunction<Real> function = null;

			// determine which type of controller value this layer needs
			switch ( type )
			{
				case TextureTransform.TranslateU:
					val = new TexCoordModifierControllerValue( layer, true, false );
					break;

				case TextureTransform.TranslateV:
					val = new TexCoordModifierControllerValue( layer, false, true );
					break;

				case TextureTransform.ScaleU:
					val = new TexCoordModifierControllerValue( layer, false, false, true, false, false );
					break;

				case TextureTransform.ScaleV:
					val = new TexCoordModifierControllerValue( layer, false, false, false, true, false );
					break;

				case TextureTransform.Rotate:
					val = new TexCoordModifierControllerValue( layer, false, false, false, false, true );
					break;
			} // switch

			// create a new waveform controller function
			function = new WaveformControllerFunction( waveType, baseVal, frequency, phase, amplitude, true );

			// finally, create the controller using frame time as the source value
			return CreateController( this.frameTimeController, val, function );
		}
Ejemplo n.º 22
0
 /// <summary>
 ///    Retrieve the index of the Texture Unit State in the pass.
 /// </summary>
 public int GetTextureUnitStateIndex(TextureUnitState state)
 {
     Debug.Assert(state != null, "state is 0 in Pass.AddTextureUnitState()");
     // only find index for state attached to this pass
     if (state.Parent == this) {
         // iterate through TUS container and find matching pointer to state
         for (int i=0; i<textureUnitStates.Count; i++) {
             TextureUnitState t = (TextureUnitState)textureUnitStates[i];
             if (t == state)
                 return i;
         }
     }
     else
         throw new AxiomException("TextureUnitState is not attached to this pass" +
             "  In Pass.GetTextureUnitStateIndex");
     return 0;
 }
Ejemplo n.º 23
0
		/// <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 );
			if ( state.Name == null )
			{
				// it's the last entry in the container so it's index is count - 1
				state.Name = ( textureUnitStates.Count - 1 ).ToString();
				// Since the anme was never set and a default one has been made, 
				// clear the alias name so that when the texture unit name is set 
				// by the user, the alias name will be set to that name.
				state.TextureNameAlias = null;
			}
			// needs recompilation
			_parent.NotifyNeedsRecompile();
			DirtyHash();
		}
Ejemplo n.º 24
0
        /// <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();
            contentTypeLookupBuilt = false;
        }
Ejemplo n.º 25
0
		/// <summary>
		///    Overloaded method.
		/// </summary>
		/// <returns></returns>
		public TextureUnitState CreateTextureUnitState()
		{
			TextureUnitState state = new TextureUnitState( this );
			textureUnitStates.Add( state );
			// needs recompilation
			_parent.NotifyNeedsRecompile();
			DirtyHash();
			return state;
		}
        /// <summary>
        ///		Utility function for setting all the properties of a texture unit at once.
        ///		This method is also worth using over the individual texture unit settings because it
        ///		only sets those settings which are different from the current settings for this
        ///		unit, thus minimising render state changes.
        /// </summary>
        /// <param name="textureUnit">Index of the texture unit to configure</param>
        /// <param name="layer">Reference to a TextureLayer object which defines all the settings.</param>
        public virtual void SetTextureUnit(int unit, TextureUnitState unitState, bool fixedFunction)
        {
            // This method is only ever called to set a texture unit to valid details
            // The method _disableTextureUnit is called to turn a unit off

            // Vertex texture binding?
            if (caps.CheckCap(Capabilities.VertexTextureFetch) &&
                !caps.CheckCap(Capabilities.VertexTextureFetch)) {
                if (unitState.BindingType == GpuProgramType.Vertex) {
                    // Bind vertex texture
                    SetVertexTexture(unit, unitState);
                    // bind nothing to fragment unit (hardware isn't shared but fragment
                    // unit can't be using the same index
                    SetTexture(unit, true, string.Empty);
                }
                else {
                    // vice versa
                    SetVertexTexture(unit, unitState);
                    SetTexture(unit, true, unitState.TextureName);
                }
            }
            else {
                // Shared vertex / fragment textures or no vertex texture support
                // Bind texture (may be blank)
                SetTexture(unit, true, unitState.TextureName);
            }

            // Set texture coordinate set
            // SetTextureCoordSet(unit, unitState.TextureCoordSet);
            if (!fixedFunction)
                // From Direct3D9 error log:
                // Texture coordinate index in the stage must be equal to the stage index when programmable vertex pipeline is used
                SetTextureCoordSet(unit, unit);

            // Texture layer filtering
            SetTextureUnitFiltering(
                unit,
                unitState.GetTextureFiltering(FilterType.Min),
                unitState.GetTextureFiltering(FilterType.Mag),
                unitState.GetTextureFiltering(FilterType.Mip));

            // Texture layer anistropy
            SetTextureLayerAnisotropy(unit, unitState.TextureAnisotropy);

            // Set mipmap biasing
            SetTextureMipmapBias(unit, unitState.MipmapBias);

            // Texture addressing mode
            UVWAddressingMode uvw = unitState.GetTextureAddressingMode();
            SetTextureAddressingMode(unit, uvw);
            // Set texture border colour only if required
            if (uvw.u == TextureAddressing.Border ||
                uvw.v == TextureAddressing.Border ||
                uvw.w == TextureAddressing.Border)
                SetTextureBorderColor(unit, unitState.TextureBorderColor);

            // This stuff only gets done for the fixed function pipeline.  It is not needed
            // if we are using a pixel shader.
            if (fixedFunction)
            {
                // Tex Coord Set
                SetTextureCoordSet(unit, unitState.TextureCoordSet);

                // set the texture blending mode
                SetTextureBlendMode(unit, unitState.ColorBlendMode);

                // set the texture blending mode
                SetTextureBlendMode(unit, unitState.AlphaBlendMode);

                bool anyCalcs = false;

                for (int i = 0; i < unitState.NumEffects; i++)
                {
                    TextureEffect effect = unitState.GetEffect(i);

                    switch (effect.type)
                    {
                        case TextureEffectType.EnvironmentMap:
                            if ((EnvironmentMap)effect.subtype == EnvironmentMap.Curved)
                            {
                                SetTextureCoordCalculation(unit, TexCoordCalcMethod.EnvironmentMap);
                                anyCalcs = true;
                            }
                            else if ((EnvironmentMap)effect.subtype == EnvironmentMap.Planar)
                            {
                                SetTextureCoordCalculation(unit, TexCoordCalcMethod.EnvironmentMapPlanar);
                                anyCalcs = true;
                            }
                            else if ((EnvironmentMap)effect.subtype == EnvironmentMap.Reflection)
                            {
                                SetTextureCoordCalculation(unit, TexCoordCalcMethod.EnvironmentMapReflection);
                                anyCalcs = true;
                            }
                            else if ((EnvironmentMap)effect.subtype == EnvironmentMap.Normal)
                            {
                                SetTextureCoordCalculation(unit, TexCoordCalcMethod.EnvironmentMapNormal);
                                anyCalcs = true;
                            }
                            break;

                        case TextureEffectType.Scroll:
                        case TextureEffectType.Rotate:
                        case TextureEffectType.Transform:
                            break;

                        case TextureEffectType.ProjectiveTexture:
                            SetTextureCoordCalculation(unit, TexCoordCalcMethod.ProjectiveTexture, effect.frustum);
                            anyCalcs = true;
                            break;
                    } // switch
                } // for

                // Ensure any previous texcoord calc settings are reset if there are now none
                if (!anyCalcs)
                {
                    SetTextureCoordCalculation(unit, TexCoordCalcMethod.None);
                }

                // set the texture matrix to that of the current layer for any transformations
                SetTextureMatrix(unit, unitState.TextureMatrix);
            }
        }
Ejemplo n.º 27
0
		/// <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>
 ///    Binds a texture to a vertex sampler.
 /// </summary>
 /// <remarks>
 ///     Not all rendersystems support separate vertex samplers. For those that
 ///     do, you can set a texture for them, separate to the regular texture
 ///     samplers, using this method. For those that don't, you should use the
 ///     regular texture samplers which are shared between the vertex and
 ///     fragment units; calling this method will throw an exception.
 ///     @see RenderSystemCapabilites::getVertexTextureUnitsShared
 /// </remarks>
 public void SetVertexTexture(int unit, TextureUnitState unitState)
 {
     throw new AxiomException(
         "This rendersystem does not support separate vertex texture samplers, " +
         "you should use the regular texture samplers which are shared between " +
         "the vertex and fragment units." +
         "In RenderSystem.SetVertexTexture");
 }
Ejemplo n.º 29
0
			/// <see cref="Translator.Translate"/>
			public override void Translate( ScriptCompiler compiler, AbstractNode node )
			{
				ObjectAbstractNode obj = (ObjectAbstractNode)node;

				Pass pass = (Pass)obj.Parent.Context;
				_textureunit = pass.CreateTextureUnitState();
				obj.Context = _textureunit;

				// Get the name of the technique
				if ( !string.IsNullOrEmpty( obj.Name ) )
					_textureunit.Name = obj.Name;

				// Set the properties for the material
				foreach ( AbstractNode i in obj.Children )
				{
					if ( i is PropertyAbstractNode )
					{
						PropertyAbstractNode prop = (PropertyAbstractNode)i;
						switch ( (Keywords)prop.Id )
						{
							#region ID_TEXTURE_ALIAS
							case Keywords.ID_TEXTURE_ALIAS:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"texture_alias must have at most 1 argument" );
								}
								else
								{
									string val;
									if ( getString( prop.Values[ 0 ], out val ) )
										_textureunit.TextureNameAlias = val;
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid texture alias" );
								}
								break;
							#endregion ID_TEXTURE_ALIAS

							#region ID_TEXTURE
							case Keywords.ID_TEXTURE:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 5 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"texture must have at most 5 arguments" );
								}
								else
								{
									AbstractNode j = getNodeAt( prop.Values, 0 );
									int index = 1;
									string val;
									if ( getString( j, out val ) )
									{
										TextureType texType = TextureType.TwoD;
										bool isAlpha = false;
										bool sRGBRead = false;
										PixelFormat format = PixelFormat.Unknown;
										int mipmaps = -1;//MIP_DEFAULT;

										while ( j != null )
										{
											if ( j is AtomAbstractNode )
											{
												AtomAbstractNode atom = (AtomAbstractNode)j;
												switch ( (Keywords)atom.Id )
												{
													case Keywords.ID_1D:
														texType = TextureType.OneD;
														break;

													case Keywords.ID_2D:
														texType = TextureType.TwoD;
														break;

													case Keywords.ID_3D:
														texType = TextureType.ThreeD;
														break;

													case Keywords.ID_CUBIC:
														texType = TextureType.CubeMap;
														break;

													case Keywords.ID_UNLIMITED:
														mipmaps = 0x7FFFFFFF;//MIP_UNLIMITED;
														break;

													case Keywords.ID_ALPHA:
														isAlpha = true;
														break;

													case Keywords.ID_GAMMA:
														sRGBRead = true;
														break;

													default:
														if ( atom.IsNumber )
															mipmaps = (int)atom.Number;
														else
															format = PixelUtil.GetFormatFromName( atom.Value, true );
														break;
												}
											}
											else
											{
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													j.Value + " is not a supported argument to the texture property" );
											}

											j = getNodeAt( prop.Values, index++ );
										}

										ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(
											ProcessResourceNameScriptCompilerEvent.ResourceType.Texture, val );

										compiler._fireEvent( ref evt );

										string textureName = ( (ProcessResourceNameScriptCompilerEvent)evt ).Name;

										_textureunit.SetTextureName( textureName, texType );
										_textureunit.DesiredFormat = format;
										_textureunit.IsAlpha = isAlpha;
										_textureunit.MipmapCount = mipmaps;
										_textureunit.IsHardwareGammaEnabled = sRGBRead;
									}
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											j.Value + " is not a valid texture name" );
								}
								break;
							#endregion ID_TEXTURE

							#region ID_ANIM_TEXTURE
							case Keywords.ID_ANIM_TEXTURE:
								if ( prop.Values.Count < 3 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else
								{
									AbstractNode i1 = getNodeAt( prop.Values, 1 );
									if ( i1 is AtomAbstractNode && ( (AtomAbstractNode)i ).IsNumber )
									{
										// Short form
										AbstractNode i0 = getNodeAt( prop.Values, 0 ), i2 = getNodeAt( prop.Values, 2 );
										if ( i0 is AtomAbstractNode )
										{
											string val0;
											int val1;
											Real val2;
											if ( getString( i0, out val0 ) && getInt( i1, out val1 ) && getReal( i2, out val2 ) )
											{
												ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(
													ProcessResourceNameScriptCompilerEvent.ResourceType.Texture, val0 );

												compiler._fireEvent( ref evt );
												string evtName = ( (ProcessResourceNameScriptCompilerEvent)evt ).Name;

												_textureunit.SetAnimatedTextureName( evtName, val1, val2 );
											}
											else
											{
												compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
													"anim_texture short form requires a texture name, number of frames, and animation duration" );
											}
										}
										else
										{
											compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
												"anim_texture short form requires a texture name, number of frames, and animation duration" );
										}
									}
									else
									{
										// Long form has n number of frames
										Real duration = 0;
										AbstractNode inNode = getNodeAt( prop.Values, prop.Values.Count - 1 );
										if ( getReal( inNode, out duration ) )
										{
											string[] names = new string[ prop.Values.Count - 1 ];
											int n = 0;

											AbstractNode j = prop.Values[ 0 ];
											int index = 0;
											while ( j != inNode )
											{
												if ( j is AtomAbstractNode )
												{
													string name = ( (AtomAbstractNode)j ).Value;

#warning check this if statement
													// Run the name through the listener
													if ( compiler.Listener != null )
													{
														ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(
															ProcessResourceNameScriptCompilerEvent.ResourceType.Texture, name );

														compiler._fireEvent( ref evt );
														names[ n++ ] = ( (ProcessResourceNameScriptCompilerEvent)evt ).Name;
													}
													else
													{
														names[ n++ ] = name;
													}
												}
												else
													compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
														j.Value + " is not supported as a texture name" );

												++index;
												j = prop.Values[ index ];
											}

											_textureunit.SetAnimatedTextureName( names, n, duration );
										}
										else
										{
											compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
												inNode.Value + " is not supported for the duration argument" );
										}
									}
								}
								break;
							#endregion ID_ANIM_TEXTURE

							#region ID_CUBIC_TEXTURE
							case Keywords.ID_CUBIC_TEXTURE:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count == 2 )
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 );
									if ( i0 is AtomAbstractNode && i1 is AtomAbstractNode )
									{
										AtomAbstractNode atom0 = (AtomAbstractNode)i0, atom1 = (AtomAbstractNode)i1;

										ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(
											ProcessResourceNameScriptCompilerEvent.ResourceType.Texture, atom0.Value );

										compiler._fireEvent( ref evt );
										string evtName = ( (ProcessResourceNameScriptCompilerEvent)evt ).Name;

										_textureunit.SetCubicTextureName( evtName, atom1.Id == (uint)Keywords.ID_COMBINED_UVW );
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line );
									}
								}
								else if ( prop.Values.Count == 7 )
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ),
										i1 = getNodeAt( prop.Values, 1 ),
										i2 = getNodeAt( prop.Values, 2 ),
										i3 = getNodeAt( prop.Values, 3 ),
										i4 = getNodeAt( prop.Values, 4 ),
										i5 = getNodeAt( prop.Values, 5 ),
										i6 = getNodeAt( prop.Values, 6 );

									if ( i0 is AtomAbstractNode && i1 is AtomAbstractNode && i2 is AtomAbstractNode &&
										i3 is AtomAbstractNode && i4 is AtomAbstractNode && i5 is AtomAbstractNode &&
										i6 is AtomAbstractNode )
									{
										AtomAbstractNode atom0 = (AtomAbstractNode)i0, atom1 = (AtomAbstractNode)i1,
											atom2 = (AtomAbstractNode)i2, atom3 = (AtomAbstractNode)i3,
											atom4 = (AtomAbstractNode)i4, atom5 = (AtomAbstractNode)i5,
											atom6 = (AtomAbstractNode)i6;

										string[] names = new string[ 6 ];
										names[ 0 ] = atom0.Value;
										names[ 1 ] = atom1.Value;
										names[ 2 ] = atom2.Value;
										names[ 3 ] = atom3.Value;
										names[ 4 ] = atom4.Value;
										names[ 5 ] = atom5.Value;

										if ( compiler.Listener != null )
										{
											// Run each name through the listener
											for ( int j = 0; j < 6; ++j )
											{
												ScriptCompilerEvent evt = new ProcessResourceNameScriptCompilerEvent(
													ProcessResourceNameScriptCompilerEvent.ResourceType.Texture, names[ j ] );

												compiler._fireEvent( ref evt );
												names[ j ] = ( (ProcessResourceNameScriptCompilerEvent)evt ).Name;
											}
										}

										_textureunit.SetCubicTextureName( names, atom6.Id == (uint)Keywords.ID_COMBINED_UVW );
									}

								}
								else
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"cubic_texture must have at most 7 arguments" );
								}
								break;
							#endregion ID_CUBIC_TEXTURE

							#region ID_TEX_COORD_SET
							case Keywords.ID_TEX_COORD_SET:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"tex_coord_set must have at most 1 argument" );
								}
								else
								{
									int val = 0;
									if ( getInt( prop.Values[ 0 ], out val ) )
										_textureunit.TextureCoordSet = val;
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not supported as an integer argument" );
								}
								break;
							#endregion ID_TEX_COORD_SET

							#region ID_TEX_ADDRESS_MODE
							case Keywords.ID_TEX_ADDRESS_MODE:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ),
										i1 = getNodeAt( prop.Values, 1 ),
										i2 = getNodeAt( prop.Values, 2 );

									UVWAddressing mode = new UVWAddressing( TextureAddressing.Wrap );

									if ( i0 != null && i0 is AtomAbstractNode )
									{
										AtomAbstractNode atom = (AtomAbstractNode)i0;
										switch ( (Keywords)atom.Id )
										{
											case Keywords.ID_WRAP:
												mode.U = TextureAddressing.Wrap;
												break;

											case Keywords.ID_CLAMP:
												mode.U = TextureAddressing.Clamp;
												break;

											case Keywords.ID_MIRROR:
												mode.U = TextureAddressing.Mirror;
												break;

											case Keywords.ID_BORDER:
												mode.U = TextureAddressing.Border;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i0.Value + " not supported as first argument (must be \"wrap\", \"clamp\", \"mirror\", or \"border\")" );
												break;
										}
									}
									mode.V = mode.U;
									mode.W = mode.U;

									if ( i1 != null && i1 is AtomAbstractNode )
									{
										AtomAbstractNode atom = (AtomAbstractNode)i1;
										switch ( (Keywords)atom.Id )
										{
											case Keywords.ID_WRAP:
												mode.V = TextureAddressing.Wrap;
												break;

											case Keywords.ID_CLAMP:
												mode.V = TextureAddressing.Clamp;
												break;

											case Keywords.ID_MIRROR:
												mode.V = TextureAddressing.Mirror;
												break;

											case Keywords.ID_BORDER:
												mode.V = TextureAddressing.Border;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i0.Value + " not supported as second argument (must be \"wrap\", \"clamp\", \"mirror\", or \"border\")" );
												break;
										}
									}

									if ( i2 != null && i2 is AtomAbstractNode )
									{
										AtomAbstractNode atom = (AtomAbstractNode)i2;
										switch ( (Keywords)atom.Id )
										{
											case Keywords.ID_WRAP:
												mode.W = TextureAddressing.Wrap;
												break;

											case Keywords.ID_CLAMP:
												mode.W = TextureAddressing.Clamp;
												break;

											case Keywords.ID_MIRROR:
												mode.W = TextureAddressing.Mirror;
												break;

											case Keywords.ID_BORDER:
												mode.W = TextureAddressing.Border;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i0.Value + " not supported as third argument (must be \"wrap\", \"clamp\", \"mirror\", or \"border\")" );
												break;
										}
									}

									_textureunit.SetTextureAddressingMode( mode );
								}
								break;
							#endregion ID_TEX_ADDRESS_MODE

							#region ID_TEX_BORDER_COLOUR
							case Keywords.ID_TEX_BORDER_COLOUR:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else
								{
									ColorEx val;
									if ( getColor( prop.Values, 0, out val ) )
										_textureunit.TextureBorderColor = val;
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											"tex_border_colour only accepts a colour argument" );
								}
								break;
							#endregion ID_TEX_BORDER_COLOUR

							#region ID_FILTERING
							case Keywords.ID_FILTERING:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count == 1 )
								{
									if ( prop.Values[ 0 ] is AtomAbstractNode )
									{
										AtomAbstractNode atom = (AtomAbstractNode)prop.Values[ 0 ];
										switch ( (Keywords)atom.Id )
										{
											case Keywords.ID_NONE:
												_textureunit.SetTextureFiltering( TextureFiltering.None );
												break;

											case Keywords.ID_BILINEAR:
												_textureunit.SetTextureFiltering( TextureFiltering.Bilinear );
												break;

											case Keywords.ID_TRILINEAR:
												_textureunit.SetTextureFiltering( TextureFiltering.Trilinear );
												break;

											case Keywords.ID_ANISOTROPIC:
												_textureunit.SetTextureFiltering( TextureFiltering.Anisotropic );
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													prop.Values[ 0 ].Value + " not supported as first argument (must be \"none\", \"bilinear\", \"trilinear\", or \"anisotropic\")" );
												break;
										}
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " not supported as first argument (must be \"none\", \"bilinear\", \"trilinear\", or \"anisotropic\")" );
									}
								}
								else if ( prop.Values.Count == 3 )
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ),
										i1 = getNodeAt( prop.Values, 1 ),
										i2 = getNodeAt( prop.Values, 2 );

									if ( i0 is AtomAbstractNode && i1 is AtomAbstractNode && i2 is AtomAbstractNode )
									{
										AtomAbstractNode atom0 = (AtomAbstractNode)i0,
											atom1 = (AtomAbstractNode)i1,
											atom2 = (AtomAbstractNode)i2;

										FilterOptions tmin = FilterOptions.None, tmax = FilterOptions.None, tmip = FilterOptions.None;
										switch ( (Keywords)atom0.Id )
										{
											case Keywords.ID_NONE:
												tmin = FilterOptions.None;
												break;

											case Keywords.ID_POINT:
												tmin = FilterOptions.Point;
												break;

											case Keywords.ID_LINEAR:
												tmin = FilterOptions.Linear;
												break;

											case Keywords.ID_ANISOTROPIC:
												tmin = FilterOptions.Anisotropic;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i0.Value + " not supported as first argument (must be \"none\", \"point\", \"linear\", or \"anisotropic\")" );
												break;
										}

										switch ( (Keywords)atom1.Id )
										{
											case Keywords.ID_NONE:
												tmax = FilterOptions.None;
												break;

											case Keywords.ID_POINT:
												tmax = FilterOptions.Point;
												break;

											case Keywords.ID_LINEAR:
												tmax = FilterOptions.Linear;
												break;

											case Keywords.ID_ANISOTROPIC:
												tmax = FilterOptions.Anisotropic;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i0.Value + " not supported as second argument (must be \"none\", \"point\", \"linear\", or \"anisotropic\")" );
												break;
										}

										switch ( (Keywords)atom2.Id )
										{
											case Keywords.ID_NONE:
												tmip = FilterOptions.None;
												break;

											case Keywords.ID_POINT:
												tmip = FilterOptions.Point;
												break;

											case Keywords.ID_LINEAR:
												tmip = FilterOptions.Linear;
												break;

											case Keywords.ID_ANISOTROPIC:
												tmip = FilterOptions.Anisotropic;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i0.Value + " not supported as third argument (must be \"none\", \"point\", \"linear\", or \"anisotropic\")" );
												break;
										}

										_textureunit.SetTextureFiltering( tmin, tmax, tmip );
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line );
									}
								}
								else
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"filtering must have either 1 or 3 arguments" );
								}
								break;
							#endregion ID_FILTERING

							#region ID_MAX_ANISOTROPY
							case Keywords.ID_MAX_ANISOTROPY:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"max_anisotropy must have at most 1 argument" );
								}
								else
								{
									int val = 0;
									if ( getInt( prop.Values[ 0 ], out val ) )
										_textureunit.TextureAnisotropy = val;
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid integer argument" );
								}
								break;
							#endregion ID_MAX_ANISOTROPY

							#region ID_MIPMAP_BIAS
							case Keywords.ID_MIPMAP_BIAS:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"mipmap_bias must have at most 1 argument" );
								}
								else
								{
									throw new NotImplementedException();
#if UNREACHABLE_CODE
									Real val = 0.0f;
									if ( getReal( prop.Values[ 0 ], out val ) )
									{ /*mUnit->setTextureMipmapBias(val);*/
									}
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid number argument" );
#endif
								}
								break;
							#endregion ID_MIPMAP_BIAS

							#region ID_COLOUR_OP
							case Keywords.ID_COLOUR_OP:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"colour_op must have at most 1 argument" );
								}
								else
								{
									if ( prop.Values[ 0 ] is AtomAbstractNode )
									{
										AtomAbstractNode atom = (AtomAbstractNode)prop.Values[ 0 ];
										switch ( (Keywords)atom.Id )
										{
											case Keywords.ID_REPLACE:
												_textureunit.ColorOperation = LayerBlendOperation.Replace;
												break;

											case Keywords.ID_ADD:
												_textureunit.ColorOperation = LayerBlendOperation.Add;
												break;

											case Keywords.ID_MODULATE:
												_textureunit.ColorOperation = LayerBlendOperation.Modulate;
												break;

											case Keywords.ID_ALPHA_BLEND:
												_textureunit.ColorOperation = LayerBlendOperation.AlphaBlend;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													prop.Values[ 0 ].Value + " is not a valid argument (must be \"replace\", \"add\", \"modulate\", or \"alpha_blend\")" );
												break;
										}
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid argument (must be \"replace\", \"add\", \"modulate\", or \"alpha_blend\")" );
									}
								}
								break;
							#endregion ID_COLOUR_OP

							#region ID_COLOUR_OP_EX
							case Keywords.ID_COLOUR_OP_EX:
								if ( prop.Values.Count < 3 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line,
										"colour_op_ex must have at least 3 arguments" );
								}
								else if ( prop.Values.Count > 10 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"colour_op_ex must have at most 10 arguments" );
								}
								else
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ),
										i1 = getNodeAt( prop.Values, 1 ),
										i2 = getNodeAt( prop.Values, 2 );

									if ( i0 is AtomAbstractNode && i1 is AtomAbstractNode && i2 is AtomAbstractNode )
									{
										AtomAbstractNode atom0 = (AtomAbstractNode)i0,
											atom1 = (AtomAbstractNode)i1,
											atom2 = (AtomAbstractNode)i2;

										LayerBlendOperationEx op = LayerBlendOperationEx.Add;
										LayerBlendSource source1 = LayerBlendSource.Current, source2 = LayerBlendSource.Texture;
										ColorEx arg1 = ColorEx.White, arg2 = ColorEx.White;
										Real manualBlend = 0.0f;

										switch ( (Keywords)atom0.Id )
										{
											case Keywords.ID_SOURCE1:
												op = LayerBlendOperationEx.Source1;
												break;

											case Keywords.ID_SOURCE2:
												op = LayerBlendOperationEx.Source2;
												break;

											case Keywords.ID_MODULATE:
												op = LayerBlendOperationEx.Modulate;
												break;

											case Keywords.ID_MODULATE_X2:
												op = LayerBlendOperationEx.ModulateX2;
												break;

											case Keywords.ID_MODULATE_X4:
												op = LayerBlendOperationEx.ModulateX4;
												break;

											case Keywords.ID_ADD:
												op = LayerBlendOperationEx.Add;
												break;

											case Keywords.ID_ADD_SIGNED:
												op = LayerBlendOperationEx.AddSigned;
												break;

											case Keywords.ID_ADD_SMOOTH:
												op = LayerBlendOperationEx.AddSmooth;
												break;

											case Keywords.ID_SUBTRACT:
												op = LayerBlendOperationEx.Subtract;
												break;

											case Keywords.ID_BLEND_DIFFUSE_ALPHA:
												op = LayerBlendOperationEx.BlendDiffuseAlpha;
												break;

											case Keywords.ID_BLEND_TEXTURE_ALPHA:
												op = LayerBlendOperationEx.BlendTextureAlpha;
												break;

											case Keywords.ID_BLEND_CURRENT_ALPHA:
												op = LayerBlendOperationEx.BlendCurrentAlpha;
												break;

											case Keywords.ID_BLEND_MANUAL:
												op = LayerBlendOperationEx.BlendManual;
												break;

											case Keywords.ID_DOT_PRODUCT:
												op = LayerBlendOperationEx.DotProduct;
												break;

											case Keywords.ID_BLEND_DIFFUSE_COLOUR:
												op = LayerBlendOperationEx.BlendDiffuseColor;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i0.Value + " is not a valid first argument (must be \"source1\", \"source2\", \"modulate\", \"modulate_x2\", \"modulate_x4\", \"add\", \"add_signed\", \"add_smooth\", \"subtract\", \"blend_diffuse_alpha\", \"blend_texture_alpha\", \"blend_current_alpha\", \"blend_manual\", \"dot_product\", or \"blend_diffuse_colour\")" );
												break;
										}

										switch ( (Keywords)atom1.Id )
										{
											case Keywords.ID_SRC_CURRENT:
												source1 = LayerBlendSource.Current;
												break;

											case Keywords.ID_SRC_TEXTURE:
												source1 = LayerBlendSource.Texture;
												break;

											case Keywords.ID_SRC_DIFFUSE:
												source1 = LayerBlendSource.Diffuse;
												break;

											case Keywords.ID_SRC_SPECULAR:
												source1 = LayerBlendSource.Specular;
												break;

											case Keywords.ID_SRC_MANUAL:
												source1 = LayerBlendSource.Manual;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i1.Value + " is not a valid second argument (must be \"src_current\", \"src_texture\", \"src_diffuse\", \"src_specular\", or \"src_manual\")" );
												break;
										}

										switch ( (Keywords)atom2.Id )
										{
											case Keywords.ID_SRC_CURRENT:
												source2 = LayerBlendSource.Current;
												break;

											case Keywords.ID_SRC_TEXTURE:
												source2 = LayerBlendSource.Texture;
												break;

											case Keywords.ID_SRC_DIFFUSE:
												source2 = LayerBlendSource.Diffuse;
												break;

											case Keywords.ID_SRC_SPECULAR:
												source2 = LayerBlendSource.Specular;
												break;

											case Keywords.ID_SRC_MANUAL:
												source2 = LayerBlendSource.Manual;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i2.Value + " is not a valid third argument (must be \"src_current\", \"src_texture\", \"src_diffuse\", \"src_specular\", or \"src_manual\")" );
												break;
										}

										if ( op == LayerBlendOperationEx.BlendManual )
										{
											AbstractNode i3 = getNodeAt( prop.Values, 3 );
											if ( i3 != null )
											{
												if ( !getReal( i3, out manualBlend ) )
													compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
														i3.Value + " is not a valid number argument" );
											}
											else
											{
												compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
													"fourth argument expected when blend_manual is used" );
											}
										}

										AbstractNode j = getNodeAt( prop.Values, 3 );
										int index = 3;
										if ( op == LayerBlendOperationEx.BlendManual )
											j = getNodeAt( prop.Values, ++index );

										if ( source1 == LayerBlendSource.Manual )
										{
											if ( j != null )
											{
												if ( !getColor( prop.Values, 3, out arg1, 3 ) )
													compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
														"valid colour expected when src_manual is used" );
											}
											else
											{
												compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
													"valid colour expected when src_manual is used" );
											}
										}

										if ( source2 == LayerBlendSource.Manual )
										{
											if ( j != null )
											{
												if ( !getColor( prop.Values, 3, out arg2, 3 ) )
													compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
														"valid colour expected when src_manual is used" );
											}
											else
											{
												compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
													"valid colour expected when src_manual is used" );
											}
										}

										_textureunit.SetColorOperationEx( op, source1, source2, arg1, arg2, manualBlend );
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line );
									}
								}
								break;
							#endregion ID_COLOUR_OP_EX

							#region ID_COLOUR_OP_MULTIPASS_FALLBACK
							case Keywords.ID_COLOUR_OP_MULTIPASS_FALLBACK:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 2 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"colour_op_multiplass_fallback must have at most 2 arguments" );
								}
								else if ( prop.Values.Count == 1 )
								{
									if ( prop.Values[ 0 ] is AtomAbstractNode )
									{
										AtomAbstractNode atom = (AtomAbstractNode)prop.Values[ 0 ];
										switch ( (Keywords)atom.Id )
										{
											case Keywords.ID_ADD:
												_textureunit.SetColorOpMultipassFallback( SceneBlendFactor.One, SceneBlendFactor.One );
												break;

											case Keywords.ID_MODULATE:
												_textureunit.SetColorOpMultipassFallback( SceneBlendFactor.DestColor, SceneBlendFactor.Zero );
												break;

											case Keywords.ID_COLOUR_BLEND:
												_textureunit.SetColorOpMultipassFallback( SceneBlendFactor.SourceColor, SceneBlendFactor.OneMinusSourceColor );
												break;

											case Keywords.ID_ALPHA_BLEND:
												_textureunit.SetColorOpMultipassFallback( SceneBlendFactor.SourceAlpha, SceneBlendFactor.OneMinusSourceAlpha );
												break;

											case Keywords.ID_REPLACE:
												_textureunit.SetColorOpMultipassFallback( SceneBlendFactor.One, SceneBlendFactor.Zero );
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													"argument must be a valid scene blend type (add, modulate, colour_blend, alpha_blend, or replace)" );
												break;
										}
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											"argument must be a valid scene blend type (add, modulate, colour_blend, alpha_blend, or replace)" );
									}
								}
								else
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 );
									SceneBlendFactor sbf0, sbf1;
									if ( getEnumeration<SceneBlendFactor>( i0, compiler, out sbf0 ) && getEnumeration<SceneBlendFactor>( i1, compiler, out sbf1 ) )
										_textureunit.SetColorOpMultipassFallback( sbf0, sbf1 );
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											"arguments must be valid scene blend factors" );
								}
								break;
							#endregion ID_COLOUR_OP_MULTIPASS_FALLBACK

							#region ID_ALPHA_OP_EX
							case Keywords.ID_ALPHA_OP_EX:
								if ( prop.Values.Count < 3 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line,
										"alpha_op_ex must have at least 3 arguments" );
								}
								else if ( prop.Values.Count > 6 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"alpha_op_ex must have at most 6 arguments" );
								}
								else
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ),
										i1 = getNodeAt( prop.Values, 1 ),
										i2 = getNodeAt( prop.Values, 2 );

									if ( i0 is AtomAbstractNode && i1 is AtomAbstractNode && i2 is AtomAbstractNode )
									{
										AtomAbstractNode atom0 = (AtomAbstractNode)i0,
											atom1 = (AtomAbstractNode)i1,
											atom2 = (AtomAbstractNode)i2;

										LayerBlendOperationEx op = LayerBlendOperationEx.Add;
										LayerBlendSource source1 = LayerBlendSource.Current, source2 = LayerBlendSource.Texture;
										Real arg1 = 0.0f, arg2 = 0.0f;
										Real manualBlend = 0.0f;

										switch ( (Keywords)atom0.Id )
										{
											case Keywords.ID_SOURCE1:
												op = LayerBlendOperationEx.Source1;
												break;

											case Keywords.ID_SOURCE2:
												op = LayerBlendOperationEx.Source2;
												break;

											case Keywords.ID_MODULATE:
												op = LayerBlendOperationEx.Modulate;
												break;

											case Keywords.ID_MODULATE_X2:
												op = LayerBlendOperationEx.ModulateX2;
												break;

											case Keywords.ID_MODULATE_X4:
												op = LayerBlendOperationEx.ModulateX4;
												break;

											case Keywords.ID_ADD:
												op = LayerBlendOperationEx.Add;
												break;

											case Keywords.ID_ADD_SIGNED:
												op = LayerBlendOperationEx.AddSigned;
												break;

											case Keywords.ID_ADD_SMOOTH:
												op = LayerBlendOperationEx.AddSmooth;
												break;

											case Keywords.ID_SUBTRACT:
												op = LayerBlendOperationEx.Subtract;
												break;

											case Keywords.ID_BLEND_DIFFUSE_ALPHA:
												op = LayerBlendOperationEx.BlendDiffuseAlpha;
												break;

											case Keywords.ID_BLEND_TEXTURE_ALPHA:
												op = LayerBlendOperationEx.BlendTextureAlpha;
												break;

											case Keywords.ID_BLEND_CURRENT_ALPHA:
												op = LayerBlendOperationEx.BlendCurrentAlpha;
												break;

											case Keywords.ID_BLEND_MANUAL:
												op = LayerBlendOperationEx.BlendManual;
												break;

											case Keywords.ID_DOT_PRODUCT:
												op = LayerBlendOperationEx.DotProduct;
												break;

											case Keywords.ID_BLEND_DIFFUSE_COLOUR:
												op = LayerBlendOperationEx.BlendDiffuseColor;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i0.Value + " is not a valid first argument (must be \"source1\", \"source2\", \"modulate\", \"modulate_x2\", \"modulate_x4\", \"add\", \"add_signed\", \"add_smooth\", \"subtract\", \"blend_diffuse_alpha\", \"blend_texture_alpha\", \"blend_current_alpha\", \"blend_manual\", \"dot_product\", or \"blend_diffuse_colour\")" );
												break;
										}

										switch ( (Keywords)atom1.Id )
										{
											case Keywords.ID_SRC_CURRENT:
												source1 = LayerBlendSource.Current;
												break;

											case Keywords.ID_SRC_TEXTURE:
												source1 = LayerBlendSource.Texture;
												break;

											case Keywords.ID_SRC_DIFFUSE:
												source1 = LayerBlendSource.Diffuse;
												break;

											case Keywords.ID_SRC_SPECULAR:
												source1 = LayerBlendSource.Specular;
												break;

											case Keywords.ID_SRC_MANUAL:
												source1 = LayerBlendSource.Manual;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i1.Value + " is not a valid second argument (must be \"src_current\", \"src_texture\", \"src_diffuse\", \"src_specular\", or \"src_manual\")" );
												break;
										}

										switch ( (Keywords)atom2.Id )
										{
											case Keywords.ID_SRC_CURRENT:
												source2 = LayerBlendSource.Current;
												break;

											case Keywords.ID_SRC_TEXTURE:
												source2 = LayerBlendSource.Texture;
												break;

											case Keywords.ID_SRC_DIFFUSE:
												source2 = LayerBlendSource.Diffuse;
												break;

											case Keywords.ID_SRC_SPECULAR:
												source2 = LayerBlendSource.Specular;
												break;

											case Keywords.ID_SRC_MANUAL:
												source2 = LayerBlendSource.Manual;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													i2.Value + " is not a valid third argument (must be \"src_current\", \"src_texture\", \"src_diffuse\", \"src_specular\", or \"src_manual\")" );
												break;
										}

										if ( op == LayerBlendOperationEx.BlendManual )
										{
											AbstractNode i3 = getNodeAt( prop.Values, 3 );
											if ( i3 != null )
											{
												if ( !getReal( i3, out manualBlend ) )
													compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
														"valid number expected when blend_manual is used" );
											}
											else
											{
												compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
													"valid number expected when blend_manual is used" );
											}
										}

										AbstractNode j = getNodeAt( prop.Values, 3 );
										int index = 3;
										if ( op == LayerBlendOperationEx.BlendManual )
											j = getNodeAt( prop.Values, ++index );

										if ( source1 == LayerBlendSource.Manual )
										{
											if ( j != null )
											{
												if ( !getReal( j, out arg1 ) )
													compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
														"valid colour expected when src_manual is used" );
												else
													j = getNodeAt( prop.Values, ++index );
											}
											else
											{
												compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
													"valid colour expected when src_manual is used" );
											}
										}

										if ( source2 == LayerBlendSource.Manual )
										{
											if ( j != null )
											{
												if ( !getReal( j, out arg2 ) )
													compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
														"valid colour expected when src_manual is used" );
											}
											else
											{
												compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line,
													"valid colour expected when src_manual is used" );
											}
										}

										_textureunit.SetAlphaOperation( op, source1, source2, arg1, arg2, manualBlend );
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line );
									}
								}
								break;
							#endregion ID_ALPHA_OP_EX

							#region ID_ENV_MAP
							case Keywords.ID_ENV_MAP:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.StringExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"env_map must have at most 1 argument" );
								}
								else
								{
									if ( prop.Values[ 0 ] is AtomAbstractNode )
									{
										AtomAbstractNode atom = (AtomAbstractNode)prop.Values[ 0 ];
										switch ( atom.Id )
										{
											case (uint)BuiltIn.ID_OFF:
												_textureunit.SetEnvironmentMap( false );
												break;

											case (uint)Keywords.ID_SPHERICAL:
												_textureunit.SetEnvironmentMap( true, EnvironmentMap.Curved );
												break;

											case (uint)Keywords.ID_PLANAR:
												_textureunit.SetEnvironmentMap( true, EnvironmentMap.Planar );
												break;

											case (uint)Keywords.ID_CUBIC_REFLECTION:
												_textureunit.SetEnvironmentMap( true, EnvironmentMap.Reflection );
												break;

											case (uint)Keywords.ID_CUBIC_NORMAL:
												_textureunit.SetEnvironmentMap( true, EnvironmentMap.Normal );
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													prop.Values[ 0 ].Value + " is not a valid argument (must be \"off\", \"spherical\", \"planar\", \"cubic_reflection\", or \"cubic_normal\")" );
												break;
										}
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid argument (must be \"off\", \"spherical\", \"planar\", \"cubic_reflection\", or \"cubic_normal\")" );
									}
								}
								break;
							#endregion ID_ENV_MAP

							#region ID_SCROLL
							case Keywords.ID_SCROLL:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 2 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"scroll must have at most 2 arguments" );
								}
								else
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 );
									Real x, y;
									if ( getReal( i0, out x ) && getReal( i1, out y ) )
										_textureunit.SetTextureScroll( x, y );
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											i0.Value + " and/or " + i1.Value + " is invalid; both must be numbers" );
								}
								break;
							#endregion ID_SCROLL

							#region ID_SCROLL_ANIM
							case Keywords.ID_SCROLL_ANIM:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 2 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"scroll_anim must have at most 2 arguments" );
								}
								else
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 );
									Real x, y;
									if ( getReal( i0, out x ) && getReal( i1, out y ) )
										_textureunit.SetScrollAnimation( x, y );
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											i0.Value + " and/or " + i1.Value + " is invalid; both must be numbers" );
								}
								break;
							#endregion ID_SCROLL_ANIM

							#region ID_ROTATE
							case Keywords.ID_ROTATE:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"rotate must have at most 1 argument" );
								}
								else
								{
									Real angle;
									if ( getReal( prop.Values[ 0 ], out angle ) )
#warning check this statement
										//mUnit->setTextureRotate(Degree(angle));
										_textureunit.SetTextureRotate( angle );
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid number value" );
								}
								break;
							#endregion ID_ROTATE

							#region ID_ROTATE_ANIM
							case Keywords.ID_ROTATE_ANIM:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"rotate_anim must have at most 1 argument" );
								}
								else
								{
									Real angle;
									if ( getReal( prop.Values[ 0 ], out angle ) )
										_textureunit.SetRotateAnimation( angle );
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid number value" );
								}
								break;
							#endregion ID_ROTATE_ANIM

							#region ID_SCALE
							case Keywords.ID_SCALE:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 2 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"scale must have at most 2 arguments" );
								}
								else
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 );
									Real x, y;
									if ( getReal( i0, out x ) && getReal( i1, out y ) )
										_textureunit.SetTextureScale( x, y );
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
										"first and second arguments must both be valid number values (received " + i0.Value + ", " + i1.Value + ")" );
								}
								break;
							#endregion ID_SCALE

							#region ID_WAVE_XFORM
							case Keywords.ID_WAVE_XFORM:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 6 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"wave_xform must have at most 6 arguments" );
								}
								else
								{
									AbstractNode i0 = getNodeAt( prop.Values, 0 ), i1 = getNodeAt( prop.Values, 1 ),
										i2 = getNodeAt( prop.Values, 2 ), i3 = getNodeAt( prop.Values, 3 ),
										i4 = getNodeAt( prop.Values, 4 ), i5 = getNodeAt( prop.Values, 5 );

									if ( i0 is AtomAbstractNode && i1 is AtomAbstractNode && i2 is AtomAbstractNode &&
										i3 is AtomAbstractNode && i4 is AtomAbstractNode && i5 is AtomAbstractNode )
									{
										AtomAbstractNode atom0 = (AtomAbstractNode)i0, atom1 = (AtomAbstractNode)i1;
										TextureTransform type = TextureTransform.Rotate;
										WaveformType wave = WaveformType.Sine;
										Real baseVal = 0.0f, freq = 0.0f, phase = 0.0f, amp = 0.0f;

										switch ( (Keywords)atom0.Id )
										{
											case Keywords.ID_SCROLL_X:
												type = TextureTransform.TranslateU;
												break;

											case Keywords.ID_SCROLL_Y:
												type = TextureTransform.TranslateV;
												break;

											case Keywords.ID_SCALE_X:
												type = TextureTransform.ScaleU;
												break;

											case Keywords.ID_SCALE_Y:
												type = TextureTransform.ScaleV;
												break;

											case Keywords.ID_ROTATE:
												type = TextureTransform.Rotate;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													atom0.Value + " is not a valid transform type (must be \"scroll_x\", \"scroll_y\", \"scale_x\", \"scale_y\", or \"rotate\")" );
												break;
										}

										switch ( (Keywords)atom1.Id )
										{
											case Keywords.ID_SINE:
												wave = WaveformType.Sine;
												break;

											case Keywords.ID_TRIANGLE:
												wave = WaveformType.Triangle;
												break;

											case Keywords.ID_SQUARE:
												wave = WaveformType.Square;
												break;

											case Keywords.ID_SAWTOOTH:
												wave = WaveformType.Sawtooth;
												break;

											case Keywords.ID_INVERSE_SAWTOOTH:
												wave = WaveformType.InverseSawtooth;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													atom1.Value + " is not a valid waveform type (must be \"sine\", \"triangle\", \"square\", \"sawtooth\", or \"inverse_sawtooth\")" );
												break;
										}

										if ( !getReal( i2, out baseVal ) || !getReal( i3, out freq ) || !getReal( i4, out phase ) || !getReal( i5, out amp ) )
											compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
												"arguments 3, 4, 5, and 6 must be valid numbers; received " + i2.Value + ", " + i3.Value + ", " + i4.Value + ", " + i5.Value );

										_textureunit.SetTransformAnimation( type, wave, baseVal, freq, phase, amp );
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line );
									}
								}
								break;
							#endregion ID_WAVE_XFORM

							#region ID_TRANSFORM
							case Keywords.ID_TRANSFORM:
						    {
						        throw new NotImplementedException();
#if UNREACHABLE_CODE
									Matrix4 m;
									if ( getMatrix4( prop.Values, 0, out m ) )
									{ /*mUnit->setTextureTransform(m);*/
									}
									else
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line );
								}
								break;
#else
						    }
#endif

						        #endregion ID_TRANSFORM

							#region ID_BINDING_TYPE
							case Keywords.ID_BINDING_TYPE:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 1 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"binding_type must have at most 1 argument" );
								}
								else
								{
									if ( prop.Values[ 0 ] is AtomAbstractNode )
									{
										AtomAbstractNode atom = (AtomAbstractNode)prop.Values[ 0 ];
										switch ( (Keywords)atom.Id )
										{
											case Keywords.ID_VERTEX:
												_textureunit.BindingType = TextureBindingType.Vertex;
												break;

											case Keywords.ID_FRAGMENT:
												_textureunit.BindingType = TextureBindingType.Fragment;
												break;

											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													atom.Value + " is not a valid binding type (must be \"vertex\" or \"fragment\")" );
												break;
										}
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid binding type" );
									}
								}
								break;
							#endregion ID_BINDING_TYPE

							#region ID_CONTENT_TYPE
							case Keywords.ID_CONTENT_TYPE:
								if ( prop.Values.Count == 0 )
								{
									compiler.AddError( CompileErrorCode.NumberExpected, prop.File, prop.Line );
								}
								else if ( prop.Values.Count > 4 )
								{
									compiler.AddError( CompileErrorCode.FewerParametersExpected, prop.File, prop.Line,
										"content_type must have at most 4 arguments" );
								}
								else
								{
									if ( prop.Values[ 0 ] is AtomAbstractNode )
									{
										throw new NotImplementedException();
#if UNREACHABLE_CODE
										AtomAbstractNode atom = (AtomAbstractNode)prop.Values[ 0 ];
										switch ( (Keywords)atom.Id )
										{
											case Keywords.ID_NAMED:
												//mUnit->setContentType(TextureUnitState::CONTENT_NAMED);
												break;

											case Keywords.ID_SHADOW:
												//mUnit->setContentType(TextureUnitState::CONTENT_SHADOW);
												break;

											case Keywords.ID_COMPOSITOR:
												//mUnit->setContentType(TextureUnitState::CONTENT_COMPOSITOR);
												if ( prop.Values.Count >= 3 )
												{
													string compositorName;
													getString( getNodeAt( prop.Values, 1 ), out compositorName );
													string textureName;
													getString( getNodeAt( prop.Values, 2 ), out textureName );

													if ( prop.Values.Count == 4 )
													{
														uint mrtIndex;
														getUInt( getNodeAt( prop.Values, 3 ), out mrtIndex );
														//mUnit->setCompositorReference(compositorName, textureName, mrtIndex);
													}
													else
													{
														//mUnit->setCompositorReference(compositorName, textureName);
													}
												}
												else
												{
													compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
														"content_type compositor must have an additional 2 or 3 parameters" );
												}

												break;
											default:
												compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
													atom.Value + " is not a valid content type (must be \"named\" or \"shadow\" or \"compositor\")" );
												break;
										}
#endif
									}
									else
									{
										compiler.AddError( CompileErrorCode.InvalidParameters, prop.File, prop.Line,
											prop.Values[ 0 ].Value + " is not a valid content type" );
									}
								}
								break;
Ejemplo n.º 30
0
		public virtual void WriteInstance( MaterialSerializer ser, SubRenderState subRenderState,
		                                   TextureUnitState srcTextureUnit, TextureUnitState dstTextureUnit )
		{
		}