/
Shader.cs
100 lines (93 loc) · 3.22 KB
/
Shader.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
using Silk.NET.OpenGL;
using System;
using System.IO;
using System.Numerics;
namespace Abstractions
{
public class Shader
{
private uint _handle;
private GL _gl;
public Shader(GL gl, string vertexPath, string fragmentPath)
{
_gl = gl;
uint vertex = LoadShader(ShaderType.VertexShader, vertexPath);
uint fragment = LoadShader(ShaderType.FragmentShader, fragmentPath);
_handle = _gl.CreateProgram();
_gl.AttachShader(_handle, vertex);
_gl.AttachShader(_handle, fragment);
_gl.LinkProgram(_handle);
_gl.GetProgram(_handle, GLEnum.LinkStatus, out var status);
if (status == 0)
{
throw new Exception($"Program failed to link with error: {_gl.GetProgramInfoLog(_handle)}");
}
_gl.DetachShader(_handle, vertex);
_gl.DetachShader(_handle, fragment);
_gl.DeleteShader(vertex);
_gl.DeleteShader(fragment);
}
public void Use()
{
_gl.UseProgram(_handle);
}
public void SetUniform(string name, int value)
{
int location = _gl.GetUniformLocation(_handle, name);
if (location == -1)
{
throw new Exception($"{name} uniform not found on shader.");
}
Use();
_gl.Uniform1(location, value);
}
public unsafe void SetUniform(string name, Vector2 value)
{
int location = _gl.GetUniformLocation(_handle, name);
if (location == -1)
{
throw new Exception($"{name} uniform not found on shader.");
}
Use();
_gl.Uniform2(location, value);
}
public unsafe void SetUniform(string name, Matrix4x4 value)
{
//A new overload has been created for setting a uniform so we can use the transform in our shader.
int location = _gl.GetUniformLocation(_handle, name);
if (location == -1)
{
throw new Exception($"{name} uniform not found on shader.");
}
Use();
_gl.UniformMatrix4(location, 1, false, (float*)&value);
}
public void SetUniform(string name, float value)
{
int location = _gl.GetUniformLocation(_handle, name);
if (location == -1)
{
throw new Exception($"{name} uniform not found on shader.");
}
Use();
_gl.Uniform1(location, value);
}
public void Dispose()
{
_gl.DeleteProgram(_handle);
}
private uint LoadShader(ShaderType type, string path)
{
string src = File.ReadAllText(path);
uint handle = _gl.CreateShader(type);
_gl.ShaderSource(handle, src);
_gl.CompileShader(handle);
string infoLog = _gl.GetShaderInfoLog(handle);
if (!string.IsNullOrWhiteSpace(infoLog))
{
throw new Exception($"Error compiling shader of type {type}, failed with error {infoLog}");
}
return handle;
}
}
}