working compute shader - faulty face gen in 6-vertex case
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
in float w;
|
||||
in vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(w, 0, 1 - w, 1);
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user