using System.Drawing; using Ijw.DirectX; using IjwFramework.Collections; using OpenRa.FileFormats; namespace OpenRa.Graphics { class TerrainRenderer { FvfVertexBuffer vertexBuffer; IndexBuffer indexBuffer; Sheet terrainSheet; Renderer renderer; Map map; OverlayRenderer overlayRenderer; public TerrainRenderer(World world, Renderer renderer) { this.renderer = renderer; this.map = world.Map; Size tileSize = new Size( Game.CellSize, Game.CellSize ); var tileMapping = new Cache( x => SheetBuilder.Add(world.TileSet.GetBytes(x), tileSize)); Vertex[] vertices = new Vertex[4 * map.Height * map.Width]; ushort[] indices = new ushort[6 * map.Height * map.Width]; int nv = 0; int ni = 0; for( int j = map.YOffset ; j < map.YOffset + map.Height ; j++ ) for( int i = map.XOffset ; i < map.XOffset + map.Width; i++ ) { Sprite tile = tileMapping[map.MapTiles[i, j]]; Util.FastCreateQuad(vertices, indices, Game.CellSize * new float2(i, j), tile, (int)PaletteType.Terrain, nv, ni, tile.size); nv += 4; ni += 6; } terrainSheet = tileMapping[map.MapTiles[map.XOffset, map.YOffset]].sheet; vertexBuffer = new FvfVertexBuffer( renderer.Device, vertices.Length, Vertex.Format ); vertexBuffer.SetData( vertices ); indexBuffer = new IndexBuffer( renderer.Device, indices.Length ); indexBuffer.SetData( indices ); overlayRenderer = new OverlayRenderer( renderer, map ); } public void Draw( Viewport viewport ) { int indicesPerRow = map.Width * 6; int verticesPerRow = map.Width * 4; int visibleRows = (int)(viewport.Height / 24.0f + 2); int firstRow = (int)((viewport.Location.Y) / 24.0f - map.YOffset); int lastRow = firstRow + visibleRows; if (lastRow < 0 || firstRow > map.Height) return; if (firstRow < 0) firstRow = 0; if (lastRow > map.Height) lastRow = map.Height; if (!Game.world.LocalPlayer.Shroud.HasGPS && Game.world.LocalPlayer.Shroud.bounds.HasValue) { var r = Game.world.LocalPlayer.Shroud.bounds.Value; if (firstRow < r.Top - map.YOffset) firstRow = r.Top - map.YOffset; if (firstRow > r.Bottom - map.YOffset) firstRow = r.Bottom - map.YOffset; } renderer.SpriteShader.Quality = ShaderQuality.Low; renderer.SpriteShader.Render(() => renderer.DrawBatch(vertexBuffer, indexBuffer, new Range(verticesPerRow * firstRow, verticesPerRow * lastRow), new Range(indicesPerRow * firstRow, indicesPerRow * lastRow), terrainSheet.Texture, PrimitiveType.TriangleList, renderer.SpriteShader)); overlayRenderer.Draw(); } } }