diff --git a/hexworld/Driver.cs b/hexworld/Driver.cs index 966bbd3..24e9c4a 100644 --- a/hexworld/Driver.cs +++ b/hexworld/Driver.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Newtonsoft.Json; +using OpenTK; namespace hexworld { diff --git a/hexworld/HexRender.cs b/hexworld/HexRender.cs index 9711c4e..e0eabee 100644 --- a/hexworld/HexRender.cs +++ b/hexworld/HexRender.cs @@ -1,132 +1,34 @@ using System; using System.Drawing; using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security.Policy; using hexworld.Util; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL4; namespace hexworld { - public struct Vertex - { - public Vector3 Position; - public Vector2 UV; - public Vector3 Normal; - - public Vertex(Vector3 position, Vector2 uv, Vector3 normal) - { - Position = position; - UV = uv; - Normal = normal; - } - } - - public struct Tile - { - public Vector3 Position; - - public Tile(Vector3 position) - { - Position = position; - } - } - - public class HexRender : GameWindow + public partial class HexRender : GameWindow { private Program pgm; + // todo: generate texture atlas + // or at least embed sub-uvs and materials into json private Texture grass; private Texture stone; - private Texture tex2; private Matrix4 view; private Matrix4 proj; - private VBO tileVbo; - private VBO cubeVbo; + private VBO tileVbo; + private VBO cubeVbo; - private readonly Vertex[] cubeVerts = - { - // +X - new Vertex(new Vector3(+.5f, +.5f, -.5f), new Vector2(1.0f, 0.5f), new Vector3(+1, +0, +0)), - new Vertex(new Vector3(+.5f, +.5f, +.5f), new Vector2(1.0f, 0.0f), new Vector3(+1, +0, +0)), - new Vertex(new Vector3(+.5f, -.5f, +.5f), new Vector2(0.5f, 0.0f), new Vector3(+1, +0, +0)), - new Vertex(new Vector3(+.5f, -.5f, +.5f), new Vector2(0.5f, 0.0f), new Vector3(+1, +0, +0)), - new Vertex(new Vector3(+.5f, -.5f, -.5f), new Vector2(0.5f, 0.5f), new Vector3(+1, +0, +0)), - new Vertex(new Vector3(+.5f, +.5f, -.5f), new Vector2(1.0f, 0.5f), new Vector3(+1, +0, +0)), - // -X - new Vertex(new Vector3(-.5f, +.5f, +.5f), new Vector2(0.5f, 0.0f), new Vector3(-1, +0, +0)), - new Vertex(new Vector3(-.5f, +.5f, -.5f), new Vector2(0.5f, 0.5f), new Vector3(-1, +0, +0)), - new Vertex(new Vector3(-.5f, -.5f, -.5f), new Vector2(1.0f, 0.5f), new Vector3(-1, +0, +0)), - new Vertex(new Vector3(-.5f, -.5f, -.5f), new Vector2(1.0f, 0.5f), new Vector3(-1, +0, +0)), - new Vertex(new Vector3(-.5f, -.5f, +.5f), new Vector2(1.0f, 0.0f), new Vector3(-1, +0, +0)), - new Vertex(new Vector3(-.5f, +.5f, +.5f), new Vector2(0.5f, 0.0f), new Vector3(-1, +0, +0)), - // +Y - new Vertex(new Vector3(+.5f, +.5f, -.5f), new Vector2(0.5f, 0.5f), new Vector3(+0, +1, +0)), - new Vertex(new Vector3(-.5f, +.5f, -.5f), new Vector2(1.0f, 0.5f), new Vector3(+0, +1, +0)), - new Vertex(new Vector3(-.5f, +.5f, +.5f), new Vector2(1.0f, 0.0f), new Vector3(+0, +1, +0)), - new Vertex(new Vector3(-.5f, +.5f, +.5f), new Vector2(1.0f, 0.0f), new Vector3(+0, +1, +0)), - new Vertex(new Vector3(+.5f, +.5f, +.5f), new Vector2(0.5f, 0.0f), new Vector3(+0, +1, +0)), - new Vertex(new Vector3(+.5f, +.5f, -.5f), new Vector2(0.5f, 0.5f), new Vector3(+0, +1, +0)), - // -Y - new Vertex(new Vector3(+.5f, -.5f, +.5f), new Vector2(1.0f, 0.0f), new Vector3(+0, -1, +0)), - new Vertex(new Vector3(-.5f, -.5f, +.5f), new Vector2(0.5f, 0.0f), new Vector3(+0, -1, +0)), - new Vertex(new Vector3(-.5f, -.5f, -.5f), new Vector2(0.5f, 0.5f), new Vector3(+0, -1, +0)), - new Vertex(new Vector3(-.5f, -.5f, -.5f), new Vector2(0.5f, 0.5f), new Vector3(+0, -1, +0)), - new Vertex(new Vector3(+.5f, -.5f, -.5f), new Vector2(1.0f, 0.5f), new Vector3(+0, -1, +0)), - new Vertex(new Vector3(+.5f, -.5f, +.5f), new Vector2(1.0f, 0.0f), new Vector3(+0, -1, +0)), - // +Z - new Vertex(new Vector3(+.5f, +.5f, +.5f), new Vector2(0.5f, 0.0f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(-.5f, +.5f, +.5f), new Vector2(0.0f, 0.0f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(-.5f, -.5f, +.5f), new Vector2(0.0f, 0.5f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(-.5f, -.5f, +.5f), new Vector2(0.0f, 0.5f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(+.5f, -.5f, +.5f), new Vector2(0.5f, 0.5f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(+.5f, +.5f, +.5f), new Vector2(0.5f, 0.0f), new Vector3(+0, +0, +1)), - // -Z - new Vertex(new Vector3(+.5f, +.5f, -.5f), new Vector2(0.5f, 0.5f), new Vector3(+0, +0, -1)), - new Vertex(new Vector3(-.5f, +.5f, -.5f), new Vector2(0.0f, 0.5f), new Vector3(+0, +0, -1)), - new Vertex(new Vector3(-.5f, -.5f, -.5f), new Vector2(0.0f, 1.0f), new Vector3(+0, +0, -1)), - new Vertex(new Vector3(-.5f, -.5f, -.5f), new Vector2(0.0f, 1.0f), new Vector3(+0, +0, -1)), - new Vertex(new Vector3(+.5f, -.5f, -.5f), new Vector2(0.5f, 1.0f), new Vector3(+0, +0, -1)), - new Vertex(new Vector3(+.5f, +.5f, -.5f), new Vector2(0.5f, 0.5f), new Vector3(+0, +0, -1)), - - // Plane - new Vertex(new Vector3(+.5f, +.5f, 0.0f), new Vector2(0.5f, 0.0f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(-.5f, +.5f, 0.0f), new Vector2(0.0f, 0.0f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(-.5f, -.5f, 0.0f), new Vector2(0.0f, 0.5f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(-.5f, -.5f, 0.0f), new Vector2(0.0f, 0.5f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(+.5f, -.5f, 0.0f), new Vector2(0.5f, 0.5f), new Vector3(+0, +0, +1)), - new Vertex(new Vector3(+.5f, +.5f, 0.0f), new Vector2(0.5f, 0.0f), new Vector3(+0, +0, +1)), - }; - - private Tile[] tiles = - { - // Grass - new Tile(new Vector3(-2, -2, 0)), - new Tile(new Vector3(-2, -1, 0)), - new Tile(new Vector3(-2, +0, 0)), - new Tile(new Vector3(-2, +1, 0)), - new Tile(new Vector3(-2, +2, 0)), - new Tile(new Vector3(+2, -2, 0)), - new Tile(new Vector3(+2, -1, 0)), - new Tile(new Vector3(+2, +0, 0)), - new Tile(new Vector3(+2, +1, 0)), - new Tile(new Vector3(+2, +2, 0)), - new Tile(new Vector3(-1, -2, 0)), - new Tile(new Vector3(-1, +2, 0)), - new Tile(new Vector3(+0, -2, 0)), - new Tile(new Vector3(+0, +2, 0)), - new Tile(new Vector3(+1, -2, 0)), - new Tile(new Vector3(+1, +2, 0)), - // Stone - new Tile(new Vector3(+0, +0, +1)), - new Tile(new Vector3(+0, +1, +1)), - new Tile(new Vector3(+0, -1, +1)), - new Tile(new Vector3(+1, +0, +1)), - new Tile(new Vector3(-1, +0, +1)), - }; - - public HexRender(int width, int height) : base(width, height, new GraphicsMode(32, 32, 0, 0)) + public HexRender(int width, int height) + : base(width, height, new GraphicsMode(32, 24, 0, 0)) { Width = width; Height = Height; @@ -134,7 +36,6 @@ namespace hexworld Y = (DisplayDevice.Default.Height - Height) / 2; } - private Random rand = new Random(); private double t; protected override void OnUpdateFrame(FrameEventArgs e) @@ -151,7 +52,6 @@ namespace hexworld tiles[i].Position.Z = (float) (Math.Sin((t + ti.Position.X - ti.Position.Y / 1.5) / 1.5) * .25); } -// tileVbo.Data(tiles, BufferUsageHint.DynamicDraw); tileVbo.Bind(); GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr) (0), (IntPtr) (16 * 3 * sizeof(float)), tiles); VBO.Unbind(); @@ -161,10 +61,10 @@ namespace hexworld { base.OnLoad(e); - cubeVbo = new VBO(); + cubeVbo = new VBO(); cubeVbo.Data(cubeVerts, BufferUsageHint.StaticDraw); - tileVbo = new VBO(); + tileVbo = new VBO(); tileVbo.Data(tiles, BufferUsageHint.DynamicDraw); var vs = new Shader(ShaderType.VertexShader) @@ -187,31 +87,8 @@ namespace hexworld pgm.Link(); Console.Out.WriteLine(pgm.Log); - var pos = pgm.GetAttribute("locpos"); - var crd = pgm.GetAttribute("coord"); - var nrm = pgm.GetAttribute("norm"); - var tpos = pgm.GetAttribute("glbpos"); - - GL.EnableVertexAttribArray(pos); - GL.EnableVertexAttribArray(crd); - GL.EnableVertexAttribArray(nrm); - GL.EnableVertexAttribArray(tpos); - - cubeVbo.Bind(); - - GL.VertexAttribPointer(pos, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), - 0); - GL.VertexAttribPointer(crd, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), - 3 * sizeof(float)); - GL.VertexAttribPointer(nrm, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), - 5 * sizeof(float)); - - tileVbo.Bind(); - - GL.VertexAttribPointer(tpos, 3, VertexAttribPointerType.Float, false, 0, 0); - GL.VertexAttribDivisor(tpos, 1); - - VBO.Unbind(); + cubeVbo.AttribPointers(pgm); + tileVbo.AttribPointers(pgm); grass = Texture.FromBitmap(new Bitmap("grass.png")); stone = Texture.FromBitmap(new Bitmap("stone.png")); @@ -223,16 +100,18 @@ namespace hexworld GL.Viewport(ClientRectangle); - GL.ClearColor(0.2392157F,0.5607843F,0.9960784F, 1f); + GL.ClearColor(0.2392157F, 0.5607843F, 0.9960784F, 1f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.Enable(EnableCap.DepthTest); GL.DepthFunc(DepthFunction.Lequal); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); - + GL.Enable(EnableCap.CullFace); + GL.CullFace(CullFaceMode.Back); pgm.Use(); + pgm.EnableAllAttribArrays(); grass.Bind(0); stone.Bind(1); @@ -247,9 +126,10 @@ namespace hexworld GL.UniformMatrix4(pgm.GetUniform("view"), false, ref view); GL.UniformMatrix4(pgm.GetUniform("proj"), false, ref proj); -// GL.DrawArraysInstancedBaseInstance(PrimitiveType.Triangles, 36, 6, 5, 16); GL.DrawArraysInstancedBaseInstance(PrimitiveType.Triangles, 0, 36, 5, 16); + pgm.DisableAllAttribArrays(); + SwapBuffers(); } } diff --git a/hexworld/Util/Program.cs b/hexworld/Util/Program.cs index 3119c58..48ff816 100644 --- a/hexworld/Util/Program.cs +++ b/hexworld/Util/Program.cs @@ -47,20 +47,42 @@ namespace hexworld.Util return true; } + public bool TryGetUniform(string name, out int id) + { + return uniforms.TryGetValue(name, out id); + } + public int GetUniform(string name) { - if (!uniforms.TryGetValue(name, out int id)) + if (!TryGetUniform(name, out int id)) throw new ShaderException($"Shader Program {Id} does not contain uniform '{name}'"); return id; } + public bool TryGetAttribute(string name, out int id) + { + return attributes.TryGetValue(name, out id); + } + public int GetAttribute(string name) { - if (!attributes.TryGetValue(name, out int id)) - throw new ShaderException($"Shader Program {Id} does not contain attribute '{name}'"); + if (!TryGetAttribute(name, out int id)) + throw new ShaderException($"Shader Program {Id} does not contain id '{name}'"); return id; } + public void EnableAllAttribArrays() + { + foreach (var loc in attributes.Values) + GL.EnableVertexAttribArray(loc); + } + + public void DisableAllAttribArrays() + { + foreach (var loc in attributes.Values) + GL.DisableVertexAttribArray(loc); + } + public void Use() => GL.UseProgram(Id); public static void UseDefault() => GL.UseProgram(0); diff --git a/hexworld/Util/VBO.cs b/hexworld/Util/VBO.cs index 500c6b9..b30187f 100644 --- a/hexworld/Util/VBO.cs +++ b/hexworld/Util/VBO.cs @@ -8,7 +8,15 @@ using OpenTK.Graphics.OpenGL4; namespace hexworld.Util { - public class VBO : GLObject + public static class VBO + { + public static void Unbind() + { + GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + } + } + + public class VBO : GLObject where T : struct { public VBO() : base((uint) GL.GenBuffer()) @@ -20,17 +28,49 @@ namespace hexworld.Util GL.BindBuffer(BufferTarget.ArrayBuffer, Id); } - public void Data(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw) where T : struct + public void Data(T[] data, BufferUsageHint usage = BufferUsageHint.StaticDraw) { Bind(); var size = Marshal.SizeOf(); - GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(size * data.Length), data, usage); - Unbind(); + GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (size * data.Length), data, usage); + VBO.Unbind(); } - public static void Unbind() + // todo: this needs a better solution. + private static readonly int Stride; + private static readonly VertexPointerAttribute[] Attributes; + + static VBO() { - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + var attribList = new List(); + Stride = Marshal.SizeOf(); + + foreach (var fieldInfo in typeof(T).GetFields()) + { + var attrs = fieldInfo.GetCustomAttributes(typeof(VertexPointerAttribute), false); + if (attrs.Length == 0) continue; + var offset = (int) Marshal.OffsetOf(fieldInfo.Name); + foreach (var attr in attrs) + { + var vpa = (VertexPointerAttribute) attr; + vpa.Offset = offset; + attribList.Add(vpa); + } + } + + Attributes = attribList.ToArray(); + } + + public void AttribPointers(Program pgm) + { + Bind(); + foreach (var attr in Attributes) + { + if (!pgm.TryGetAttribute(attr.Name, out int loc)) continue; + GL.VertexAttribPointer(loc, attr.Size, attr.Type, attr.Normalized, Stride, attr.Offset); + GL.VertexAttribDivisor(loc, attr.Divisor); + } + VBO.Unbind(); } } } \ No newline at end of file diff --git a/hexworld/Util/VertexPointerAttribute.cs b/hexworld/Util/VertexPointerAttribute.cs new file mode 100644 index 0000000..0892757 --- /dev/null +++ b/hexworld/Util/VertexPointerAttribute.cs @@ -0,0 +1,22 @@ +using System; +using OpenTK.Graphics.OpenGL4; + +namespace hexworld.Util +{ + [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = true)] + public sealed class VertexPointerAttribute : Attribute + { + public string Name { get; } + public int Size { get; } + public VertexAttribPointerType Type { get; set; } = VertexAttribPointerType.Float; + public bool Normalized { get; set; } = false; + public int Divisor { get; set; } = 0; + public int Offset { get; set; } = 0; + + public VertexPointerAttribute(string name, int size) + { + Name = name; + Size = size; + } + } +} \ No newline at end of file diff --git a/hexworld/VertexData.cs b/hexworld/VertexData.cs new file mode 100644 index 0000000..522487d --- /dev/null +++ b/hexworld/VertexData.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using hexworld.Util; +using Newtonsoft.Json; +using OpenTK; + +namespace hexworld +{ + public partial class HexRender + { + public struct Tile + { + [JsonProperty("pos")] + [VertexPointer("glbpos", 3, Divisor = 1)] + public Vector3 Position; + + public Tile(Vector3 position) + { + Position = position; + } + } + + public struct Vertex + { + [JsonProperty("pos")] + [VertexPointer("locpos", 3)] + public Vector3 Position; + + [JsonProperty("uv")] + [VertexPointer("coord", 2)] + public Vector2 UV; + + [JsonProperty("norm")] + [VertexPointer("norm", 3)] + public Vector3 Normal; + + public Vertex(Vector3 position, Vector2 uv, Vector3 normal) + { + Position = position; + UV = uv; + Normal = normal; + } + } + + private readonly Vertex[] cubeVerts = JsonConvert.DeserializeObject(File.ReadAllText("cube.json")); + private Tile[] tiles = JsonConvert.DeserializeObject(File.ReadAllText("tiles.json")); + } +} \ No newline at end of file diff --git a/hexworld/cube.json b/hexworld/cube.json new file mode 100644 index 0000000..e137050 --- /dev/null +++ b/hexworld/cube.json @@ -0,0 +1,38 @@ +[ + { "pos": { "x": .5, "y": .5, "z": -.5 }, "uv": { "x": 1, "y": .5 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": 0 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": 0 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": 0 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": -.5 }, "uv": { "x": 1, "y": .5 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": 0 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": .5, "z": -.5 }, "uv": { "x": 1, "y": .5 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": 0 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": 0 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": .5, "z": -.5 }, "uv": { "x": 1, "y": .5 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": 0 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": 0 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": .5 }, "uv": { "x": .5, "y": 0 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": 1, "y": 0 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": 0 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": -.5 }, "uv": { "x": 1, "y": .5 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": 1, "y": 0 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": .5 }, "uv": { "x": .5, "y": 0 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 0, "y": 0 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": -.5, "y": -.5, "z": .5 }, "uv": { "x": 0, "y": .5 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": -.5, "y": -.5, "z": .5 }, "uv": { "x": 0, "y": .5 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": .5, "y": .5, "z": .5 }, "uv": { "x": .5, "y": .0 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": .5, "y": -.5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": 0, "y": 0, "z": -1 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": 0, "y": .5 }, "norm": { "x": 0, "y": 0, "z": -1 } }, + { "pos": { "x": -.5, "y": .5, "z": -.5 }, "uv": { "x": 0, "y": 0 }, "norm": { "x": 0, "y": 0, "z": -1 } }, + { "pos": { "x": -.5, "y": .5, "z": -.5 }, "uv": { "x": 0, "y": 0 }, "norm": { "x": 0, "y": 0, "z": -1 } }, + { "pos": { "x": .5, "y": .5, "z": -.5 }, "uv": { "x": .5, "y": 0 }, "norm": { "x": 0, "y": 0, "z": -1 } }, + { "pos": { "x": .5, "y": -.5, "z": -.5 }, "uv": { "x": .5, "y": .5 }, "norm": { "x": 0, "y": 0, "z": -1 } }, +] \ No newline at end of file diff --git a/hexworld/hexworld.csproj b/hexworld/hexworld.csproj index a20381a..97a31c4 100644 --- a/hexworld/hexworld.csproj +++ b/hexworld/hexworld.csproj @@ -51,6 +51,7 @@ + @@ -61,6 +62,7 @@ + @@ -72,6 +74,12 @@ Always + + Always + + + Always + diff --git a/hexworld/tiles.json b/hexworld/tiles.json new file mode 100644 index 0000000..207b544 --- /dev/null +++ b/hexworld/tiles.json @@ -0,0 +1,23 @@ +[ + { "pos": { "x": -2, "y": -2, "z": 0 } }, + { "pos": { "x": -2, "y": -1, "z": 0 } }, + { "pos": { "x": -2, "y": 0, "z": 0 } }, + { "pos": { "x": -2, "y": 1, "z": 0 } }, + { "pos": { "x": -2, "y": 2, "z": 0 } }, + { "pos": { "x": 2, "y": -2, "z": 0 } }, + { "pos": { "x": 2, "y": -1, "z": 0 } }, + { "pos": { "x": 2, "y": 0, "z": 0 } }, + { "pos": { "x": 2, "y": 1, "z": 0 } }, + { "pos": { "x": 2, "y": 2, "z": 0 } }, + { "pos": { "x": -1, "y": -2, "z": 0 } }, + { "pos": { "x": -1, "y": 2, "z": 0 } }, + { "pos": { "x": 0, "y": -2, "z": 0 } }, + { "pos": { "x": 0, "y": 2, "z": 0 } }, + { "pos": { "x": 1, "y": -2, "z": 0 } }, + { "pos": { "x": 1, "y": 2, "z": 0 } }, + { "pos": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": 0, "y": 1, "z": 1 } }, + { "pos": { "x": 0, "y": -1, "z": 1 } }, + { "pos": { "x": -1, "y": 0, "z": 1 } }, + { "pos": { "x": 1, "y": 0, "z": 1 } } +] \ No newline at end of file