Advertisement
Guest User

C# SB

a guest
Jul 14th, 2014
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 22.26 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using OpenTK;
  6. using OpenTK.Graphics.OpenGL4;
  7.  
  8. namespace EGL {
  9.     public struct VertexSpriteBatch {
  10.         public static readonly int Size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertexSpriteBatch));
  11.         public static readonly ArrayBind[] Binds = new ArrayBind[]{
  12.           new ArrayBind(Semantic.Position, VertexAttribPointerType.Float, 3, sizeof(float) * 0),
  13.           new ArrayBind(Semantic.TexCoord, VertexAttribPointerType.Float, 2, sizeof(float) * 3),
  14.           new ArrayBind(Semantic.TexCoord | Semantic.Index1, VertexAttribPointerType.Float, 4, sizeof(float) * 5),
  15.           new ArrayBind(Semantic.Color, VertexAttribPointerType.UnsignedByte, 4, sizeof(float) * 9, true)
  16.         };
  17.  
  18.         public Vector3 Position;
  19.         public Vector2 UV;
  20.         public Vector4 UVRect;
  21.         public Color Color;
  22.  
  23.         public VertexSpriteBatch(Vector3 p, Vector2 uv, Vector4 uvr, Color c) {
  24.             Position = p;
  25.             UV = uv;
  26.             UVRect = uvr;
  27.             Color = c;
  28.         }
  29.     }
  30.  
  31.     public enum SpriteSortMode {
  32.         None,
  33.         FrontToBack,
  34.         BackToFront,
  35.         Texture
  36.     }
  37.  
  38.     public class SpriteGlyph {
  39.         public GLTexture Texture;
  40.         public float Depth;
  41.  
  42.         public VertexSpriteBatch VTL;
  43.         public VertexSpriteBatch VTR;
  44.         public VertexSpriteBatch VBL;
  45.         public VertexSpriteBatch VBR;
  46.  
  47.         public SpriteGlyph(GLTexture t, float d) {
  48.             Texture = t;
  49.             Depth = d;
  50.         }
  51.     }
  52.  
  53.     public class SpriteBatch : IDisposable {
  54.         public const int INITIAL_GLYPH_CAP = 32;
  55.  
  56.         #region Sorters
  57.         public static int SSMTexture(SpriteGlyph g1, SpriteGlyph g2) {
  58.             return g1.Texture.ID.CompareTo(g2.Texture.ID);
  59.         }
  60.         public static int SSMFrontToBack(SpriteGlyph g1, SpriteGlyph g2) {
  61.             return g1.Depth.CompareTo(g2.Depth);
  62.         }
  63.         public static int SSMBackToFront(SpriteGlyph g1, SpriteGlyph g2) {
  64.             return g2.Depth.CompareTo(g1.Depth);
  65.         }
  66.         #endregion
  67.  
  68.         class SpriteBatchCall {
  69.             public GLTexture Texture;
  70.             public int Indices;
  71.             public int IndexOffset;
  72.  
  73.             public SpriteBatchCall(int iOff, GLTexture t, List<SpriteBatchCall> calls) {
  74.                 Texture = t;
  75.                 IndexOffset = iOff;
  76.                 Indices = 6;
  77.                 calls.Add(this);
  78.             }
  79.  
  80.             public SpriteBatchCall Append(SpriteGlyph g, List<SpriteBatchCall> calls) {
  81.                 if(g.Texture != Texture) return new SpriteBatchCall(IndexOffset + Indices, g.Texture, calls);
  82.                 else Indices += 6;
  83.                 return this;
  84.             }
  85.         }
  86.  
  87.         #region Vertex Shader
  88.         private const string VS_SRC =
  89. @"uniform mat4 World;
  90. uniform mat4 VP;
  91. in vec4 vPosition;  // Sem  (Position    0)
  92. in vec2 vUV;        // Sem  (Texcoord    0)
  93. in vec4 vUVRect;    // Sem  (Texcoord    1)
  94. in vec4 vTint;      // Sem  (Color       0)
  95. out vec2 fUV;
  96. out vec4 fUVRect;
  97. out vec4 fTint;
  98. void main() {
  99.    fTint = vTint;
  100.    fUV = vUV;
  101.    fUVRect = vUVRect;
  102.    vec4 worldPos = vPosition * World;
  103.    gl_Position = worldPos * VP;
  104. }
  105. ";
  106.         #endregion
  107.         #region Fragment Shader
  108.         private const string FS_SRC =
  109. @"uniform sampler2D SBTex;
  110. in vec2 fUV;
  111. in vec4 fUVRect;
  112. in vec4 fTint;
  113. void main() {
  114.    gl_FragColor = texture(SBTex, (vec2(mod(fUV.x, 1.0), mod(fUV.y, 1.0)) * fUVRect.zw) + fUVRect.xy) * fTint;
  115. }
  116. ";
  117.         #endregion
  118.  
  119.         #region Test Shaders
  120.         private const string VS_SRC_TEST =
  121.         "#version 130 core\n" +
  122.         "in vec4 vPosition;\n" +
  123.         "in vec4 vTint;\n" +
  124.         "out vec4 fColor;\n" +
  125.         "void main(void) {\n" +
  126.         "   fColor = vTint;\n" +
  127.         "   gl_Position = vPosition;\n" +
  128.         "}";
  129.         private const string FS_SRC_TEST =
  130.         "#version 130 core\n" +
  131.         "in vec4 fColor;\n" +
  132.         "out vec4 out_Color;\n" +
  133.         "void main(void) {\n" +
  134.         "   out_Color = fColor;\n" +
  135.         "}";
  136.         #endregion
  137.  
  138.         public static readonly Vector4 FULL_UV_RECT = new Vector4(0, 0, 1, 1);
  139.         public static readonly Vector2 UV_NO_TILE = new Vector2(1, 1);
  140.  
  141.         public static Matrix4 CreateCameraFromWindow(float w, float h) {
  142.             w *= 0.5f;
  143.             h *= 0.5f;
  144.             //Matrix4 mm = new Matrix4(
  145.             //    w, 0, 0, 0,
  146.             //    0, -h, 0, 0,
  147.             //    0, 0, -1, 0,
  148.             //    w, h, 0, 1
  149.             //    ).Inverted();
  150.             Matrix4 mo =
  151.                 Matrix4.CreateScale(1 / w, -1 / h, 1) *
  152.                 Matrix4.CreateTranslation(-1, 1, -1)
  153.                 ;
  154.             return mo;
  155.         }
  156.  
  157.         // Glyph Information
  158.         private List<SpriteGlyph> glyphs;
  159.         private Queue<SpriteGlyph> emptyGlyphs;
  160.  
  161.         // Render Batches
  162.         private BufferUsageHint bufUsage;
  163.         private int vao, vbo, glyphCapacity;
  164.         private List<SpriteBatchCall> batches;
  165.  
  166.         // Custom Shader
  167.         private int idProg, idVS, idFS;
  168.         private int unWorld, unVP, unTexture;
  169.  
  170.         public SpriteBatch(bool isDynamic = true) {
  171.             bufUsage = isDynamic ? BufferUsageHint.DynamicDraw : BufferUsageHint.StaticDraw;
  172.  
  173.             InitGL();
  174.  
  175.             emptyGlyphs = new Queue<SpriteGlyph>();
  176.         }
  177.         public void InitGL() {
  178.             CreateProgram();
  179.             SearchUniforms();
  180.             CreateVertexArray();
  181.         }
  182.         public void Dispose() {
  183.             GL.DeleteBuffer(vbo);
  184.             vbo = 0;
  185.             GL.DeleteVertexArray(vao);
  186.             vao = 0;
  187.  
  188.             GL.DetachShader(idProg, idVS);
  189.             GL.DeleteShader(idVS);
  190.             GL.DetachShader(idProg, idFS);
  191.             GL.DeleteShader(idFS);
  192.             GL.DeleteProgram(idProg);
  193.         }
  194.  
  195.         private void CreateProgram() {
  196.             // Create The Program
  197.             idProg = GL.CreateProgram();
  198.             int status;
  199.  
  200.             // Make Vertex Shader
  201.             idVS = GL.CreateShader(ShaderType.VertexShader);
  202.             GL.ShaderSource(idVS, VS_SRC_TEST);
  203.             GL.CompileShader(idVS);
  204.             GL.GetShader(idVS, ShaderParameter.CompileStatus, out status);
  205.             if(status != 1)
  206.                 throw new Exception("Vert Shader Had Compilation Errors");
  207.             GL.AttachShader(idProg, idVS);
  208.  
  209.             // Make Fragment Shader
  210.             idFS = GL.CreateShader(ShaderType.FragmentShader);
  211.             GL.ShaderSource(idFS, FS_SRC_TEST);
  212.             GL.CompileShader(idFS);
  213.             GL.GetShader(idFS, ShaderParameter.CompileStatus, out status);
  214.             if(status != 1)
  215.                 throw new Exception("Frag Shader Had Compilation Errors");
  216.             GL.AttachShader(idProg, idFS);
  217.  
  218.             // Setup Vertex Attribute Locations
  219.             GL.BindAttribLocation(idProg, 0, "vPosition");
  220.             GL.BindAttribLocation(idProg, 1, "vTint");
  221.             //        glBindAttribLocation(idProg, 2, "vUV");
  222.             //        glBindAttribLocation(idProg, 3, "vUVRect");
  223.  
  224.             GL.LinkProgram(idProg);
  225.             GL.ValidateProgram(idProg);
  226.             GL.GetProgram(idProg, GetProgramParameterName.LinkStatus, out status);
  227.             if(status != 1)
  228.                 throw new Exception("Program Had Compilation Errors");
  229.         }
  230.         private void SearchUniforms() {
  231.             unWorld = GL.GetUniformLocation(idProg, "World");
  232.             unVP = GL.GetUniformLocation(idProg, "VP");
  233.             unTexture = GL.GetUniformLocation(idProg, "SBTex");
  234.         }
  235.         private void CreateVertexArray() {
  236.             vao = GL.GenVertexArray();
  237.             GL.BindVertexArray(vao);
  238.  
  239.             vbo = GL.GenBuffer();
  240.             glyphCapacity = INITIAL_GLYPH_CAP;
  241.             GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
  242.             GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr((glyphCapacity * 6) * VertexSpriteBatch.Size), IntPtr.Zero, bufUsage);
  243.  
  244.             GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, VertexSpriteBatch.Size, 0);
  245.             GL.VertexAttribPointer(1, 4, VertexAttribPointerType.UnsignedByte, true, VertexSpriteBatch.Size, 36);
  246.             GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, VertexSpriteBatch.Size, 12);
  247.             GL.VertexAttribPointer(3, 4, VertexAttribPointerType.Float, false, VertexSpriteBatch.Size, 20);
  248.  
  249.             GL.BindVertexArray(0);
  250.  
  251.             GLBuffer.Unbind(BufferTarget.ArrayBuffer);
  252.         }
  253.  
  254.         public void Begin() {
  255.             // Only Clear The Glyphs
  256.             glyphs = new List<SpriteGlyph>();
  257.             batches = new List<SpriteBatchCall>();
  258.         }
  259.  
  260.         private SpriteGlyph CreateGlyph(GLTexture t, float d) {
  261.             if(emptyGlyphs.Count > 0) {
  262.                 var g = emptyGlyphs.Dequeue();
  263.                 g.Texture = t;
  264.                 g.Depth = d;
  265.                 return g;
  266.             }
  267.             else {
  268.                 return new SpriteGlyph(t, d);
  269.             }
  270.         }
  271.         public void Draw(GLTexture t, Vector4? uvRect, Vector2? uvTiling, Matrix4 mTransform, Color tint, float depth = 0f) {
  272.             Vector4 uvr = uvRect.HasValue ? uvRect.Value : FULL_UV_RECT;
  273.             Vector2 uvt = uvTiling.HasValue ? uvTiling.Value : UV_NO_TILE;
  274.             SpriteGlyph g = CreateGlyph(t, depth);
  275.  
  276.  
  277.             g.VTL = new VertexSpriteBatch(new Vector3(0, 0, depth), new Vector2(0, 0), uvr, tint);
  278.             g.VTR = new VertexSpriteBatch(new Vector3(1, 0, depth), new Vector2(uvt.X, 0), uvr, tint);
  279.             g.VBL = new VertexSpriteBatch(new Vector3(0, 1, depth), new Vector2(0, uvt.Y), uvr, tint);
  280.             g.VBR = new VertexSpriteBatch(new Vector3(1, 1, depth), uvt, uvr, tint);
  281.  
  282.             // Transform The Vertex Positions
  283.             g.VTL.Position = Vector3.Transform(g.VTL.Position, mTransform);
  284.             g.VTR.Position = Vector3.Transform(g.VTR.Position, mTransform);
  285.             g.VBL.Position = Vector3.Transform(g.VBL.Position, mTransform);
  286.             g.VBR.Position = Vector3.Transform(g.VBR.Position, mTransform);
  287.  
  288.             glyphs.Add(g);
  289.         }
  290.         public void Draw(GLTexture t, Vector4? uvRect, Vector2? uvTiling, Vector2 position, Vector2 offset, Vector2 size, float rotation, Color tint, float depth = 0f) {
  291.             Vector4 uvr = uvRect.HasValue ? uvRect.Value : FULL_UV_RECT;
  292.             Vector2 uvt = uvTiling.HasValue ? uvTiling.Value : UV_NO_TILE;
  293.             SpriteGlyph g = CreateGlyph(t, depth);
  294.  
  295.             float rxx = (float)Math.Cos(-rotation);
  296.             float rxy = (float)Math.Sin(-rotation);
  297.             float cl = size.X * (-offset.X);
  298.             float cr = size.X * (1 - offset.X);
  299.             float ct = size.Y * (-offset.Y);
  300.             float cb = size.Y * (1 - offset.Y);
  301.  
  302.             g.VTL.Position.X = (cl * rxx) + (ct * rxy) + position.X;
  303.             g.VTL.Position.Y = (cl * -rxy) + (ct * rxx) + position.Y;
  304.             g.VTL.Position.Z = depth;
  305.             g.VTL.UV.X = 0;
  306.             g.VTL.UV.Y = 0;
  307.             g.VTL.UVRect = uvr;
  308.             g.VTL.Color = tint;
  309.  
  310.             g.VTR.Position.X = (cr * rxx) + (ct * rxy) + position.X;
  311.             g.VTR.Position.Y = (cr * -rxy) + (ct * rxx) + position.Y;
  312.             g.VTR.Position.Z = depth;
  313.             g.VTR.UV.X = uvt.X;
  314.             g.VTR.UV.Y = 0;
  315.             g.VTR.UVRect = uvr;
  316.             g.VTR.Color = tint;
  317.  
  318.             g.VBL.Position.X = (cl * rxx) + (cb * rxy) + position.X;
  319.             g.VBL.Position.Y = (cl * -rxy) + (cb * rxx) + position.Y;
  320.             g.VBL.Position.Z = depth;
  321.             g.VBL.UV.X = 0;
  322.             g.VBL.UV.Y = uvt.Y;
  323.             g.VBL.UVRect = uvr;
  324.             g.VBL.Color = tint;
  325.  
  326.             g.VBR.Position.X = (cr * rxx) + (cb * rxy) + position.X;
  327.             g.VBR.Position.Y = (cr * -rxy) + (cb * rxx) + position.Y;
  328.             g.VBR.Position.Z = depth;
  329.             g.VBR.UV.X = uvt.X;
  330.             g.VBR.UV.Y = uvt.Y;
  331.             g.VBR.UVRect = uvr;
  332.             g.VBR.Color = tint;
  333.  
  334.             glyphs.Add(g);
  335.         }
  336.         public void Draw(GLTexture t, Vector4? uvRect, Vector2? uvTiling, Vector2 position, Vector2 offset, Vector2 size, Color tint, float depth = 0f) {
  337.             Vector4 uvr = uvRect.HasValue ? uvRect.Value : FULL_UV_RECT;
  338.             Vector2 uvt = uvTiling.HasValue ? uvTiling.Value : UV_NO_TILE;
  339.             SpriteGlyph g = CreateGlyph(t, depth);
  340.  
  341.             float cl = size.X * (-offset.X);
  342.             float cr = size.X * (1 - offset.X);
  343.             float ct = size.Y * (-offset.Y);
  344.             float cb = size.Y * (1 - offset.Y);
  345.  
  346.             g.VTL.Position.X = cl + position.X;
  347.             g.VTL.Position.Y = ct + position.Y;
  348.             g.VTL.Position.Z = depth;
  349.             g.VTL.UV.X = 0;
  350.             g.VTL.UV.Y = 0;
  351.             g.VTL.UVRect = uvr;
  352.             g.VTL.Color = tint;
  353.  
  354.             g.VTR.Position.X = cr + position.X;
  355.             g.VTR.Position.Y = ct + position.Y;
  356.             g.VTR.Position.Z = depth;
  357.             g.VTR.UV.X = uvt.X;
  358.             g.VTR.UV.Y = 0;
  359.             g.VTR.UVRect = uvr;
  360.             g.VTR.Color = tint;
  361.  
  362.             g.VBL.Position.X = cl + position.X;
  363.             g.VBL.Position.Y = cb + position.Y;
  364.             g.VBL.Position.Z = depth;
  365.             g.VBL.UV.X = 0;
  366.             g.VBL.UV.Y = uvt.Y;
  367.             g.VBL.UVRect = uvr;
  368.             g.VBL.Color = tint;
  369.  
  370.             g.VBR.Position.X = cr + position.X;
  371.             g.VBR.Position.Y = cb + position.Y;
  372.             g.VBR.Position.Z = depth;
  373.             g.VBR.UV.X = uvt.X;
  374.             g.VBR.UV.Y = uvt.Y;
  375.             g.VBR.UVRect = uvr;
  376.             g.VBR.Color = tint;
  377.  
  378.             glyphs.Add(g);
  379.         }
  380.         public void Draw(GLTexture t, Vector4? uvRect, Vector2? uvTiling, Vector2 position, Vector2 size, Color tint, float depth = 0f) {
  381.             Vector4 uvr = uvRect.HasValue ? uvRect.Value : FULL_UV_RECT;
  382.             Vector2 uvt = uvTiling.HasValue ? uvTiling.Value : UV_NO_TILE;
  383.             SpriteGlyph g = CreateGlyph(t, depth);
  384.  
  385.             g.VTL.Position.X = position.X;
  386.             g.VTL.Position.Y = position.Y;
  387.             g.VTL.Position.Z = depth;
  388.             g.VTL.UV.X = 0;
  389.             g.VTL.UV.Y = 0;
  390.             g.VTL.UVRect = uvr;
  391.             g.VTL.Color = tint;
  392.  
  393.             g.VTR.Position.X = size.X + position.X;
  394.             g.VTR.Position.Y = position.Y;
  395.             g.VTR.Position.Z = depth;
  396.             g.VTR.UV.X = uvt.X;
  397.             g.VTR.UV.Y = 0;
  398.             g.VTR.UVRect = uvr;
  399.             g.VTR.Color = tint;
  400.  
  401.             g.VBL.Position.X = position.X;
  402.             g.VBL.Position.Y = size.Y + position.Y;
  403.             g.VBL.Position.Z = depth;
  404.             g.VBL.UV.X = 0;
  405.             g.VBL.UV.Y = uvt.Y;
  406.             g.VBL.UVRect = uvr;
  407.             g.VBL.Color = tint;
  408.  
  409.             g.VBR.Position.X = size.X + position.X;
  410.             g.VBR.Position.Y = size.Y + position.Y;
  411.             g.VBR.Position.Z = depth;
  412.             g.VBR.UV.X = uvt.X;
  413.             g.VBR.UV.Y = uvt.Y;
  414.             g.VBR.UVRect = uvr;
  415.             g.VBR.Color = tint;
  416.  
  417.             glyphs.Add(g);
  418.         }
  419.         public void Draw(GLTexture t, Vector4? uvRect, Vector2 position, Vector2 size, Color tint, float depth = 0f) {
  420.             Vector4 uvr = uvRect.HasValue ? uvRect.Value : FULL_UV_RECT;
  421.             SpriteGlyph g = CreateGlyph(t, depth);
  422.  
  423.             g.VTL.Position.X = position.X;
  424.             g.VTL.Position.Y = position.Y;
  425.             g.VTL.Position.Z = depth;
  426.             g.VTL.UV.X = 0;
  427.             g.VTL.UV.Y = 0;
  428.             g.VTL.UVRect = uvr;
  429.             g.VTL.Color = tint;
  430.  
  431.             g.VTR.Position.X = size.X + position.X;
  432.             g.VTR.Position.Y = position.Y;
  433.             g.VTR.Position.Z = depth;
  434.             g.VTR.UV.X = 1;
  435.             g.VTR.UV.Y = 0;
  436.             g.VTR.UVRect = uvr;
  437.             g.VTR.Color = tint;
  438.  
  439.             g.VBL.Position.X = position.X;
  440.             g.VBL.Position.Y = size.Y + position.Y;
  441.             g.VBL.Position.Z = depth;
  442.             g.VBL.UV.X = 0;
  443.             g.VBL.UV.Y = 1;
  444.             g.VBL.UVRect = uvr;
  445.             g.VBL.Color = tint;
  446.  
  447.             g.VBR.Position.X = size.X + position.X;
  448.             g.VBR.Position.Y = size.Y + position.Y;
  449.             g.VBR.Position.Z = depth;
  450.             g.VBR.UV.X = 1;
  451.             g.VBR.UV.Y = 1;
  452.             g.VBR.UVRect = uvr;
  453.             g.VBR.Color = tint;
  454.  
  455.             glyphs.Add(g);
  456.         }
  457.         public void Draw(GLTexture t, Vector2 position, Vector2 size, Color tint, float depth = 0f) {
  458.             SpriteGlyph g = CreateGlyph(t, depth);
  459.  
  460.             g.VTL.Position.X = position.X;
  461.             g.VTL.Position.Y = position.Y;
  462.             g.VTL.Position.Z = depth;
  463.             g.VTL.UV.X = 0;
  464.             g.VTL.UV.Y = 0;
  465.             g.VTL.UVRect = FULL_UV_RECT;
  466.             g.VTL.Color = tint;
  467.  
  468.             g.VTR.Position.X = size.X + position.X;
  469.             g.VTR.Position.Y = position.Y;
  470.             g.VTR.Position.Z = depth;
  471.             g.VTR.UV.X = 1;
  472.             g.VTR.UV.Y = 0;
  473.             g.VTR.UVRect = FULL_UV_RECT;
  474.             g.VTR.Color = tint;
  475.  
  476.             g.VBL.Position.X = position.X;
  477.             g.VBL.Position.Y = size.Y + position.Y;
  478.             g.VBL.Position.Z = depth;
  479.             g.VBL.UV.X = 0;
  480.             g.VBL.UV.Y = 1;
  481.             g.VBL.UVRect = FULL_UV_RECT;
  482.             g.VBL.Color = tint;
  483.  
  484.             g.VBR.Position.X = size.X + position.X;
  485.             g.VBR.Position.Y = size.Y + position.Y;
  486.             g.VBR.Position.Z = depth;
  487.             g.VBR.UV.X = 1;
  488.             g.VBR.UV.Y = 1;
  489.             g.VBR.UVRect = FULL_UV_RECT;
  490.             g.VBR.Color = tint;
  491.  
  492.             glyphs.Add(g);
  493.         }
  494.         public void DrawString(SpriteFont font, string s, Vector2 position, Vector2 scaling, Color tint, float depth = 0f) {
  495.             if(s == null) s = "";
  496.             font.Draw(this, s, position, scaling, tint, depth);
  497.         }
  498.         public void DrawString(SpriteFont font, string s, Vector2 position, float desiredHeight, float scaleX, Color tint, float depth = 0f) {
  499.             if(s == null) s = "";
  500.             Vector2 scaling = new Vector2(desiredHeight / font.FontHeight);
  501.             scaling.X *= scaleX;
  502.             font.Draw(this, s, position, scaling, tint, depth);
  503.         }
  504.  
  505.         private void SortGlyphs(SpriteSortMode ssm) {
  506.             if(glyphs.Count < 1) return;
  507.  
  508.             switch(ssm) {
  509.                 case SpriteSortMode.Texture:
  510.                     glyphs.Sort(SSMTexture);
  511.                     break;
  512.                 case SpriteSortMode.FrontToBack:
  513.                     glyphs.Sort(SSMFrontToBack);
  514.                     break;
  515.                 case SpriteSortMode.BackToFront:
  516.                     glyphs.Sort(SSMBackToFront);
  517.                     break;
  518.                 default:
  519.                     break;
  520.             }
  521.         }
  522.         private void GenerateBatches() {
  523.             if(glyphs.Count < 1) return;
  524.  
  525.             // Create Arrays
  526.             VertexSpriteBatch[] verts = new VertexSpriteBatch[6 * glyphs.Count];
  527.             int vi = 0;
  528.  
  529.             var call = new SpriteBatchCall(0, glyphs[0].Texture, batches);
  530.             verts[vi++] = glyphs[0].VTL;
  531.             verts[vi++] = glyphs[0].VTR;
  532.             verts[vi++] = glyphs[0].VBL;
  533.             verts[vi++] = glyphs[0].VBL;
  534.             verts[vi++] = glyphs[0].VTR;
  535.             verts[vi++] = glyphs[0].VBR;
  536.  
  537.             int gc = glyphs.Count;
  538.             for(int i = 1; i < gc; i++) {
  539.                 var glyph = glyphs[i];
  540.                 call = call.Append(glyph, batches);
  541.                 verts[vi++] = glyph.VTL;
  542.                 verts[vi++] = glyph.VTR;
  543.                 verts[vi++] = glyph.VBL;
  544.                 verts[vi++] = glyph.VBL;
  545.                 verts[vi++] = glyph.VTR;
  546.                 verts[vi++] = glyph.VBR;
  547.                 emptyGlyphs.Enqueue(glyphs[i]);
  548.             }
  549.             glyphs = null;
  550.  
  551.             // Set The Buffer Data
  552.             GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
  553.             if(gc > glyphCapacity) {
  554.                 glyphCapacity = gc * 2;
  555.                 GL.BufferData(
  556.                     BufferTarget.ArrayBuffer,
  557.                     new IntPtr((glyphCapacity * 6) * VertexSpriteBatch.Size),
  558.                     IntPtr.Zero,
  559.                     bufUsage
  560.                     );
  561.             }
  562.             unsafe {
  563.                 fixed(VertexSpriteBatch* ptr = verts) {
  564.                     GL.BufferSubData(
  565.                         BufferTarget.ArrayBuffer,
  566.                         IntPtr.Zero,
  567.                         new IntPtr(verts.Length * VertexSpriteBatch.Size),
  568.                         new IntPtr(ptr)
  569.                         );
  570.                 }
  571.             }
  572.             GLBuffer.Unbind(BufferTarget.ArrayBuffer);
  573.         }
  574.         public void End(SpriteSortMode ssm = SpriteSortMode.Texture) {
  575.             SortGlyphs(ssm);
  576.             GenerateBatches();
  577.         }
  578.  
  579.         public void RenderBatch(Matrix4 mWorld, Matrix4 mCamera, BlendState bs = null, SamplerState ss = null, DepthState ds = null, RasterizerState rs = null) {
  580.             if(bs == null) bs = BlendState.PremultipliedAlphaBlend;
  581.             if(ds == null) ds = DepthState.None;
  582.             if(rs == null) rs = RasterizerState.CullNone;
  583.             if(ss == null) ss = SamplerState.LinearWrap;
  584.  
  585.             // Setup The Shader
  586.             bs.Set();
  587.             ds.Set();
  588.             rs.Set();
  589.  
  590.             GL.UseProgram(idProg);
  591.  
  592.             GL.UniformMatrix4(unWorld, true, ref mWorld);
  593.             GL.UniformMatrix4(unVP, true, ref mCamera);
  594.  
  595.             GL.BindVertexArray(vao);
  596.             GL.EnableVertexAttribArray(0);
  597.             GL.EnableVertexAttribArray(1);
  598.             GL.EnableVertexAttribArray(2);
  599.             GL.EnableVertexAttribArray(3);
  600.  
  601.             // Draw All The Batches
  602.             int bc = batches.Count;
  603.             for(int i = 0; i < bc; i++) {
  604.                 var batch = batches[i];
  605.                 //batch.Texture.Use(TextureUnit.Texture0, unTexture);
  606.                 //ss.Set(batch.Texture.Target);
  607.                 GL.DrawArrays(PrimitiveType.Triangles, batch.IndexOffset, batch.Indices);
  608.                 //batch.Texture.Unuse();
  609.             }
  610.  
  611.             //GLProgram.Unuse();
  612.             GL.UseProgram(0);
  613.             GL.BindVertexArray(0);
  614.         }
  615.     }
  616. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement