OpenGL for Windows forms

Hello,
I’m working on some sort of level editor on C#, so i’ve been using Tao framework to add OpenGL capability to C#, and now I want to render the OpenGL window into my windows forms,
Any help please?

Use OpenTK. It has a glcontrol control which can host gl.

I made the simple examples for you to show how to use OpenTK GLControl in WinForms, WPF and Console GameWindow projects.

You can open and run it in VS2012-VS2015. I use modern OpenGL 3.3 and .NET 2.0 for WinForms and .NET 3.0 for WPF for running apps on Windows XP.

[ul]
[li]TriangleInOpenTkWinForms.zip[/li][li]TriangleInOpenTkWPF.zip[/li][li]TriangleInOpenTkConsoleProjectGameWindow.zip[/li][li]TriangleInWebGL (the same code)[/li][/ul]

TriangleInOpenTkConsoleProjectGameWindow Project:

VertexShader.glsl


#version 330

in vec4 a_Position;

void main()
{
    gl_Position = a_Position;
}

FragmentShader.glsl


#version 330

out vec4 fragColor;

void main()
{
    fragColor = vec4(0.0, 1.0, 1.0, 1.0);
}

Program.cs


namespace TriangleInOpenTkConsoleProjectGameWindow
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var mainWindow = new MainWindow())
            {
                mainWindow.Run(30);
            }
        }
    }
}

MainWindow.cs


using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using Utils;

namespace TriangleInOpenTkConsoleProjectGameWindow
{
    class MainWindow : GameWindow
    {
        private bool canDraw = false;
        private int program;
        private int nVertices;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            Title = "Triangle";
            Width = 400;
            Height = 400;

            // Load shaders from files
            string vShaderSource = null;
            string fShaderSource = null;
            ShaderLoader.LoadShader("./Shaders/VertexShader.glsl", out vShaderSource);
            ShaderLoader.LoadShader("./Shaders/FragmentShader.glsl", out fShaderSource);
            if (vShaderSource == null || fShaderSource == null)
            {
                Logger.Append("Failed load shaders from files");
                return;
            }

            // Initialize the shaders
            if (!ShaderLoader.InitShaders(vShaderSource, fShaderSource, out program))
            {
                Logger.Append("Failed to initialize the shaders");
                return;
            }

            // Write the positions of vertices to a vertex shader
            nVertices = InitVertexBuffers();
            if (nVertices <= 0)
            {
                Logger.Append("Failed to write the positions of vertices to a vertex shader");
                return;
            }

            // Specify the color for clearing
            GL.ClearColor(Color.DarkSlateBlue);

            canDraw = true;
        }

        private int InitVertexBuffers()
        {
            float[] vertices = new float[] { 0f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f };

            // Create a buffer object
            int vertexBuffer;
            GL.GenBuffers(1, out vertexBuffer);

            // Bind the buffer object to target
            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);

            // Write data into the buffer object
            GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);

            // Get the storage location of a_Position
            int a_Position = GL.GetAttribLocation(program, "a_Position");
            if (a_Position < 0)
            {
                Logger.Append("Failed to get the storage location of a_Position");
                return -1;
            }

            // Assign the buffer object to a_Position variable
            GL.VertexAttribPointer(a_Position, 2, VertexAttribPointerType.Float, false, 0, 0);

            // Enable the assignment to a_Position variable
            GL.EnableVertexAttribArray(a_Position);

            return vertices.Length / 2;
        }

        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);

            GL.Viewport(0, 0, Width, Height);

            // Clear the render canvas with the current color
            GL.Clear(ClearBufferMask.ColorBufferBit);

            if (canDraw)
            {
                // Draw a triangle
                GL.DrawArrays(PrimitiveType.Triangles, 0, nVertices);
            }

            GL.Flush();
            SwapBuffers();
        }
    }
}

Utils.cs


using System;
using OpenTK.Graphics.OpenGL;
using System.IO;

namespace Utils
{
    public class ShaderLoader
    {
        ///<summary>
        ///Create a program object and make current
        ///</summary>
        ///<param name="vShader">a vertex shader program</param>
        ///<param name="fShader">a fragment shader program</param>
        ///<param name="program">created program</param>
        ///<returns>
        ///return true, if the program object was created and successfully made current
        ///</returns>
        public static bool InitShaders(string vShaderSource, string fShaderSource, out int program)
        {
            program = CreateProgram(vShaderSource, fShaderSource);
            if (program == 0)
            {
                Logger.Append("Failed to create program");
                return false;
            }

            GL.UseProgram(program);

            return true;
        }

        ///<summary>
        ///Load a shader from a file
        ///</summary>
        ///<param name="errorOutputFileName">a file name for error messages</param>
        ///<param name="fileName">a file name to a shader</param>
        ///<param name="shaderSource">a shader source string</param>
        public static void LoadShader(string shaderFileName, out string shaderSource)
        {
            if (File.Exists(Logger.logFileName))
            {
                // Clear File
                File.WriteAllText(Logger.logFileName, "");
            }

            shaderSource = null;

            using (StreamReader sr = new StreamReader(shaderFileName))
            {
                shaderSource = sr.ReadToEnd();
            }
        }

        private static int CreateProgram(string vShader, string fShader)
        {
            // Create shader object
            int vertexShader = LoadShader(ShaderType.VertexShader, vShader);
            int fragmentShader = LoadShader(ShaderType.FragmentShader, fShader);
            if (vertexShader == 0 || fragmentShader == 0)
            {
                return 0;
            }

            // Create a program object
            int program = GL.CreateProgram();
            if (program == 0)
            {
                return 0;
            }

            // Attach the shader objects
            GL.AttachShader(program, vertexShader);
            GL.AttachShader(program, fragmentShader);

            // Link the program object
            GL.LinkProgram(program);

            // Check the result of linking
            int status;
            GL.GetProgram(program, GetProgramParameterName.LinkStatus, out status);
            if (status == 0)
            {
                string errorString = string.Format("Failed to link program: {0}" + Environment.NewLine, GL.GetProgramInfoLog(program));
                Logger.Append(errorString);
                GL.DeleteProgram(program);
                GL.DeleteShader(vertexShader);
                GL.DeleteShader(fragmentShader);
                return 0;
            }

            return program;
        }

        private static int LoadShader(ShaderType shaderType, string shaderSource)
        {
            // Create shader object
            int shader = GL.CreateShader(shaderType);
            if (shader == 0)
            {
                Logger.Append("Unable to create shader");
                return 0;
            }

            // Set the shader program
            GL.ShaderSource(shader, shaderSource);

            // Compile the shader
            GL.CompileShader(shader);

            // Check the result of compilation
            int status;
            GL.GetShader(shader, ShaderParameter.CompileStatus, out status);
            if (status == 0)
            {
                string errorString = string.Format("Failed to compile {0} shader: {1}", shaderType.ToString(), GL.GetShaderInfoLog(shader));
                Logger.Append(errorString);
                GL.DeleteShader(shader);
                return 0;
            }

            return shader;
        }
    }

    public class Logger
    {
        public static string logFileName = "info.txt";

        /// <summary>
        /// Write a message to a log file
        /// </summary>
        /// <param name="message">a message that will append to a log file</param>
        public static void Append(string message)
        {
            File.AppendAllText(logFileName, message + Environment.NewLine);
        }
    }
}

Thank you I will try it.