public static void Run()
        {
            ShaderProgram prog = null, terrProg = null;
            Texture tex = null, t2 = null;

            GraphicsContext context = new GraphicsContext()
            {
                Camera = new FirstPersonCamera(new Vector3(4, 3, 3), Vector3.UnitY)
            };

            BitmapTextureSource bmpTex, b2, b3;
            bmpTex = TextDrawer.CreateWriter("Times New Roman", FontStyle.Regular).Write("Hello!", 200, System.Drawing.Color.White);
            b2 = new BitmapTextureSource("test.jpg", 0);
            b3 = new BitmapTextureSource("test.png", 0);

            Texture fbufTex = null, t3 = null;
            FramebufferTextureSource fbufTexSrc = new FramebufferTextureSource(256, 256, 0);
            Framebuffer fbuf = null;

            Matrix4 World = Matrix4.Identity;
            EngineObject eObj = null, fsq = null;
            float timer = 0;

            CubeMapTextureSource tFace = new CubeMapTextureSource(CubeMapTextureSource.CubeMapFace.PositiveY, b3),
                bFace = new CubeMapTextureSource(CubeMapTextureSource.CubeMapFace.PositiveX, b3),
                lFace = new CubeMapTextureSource(CubeMapTextureSource.CubeMapFace.PositiveZ, b3),
                rFace = new CubeMapTextureSource(CubeMapTextureSource.CubeMapFace.NegativeX, b3),
                fFace = new CubeMapTextureSource(CubeMapTextureSource.CubeMapFace.NegativeY, b3),
                hFace = new CubeMapTextureSource(CubeMapTextureSource.CubeMapFace.NegativeZ, b3);

            GraphicsDevice.Load += () =>
            {
                // setup settings, load textures, sounds
                GraphicsDevice.Wireframe = false;
                GraphicsDevice.AlphaEnabled = true;
                GraphicsDevice.DepthTestEnabled = true;
                GraphicsDevice.CullEnabled = false;
                GraphicsDevice.CullMode = CullFaceMode.Back;

                eObj = new EngineObject();
                float[] data =
                {     -1, -1, 1,
                       1, -1, 1,
                       0, 1, 1
                };

                uint[] indexData = new uint[]
                {
                    0, 1, 2
                };

                ShaderSource vert = ShaderSource.Load(ShaderType.VertexShader, "Testing/TG_A/vertex.glsl");
                ShaderSource frag = ShaderSource.Load(ShaderType.FragmentShader, "Testing/TG_A/fragment.glsl");
                ShaderSource tctrl = ShaderSource.Load(ShaderType.TessControlShader, "Testing/TG_A/tesscontrol.glsl");
                ShaderSource teval = ShaderSource.Load(ShaderType.TessEvaluationShader, "Testing/TG_A/tessdomain.glsl");

                ShaderSource vA = ShaderSource.Load(ShaderType.VertexShader, "Shaders/TerrainGen/vertex.glsl");
                ShaderSource fA = ShaderSource.Load(ShaderType.FragmentShader, "Shaders/TerrainGen/fragment.glsl");
                terrProg = new ShaderProgram(vA, fA);
                terrProg.Set("World", Matrix4.Identity);

                fbuf = new Framebuffer(256, 256);
                fbufTex = new Texture();
                fbufTex.SetData(fbufTexSrc);
                fbuf[FramebufferAttachment.ColorAttachment0] = fbufTex;

                fsq = FullScreenQuadFactory.Create();

                t3 = new Texture();
                t3.SetData(tFace);
                t3.SetData(bFace);
                t3.SetData(lFace);
                t3.SetData(rFace);
                t3.SetData(fFace);
                t3.SetData(hFace);
                t3.SetEnableLinearFilter(true);
                t3.SetAnisotropicFilter(Texture.MaxAnisotropy);

                tex = new Texture();
                tex.SetData(bmpTex);
                tex.SetAnisotropicFilter(Texture.MaxAnisotropy);

                t2 = new Texture();
                t2.SetData(b3);
                t2.SetAnisotropicFilter(Texture.MaxAnisotropy);

                prog = new ShaderProgram(vert, tctrl, teval, frag);
                prog.Set("img", 0);
                prog.Set("heightmap", 1);
                prog.Set("World", World);

                vert.Dispose();
                frag.Dispose();
                tctrl.Dispose();
                teval.Dispose();

                //eObj = FullScreenQuadFactory.Create();
                eObj = CubeFactory.Create();
                eObj.SetTexture(0, t2);
                eObj.SetTexture(1, t3);

                b3.Dispose();
            };
            bool eyePosStill = false;
            GraphicsDevice.Update += (e) =>
            {
                // add game logic, input handling
                if (GraphicsDevice.Keyboard[Key.Escape])
                {
                    GraphicsDevice.Exit();
                }

                if(GraphicsDevice.Keyboard[Key.Z])
                {
                    GraphicsDevice.Wireframe = !GraphicsDevice.Wireframe;
                    //GraphicsDevice.CullEnabled = !GraphicsDevice.Wireframe;
                }

                if(GraphicsDevice.Keyboard[Key.F])
                {
                    eyePosStill = !eyePosStill;
                    Console.WriteLine("EyePosStill = " + eyePosStill);
                }

                context.Update(e);
                //context.Projection = Matrix4.Identity;
                //context.View = Matrix4.Identity;

                prog.Set("View", context.View);
                prog.Set("Proj", context.Projection);
                if(!eyePosStill)prog.Set("eyePos", context.Camera.Position);

                prog.Set("Fcoef", (float)(2.0f / Math.Log(1000001)/Math.Log(2)));

                //timer += 0.001f;
                //World = Matrix4.RotateY(timer);
                World = Matrix4.CreateScale(10);
                prog.Set("World", World);

                prog.Set("timer", timer);
                terrProg.Set("timer", timer);
            };

            bool te1 = false;

            GraphicsDevice.Render += (e) =>
            {
                GraphicsDevice.SetFramebuffer(fbuf);
                GraphicsDevice.Clear();

                fsq.Bind();
                GraphicsDevice.SetShaderProgram(terrProg);
                GraphicsDevice.SetViewport(0, 0, 256, 256);
                GraphicsDevice.Draw(PrimitiveType.Triangles, 0, fsq.IndexCount);

                eObj.Bind();
                GraphicsDevice.SetShaderProgram(prog);
                GraphicsDevice.SetViewport(0, 0, GraphicsDevice.WindowSize.Width, GraphicsDevice.WindowSize.Height);
                GraphicsDevice.PatchCount = 3;
                GraphicsDevice.Draw(PrimitiveType.Patches, 0, eObj.IndexCount);

                GraphicsDevice.SwapBuffers();
                if (!te1)
                {
                    te1 = true;
                    GraphicsDevice.SaveTexture(fbufTex, "test1.png");
                }
            };

            GraphicsDevice.Name = "The Julis Faction";
            // Run the game at 60 updates per second
            GraphicsDevice.Run(60.0, 60.0);
            if(GraphicsDevice.Cleanup != null)GraphicsDevice.Cleanup();
        }
        public static void Run()
        {
            GraphicsContext context = new GraphicsContext()
            {
                Camera = new FirstPersonCamera(new Vector3(4, 3, 3), Vector3.UnitY)
            };
            Matrix4 World = Matrix4.Identity;

            VoxelTypeMap v = new VoxelTypeMap();
            v[0] = new VoxelTypeMap.VoxelTypeData()
            {
                Color = Vector4.One,
                Visible = false
            };

            v[1] = new VoxelTypeMap.VoxelTypeData()
            {
                Color = Vector4.UnitY * 0.7f + Vector4.UnitW,
                Visible = true
            };

            v[2] = new VoxelTypeMap.VoxelTypeData()
            {
                Color = Vector4.UnitX + Vector4.UnitW,
                Visible = true
            };

            BlockManager man = new BlockManager();
            man.Side = 32;
            man.VoxelTypes = v;

            //Rendering stuff
            ShaderProgram prog = null;

            GraphicsDevice.Load += () =>
            {
                //GraphicsDevice.Winding = FaceWinding.Clockwise;
                GraphicsDevice.CullMode = OpenTK.Graphics.OpenGL4.CullFaceMode.Back;
                GraphicsDevice.DepthTestEnabled = true;
                GraphicsDevice.Window.KeyUp += (k, e) =>
                {
                    if (e.Key == OpenTK.Input.Key.Z) GraphicsDevice.Wireframe = !GraphicsDevice.Wireframe;
                    else if (e.Key == OpenTK.Input.Key.C) GraphicsDevice.CullEnabled = !GraphicsDevice.CullEnabled;
                };

                Random rng = new Random(0);
                double n = 64;

                v.UpdateBuffers();
                GraphicsDevice.SetBufferTexture(0, v.ColorData);

                ShaderSource vShader = ShaderSource.Load(OpenTK.Graphics.OpenGL4.ShaderType.VertexShader, "Testing/VoxTest/vertex.glsl");
                ShaderSource fShader = ShaderSource.Load(OpenTK.Graphics.OpenGL4.ShaderType.FragmentShader, "Testing/VoxTest/fragment.glsl");

                prog = new ShaderProgram(vShader, fShader);
                prog.Set("materialColors", 0);

            };

            GraphicsDevice.Update += (e) =>
            {
                context.Update(e);

                //World *= Matrix4.CreateRotationY(0.01f);

                prog.Set("World", Matrix4.Identity);
                prog.Set("View", context.View);
                prog.Set("Proj", context.Projection);
                prog.Set("Fcoef", (float)(2.0f / Math.Log(1000001) / Math.Log(2)));
                prog.Set("lightDir", new Vector3(5, 10, 5).Normalized());

            };

            GraphicsDevice.Render += (e) =>
            {
                GraphicsDevice.Clear();

                for (int k = -2; k < 0; k++)
                {
                    Vector3 a = new Vector3();
                    a.Y = k * man.Side;
                    for (int i = -5; i <= 5; i++)
                    {
                        a.Z = i * man.Side;
                        for (int j = -5; j <= 5; j++)
                        {
                            a.X = j * man.Side;
                            Vector3 dir = (context.Camera as FirstPersonCamera).Direction;
                            if (Vector3.Dot(dir.Normalized(), a.Normalized()) >= -0.3)
                            {
                                //Chunk c = man.Draw(-Vector3.UnitY * 123, out World);
                                Chunk c = man.Draw(context.Camera.Position + a, out World);
                                if (c.ChunkReady)
                                {
                                    c.Bind();
                                    prog.Set("World", World);

                                    prog.Set("range1", c.NormalOffsets[1]);
                                    prog.Set("range2", c.NormalOffsets[2]);
                                    prog.Set("range3", c.NormalOffsets[3]);
                                    prog.Set("range4", c.NormalOffsets[4]);
                                    prog.Set("range5", c.NormalOffsets[5]);
                                    GraphicsDevice.SetShaderProgram(prog);

                                    GraphicsDevice.Draw(OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles, 0, c.NormalGroupSizes[6]);
                                }
                            }
                        }
                    }
                }

                GraphicsDevice.SwapBuffers();
            };

            GraphicsDevice.Name = "Voxel Test";
            GraphicsDevice.Run(60, 0);
            if (GraphicsDevice.Cleanup != null) GraphicsDevice.Cleanup();
        }