From edb2985a989d60226a590960a194e537a97e4483 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Fri, 6 Apr 2018 03:01:07 -0400 Subject: [PATCH] working compute shader - faulty face gen in 6-vertex case --- Tetrahedrons/Gl4Window.cs | 157 +++++++++++++++++++--------- Tetrahedrons/Shaders/intersect.comp | 84 +++++++++++++-- Tetrahedrons/Shaders/simple.frag | 4 +- Tetrahedrons/Shaders/simple.vert | 6 +- 4 files changed, 187 insertions(+), 64 deletions(-) diff --git a/Tetrahedrons/Gl4Window.cs b/Tetrahedrons/Gl4Window.cs index 77bfc89..2693609 100644 --- a/Tetrahedrons/Gl4Window.cs +++ b/Tetrahedrons/Gl4Window.cs @@ -1,11 +1,33 @@ using System; using System.Drawing; using System.IO; +using System.Runtime.InteropServices; +using System.Security.Cryptography; using OpenTK; using OpenTK.Graphics.OpenGL; +using OpenTK.Platform.Windows; namespace Tetrahedrons { + struct MatrixBlock + { + public Matrix4 Model; + public Matrix4 View; + public Matrix4 Projection; + + public static MatrixBlock Identity => new MatrixBlock() {Model = Matrix4.Identity, View = Matrix4.Identity, Projection = Matrix4.Identity}; + public static readonly int SizeInBytes = Marshal.SizeOf(typeof(MatrixBlock)); + } + + struct TransformMats + { + public Matrix4 Rotate; + public Vector4 Pivot; + + public static TransformMats Identity => new TransformMats() {Rotate = Matrix4.Identity, Pivot = Vector4.Zero}; + public static readonly int SizeInBytes = Marshal.SizeOf(typeof(TransformMats)); + } + internal class Gl4Window : GameWindow { private float _t; @@ -15,18 +37,29 @@ namespace Tetrahedrons private int _shVert; private int _shFrag; - private int _bufInVerts; - private int _bufInInds; - private int _bufMats; + private int _bufPentVerts; + private int _bufPentInds; + private int _bufUniform; + private int _bufPenMats; - private Vector4[] _datVerts; - private int[] _datInds; - private Matrix4[] _datMats; + private Vector4[] _datPentVerts; + private uint[] _datPentInds; + + private MatrixBlock _datMats; + private TransformMats _datPenMats; + + private int _bufHullVerts; + private int _bufHullInds; - private int _bufOutVerts; private int _shComp; private int _pgmComp; + private int _hullIndsCount; + private int _hullVertsCount; + private int _penIndsCount; + private int _penVertsCount; + private int _invocationCount; + protected override void OnLoad(EventArgs e) { base.OnLoad(e); @@ -67,54 +100,61 @@ namespace Tetrahedrons #endregion - _datVerts = new[] + _datPentVerts = 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, new Vector4(+1, +1, +1, +1) / 2, }; - - _datInds = new[] + _datPentInds = new uint[] { - 0, 1, - 0, 2, - 0, 3, - 0, 4, - 1, 2, - 1, 3, - 1, 4, - 2, 3, - 2, 4, - 3, 4, + 0, 1, 2, 3, 4, +// 0, 1, 2, 3, 5, }; - _datMats = new Matrix4[3]; + _datMats = MatrixBlock.Identity; + _datPenMats = TransformMats.Identity; - _bufInVerts = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufInVerts); - GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_datVerts.Length * Vector4.SizeInBytes), _datVerts, BufferUsageHint.StaticDraw); + _penVertsCount = _datPentVerts.Length; + _penIndsCount = _datPentInds.Length; + + _invocationCount = _penIndsCount / 5; + + _hullVertsCount = _invocationCount * 6; // 6 hull verts per pent + _hullIndsCount = _invocationCount * 24; // 24 hull inds per pent + Console.Out.WriteLine("_hullIndsCount = {0}", _hullIndsCount); + + _bufPentVerts = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufPentVerts); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_penVertsCount * Vector4.SizeInBytes), _datPentVerts, BufferUsageHint.DynamicDraw); GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); - _bufInInds = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufInInds); - GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_datInds.Length * sizeof(int)), _datInds, BufferUsageHint.StaticDraw); + _bufPentInds = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufPentInds); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_penIndsCount * sizeof(int)), _datPentInds, BufferUsageHint.DynamicDraw); GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); - _bufOutVerts = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufOutVerts); - GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_datVerts.Length * Vector4.SizeInBytes), IntPtr.Zero, BufferUsageHint.StaticDraw); + _bufHullVerts = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufHullVerts); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_hullVertsCount * Vector4.SizeInBytes), IntPtr.Zero, BufferUsageHint.DynamicDraw); 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); + _bufHullInds = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufHullInds); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_hullIndsCount * sizeof(int)), IntPtr.Zero, BufferUsageHint.DynamicDraw); GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); - GL.BindBuffer(BufferTarget.ArrayBuffer, _bufOutVerts); - GL.VertexAttribPointer(0, 4, VertexAttribPointerType.Float, false, 0, 0); - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + _bufUniform = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufUniform); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) MatrixBlock.SizeInBytes, ref _datMats, BufferUsageHint.DynamicDraw); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); + + _bufPenMats = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufPenMats); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) MatrixBlock.SizeInBytes, ref _datPenMats, BufferUsageHint.DynamicDraw); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); GL.UniformBlockBinding(_pgmRend, 0, 0); } @@ -128,16 +168,22 @@ namespace Tetrahedrons 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.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, _bufPentVerts); + GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, _bufPentInds); + GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 3, _bufHullVerts); + GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 4, _bufHullInds); + GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 5, _bufPenMats); + GL.DispatchCompute(_invocationCount, 1, 1); GL.MemoryBarrier(MemoryBarrierFlags.ShaderStorageBarrierBit); GL.UseProgram(_pgmRend); - GL.BindBuffer(BufferTarget.ElementArrayBuffer, _bufInInds); + GL.BindBuffer(BufferTarget.ElementArrayBuffer, _bufHullInds); + GL.BindBuffer(BufferTarget.ArrayBuffer, _bufHullVerts); + GL.VertexAttribPointer(0, 4, VertexAttribPointerType.Float, false, 0, 0); + GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.Enable(EnableCap.DepthTest); GL.EnableVertexAttribArray(0); - GL.DrawElements(BeginMode.Lines, _datInds.Length, DrawElementsType.UnsignedInt, 0); + GL.DrawElements(BeginMode.Triangles, _hullIndsCount, DrawElementsType.UnsignedInt, 0); GL.DisableVertexAttribArray(0); GL.Disable(EnableCap.DepthTest); @@ -151,15 +197,28 @@ namespace Tetrahedrons _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); + _datMats.Projection = Matrix4.CreateOrthographic(w, w * Height / Width, -w, w); + _datMats.View = Matrix4.LookAt(Vector3.Zero, -new Vector3(1, -1, 1), Vector3.UnitZ); + _datMats.Model = Matrix4.CreateRotationZ(_t / 10); + + _bufUniform = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.UniformBuffer, _bufUniform); + GL.BufferData(BufferTarget.UniformBuffer, (IntPtr) MatrixBlock.SizeInBytes, ref _datMats, BufferUsageHint.StaticDraw); + GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, _bufUniform); GL.BindBuffer(BufferTarget.UniformBuffer, 0); + + _datPenMats.Pivot.W = (float) (Math.Sin(_t) * .6); + _datPenMats.Rotate = new Matrix4( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, (float)Math.Sin(_t/2), (float)-Math.Cos(_t/2), + 0, 0, (float)Math.Cos(_t/2), (float)Math.Sin(_t/2)); + + _bufPenMats = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufPenMats); + GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) MatrixBlock.SizeInBytes, ref _datPenMats, BufferUsageHint.DynamicDraw); + GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0); } } } \ No newline at end of file diff --git a/Tetrahedrons/Shaders/intersect.comp b/Tetrahedrons/Shaders/intersect.comp index ce73d1c..51a067c 100644 --- a/Tetrahedrons/Shaders/intersect.comp +++ b/Tetrahedrons/Shaders/intersect.comp @@ -1,24 +1,88 @@ -#version 430 compatibility -#extension GL_ARB_compute_shader: enable -#extension GL_ARB_shader_storage_buffer_object: enable +#version 430 -layout(std140, binding=1) buffer bufIn +layout(std430, binding=1) buffer PentVerts { - vec4 inVerts[]; + vec4 pentVerts[]; }; -layout(std140, binding=2) buffer bufOut +layout(std430, binding=2) buffer PentInds { - vec4 outVerts[]; + uint pentInds[]; +}; + +layout(std430, binding=3) buffer HullVerts +{ + vec4 hullVerts[]; +}; + +layout(std430, binding=4) buffer HullInds +{ + uint hullInds[]; +}; + +layout(std430, binding=5) buffer Transform +{ + mat4 rotate; + vec4 pivot; }; layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in; void main() { - uint n = gl_GlobalInvocationID.x; + uint pentInd0 = gl_GlobalInvocationID.x * 5; + uint hullVrt0 = gl_GlobalInvocationID.x * 6; + uint hullInd0 = gl_GlobalInvocationID.x * 24; - for(int i = 0; i < n; i++) + int k = 0; + for(int i = 0; i < 5; i++) + for(int j = i + 1; j < 5; j++) { - outVerts[i] = inVerts[i]; + vec4 a = (pentVerts[pentInds[pentInd0 + i]] - pivot) * rotate; + vec4 b = (pentVerts[pentInds[pentInd0 + j]] - pivot) * rotate; + + if (a.w * b.w < 0) // different sides + { + float alph = a.w / (a.w - b.w); + vec4 p = a + alph * (b - a); + hullVerts[hullVrt0 + k++] = p + pivot; + } + } + + for (int i = 0; i < 24; i++) + hullInds[hullInd0 + i] = 0; + + int v = 0; + + if (k == 4) + { + for(int i = 0; i < 4; i++) + for(int j = i + 1; j < 4; j++) + for(int k = j + 1; k < 4; k++) + { + hullInds[hullInd0 + v++] = hullVrt0 + i; + hullInds[hullInd0 + v++] = hullVrt0 + j; + hullInds[hullInd0 + v++] = hullVrt0 + k; + } + } + else if (k == 6) + { + for (int i = 0; i < 6; i++) + hullInds[hullInd0 + v++] = hullVrt0 + i; + + for (int i = 0; i < 3; i++) + { + int a = i; + int b = (1 + i) % 3; + int c = 3 + i; + int d = 3 + (1 + i) % 3; + + hullInds[hullInd0 + v++] = hullVrt0 + c; + hullInds[hullInd0 + v++] = hullVrt0 + a; + hullInds[hullInd0 + v++] = hullVrt0 + b; + hullInds[hullInd0 + v++] = hullVrt0 + b; + hullInds[hullInd0 + v++] = hullVrt0 + d; + hullInds[hullInd0 + v++] = hullVrt0 + c; + + } } } diff --git a/Tetrahedrons/Shaders/simple.frag b/Tetrahedrons/Shaders/simple.frag index d90c9f3..dd56410 100644 --- a/Tetrahedrons/Shaders/simple.frag +++ b/Tetrahedrons/Shaders/simple.frag @@ -1,6 +1,6 @@ -in float w; +in vec4 color; void main() { - gl_FragColor = vec4(w, 0, 1 - w, 1); + gl_FragColor = color; } diff --git a/Tetrahedrons/Shaders/simple.vert b/Tetrahedrons/Shaders/simple.vert index 774ed66..f54c4a3 100644 --- a/Tetrahedrons/Shaders/simple.vert +++ b/Tetrahedrons/Shaders/simple.vert @@ -3,16 +3,16 @@ layout(row_major) uniform Matrices { mat4 model; - mat4 proj; mat4 view; + mat4 proj; }; in vec4 pos; -out float w; +out vec4 color; void main() { gl_Position = vec4(pos.xyz, 1) * model * view * proj; - w = (1 + pos.w) / 2; + color = vec4(gl_Position.xyz + vec3(.5), 1); } \ No newline at end of file