outlines and intersections of tetrahedral primitives

This commit is contained in:
2018-04-10 16:59:05 -04:00
parent f3bfaf021e
commit 2212fb762e
2 changed files with 164 additions and 46 deletions

View File

@@ -3,6 +3,7 @@ using System.Data.Common;
using System.Drawing; using System.Drawing;
using OpenTK; using OpenTK;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
using Platformer.Util; using Platformer.Util;
using BeginMode = OpenTK.Graphics.OpenGL4.BeginMode; using BeginMode = OpenTK.Graphics.OpenGL4.BeginMode;
using BufferRangeTarget = OpenTK.Graphics.OpenGL4.BufferRangeTarget; using BufferRangeTarget = OpenTK.Graphics.OpenGL4.BufferRangeTarget;
@@ -32,29 +33,30 @@ namespace Platformer
public class PlatformWindow : GameWindow public class PlatformWindow : GameWindow
{ {
private Program _render;
private Buffer<Vector4> _tVerts;
private Buffer<uint> _tFaces;
private Buffer<uint> _tEdges;
private Buffer<ViewMats> _viewBuf; private Buffer<ViewMats> _viewBuf;
private Buffer<PlaneMats> _tformBuf; private Buffer<PlaneMats> _tformBuf;
private VertexArray _tetraVao;
private ViewMats _view; private ViewMats _view;
private PlaneMats _tform; private PlaneMats _tform;
private Buffer<uint> _tInds; private Program _render;
private Buffer<Vector4> _pVerts;
private Program _compute; private Program _compute;
private Buffer<uint> _pEdges; private Buffer<Vector4> _tVerts;
private Buffer<uint> _pAreas; private Buffer<uint> _tInds;
private VertexArray _tetraVao;
private VertexArray _polyVao; private VertexArray _polyVao;
private Buffer<Vector4> _pVerts;
private Buffer<uint> _pEdges;
private Buffer<uint> _pFaces;
private Buffer<uint> _tEdges;
private Buffer<uint> _tFaces;
private int _tetraCount;
protected override void OnLoad(EventArgs e) protected override void OnLoad(EventArgs e)
{ {
base.OnLoad(e); base.OnLoad(e);
@@ -69,25 +71,55 @@ namespace Platformer
var comp = Shader.Compile("shaders/intersect.comp"); var comp = Shader.Compile("shaders/intersect.comp");
_compute = Program.Link(comp); _compute = Program.Link(comp);
_tFaces = Buffer<uint>.FromData(new uint[] {0, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 3}); // _tVerts = Buffer<Vector4>.FromData(new[]
_tEdges = Buffer<uint>.FromData(new uint[] {0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3}); // {
// new Vector4(-.5f - 1, -.5f, -.5f, 1),
// new Vector4(+.5f - 1, +.5f, -.5f, 1),
// new Vector4(+.5f - 1, -.5f, +.5f, 1),
// new Vector4(-.5f - 1, +.5f, +.5f, 1),
//
// new Vector4(-.5f + 1, -.5f, -.5f, 1),
// new Vector4(+.5f + 1, +.5f, -.5f, 1),
// new Vector4(+.5f + 1, -.5f, +.5f, 1),
// new Vector4(-.5f + 1, +.5f, +.5f, 1),
// });
//
// _tInds = Buffer<uint>.FromData(new uint[]
// {
// 0, 1, 2, 3,
// 4, 5, 6, 7,
// 0, 1, 6, 7,
// });
_tVerts = Buffer<Vector4>.FromData(new[] _tVerts = Buffer<Vector4>.FromData(new[]
{ {
new Vector4(-.5f - 1, -.5f, -.5f, 1), new Vector4(-1, -1, -1, 1),
new Vector4(+.5f - 1, +.5f, -.5f, 1), new Vector4(-1, -1, +1, 1),
new Vector4(+.5f - 1, -.5f, +.5f, 1), new Vector4(-1, +1, -1, 1),
new Vector4(-.5f - 1, +.5f, +.5f, 1), new Vector4(-1, +1, +1, 1),
new Vector4(+1, -1, -1, 1),
new Vector4(-.5f + 1, -.5f, -.5f, 1), new Vector4(+1, -1, +1, 1),
new Vector4(+.5f + 1, +.5f, -.5f, 1), new Vector4(+1, +1, -1, 1),
new Vector4(+.5f + 1, -.5f, +.5f, 1), new Vector4(+1, +1, +1, 1),
new Vector4(-.5f + 1, +.5f, +.5f, 1),
}); });
_tInds = Buffer<uint>.FromData(new uint[] {0, 1, 2, 3}); _tInds = Buffer<uint>.FromData(new uint[]
_pVerts = new Buffer<Vector4>(_tInds.Count / 4 * 4); {
_pEdges = new Buffer<uint>(_tInds.Count / 4 * 8); 0, 3, 5, 6,
_pAreas = new Buffer<uint>(_tInds.Count / 4 * 6); 0, 3, 2, 6,
0, 3, 1, 5,
3, 7, 5, 6,
0, 4, 5, 6,
});
_tetraCount = _tInds.Count / 4;
_pVerts = new Buffer<Vector4>(_tetraCount * 4);
_pEdges = new Buffer<uint>(_tetraCount * 8);
_pFaces = new Buffer<uint>(_tetraCount * 6);
_tEdges = new Buffer<uint>(_tetraCount * 12);
_tFaces = new Buffer<uint>(_tetraCount * 12);
_viewBuf = new Buffer<ViewMats>(); _viewBuf = new Buffer<ViewMats>();
_view = ViewMats.Identity; _view = ViewMats.Identity;
@@ -119,22 +151,31 @@ namespace Platformer
GL.UseProgram(_render); GL.UseProgram(_render);
GL.BindVertexArray(_tetraVao); GL.BindVertexArray(_tetraVao);
GL.Disable(EnableCap.DepthTest);
GL.Enable(EnableCap.DepthTest);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _tEdges);
GL.Uniform3(_render.UnifLoc("color"), 0f, 0, 0);
GL.DrawElements(BeginMode.Lines, _tEdges.Count, DrawElementsType.UnsignedInt, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _tFaces); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _tFaces);
GL.Uniform3(_render.UnifLoc("color"), 1f, 1, 1); GL.Uniform3(_render.UnifLoc("color"), 1f, 1, 1);
GL.DrawElements(BeginMode.Triangles, _tEdges.Count, DrawElementsType.UnsignedInt, 0); GL.DrawElements(BeginMode.Triangles, _tEdges.Count, DrawElementsType.UnsignedInt, 0);
GL.Disable(EnableCap.DepthTest);
GL.BindVertexArray(_polyVao); GL.BindVertexArray(_polyVao);
GL.Enable(EnableCap.DepthTest);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _pFaces);
GL.Uniform3(_render.UnifLoc("color"), .8f, .8f, .9f);
GL.DrawElements(BeginMode.Triangles, _pFaces.Count, DrawElementsType.UnsignedInt, 0);
GL.BindVertexArray(_polyVao);
GL.Disable(EnableCap.DepthTest);
GL.LineWidth(5f);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _pEdges); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _pEdges);
GL.Uniform3(_render.UnifLoc("color"), .1f, .1f, .6f); GL.Uniform3(_render.UnifLoc("color"), .1f, .1f, .6f);
GL.DrawElements(BeginMode.Lines, _pEdges.Count, DrawElementsType.UnsignedInt, 0); GL.DrawElements(BeginMode.Lines, _pEdges.Count, DrawElementsType.UnsignedInt, 0);
GL.BindVertexArray(_tetraVao);
GL.Enable(EnableCap.DepthTest);
GL.LineWidth(2f);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _tEdges);
GL.Uniform3(_render.UnifLoc("color"), 0f, 0, 0);
GL.DrawElements(BeginMode.Lines, _tEdges.Count, DrawElementsType.UnsignedInt, 0);
GL.Flush(); GL.Flush();
SwapBuffers(); SwapBuffers();
@@ -144,19 +185,36 @@ namespace Platformer
{ {
base.OnUpdateFrame(e); base.OnUpdateFrame(e);
var dv = Matrix4.Identity;
if (Keyboard[Key.A]) dv *= Matrix4.CreateRotationZ((float) e.Time);
if (Keyboard[Key.D]) dv *= Matrix4.CreateRotationZ(-(float) e.Time);
if (Keyboard[Key.W]) dv *= Matrix4.CreateRotationY((float) e.Time);
if (Keyboard[Key.S]) dv *= Matrix4.CreateRotationY(-(float) e.Time);
_view.Proj = Matrix4.CreateOrthographic(5, 5f * Height / Width, -2.5f, 2.5f); _view.Proj = Matrix4.CreateOrthographic(5, 5f * Height / Width, -2.5f, 2.5f);
_view.View = Matrix4.LookAt(Vector3.Zero, -Vector3.One, Vector3.UnitZ); // _view.View = Matrix4.LookAt(Vector3.Zero, -Vector3.One, Vector3.UnitZ);
_tform.Tform = _view.Model *= Matrix4.CreateRotationZ((float) e.Time); _view.View = Matrix4.LookAt(Vector3.Zero, Vector3.UnitX, Vector3.UnitZ);
// _tform.Tform *= Matrix4.CreateRotationZ((float) e.Time) * Matrix4.CreateRotationX((float) e.Time / 1.7f);
_view.Model = _tform.Tform *= dv;
_viewBuf.SetData(ref _view); _viewBuf.SetData(ref _view);
_tformBuf.SetData(ref _tform); _tformBuf.SetData(ref _tform);
GL.UseProgram(_compute); GL.UseProgram(_compute);
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, _tVerts); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, _tVerts);
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, _tInds); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, _tInds);
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, _pVerts); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, _pVerts);
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 3, _pEdges); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 3, _pEdges);
GL.DispatchCompute(_tInds.Count / 4, 1, 1); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 4, _pFaces);
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 5, _tEdges);
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 6, _tFaces);
GL.DispatchCompute(_tetraCount, 1, 1);
} }
} }
} }

