Пример #1
0
        internal void Launch()
        {
            Console.WriteLine("Windows...");

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext();
            using var window1          = windowServer.CreateWindow(renderingContext);
            using var window2          = windowServer.CreateWindow(renderingContext);

            var eventLogger = new EventLogger();

            window1.Title = "Window 1";
            eventLogger.RegisterWindow(window1);

            window2.Title       = "Window 2";
            window2.BorderStyle = WindowBorderStyle.Sizable;
            eventLogger.RegisterWindow(window2);
            var cursor = CreateCursor();

            window2.Cursor = windowServer.CreateCursor(cursor.Data, cursor.Size, (7, 7));

            renderingContext.CurrentWindow = window1;
            var glClear      = renderingContext.GetOpenGLEntryPoint <GLClearDelegate>("glClear");
            var glClearColor = renderingContext.GetOpenGLEntryPoint <GLClearColorDelegate>("glClearColor");

            window1.Visible = true;
            window2.Visible = true;
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            while (windowServer.Windows.Count > 0)
            {
                if (!window1.Disposed)
                {
                    renderingContext.CurrentWindow = window1;
                    glClearColor(0.2f, 0.5f, 0.8f, 1.0f);
                    glClear(GLBuffers.Color);
                    renderingContext.SwapBuffers(window1);
                }
                if (!window2.Disposed)
                {
                    renderingContext.CurrentWindow = window2;
                    glClearColor(0.8f, 0.5f, 0.2f, 1.0f);
                    glClear(GLBuffers.Color);
                    renderingContext.SwapBuffers(window2);
                }
                windowServer.ProcessEvents(0.02);
                eventLogger.PrintLog(stopwatch.ElapsedMilliseconds);
            }
            stopwatch.Stop();
            Console.WriteLine("Windows done.");
        }
Пример #2
0
        internal unsafe void Launch()
        {
            Console.WriteLine("Draw Texture...");

            var image      = new RasterImage();
            var namePrefix = typeof(DrawTextureLauncher).Namespace + ".Resources.";

            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "kitten.bmp"))
            {
                image.LoadBmp(stream ?? throw new InvalidOperationException());
            }

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext();
            using var window           = windowServer.CreateWindow(renderingContext);

            window.BorderStyle             = WindowBorderStyle.Sizable;
            renderingContext.CurrentWindow = window;
            window.MinimumSize             = (400, 300);
            window.MaximumSize             = (600, 500);
            window.Size    = (450, 350);
            window.Opacity = 0.8;

            var gl = new GraphicsLibrary(renderingContext);

            gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);

            var program      = gl.CreateProgram();
            var vertexShader = OpenGLHelper.LoadShader(gl, ShaderType.Vertex, @"
                    in vec2 position;
                    in vec3 color;
                    in vec2 texCoord;
                    out vec3 fColor;
                    out vec2 fTexCoord;
                    void main() {
                        gl_Position = vec4(position, 0.0, 1.0);
                        fColor = color;
                        fTexCoord = texCoord;
                    }
                ");

            gl.AttachShader(program, vertexShader);
            var fragmentShader = OpenGLHelper.LoadShader(gl, ShaderType.Fragment, @"
                    in vec3 fColor;
                    in vec2 fTexCoord;
                    out vec4 outColor;
                    uniform sampler2D tex;
                    void main() {
                        outColor = texture(tex, fTexCoord) * vec4(fColor, 1.0);
                    }
                ");

            gl.AttachShader(program, fragmentShader);

            var position = 0u;

            OpenGLHelper.BindAttribLocation(gl, program, position, "position");
            var color = 1u;

            OpenGLHelper.BindAttribLocation(gl, program, color, "color");
            var texCoord = 2u;

            OpenGLHelper.BindAttribLocation(gl, program, texCoord, "texCoord");

            OpenGLHelper.LinkProgram(gl, program);

            uint h;

            gl.GenVertexArrays(1, &h);
            uint vertexArray = h;

            gl.BindVertexArray(vertexArray);

            float[] vertices = new float[] {
                -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,     // Top-left
                0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,      // Top-right
                0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,     // Bottom-right
                -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f     // Bottom-left
            };
            gl.GenBuffers(1, &h);
            uint vertexBuffer = h;

            gl.BindBuffer(BufferTarget.Array, vertexBuffer);
            OpenGLHelper.BufferData(gl, BufferTarget.Array, vertices, BufferUsage.StaticDraw);

            var elements = new ushort[] {
                0, 1, 2,
                2, 3, 0
            };

            gl.GenBuffers(1, &h);
            uint elementBuffer = h;

            gl.BindBuffer(BufferTarget.ElementArray, elementBuffer);
            OpenGLHelper.BufferData(gl, BufferTarget.ElementArray, elements, BufferUsage.StaticDraw);

            gl.UseProgram(program);
            var stride = sizeof(float) * 7;

            gl.EnableVertexAttribArray(position);
            gl.VertexAttribPointer(position, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero);
            gl.EnableVertexAttribArray(color);
            gl.VertexAttribPointer(color, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 2 * sizeof(float));
            gl.EnableVertexAttribArray(texCoord);
            gl.VertexAttribPointer(texCoord, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 5 * sizeof(float));

            gl.GenTextures(1, &h);
            var texture = h;

            gl.ActiveTexture(TextureUnit.Texture0);
            gl.BindTexture(TextureTarget.Texture2d, texture);
            OpenGLHelper.TexImage2D(gl, image, TextureTarget2D.Texture2d, 0);

            gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureWrapS, (int)TextureParameterValue.ClampToEdge);
            gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureWrapT, (int)TextureParameterValue.ClampToEdge);
            gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureMinFilter, (int)TextureParameterValue.Linear);
            gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureMagFilter, (int)TextureParameterValue.Linear);

            var tex = OpenGLHelper.GetUniformLocation(gl, program, "tex");

            gl.Uniform1i(tex, 0);

            window.Closed += (sender, e) => {
                uint t = texture;
                gl.DeleteTextures(1, &t);
                gl.DeleteProgram(program);
                gl.DeleteShader(vertexShader);
                gl.DeleteShader(fragmentShader);
                t = vertexBuffer;
                gl.DeleteBuffers(1, &t);
                t = elementBuffer;
                gl.DeleteBuffers(1, &t);
                t = vertexArray;
                gl.DeleteVertexArrays(1, &t);
            };

            void draw()
            {
                var(width, height) = window.ViewportSize;
                gl.Viewport(0, 0, (int)width, (int)height);
                gl.Clear(Buffers.Color);
                gl.DrawElements(DrawMode.Triangles, 6, DrawIndexType.UnsignedShort, IntPtr.Zero);
                renderingContext.SwapBuffers(window);
            }

            window.Resize += (sender, e) => draw();

            window.Visible = true;
            while (windowServer.Windows.Count > 0)
            {
                draw();

                windowServer.ProcessEvents(0.02);
            }

            Console.WriteLine("Draw Texture done.");
        }
