// ----------------------------------------------------------------------------- // file="ShaderGenerator" // Project: StgSharp // Copyright (c) Nitload. // SPDX-License-Identifier: MIT // ----------------------------------------------------------------------------- using StgSharp.Graphics; using StgSharp.Graphics.OpenGL; using StgSharp.Mathematics; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace StgSharp.Graphics.ShaderEdit { public class ShaderGenerator { private Dictionary uniformDefine; private List codeList; private List usedShaderFunctions; public Uniform DefineUniform( string name, int index ) where T : unmanaged { ShaderParameter p = new ShaderParameter(name, ShaderParameter.TypeMarshal()); uniformDefine.Add(index, p); // return new Uniform(); throw new NotImplementedException(); } } public class ShaderFunction { private List codeList; private List inputList; private ShaderParameter outPut; private string name; public int ParameterCount => inputList.Count; public void EmitCall( ShaderFunction function, ShaderParameter outPut, params ShaderParameter[] inputParams ) { if (inputParams.Length != function.ParameterCount) { // Param list length not equal throw new ArgumentException( "Provided parameters does not match function's parameter list."); } if (!ShaderParameter.IsSameType(outPut, function.outPut)) { // Type of returning value not equal throw new ArgumentException( "Provided parameters does not match function's parameter list."); } for (int i = 0; i < inputParams.Length; i++) { if (!ShaderParameter.IsSameType(function.inputList[i], inputParams[i])) { // Input type not match throw new InvalidCastException( "Provided parameters does not match function's parameter list."); } } string codeLine = string.Empty; // adding a line like " outvalue = Func(input1, input2,...); " if (outPut != ShaderParameter.Void) { codeLine += $"{outPut.name} = "; } codeLine += $"{function.name}("; foreach (ShaderParameter inputParam in inputParams) { codeLine += inputParam.name; } codeLine += ");\n"; codeList.Add(codeLine); } } public class ShaderParameter { public static readonly ShaderParameter Void = new ShaderParameter( string.Empty, InternalShaderType.Void); internal readonly bool isReadOnly; internal readonly InternalShaderType type; internal readonly string name; public ShaderParameter( string name, InternalShaderType type ) { this.name = name; this.type = type; isReadOnly = false; } public static bool IsSameType( ShaderParameter param1, ShaderParameter param2 ) { if (param1.type != InternalShaderType.Struct) { return param1.type == param2.type; } else { throw new Exception("Struct is currently not supported."); } } public static InternalShaderType TypeMarshal() where T : unmanaged { switch (Type.GetTypeCode(typeof(T))) { case TypeCode.Single: return InternalShaderType.Float; case TypeCode.Double: return InternalShaderType.Double; case TypeCode.Int32: return InternalShaderType.Int; case TypeCode.UInt32: return InternalShaderType.UInt; default: break; } switch (typeof(T).Name) { case "vec4d": return InternalShaderType.Vector4; case "Matrix2x2": return InternalShaderType.Matrix2x2; case "Matrix2x3": return InternalShaderType.Matrix2x3; case "Matrix2x4": return InternalShaderType.Matrix2x4; case "Matrix3x2": return InternalShaderType.Matrix3x2; case "Matrix3x3": return InternalShaderType.Matrix3x3; case "Matrix3x4": return InternalShaderType.Matrix3x4; case "Matrix4x2": return InternalShaderType.Matrix4x2; case "Matrix4x3": return InternalShaderType.Matrix4x3; case "Matrix4x4": return InternalShaderType.Matrix4x4; default: throw new ArgumentException("Not supported shader data type."); } } } public enum InternalShaderType { #pragma warning disable CS1591 Struct, Void, Int, UInt, Float, Double, Vector2, Vector3, Vector4, VectorD2, VectorD3, VectorD4, Matrix2x2, Matrix2x3, Matrix2x4, Matrix3x2, Matrix3x3, Matrix3x4, Matrix4x2, Matrix4x3, Matrix4x4, #pragma warning restore CS1591 } }