From 492c76262bdd9d8ce6ebe5f7111a9ebab6db25f6 Mon Sep 17 00:00:00 2001 From: chrisf Date: Wed, 11 Jul 2007 10:53:48 +0000 Subject: [PATCH] git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1168 993157c7-ee19-0410-b2c4-bb4e9862e678 --- OpenRa.Game/Actor.cs | 160 --------------------------------- OpenRa.Game/MainWindow.cs | 20 +---- OpenRa.Game/OpenRa.Game.csproj | 3 + OpenRa.Game/Tree.cs | 17 ++++ OpenRa.Game/TreeCache.cs | 56 ++++++++++++ OpenRa.Game/World.cs | 112 +++++++++++++++++++++++ 6 files changed, 192 insertions(+), 176 deletions(-) create mode 100644 OpenRa.Game/Tree.cs create mode 100644 OpenRa.Game/TreeCache.cs create mode 100644 OpenRa.Game/World.cs diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index c459f67846..0b8ed203ef 100644 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -13,164 +13,4 @@ namespace OpenRa.Game public PointF location; public SheetRectangle[] currentImages; } - - class Tree : Actor - { - public Tree( TreeReference r, TreeCache renderer, Map map ) - { - location = new PointF(24 * (r.X - map.XOffset), 24 * (r.Y - map.YOffset)); - currentImages = new SheetRectangle[] { renderer.GetImage( r.Image ) }; - } - } - - class TreeCache - { - Dictionary> trees = new Dictionary>(); - - public readonly Sheet sh; - - public TreeCache(GraphicsDevice device, Map map, Package package, Palette pal) - { - Size pageSize = new Size( 1024, 512 ); - List sheets = new List(); - - Provider sheetProvider = delegate - { - Sheet sheet = new Sheet(new Bitmap(pageSize.Width, pageSize.Height)); - sheets.Add(sheet); - return sheet; - }; - - TileSheetBuilder builder = new TileSheetBuilder(pageSize, sheetProvider); - - foreach (TreeReference r in map.Trees) - { - if (trees.ContainsKey( r.Image )) - continue; - - ShpReader reader = new ShpReader(package.GetContent(r.Image + "." + map.Theater.Substring(0,3))); - Bitmap bitmap = BitmapBuilder.FromBytes(reader[0].Image, reader.Width, reader.Height, pal); - - SheetRectangle rect = builder.AddImage(bitmap.Size); - using (Graphics g = Graphics.FromImage(rect.sheet.bitmap)) - g.DrawImage(bitmap, rect.origin); - - trees.Add(r.Image, rect); - } - - foreach (Sheet sheet in sheets) - sheet.LoadTexture(device); - - sh = sheets[0]; - } - - public SheetRectangle GetImage( string tree ) - { - return trees[tree]; - } - } - - class World - { - const int spritesPerBatch = 1024; - - List actors = new List(); - FvfVertexBuffer vb; - IndexBuffer ib; - GraphicsDevice device; - - public World(GraphicsDevice device) - { - this.device = device; - this.vb = new FvfVertexBuffer(device, spritesPerBatch * 4, Vertex.Format); - this.ib = new IndexBuffer(device, spritesPerBatch * 6); - } - - public void Add(Actor a) - { - actors.Add(a); //todo: protect from concurrent modification - } - - // assumption: there is only one sheet! - // some noob needs to fix this! - - // assumption: its not going to hurt, to draw *all* units. - // in reality, 500 tanks is going to hurt our perf. - - public void Draw( Renderer renderer ) - { - int sprites = 0; - List vertices = new List(); - List indices = new List(); - Sheet sheet = null; - - foreach (Actor a in actors) - { - if (a.currentImages == null) - continue; - - foreach (SheetRectangle image in a.currentImages) - { - int offset = vertices.Count; - vertices.Add(new Vertex(a.location.X, a.location.Y, 0, U(image, 0), V(image, 0))); - vertices.Add(new Vertex(a.location.X + image.size.Width, a.location.Y, 0, U(image, 1), V(image, 0))); - vertices.Add(new Vertex(a.location.X, a.location.Y + image.size.Height, 0, U(image, 0), V(image, 1))); - vertices.Add(new Vertex(a.location.X + image.size.Width, a.location.Y + image.size.Height, 0, U(image, 1), V(image, 1))); - - indices.Add((ushort)offset); - indices.Add((ushort)(offset + 1)); - indices.Add((ushort)(offset + 2)); - - indices.Add((ushort)(offset + 1)); - indices.Add((ushort)(offset + 3)); - indices.Add((ushort)(offset + 2)); - - sheet = image.sheet; - - if (++sprites >= spritesPerBatch) - { - DrawBatch(vertices, indices, renderer, sheet); - - vertices = new List(); - indices = new List(); - sprites = 0; - } - } - } - - if (sprites > 0) - DrawBatch(vertices, indices, renderer, sheet); - } - - void DrawBatch(List vertices, List indices, Renderer renderer, Sheet sheet) - { - vb.SetData(vertices.ToArray()); - ib.SetData(indices.ToArray()); - - renderer.DrawWithShader(ShaderQuality.High, - delegate - { - renderer.DrawBatch(vb, ib, - new Range(0, vertices.Count), - new Range(0, indices.Count), - sheet.texture); - }); - } - - static float U(SheetRectangle s, float u) - { - float u0 = (float)(s.origin.X + 0.5f) / (float)s.sheet.bitmap.Width; - float u1 = (float)(s.origin.X + s.size.Width) / (float)s.sheet.bitmap.Width; - - return (u > 0) ? u1 : u0;// (1 - u) * u0 + u * u1; - } - - static float V(SheetRectangle s, float v) - { - float v0 = (float)(s.origin.Y + 0.5f) / (float)s.sheet.bitmap.Height; - float v1 = (float)(s.origin.Y + s.size.Height) / (float)s.sheet.bitmap.Height; - - return (v > 0) ? v1 : v0;// return (1 - v) * v0 + v * v1; - } - } } diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index 065ac5398d..3fc23888bb 100644 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -181,16 +181,6 @@ namespace OpenRa.Game } } - static T Nth(IEnumerable src, int n) - { - IEnumerator enumerator = src.GetEnumerator(); - bool ok = false; - while (n-- > 0) - ok = enumerator.MoveNext(); - - return ok ? enumerator.Current : default(T); - } - void Frame() { PointF r1 = new PointF(2.0f / ClientSize.Width, -2.0f / ClientSize.Height); @@ -217,17 +207,15 @@ namespace OpenRa.Game int lastRow = firstRow + visibleRows; if (firstRow < 0) firstRow = 0; - if (lastRow < 0) lastRow = 0; - if (lastRow > map.Height) lastRow = map.Height; - Range indexRange = new Range(indicesPerRow * firstRow, indicesPerRow * lastRow); - Range vertexRange = new Range(verticesPerRow * firstRow, verticesPerRow * lastRow); - renderer.DrawWithShader(ShaderQuality.Low, delegate { - renderer.DrawBatch(vertexBuffer, batch.Value, vertexRange, indexRange, batch.Key.texture); + renderer.DrawBatch(vertexBuffer, batch.Value, + new Range(verticesPerRow * firstRow, verticesPerRow * lastRow), + new Range(indicesPerRow * firstRow, indicesPerRow * lastRow), + batch.Key.texture); }); } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index f3d6f6b791..322e51d7e2 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -45,7 +45,10 @@ + + + diff --git a/OpenRa.Game/Tree.cs b/OpenRa.Game/Tree.cs new file mode 100644 index 0000000000..9228b424e5 --- /dev/null +++ b/OpenRa.Game/Tree.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenRa.FileFormats; +using System.Drawing; + +namespace OpenRa.Game +{ + class Tree : Actor + { + public Tree(TreeReference r, TreeCache renderer, Map map) + { + location = new PointF(24 * (r.X - map.XOffset), 24 * (r.Y - map.YOffset)); + currentImages = new SheetRectangle[] { renderer.GetImage(r.Image) }; + } + } +} diff --git a/OpenRa.Game/TreeCache.cs b/OpenRa.Game/TreeCache.cs new file mode 100644 index 0000000000..16b5278e77 --- /dev/null +++ b/OpenRa.Game/TreeCache.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenRa.FileFormats; +using BluntDirectX.Direct3D; +using System.Drawing; + +namespace OpenRa.Game +{ + class TreeCache + { + Dictionary> trees = new Dictionary>(); + + public readonly Sheet sh; + + public TreeCache(GraphicsDevice device, Map map, Package package, Palette pal) + { + Size pageSize = new Size(1024, 512); + List sheets = new List(); + + Provider sheetProvider = delegate + { + Sheet sheet = new Sheet(new Bitmap(pageSize.Width, pageSize.Height)); + sheets.Add(sheet); + return sheet; + }; + + TileSheetBuilder builder = new TileSheetBuilder(pageSize, sheetProvider); + + foreach (TreeReference r in map.Trees) + { + if (trees.ContainsKey(r.Image)) + continue; + + ShpReader reader = new ShpReader(package.GetContent(r.Image + "." + map.Theater.Substring(0, 3))); + Bitmap bitmap = BitmapBuilder.FromBytes(reader[0].Image, reader.Width, reader.Height, pal); + + SheetRectangle rect = builder.AddImage(bitmap.Size); + using (Graphics g = Graphics.FromImage(rect.sheet.bitmap)) + g.DrawImage(bitmap, rect.origin); + + trees.Add(r.Image, rect); + } + + foreach (Sheet sheet in sheets) + sheet.LoadTexture(device); + + sh = sheets[0]; + } + + public SheetRectangle GetImage(string tree) + { + return trees[tree]; + } + } +} diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs new file mode 100644 index 0000000000..36e66cf911 --- /dev/null +++ b/OpenRa.Game/World.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Text; +using BluntDirectX.Direct3D; +using OpenRa.FileFormats; + +namespace OpenRa.Game +{ + class World + { + const int spritesPerBatch = 1024; + + List actors = new List(); + FvfVertexBuffer vb; + IndexBuffer ib; + GraphicsDevice device; + + public World(GraphicsDevice device) + { + this.device = device; + this.vb = new FvfVertexBuffer(device, spritesPerBatch * 4, Vertex.Format); + this.ib = new IndexBuffer(device, spritesPerBatch * 6); + } + + public void Add(Actor a) + { + actors.Add(a); //todo: protect from concurrent modification + } + + // assumption: there is only one sheet! + // some noob needs to fix this! + + // assumption: its not going to hurt, to draw *all* units. + // in reality, 500 tanks is going to hurt our perf. + + public void Draw(Renderer renderer) + { + int sprites = 0; + List vertices = new List(); + List indices = new List(); + Sheet sheet = null; + + foreach (Actor a in actors) + { + if (a.currentImages == null) + continue; + + foreach (SheetRectangle image in a.currentImages) + { + int offset = vertices.Count; + vertices.Add(new Vertex(a.location.X, a.location.Y, 0, U(image, 0), V(image, 0))); + vertices.Add(new Vertex(a.location.X + image.size.Width, a.location.Y, 0, U(image, 1), V(image, 0))); + vertices.Add(new Vertex(a.location.X, a.location.Y + image.size.Height, 0, U(image, 0), V(image, 1))); + vertices.Add(new Vertex(a.location.X + image.size.Width, a.location.Y + image.size.Height, 0, U(image, 1), V(image, 1))); + + indices.Add((ushort)offset); + indices.Add((ushort)(offset + 1)); + indices.Add((ushort)(offset + 2)); + + indices.Add((ushort)(offset + 1)); + indices.Add((ushort)(offset + 3)); + indices.Add((ushort)(offset + 2)); + + sheet = image.sheet; + + if (++sprites >= spritesPerBatch) + { + DrawBatch(vertices, indices, renderer, sheet); + + vertices = new List(); + indices = new List(); + sprites = 0; + } + } + } + + if (sprites > 0) + DrawBatch(vertices, indices, renderer, sheet); + } + + void DrawBatch(List vertices, List indices, Renderer renderer, Sheet sheet) + { + vb.SetData(vertices.ToArray()); + ib.SetData(indices.ToArray()); + + renderer.DrawWithShader(ShaderQuality.High, + delegate + { + renderer.DrawBatch(vb, ib, + new Range(0, vertices.Count), + new Range(0, indices.Count), + sheet.texture); + }); + } + + static float U(SheetRectangle s, float u) + { + float u0 = (float)(s.origin.X + 0.5f) / (float)s.sheet.bitmap.Width; + float u1 = (float)(s.origin.X + s.size.Width) / (float)s.sheet.bitmap.Width; + + return (u > 0) ? u1 : u0;// (1 - u) * u0 + u * u1; + } + + static float V(SheetRectangle s, float v) + { + float v0 = (float)(s.origin.Y + 0.5f) / (float)s.sheet.bitmap.Height; + float v1 = (float)(s.origin.Y + s.size.Height) / (float)s.sheet.bitmap.Height; + + return (v > 0) ? v1 : v0;// return (1 - v) * v0 + v * v1; + } + } +}