Compare commits
11 Commits
master
...
platformer
| Author | SHA1 | Date | |
|---|---|---|---|
| c8627cba4c | |||
| 2983d0c959 | |||
| 2212fb762e | |||
| f3bfaf021e | |||
| dd5f05a12f | |||
| 6539dd5ee6 | |||
| f175dd84f4 | |||
| edb2985a98 | |||
| dd1fc7e12e | |||
| 8d2177ef4a | |||
| d5feb8facd |
11
Platformer/Driver.cs
Normal file
11
Platformer/Driver.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Platformer
|
||||
{
|
||||
internal static class Driver
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
using (var pw = new PlatformWindow())
|
||||
pw.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
337
Platformer/PlatformWindow.cs
Normal file
337
Platformer/PlatformWindow.cs
Normal file
@@ -0,0 +1,337 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK.Input;
|
||||
using Platformer.Util;
|
||||
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 struct ViewMats
|
||||
{
|
||||
public Matrix4 Model;
|
||||
public Matrix4 View;
|
||||
public Matrix4 Proj;
|
||||
|
||||
public static ViewMats Identity => new ViewMats {Model = Matrix4.Identity, View = Matrix4.Identity};
|
||||
}
|
||||
|
||||
public struct PlaneMats
|
||||
{
|
||||
public Matrix4 Tform;
|
||||
|
||||
public static PlaneMats Identity => new PlaneMats {Tform = Matrix4.Identity};
|
||||
}
|
||||
|
||||
public class PlatformWindow : GameWindow
|
||||
{
|
||||
private Buffer<ViewMats> _viewBuf;
|
||||
private Buffer<PlaneMats> _tformBuf;
|
||||
private ViewMats _view;
|
||||
private PlaneMats _tform;
|
||||
|
||||
private Program _render;
|
||||
private Program _compute;
|
||||
|
||||
private Buffer<Vector4> _tVerts;
|
||||
private Buffer<uint> _tInds;
|
||||
private int _tCount;
|
||||
|
||||
private VertexArray _tetraVao;
|
||||
private VertexArray _polyVao;
|
||||
|
||||
private Buffer<Vector4> _pVerts;
|
||||
|
||||
private Buffer<uint> _pEdges;
|
||||
private Buffer<uint> _pFaces;
|
||||
|
||||
private Buffer<uint> _tEdges;
|
||||
private Buffer<uint> _tFaces;
|
||||
|
||||
private bool _flat = false;
|
||||
private bool _tetra = true;
|
||||
private bool _pOutline = true;
|
||||
private bool _tOutline = true;
|
||||
private float _time;
|
||||
|
||||
|
||||
private void GenSphere(uint res)
|
||||
{
|
||||
var tv = new List<Vector3>();
|
||||
var ns = new List<uint>();
|
||||
|
||||
tv.Add(new Vector3(0, 0, 0));
|
||||
|
||||
var c = res + 1;
|
||||
for (var p = 0; p <= res; p++)
|
||||
for (var t = 0; t <= res; t++)
|
||||
{
|
||||
var pp = Math.PI * p / res;
|
||||
var tt = Math.PI * 2 * t / res;
|
||||
tv.Add(new Vector3(
|
||||
(float) (Math.Sin(pp) * Math.Cos(tt)),
|
||||
(float) (Math.Sin(pp) * Math.Sin(tt)),
|
||||
(float) (Math.Cos(pp))
|
||||
));
|
||||
}
|
||||
|
||||
for (uint i = 0; i < c - 1; i++)
|
||||
for (uint j = 0; j < c - 1; j++)
|
||||
{
|
||||
var k = 1 + i + j * c;
|
||||
ns.Add(0);
|
||||
ns.Add(k);
|
||||
ns.Add(k + 1);
|
||||
ns.Add(k + c);
|
||||
ns.Add(0);
|
||||
ns.Add(k + c + 1);
|
||||
ns.Add(k + 1);
|
||||
ns.Add(k + c);
|
||||
}
|
||||
|
||||
if (_tVerts == null)
|
||||
_tVerts = new Buffer<Vector4>();
|
||||
if (_tInds == null)
|
||||
_tInds = new Buffer<uint>();
|
||||
|
||||
_tVerts.SetData(tv.Select(v => new Vector4(v, 1)).ToArray());
|
||||
_tInds.SetData(ns.ToArray());
|
||||
_tCount = _tInds.Count / 4;
|
||||
}
|
||||
|
||||
private void GenTorus(uint res, double a, double b)
|
||||
{
|
||||
var tv = new List<Vector3>();
|
||||
var ns = new List<uint>();
|
||||
|
||||
for (uint t = 0; t <= res; t++)
|
||||
for (uint p = 0; p <= res; p++)
|
||||
{
|
||||
var tt = Math.PI * 2 * t / res;
|
||||
var pp = Math.PI * 2 * p / res;
|
||||
|
||||
var v = new Vector3d(
|
||||
(a - b * Math.Cos(pp)) * Math.Cos(tt),
|
||||
(a - b * Math.Cos(pp)) * Math.Sin(tt),
|
||||
b * Math.Sin(pp)
|
||||
);
|
||||
|
||||
tv.Add((Vector3) v);
|
||||
}
|
||||
|
||||
for (uint t = 0; t < res; t++)
|
||||
for (uint p = 1; p < res; p++)
|
||||
{
|
||||
var k = res + 1;
|
||||
|
||||
ns.Add(t * k);
|
||||
ns.Add(t * k + p);
|
||||
ns.Add(t * k + p + 1);
|
||||
ns.Add(t * k + p + k);
|
||||
|
||||
ns.Add(t * k);
|
||||
ns.Add(t * k + p + 1);
|
||||
ns.Add(t * k + p + k);
|
||||
ns.Add(t * k + p + k + 1);
|
||||
|
||||
ns.Add(t * k);
|
||||
ns.Add(t * k + k);
|
||||
ns.Add(t * k + p + k);
|
||||
ns.Add(t * k + p + k + 1);
|
||||
}
|
||||
|
||||
if (_tVerts == null)
|
||||
_tVerts = new Buffer<Vector4>();
|
||||
if (_tInds == null)
|
||||
_tInds = new Buffer<uint>();
|
||||
|
||||
_tVerts.SetData(tv.Select(v => new Vector4(v, 1)).ToArray());
|
||||
_tInds.SetData(ns.ToArray());
|
||||
_tCount = _tInds.Count / 4;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
X = (DisplayDevice.Default.Width - Width) / 2;
|
||||
Y = (DisplayDevice.Default.Height - Height) / 2;
|
||||
|
||||
var vert = Shader.Compile("shaders/simple.vert");
|
||||
var frag = Shader.Compile("shaders/simple.frag");
|
||||
_render = Program.Link(vert, frag);
|
||||
|
||||
var comp = Shader.Compile("shaders/intersect.comp");
|
||||
_compute = Program.Link(comp);
|
||||
|
||||
// GenSphere(20);
|
||||
GenTorus(20, 1, .5);
|
||||
|
||||
_pVerts = new Buffer<Vector4>(_tCount * 4);
|
||||
_pEdges = new Buffer<uint>(_tCount * 8);
|
||||
_pFaces = new Buffer<uint>(_tCount * 6);
|
||||
|
||||
_tEdges = new Buffer<uint>(_tCount * 12);
|
||||
_tFaces = new Buffer<uint>(_tCount * 12);
|
||||
|
||||
_viewBuf = new Buffer<ViewMats>();
|
||||
_view = ViewMats.Identity;
|
||||
|
||||
_tformBuf = new Buffer<PlaneMats>();
|
||||
_tform = PlaneMats.Identity;
|
||||
|
||||
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, _viewBuf);
|
||||
GL.UniformBlockBinding(_render, _render.UnifBlockInd("ViewMats"), 0);
|
||||
|
||||
GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 1, _tformBuf);
|
||||
GL.UniformBlockBinding(_compute, _compute.UnifBlockInd("PlaneMats"), 1);
|
||||
|
||||
_tetraVao = new VertexArray();
|
||||
_tetraVao.VertexPointer(_tVerts, index: _render.AttrLoc("pos"), size: 4);
|
||||
|
||||
_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);
|
||||
|
||||
if (_tetra)
|
||||
{
|
||||
GL.BindVertexArray(_tetraVao);
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _tFaces);
|
||||
GL.Uniform3(_render.UnifLoc("color"), 1f, 1, 1);
|
||||
GL.DrawElements(BeginMode.Triangles, _tEdges.Count, DrawElementsType.UnsignedInt, 0);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (_pOutline)
|
||||
{
|
||||
GL.BindVertexArray(_polyVao);
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _pEdges);
|
||||
GL.Uniform3(_render.UnifLoc("color"), .1f, .1f, .6f);
|
||||
GL.DrawElements(BeginMode.Lines, _pEdges.Count, DrawElementsType.UnsignedInt, 0);
|
||||
}
|
||||
|
||||
if (_tetra && _tOutline)
|
||||
{
|
||||
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();
|
||||
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
var dt = (float) e.Time;
|
||||
_time += dt;
|
||||
|
||||
var dv = Matrix4.Identity;
|
||||
|
||||
if (Keyboard[Key.LControl])
|
||||
dt /= 4;
|
||||
|
||||
if (Keyboard[Key.LShift])
|
||||
{
|
||||
if (Keyboard[Key.Left]) dv *= Matrix4.CreateRotationZ(dt);
|
||||
if (Keyboard[Key.Right]) dv *= Matrix4.CreateRotationZ(-dt);
|
||||
if (Keyboard[Key.Up]) dv *= Matrix4.CreateRotationY(dt);
|
||||
if (Keyboard[Key.Down]) dv *= Matrix4.CreateRotationY(-dt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Keyboard[Key.Left]) dv *= Matrix4.CreateRotationZ(dt);
|
||||
if (Keyboard[Key.Right]) dv *= Matrix4.CreateRotationZ(-dt);
|
||||
if (Keyboard[Key.Up]) dv *= Matrix4.CreateTranslation(-dt, 0, 0);
|
||||
if (Keyboard[Key.Down]) dv *= Matrix4.CreateTranslation(dt, 0, 0);
|
||||
}
|
||||
|
||||
_tform.Tform *= dv;
|
||||
|
||||
_view.Proj = Matrix4.CreateOrthographic(5, 5f * Height / Width, -2.5f, 2.5f);
|
||||
|
||||
if (_flat)
|
||||
{
|
||||
_view.View = Matrix4.LookAt(Vector3.Zero, Vector3.UnitX, Vector3.UnitZ);
|
||||
_view.Model = _tform.Tform;
|
||||
}
|
||||
else
|
||||
{
|
||||
_view.View = Matrix4.LookAt(Vector3.Zero, -Vector3.One, Vector3.UnitZ);
|
||||
_view.Model = Matrix4.Identity;
|
||||
}
|
||||
|
||||
_viewBuf.SetData(ref _view);
|
||||
_tformBuf.SetData(ref _tform);
|
||||
|
||||
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.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 4, _pFaces);
|
||||
|
||||
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 5, _tEdges);
|
||||
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 6, _tFaces);
|
||||
|
||||
GL.DispatchCompute(_tCount, 1, 1);
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyboardKeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.A:
|
||||
_flat = !_flat;
|
||||
break;
|
||||
case Key.S:
|
||||
_tetra = !_tetra;
|
||||
break;
|
||||
case Key.D:
|
||||
_pOutline = !_pOutline;
|
||||
break;
|
||||
case Key.F:
|
||||
_tOutline = !_tOutline;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
73
Platformer/Platformer.csproj
Normal file
73
Platformer/Platformer.csproj
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{9A4A039D-58DF-4FA1-8743-A0CBB452B9D3}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Platformer</RootNamespace>
|
||||
<AssemblyName>Platformer</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4">
|
||||
<HintPath>..\packages\OpenTK.3.0.0-pre\lib\net20\OpenTK.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Driver.cs" />
|
||||
<Compile Include="PlatformWindow.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Util\Buffer.cs" />
|
||||
<Compile Include="Util\GlObj.cs" />
|
||||
<Compile Include="Util\Program.cs" />
|
||||
<Compile Include="Util\Shader.cs" />
|
||||
<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>
|
||||
<Content Include="shaders\simple.vert">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
35
Platformer/Properties/AssemblyInfo.cs
Normal file
35
Platformer/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Platformer")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Platformer")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("9A4A039D-58DF-4FA1-8743-A0CBB452B9D3")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
56
Platformer/Util/Buffer.cs
Normal file
56
Platformer/Util/Buffer.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Platformer.Util
|
||||
{
|
||||
public class Buffer<T> : GlObj where T : struct
|
||||
{
|
||||
public static readonly int ElementSize = Marshal.SizeOf(typeof(T));
|
||||
public int Count { get; private set; }
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Platformer/Util/GlObj.cs
Normal file
14
Platformer/Util/GlObj.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Platformer.Util
|
||||
{
|
||||
public abstract class GlObj
|
||||
{
|
||||
public readonly int Id;
|
||||
|
||||
public GlObj(int id)
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
|
||||
public static implicit operator int(GlObj o) => o.Id;
|
||||
}
|
||||
}
|
||||
53
Platformer/Util/Program.cs
Normal file
53
Platformer/Util/Program.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Platformer.Util
|
||||
{
|
||||
public class Program : GlObj
|
||||
{
|
||||
private Dictionary<string, int> _unifCache;
|
||||
private Dictionary<string, int> _attrCache;
|
||||
private Dictionary<string, int> _unifBlockCache;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Platformer/Util/Shader.cs
Normal file
41
Platformer/Util/Shader.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
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 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);
|
||||
Console.Error.WriteLine(GL.GetShaderInfoLog(s));
|
||||
return s;
|
||||
}
|
||||
|
||||
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}");
|
||||
|
||||
return Compile(_shaderTypes[ext], File.ReadAllText(filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Platformer/Util/VertexArray.cs
Normal file
27
Platformer/Util/VertexArray.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using OpenTK.Graphics.OpenGL4;
|
||||
|
||||
namespace Platformer.Util
|
||||
{
|
||||
public class VertexArray : GlObj
|
||||
{
|
||||
public VertexArray() : base(GL.GenVertexArray())
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Platformer/shaders/intersect.comp
Normal file
122
Platformer/shaders/intersect.comp
Normal file
@@ -0,0 +1,122 @@
|
||||
#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 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
|
||||
{
|
||||
mat4 tform;
|
||||
};
|
||||
|
||||
layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
void main () {
|
||||
int ti0 = int(gl_GlobalInvocationID.x * 4);
|
||||
int pv0 = int(gl_GlobalInvocationID.x * 4);
|
||||
|
||||
int pe0 = int(gl_GlobalInvocationID.x * 8);
|
||||
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 j = i + 1; j < 4; j++)
|
||||
{
|
||||
vec4 a = tetraVerts[tetraInds[ti0 + i]];
|
||||
vec4 a_ = tform * a;
|
||||
|
||||
vec4 b = tetraVerts[tetraInds[ti0 + j]];
|
||||
vec4 b_ = tform * b;
|
||||
|
||||
if (a_.x * b_.x < 0)
|
||||
{
|
||||
vec4 p = (b-a) / (a_.x - b_.x) * b_.x + b;
|
||||
polyVerts[pv0 + pvi++] = p;
|
||||
}
|
||||
}
|
||||
|
||||
polyEdges[pe0 + pei++] = pv0 + 0;
|
||||
polyEdges[pe0 + pei++] = pv0 + 1;
|
||||
polyEdges[pe0 + pei++] = pv0 + 1;
|
||||
if (pvi == 4)
|
||||
{
|
||||
polyEdges[pe0 + pei++] = pv0 + 3;
|
||||
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;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
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;
|
||||
}
|
||||
7
Platformer/shaders/simple.frag
Normal file
7
Platformer/shaders/simple.frag
Normal file
@@ -0,0 +1,7 @@
|
||||
#version 430
|
||||
|
||||
uniform vec3 color;
|
||||
|
||||
void main () {
|
||||
gl_FragColor = vec4(color, 1);
|
||||
}
|
||||
14
Platformer/shaders/simple.vert
Normal file
14
Platformer/shaders/simple.vert
Normal file
@@ -0,0 +1,14 @@
|
||||
#version 430
|
||||
|
||||
uniform ViewMats
|
||||
{
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
};
|
||||
|
||||
in vec4 pos;
|
||||
|
||||
void main () {
|
||||
gl_Position = proj * view * model * pos;
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tetrahedrons", "Tetrahedrons\Tetrahedrons.csproj", "{D70DFA78-49B4-404B-BE1C-7CDC0DAE26FD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platformer", "Platformer\Platformer.csproj", "{9A4A039D-58DF-4FA1-8743-A0CBB452B9D3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -12,5 +14,9 @@ Global
|
||||
{D70DFA78-49B4-404B-BE1C-7CDC0DAE26FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D70DFA78-49B4-404B-BE1C-7CDC0DAE26FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D70DFA78-49B4-404B-BE1C-7CDC0DAE26FD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9A4A039D-58DF-4FA1-8743-A0CBB452B9D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9A4A039D-58DF-4FA1-8743-A0CBB452B9D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9A4A039D-58DF-4FA1-8743-A0CBB452B9D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9A4A039D-58DF-4FA1-8743-A0CBB452B9D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
224
Tetrahedrons/Gl4Window.cs
Normal file
224
Tetrahedrons/Gl4Window.cs
Normal file
@@ -0,0 +1,224 @@
|
||||
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;
|
||||
|
||||
private int _pgmRend;
|
||||
|
||||
private int _shVert;
|
||||
private int _shFrag;
|
||||
|
||||
private int _bufPentVerts;
|
||||
private int _bufPentInds;
|
||||
private int _bufUniform;
|
||||
private int _bufPenMats;
|
||||
|
||||
private Vector4[] _datPentVerts;
|
||||
private uint[] _datPentInds;
|
||||
|
||||
private MatrixBlock _datMats;
|
||||
private TransformMats _datPenMats;
|
||||
|
||||
private int _bufHullVerts;
|
||||
private int _bufHullInds;
|
||||
|
||||
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);
|
||||
|
||||
X = (DisplayDevice.Default.Width - Width) / 2;
|
||||
Y = (DisplayDevice.Default.Height - Height) / 2;
|
||||
|
||||
#region Shaders
|
||||
|
||||
_pgmRend = GL.CreateProgram();
|
||||
|
||||
_shVert = GL.CreateShader(ShaderType.VertexShader);
|
||||
GL.ShaderSource(_shVert, File.ReadAllText("Shaders/simple.vert"));
|
||||
GL.CompileShader(_shVert);
|
||||
GL.AttachShader(_pgmRend, _shVert);
|
||||
Console.WriteLine(GL.GetShaderInfoLog(_shVert));
|
||||
|
||||
_shFrag = GL.CreateShader(ShaderType.FragmentShader);
|
||||
GL.ShaderSource(_shFrag, File.ReadAllText("Shaders/simple.frag"));
|
||||
GL.CompileShader(_shFrag);
|
||||
GL.AttachShader(_pgmRend, _shFrag);
|
||||
Console.WriteLine(GL.GetShaderInfoLog(_shFrag));
|
||||
|
||||
GL.LinkProgram(_pgmRend);
|
||||
Console.WriteLine(GL.GetProgramInfoLog(_pgmRend));
|
||||
|
||||
|
||||
_pgmComp = GL.CreateProgram();
|
||||
|
||||
_shComp = GL.CreateShader(ShaderType.ComputeShader);
|
||||
GL.ShaderSource(_shComp, File.ReadAllText("Shaders/intersect.comp"));
|
||||
GL.CompileShader(_shComp);
|
||||
GL.AttachShader(_pgmComp, _shComp);
|
||||
Console.Out.WriteLine(GL.GetShaderInfoLog(_shComp));
|
||||
|
||||
GL.LinkProgram(_pgmComp);
|
||||
Console.Out.WriteLine(GL.GetProgramInfoLog(_pgmComp));
|
||||
|
||||
#endregion
|
||||
|
||||
_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,
|
||||
};
|
||||
_datPentInds = new uint[]
|
||||
{
|
||||
0, 1, 2, 3, 4,
|
||||
// 0, 1, 2, 3, 5,
|
||||
};
|
||||
|
||||
_datMats = MatrixBlock.Identity;
|
||||
_datPenMats = TransformMats.Identity;
|
||||
|
||||
_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);
|
||||
|
||||
_bufPentInds = GL.GenBuffer();
|
||||
GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _bufPentInds);
|
||||
GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr) (_penIndsCount * sizeof(int)), _datPentInds, BufferUsageHint.DynamicDraw);
|
||||
GL.BindBuffer(BufferTarget.ShaderStorageBuffer, 0);
|
||||
|
||||
_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);
|
||||
|
||||
_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);
|
||||
|
||||
_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);
|
||||
}
|
||||
|
||||
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnRenderFrame(e);
|
||||
GL.Viewport(0, 0, Width, Height);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
|
||||
GL.UseProgram(_pgmComp);
|
||||
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, _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.Triangles, _hullIndsCount, DrawElementsType.UnsignedInt, 0);
|
||||
GL.DisableVertexAttribArray(0);
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
|
||||
GL.Flush();
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
_t += (float) e.Time;
|
||||
|
||||
float w = 3;
|
||||
|
||||
_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,11 @@ namespace Tetrahedrons
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
using (var p = new TetrahedronWindow())
|
||||
using (var p = new Gl4Window())
|
||||
p.Run();
|
||||
|
||||
// using (var p = new TetrahedronWindow())
|
||||
// p.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Tetrahedrons/Shaders/intersect.comp
Normal file
88
Tetrahedrons/Shaders/intersect.comp
Normal file
@@ -0,0 +1,88 @@
|
||||
#version 430
|
||||
|
||||
layout(std430, binding=1) buffer PentVerts
|
||||
{
|
||||
vec4 pentVerts[];
|
||||
};
|
||||
|
||||
layout(std430, binding=2) buffer PentInds
|
||||
{
|
||||
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 pentInd0 = gl_GlobalInvocationID.x * 5;
|
||||
uint hullVrt0 = gl_GlobalInvocationID.x * 6;
|
||||
uint hullInd0 = gl_GlobalInvocationID.x * 24;
|
||||
|
||||
int k = 0;
|
||||
for(int i = 0; i < 5; i++)
|
||||
for(int j = i + 1; j < 5; j++)
|
||||
{
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
6
Tetrahedrons/Shaders/simple.frag
Normal file
6
Tetrahedrons/Shaders/simple.frag
Normal file
@@ -0,0 +1,6 @@
|
||||
in vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
||||
18
Tetrahedrons/Shaders/simple.vert
Normal file
18
Tetrahedrons/Shaders/simple.vert
Normal file
@@ -0,0 +1,18 @@
|
||||
#version 430 compatibility
|
||||
|
||||
layout(row_major) uniform Matrices
|
||||
{
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
};
|
||||
|
||||
in vec4 pos;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(pos.xyz, 1) * model * view * proj;
|
||||
color = vec4(gl_Position.xyz + vec3(.5), 1);
|
||||
}
|
||||
@@ -23,8 +23,8 @@ namespace Tetrahedrons
|
||||
private MVec4D _a = MVec4D.UnitX;
|
||||
private MVec4D _b = MVec4D.UnitY;
|
||||
|
||||
private Simplex[] _simplexes;
|
||||
private Simplex[] _intersections;
|
||||
private Simplex _sim;
|
||||
private Simplex _int;
|
||||
|
||||
private double _t;
|
||||
private bool _pause;
|
||||
@@ -39,27 +39,13 @@ namespace Tetrahedrons
|
||||
|
||||
_view = Matrix4.LookAt(Vector3.Zero, -new Vector3(.86f, .5f, 1), Vector3.UnitZ);
|
||||
|
||||
const int n = 5;
|
||||
_simplexes = new Simplex[n * n * n * n];
|
||||
_intersections = new Simplex[_simplexes.Length];
|
||||
|
||||
var off = (new Vector4d(n - 1, n - 1, n - 1, n - 1)) / 2;
|
||||
int i = 0;
|
||||
for (var x = 0; x < n; x++)
|
||||
for (var y = 0; y < n; y++)
|
||||
for (var z = 0; z < n; z++)
|
||||
for (var w = 0; w < n; w++)
|
||||
{
|
||||
var d = new Vector4d(x, y, z, w);
|
||||
_simplexes[i] = new Simplex( // not-quite-regular pentatope
|
||||
new Vector4d(+.5, -.5, -.5, -.5) + d - off,
|
||||
new Vector4d(-.5, +.5, -.5, -.5) + d - off,
|
||||
new Vector4d(-.5, -.5, +.5, -.5) + d - off,
|
||||
new Vector4d(-.5, -.5, -.5, +.5) + d - off,
|
||||
new Vector4d(+.5, +.5, +.5, +.5) + d - off);
|
||||
_intersections[i] = new Simplex();
|
||||
i++;
|
||||
}
|
||||
_sim = new Simplex( // not-quite-regular pentatope
|
||||
new Vector4d(+.5, -.5, -.5, -.5),
|
||||
new Vector4d(-.5, +.5, -.5, -.5),
|
||||
new Vector4d(-.5, -.5, +.5, -.5),
|
||||
new Vector4d(-.5, -.5, -.5, +.5),
|
||||
new Vector4d(+.5, +.5, +.5, +.5));
|
||||
_int = new Simplex();
|
||||
}
|
||||
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
@@ -83,17 +69,15 @@ namespace Tetrahedrons
|
||||
|
||||
GL.Begin(PrimitiveType.Lines);
|
||||
GL.Color3(0f, 0, 0);
|
||||
foreach (var intr in _intersections)
|
||||
foreach (var f in intr.Edjes)
|
||||
Util.Vertex3(intr.Verts[f]);
|
||||
foreach (var f in _int.Edjes)
|
||||
Util.Vertex3(_int.Verts[f]);
|
||||
GL.End();
|
||||
|
||||
GL.Begin(PrimitiveType.Triangles);
|
||||
foreach (var intr in _intersections)
|
||||
foreach (var f in intr.Faces)
|
||||
foreach (var f in _int.Faces)
|
||||
{
|
||||
Util.Color3(intr.Verts[f]);
|
||||
Util.Vertex3(intr.Verts[f]);
|
||||
Util.Color3(_int.Verts[f]);
|
||||
Util.Vertex3(_int.Verts[f]);
|
||||
}
|
||||
|
||||
GL.End();
|
||||
@@ -102,9 +86,8 @@ namespace Tetrahedrons
|
||||
if (_wire)
|
||||
{
|
||||
GL.Begin(PrimitiveType.Lines);
|
||||
foreach (var sim in _simplexes)
|
||||
foreach (var f in sim.Edjes)
|
||||
Util.Vertex4(sim.Verts[f]);
|
||||
foreach (var f in _sim.Edjes)
|
||||
Util.Vertex4(_sim.Verts[f]);
|
||||
|
||||
GL.End();
|
||||
}
|
||||
@@ -116,7 +99,7 @@ namespace Tetrahedrons
|
||||
{
|
||||
base.OnUpdateFrame(e);
|
||||
|
||||
var w = 10f;
|
||||
var w = 2f;
|
||||
var d = w;
|
||||
_proj3d = Matrix4.CreateOrthographic(w, w * Height / Width, -d / 2, d / 2);
|
||||
|
||||
@@ -124,19 +107,15 @@ namespace Tetrahedrons
|
||||
|
||||
_t += e.Time;
|
||||
|
||||
var pln = MVec4D.UnitXy + MVec4D.UnitXz + MVec4D.UnitYw;
|
||||
var r = MVec4D.Rotor(e.Time / 10, pln.Normalized);
|
||||
foreach (var pent in _simplexes)
|
||||
for (var i = 0; i < pent.Verts.Length; i++)
|
||||
pent.Verts[i] |= r;
|
||||
|
||||
var plane = MVec4D.UnitXw-2*MVec4D.UnitXy;
|
||||
var blade = MVec4D.UnitXyz;
|
||||
var pivot = MVec4D.Zero;
|
||||
var pivot = .1 * MVec4D.UnitW;
|
||||
|
||||
for (var i = 0; i < _simplexes.Length; i++)
|
||||
{
|
||||
_intersections[i] = _simplexes[i].Intersect(blade, pivot);
|
||||
}
|
||||
var r = MVec4D.Rotor(e.Time / 10, plane.Normalized);
|
||||
for (var i = 0; i < _sim.Verts.Length; i++)
|
||||
_sim.Verts[i] |= r;
|
||||
|
||||
_int = _sim.Intersect(blade, pivot);
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyboardKeyEventArgs e)
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Gl4Window.cs" />
|
||||
<Compile Include="MVec4D.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -53,6 +54,17 @@
|
||||
<None Include="OpenTK.dll.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Shaders\intersect.comp">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Shaders\simple.frag">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Shaders\simple.vert">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
Reference in New Issue
Block a user