public static Shader Create(ShaderType type, uint id) { Shader result = null; switch (type) { case ShaderType.VertexShader: result = new VertexShader(id); break; case ShaderType.TessControlShader: result = new TessControlShader(id); break; case ShaderType.TessEvaluationShader: result = new TessEvaluationShader(id); break; case ShaderType.GeometryShader: result = new GeometryShader(id); break; case ShaderType.FragmentShader: result = new FragmentShader(id); break; case ShaderType.ComputeShader: result = new ComputeShader(id); break; default: throw new NotImplementedException(); } return(result); }
private unsafe void FragmentShaderStage(ShaderProgram program, List <Fragment> fragmentList) { FragmentShader fs = program.FragmentShader; if (fs == null) { return; } foreach (var fragment in fragmentList) { var instance = fs.CreateCodeInstance() as FragmentCodeBase; // an executable fragment shader. instance.gl_FragCoord = fragment.gl_FragCoord; // setup fragmen coordinatein window/screen space. // setup "in SomeType varName;" vertex attributes. InVariable[] inVariables = fs.inVariableDict.Values.ToArray(); if (inVariables.Length != fragment.attributes.Length) { throw new Exception("This should not happen!"); } for (int index = 0; index < inVariables.Length; index++) { InVariable inVar = inVariables[index]; PassBuffer attribute = fragment.attributes[index]; var pointer = attribute.Mapbuffer().ToPointer(); switch (attribute.elementType) { case PassType.Float: inVar.fieldInfo.SetValue(instance, ((float *)pointer)[0]); break; case PassType.Vec2: inVar.fieldInfo.SetValue(instance, ((vec2 *)pointer)[0]); break; case PassType.Vec3: inVar.fieldInfo.SetValue(instance, ((vec3 *)pointer)[0]); break; case PassType.Vec4: inVar.fieldInfo.SetValue(instance, ((vec4 *)pointer)[0]); break; case PassType.Mat2: inVar.fieldInfo.SetValue(instance, ((mat2 *)pointer)[0]); break; case PassType.Mat3: inVar.fieldInfo.SetValue(instance, ((mat3 *)pointer)[0]); break; case PassType.Mat4: inVar.fieldInfo.SetValue(instance, ((mat4 *)pointer)[0]); break; default: throw new NotDealWithNewEnumItemException(typeof(PassType)); } attribute.Unmapbuffer(); } // setup "uniform SomeType varName;" in fragment shader. Dictionary <string, UniformValue> nameUniformDict = program.nameUniformDict; foreach (UniformVariable uniformVar in fs.UniformVariableDict.Values) { string name = uniformVar.fieldInfo.Name; UniformValue obj = null; if (nameUniformDict.TryGetValue(name, out obj)) { if (obj.value != null) { uniformVar.fieldInfo.SetValue(instance, obj.value); } } } instance.main(); // execute fragment shader code. fragment.discard = instance.discard; if (!instance.discard) // if this fragment is not discarded. { OutVariable[] outVariables = fs.outVariableDict.Values.ToArray(); var outBuffers = new PassBuffer[outVariables.Length]; for (int index = 0; index < outVariables.Length; index++) { OutVariable outVar = outVariables[index]; var outBuffer = new PassBuffer(outVar.fieldInfo.FieldType.GetPassType(), 1); var pointer = outBuffer.Mapbuffer().ToPointer(); switch (outBuffer.elementType) { case PassType.Float: ((float *)pointer)[0] = (float)outVar.fieldInfo.GetValue(instance); break; case PassType.Vec2: ((vec2 *)pointer)[0] = (vec2)outVar.fieldInfo.GetValue(instance); break; case PassType.Vec3: ((vec3 *)pointer)[0] = (vec3)outVar.fieldInfo.GetValue(instance); break; case PassType.Vec4: ((vec4 *)pointer)[0] = (vec4)outVar.fieldInfo.GetValue(instance); break; case PassType.Mat2: ((mat2 *)pointer)[0] = (mat2)outVar.fieldInfo.GetValue(instance); break; case PassType.Mat3: ((mat3 *)pointer)[0] = (mat3)outVar.fieldInfo.GetValue(instance); break; case PassType.Mat4: ((mat4 *)pointer)[0] = (mat4)outVar.fieldInfo.GetValue(instance); break; default: throw new NotDealWithNewEnumItemException(typeof(PassType)); } outBuffer.Unmapbuffer(); outBuffers[index] = outBuffer; } fragment.outVariables = outBuffers; } } }
/// <summary> /// find the vertex shader and other shaders. /// </summary> /// <returns></returns> private bool FindTypedShaders() { bool result = true; VertexShader vertexShader = null; TessControlShader tessControlShader = null; TessEvaluationShader tessEvaluationShader = null; GeometryShader geometryShader = null; FragmentShader fragmentShader = null; ComputeShader computeShader = null; foreach (var item in this.attachedShaders) { if (item.InfoLog != string.Empty) { this.logInfo = "Shader Compiling Error!"; result = false; break; } switch (item.ShaderType) { case ShaderType.VertexShader: if (vertexShader != null) { this.logInfo = "Multiple VertexShader!"; result = false; break; } else { vertexShader = item as VertexShader; } break; case ShaderType.TessControlShader: if (tessControlShader != null) { this.logInfo = "Multiple TessControlShader!"; result = false; break; } else { tessControlShader = item as TessControlShader; } break; case ShaderType.TessEvaluationShader: if (tessEvaluationShader != null) { this.logInfo = "Multiple TessEvaluationShader!"; result = false; break; } else { tessEvaluationShader = item as TessEvaluationShader; } break; case ShaderType.GeometryShader: if (geometryShader != null) { this.logInfo = "Multiple GeometryShader!"; result = false; break; } else { geometryShader = item as GeometryShader; } break; case ShaderType.FragmentShader: if (fragmentShader != null) { this.logInfo = "Multiple FragmentShader!"; result = false; break; } else { fragmentShader = item as FragmentShader; } break; case ShaderType.ComputeShader: if (computeShader != null) { this.logInfo = "Multiple ComputeShader!"; result = false; break; } else { computeShader = item as ComputeShader; } break; default: throw new NotImplementedException(); } } if (vertexShader == null) { this.logInfo = "No VertexShader found!"; result = false; return(result); } { // TODO: support other shaders. this.VertexShader = vertexShader; //this.tessControlShader = tessControlShader; //this.tessEvaluationShader = tessEvaluationShader; //this.geometryShader = geometryShader; this.FragmentShader = fragmentShader; //this.computeShader = computeShader; } return(result); }