View File

@@ -20,6 +20,21 @@ layout(std430, binding=3) buffer PolyEdges
uint polyEdges[]; uint polyEdges[];
}; };
layout(std430, binding=4) buffer PolyFaces
{
uint polyFaces[];
};
layout(std430, binding=5) buffer TetraEdges
{
uint tetrEdges[];
};
layout(std430, binding=6) buffer TetraFaces
{
uint tetrFaces[];
};
uniform PlaneMats uniform PlaneMats
{ {
mat4 tform; mat4 tform;
@@ -30,10 +45,20 @@ layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
void main () { void main () {
int ti0 = int(gl_GlobalInvocationID.x * 4); int ti0 = int(gl_GlobalInvocationID.x * 4);
int pv0 = int(gl_GlobalInvocationID.x * 4); int pv0 = int(gl_GlobalInvocationID.x * 4);
int pe0 = int(gl_GlobalInvocationID.x * 8);
int ii = 0; int pe0 = int(gl_GlobalInvocationID.x * 8);
int vv = 0; int pf0 = int(gl_GlobalInvocationID.x * 6);
int te0 = int(gl_GlobalInvocationID.x * 12);
int tf0 = int(gl_GlobalInvocationID.x * 12);
int pvi = 0;
int pei = 0;
int pfi = 0;
int tei = 0;
int tfi = 0;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
for (int j = i + 1; j < 4; j++) for (int j = i + 1; j < 4; j++)
@@ -47,16 +72,51 @@ void main () {
if (a_.x * b_.x < 0) if (a_.x * b_.x < 0)
{ {
vec4 p = (b-a) / (a_.x - b_.x) * b_.x + b; vec4 p = (b-a) / (a_.x - b_.x) * b_.x + b;
polyVerts[pv0 + vv++] = p; polyVerts[pv0 + pvi++] = p;
} }
} }
for (int i = 0; i < vv; i++) polyEdges[pe0 + pei++] = pv0 + 0;
polyEdges[pe0 + pei++] = pv0 + 1;
polyEdges[pe0 + pei++] = pv0 + 1;
if (pvi == 4)
{ {
polyEdges[pe0 + ii++] = pv0 + i; polyEdges[pe0 + pei++] = pv0 + 3;
polyEdges[pe0 + ii++] = pv0 + (i + 1) % vv; polyEdges[pe0 + pei++] = pv0 + 3;
}
polyEdges[pe0 + pei++] = pv0 + 2;
polyEdges[pe0 + pei++] = pv0 + 2;
polyEdges[pe0 + pei++] = pv0 + 0;
polyFaces[pf0 + pfi++] = pv0 + 0;
polyFaces[pf0 + pfi++] = pv0 + 1;
polyFaces[pf0 + pfi++] = pv0 + 2;
if (pvi == 4)
{
polyFaces[pf0 + pfi++] = pv0 + 1;
polyFaces[pf0 + pfi++] = pv0 + 2;
polyFaces[pf0 + pfi++] = pv0 + 3;
} }
while (vv < 4) polyVerts[pv0 + vv++] = vec4(0); for (int i = 0; i < 4; i++)
while (ii < 8) polyEdges[pe0 + ii++] = 0; for (int j = i + 1; j < 4; j++)
for (int k = j + 1; k < 4; k++)
{
tetrFaces[tf0 + tfi++] = tetraInds[ti0 + i];
tetrFaces[tf0 + tfi++] = tetraInds[ti0 + j];
tetrFaces[tf0 + tfi++] = tetraInds[ti0 + k];
}
for (int i = 0; i < 4; i++)
for (int j = i + 1; j < 4; j++)
{
tetrEdges[tf0 + tei++] = tetraInds[ti0 + i];
tetrEdges[tf0 + tei++] = tetraInds[ti0 + j];
}
while (pvi < 4) polyVerts[pv0 + pvi++] = vec4(0);
while (pei < 8) polyEdges[pe0 + pei++] = 0;
while (pfi < 6) polyFaces[pf0 + pfi++] = 0;
while (tei < 8) polyEdges[te0 + tei++] = 0;
while (tfi < 6) polyFaces[tf0 + tfi++] = 0;
} }