Archived
Private
Public Access
1
0
This repository has been archived on 2026-02-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2022-09-04 13:23:45 +02:00

103 lines
3.7 KiB
C#

using System;
using System.IO;
using System.Numerics;
using System.Text;
using System.Text.RegularExpressions;
using static OpenGL.GL;
namespace OpenGLTutorial.Rendering.Shaders {
public class Shader {
private readonly string _vertexCode;
private readonly string _fragmentCode;
private bool _loaded = false;
public uint Program { get; private set; }
public Shader(string vertexPath, string fragmentPath) {
using (var vertexReader = new StreamReader(vertexPath, Encoding.UTF8))
_vertexCode = vertexReader.ReadToEnd();
using (var fragmentReader = new StreamReader(fragmentPath, Encoding.UTF8))
_fragmentCode = fragmentReader.ReadToEnd();
}
public Shader(string shader, bool isFile = true) {
using var reader = isFile ? new StreamReader(shader, Encoding.UTF8) : null;
string source = isFile ? reader.ReadToEnd() : shader;
string[] splitString = Regex.Split(source, "(#type [a-zA-Z]+)");
string firstPattern = splitString[1].Replace("#type ", "").Trim();
string secondPattern = splitString[3].Replace("#type ", "").Trim();
if (firstPattern.ToLower().Equals("vertex"))
_vertexCode = splitString[2];
else if (firstPattern.ToLower().Equals("fragment"))
_fragmentCode = splitString[2];
else throw new IOException("Unexpected token '" + firstPattern + "' in '" + shader + "'");
if (secondPattern.ToLower().Equals("vertex"))
_vertexCode = splitString[4];
else if (secondPattern.ToLower().Equals("fragment"))
_fragmentCode = splitString[4];
else throw new IOException("Unexpected token '" + secondPattern + "' in '" + shader + "'");
}
public void Load() {
if (_loaded) return;
_loaded = true;
uint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, _vertexCode);
glCompileShader(vs);
int[] status = glGetShaderiv(vs, GL_COMPILE_STATUS, 1);
if (status[0] == 0) {
string error = glGetShaderInfoLog(vs);
throw new Exception("Error compiling vertex shader: " + error);
}
uint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, _fragmentCode);
glCompileShader(fs);
status = glGetShaderiv(fs, GL_COMPILE_STATUS, 1);
if (status[0] == 0) {
string error = glGetShaderInfoLog(fs);
throw new Exception("Error compiling fragment shader: " + error);
}
Program = glCreateProgram();
glAttachShader(Program, vs);
glAttachShader(Program, fs);
glLinkProgram(Program);
glDetachShader(Program, vs);
glDetachShader(Program, fs);
glDeleteShader(vs);
glDeleteShader(fs);
}
public void Use() {
glUseProgram(Program);
}
public void Delete() {
glUseProgram(0);
glDeleteProgram(Program);
}
public void SetMatrix4X4(string uniformName, Matrix4x4 matrix) {
int location = glGetUniformLocation(Program, uniformName);
glUniformMatrix4fv(location, 1, false, GetMatrix4X4Values(matrix));
}
private float[] GetMatrix4X4Values(Matrix4x4 m) {
return new [] {
m.M11, m.M12, m.M13, m.M14,
m.M21, m.M22, m.M23, m.M24,
m.M31, m.M32, m.M33, m.M34,
m.M41, m.M42, m.M43, m.M44
};
}
}
}