diff --git a/Diamond/Buffers/SubArray.cs b/Diamond/Buffers/SubArray.cs index 9249399..822beb1 100644 --- a/Diamond/Buffers/SubArray.cs +++ b/Diamond/Buffers/SubArray.cs @@ -13,19 +13,13 @@ namespace Diamond.Buffers public int Offset; public int Length; - public T this[int i] + public ref T this[int i] { get { if (i < 0 || i >= Length) throw new IndexOutOfRangeException("Index out of bounds of subarray"); - return Array[i + Offset]; - } - set - { - if (i < 0 || i >= Length) - throw new IndexOutOfRangeException("Index out of bounds of subarray."); - Array[i + Offset] = value; + return ref Array[i + Offset]; } } diff --git a/hexworld/HexRender.cs b/hexworld/HexRender.cs index 20e0995..fbe520d 100644 --- a/hexworld/HexRender.cs +++ b/hexworld/HexRender.cs @@ -24,15 +24,18 @@ namespace hexworld private Texture _grass; private Texture _stone; + private Texture _gray; private Matrix4 _view; private Matrix4 _proj; private SubArray _grassTiles; private SubArray _stoneTiles; + private SubArray _grayTiles; private SubArray _cubeVertices; private SubArray _panelVertices; + private SubArray _sidesVertices; private Tile[] _allTiles; private Vertex[] _allVertices; @@ -51,29 +54,6 @@ namespace hexworld Y = (DisplayDevice.Default.Height - Height) / 2; } - protected override void OnUpdateFrame(FrameEventArgs e) - { - base.OnUpdateFrame(e); - - _time += e.Time; - - _view = Matrix4.LookAt(10 * Vector3.One, Vector3.Zero, Vector3.UnitZ); - _proj = Matrix4.CreateOrthographic(Width / 100f, Height / 100f, -100, 100); - - for (var i = 0; i < _grassTiles.Length; i++) - { - var ti = _grassTiles[i]; - ti.Position.Z = (float) (Math.Sin((_time + ti.Position.X - ti.Position.Y / 1.5) / 1.5) * .25); - _grassTiles[i] = ti; - } - - _tileBuffer.SubData(_grassTiles); - - _tileBuffer.Bind(); - GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr) (5 * 3 * sizeof(float)), - (IntPtr) (16 * 3 * sizeof(float)), _grassTiles.ToArray()); - } - protected override void OnLoad(EventArgs e) { base.OnLoad(e); @@ -104,14 +84,18 @@ namespace hexworld JsonConvert.DeserializeObject(File.ReadAllText("data_vert_cubes.json"))); _panelVertices = new SubArray( JsonConvert.DeserializeObject(File.ReadAllText("data_vert_panels.json"))); + _sidesVertices = new SubArray( + JsonConvert.DeserializeObject(File.ReadAllText("data_vert_sides.json"))); _grassTiles = new SubArray( JsonConvert.DeserializeObject(File.ReadAllText("data_tile_grass.json"))); _stoneTiles = new SubArray( JsonConvert.DeserializeObject(File.ReadAllText("data_tile_stone.json"))); + _grayTiles = new SubArray( + JsonConvert.DeserializeObject(File.ReadAllText("data_tile_gray.json"))); - _allTiles = SubArray.Join(_stoneTiles, _grassTiles); - _allVertices = SubArray.Join(_panelVertices, _cubeVertices); + _allTiles = SubArray.Join(_stoneTiles, _grassTiles, _grayTiles); + _allVertices = SubArray.Join(_panelVertices, _cubeVertices, _sidesVertices); _tileBuffer = new Buffer(BufferTarget.ArrayBuffer, BufferUsageHint.DynamicDraw); _tileBuffer.Data(_allTiles); @@ -124,19 +108,30 @@ namespace hexworld _grass = Texture.FromBitmap(new Bitmap("grass.png")); _stone = Texture.FromBitmap(new Bitmap("stone.png")); + _gray = Texture.FromBitmap(new Bitmap("gray.png")); } - protected override void OnClosed(EventArgs e) + protected override void OnUpdateFrame(FrameEventArgs e) { - base.OnClosed(e); + base.OnUpdateFrame(e); - _pgm.Dispose(); + _time += e.Time; - _tileBuffer.Dispose(); - _vertexBuffer.Dispose(); + _view = Matrix4.CreateRotationZ((float) _time/3)*Matrix4.LookAt(10 * Vector3.One, Vector3.Zero, Vector3.UnitZ); + _proj = Matrix4.CreateOrthographic(Width / 100f, Height / 100f, -100, 100); - _grass.Dispose(); - _stone.Dispose(); + for (var i = 0; i < _grassTiles.Length; i++) + { + var ti = _grassTiles[i]; + _grassTiles[i].Position.Z = + (float) (Math.Sin((_time + ti.Position.X - ti.Position.Y / 1.5) / 1.5) * .25); + } + + _tileBuffer.SubData(_grassTiles); + + _tileBuffer.Bind(); + GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr) (5 * 3 * sizeof(float)), + (IntPtr) (16 * 3 * sizeof(float)), _grassTiles.ToArray()); } protected override void OnRenderFrame(FrameEventArgs e) @@ -160,6 +155,7 @@ namespace hexworld _grass.Bind(0); _stone.Bind(1); + _gray.Bind(2); GL.Uniform1(_pgm.GetUniform("tex"), 0); GL.UniformMatrix4(_pgm.GetUniform("view"), false, ref _view); @@ -177,9 +173,31 @@ namespace hexworld _panelVertices.Offset, _panelVertices.Length, _stoneTiles.Length, _stoneTiles.Offset); + GL.Uniform1(_pgm.GetUniform("tex"), 2); + GL.UniformMatrix4(_pgm.GetUniform("view"), false, ref _view); + GL.UniformMatrix4(_pgm.GetUniform("proj"), false, ref _proj); + + GL.DrawArraysInstancedBaseInstance(PrimitiveType.Triangles, + _sidesVertices.Offset, _sidesVertices.Length, + _grayTiles.Length, _grayTiles.Offset); + _pgm.DisableAllAttribArrays(); SwapBuffers(); } + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + + _pgm.Dispose(); + + _tileBuffer.Dispose(); + _vertexBuffer.Dispose(); + + _grass.Dispose(); + _stone.Dispose(); + _gray.Dispose(); + } } } \ No newline at end of file diff --git a/hexworld/data_tile_gray.json b/hexworld/data_tile_gray.json new file mode 100644 index 0000000..faa6954 --- /dev/null +++ b/hexworld/data_tile_gray.json @@ -0,0 +1,12 @@ +[ + { "pos": { "x": 0, "y": 0, "z": 0 } }, + { "pos": { "x": -1, "y": -1, "z": 0 } }, + { "pos": { "x": 0, "y": -1, "z": 0 } }, + { "pos": { "x": 1, "y": -1, "z": 0 } }, + { "pos": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": 0, "y": 0, "z": 0 } }, + { "pos": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": -1, "y": 1, "z": 0 } }, + { "pos": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": 1, "y": 1, "z": 0 } }, +] \ No newline at end of file diff --git a/hexworld/data_vert_panels.json b/hexworld/data_vert_panels.json index 1a724dc..cd2aa46 100644 --- a/hexworld/data_vert_panels.json +++ b/hexworld/data_vert_panels.json @@ -1,28 +1,28 @@ [ - { "pos": { "x": .5, "y": .5, "z": .3 }, "uv": { "x": 1, "y": .3 }, "norm": { "x": 1, "y": 0, "z": 0 } }, - { "pos": { "x": .5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": .2 }, "norm": { "x": 1, "y": 0, "z": 0 } }, - { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": .2 }, "norm": { "x": 1, "y": 0, "z": 0 } }, - { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": .2 }, "norm": { "x": 1, "y": 0, "z": 0 } }, - { "pos": { "x": .5, "y": -.5, "z": .3 }, "uv": { "x": .5, "y": .3 }, "norm": { "x": 1, "y": 0, "z": 0 } }, - { "pos": { "x": .5, "y": .5, "z": .3 }, "uv": { "x": 1, "y": .3 }, "norm": { "x": 1, "y": 0, "z": 0 } }, - { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": .2 }, "norm": { "x": -1, "y": 0, "z": 0 } }, - { "pos": { "x": -.5, "y": .5, "z": .3 }, "uv": { "x": 1, "y": .3 }, "norm": { "x": -1, "y": 0, "z": 0 } }, - { "pos": { "x": -.5, "y": -.5, "z": .3 }, "uv": { "x": .5, "y": .3 }, "norm": { "x": -1, "y": 0, "z": 0 } }, - { "pos": { "x": -.5, "y": -.5, "z": .3 }, "uv": { "x": .5, "y": .3 }, "norm": { "x": -1, "y": 0, "z": 0 } }, - { "pos": { "x": -.5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": .2 }, "norm": { "x": -1, "y": 0, "z": 0 } }, - { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": .2 }, "norm": { "x": -1, "y": 0, "z": 0 } }, - { "pos": { "x": .5, "y": .5, "z": .3 }, "uv": { "x": .5, "y": .3 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": -.5, "y": .5, "z": .3 }, "uv": { "x": 1, "y": .3 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": .2 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": -.5, "y": .5, "z": .5 }, "uv": { "x": 1, "y": .2 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": .5, "y": .5, "z": .5 }, "uv": { "x": .5, "y": .2 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": .5, "y": .5, "z": .3 }, "uv": { "x": .5, "y": .3 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": 1, "y": .2 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": -.5, "y": -.5, "z": .5 }, "uv": { "x": .5, "y": .2 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": -.5, "y": -.5, "z": .3 }, "uv": { "x": .5, "y": .3 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": -.5, "y": -.5, "z": .3 }, "uv": { "x": .5, "y": .3 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": .5, "y": -.5, "z": .3 }, "uv": { "x": 1, "y": .3 }, "norm": { "x": 0, "y": 1, "z": 0 } }, - { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": 1, "y": .2 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": .3 }, "uv": { "x": 1, "y": .1 }, "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": .3 }, "uv": { "x": .5, "y": .1 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": .3 }, "uv": { "x": 1, "y": .1 }, "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": .3 }, "uv": { "x": 1, "y": .1 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": .3 }, "uv": { "x": .5, "y": .1 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": .3 }, "uv": { "x": .5, "y": .1 }, "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": .3 }, "uv": { "x": .5, "y": .1 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": .5, "z": .3 }, "uv": { "x": 1, "y": .1 }, "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": .3 }, "uv": { "x": .5, "y": .1 }, "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": .3 }, "uv": { "x": .5, "y": .1 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": .3 }, "uv": { "x": .5, "y": .1 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": .3 }, "uv": { "x": 1, "y": .1 }, "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 } }, diff --git a/hexworld/data_vert_sides.json b/hexworld/data_vert_sides.json new file mode 100644 index 0000000..e3df8a5 --- /dev/null +++ b/hexworld/data_vert_sides.json @@ -0,0 +1,43 @@ +[ + { "pos": { "x": .5, "y": .5, "z": -.5 }, "uv": { "x": .25, "y": .5 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": .5 }, "uv": { "x": .25, "y": 0 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": 0, "y": 0 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": 0, "y": 0 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": -.5, "z": -.5 }, "uv": { "x": 0, "y": .5 }, "norm": { "x": 1, "y": 0, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": -.5 }, "uv": { "x": .25, "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": .5, "y": .5 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .75, "y": .5 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .75, "y": .5 }, "norm": { "x": -1, "y": 0, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": .5 }, "uv": { "x": .75, "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": .25, "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": .5, "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": .25, "y": 0 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": .5, "y": .5, "z": -.5 }, "uv": { "x": .25, "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": .75, "y": 0 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .75, "y": .5 }, "norm": { "x": 0, "y": 1, "z": 0 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .75, "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": .25, "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": 1 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": -.5, "y": -.5, "z": .5 }, "uv": { "x": 0, "y": 1 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": .5, "y": -.5, "z": .5 }, "uv": { "x": .25, "y": 1 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + { "pos": { "x": .5, "y": .5, "z": .5 }, "uv": { "x": .25, "y": .5 }, "norm": { "x": 0, "y": 0, "z": 1 } }, + + { "pos": { "x": .5, "y": -.5, "z": -.5 }, "uv": { "x": .5, "y": 1 }, "norm": { "x": 0, "y": 0, "z": -1 } }, + { "pos": { "x": -.5, "y": -.5, "z": -.5 }, "uv": { "x": .25, "y": 1 }, "norm": { "x": 0, "y": 0, "z": -1 } }, + { "pos": { "x": -.5, "y": .5, "z": -.5 }, "uv": { "x": .25, "y": .5 }, "norm": { "x": 0, "y": 0, "z": -1 } }, + { "pos": { "x": -.5, "y": .5, "z": -.5 }, "uv": { "x": .25, "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": 1 }, "norm": { "x": 0, "y": 0, "z": -1 } }, +] \ No newline at end of file diff --git a/hexworld/gray.png b/hexworld/gray.png new file mode 100644 index 0000000..2b8dd16 Binary files /dev/null and b/hexworld/gray.png differ diff --git a/hexworld/hexworld.csproj b/hexworld/hexworld.csproj index 77915c6..e6417f5 100644 --- a/hexworld/hexworld.csproj +++ b/hexworld/hexworld.csproj @@ -59,9 +59,15 @@ + + Always + Always + + Always + Always @@ -84,6 +90,9 @@ Always + + Always + Always diff --git a/hexworld/stone.png b/hexworld/stone.png index 1240af3..b01162e 100644 Binary files a/hexworld/stone.png and b/hexworld/stone.png differ