using System; using System.Collections.Generic; using System.Text; using OpenRa.FileFormats; using System.Drawing; using System.IO; using System.Windows.Forms; using Ijw.DirectX; using IjwFramework.Collections; namespace OpenRa.Game { class TerrainRenderer { FvfVertexBuffer vertexBuffer; IndexBuffer indexBuffer; Sheet terrainSheet; public TileSet tileSet; Region region; Renderer renderer; Map map; public TerrainRenderer(Renderer renderer, Map map, Viewport viewport) { this.renderer = renderer; region = Region.Create(viewport, DockStyle.Left, viewport.Width - 128, Draw, (_, e) => { } ); viewport.AddRegion(region); this.map = map; tileSet = new TileSet( map.TileSuffix ); Size tileSize = new Size( 24, 24 ); var tileMapping = new Cache( x => SheetBuilder.Add(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 = 0 ; j < map.Height ; j++ ) for (int i = 0; i < map.Width; i++) { Sprite tile = tileMapping[map.MapTiles[i + map.XOffset, j + map.YOffset]]; Util.FastCreateQuad(vertices, indices, 24 * new float2(i, j), tile, 0, nv, ni); 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 ); } void Draw() { int indicesPerRow = map.Width * 6; int verticesPerRow = map.Width * 4; int visibleRows = (int)(region.Size.Y / 24.0f + 2); int firstRow = (int)(region.Location.Y / 24.0f); int lastRow = firstRow + visibleRows; if (lastRow < 0 || firstRow > map.Height) return; if (firstRow < 0) firstRow = 0; if (lastRow > map.Height) lastRow = map.Height; renderer.DrawWithShader(ShaderQuality.Low, () => renderer.DrawBatch(vertexBuffer, indexBuffer, new Range(verticesPerRow * firstRow, verticesPerRow * lastRow), new Range(indicesPerRow * firstRow, indicesPerRow * lastRow), terrainSheet.Texture)); } } }