119 lines
2.7 KiB
C#
119 lines
2.7 KiB
C#
using OpenTK.Graphics.OpenGL4;
|
|
|
|
namespace SemiColinGames;
|
|
|
|
public class Shader : IDisposable {
|
|
public int Handle;
|
|
private bool init = false;
|
|
|
|
public Shader() {}
|
|
|
|
public void Init() {
|
|
init = true;
|
|
int VertexShader;
|
|
int FragmentShader;
|
|
|
|
string VertexShaderSource = @"
|
|
#version 330
|
|
|
|
layout(location = 0) in vec3 aPosition;
|
|
layout(location = 1) in vec2 aTexCoord;
|
|
|
|
out vec2 texCoord;
|
|
|
|
uniform mat4 projection;
|
|
|
|
void main(void) {
|
|
texCoord = aTexCoord;
|
|
gl_Position = vec4(aPosition, 1.0) * projection;
|
|
}";
|
|
|
|
string FragmentShaderSource = @"
|
|
#version 330
|
|
|
|
out vec4 outputColor;
|
|
in vec2 texCoord;
|
|
uniform sampler2D texture0;
|
|
uniform vec4 color;
|
|
|
|
void main() {
|
|
outputColor = texture(texture0, texCoord) * color;
|
|
}";
|
|
|
|
VertexShader = GL.CreateShader(ShaderType.VertexShader);
|
|
GL.ShaderSource(VertexShader, VertexShaderSource);
|
|
|
|
FragmentShader = GL.CreateShader(ShaderType.FragmentShader);
|
|
GL.ShaderSource(FragmentShader, FragmentShaderSource);
|
|
|
|
GL.CompileShader(VertexShader);
|
|
|
|
int success;
|
|
GL.GetShader(VertexShader, ShaderParameter.CompileStatus, out success);
|
|
if (success == 0) {
|
|
string infoLog = GL.GetShaderInfoLog(VertexShader);
|
|
Console.WriteLine(infoLog);
|
|
}
|
|
|
|
GL.CompileShader(FragmentShader);
|
|
|
|
GL.GetShader(FragmentShader, ShaderParameter.CompileStatus, out success);
|
|
if (success == 0) {
|
|
string infoLog = GL.GetShaderInfoLog(FragmentShader);
|
|
Console.WriteLine(infoLog);
|
|
}
|
|
Handle = GL.CreateProgram();
|
|
|
|
GL.AttachShader(Handle, VertexShader);
|
|
GL.AttachShader(Handle, FragmentShader);
|
|
|
|
GL.LinkProgram(Handle);
|
|
|
|
GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out success);
|
|
if (success == 0) {
|
|
string infoLog = GL.GetProgramInfoLog(Handle);
|
|
Console.WriteLine(infoLog);
|
|
}
|
|
|
|
GL.DetachShader(Handle, VertexShader);
|
|
GL.DetachShader(Handle, FragmentShader);
|
|
GL.DeleteShader(FragmentShader);
|
|
GL.DeleteShader(VertexShader);
|
|
}
|
|
|
|
public void Use() {
|
|
if (!init) {
|
|
Console.WriteLine("Shader.Use(): must call Init() first");
|
|
}
|
|
GL.UseProgram(Handle);
|
|
}
|
|
|
|
private bool disposedValue = false;
|
|
|
|
protected virtual void Dispose(bool disposing) {
|
|
if (!disposedValue) {
|
|
GL.DeleteProgram(Handle);
|
|
disposedValue = true;
|
|
}
|
|
}
|
|
|
|
~Shader() {
|
|
if (disposedValue == false) {
|
|
Console.WriteLine("~Shader(): resource leak? Dispose() should be called manually.");
|
|
}
|
|
}
|
|
|
|
public void Dispose() {
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
public int GetAttribLocation(string name) {
|
|
return GL.GetAttribLocation(Handle, name);
|
|
}
|
|
|
|
public int GetUniformLocation(string name) {
|
|
return GL.GetUniformLocation(Handle, name);
|
|
}
|
|
}
|