diff --git a/Diamond/Level/Level.cs b/Diamond/Level/Level.cs index 241b7e5..6554a78 100644 --- a/Diamond/Level/Level.cs +++ b/Diamond/Level/Level.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Drawing; using System.IO; using System.Linq; using Diamond.Buffers; using Diamond.Shaders; +using Diamond.Textures; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenTK; @@ -22,6 +24,8 @@ namespace Diamond.Level private Mesh[] _meshes; private TileGroup[] _tileGroups; + private Texture[] _textures; + private GLBuffer _tileBuffer; private GLBuffer _vertexBuffer; @@ -63,18 +67,26 @@ namespace Diamond.Level }) .ToDictionary(s => s.name, s => s.program); + var texturePaths = levelData["textures"] + .Select(path => (string) path) + .ToArray(); + var textures = texturePaths.Select(path => Texture.FromBitmap(new Bitmap(Path.Combine(dir, (string)path)))).ToArray(); + var textureMap = texturePaths.Select((path, i) => new {path = path, i = i}) + .ToDictionary(v => v.path, v => v.i); + var tilegroups = levelData["tiles"] .Select(tile => new { info = new { mesh = meshDict[(string) tile["mesh"]], - shader = programs[(string) tile["shader"]] + shader = programs[(string) tile["shader"]], + texture = textureMap[(string) tile["tex"]] }, pos = tile["pos"].ToObject() }) .GroupBy(tile => tile.info) - .Select(group => new TileGroup(group.Key.mesh, group.Key.shader, + .Select(group => new TileGroup(group.Key.mesh, group.Key.shader, group.Key.texture, new SubArray( group.Select(data => new TileData(data.pos)) .ToArray()))) @@ -91,7 +103,8 @@ namespace Diamond.Level _allVertices = allVertices, _meshes = meshes, _tileGroups = tilegroups, - Programs = programs + Programs = programs, + _textures = textures }; level.InitializeBuffers(); @@ -101,10 +114,17 @@ namespace Diamond.Level public void Draw() { + for (var i = 0; i < _textures.Length; i++) + { + var texture = _textures[i]; + texture.Bind(i); + } + foreach (var tileGroup in _tileGroups) { var pgm = tileGroup.Program; pgm.Use(); + GL.Uniform1(pgm.GetUniform("tex"), tileGroup.Texture); pgm.SetAttribPointers(_vertexBuffer); pgm.SetAttribPointers(_tileBuffer); tileGroup.Mesh.DrawInstanced(tileGroup.Tiles); @@ -116,6 +136,9 @@ namespace Diamond.Level _tileBuffer?.Dispose(); _vertexBuffer?.Dispose(); + foreach (var texture in _textures) + texture?.Dispose(); + foreach (var program in Programs.Values) program?.Dispose(); diff --git a/Diamond/Level/TileGroup.cs b/Diamond/Level/TileGroup.cs index 5687fd6..a5fc5db 100644 --- a/Diamond/Level/TileGroup.cs +++ b/Diamond/Level/TileGroup.cs @@ -8,12 +8,14 @@ namespace Diamond.Level public SubArray Tiles; public Mesh Mesh; public Program Program; + public int Texture; - public TileGroup(Mesh mesh, Program program, SubArray tiles) + public TileGroup(Mesh mesh, Program program, int texture, SubArray tiles) { Mesh = mesh; Program = program; Tiles = tiles; + Texture = texture; } } } \ No newline at end of file diff --git a/hexworld/HexRender.cs b/hexworld/HexRender.cs index c32db1b..bc3b124 100644 --- a/hexworld/HexRender.cs +++ b/hexworld/HexRender.cs @@ -15,22 +15,12 @@ namespace hexworld #region GLObjects - private Texture _grass; - private Texture _stone; - private Texture _gray; - private Texture _door; - private Level _level; protected override void OnClosed(EventArgs e) { base.OnClosed(e); - _grass?.Dispose(); - _stone?.Dispose(); - _gray?.Dispose(); - _door?.Dispose(); - _level?.Dispose(); } @@ -58,11 +48,6 @@ namespace hexworld base.OnLoad(e); _level = Level.LoadLevel(@"res\level.json"); - - _grass = Texture.FromBitmap(new Bitmap(@"res\grass.png")); - _stone = Texture.FromBitmap(new Bitmap(@"res\stone.png")); - _gray = Texture.FromBitmap(new Bitmap(@"res\gray.png")); - _door = Texture.FromBitmap(new Bitmap(@"res\door.png")); } protected override void OnUpdateFrame(FrameEventArgs e) @@ -90,14 +75,9 @@ namespace hexworld GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); - _grass.Bind(0); - _stone.Bind(1); - _gray.Bind(2); - _door.Bind(3); - var pgm = _level.Programs["textured"]; + pgm.Use(); - GL.Uniform1(pgm.GetUniform("tex"), 0); GL.UniformMatrix4(pgm.GetUniform("view"), false, ref _view); GL.UniformMatrix4(pgm.GetUniform("proj"), false, ref _proj); diff --git a/hexworld/res/level.json b/hexworld/res/level.json index f7ed942..7b71e5a 100644 --- a/hexworld/res/level.json +++ b/hexworld/res/level.json @@ -12,41 +12,46 @@ ] } ], + "textures": + [ + "grass.png", + "door.png" + ], "tiles": [ - { "mesh": "BaseLeft", "shader": "textured", "pos": { "x": -1, "y": 0, "z": 0 } }, - { "mesh": "BaseRight", "shader": "textured", "pos": { "x": 1, "y": 0, "z": 0 } }, - { "mesh": "Stairs", "shader": "textured", "pos": { "x": 0, "y": 0, "z": 0 } }, - { "mesh": "ColLeft", "shader": "textured", "pos": { "x": -1, "y": 0, "z": 1 } }, - { "mesh": "ColRight", "shader": "textured", "pos": { "x": 1, "y": 0, "z": 1 } }, - { "mesh": "ColLeft", "shader": "textured", "pos": { "x": -1, "y": 0, "z": 2 } }, - { "mesh": "ColRight", "shader": "textured", "pos": { "x": 1, "y": 0, "z": 2 } }, - { "mesh": "CapLeft", "shader": "textured", "pos": { "x": -1, "y": 0, "z": 3 } }, - { "mesh": "Lintel", "shader": "textured", "pos": { "x": 0, "y": 0, "z": 3 } }, - { "mesh": "CapRight", "shader": "textured", "pos": { "x": 1, "y": 0, "z": 3 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -2, "y": -2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -2, "y": -1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -2, "y": 0, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -2, "y": 1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -2, "y": 2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -1, "y": -2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -1, "y": -1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -1, "y": 0, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -1, "y": 1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": -1, "y": 2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 0, "y": -2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 0, "y": -1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 0, "y": 0, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 0, "y": 1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 0, "y": 2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 1, "y": -2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 1, "y": -1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 1, "y": 0, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 1, "y": 1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 1, "y": 2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 2, "y": -2, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 2, "y": -1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 2, "y": 0, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 2, "y": 1, "z": -1 } }, - { "mesh": "Cube", "shader": "textured", "pos": { "x": 2, "y": 2, "z": -1 } }, + { "mesh": "BaseLeft", "shader": "textured", "tex": "door.png", "pos": { "x": -1, "y": 0, "z": 0 } }, + { "mesh": "BaseRight", "shader": "textured", "tex": "door.png", "pos": { "x": 1, "y": 0, "z": 0 } }, + { "mesh": "Stairs", "shader": "textured", "tex": "door.png", "pos": { "x": 0, "y": 0, "z": 0 } }, + { "mesh": "ColLeft", "shader": "textured", "tex": "door.png", "pos": { "x": -1, "y": 0, "z": 1 } }, + { "mesh": "ColRight", "shader": "textured", "tex": "door.png", "pos": { "x": 1, "y": 0, "z": 1 } }, + { "mesh": "ColLeft", "shader": "textured", "tex": "door.png", "pos": { "x": -1, "y": 0, "z": 2 } }, + { "mesh": "ColRight", "shader": "textured", "tex": "door.png", "pos": { "x": 1, "y": 0, "z": 2 } }, + { "mesh": "CapLeft", "shader": "textured", "tex": "door.png", "pos": { "x": -1, "y": 0, "z": 3 } }, + { "mesh": "Lintel", "shader": "textured", "tex": "door.png", "pos": { "x": 0, "y": 0, "z": 3 } }, + { "mesh": "CapRight", "shader": "textured", "tex": "door.png", "pos": { "x": 1, "y": 0, "z": 3 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -2, "y": -2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -2, "y": -1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -2, "y": 0, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -2, "y": 1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -2, "y": 2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -1, "y": -2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -1, "y": -1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -1, "y": 0, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -1, "y": 1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": -1, "y": 2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 0, "y": -2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 0, "y": -1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 0, "y": 0, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 0, "y": 1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 0, "y": 2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 1, "y": -2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 1, "y": -1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 1, "y": 0, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 1, "y": 1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 1, "y": 2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 2, "y": -2, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 2, "y": -1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 2, "y": 0, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 2, "y": 1, "z": -1 } }, + { "mesh": "Cube", "shader": "textured", "tex": "grass.png", "pos": { "x": 2, "y": 2, "z": -1 } }, ] }