Advertisement
krzat

SFML.Net TileRenderer

Jan 8th, 2013
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.50 KB | None | 0 0
  1. using System;
  2. using SFML.Graphics;
  3. using SFML.Window;
  4. using Test;
  5.  
  6. namespace SFML.Utils
  7. {
  8.     public delegate void TileProvider(int x, int y, int layer, out Color color, out IntRect rec);
  9.     class MapRenderer : Drawable
  10.     {
  11.         private readonly float TileSize;
  12.         public readonly int Layers;
  13.  
  14.         private int height;
  15.         private int width;
  16.  
  17.         private Vector2i offset;
  18.         private Vertex[] vertices;
  19.  
  20.         private TileProvider provider;
  21.         private Texture texture;
  22.  
  23.         public MapRenderer(Texture texture, TileProvider provider, float tileSize = 16, int layers = 1)
  24.         {
  25.             if(provider == null || layers <= 0) throw new ArgumentException();
  26.             this.provider = provider;
  27.  
  28.             TileSize = tileSize;
  29.             Layers = layers;
  30.  
  31.             vertices = new Vertex[0];
  32.             this.texture = texture;
  33.  
  34.         }
  35.  
  36.         public void Refresh()
  37.         {
  38.             RefreshLocal(0, 0, width, height);
  39.         }
  40.  
  41.         private void RefreshLocal(int left, int top, int right, int bottom)
  42.         {
  43.             for (var y = top; y < bottom; y++)
  44.                 for (var x = left; x < right; x++)
  45.                 {
  46.                     Refresh(x+offset.X, y+offset.Y);
  47.                 }
  48.         }
  49.  
  50.         private void SetSize(Vector2f v)
  51.         {
  52.             var w = (int) (v.X/TileSize) + 2;
  53.             var h = (int) (v.Y/TileSize) + 2;
  54.             if (w == width && h == height) return;
  55.  
  56.             width = w;
  57.             height = h;
  58.  
  59.             vertices = new Vertex[width*height*4*Layers];
  60.             Refresh();
  61.         }
  62.  
  63.         private void SetCorner(Vector2f v)
  64.         {
  65.             var tile = GetTile(v);
  66.             var dif = tile - offset;
  67.             if (dif.X == 0 && dif.Y == 0) return;
  68.             offset = tile;
  69.  
  70.             if (Math.Abs(dif.X) > width/4 || Math.Abs(dif.Y) > height/4)
  71.             {
  72.                 Refresh();
  73.                 return;
  74.             }
  75.  
  76.             if (dif.X > 0) RefreshLocal(width - dif.X, 0, width, height);
  77.             else RefreshLocal(0, 0, -dif.X, height);
  78.  
  79.             if (dif.Y > 0) RefreshLocal(0, height - dif.Y, width, height);
  80.             else RefreshLocal(0, 0, width, -dif.Y);
  81.         }
  82.  
  83.         private Vector2i GetTile(Vector2f pos)
  84.         {
  85.             var x = (int) (pos.X/TileSize);
  86.             var y = (int) (pos.Y/TileSize);
  87.             if (pos.X < 0) x--;
  88.             if (pos.Y < 0) y--;
  89.             return new Vector2i(x, y);
  90.         }
  91.  
  92.  
  93.         public void Refresh(int x, int y)
  94.         {
  95.             if(x < offset.X || x >= offset.X + width || y < offset.Y || y >= offset.Y + height)
  96.                 return;
  97.             var vx = x % width;      
  98.             var vy = y % height;
  99.             if (vx < 0) vx += width;
  100.             if (vy < 0) vy += height;
  101.  
  102.             var index = (vx+vy * width) * 4 * Layers;
  103.             var rec = new FloatRect(x * TileSize, y * TileSize, TileSize, TileSize);
  104.  
  105.             for (int i = 0; i < Layers; i++)
  106.             {
  107.                 Color color;
  108.                 IntRect src;
  109.                 provider(x, y, i, out color, out src);
  110.  
  111.                 Draw(index, rec, src, color);
  112.                 index += 4;
  113.             }
  114.         }
  115.  
  116.         private unsafe void Draw(int index, FloatRect rec, IntRect src, Color color)
  117.         {
  118.             fixed (Vertex* fptr = vertices)
  119.             {
  120.                 var ptr = fptr + index;
  121.  
  122.                 ptr->Position.X = rec.Left;
  123.                 ptr->Position.Y = rec.Top;
  124.                 ptr->TexCoords.X = src.Left;
  125.                 ptr->TexCoords.Y = src.Top;
  126.                 ptr->Color = color;
  127.                 ptr++;
  128.  
  129.                 ptr->Position.X = rec.Left + rec.Width;
  130.                 ptr->Position.Y = rec.Top;
  131.                 ptr->TexCoords.X = src.Left + src.Width;
  132.                 ptr->TexCoords.Y = src.Top;
  133.                 ptr->Color = color;
  134.                 ptr++;
  135.  
  136.                 ptr->Position.X = rec.Left + rec.Width;
  137.                 ptr->Position.Y = rec.Top + rec.Height;
  138.                 ptr->TexCoords.X = src.Left + src.Width;
  139.                 ptr->TexCoords.Y = src.Top + src.Height;
  140.                 ptr->Color = color;
  141.                 ptr++;
  142.  
  143.                 ptr->Position.X = rec.Left;
  144.                 ptr->Position.Y = rec.Top + rec.Height;
  145.                 ptr->TexCoords.X = src.Left;
  146.                 ptr->TexCoords.Y = src.Top + src.Height;
  147.                 ptr->Color = color;
  148.             }
  149.         }
  150.  
  151.         public void Draw(RenderTarget rt, RenderStates states)
  152.         {
  153.             var view = rt.GetView();
  154.             states.Texture = texture;
  155.             SetSize(view.Size);
  156.             SetCorner(rt.MapPixelToCoords(new Vector2i()));
  157.  
  158.  
  159.             rt.Draw(vertices, PrimitiveType.Quads, states);
  160.         }
  161.     }
  162.  
  163.     class MinimalTest
  164.     {      
  165.         public static void Main()
  166.         {
  167.             var rw = new RenderWindow(new VideoMode(800, 600), "Game");
  168.             rw.Closed += (s, a) => rw.Close();
  169.             var renderer = new MapRenderer(null, Provider);
  170.  
  171.             while (rw.IsOpen())
  172.             {
  173.                 rw.Clear();
  174.                 rw.Draw(renderer);
  175.                 rw.Display();
  176.                 rw.DispatchEvents();
  177.             }
  178.         }
  179.         private static void Provider(int x, int y, int layer, out Color color, out IntRect rec)
  180.         {
  181.             color = new Color((byte)(x*5), 50,50);
  182.             rec = new IntRect(0,0,1,1);
  183.         }
  184.     }
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement