public static void TackObjectGetInfo(string[] args)
        {
            if (args.Length == 2)
            {
                // Try and get the TackObject by treating args[1] has a name
                TackObject calledObject = TackObject.Get(args[1]);

                // If there is no TackObject with name that is equal to args[1]
                //  - Treat args[1] as a hash and look for TackObject based on hash
                if (calledObject == null)
                {
                    calledObject = TackObject.GetUsingHash(args[1]);
                }

                // If there is no TackObject with name OR hash equal to args[1], return
                if (calledObject == null)
                {
                    TackConsole.EngineLog(EngineLogType.Error, "There is no TackObject that has name/hash with value: " + args[1]);
                    return;
                }

                TackConsole.EngineLog(EngineLogType.Message, "TackObject Info");
                TackConsole.EngineLog(EngineLogType.Message, "--------------------------------------");
                TackConsole.EngineLog(EngineLogType.Message, "Name: {0:-20}", calledObject.Name);
                TackConsole.EngineLog(EngineLogType.Message, "Hash: {0:-20}", calledObject.GetHash());
                TackConsole.EngineLog(EngineLogType.Message, "Position: {0:-20}", calledObject.Position.ToString());
                TackConsole.EngineLog(EngineLogType.Message, "Scale: {0:-20}", calledObject.Scale.ToString());
                TackConsole.EngineLog(EngineLogType.Message, "Rotation: {0:-20}", calledObject.Rotation);
                TackConsole.EngineLog(EngineLogType.Message, "Components ({0}):", calledObject.GetComponents().Length);

                TackComponent[] components = calledObject.GetComponents();

                foreach (TackComponent comp in components)
                {
                    TackConsole.EngineLog(EngineLogType.Message, "          - {0}", comp.GetType().Name);
                }

                return;
            }

            TackConsole.EngineLog(EngineLogType.Error, "Incorrect number of arguments for command: " + args[0]);
        }
        /// <summary>
        /// Loops through all active TackObjects and renders all QuadRenderer components
        /// </summary>
        private void RenderQuadRendererComponents()
        {
            GL.Enable(EnableCap.Texture2D);
            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.One, BlendingFactor.OneMinusSrcAlpha);

            GL.EnableClientState(ArrayCap.ColorArray);
            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.IndexArray);
            GL.EnableClientState(ArrayCap.TextureCoordArray);

            // Tell OpenGL to use teh default object shader
            //GL.UseProgram(GetShader("shaders.default_world_shader", TackShaderType.World).Id);

            TackObject[] allObjects = TackObject.Get();

            List <TackObject> allObjectsWithQRComp = new List <TackObject>(allObjects.Where(x => x.GetComponent <QuadRenderer>() != null));
            List <TackObject> orderedComponents    = new List <TackObject>(allObjectsWithQRComp.OrderBy(x => x.GetComponent <QuadRenderer>().RenderLayer));

            foreach (TackObject currentTackObject in orderedComponents)
            {
                // Continue with the loop if currentTackObject does not contain a QuadRenderer component
                if (currentTackObject.GetComponent <QuadRenderer>() == null)
                {
                    continue;
                }

                /*
                 * // Continue if TackObject is currently inactive
                 * if (currentTackObject.)
                 */

                QuadRenderer quadRenderer = currentTackObject.GetComponent <QuadRenderer>();

                RectangleShape tackObjectBounds = new RectangleShape()
                {
                    X      = ((currentTackObject.Position.X - TackEngine.MainCamera.GetParent().Position.X) - (currentTackObject.Scale.X / 2)) / (TackEngine.ScreenWidth / 2),
                    Y      = ((currentTackObject.Position.Y - TackEngine.MainCamera.GetParent().Position.Y) + (currentTackObject.Scale.Y / 2)) / (TackEngine.ScreenHeight / 2),
                    Width  = (currentTackObject.Scale.X) / (TackEngine.ScreenWidth / 2),
                    Height = (currentTackObject.Scale.Y) / (TackEngine.ScreenHeight / 2)
                };

                /*
                 *    v4 ------ v1
                 *    |         |
                 *    |         |
                 *    |         |
                 *    v3 ------ v2
                 *
                 */


                //mVertexData = new float[32]
                //{
                //       Position (XYZ)                                                                                                      Colours (RGB)                                                                                  TexCoords (XY)
                /* v1 */     //(tackObjectBounds.X + tackObjectBounds.Width), (tackObjectBounds.Y), 1.0f,                                          (quadRenderer.Colour.R / 255), (quadRenderer.Colour.G / 255), (quadRenderer.Colour.B / 255),   1.0f, 0.0f,
                /* v2 */     //(tackObjectBounds.X + tackObjectBounds.Width), (tackObjectBounds.Y - tackObjectBounds.Height), 1.0f,                (quadRenderer.Colour.R / 255), (quadRenderer.Colour.G / 255), (quadRenderer.Colour.B / 255),   1.0f, 1.0f,
                /* v3 */     //(tackObjectBounds.X), (tackObjectBounds.Y - tackObjectBounds.Height), 1.0f,                                         (quadRenderer.Colour.R / 255), (quadRenderer.Colour.G / 255), (quadRenderer.Colour.B / 255),   0.0f, 1.0f,
                /* v4 */     //(tackObjectBounds.X), (tackObjectBounds.Y), 1.0f,                                                                   (quadRenderer.Colour.R / 255), (quadRenderer.Colour.G / 255), (quadRenderer.Colour.B / 255),   0.0f, 0.0f
                //};

                mVertexData = new float[32]
                {
                    //       Position (XYZ)                                                                                                      Colours (RGB)                                                                                  TexCoords (XY)
                    /* v1 */ FindScreenCoordsFromPosition(quadRenderer.FindVertexPoint(1)).X, FindScreenCoordsFromPosition(quadRenderer.FindVertexPoint(1)).Y, 1.0f, (quadRenderer.Colour.R / 255.0f), (quadRenderer.Colour.G / 255.0f), (quadRenderer.Colour.B / 255.0f), 1.0f, 0.0f,
                    /* v2 */ FindScreenCoordsFromPosition(quadRenderer.FindVertexPoint(2)).X, FindScreenCoordsFromPosition(quadRenderer.FindVertexPoint(2)).Y, 1.0f, (quadRenderer.Colour.R / 255.0f), (quadRenderer.Colour.G / 255.0f), (quadRenderer.Colour.B / 255.0f), 1.0f, 1.0f,
                    /* v3 */ FindScreenCoordsFromPosition(quadRenderer.FindVertexPoint(3)).X, FindScreenCoordsFromPosition(quadRenderer.FindVertexPoint(3)).Y, 1.0f, (quadRenderer.Colour.R / 255.0f), (quadRenderer.Colour.G / 255.0f), (quadRenderer.Colour.B / 255.0f), 0.0f, 1.0f,
                    /* v4 */ FindScreenCoordsFromPosition(quadRenderer.FindVertexPoint(4)).X, FindScreenCoordsFromPosition(quadRenderer.FindVertexPoint(4)).Y, 1.0f, (quadRenderer.Colour.R / 255.0f), (quadRenderer.Colour.G / 255.0f), (quadRenderer.Colour.B / 255.0f), 0.0f, 0.0f
                };

                int[] indices = new int[]
                {
                    0, 1, 3, // first triangle
                    1, 2, 3  // second triangle
                };

                //Sprite sp = Sprite.LoadFromFile("Resources/background_image.png");
                //sp.Create(false);

                int VAO = GL.GenVertexArray();
                int VBO = GL.GenBuffer();
                int EBO = GL.GenBuffer();

                GL.BindVertexArray(VAO);

                GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
                GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * 32, mVertexData, BufferUsageHint.StaticDraw);

                GL.BindBuffer(BufferTarget.ElementArrayBuffer, EBO);
                GL.BufferData(BufferTarget.ElementArrayBuffer, sizeof(int) * 6, indices, BufferUsageHint.StaticDraw);

                // position attribute
                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0);
                GL.EnableVertexAttribArray(0);

                // color attribute
                GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 3 * sizeof(float));
                GL.EnableVertexAttribArray(1);

                // texture coord attribute
                GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), 6 * sizeof(float));
                GL.EnableVertexAttribArray(2);

                // Set texture attributes
                GL.ActiveTexture(TextureUnit.Texture0);
                if (quadRenderer.RenderMode == RendererMode.SpriteSheet)
                {
                    GL.BindTexture(TextureTarget.Texture2D, quadRenderer.SpriteSheet.GetActiveSprite().Id);
                }
                else
                {
                    GL.BindTexture(TextureTarget.Texture2D, quadRenderer.Sprite.Id);
                }


                //GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, quadRenderer.Sprite.Width, quadRenderer.Sprite.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, quadRenderer.Sprite.SpriteData.Scan0);


                // set texture filtering parameters
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

                // set the texture wrapping parameters
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);



                GL.ActiveTexture(TextureUnit.Texture0);

                if (quadRenderer.RenderMode == RendererMode.SpriteSheet)
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, quadRenderer.SpriteSheet.SingleSpriteWidth, quadRenderer.SpriteSheet.SingleSpriteHeight, 0, PixelFormat.Bgra, PixelType.UnsignedByte, (IntPtr)0); // changed the end value from sprite.bitmpadata.scan0
                }
                else
                {
                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, quadRenderer.Sprite.Width, quadRenderer.Sprite.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, quadRenderer.Sprite.Data);
                }
                //GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);

                m_defaultWorldShader.Use();
                m_defaultWorldShader.SetUniformValue("ourTexture", 0);
                // Set the shader uniform value
                //GL.Uniform1(GL.GetUniformLocation(GetShader("shaders.default_world_shader", TackShaderType.World).Id, "ourTexture"), 0);

                GL.ActiveTexture(TextureUnit.Texture0);
                if (quadRenderer.RenderMode == RendererMode.SpriteSheet)
                {
                    GL.BindTexture(TextureTarget.Texture2D, quadRenderer.SpriteSheet.GetActiveSprite().Id);
                }
                else
                {
                    GL.BindTexture(TextureTarget.Texture2D, quadRenderer.Sprite.Id);
                }

                GL.BindVertexArray(VAO);

                GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, IntPtr.Zero);

                //sp.Destory(false);

                GL.DeleteBuffer(EBO);
                GL.DeleteBuffer(VBO);
                GL.DeleteVertexArray(VAO);
            }
        }