From b30f79acdac3cd4f81760c946158edb0779f7881 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Sat, 25 Feb 2017 16:01:56 -0500 Subject: [PATCH] Shader loader --- hexworld/HexRender.cs | 41 ++++++++++++++++++++++--------------- hexworld/Util/Extensions.cs | 24 ---------------------- hexworld/Util/Program.cs | 20 ++++++++++++++++++ hexworld/Util/Shader.cs | 23 +++++++++++++++++++++ hexworld/Util/VBO.cs | 7 ++++--- hexworld/hexworld.csproj | 1 - 6 files changed, 72 insertions(+), 44 deletions(-) delete mode 100644 hexworld/Util/Extensions.cs diff --git a/hexworld/HexRender.cs b/hexworld/HexRender.cs index e0eabee..faa9103 100644 --- a/hexworld/HexRender.cs +++ b/hexworld/HexRender.cs @@ -16,9 +16,11 @@ namespace hexworld public partial class HexRender : GameWindow { private Program pgm; + // todo: generate texture atlas // or at least embed sub-uvs and materials into json private Texture grass; + private Texture stone; private Matrix4 view; @@ -67,25 +69,32 @@ namespace hexworld tileVbo = new VBO(); tileVbo.Data(tiles, BufferUsageHint.DynamicDraw); - var vs = new Shader(ShaderType.VertexShader) - { - Source = File.ReadAllText("s.vs.glsl") - }; - vs.Compile(); - Console.Out.WriteLine(vs.Log); + var vs = Shader.FromFile("s.vs.glsl", ShaderType.VertexShader); + var fs = Shader.FromFile("s.fs.glsl", ShaderType.FragmentShader); + pgm = Program.FromShaders(vs, fs); - var fs = new Shader(ShaderType.FragmentShader) + if (!vs.Compiled | !fs.Compiled) { - Source = File.ReadAllText("s.fs.glsl") - }; - fs.Compile(); - Console.Out.WriteLine(fs.Log); + Console.Out.WriteLine("Failed to compile shaders:"); + if (!vs.Compiled) + Console.Out.WriteLine("Vertex Shader:\n" + vs.Log.Trim()); + if (!fs.Compiled) + Console.Out.WriteLine("Fragment Shader:\n" + fs.Log.Trim()); + Console.Out.WriteLine("Press any key to exit."); + Console.ReadKey(); + Exit(); + return; + } - pgm = new Program(); - pgm.Attach(vs); - pgm.Attach(fs); - pgm.Link(); - Console.Out.WriteLine(pgm.Log); + if (!pgm.LinkStatus) + { + Console.Out.WriteLine("Failed to link program:"); + Console.Out.WriteLine(pgm.Log.Trim()); + Console.Out.WriteLine("Press any key to exit."); + Console.ReadKey(); + Exit(); + return; + } cubeVbo.AttribPointers(pgm); tileVbo.AttribPointers(pgm); diff --git a/hexworld/Util/Extensions.cs b/hexworld/Util/Extensions.cs deleted file mode 100644 index 0ab84c4..0000000 --- a/hexworld/Util/Extensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -using OpenTK.Graphics.OpenGL4; - -namespace hexworld.Util -{ - public static class Extensions - { - public static byte[] ToBytes(this T[] arr) where T : struct - { - var size = Marshal.SizeOf()*arr.Length; - var bytes = new byte[size]; - var ptr = Marshal.AllocHGlobal(size); - Marshal.StructureToPtr(arr, ptr, false); - Marshal.Copy(ptr, bytes, 0, size); - Marshal.FreeHGlobal(ptr); - return bytes; - } - } -} \ No newline at end of file diff --git a/hexworld/Util/Program.cs b/hexworld/Util/Program.cs index 48ff816..9574994 100644 --- a/hexworld/Util/Program.cs +++ b/hexworld/Util/Program.cs @@ -19,6 +19,15 @@ namespace hexworld.Util public void Attach(Shader shader) => GL.AttachShader(Id, shader.Id); + public bool LinkStatus + { + get + { + GL.GetProgram(Id, GetProgramParameterName.LinkStatus, out int success); + return success != 0; + } + } + public bool Link() { uniforms.Clear(); @@ -86,5 +95,16 @@ namespace hexworld.Util public void Use() => GL.UseProgram(Id); public static void UseDefault() => GL.UseProgram(0); + + public static Program FromShaders(params Shader[] shaders) + { + var p = new Program(); + foreach (var shader in shaders) + { + p.Attach(shader); + } + p.Link(); + return p; + } } } \ No newline at end of file diff --git a/hexworld/Util/Shader.cs b/hexworld/Util/Shader.cs index 9e046a9..55212c7 100644 --- a/hexworld/Util/Shader.cs +++ b/hexworld/Util/Shader.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using OpenTK.Graphics.OpenGL4; +using System.IO; namespace hexworld.Util { @@ -23,6 +24,15 @@ namespace hexworld.Util public string Log => GL.GetShaderInfoLog((int) Id); + public bool Compiled + { + get + { + GL.GetShader(Id, ShaderParameter.CompileStatus, out int success); + return success != 0; + } + } + public Shader(ShaderType type) : base((uint) GL.CreateShader(type)) { @@ -35,5 +45,18 @@ namespace hexworld.Util GL.GetShader(Id, ShaderParameter.CompileStatus, out int success); return success != 0; } + + public static Shader FromFile(string path, ShaderType type) + { + return FromFile(path, type, out bool success); + } + + public static Shader FromFile(string path, ShaderType type, out bool success) + { + var s = new Shader(type); + s.Source = File.ReadAllText(path); + success = s.Compile(); + return s; + } } } \ No newline at end of file diff --git a/hexworld/Util/VBO.cs b/hexworld/Util/VBO.cs index b30187f..8f52ba1 100644 --- a/hexworld/Util/VBO.cs +++ b/hexworld/Util/VBO.cs @@ -31,7 +31,7 @@ namespace hexworld.Util public void Data(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw) { Bind(); - var size = Marshal.SizeOf(); + var size = Marshal.SizeOf(typeof(T)); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (size * data.Length), data, usage); VBO.Unbind(); } @@ -43,13 +43,14 @@ namespace hexworld.Util static VBO() { var attribList = new List(); - Stride = Marshal.SizeOf(); + Stride = Marshal.SizeOf(typeof(T)); foreach (var fieldInfo in typeof(T).GetFields()) { var attrs = fieldInfo.GetCustomAttributes(typeof(VertexPointerAttribute), false); if (attrs.Length == 0) continue; - var offset = (int) Marshal.OffsetOf(fieldInfo.Name); + + var offset = (int) Marshal.OffsetOf(typeof(T), fieldInfo.Name); foreach (var attr in attrs) { var vpa = (VertexPointerAttribute) attr; diff --git a/hexworld/hexworld.csproj b/hexworld/hexworld.csproj index 97a31c4..968dad6 100644 --- a/hexworld/hexworld.csproj +++ b/hexworld/hexworld.csproj @@ -55,7 +55,6 @@ -