Передать видеокадры с веб-камеры в opentk - c # opengl - PullRequest
0 голосов
/ 03 октября 2018

Я использую VideoCaptureDeviceForm из Aforge для отображения видео с веб-камеры в моем приложении.Он может захватывать каждый кадр, когда веб-камера включена.И у меня есть openglcontrol opentk, который передает файл изображения в opengl и меняет цвет изображения с черной областью на красный.Теперь я хочу объединить обе эти функции.Значит, когда моя веб-камера начинает играть, я хочу передать эти кадры в opengl и должен показать эти кадры в openglcontrol.Короче говоря, glcontrol должен показывать видео с веб-камеры с кодом шейдера, который я применил.

Как мне этого добиться?Мой код:

using System.Windows.Forms;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Drawing.Imaging;
using AForge.Video.DirectShow;
using AForge.Video;

namespace DemoWebCam1
{
public partial class Form2 : Form
{
    Bitmap FrameData;
    bool loaded = false;
    string file = "content/penguine.png";
    int program;
    int vertShader;
    int fragShader;
    int buffer;
    int positionLocation;
    int texture;
    float[] vertices = {
            // Left bottom triangle
            -1f, -1f, 0f,
            1f, -1f, 0f,
            1f, 1f, 0f,
            // Right top triangle
            1f, 1f, 0f,
              -1f, 1f, 0f,
             -1f, -1f, 0f
    };

    public Form2()
    {
        InitializeComponent();
    }

     private void glControl1_Load(object sender, EventArgs e)
     {
        loaded = true;
        Init();
    }
   private void Form2_Load(object sender, EventArgs e)
    {
        VideoCaptureDeviceForm form = new VideoCaptureDeviceForm();

        if (form.ShowDialog(this) == DialogResult.OK)
        {
            // create video source
            VideoCaptureDevice videoSource = form.VideoDevice;
           // glControl1_Resize(sender, e);
            // open it
            OpenVideoSource(videoSource);
        }
       }
      private void glControl1_Paint(object sender, PaintEventArgs e)
    {

        if (!loaded)
            return;
        DrawImage(texture);

    }

    private void OpenVideoSource(IVideoSource source)
    {
        // set busy cursor
        this.Cursor = Cursors.WaitCursor;

        // stop current video source
        CloseCurrentVideoSource();

        // start new video source
        videoSourcePlayer.VideoSource = source;
        videoSourcePlayer.Start();
        this.Cursor = Cursors.Default;
        source.NewFrame += new AForge.Video.NewFrameEventHandler(Video_NewFrame);
    }

    private void Video_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
    {
       FrameData = new Bitmap(eventArgs.Frame);
        //Add to PictureBox
        pictureBox1.Image = FrameData;
   //need to pass this framedata to opengl texture
    }


    private void Init()
    {
        texture = LoadTexture(file);
        CreateShaders();
        CreateProgram();
        InitBuffers();
    }
    private void CreateProgram()
    {
        program = GL.CreateProgram();
        GL.AttachShader(program, vertShader);
        GL.AttachShader(program, fragShader);
        GL.LinkProgram(program);
    }

    private void CreateShaders()
    {
        /***********Vert Shader********************/
        vertShader = GL.CreateShader(ShaderType.VertexShader);
        GL.ShaderSource(vertShader, @"attribute vec3 a_position;
                                    varying vec2 vTexCoord;
                                    void main() {
                                    vTexCoord = (a_position.xy + 1) / 2;
                                    gl_Position = vec4(a_position, 1);
                                    }");
        GL.CompileShader(vertShader);


        /***********Frag Shader ****************/
        fragShader = GL.CreateShader(ShaderType.FragmentShader);
        GL.ShaderSource(fragShader, @"precision highp float;
    uniform sampler2D sTexture;
                                   varying vec2 vTexCoord;
                             void main ()
                             {
                                 vec4    color   = texture2D (sTexture, vTexCoord);
                                if(color.r < 0.3){color.r = 1.0;}
                              //  Save the result
                                 gl_FragColor    = color;
                             }");
        GL.CompileShader(fragShader);
    }
    private void InitBuffers()
    {
        buffer = GL.GenBuffer();
        positionLocation = GL.GetAttribLocation(program, "a_position");
        GL.EnableVertexAttribArray(positionLocation);
        GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StaticDraw);
        GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 0, 0);
    }

    public int LoadTexture(string file)
    {
        Bitmap bitmap = new Bitmap(file);//instead of file, need to pass FrameData here

        int tex;
        GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);

        GL.GenTextures(1, out tex);
        GL.BindTexture(TextureTarget.Texture2D, tex);
        FrameData.RotateFlip(RotateFlipType.RotateNoneFlipY);
        BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
       ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
        OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
        bitmap.UnlockBits(data);


        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);

        return tex;
    }
    public void DrawImage(int image)
    {

        GL.Viewport(new Rectangle(0, 0, 1920, 1080));
        GL.MatrixMode(MatrixMode.Projection);
        GL.PushMatrix();
        GL.LoadIdentity();


        //GL.Ortho(0, 1920, 0, 1080, 0, 1);

        GL.MatrixMode(MatrixMode.Modelview);
        GL.PushMatrix();
        GL.LoadIdentity();

        GL.Disable(EnableCap.Lighting);

        GL.Enable(EnableCap.Texture2D);

        GL.ActiveTexture(TextureUnit.Texture0);
        GL.BindTexture(TextureTarget.Texture2D, image);

        RunShaders();

        GL.Disable(EnableCap.Texture2D);
        GL.PopMatrix();

        GL.MatrixMode(MatrixMode.Projection);
        GL.PopMatrix();

        GL.MatrixMode(MatrixMode.Modelview);

        ErrorCode ec = GL.GetError();
        if (ec != 0)
            System.Console.WriteLine(ec.ToString());
        Console.Read();
        glControl1.SwapBuffers();
    }
    private void RunShaders()
    {
        GL.ClearColor(Color.Yellow);
        GL.UseProgram(program);
        GL.DrawArrays(PrimitiveType.Triangles, 0, vertices.Length / 3);

        ErrorCode ec = GL.GetError();
        if (ec != 0)
            System.Console.WriteLine(ec.ToString());
        Console.Read();
    }

    private void Form2_FormClosed(object sender, FormClosedEventArgs e)
    {
        CloseCurrentVideoSource();
    }

}

}

...