Advertisement
krzat

SFML SpriteBatch

Dec 8th, 2012
588
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.35 KB | None | 0 0
  1. #define LOOKUP
  2. using SFML.Graphics;
  3. using SFML.Window;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7.  
  8.  
  9. namespace SFML.Graphics
  10. {
  11.     /// <summary>
  12.     /// Provides optimized drawing of sprites
  13.     /// </summary>
  14.     public class SpriteBatch
  15.     {
  16.  
  17.         public int Count {get { return count; }}
  18.  
  19. #if(LOOKUP)
  20.  
  21.         private const int LookupSize = 1024; //has to be power of 2
  22.         static readonly private float[] getSin, getCos;
  23.         static SpriteBatch()
  24.         {
  25.             getSin = new float[LookupSize];
  26.             getCos = new float[LookupSize];
  27.  
  28.             for (int i = 0; i < LookupSize; i++)
  29.             {
  30.                 getSin[i] = (float)Math.Sin(i * Math.PI / LookupSize * 2);
  31.                 getCos[i] = (float)Math.Cos(i * Math.PI / LookupSize * 2);
  32.             }
  33.  
  34.             float max = 0;
  35.             for (int i = 1; i < LookupSize; i++)
  36.             {
  37.                 max = Math.Max(max, Math.Abs(getSin[i] - getSin[i - 1]));
  38.             }
  39.             max /= 2;
  40.             Debug.WriteLine("Max sin/cos error is: " + max);
  41.         }
  42. #endif
  43.  
  44.  
  45.         Vertex[] vertices = new Vertex[100 * 4];
  46.         int count;
  47.         RenderStates state;
  48.  
  49.         public RenderTarget RenderTarget;
  50.  
  51.         /// <summary>
  52.         /// Setting this causes Display
  53.         /// </summary>
  54.         public BlendMode BlendMode
  55.         {
  56.             get { return state.BlendMode; }
  57.             set
  58.             {
  59.                 Display(false);
  60.                 state.BlendMode = value;
  61.             }
  62.         }
  63.  
  64.         /// <summary>
  65.         /// Setting this causes Display
  66.         /// </summary>
  67.         public Shader Shader
  68.         {
  69.             get { return state.Shader; }
  70.             set
  71.             {
  72.                 Display(false);
  73.                 state.Shader = value;
  74.             }
  75.         }
  76.  
  77.         public SpriteBatch(RenderTarget rt)
  78.         {
  79.             state = RenderStates.Default;
  80.             this.RenderTarget = rt;
  81.  
  82.  
  83.         }
  84.  
  85.         /// <summary>
  86.         /// Sends buffered sprites to GPU.
  87.         /// </summary>
  88.         /// <param name="resetState">true will reset internal  RenderStates to default value</param>
  89.         public void Display(bool resetState = true, bool flush = true)
  90.         {
  91.             if (count > 0)
  92.                 RenderTarget.Draw(vertices, 0, (uint)count * 4, PrimitiveType.Quads, state);
  93.             if (resetState)
  94.                 state = RenderStates.Default;
  95.             if (flush)
  96.                 count = 0;
  97.         }
  98.  
  99.         public void Flush()
  100.         {
  101.             count = 0;
  102.         }
  103.  
  104.         public void Draw(IEnumerable<Sprite> sprites)
  105.         {
  106.             foreach (var s in sprites)
  107.                 Draw(s);
  108.         }
  109.  
  110.         public void Draw(Sprite sprite)
  111.         {
  112.             Draw(sprite.Texture, sprite.Position, sprite.TextureRect, sprite.Color, sprite.Scale, sprite.Origin, sprite.Rotation);
  113.         }
  114.  
  115.         private const int Max = 4000000;
  116.  
  117.  
  118.         private const float PI = 3.14f;
  119.  
  120.         int Create(Texture texture)
  121.         {
  122.             if (texture != state.Texture)
  123.             {
  124.                 Display(false);
  125.                 state.Texture = texture;
  126.             }
  127.  
  128.             if (count >= (vertices.Length / 4))
  129.             {
  130.                 //Display(false);
  131.                 if (vertices.Length < Max)
  132.                 {
  133.                     Array.Resize(ref vertices, Math.Min(vertices.Length * 2, Max));
  134.                     //vertices = new Vertex[vertices.Length * 2];
  135.                 }
  136.             }
  137.             return 4 * count++;
  138.         }
  139.  
  140.         /// <summary>
  141.         /// Setting this will cause Display if provided texture is different than previous
  142.         /// </summary>
  143.         public unsafe void Draw(Texture texture, Vector2f position, IntRect rec, Color color, Vector2f scale, Vector2f origin, float rotation = 0)
  144.         {
  145.             var index = Create(texture);
  146. #if(LOOKUP)
  147.             int rot = (int)(rotation * (LookupSize / 360f) + 0.5f) & (LookupSize - 1);
  148.             //int rot = (int) (rotation*(LookupSize/360f) + 0.5f)%LookupSize;
  149.             //if (rot < 0) rot += LookupSize;
  150.  
  151.             float cos = getCos[rot];
  152.             float sin = getSin[rot];
  153. #else
  154.             float sin = 0, cos = 1;
  155.             if (rotation != 0)
  156.             {
  157.                 rotation = rotation * (float)Math.PI / 180;
  158.                 sin = (float)Math.Sin(rotation);
  159.                 cos = (float)Math.Cos(rotation);
  160.             }
  161. #endif
  162.  
  163.             scale.X *= rec.Width;
  164.             scale.Y *= rec.Height;
  165.             var pX = -origin.X * scale.X;
  166.             var pY = -origin.Y * scale.Y;
  167.  
  168.             fixed (Vertex* fptr = vertices)
  169.             {
  170.                 var ptr = fptr + index;
  171.  
  172.                 ptr->Position.X = pX * cos - pY * sin + position.X;
  173.                 ptr->Position.Y = pX * sin + pY * cos + position.Y;
  174.                 ptr->TexCoords.X = rec.Left;
  175.                 ptr->TexCoords.Y = rec.Top;
  176.                 ptr->Color = color;
  177.                 ptr++;
  178.  
  179.                 pX += scale.X;
  180.                 ptr->Position.X = pX * cos - pY * sin + position.X;
  181.                 ptr->Position.Y = pX * sin + pY * cos + position.Y;
  182.                 ptr->TexCoords.X = rec.Left + rec.Width;
  183.                 ptr->TexCoords.Y = rec.Top;
  184.                 ptr->Color = color;
  185.                 ptr++;
  186.  
  187.                 pY += scale.Y;
  188.                 ptr->Position.X = pX * cos - pY * sin + position.X;
  189.                 ptr->Position.Y = pX * sin + pY * cos + position.Y;
  190.                 ptr->TexCoords.X = rec.Left + rec.Width;
  191.                 ptr->TexCoords.Y = rec.Top + rec.Height;
  192.                 ptr->Color = color;
  193.                 ptr++;
  194.  
  195.                 pX -= scale.X;
  196.                 ptr->Position.X = pX * cos - pY * sin + position.X;
  197.                 ptr->Position.Y = pX * sin + pY * cos + position.Y;
  198.                 ptr->TexCoords.X = rec.Left;
  199.                 ptr->TexCoords.Y = rec.Top + rec.Height;
  200.                 ptr->Color = color;
  201.             }
  202.         }
  203.  
  204.         public unsafe void Draw(Texture texture, FloatRect rec, IntRect src, Color color)
  205.         {
  206.             var index = Create(texture);
  207.  
  208.             fixed (Vertex* fptr = vertices)
  209.             {
  210.                 var ptr = fptr + index;
  211.  
  212.                 ptr->Position.X = rec.Left;
  213.                 ptr->Position.Y = rec.Top;
  214.                 ptr->TexCoords.X = src.Left;
  215.                 ptr->TexCoords.Y = src.Top;
  216.                 ptr->Color = color;
  217.                 ptr++;
  218.  
  219.                 ptr->Position.X = rec.Left + rec.Width;
  220.                 ptr->Position.Y = rec.Top;
  221.                 ptr->TexCoords.X = src.Left + src.Width;
  222.                 ptr->TexCoords.Y = src.Top;
  223.                 ptr->Color = color;
  224.                 ptr++;
  225.  
  226.                 ptr->Position.X = rec.Left +rec.Width;
  227.                 ptr->Position.Y = rec.Top + rec.Height;
  228.                 ptr->TexCoords.X = src.Left + src.Width;
  229.                 ptr->TexCoords.Y = src.Top + src.Height;
  230.                 ptr->Color = color;
  231.                 ptr++;
  232.  
  233.                 ptr->Position.X = rec.Left;
  234.                 ptr->Position.Y = rec.Top + rec.Height;
  235.                 ptr->TexCoords.X = src.Left;
  236.                 ptr->TexCoords.Y = src.Top + src.Height;
  237.                 ptr->Color = color;
  238.             }
  239.         }
  240.     }
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement