starting compute shader for tetrahedron intersections
This commit is contained in:
@@ -1,74 +1,142 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using Platformer.Util;
|
||||
using Buffer = Platformer.Util.Buffer;
|
||||
using BeginMode = OpenTK.Graphics.OpenGL4.BeginMode;
|
||||
using BufferRangeTarget = OpenTK.Graphics.OpenGL4.BufferRangeTarget;
|
||||
using BufferTarget = OpenTK.Graphics.OpenGL4.BufferTarget;
|
||||
using ClearBufferMask = OpenTK.Graphics.OpenGL4.ClearBufferMask;
|
||||
using DrawElementsType = OpenTK.Graphics.OpenGL4.DrawElementsType;
|
||||
using EnableCap = OpenTK.Graphics.OpenGL4.EnableCap;
|
||||
using GL = OpenTK.Graphics.OpenGL4.GL;
|
||||
|
||||
namespace Platformer
|
||||
{
|
||||
public class PlatformWindow : GameWindow
|
||||
{
|
||||
private Program _render;
|
||||
public struct ViewMats
|
||||
{
|
||||
public Matrix4 Model;
|
||||
public Matrix4 View;
|
||||
public Matrix4 Proj;
|
||||
|
||||
private Buffer _vbo;
|
||||
private Buffer _ibo;
|
||||
public static ViewMats Identity => new ViewMats {Model = Matrix4.Identity, View = Matrix4.Identity};
|
||||
}
|
||||
|
||||
private Vector4[] _verts;
|
||||
private uint[] _inds;
|
||||
private VertexArray _vao;
|
||||
public class PlatformWindow : GameWindow
|
||||
{
|
||||
private Program _render;
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
private Buffer<Vector4> _tVerts;
|
||||
private Buffer<uint> _tFaces;
|
||||
private Buffer<uint> _tEdges;
|
||||
private Buffer<ViewMats> _ubo;
|
||||
|
||||
_verts = new[]
|
||||
{
|
||||
new Vector4(-.5f, -.5f, +0, +1),
|
||||
new Vector4(-.5f, +.5f, +0, +1),
|
||||
new Vector4(+.5f, -.5f, +0, +1),
|
||||
new Vector4(+.5f, +.5f, +0, +1),
|
||||
};
|
||||
private VertexArray _tetraVao;
|
||||
|
||||
_inds = new uint[]
|
||||
{
|
||||
0, 1, 2,
|
||||
};
|
||||
private ViewMats _view;
|
||||
private Buffer<uint> _tInds;
|
||||
private Buffer<Vector4> _pVerts;
|
||||
private Program _compute;
|
||||
private Buffer<uint> _pEdges;
|
||||
private Buffer<uint> _pAreas;
|
||||
private VertexArray _polyVao;
|
||||
|
||||
var vert = Shader.Compile("shaders/simple.vert");
|
||||
var frag = Shader.Compile("shaders/simple.frag");
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
_render = Program.Link(vert, frag);
|
||||
X = (DisplayDevice.Default.Width - Width) / 2;
|
||||
Y = (DisplayDevice.Default.Height - Height) / 2;
|
||||
|
||||
_vbo = new Buffer();
|
||||
_vbo.SetData(_verts);
|
||||
var vert = Shader.Compile("shaders/simple.vert");
|
||||
var frag = Shader.Compile("shaders/simple.frag");
|
||||
_render = Program.Link(vert, frag);
|
||||
|
||||
_ibo = new Buffer();
|
||||
_ibo.SetData(_inds);
|
||||
var comp = Shader.Compile("shaders/intersect.comp");
|
||||
_compute = Program.Link(comp);
|
||||
|
||||
_vao = new VertexArray();
|
||||
_vao.VertexPointer(_vbo, index: 0, size: 4);
|
||||
}
|
||||
_tFaces = Buffer<uint>.FromData(new uint[] {0, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 3});
|
||||
_tEdges = Buffer<uint>.FromData(new uint[] {0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3});
|
||||
_tVerts = Buffer<Vector4>.FromData(new[]
|
||||
{
|
||||
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),
|
||||
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnRenderFrame(e);
|
||||
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),
|
||||
});
|
||||
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
_tInds = Buffer<uint>.FromData(new uint[] {0, 1, 2, 3});
|
||||
_pVerts = new Buffer<Vector4>(_tInds.Count / 4 * 4);
|
||||
_pEdges = new Buffer<uint>(_tInds.Count / 4 * 8);
|
||||
_pAreas = new Buffer<uint>(_tInds.Count / 4 * 6);
|
||||
|
||||
GL.Viewport(ClientRectangle);
|
||||
_ubo = new Buffer<ViewMats>();
|
||||
_view = ViewMats.Identity;
|
||||
|
||||
GL.UseProgram(_render);
|
||||
GL.BindVertexArray(_vao);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _ibo);
|
||||
GL.DrawElements(BeginMode.Triangles, _inds.Length, DrawElementsType.UnsignedInt, 0);
|
||||
GL.Flush();
|
||||
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, _ubo);
|
||||
GL.UniformBlockBinding(_render, _render.UnifBlockInd("ViewMats"), 0);
|
||||
|
||||
SwapBuffers();
|
||||
}
|
||||
_tetraVao = new VertexArray();
|
||||
_tetraVao.VertexPointer(_tVerts, index: _render.AttrLoc("pos"), size: 4);
|
||||
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
}
|
||||
}
|
||||
_polyVao = new VertexArray();
|
||||
_polyVao.VertexPointer(_pVerts, index: _render.AttrLoc("pos"), size: 4);
|
||||
}
|
||||
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnRenderFrame(e);
|
||||
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
|
||||
GL.Viewport(ClientRectangle);
|
||||
|
||||
GL.UseProgram(_render);
|
||||
|
||||
GL.BindVertexArray(_tetraVao);
|
||||
|
||||
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.Uniform3(_render.UnifLoc("color"), 1f, 1, 1);
|
||||
GL.DrawElements(BeginMode.Triangles, _tEdges.Count, DrawElementsType.UnsignedInt, 0);
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
|
||||
GL.BindVertexArray(_polyVao);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _pEdges);
|
||||
GL.Uniform3(_render.UnifLoc("color"), .1f, .1f, .9f);
|
||||
GL.DrawElements(BeginMode.Lines, _pEdges.Count, DrawElementsType.UnsignedInt, 0);
|
||||
|
||||
GL.Flush();
|
||||
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
|
||||
_view.Proj = Matrix4.CreateOrthographic(5, 5f * Height / Width, -2.5f, 2.5f);
|
||||
_view.View = Matrix4.LookAt(Vector3.Zero, -Vector3.One, Vector3.UnitZ);
|
||||
|
||||
_view.Model *= Matrix4.CreateRotationZ((float) e.Time);
|
||||
|
||||
_ubo.SetData(ref _view);
|
||||
|
||||
GL.UseProgram(_compute);
|
||||
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, _tVerts);
|
||||
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, _tInds);
|
||||
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, _pVerts);
|
||||
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 3, _pEdges);
|
||||
GL.DispatchCompute(_tInds.Count / 4, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,9 @@
|
||||
<Compile Include="Util\VertexArray.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="shaders\intersect.comp">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="shaders\simple.frag">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
@@ -1,20 +1,56 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Platformer.Util
|
||||
{
|
||||
public class Buffer : GlObj
|
||||
{
|
||||
public Buffer() : base(GL.GenBuffer())
|
||||
{
|
||||
}
|
||||
public class Buffer<T> : GlObj where T : struct
|
||||
{
|
||||
public static readonly int ElementSize = Marshal.SizeOf(typeof(T));
|
||||
public int Count { get; private set; }
|
||||
|
||||
public void SetData<T>(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw) where T : struct
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, this);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(data.Length * Marshal.SizeOf(typeof(T))), data, usage);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
}
|
||||
}
|
||||
public Buffer() : base(GL.GenBuffer())
|
||||
{
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public Buffer(int size, BufferUsageHint usage = BufferUsageHint.StaticDraw) : base(GL.GenBuffer())
|
||||
{
|
||||
Count = size;
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, this);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (size * ElementSize), IntPtr.Zero, usage);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
}
|
||||
|
||||
public void SetData(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw)
|
||||
{
|
||||
Count = data.Length;
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, this);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (data.Length * ElementSize), data, usage);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
}
|
||||
|
||||
public void SetData(ref T data, BufferUsageHint usage = BufferUsageHint.StaticDraw)
|
||||
{
|
||||
Count = 1;
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, this);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (ElementSize), ref data, usage);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
}
|
||||
|
||||
public static Buffer<T> FromData(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw)
|
||||
{
|
||||
var buf = new Buffer<T>();
|
||||
buf.SetData(data, usage);
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static Buffer<T> FromData(ref T data, BufferUsageHint usage = BufferUsageHint.StaticDraw)
|
||||
{
|
||||
var buf = new Buffer<T>();
|
||||
buf.SetData(ref data, usage);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,53 @@
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Platformer.Util
|
||||
{
|
||||
public class Program : GlObj
|
||||
{
|
||||
public Program() : base(GL.CreateProgram())
|
||||
{
|
||||
}
|
||||
public class Program : GlObj
|
||||
{
|
||||
private Dictionary<string, int> _unifCache;
|
||||
private Dictionary<string, int> _attrCache;
|
||||
private Dictionary<string, int> _unifBlockCache;
|
||||
|
||||
public static Program Link(params Shader[] shaders)
|
||||
{
|
||||
var p = new Program();
|
||||
foreach (var s in shaders)
|
||||
GL.AttachShader(p, s);
|
||||
GL.LinkProgram(p);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
public Program() : base(GL.CreateProgram())
|
||||
{
|
||||
_unifCache = new Dictionary<string, int>();
|
||||
_attrCache = new Dictionary<string, int>();
|
||||
_unifBlockCache = new Dictionary<string, int>();
|
||||
}
|
||||
|
||||
public int UnifLoc(string name)
|
||||
{
|
||||
if (!_unifCache.ContainsKey(name))
|
||||
_unifCache[name] = GL.GetUniformLocation(this, name);
|
||||
return _unifCache[name];
|
||||
}
|
||||
|
||||
public int UnifBlockInd(string name)
|
||||
{
|
||||
if (!_unifBlockCache.ContainsKey(name))
|
||||
_unifBlockCache[name] = GL.GetUniformBlockIndex(this, name);
|
||||
return _unifBlockCache[name];
|
||||
}
|
||||
|
||||
public int AttrLoc(string name)
|
||||
{
|
||||
if (!_attrCache.ContainsKey(name))
|
||||
_attrCache[name] = GL.GetAttribLocation(this, name);
|
||||
return _attrCache[name];
|
||||
}
|
||||
|
||||
public static Program Link(params Shader[] shaders)
|
||||
{
|
||||
var p = new Program();
|
||||
foreach (var s in shaders)
|
||||
GL.AttachShader(p, s);
|
||||
GL.LinkProgram(p);
|
||||
|
||||
Console.Error.WriteLine(GL.GetProgramInfoLog(p));
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,36 +5,37 @@ using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Platformer.Util
|
||||
{
|
||||
public class Shader : GlObj
|
||||
{
|
||||
private static Dictionary<string, ShaderType> _shaderTypes = new Dictionary<string, ShaderType>()
|
||||
{
|
||||
[".vert"] = ShaderType.VertexShader,
|
||||
[".frag"] = ShaderType.FragmentShader,
|
||||
[".geom"] = ShaderType.GeometryShader,
|
||||
[".comp"] = ShaderType.ComputeShader,
|
||||
};
|
||||
public class Shader : GlObj
|
||||
{
|
||||
private static Dictionary<string, ShaderType> _shaderTypes = new Dictionary<string, ShaderType>()
|
||||
{
|
||||
[".vert"] = ShaderType.VertexShader,
|
||||
[".frag"] = ShaderType.FragmentShader,
|
||||
[".geom"] = ShaderType.GeometryShader,
|
||||
[".comp"] = ShaderType.ComputeShader,
|
||||
};
|
||||
|
||||
public Shader(ShaderType type) : base(GL.CreateShader(type))
|
||||
{
|
||||
}
|
||||
public Shader(ShaderType type) : base(GL.CreateShader(type))
|
||||
{
|
||||
}
|
||||
|
||||
public static Shader Compile(ShaderType type, string source)
|
||||
{
|
||||
var s = new Shader(type);
|
||||
GL.ShaderSource(s, source);
|
||||
GL.CompileShader(s);
|
||||
return s;
|
||||
}
|
||||
public static Shader Compile(ShaderType type, string source)
|
||||
{
|
||||
var s = new Shader(type);
|
||||
GL.ShaderSource(s, source);
|
||||
GL.CompileShader(s);
|
||||
Console.Error.WriteLine(GL.GetShaderInfoLog(s));
|
||||
return s;
|
||||
}
|
||||
|
||||
public static Shader Compile(string filename)
|
||||
{
|
||||
var ext = Path.GetExtension(filename);
|
||||
public static Shader Compile(string filename)
|
||||
{
|
||||
var ext = Path.GetExtension(filename);
|
||||
|
||||
if (!_shaderTypes.ContainsKey(ext))
|
||||
throw new InvalidOperationException($"Can't infer shader type for {filename}");
|
||||
if (!_shaderTypes.ContainsKey(ext))
|
||||
throw new InvalidOperationException($"Can't infer shader type for {filename}");
|
||||
|
||||
return Compile(_shaderTypes[ext], File.ReadAllText(filename));
|
||||
}
|
||||
}
|
||||
return Compile(_shaderTypes[ext], File.ReadAllText(filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,25 +2,26 @@
|
||||
|
||||
namespace Platformer.Util
|
||||
{
|
||||
public class VertexArray : GlObj
|
||||
{
|
||||
public VertexArray() : base(GL.GenVertexArray())
|
||||
{
|
||||
}
|
||||
public class VertexArray : GlObj
|
||||
{
|
||||
public VertexArray() : base(GL.GenVertexArray())
|
||||
{
|
||||
}
|
||||
|
||||
public void VertexPointer(Buffer buffer, int index, int size,
|
||||
VertexAttribPointerType type = VertexAttribPointerType.Float,
|
||||
bool normalized = false, int stride = 0, int offset = 0)
|
||||
{
|
||||
GL.BindVertexArray(this);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
|
||||
GL.VertexAttribPointer(index, size, type, normalized, stride, offset);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
|
||||
GL.EnableVertexArrayAttrib(this, index);
|
||||
|
||||
GL.BindVertexArray(0);
|
||||
}
|
||||
}
|
||||
public void VertexPointer<T>(Buffer<T> buffer, int index, int size,
|
||||
VertexAttribPointerType type = VertexAttribPointerType.Float,
|
||||
bool normalized = false, int stride = 0, int offset = 0)
|
||||
where T : struct
|
||||
{
|
||||
GL.BindVertexArray(this);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
|
||||
GL.VertexAttribPointer(index, size, type, normalized, stride, offset);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
|
||||
GL.EnableVertexArrayAttrib(this, index);
|
||||
|
||||
GL.BindVertexArray(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Platformer/shaders/intersect.comp
Normal file
25
Platformer/shaders/intersect.comp
Normal file
@@ -0,0 +1,25 @@
|
||||
#version 430
|
||||
|
||||
layout(std430, binding=0) buffer TetraVerts
|
||||
{
|
||||
vec4 tetraVerts[];
|
||||
};
|
||||
|
||||
layout(std430, binding=1) buffer TetraInds
|
||||
{
|
||||
uint tetraInds[];
|
||||
};
|
||||
|
||||
layout(std430, binding=2) buffer PolyVerts
|
||||
{
|
||||
vec4 polyVerts[];
|
||||
};
|
||||
|
||||
layout(std430, binding=3) buffer EdgeInds
|
||||
{
|
||||
uint edgeInds[];
|
||||
};
|
||||
|
||||
void main () {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#version 430
|
||||
|
||||
uniform vec3 color;
|
||||
|
||||
void main () {
|
||||
gl_Fragcolor = vec4(1);
|
||||
gl_FragColor = vec4(color, 1);
|
||||
}
|
||||
@@ -1,7 +1,14 @@
|
||||
#version 430
|
||||
|
||||
uniform ViewMats
|
||||
{
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
};
|
||||
|
||||
in vec4 pos;
|
||||
|
||||
void main () {
|
||||
gl_Position = pos;
|
||||
gl_Position = proj * view * model * pos;
|
||||
}
|
||||
Reference in New Issue
Block a user