From dd1fc7e12eab98d43778283abfeaa2fa01b2fcf5 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Thu, 5 Apr 2018 20:08:39 -0400 Subject: [PATCH] simple compute shader pipeline --- Tetrahedrons/Gl4Window.cs | 202 ++++++++++++++++++---------- Tetrahedrons/Shaders/intersect.comp | 24 ++++ Tetrahedrons/Shaders/simple.frag | 9 +- Tetrahedrons/Shaders/simple.vert | 16 ++- Tetrahedrons/Tetrahedrons.csproj | 3 + 5 files changed, 176 insertions(+), 78 deletions(-) create mode 100644 Tetrahedrons/Shaders/intersect.comp diff --git a/Tetrahedrons/Gl4Window.cs b/Tetrahedrons/Gl4Window.cs index 838b188..77bfc89 100644 --- a/Tetrahedrons/Gl4Window.cs +++ b/Tetrahedrons/Gl4Window.cs @@ -6,96 +6,160 @@ using OpenTK.Graphics.OpenGL; namespace Tetrahedrons { - internal class Gl4Window : GameWindow - { - private int _pgm; + internal class Gl4Window : GameWindow + { + private float _t; - private int _shVs; - private int _shFs; + private int _pgmRend; - private int _bufVerts; - private int _bufInds; + private int _shVert; + private int _shFrag; - private Vector4[] _datVerts; - private int[] _datInds; + private int _bufInVerts; + private int _bufInInds; + private int _bufMats; - protected override void OnLoad(EventArgs e) - { - base.OnLoad(e); + private Vector4[] _datVerts; + private int[] _datInds; + private Matrix4[] _datMats; - X = (DisplayDevice.Default.Width - Width) / 2; - Y = (DisplayDevice.Default.Height - Height) / 2; + private int _bufOutVerts; + private int _shComp; + private int _pgmComp; - _pgm = GL.CreateProgram(); + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); - _shVs = GL.CreateShader(ShaderType.VertexShader); - GL.ShaderSource(_shVs, File.ReadAllText("Shaders/simple.vert")); - GL.CompileShader(_shVs); - GL.AttachShader(_pgm, _shVs); - Console.WriteLine(GL.GetShaderInfoLog(_shVs)); + X = (DisplayDevice.Default.Width - Width) / 2; + Y = (DisplayDevice.Default.Height - Height) / 2; - _shFs = GL.CreateShader(ShaderType.FragmentShader); - GL.ShaderSource(_shFs, File.ReadAllText("Shaders/simple.frag")); - GL.CompileShader(_shFs); - GL.AttachShader(_pgm, _shFs); - Console.WriteLine(GL.GetShaderInfoLog(_shFs)); + #region Shaders - GL.LinkProgram(_pgm); - Console.WriteLine(GL.GetProgramInfoLog(_pgm)); + _pgmRend = GL.CreateProgram(); - _bufVerts = GL.GenBuffer(); - _bufInds = GL.GenBuffer(); + _shVert = GL.CreateShader(ShaderType.VertexShader); + GL.ShaderSource(_shVert, File.ReadAllText("Shaders/simple.vert")); + GL.CompileShader(_shVert); + GL.AttachShader(_pgmRend, _shVert); + Console.WriteLine(GL.GetShaderInfoLog(_shVert)); - _datVerts = new[] - { - new Vector4(+1, -1, -1, -1) / 2, - new Vector4(-1, +1, -1, -1) / 2, - new Vector4(-1, -1, +1, -1) / 2, - new Vector4(-1, -1, -1, +1) / 2, - new Vector4(+1, +1, +1, +1) / 2 - }; + _shFrag = GL.CreateShader(ShaderType.FragmentShader); + GL.ShaderSource(_shFrag, File.ReadAllText("Shaders/simple.frag")); + GL.CompileShader(_shFrag); + GL.AttachShader(_pgmRend, _shFrag); + Console.WriteLine(GL.GetShaderInfoLog(_shFrag)); - _datInds = new[] - { - 0, 1, 2, - 0, 1, 3, - 0, 2, 3, - 1, 2, 3 - }; - } + GL.LinkProgram(_pgmRend); + Console.WriteLine(GL.GetProgramInfoLog(_pgmRend)); - protected override void OnRenderFrame(FrameEventArgs e) - { - base.OnRenderFrame(e); - GL.Viewport(0, 0, Width, Height); - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - GL.Enable(EnableCap.DepthTest); + _pgmComp = GL.CreateProgram(); - GL.EnableVertexAttribArray(0); + _shComp = GL.CreateShader(ShaderType.ComputeShader); + GL.ShaderSource(_shComp, File.ReadAllText("Shaders/intersect.comp")); + GL.CompileShader(_shComp); + GL.AttachShader(_pgmComp, _shComp); + Console.Out.WriteLine(GL.GetShaderInfoLog(_shComp)); - GL.DrawElements(BeginMode.Triangles, _datInds.Length, DrawElementsType.UnsignedInt, 0); + GL.LinkProgram(_pgmComp); + Console.Out.WriteLine(GL.GetProgramInfoLog(_pgmComp)); - GL.DisableVertexAttribArray(0); + #endregion - GL.Flush(); - SwapBuffers(); - } + _datVerts = new[] + { + new Vector4(+1, -1, -1, -1) / 2, + new Vector4(-1, +1, -1, -1) / 2, + new Vector4(-1, -1, +1, -1) / 2, + new Vector4(-1, -1, -1, +1) / 2, + new Vector4(+1, +1, +1, +1) / 2, + }; - protected override void OnUpdateFrame(FrameEventArgs e) - { - base.OnUpdateFrame(e); + _datInds = new[] + { + 0, 1, + 0, 2, + 0, 3, + 0, 4, + 1, 2, + 1, 3, + 1, 4, + 2, 3, + 2, 4, + 3, 4, + }; - GL.BindBuffer(BufferTarget.ArrayBuffer, _bufVerts); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (_datVerts.Length * Vector4.SizeInBytes), _datVerts, BufferUsageHint.StaticDraw); - GL.VertexAttribPointer(0, 4, VertexAttribPointerType.Float, false, 0, 0); + _datMats = new Matrix4[3]; - GL.UseProgram(_pgm); + _bufInVerts = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufInVerts); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_datVerts.Length * Vector4.SizeInBytes), _datVerts, BufferUsageHint.StaticDraw); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + _bufInInds = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufInInds); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_datInds.Length * sizeof(int)), _datInds, BufferUsageHint.StaticDraw); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); - GL.BindBuffer(BufferTarget.ElementArrayBuffer, _bufInds); - GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr) (_datInds.Length * sizeof(int)), _datInds, BufferUsageHint.StaticDraw); - } - } + _bufOutVerts = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufOutVerts); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_datVerts.Length * Vector4.SizeInBytes), IntPtr.Zero, BufferUsageHint.StaticDraw); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); + + _bufMats = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufMats); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_datMats.Length * 4 * Vector4.SizeInBytes), _datMats, BufferUsageHint.StaticDraw); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); + + GL.BindBuffer(BufferTarget.ArrayBuffer, _bufOutVerts); + GL.VertexAttribPointer(0, 4, VertexAttribPointerType.Float, false, 0, 0); + GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + + GL.UniformBlockBinding(_pgmRend, 0, 0); + } + + + protected override void OnRenderFrame(FrameEventArgs e) + { + base.OnRenderFrame(e); + GL.Viewport(0, 0, Width, Height); + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + GL.Enable(EnableCap.DepthTest); + + GL.UseProgram(_pgmComp); + GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, _bufInVerts); + GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, _bufOutVerts); + GL.DispatchCompute(_datVerts.Length, 1, 1); + GL.MemoryBarrier(MemoryBarrierFlags.ShaderStorageBarrierBit); + + GL.UseProgram(_pgmRend); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, _bufInInds); + GL.Enable(EnableCap.DepthTest); + GL.EnableVertexAttribArray(0); + GL.DrawElements(BeginMode.Lines, _datInds.Length, DrawElementsType.UnsignedInt, 0); + GL.DisableVertexAttribArray(0); + GL.Disable(EnableCap.DepthTest); + + GL.Flush(); + SwapBuffers(); + } + + protected override void OnUpdateFrame(FrameEventArgs e) + { + base.OnUpdateFrame(e); + _t += (float) e.Time; + + float w = 3; + _datMats[0] = Matrix4.Identity; + _datMats[1] = Matrix4.CreateOrthographic(w, w * Height / Width, -w, w); + _datMats[2] = Matrix4.LookAt(Vector3.Zero, -new Vector3(1, -1, 1), Vector3.UnitZ); + + _bufMats = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.UniformBuffer, _bufMats); + GL.BufferData(BufferTarget.UniformBuffer, (IntPtr) (_datMats.Length * 4 * Vector4.SizeInBytes), _datMats, BufferUsageHint.StaticDraw); + GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, _bufMats); + GL.BindBuffer(BufferTarget.UniformBuffer, 0); + } + } } \ No newline at end of file diff --git a/Tetrahedrons/Shaders/intersect.comp b/Tetrahedrons/Shaders/intersect.comp new file mode 100644 index 0000000..ce73d1c --- /dev/null +++ b/Tetrahedrons/Shaders/intersect.comp @@ -0,0 +1,24 @@ +#version 430 compatibility +#extension GL_ARB_compute_shader: enable +#extension GL_ARB_shader_storage_buffer_object: enable + +layout(std140, binding=1) buffer bufIn +{ + vec4 inVerts[]; +}; + +layout(std140, binding=2) buffer bufOut +{ + vec4 outVerts[]; +}; + +layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in; + +void main() { + uint n = gl_GlobalInvocationID.x; + + for(int i = 0; i < n; i++) + { + outVerts[i] = inVerts[i]; + } +} diff --git a/Tetrahedrons/Shaders/simple.frag b/Tetrahedrons/Shaders/simple.frag index 9d7cb73..d90c9f3 100644 --- a/Tetrahedrons/Shaders/simple.frag +++ b/Tetrahedrons/Shaders/simple.frag @@ -1,9 +1,6 @@ -#version 330 +in float w; -out vec4 outputColor; - -void -main() +void main() { - outputColor = vec4(1); + gl_FragColor = vec4(w, 0, 1 - w, 1); } diff --git a/Tetrahedrons/Shaders/simple.vert b/Tetrahedrons/Shaders/simple.vert index 217416d..774ed66 100644 --- a/Tetrahedrons/Shaders/simple.vert +++ b/Tetrahedrons/Shaders/simple.vert @@ -1,8 +1,18 @@ -#version 330 +#version 430 compatibility -in vec3 vPosition; +layout(row_major) uniform Matrices +{ + mat4 model; + mat4 proj; + mat4 view; +}; + +in vec4 pos; + +out float w; void main() { - gl_Position = vec4(vPosition.xyz, 1); + gl_Position = vec4(pos.xyz, 1) * model * view * proj; + w = (1 + pos.w) / 2; } \ No newline at end of file diff --git a/Tetrahedrons/Tetrahedrons.csproj b/Tetrahedrons/Tetrahedrons.csproj index 1d79c3e..be3fc4d 100644 --- a/Tetrahedrons/Tetrahedrons.csproj +++ b/Tetrahedrons/Tetrahedrons.csproj @@ -55,6 +55,9 @@ + + Always + Always