Пример #3
0
        internal void Launch()
        {
            Console.WriteLine("Terrain...");
            Console.WriteLine("  Press Esc to exit.");
            Console.WriteLine("  Press W, Q, S, D, Space to move.");

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 4 } };

            using var window   = windowServer.CreateWindow(renderingContext);
            window.Title       = "Terrain";
            window.BorderStyle = WindowBorderStyle.Sizable;

            const double WindowWidth  = 1024;
            const double WindowHeight = 768;

            window.Size = (WindowWidth, WindowHeight);

            renderingContext.CurrentWindow = window;
            var gl = new GraphicsLibrary(renderingContext);

            gl.ClearColor(0, 0, 0, 1);
            using (var scene = new Scene(gl))
            {
                var imageLength = 16 * 16 * 3;
                var buffer      = new byte[imageLength * 3];
                var image       = new RasterImage();
                var namePrefix  = typeof(TerrainLauncher).Namespace + ".Resources.";
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "grass.png"))
                {
                    image.LoadPng(stream ?? throw new InvalidOperationException());
                }
                Array.Copy(image.Data, 0, buffer, 0, imageLength);
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "grass_side.png"))
                {
                    image.LoadPng(stream ?? throw new InvalidOperationException());
                }
                Array.Copy(image.Data, 0, buffer, imageLength, imageLength);
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "dirt.png"))
                {
                    image.LoadPng(stream ?? throw new InvalidOperationException());
                }
                Array.Copy(image.Data, 0, buffer, imageLength * 2, imageLength);
                scene.AddTextureMap(buffer, 3);

                var viewportSize = window.ViewportSize;
                scene.SetViewport(0, 0, (int)viewportSize.width, (int)viewportSize.height);

                (double x, double y)previousPoint = (-1d, -1d);
                window.MouseMove += (sender, e) =>
                {
                    if (previousPoint.x != -1d || previousPoint.y != -1d)
                    {
                        scene.Rotate((float)(e.Position.x - previousPoint.x), (float)(e.Position.y - previousPoint.y));
                    }
                    previousPoint = e.Position;
                };


                void draw()
                {
                    scene.Render();
                    renderingContext.SwapBuffers(window);
                }

                window.Resize += (sender, e) =>
                {
                    var(width, height) = window.ViewportSize;
                    scene.SetViewport(0, 0, (int)width, (int)height);
                    draw();
                };

                window.FramebufferResize += (sender, e) =>
                {
                    var(width, height) = window.ViewportSize;
                    scene.SetViewport(0, 0, (int)width, (int)height);
                };

                window.Closed += (sender, e) =>
                {
                    scene.Dispose();
                };

                var stopWatch = new Stopwatch();
                stopWatch.Start();
                var lastTime  = stopWatch.ElapsedMilliseconds / 1e3f;
                var deltaTime = 0.0f;

                window.FreeLookMouse = true;
                //renderingContext.SyncWithVerticalBlank(window, false);
                Console.WriteLine("Press 'Esc' to quit.");
                window.Visible = true;
                while (windowServer.Windows.Count > 0)
                {
                    var currentTime = stopWatch.ElapsedMilliseconds / 1e3f;
                    deltaTime = currentTime - lastTime;
                    lastTime  = currentTime;

                    if (window.IsKeyPressed(Keycode.W))
                    {
                        scene.MoveForward(deltaTime);
                    }
                    if (window.IsKeyPressed(Keycode.S))
                    {
                        scene.MoveBackward(deltaTime);
                    }
                    if (window.IsKeyPressed(Keycode.A))
                    {
                        scene.MoveLeft(deltaTime);
                    }
                    if (window.IsKeyPressed(Keycode.D))
                    {
                        scene.MoveRight(deltaTime);
                    }
                    if (window.IsKeyPressed(Keycode.Space))
                    {
                        scene.MoveUp(deltaTime);
                    }
                    if (window.IsKeyPressed(Keycode.Escape))
                    {
                        window.Close();
                        windowServer.ProcessEvents(0.0);
                        break;
                    }

                    draw();

                    windowServer.ProcessEvents(0.0);
                }
                stopWatch.Stop();
            }
            Console.WriteLine("Terrain done.");
        }
