removed Mesh, added VertexBuffer
This commit is contained in:
@@ -17,7 +17,7 @@ namespace Diamond.Buffers
|
|||||||
internal readonly BufferWrap Wrapper;
|
internal readonly BufferWrap Wrapper;
|
||||||
private readonly VertexDataInfo _vdi;
|
private readonly VertexDataInfo _vdi;
|
||||||
|
|
||||||
private readonly int _size;
|
protected readonly int Size;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The target for this buffer; its type
|
/// The target for this buffer; its type
|
||||||
@@ -38,7 +38,7 @@ namespace Diamond.Buffers
|
|||||||
{
|
{
|
||||||
Wrapper = wrapper;
|
Wrapper = wrapper;
|
||||||
Name = name;
|
Name = name;
|
||||||
_size = Marshal.SizeOf<T>();
|
Size = Marshal.SizeOf<T>();
|
||||||
_vdi = VertexDataInfo.GetInfo<T>();
|
_vdi = VertexDataInfo.GetInfo<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ namespace Diamond.Buffers
|
|||||||
/// Upload data to this buffer
|
/// Upload data to this buffer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">The data to upload</param>
|
/// <param name="data">The data to upload</param>
|
||||||
public void Data(T[] data) => Wrapper.Data(_size, data);
|
public void Data(T[] data) => Wrapper.Data(Size, data);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Upload a range of data to this buffer
|
/// Upload a range of data to this buffer
|
||||||
@@ -54,7 +54,7 @@ namespace Diamond.Buffers
|
|||||||
/// <param name="offset">The range offset</param>
|
/// <param name="offset">The range offset</param>
|
||||||
/// <param name="count">The range length</param>
|
/// <param name="count">The range length</param>
|
||||||
/// <param name="data">The data to upload, offset and length apply to both this and the target</param>
|
/// <param name="data">The data to upload, offset and length apply to both this and the target</param>
|
||||||
public void Data(int offset, int count, T[] data) => Wrapper.SubData(_size, offset, count, data);
|
public void Data(int offset, int count, T[] data) => Wrapper.SubData(Size, offset, count, data);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Upload a range of data to this buffer
|
/// Upload a range of data to this buffer
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
<Compile Include="Buffers\VertexDataAttribute.cs" />
|
<Compile Include="Buffers\VertexDataAttribute.cs" />
|
||||||
<Compile Include="Wrappers\Wrapper.cs" />
|
<Compile Include="Wrappers\Wrapper.cs" />
|
||||||
<Compile Include="Util\TileData.cs" />
|
<Compile Include="Util\TileData.cs" />
|
||||||
<Compile Include="Util\Mesh.cs" />
|
<Compile Include="Render\VertexBuffer.cs" />
|
||||||
<Compile Include="Util\ObjVertex.cs" />
|
<Compile Include="Util\ObjVertex.cs" />
|
||||||
<Compile Include="Shaders\Program.cs" />
|
<Compile Include="Shaders\Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|||||||
@@ -13,23 +13,15 @@ namespace Diamond.Render
|
|||||||
/// <typeparam name="TVertex">The type of data to use as Vertex information</typeparam>
|
/// <typeparam name="TVertex">The type of data to use as Vertex information</typeparam>
|
||||||
public class RenderGroup<TInstance, TVertex> where TInstance : struct where TVertex : struct
|
public class RenderGroup<TInstance, TVertex> where TInstance : struct where TVertex : struct
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The range of instance values to render
|
|
||||||
/// </summary>
|
|
||||||
public SubArray<TInstance> Instances;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The range of vertex values to render
|
/// The range of vertex values to render
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Mesh<TVertex> Vertices;
|
public VertexBuffer<TVertex> Vertices;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The buffer to use for instance data
|
/// The range of instance values to render
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Buffer<TInstance> InstanceBuffer;
|
public VertexBuffer<TInstance> Instance;
|
||||||
/// <summary>
|
|
||||||
/// The buffer to use for instance data
|
|
||||||
/// </summary>
|
|
||||||
public Buffer<TVertex> VertexBuffer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The program to use to render this Rendergroup
|
/// The program to use to render this Rendergroup
|
||||||
@@ -53,9 +45,6 @@ namespace Diamond.Render
|
|||||||
{
|
{
|
||||||
Program.Use();
|
Program.Use();
|
||||||
|
|
||||||
InstanceBuffer.PointTo(Program);
|
|
||||||
VertexBuffer.PointTo(Program);
|
|
||||||
|
|
||||||
Texture.Bind(0);
|
Texture.Bind(0);
|
||||||
|
|
||||||
var texLoc = Program.UniformLocation("tex");
|
var texLoc = Program.UniformLocation("tex");
|
||||||
@@ -69,7 +58,10 @@ namespace Diamond.Render
|
|||||||
if (projLoc.HasValue)
|
if (projLoc.HasValue)
|
||||||
GL.UniformMatrix4(projLoc.Value, false, ref Camera.Projection);
|
GL.UniformMatrix4(projLoc.Value, false, ref Camera.Projection);
|
||||||
|
|
||||||
Vertices.DrawInstanced(Instances);
|
if (Instance != null)
|
||||||
|
Vertices.DrawInstanced(Instance);
|
||||||
|
else
|
||||||
|
Vertices.Draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
203
Diamond/Render/VertexBuffer.cs
Normal file
203
Diamond/Render/VertexBuffer.cs
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Diamond.Buffers;
|
||||||
|
using Diamond.Shaders;
|
||||||
|
using Diamond.Util;
|
||||||
|
using NLog;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics.OpenGL4;
|
||||||
|
using Buffer = Diamond.Buffers.Buffer;
|
||||||
|
|
||||||
|
namespace Diamond.Render
|
||||||
|
{
|
||||||
|
public class VertexBuffer<T> : IDisposable where T : struct
|
||||||
|
{
|
||||||
|
private Logger Logger = LogManager.GetLogger("VertexBuffer");
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
public Buffer<T> Buffer;
|
||||||
|
public SubArray<T> Vertices;
|
||||||
|
public PrimitiveType Primitive;
|
||||||
|
|
||||||
|
private static readonly VertexDataInfo tVdi;
|
||||||
|
|
||||||
|
static VertexBuffer()
|
||||||
|
{
|
||||||
|
tVdi = VertexDataInfo.GetInfo<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal VertexBuffer(Buffer<T> buffer, SubArray<T> vertices, PrimitiveType primitive, string name)
|
||||||
|
{
|
||||||
|
Buffer = buffer;
|
||||||
|
Vertices = vertices;
|
||||||
|
Primitive = primitive;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw()
|
||||||
|
{
|
||||||
|
Buffer.PointTo(Program.Current);
|
||||||
|
|
||||||
|
tVdi.EnableVertexPointers();
|
||||||
|
|
||||||
|
GL.DrawArrays(Primitive, Vertices.Offset, Vertices.Length);
|
||||||
|
|
||||||
|
tVdi.DisableVertexPointers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawInstanced<TI>(VertexBuffer<TI> instance) where TI : struct
|
||||||
|
{
|
||||||
|
var tiVdi = VertexBuffer<TI>.tVdi;
|
||||||
|
|
||||||
|
if (tiVdi.Divisor == 0)
|
||||||
|
{
|
||||||
|
Logger.Error("Cannot render mesh with instanced of type {0} - Divisor is 0", typeof(TI).Name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer.PointTo(Program.Current);
|
||||||
|
instance.Buffer.PointTo(Program.Current);
|
||||||
|
|
||||||
|
tVdi.EnableVertexPointers();
|
||||||
|
tiVdi.EnableVertexPointers();
|
||||||
|
|
||||||
|
GL.DrawArraysInstancedBaseInstance(Primitive, Vertices.Offset, Vertices.Length, instance.Vertices.Length,
|
||||||
|
instance.Vertices.Offset);
|
||||||
|
|
||||||
|
tVdi.DisableVertexPointers();
|
||||||
|
tiVdi.DisableVertexPointers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Buffer.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class VertexBuffer
|
||||||
|
{
|
||||||
|
public static VertexBuffer<T>[] FromArrays<T>(T[][] arrays, PrimitiveType primitive = PrimitiveType.Triangles,
|
||||||
|
string name = null) where T : struct
|
||||||
|
{
|
||||||
|
var buffer = Buffer.Empty<T>(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, name);
|
||||||
|
|
||||||
|
var vertices = arrays.SelectMany(x => x).ToArray();
|
||||||
|
buffer.Data(vertices);
|
||||||
|
|
||||||
|
var vertBuffers = new List<VertexBuffer<T>>();
|
||||||
|
|
||||||
|
var offset = 0;
|
||||||
|
foreach (var array in arrays)
|
||||||
|
{
|
||||||
|
vertBuffers.Add(new VertexBuffer<T>(
|
||||||
|
buffer,
|
||||||
|
new SubArray<T>(vertices, offset, array.Length),
|
||||||
|
primitive, name));
|
||||||
|
offset += array.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vertBuffers.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VertexBuffer<T>[] FromArrays<T>(IEnumerable<IEnumerable<T>> arrays,
|
||||||
|
PrimitiveType primitive = PrimitiveType.Triangles, string name = null) where T : struct =>
|
||||||
|
FromArrays(arrays.Select(x => x.ToArray()).ToArray(), primitive, name);
|
||||||
|
|
||||||
|
public static VertexBuffer<ObjVertex>[] FromWavefront(string file)
|
||||||
|
{
|
||||||
|
var lines = File.ReadAllLines(file);
|
||||||
|
|
||||||
|
var buffer = Buffer<ObjVertex>.Empty(BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw,
|
||||||
|
$"{file} buffer");
|
||||||
|
|
||||||
|
var vs = new List<Vector3>();
|
||||||
|
var vts = new List<Vector2>();
|
||||||
|
var vns = new List<Vector3>();
|
||||||
|
var faces = new List<ObjVertex>();
|
||||||
|
var vertices = new List<ObjVertex>();
|
||||||
|
|
||||||
|
var name = file;
|
||||||
|
|
||||||
|
var vertBuffers = new List<VertexBuffer<ObjVertex>>();
|
||||||
|
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
if (line.StartsWith("#")) continue;
|
||||||
|
|
||||||
|
var items = line.Split(' ');
|
||||||
|
|
||||||
|
switch (items[0])
|
||||||
|
{
|
||||||
|
case "v":
|
||||||
|
var v = new Vector3(
|
||||||
|
float.Parse(items[1]),
|
||||||
|
float.Parse(items[2]),
|
||||||
|
float.Parse(items[3]));
|
||||||
|
vs.Add(v);
|
||||||
|
break;
|
||||||
|
case "vt":
|
||||||
|
var vt = new Vector2(
|
||||||
|
float.Parse(items[1]),
|
||||||
|
1 - float.Parse(items[2]));
|
||||||
|
vts.Add(vt);
|
||||||
|
break;
|
||||||
|
case "vn":
|
||||||
|
var vn = new Vector3(
|
||||||
|
float.Parse(items[1]),
|
||||||
|
float.Parse(items[2]),
|
||||||
|
float.Parse(items[3]));
|
||||||
|
vns.Add(vn);
|
||||||
|
break;
|
||||||
|
case "f":
|
||||||
|
for (var i = 1; i < 4; i++)
|
||||||
|
{
|
||||||
|
var inds = items[i].Split('/');
|
||||||
|
var vi = inds[0] == "" ? Vector3.Zero : vs[int.Parse(inds[0]) - 1];
|
||||||
|
var vti = inds[1] == "" ? Vector2.Zero : vts[int.Parse(inds[1]) - 1];
|
||||||
|
var vni = inds[2] == "" ? Vector3.Zero : vns[int.Parse(inds[2]) - 1];
|
||||||
|
var f = new ObjVertex(vi, vti, vni);
|
||||||
|
faces.Add(f);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "o":
|
||||||
|
if (faces.Count > 0)
|
||||||
|
{
|
||||||
|
var count = vertices.Count;
|
||||||
|
vertices.AddRange(faces);
|
||||||
|
vertBuffers.Add(new VertexBuffer<ObjVertex>(
|
||||||
|
buffer,
|
||||||
|
new SubArray<ObjVertex>(vertices.ToArray(), count, faces.Count),
|
||||||
|
PrimitiveType.Triangles,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
name = items[1];
|
||||||
|
faces.Clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (faces.Count > 0)
|
||||||
|
{
|
||||||
|
var count = vertices.Count;
|
||||||
|
vertices.AddRange(faces);
|
||||||
|
vertBuffers.Add(new VertexBuffer<ObjVertex>(
|
||||||
|
buffer, new SubArray<ObjVertex>(vertices.ToArray(), count, faces.Count),
|
||||||
|
PrimitiveType.Triangles,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = vertices.ToArray();
|
||||||
|
|
||||||
|
foreach (var vertexBuffer in vertBuffers)
|
||||||
|
vertexBuffer.Vertices.Array = data;
|
||||||
|
|
||||||
|
buffer.Data(vertices.ToArray());
|
||||||
|
|
||||||
|
return vertBuffers.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Diamond.Buffers;
|
|
||||||
using NLog;
|
|
||||||
using OpenTK;
|
|
||||||
using OpenTK.Graphics.OpenGL4;
|
|
||||||
|
|
||||||
namespace Diamond.Util
|
|
||||||
{
|
|
||||||
public class Mesh<T> where T : struct
|
|
||||||
{
|
|
||||||
private static readonly Logger Logger = LogManager.GetLogger("Mesh");
|
|
||||||
|
|
||||||
public SubArray<T> Vertices;
|
|
||||||
public PrimitiveType Primitive;
|
|
||||||
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
private static readonly VertexDataInfo tVdi;
|
|
||||||
|
|
||||||
static Mesh()
|
|
||||||
{
|
|
||||||
tVdi = VertexDataInfo.GetInfo<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mesh(T[] vertices, PrimitiveType primitive = PrimitiveType.Triangles)
|
|
||||||
: this(new SubArray<T>(vertices), primitive)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mesh(SubArray<T> vertices, PrimitiveType primitive = PrimitiveType.Triangles)
|
|
||||||
{
|
|
||||||
Vertices = vertices;
|
|
||||||
Primitive = primitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Draw()
|
|
||||||
{
|
|
||||||
tVdi.EnableVertexPointers();
|
|
||||||
|
|
||||||
GL.DrawArrays(Primitive, Vertices.Offset, Vertices.Length);
|
|
||||||
|
|
||||||
tVdi.DisableVertexPointers();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DrawInstanced<TI>(SubArray<TI> instanceArray) where TI : struct
|
|
||||||
{
|
|
||||||
var tiVdi = VertexDataInfo.GetInfo<TI>();
|
|
||||||
|
|
||||||
if (tiVdi.Divisor == 0)
|
|
||||||
{
|
|
||||||
Logger.Error("Cannot render mesh with instances of type {0} - Divisor is 0", typeof(TI).Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
tVdi.EnableVertexPointers();
|
|
||||||
tiVdi.EnableVertexPointers();
|
|
||||||
|
|
||||||
GL.DrawArraysInstancedBaseInstance(Primitive, Vertices.Offset, Vertices.Length, instanceArray.Length,
|
|
||||||
instanceArray.Offset);
|
|
||||||
|
|
||||||
tVdi.DisableVertexPointers();
|
|
||||||
tiVdi.DisableVertexPointers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Mesh
|
|
||||||
{
|
|
||||||
public static Mesh<ObjVertex>[] FromObj(string file, bool join = true)
|
|
||||||
{
|
|
||||||
var lines = File.ReadAllLines(file);
|
|
||||||
|
|
||||||
var meshes = new List<Mesh<ObjVertex>>();
|
|
||||||
var name = file;
|
|
||||||
var vs = new List<Vector3>();
|
|
||||||
var vts = new List<Vector2>();
|
|
||||||
var vns = new List<Vector3>();
|
|
||||||
var faces = new List<ObjVertex>();
|
|
||||||
|
|
||||||
foreach (var line in lines)
|
|
||||||
{
|
|
||||||
if (line.StartsWith("#")) continue;
|
|
||||||
|
|
||||||
var items = line.Split(' ');
|
|
||||||
|
|
||||||
switch (items[0])
|
|
||||||
{
|
|
||||||
case "v":
|
|
||||||
var v = new Vector3(
|
|
||||||
float.Parse(items[1]),
|
|
||||||
float.Parse(items[2]),
|
|
||||||
float.Parse(items[3]));
|
|
||||||
vs.Add(v);
|
|
||||||
break;
|
|
||||||
case "vt":
|
|
||||||
var vt = new Vector2(
|
|
||||||
float.Parse(items[1]),
|
|
||||||
1 - float.Parse(items[2]));
|
|
||||||
vts.Add(vt);
|
|
||||||
break;
|
|
||||||
case "vn":
|
|
||||||
var vn = new Vector3(
|
|
||||||
float.Parse(items[1]),
|
|
||||||
float.Parse(items[2]),
|
|
||||||
float.Parse(items[3]));
|
|
||||||
vns.Add(vn);
|
|
||||||
break;
|
|
||||||
case "f":
|
|
||||||
for (var i = 1; i < 4; i++)
|
|
||||||
{
|
|
||||||
var inds = items[i].Split('/');
|
|
||||||
var vi = inds[0] == "" ? Vector3.Zero : vs[int.Parse(inds[0]) - 1];
|
|
||||||
var vti = inds[1] == "" ? Vector2.Zero : vts[int.Parse(inds[1]) - 1];
|
|
||||||
var vni = inds[2] == "" ? Vector3.Zero : vns[int.Parse(inds[2]) - 1];
|
|
||||||
var f = new ObjVertex(vi, vti, vni);
|
|
||||||
faces.Add(f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "o":
|
|
||||||
if (faces.Count > 0)
|
|
||||||
{
|
|
||||||
meshes.Add(new Mesh<ObjVertex>(faces.ToArray()) {Name = name});
|
|
||||||
faces.Clear();
|
|
||||||
}
|
|
||||||
name = items[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (faces.Count > 0)
|
|
||||||
meshes.Add(new Mesh<ObjVertex>(faces.ToArray()) {Name = name});
|
|
||||||
|
|
||||||
if (join)
|
|
||||||
Join(meshes);
|
|
||||||
|
|
||||||
return meshes.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T[] Join<T>(params Mesh<T>[] meshes) where T : struct => Join((IEnumerable<Mesh<T>>) meshes);
|
|
||||||
|
|
||||||
public static T[] Join<T>(IEnumerable<Mesh<T>> meshes) where T : struct
|
|
||||||
{
|
|
||||||
return SubArray.Join(meshes.Select(x => x.Vertices));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -123,58 +123,58 @@ namespace Diamond.Util
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SubArray
|
public static class SubArray
|
||||||
{
|
{
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Make multiple subArrays cover the same array
|
// /// Make multiple subArrays cover the same array
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <typeparam name="T">The element type</typeparam>
|
// /// <typeparam name="T">The element type</typeparam>
|
||||||
/// <param name="subArrays">The SubArrays to join</param>
|
// /// <param name="subArrays">The SubArrays to join</param>
|
||||||
/// <returns>The new underlying array</returns>
|
// /// <returns>The new underlying array</returns>
|
||||||
public static T[] Join<T>(params SubArray<T>[] subArrays) => Join((IEnumerable<SubArray<T>>) subArrays);
|
// public static T[] Join<T>(params SubArray<T>[] subArrays) => Join((IEnumerable<SubArray<T>>) subArrays);
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Make multiple subArrays cover the same array
|
// /// Make multiple subArrays cover the same array
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <typeparam name="T">The element type</typeparam>
|
// /// <typeparam name="T">The element type</typeparam>
|
||||||
/// <param name="subArrays">The SubArrays to join</param>
|
// /// <param name="subArrays">The SubArrays to join</param>
|
||||||
/// <returns>The new underlying array</returns>
|
// /// <returns>The new underlying array</returns>
|
||||||
public static T[] Join<T>(IEnumerable<SubArray<T>> subArrays)
|
// public static T[] Join<T>(IEnumerable<SubArray<T>> subArrays)
|
||||||
{
|
// {
|
||||||
// todo: this breaks in the case: Join(a, b); Join(b, c)
|
// // todo: this breaks in the case: Join(a, b); Join(b, c)
|
||||||
// possibly create "multiarray" class or similar which would manage these operations
|
// // possibly create "multiarray" class or similar which would manage these operations
|
||||||
// and prevent this case from arising
|
// // and prevent this case from arising
|
||||||
|
//
|
||||||
var subArrList = subArrays.ToList(); // prevent multiple enumeration
|
// var subArrList = subArrays.ToList(); // prevent multiple enumeration
|
||||||
|
//
|
||||||
HashSet<T[]> uniqueArrays = new HashSet<T[]>();
|
// HashSet<T[]> uniqueArrays = new HashSet<T[]>();
|
||||||
foreach (var subArray in subArrList)
|
// foreach (var subArray in subArrList)
|
||||||
{
|
// {
|
||||||
uniqueArrays.Add(subArray.Array);
|
// uniqueArrays.Add(subArray.Array);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (uniqueArrays.Count == 0) return new T[0];
|
// if (uniqueArrays.Count == 0) return new T[0];
|
||||||
if (uniqueArrays.Count == 1) return uniqueArrays.ToArray()[0];
|
// if (uniqueArrays.Count == 1) return uniqueArrays.ToArray()[0];
|
||||||
|
//
|
||||||
var length = 0;
|
// var length = 0;
|
||||||
var offsets = new Dictionary<T[], int>();
|
// var offsets = new Dictionary<T[], int>();
|
||||||
foreach (var uniqueArray in uniqueArrays)
|
// foreach (var uniqueArray in uniqueArrays)
|
||||||
{
|
// {
|
||||||
offsets[uniqueArray] = length;
|
// offsets[uniqueArray] = length;
|
||||||
length += uniqueArray.Length;
|
// length += uniqueArray.Length;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var array = new T[length];
|
// var array = new T[length];
|
||||||
foreach (var uniqueArray in uniqueArrays)
|
// foreach (var uniqueArray in uniqueArrays)
|
||||||
{
|
// {
|
||||||
System.Array.ConstrainedCopy(uniqueArray, 0, array, offsets[uniqueArray], uniqueArray.Length);
|
// System.Array.ConstrainedCopy(uniqueArray, 0, array, offsets[uniqueArray], uniqueArray.Length);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
foreach (var subArray in subArrList)
|
// foreach (var subArray in subArrList)
|
||||||
{
|
// {
|
||||||
subArray.Offset = offsets[subArray.Array];
|
// subArray.Offset = offsets[subArray.Array];
|
||||||
subArray.Array = array;
|
// subArray.Array = array;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return array;
|
// return array;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Diamond.Buffers;
|
using Diamond.Buffers;
|
||||||
@@ -43,10 +44,10 @@ namespace hexworld
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private SubArray<TileData> _floorTiles;
|
private VertexBuffer<TileData> _floorTiles;
|
||||||
private SubArray<TileData> _doorTiles;
|
private VertexBuffer<TileData> _doorTiles;
|
||||||
|
|
||||||
private Mesh<ObjVertex> _cubeMesh;
|
private VertexBuffer<ObjVertex> _cubeMesh;
|
||||||
|
|
||||||
private Camera _camera;
|
private Camera _camera;
|
||||||
|
|
||||||
@@ -86,34 +87,29 @@ namespace hexworld
|
|||||||
.Select(arr => new SubArray<TileData>(arr))
|
.Select(arr => new SubArray<TileData>(arr))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
_doorTiles = allTiles[0];
|
var tileVbo = VertexBuffer.FromArrays(allTiles, 0, "tiles");
|
||||||
_floorTiles = allTiles[1];
|
|
||||||
|
_doorTiles = tileVbo[0];
|
||||||
|
_floorTiles = tileVbo[1];
|
||||||
|
|
||||||
var cubeMesh = json["models"]
|
var cubeMesh = json["models"]
|
||||||
.Select(path => (string) path)
|
.Select(path => (string) path)
|
||||||
.Select(path => Path.Combine(dir, path))
|
.Select(path => Path.Combine(dir, path))
|
||||||
.Select(path => Mesh.FromObj(path, false))
|
.Select(VertexBuffer.FromWavefront)
|
||||||
.SelectMany(meshes => meshes)
|
.SelectMany(meshes => meshes)
|
||||||
.First(mesh => mesh.Name == "Cube");
|
.First(mesh => mesh.Name == "Cube");
|
||||||
|
|
||||||
_cubeMesh = cubeMesh;
|
_cubeMesh = cubeMesh;
|
||||||
|
|
||||||
_tileBuffer = Buffer.FromData(SubArray.Join(_doorTiles, _floorTiles), BufferTarget.ArrayBuffer,
|
|
||||||
BufferUsageHint.DynamicDraw, "tile");
|
|
||||||
_meshBuffer = Buffer.FromData(cubeMesh.Vertices.ToArray(), BufferTarget.ArrayBuffer,
|
|
||||||
BufferUsageHint.StaticDraw, "mesh");
|
|
||||||
|
|
||||||
_camera = new Camera();
|
_camera = new Camera();
|
||||||
|
|
||||||
_renderGroup = new RenderGroup<TileData, ObjVertex>()
|
_renderGroup = new RenderGroup<TileData, ObjVertex>()
|
||||||
{
|
{
|
||||||
Camera = _camera,
|
Camera = _camera,
|
||||||
Vertices = _cubeMesh,
|
Instance = _floorTiles,
|
||||||
VertexBuffer = _meshBuffer,
|
|
||||||
Program = _texPgm,
|
Program = _texPgm,
|
||||||
Texture = _grassTex,
|
Vertices = _cubeMesh,
|
||||||
InstanceBuffer = _tileBuffer,
|
Texture = _grassTex
|
||||||
Instances = _floorTiles
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user