This repository was archived by the owner on Aug 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathShader.cs
More file actions
116 lines (92 loc) · 3.98 KB
/
Shader.cs
File metadata and controls
116 lines (92 loc) · 3.98 KB
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
using OpenTK;
using OpenTK.Graphics.OpenGL4;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BuildPlate_Editor
{
public class Shader
{
public int ProgramId;
private string vertexShaderSource;
private string fragmentShaderSource;
private static List<ShaderVariable> vars = new List<ShaderVariable>();
public void Compile(string shaderName)
{
string path = Program.baseDir + "Data/Shaders/" + shaderName;
vertexShaderSource = File.ReadAllText(path + ".vert");
fragmentShaderSource = File.ReadAllText(path + ".frag");
int vertex = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertex, vertexShaderSource);
GL.CompileShader(vertex);
GL.GetShader(vertex, ShaderParameter.CompileStatus, out int status);
if (status == 0) {
string err = GL.GetShaderInfoLog(vertex);
Console.WriteLine($"ERROR::SHADER::VERTEX::COMPILATION_FAILED\n{ err}");
}
int fragment = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragment, fragmentShaderSource);
GL.CompileShader(fragment);
GL.GetShader(fragment, ShaderParameter.CompileStatus, out status);
if (status == 0) {
string err = GL.GetShaderInfoLog(vertex);
Console.WriteLine($"ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n{err}");
}
ProgramId = GL.CreateProgram();
GL.AttachShader(ProgramId, vertex);
GL.AttachShader(ProgramId, fragment);
GL.LinkProgram(ProgramId);
GL.GetProgram(ProgramId, GetProgramParameterName.LinkStatus, out status);
if (status == 0) {
string err = GL.GetProgramInfoLog(vertex);
Console.WriteLine($"ERROR::SHADER::PROGRAM::LINKING_FAILED\n{err}");
}
GL.DeleteShader(vertex);
GL.DeleteShader(fragment);
GL.GetProgram(ProgramId, GetProgramParameterName.ActiveUniforms, out int numbUniforms);
GL.GetProgram(ProgramId, GetProgramParameterName.ActiveUniformMaxLength, out int maxNameLength);
if (numbUniforms > 0) {
for (int i = 0; i < numbUniforms; i++) {
GL.GetActiveUniform(ProgramId, i, maxNameLength, out int length, out int size, out ActiveUniformType type, out string name);
int varLocation = GL.GetUniformLocation(ProgramId, name);
ShaderVariable var = new ShaderVariable() { name = name, location = varLocation, programId = ProgramId };
vars.Add(var);
}
}
}
public void Bind()
{
GL.UseProgram(ProgramId);
}
public void UploadInt(string name, int val)
{
int loc = GetVarLocation(this, name);
GL.Uniform1(loc, val);
}
public void UploadMat4(string name, ref Matrix4 val)
{
GL.UniformMatrix4(GetVarLocation(this, name), false, ref val);
}
public static int GetVarLocation(Shader shader, string name)
{
ShaderVariable match = new ShaderVariable() { name = name, programId = shader.ProgramId };
for (int i = 0; i < vars.Count; i++)
if (vars[i] == match)
return vars[i].location;
return -1;
}
struct ShaderVariable
{
public string name;
public int location;
public int programId;
public static bool operator ==(ShaderVariable a, ShaderVariable b)
=> a.name == b.name && a.programId == b.programId;
public static bool operator !=(ShaderVariable a, ShaderVariable b)
=> a.name != b.name || a.programId != b.programId;
}
}
}