Пример #4
0
        internal unsafe void Launch()
        {
            Console.WriteLine("Rotate Cube...");

            var image      = new RasterImage();
            var namePrefix = typeof(DrawTextureLauncher).Namespace + ".Resources.";

            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "kitten.png"))
            {
                image.LoadPng(stream ?? throw new InvalidOperationException());
            }

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext();
            using var window           = windowServer.CreateWindow(renderingContext);

            window.BorderStyle             = WindowBorderStyle.Sizable;
            window.Title                   = "Rotate Cube...";
            renderingContext.CurrentWindow = window;

            var gl = new GraphicsLibrary(renderingContext);

            gl.ClearColor(0, 0, 0, 1);

            var program      = gl.CreateProgram();
            var vertexShader = OpenGLHelper.LoadShader(gl, ShaderType.Vertex, @"
                    in vec3 position;
                    in vec3 color;
                    in vec2 texCoord;
                    out vec3 fColor;
                    out vec2 fTexCoord;
                    uniform mat4 model;
                    uniform mat4 view;
                    uniform mat4 proj;
                    void main() {
                        gl_Position = proj * view * model * vec4(position, 1.0);
                        fColor = color;
                        fTexCoord = texCoord;
                    }
                ");

            gl.AttachShader(program, vertexShader);
            var fragmentShader = OpenGLHelper.LoadShader(gl, ShaderType.Fragment, @"
                    in vec3 fColor;
                    in vec2 fTexCoord;
                    out vec4 outColor;
                    uniform sampler2D tex;
                    void main() {
                        outColor = texture(tex, fTexCoord) * vec4(fColor, 1.0);
                    }
                ");

            gl.AttachShader(program, fragmentShader);

            var position = 0u;

            OpenGLHelper.BindAttribLocation(gl, program, position, "position");
            var color = 1u;

            OpenGLHelper.BindAttribLocation(gl, program, color, "color");
            var texCoord = 2u;

            OpenGLHelper.BindAttribLocation(gl, program, texCoord, "texCoord");

            OpenGLHelper.LinkProgram(gl, program);

            uint h;

            gl.GenVertexArrays(1, &h);
            uint vertexArray = h;

            gl.BindVertexArray(vertexArray);

            var vertices = new float[] {
                -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
                0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,

                -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
                0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,

                -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
                -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,

                0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
                0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,

                -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
                -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,

                -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
                0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
                0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
                0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
                -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
                -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
            };

            gl.GenBuffers(1, &h);
            uint vertexBuffer = h;

            gl.BindBuffer(BufferTarget.Array, vertexBuffer);
            OpenGLHelper.BufferData(gl, BufferTarget.Array, vertices, BufferUsage.StaticDraw);

            var stride = sizeof(float) * 8;

            gl.EnableVertexAttribArray(position);
            gl.VertexAttribPointer(position, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero);
            gl.EnableVertexAttribArray(color);
            gl.VertexAttribPointer(color, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 3 * sizeof(float));
            gl.EnableVertexAttribArray(texCoord);
            gl.VertexAttribPointer(texCoord, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero + 6 * sizeof(float));

            gl.GenTextures(1, &h);
            var texture = h;

            gl.ActiveTexture(TextureUnit.Texture0);
            gl.BindTexture(TextureTarget.Texture2d, texture);
            OpenGLHelper.TexImage2D(gl, image, TextureTarget2D.Texture2d, 0);

            gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureWrapS, (int)TextureParameterValue.ClampToEdge);
            gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureWrapT, (int)TextureParameterValue.ClampToEdge);
            gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureMinFilter, (int)TextureParameterValue.Linear);
            gl.TexParameteri(TextureTarget.Texture2d, TextureParameteri.TextureMagFilter, (int)TextureParameterValue.Linear);

            gl.UseProgram(program);

            var tex = OpenGLHelper.GetUniformLocation(gl, program, "tex");

            gl.Uniform1i(tex, 0);

            var view  = OpenGLHelper.GetUniformLocation(gl, program, "view");
            var proj  = OpenGLHelper.GetUniformLocation(gl, program, "proj");
            var model = OpenGLHelper.GetUniformLocation(gl, program, "model");

            var mat = Matrix4x4.CreateLookAt(new Vector3(1.5f, 1.5f, 1.5f), new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 1f));

            OpenGLHelper.UniformMatrix(gl, view, mat);

            mat = Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), 1.3f, 1f, 10f);
            OpenGLHelper.UniformMatrix(gl, proj, mat);

            var viewportSize = window.ViewportSize;
            var windowSize   = window.Size;

            renderingContext.CurrentWindow = null;


            bool  done     = false;
            float angle    = 0f;
            var   drawLock = new object();

            void draw()
            {
                var stopWatch = new Stopwatch();

                stopWatch.Start();
                var lastTime  = stopWatch.ElapsedMilliseconds / 1e3f;
                var deltaTime = 0.0f;

                //renderingContext.SyncWithVerticalBlank(window, false);
                renderingContext.CurrentWindow = window;
                while (!done)
                {
                    var currentTime = stopWatch.ElapsedMilliseconds / 1e3f;
                    deltaTime = currentTime - lastTime;
                    lastTime  = currentTime;

                    gl.Viewport(0, 0, (int)viewportSize.width, (int)viewportSize.height);
                    gl.UseProgram(program);
                    angle += deltaTime;
                    mat    = Matrix4x4.CreateFromAxisAngle(new Vector3(0f, 0f, 1f), angle);
                    OpenGLHelper.UniformMatrix(gl, model, mat);

                    gl.Enable(Capability.DepthTest);
                    gl.Clear(Buffers.Color | Buffers.Depth);
                    gl.BindVertexArray(vertexArray);
                    gl.BindBuffer(BufferTarget.Array, vertexBuffer);
                    gl.ActiveTexture(TextureUnit.Texture0);
                    gl.BindTexture(TextureTarget.Texture2d, texture);
                    gl.DrawArrays(DrawMode.Triangles, 0, 36);
                    gl.Disable(Capability.DepthTest);

                    renderingContext.SwapBuffers(window);
                    lock (drawLock)
                    {
                        Monitor.Wait(drawLock, 15);
                    }
                }
                renderingContext.CurrentWindow = null;
            }

            var drawThread = new Thread(draw);

            window.Closed += (sender, e) => {
                done = true;
                drawThread.Join();
                renderingContext.CurrentWindow = window;
                uint t = texture;
                gl.DeleteTextures(1, &t);
                gl.DeleteProgram(program);
                gl.DeleteShader(vertexShader);
                gl.DeleteShader(fragmentShader);
                t = vertexBuffer;
                gl.DeleteBuffers(1, &t);
                t = vertexArray;
                gl.DeleteVertexArrays(1, &t);
            };

            window.Resize += (sender, e) =>
            {
                viewportSize = window.ViewportSize;
                windowSize   = window.Size;
                lock (drawLock)
                {
                    Monitor.Pulse(drawLock);
                }
            };

            window.FramebufferResize += (sender, e) =>
            {
                viewportSize = window.ViewportSize;
                lock (drawLock)
                {
                    Monitor.Pulse(drawLock);
                }
            };

            drawThread.Start();

            window.Visible = true;
            while (windowServer.Windows.Count > 0)
            {
                windowServer.ProcessEvents(-1);
            }

            Console.WriteLine("Rotate Cube done.");
        }
