This repository has been archived by the owner on Apr 20, 2022. It is now read-only.
/
GlslSourceBuilder.cs
142 lines (124 loc) · 6.29 KB
/
GlslSourceBuilder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
using System;
using System.Collections.Generic;
using System.Text;
using IIS.SLSharp.Annotations;
using IIS.SLSharp.Descriptions;
using IIS.SLSharp.Shaders;
using Mono.Cecil;
namespace IIS.SLSharp.Translation.GLSL
{
public static class GlslSourceBuilder
{
private static readonly Dictionary<Type, string> _complexTypeName = new Dictionary<Type, string>
{
{ typeof(void), "void" },
{ typeof(float), "float" },
{ typeof(ShaderDefinition.vec2), "vec2" },
{ typeof(ShaderDefinition.vec3), "vec3" },
{ typeof(ShaderDefinition.vec4), "vec4" },
{ typeof(ShaderDefinition.mat2), "mat2" },
{ typeof(ShaderDefinition.mat2x3), "mat2x3" },
{ typeof(ShaderDefinition.mat2x4), "mat2x4" },
{ typeof(ShaderDefinition.mat3x2), "mat3x2" },
{ typeof(ShaderDefinition.mat3), "mat3" },
{ typeof(ShaderDefinition.mat3x4), "mat3x4" },
{ typeof(ShaderDefinition.mat4x2), "mat4x2" },
{ typeof(ShaderDefinition.mat4x3), "mat4x3" },
{ typeof(ShaderDefinition.mat4), "mat4" },
{ typeof(ShaderDefinition.sampler1D), "sampler1D" },
{ typeof(ShaderDefinition.sampler2D), "sampler2D" },
{ typeof(ShaderDefinition.sampler3D), "sampler3D" },
{ typeof(ShaderDefinition.samplerCube), "samplerCube" },
{ typeof(ShaderDefinition.sampler1DShadow), "sampler1DShadow" },
{ typeof(ShaderDefinition.sampler2DShadow), "sampler2DShadow" },
{ typeof(ShaderDefinition.isampler1D), "isampler1D" },
{ typeof(ShaderDefinition.isampler2D), "isampler2D" },
{ typeof(ShaderDefinition.isampler3D), "isampler3D" },
{ typeof(ShaderDefinition.isamplerCube), "isamplerCube" },
{ typeof(ShaderDefinition.usampler1D), "usampler1D" },
{ typeof(ShaderDefinition.usampler2D), "usampler2D" },
{ typeof(ShaderDefinition.usampler3D), "usampler3D" },
{ typeof(ShaderDefinition.usamplerCube), "usamplerCube" },
{ typeof(ShaderDefinition.sampler2DRect), "sampler2DRect" },
{ typeof(ShaderDefinition.sampler2DRectShadow), "sampler2DRectShadow" },
{ typeof(ShaderDefinition.isampler2DRect), "isampler2DRect" },
{ typeof(ShaderDefinition.usampler2DRect), "usampler2DRect" },
{ typeof(int), "int" },
{ typeof(ShaderDefinition.ivec2), "ivec2" },
{ typeof(ShaderDefinition.ivec3), "ivec3" },
{ typeof(ShaderDefinition.ivec4), "ivec4" },
{ typeof(uint), "uint" },
{ typeof(ShaderDefinition.uvec2), "uvec2" },
{ typeof(ShaderDefinition.uvec3), "uvec3" },
{ typeof(ShaderDefinition.uvec4), "uvec4" },
{ typeof(double), "double" },
{ typeof(ShaderDefinition.dvec2), "dvec2" },
{ typeof(ShaderDefinition.dvec3), "dvec3" },
{ typeof(ShaderDefinition.dvec4), "dvec4" },
{ typeof(ShaderDefinition.dmat2), "dmat2" },
{ typeof(ShaderDefinition.dmat2x3), "dmat2x3" },
{ typeof(ShaderDefinition.dmat2x4), "dmat2x4" },
{ typeof(ShaderDefinition.dmat3x2), "dmat3x2" },
{ typeof(ShaderDefinition.dmat3), "dmat3" },
{ typeof(ShaderDefinition.dmat3x4), "dmat3x4" },
{ typeof(ShaderDefinition.dmat4x2), "dmat4x2" },
{ typeof(ShaderDefinition.dmat4x3), "dmat4x3" },
{ typeof(ShaderDefinition.dmat4), "dmat4" },
{ typeof(bool), "bool" },
{ typeof(ShaderDefinition.bvec2), "bvec2" },
{ typeof(ShaderDefinition.bvec3), "bvec3" },
{ typeof(ShaderDefinition.bvec4), "bvec4" },
};
internal static string ToGlsl(this TypeReference t)
{
var typeDef = t.Resolve();
return Shader.TypeMap[typeDef.MetadataToken.ToInt32()].Type.ToGlsl();
}
public static string ToGlsl(this Type t)
{
string glslName;
if (!_complexTypeName.TryGetValue(t, out glslName))
throw new SLSharpException(t + " is currently not supported by GLSL module");
return glslName;
}
public static string ToGlsl(this SourceDescription desc, ShaderType type)
{
var s = new StringBuilder();
s.AppendLine("#version 130");
if (type == ShaderType.FragmentShader)
s.AppendLine("precision highp float;");
s.AppendLine("// " + type);
desc.Uniforms.ForEach(
v => s.AppendFormat("uniform {0} {1};{2}", v.Type.ToGlsl(), v.Name, v.Comment).Append(Environment.NewLine));
var varyingDirection = type == ShaderType.VertexShader ? "out" : "in";
desc.Varyings.ForEach(
v =>
s.AppendFormat("{0} {1} {2};{3}", varyingDirection, v.Type.ToGlsl(), v.Name, v.Comment).Append(
Environment.NewLine));
if (type == ShaderType.VertexShader)
desc.VertexIns.ForEach(
v => s.AppendFormat("in {0} {1};{2}", v.Type.ToGlsl(), v.Name, v.Comment).Append(Environment.NewLine));
if (type == ShaderType.FragmentShader)
desc.FragmentOuts.ForEach(
v =>
{
if (v.Semantic == UsageSemantic.Depth)
{
// validate type and let SL# throw rather than generate invalid GL code
if (v.Type != typeof(float))
throw new SLSharpException(v.Name + "'s must be float, as it is marked as fragment depth!");
s.AppendFormat("#define {0} gl_FragDepth {1}", v.Name, v.Comment).Append(Environment.NewLine);
return;
}
s.AppendFormat("out {0} {1};{2}", v.Type.ToGlsl(), v.Name, v.Comment).Append(Environment.NewLine);
});
s.AppendLine();
desc.ForwardDecl.ForEach(v => s.AppendLine(v));
s.AppendLine();
desc.Functions.ForEach(v => s.AppendLine(v.Body));
var src = s.ToString();
Console.WriteLine(src);
return src;
}
}
}