working compute shader - faulty face gen in 6-vertex case

This commit is contained in:
2018-04-06 03:01:07 -04:00
parent dd1fc7e12e
commit edb2985a98
4 changed files with 187 additions and 64 deletions

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -1,6 +1,6 @@
in float w;
in vec4 color;
void main()
{
gl_FragColor = vec4(w, 0, 1 - w, 1);
gl_FragColor = color;
}

View File

@@ -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);
}