You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.7 KiB

  1. using OpenTK.Graphics.OpenGL4;
  2. namespace SemiColinGames;
  3. public class Shader : IDisposable {
  4. public int Handle;
  5. private bool init = false;
  6. public Shader() {}
  7. public void Init() {
  8. init = true;
  9. int VertexShader;
  10. int FragmentShader;
  11. string VertexShaderSource = @"
  12. #version 330
  13. layout(location = 0) in vec3 aPosition;
  14. layout(location = 1) in vec2 aTexCoord;
  15. out vec2 texCoord;
  16. uniform mat4 projection;
  17. void main(void) {
  18. texCoord = aTexCoord;
  19. gl_Position = vec4(aPosition, 1.0) * projection;
  20. }";
  21. string FragmentShaderSource = @"
  22. #version 330
  23. out vec4 outputColor;
  24. in vec2 texCoord;
  25. uniform sampler2D texture0;
  26. uniform vec4 color;
  27. void main() {
  28. outputColor = texture(texture0, texCoord) * color;
  29. }";
  30. VertexShader = GL.CreateShader(ShaderType.VertexShader);
  31. GL.ShaderSource(VertexShader, VertexShaderSource);
  32. FragmentShader = GL.CreateShader(ShaderType.FragmentShader);
  33. GL.ShaderSource(FragmentShader, FragmentShaderSource);
  34. GL.CompileShader(VertexShader);
  35. int success;
  36. GL.GetShader(VertexShader, ShaderParameter.CompileStatus, out success);
  37. if (success == 0) {
  38. string infoLog = GL.GetShaderInfoLog(VertexShader);
  39. Console.WriteLine(infoLog);
  40. }
  41. GL.CompileShader(FragmentShader);
  42. GL.GetShader(FragmentShader, ShaderParameter.CompileStatus, out success);
  43. if (success == 0) {
  44. string infoLog = GL.GetShaderInfoLog(FragmentShader);
  45. Console.WriteLine(infoLog);
  46. }
  47. Handle = GL.CreateProgram();
  48. GL.AttachShader(Handle, VertexShader);
  49. GL.AttachShader(Handle, FragmentShader);
  50. GL.LinkProgram(Handle);
  51. GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out success);
  52. if (success == 0) {
  53. string infoLog = GL.GetProgramInfoLog(Handle);
  54. Console.WriteLine(infoLog);
  55. }
  56. GL.DetachShader(Handle, VertexShader);
  57. GL.DetachShader(Handle, FragmentShader);
  58. GL.DeleteShader(FragmentShader);
  59. GL.DeleteShader(VertexShader);
  60. }
  61. public void Use() {
  62. if (!init) {
  63. Console.WriteLine("Shader.Use(): must call Init() first");
  64. }
  65. GL.UseProgram(Handle);
  66. }
  67. private bool disposedValue = false;
  68. protected virtual void Dispose(bool disposing) {
  69. if (!disposedValue) {
  70. GL.DeleteProgram(Handle);
  71. disposedValue = true;
  72. }
  73. }
  74. ~Shader() {
  75. if (disposedValue == false) {
  76. Console.WriteLine("~Shader(): resource leak? Dispose() should be called manually.");
  77. }
  78. }
  79. public void Dispose() {
  80. Dispose(true);
  81. GC.SuppressFinalize(this);
  82. }
  83. public int GetAttribLocation(string name) {
  84. return GL.GetAttribLocation(Handle, name);
  85. }
  86. public int GetUniformLocation(string name) {
  87. return GL.GetUniformLocation(Handle, name);
  88. }
  89. }