static public ShaderInfo FromFile (string path, Options options, IEffectCompilerOutput output)
		{
            
			var effectSource = File.ReadAllText (path);
			if (options.Profile == ShaderProfile.PureGLSL)
				return PureGLSLFromString (effectSource, path, options, output);
			return null;
			//return FromString(effectSource, path, options, output);
		}
        public void Write(BinaryWriter writer, Options options)
        {
            writer.Write(IsVertexShader);

            writer.Write(ShaderCode.Length);
            writer.Write(ShaderCode);

            writer.Write((byte)_samplers.Length);
            foreach (var sampler in _samplers)
            {
                writer.Write((byte)sampler.type);
                writer.Write((byte)sampler.textureSlot);
                writer.Write((byte)sampler.samplerSlot);

                if (sampler.state != null)
                {
                    writer.Write(true);
                    writer.Write((byte)sampler.state.AddressU);
                    writer.Write((byte)sampler.state.AddressV);
                    writer.Write((byte)sampler.state.AddressW);
                    writer.Write(sampler.state.BorderColor.R);
                    writer.Write(sampler.state.BorderColor.G);
                    writer.Write(sampler.state.BorderColor.B);
                    writer.Write(sampler.state.BorderColor.A);
                    writer.Write((byte)sampler.state.Filter);
                    writer.Write(sampler.state.MaxAnisotropy);
                    writer.Write(sampler.state.MaxMipLevel);
                    writer.Write(sampler.state.MipMapLevelOfDetailBias);
                }
                else
                    writer.Write(false);

                if (options.Profile == ShaderProfile.OpenGL)
                    writer.Write(sampler.samplerName);

                writer.Write((byte)sampler.parameter);
            }

            writer.Write((byte)_cbuffers.Length);
            foreach (var cb in _cbuffers)
                writer.Write((byte)cb);

            if (options.Profile != ShaderProfile.OpenGL)
                return;

            // The rest of this is for GL only!

            writer.Write((byte)_attributes.Length);
            foreach (var attrib in _attributes)
            {
                writer.Write(attrib.name);
                writer.Write((byte)attrib.usage);
                writer.Write((byte)attrib.index);
                writer.Write((short)0); // Unused
            }
        }
        public void Write(BinaryWriter writer, Options options)
        {
            if (options.Profile == ShaderProfile.OpenGL)
                writer.Write(Name);

            writer.Write((ushort)Size);

            writer.Write((byte)ParameterIndex.Count);
            for (var i = 0; i < ParameterIndex.Count; i++)
            {
                writer.Write((byte)ParameterIndex[i]);
                writer.Write((ushort)ParameterOffset[i]);
            }
        }
		static public ShaderInfo PureGLSLFromString (string effectSource, string filePath, Options options, IEffectCompilerOutput output)
		{

			ShaderInfo shaderInfo = new ShaderInfo ();
			shaderInfo.FilePath = options.SourceFile;
			XmlDocument doc = new XmlDocument ();
			doc.LoadXml (effectSource);
			XmlElement effectElement;
			XmlNode current = doc.FirstChild;
			while (current != null && current.NodeType != XmlNodeType.Element) {
				current = current.NextSibling;
			}
			effectElement = (XmlElement)current;
			shaderInfo.Techniques = new List<TechniqueInfo> ();
			foreach (XmlElement technique in effectElement.ChildNodes.OfType<XmlElement>()) {
				TechniqueInfo info = new TechniqueInfo ();
				info.name = technique.GetAttribute ("name");
				info.Passes = new List<PassInfo> ();
				foreach (XmlElement pass in technique.ChildNodes.OfType<XmlElement>()) {
					PassInfo pi = new PassInfo ();
					pi.name = pass.GetAttribute ("name");
					foreach (XmlElement sh in pass.ChildNodes) {
						if (sh.Name == "Shader") {
							if (sh.GetAttribute ("type") == "PixelShader") {
								pi.psFileName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(shaderInfo.FilePath),sh.GetAttribute ("filename"));
								shaderInfo.Dependencies.Add (pi.psFileName);
								pi.psShaderXML = sh.OuterXml;
							} else if (sh.GetAttribute ("type") == "VertexShader") {
								pi.vsFilename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(shaderInfo.FilePath),sh.GetAttribute ("filename"));
								shaderInfo.Dependencies.Add (pi.vsFilename);
								pi.vsShaderXML = sh.OuterXml;
							} else {
								throw new PipelineException ("Unsupported Shader type detected");
							}
						} else if (sh.Name == "BlendState") {
							pi.blendState = ParseBlendState (sh);

						} else if (sh.Name == "DepthStencilState") {
							pi.depthStencilState = ParseDepthStencilState (sh);
						} else if (sh.Name == "RasterizerState") {
							pi.rasterizerState = ParseRasterizerState (sh);
						} else {
							throw new PipelineException ("'" + sh.Name + "' element not recognized");
						}
					}
					info.Passes.Add (pi);
				}
				shaderInfo.Techniques.Add (info);
			}

			shaderInfo.Profile = options.Profile;
			shaderInfo.Debug = options.Debug;

			shaderInfo.OutputFilePath = options.OutputFile;

			return shaderInfo;
		}
        /// <summary>
        /// Writes the effect for loading later.
        /// </summary>
        public void Write(BinaryWriter writer, Options options)
        {
            // Write a very simple header for identification and versioning.
            writer.Write(Header.ToCharArray());
            writer.Write((byte)Version);

            // Write an simple identifier for DX11 vs GLSL
            // so we can easily detect the correct shader type.
            var profile = (byte)options.Profile;
            if (options.Profile == ShaderProfile.PureGLSL)
            {
                options.Profile = ShaderProfile.OpenGL;
                profile = (byte)ShaderProfile.OpenGL;
            }
            writer.Write(profile);

            // Write the rest to a memory stream.
            using (MemoryStream memStream = new MemoryStream())
            using (BinaryWriter memWriter = new BinaryWriter(memStream))
            {
                // Write all the constant buffers.
                memWriter.Write((byte)ConstantBuffers.Count);
                foreach (var cbuffer in ConstantBuffers)
                    cbuffer.Write(memWriter, options);

                // Write all the shaders.
                memWriter.Write((byte)Shaders.Count);
                foreach (var shader in Shaders)
                    shader.Write(memWriter, options);

                // Write the parameters.
                WriteParameters(memWriter, Parameters, Parameters.Length);

                // Write the techniques.
                memWriter.Write((byte)Techniques.Length);
                foreach (var technique in Techniques)
                {
                    memWriter.Write(technique.name);
                    WriteAnnotations(memWriter, technique.annotation_handles);

                    // Write the passes.
                    memWriter.Write((byte)technique.pass_count);
                    for (var p = 0; p < technique.pass_count; p++)
                    {
                        var pass = technique.pass_handles[p];

                        memWriter.Write(pass.name);
                        WriteAnnotations(memWriter, pass.annotation_handles);

                        // Write the index for the vertex and pixel shaders.
                        var vertexShader = GetShaderIndex(STATE_CLASS.VERTEXSHADER, pass.states);
                        var pixelShader = GetShaderIndex(STATE_CLASS.PIXELSHADER, pass.states);
                        memWriter.Write((byte)vertexShader);
                        memWriter.Write((byte)pixelShader);

                        // Write the state objects too!
                        if (pass.blendState != null)
                        {
                            memWriter.Write(true);
                            memWriter.Write((byte)pass.blendState.AlphaBlendFunction);
                            memWriter.Write((byte)pass.blendState.AlphaDestinationBlend);
                            memWriter.Write((byte)pass.blendState.AlphaSourceBlend);
                            memWriter.Write(pass.blendState.BlendFactor.R);
                            memWriter.Write(pass.blendState.BlendFactor.G);
                            memWriter.Write(pass.blendState.BlendFactor.B);
                            memWriter.Write(pass.blendState.BlendFactor.A);
                            memWriter.Write((byte)pass.blendState.ColorBlendFunction);
                            memWriter.Write((byte)pass.blendState.ColorDestinationBlend);
                            memWriter.Write((byte)pass.blendState.ColorSourceBlend);
                            memWriter.Write((byte)pass.blendState.ColorWriteChannels);
                            memWriter.Write((byte)pass.blendState.ColorWriteChannels1);
                            memWriter.Write((byte)pass.blendState.ColorWriteChannels2);
                            memWriter.Write((byte)pass.blendState.ColorWriteChannels3);
                            memWriter.Write(pass.blendState.MultiSampleMask);
                        }
                        else
                            memWriter.Write(false);

                        if (pass.depthStencilState != null)
                        {
                            memWriter.Write(true);
                            memWriter.Write((byte)pass.depthStencilState.CounterClockwiseStencilDepthBufferFail);
                            memWriter.Write((byte)pass.depthStencilState.CounterClockwiseStencilFail);
                            memWriter.Write((byte)pass.depthStencilState.CounterClockwiseStencilFunction);
                            memWriter.Write((byte)pass.depthStencilState.CounterClockwiseStencilPass);
                            memWriter.Write(pass.depthStencilState.DepthBufferEnable);
                            memWriter.Write((byte)pass.depthStencilState.DepthBufferFunction);
                            memWriter.Write(pass.depthStencilState.DepthBufferWriteEnable);
                            memWriter.Write(pass.depthStencilState.ReferenceStencil);
                            memWriter.Write((byte)pass.depthStencilState.StencilDepthBufferFail);
                            memWriter.Write(pass.depthStencilState.StencilEnable);
                            memWriter.Write((byte)pass.depthStencilState.StencilFail);
                            memWriter.Write((byte)pass.depthStencilState.StencilFunction);
                            memWriter.Write(pass.depthStencilState.StencilMask);
                            memWriter.Write((byte)pass.depthStencilState.StencilPass);
                            memWriter.Write(pass.depthStencilState.StencilWriteMask);
                            memWriter.Write(pass.depthStencilState.TwoSidedStencilMode);
                        }
                        else
                            memWriter.Write(false);

                        if (pass.rasterizerState != null)
                        {
                            memWriter.Write(true);
                            memWriter.Write((byte)pass.rasterizerState.CullMode);
                            memWriter.Write(pass.rasterizerState.DepthBias);
                            memWriter.Write((byte)pass.rasterizerState.FillMode);
                            memWriter.Write(pass.rasterizerState.MultiSampleAntiAlias);
                            memWriter.Write(pass.rasterizerState.ScissorTestEnable);
                            memWriter.Write(pass.rasterizerState.SlopeScaleDepthBias);
                        }
                        else
                            memWriter.Write(false);
                    }
                }

                // Calculate a hash code from memory stream
                // and write it to the header.
                var effectKey = Utilities.ComputeHash(memStream);
                writer.Write((Int32)effectKey);

                //write content from memory stream to final stream.
                memStream.WriteTo(writer.BaseStream);
            }
        }