private CompiledShader ParseShader(XmlDocument doc) { if(doc.DocumentElement.Name != "shader") throw new Exception("Invalid shader file"); ShaderLoader that = this; /*source code for vertex / fragment shaders*/ String sourceFragment = null; String sourceVertex = null; CompiledShader ret = new CompiledShader(); /*the name of the shader*/ ret.Name = doc.DocumentElement.Attributes.GetNamedItem("name").Value; /*the lists of all unoforms and attributes-*/ List<String> uniforms = new List<string>(); List<String> attributes = new List<string>(); foreach (XmlNode xmlNode in doc.DocumentElement.ChildNodes) { if (xmlNode.NodeType != XmlNodeType.Element) continue; if(xmlNode.Name == "vertex_shader") { sourceVertex = XmlHelper.InnerText(xmlNode); } else if(xmlNode.Name == "fragment_shader") { sourceFragment = XmlHelper.InnerText(xmlNode); } else if(xmlNode.Name == "uniform") { uniforms.Add(XmlHelper.InnerText(xmlNode)); } else if(xmlNode.Name == "attribute") { attributes.Add(XmlHelper.InnerText(xmlNode)); } } if(sourceFragment == null || sourceVertex == null) throw new Exception("Shader file does not contain fragment and vertex shaders"); /*compile shaders*/ IShader shaderFragment = this.CompileShader(sourceFragment, WebGLE.FragmentShader); IShader shaderVertex = this.CompileShader(sourceVertex, WebGLE.VertexShader); /*create the program*/ IShaderProgram shaderProgram = this._gl.CreateProgram(); this._gl.AttachShader(shaderProgram, shaderFragment); this._gl.AttachShader(shaderProgram, shaderVertex); this._gl.LinkProgram(shaderProgram); if (!(bool)this._gl.GetProgramParameter(shaderProgram, WebGLE.LinkStatus)) { throw new Exception("Cannot link shaders."); } ret.Attributes = new Dictionary<string, int>(); ret.Uniforms = new Dictionary<string, IUniformLocation>(); /*attribute locations*/ attributes.ForEach(delegate(string value) { ret.Attributes[value] = that._gl.GetAttribLocation(shaderProgram, value); }); /*uniform locations*/ uniforms.ForEach(delegate(string value) { ret.Uniforms[value] = that._gl.GetUniformLocation(shaderProgram, value); }); ret.ShaderProgram = shaderProgram; return ret; }
//----------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------- public void BindShader(CompiledShader shader) { this._context.UseProgram(shader.ShaderProgram); }