Пример #5
0
        internal unsafe void Launch()
        {
            Console.WriteLine("Draw Polygon...");

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext();
            using var window           = windowServer.CreateWindow(renderingContext);

            renderingContext.CurrentWindow = window;

            var gl = new GraphicsLibrary(renderingContext);

            gl.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            Console.WriteLine("  GL VERSION: " + Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.Version))));
            Console.WriteLine("GLSL VERSION: " + Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.ShadingLanguageVersion))));
            Console.WriteLine("   GL VENDOR: " + Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.Vendor))));
            Console.WriteLine(" GL RENDERER: " + Marshal.PtrToStringAnsi(new IntPtr(gl.GetString(StringParameter.Renderer))));

            var program      = gl.CreateProgram();
            var vertexShader = OpenGLHelper.LoadShader(gl, ShaderType.Vertex, @"
                        layout(location = 0) in vec2 vPosition;
                        layout(location = 1) in vec3 vColor;
                        out vec3 fColor;
                        void main() {
                            gl_Position = vec4(vPosition, 0.0, 1.0);
                            fColor = vColor;
                        }
                    ");

            gl.AttachShader(program, vertexShader);
            var fragmentShader = OpenGLHelper.LoadShader(gl, ShaderType.Fragment, @"
                        in vec3 fColor;
                        out vec4 outColor;
                        void main() {
                            outColor = vec4(fColor, 1.0);
                        }
                    ");

            gl.AttachShader(program, fragmentShader);

            const uint position = 0u;
            const uint color    = 1u;

            OpenGLHelper.LinkProgram(gl, program);

            uint h;

            gl.GenVertexArrays(1, &h);
            uint vertexArray = h;

            gl.BindVertexArray(vertexArray);
            gl.EnableVertexAttribArray(color);
            gl.EnableVertexAttribArray(position);

            var vertices = new float[] {
                -0.5f, 0.5f,         // Top-left
                0.5f, 0.5f,          // Top-right
                0.5f, -0.5f,         // Bottom-right
                -0.5f, -0.5f,        // Bottom-left
            };

            gl.GenBuffers(1, &h);
            uint vertexBuffer1 = h;

            gl.BindBuffer(BufferTarget.Array, vertexBuffer1);
            OpenGLHelper.BufferData(gl, BufferTarget.Array, vertices, BufferUsage.StaticDraw);

            var stride = sizeof(float) * 2;

            gl.VertexAttribPointer(position, 2, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero);

            vertices = new float[] {
                1.0f, 0.0f, 0.0f,         // Top-left
                0.0f, 1.0f, 0.0f,         // Top-right
                0.0f, 0.0f, 1.0f,         // Bottom-right
                1.0f, 1.0f, 1.0f,         // Bottom-left
            };

            gl.GenBuffers(1, &h);
            uint vertexBuffer2 = h;

            gl.BindBuffer(BufferTarget.Array, vertexBuffer2);
            OpenGLHelper.BufferData(gl, BufferTarget.Array, vertices, BufferUsage.StaticDraw);

            stride = sizeof(float) * 3;
            gl.VertexAttribPointer(color, 3, AttributeElementType.Float, Boolean.False, stride, IntPtr.Zero);

            var elements = new byte[] {
                0, 1, 2,
                2, 3, 0
            };

            gl.GenBuffers(1, &h);
            uint elementBuffer = h;

            gl.BindBuffer(BufferTarget.ElementArray, elementBuffer);
            OpenGLHelper.BufferData(gl, BufferTarget.ElementArray, elements, BufferUsage.StaticDraw);

            gl.UseProgram(program);

            window.Closed += (sender, e) =>
            {
                gl.DeleteProgram(program);
                gl.DeleteShader(vertexShader);
                gl.DeleteShader(fragmentShader);
                uint t = vertexBuffer1;
                gl.DeleteBuffers(1, &t);
                t = vertexBuffer2;
                gl.DeleteBuffers(1, &t);
                t = elementBuffer;
                gl.DeleteBuffers(1, &t);
                t = vertexArray;
                gl.DeleteVertexArrays(1, &t);
            };

            window.Visible = true;
            while (windowServer.Windows.Count > 0)
            {
                gl.Clear(Buffers.Color);
                gl.DrawElements(DrawMode.Triangles, 6, DrawIndexType.UnsignedByte, IntPtr.Zero);
                renderingContext.SwapBuffers(window);

                windowServer.ProcessEvents(0.02);
            }

            Console.WriteLine("Draw Polygon done.");
        }