void INativeShaderPart.LoadSource(string sourceCode, Resources.ShaderType type) { }
void INativeShaderProgram.LoadProgram(IEnumerable <INativeShaderPart> shaderParts, IEnumerable <ShaderFieldInfo> shaderFields) { DefaultOpenTKBackendPlugin.GuardSingleThreadState(); // Verify that we have exactly one shader part for each stage. // Other scenarios are valid in desktop GL, but not GL ES, so // we'll enforce the stricter rules manually to ease portability. int vertexCount = 0; int fragmentCount = 0; foreach (INativeShaderPart part in shaderParts) { Resources.ShaderType type = (part as NativeShaderPart).Type; if (type == Resources.ShaderType.Fragment) { fragmentCount++; } else if (type == Resources.ShaderType.Vertex) { vertexCount++; } } if (vertexCount == 0) { throw new ArgumentException("Cannot load program without vertex shader."); } if (fragmentCount == 0) { throw new ArgumentException("Cannot load program without fragment shader."); } if (vertexCount > 1) { throw new ArgumentException("Cannot attach multiple vertex shaders to the same program."); } if (fragmentCount > 1) { throw new ArgumentException("Cannot attach multiple fragment shaders to the same program."); } // Create or reset GL program if (this.handle == 0) { this.handle = GL.CreateProgram(); } else { this.DetachShaders(); } // Attach all individual shaders to the program foreach (INativeShaderPart part in shaderParts) { GL.AttachShader(this.handle, (part as NativeShaderPart).Handle); } // Link the shader program GL.LinkProgram(this.handle); int result; GL.GetProgram(this.handle, GetProgramParameterName.LinkStatus, out result); if (result == 0) { string errorLog = GL.GetProgramInfoLog(this.handle); this.RollbackAtFault(); throw new BackendException(string.Format("Linker error:{1}{0}", errorLog, Environment.NewLine)); } // Collect variables that are available through shader reflection, e.g. // haven't been optimized of #ifdef'd away. List <int> validLocations = new List <int>(); List <ShaderFieldInfo> validFields = new List <ShaderFieldInfo>(); foreach (ShaderFieldInfo field in shaderFields) { int location; if (field.Scope == ShaderFieldScope.Uniform) { location = GL.GetUniformLocation(this.handle, field.Name); } else { location = GL.GetAttribLocation(this.handle, field.Name); } if (location >= 0) { validLocations.Add(location); validFields.Add(field); } } this.fields = validFields.ToArray(); this.fieldLocations = validLocations.ToArray(); }