コード例 #1
0
        public override void RenderPixelBuffer(CoreVideo.CVPixelBuffer destinationPixelBuffer, CoreVideo.CVPixelBuffer foregroundPixelBuffer, CoreVideo.CVPixelBuffer backgroundPixelBuffer, float tween)
        {
            EAGLContext.SetCurrentContext(CurrentContext);

            if (foregroundPixelBuffer == null && backgroundPixelBuffer == null)
            {
                return;
            }

            var foregroundLumaTexture   = LumaTextureForPixelBuffer(foregroundPixelBuffer);
            var foregroundChromaTexture = ChromaTextureForPixelBuffer(foregroundPixelBuffer);

            var backgroundLumaTexture   = LumaTextureForPixelBuffer(backgroundPixelBuffer);
            var backgroundChromaTexture = ChromaTextureForPixelBuffer(backgroundPixelBuffer);

            var destLumaTexture   = LumaTextureForPixelBuffer(destinationPixelBuffer);
            var destChromaTexture = ChromaTextureForPixelBuffer(destinationPixelBuffer);

            GL.UseProgram(ProgramY);

            // Set the render transformq
            float[] preferredRenderTransform =
            {
                (float)RenderTransform.xx, (float)RenderTransform.xy, (float)RenderTransform.x0, 0.0f,
                (float)RenderTransform.yx, (float)RenderTransform.yy, (float)RenderTransform.y0, 0.0f,
                0.0f,                                           0.0f,                      1.0f, 0.0f,
                0.0f,                                           0.0f,                      0.0f, 1.0f
            };

            GL.UniformMatrix4(Uniforms [(int)Uniform.Y], 1, false, preferredRenderTransform);

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, (int)OffscreenBufferHandle);

            GL.Viewport(0, 0, (int)destinationPixelBuffer.GetWidthOfPlane(0), (int)destinationPixelBuffer.GetHeightOfPlane(0));

            // Y planes of foreground and background frame are used to render the Y plane of the destination frame
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(foregroundLumaTexture.Target, foregroundLumaTexture.Name);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);

            GL.ActiveTexture(TextureUnit.Texture1);
            GL.BindTexture(backgroundLumaTexture.Target, backgroundLumaTexture.Name);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);

            GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0,
                                    destLumaTexture.Target, destLumaTexture.Name, 0);

            if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
            {
                Console.WriteLine("Failed to make complete frmaebuffer object: " +
                                  GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer).ToString());

                foregroundLumaTexture.Dispose();
                foregroundChromaTexture.Dispose();
                backgroundLumaTexture.Dispose();
                backgroundChromaTexture.Dispose();
                destLumaTexture.Dispose();
                destChromaTexture.Dispose();

                // Periodic texture cache flush every frame
                VideoTextureCache.Flush(CoreVideo.CVOptionFlags.None);

                EAGLContext.SetCurrentContext(null);
            }

            GL.ClearColor(0f, 0f, 0f, 1f);
            GL.Clear(ClearBufferMask.ColorBufferBit);

            float[] quadVertexData1 =
            {
                -1.0f,  1.0f,
                1.0f,   1.0f,
                -1.0f, -1.0f,
                1.0f,  -1.0f,
                1.0f,  -1.0f,
            };
            // Compute the vertex data for the foreground frame at this instructionLerp
            quadVertexCoordinates(ref quadVertexData1, ForegroundTrack, tween);

            // texture data varies from 0 -> 1, whereas vertex data varies from -1 -> 1
            float[] quadTextureData1 =
            {
                0.5f + quadVertexData1[0] / 2f, 0.5f + quadVertexData1[1] / 2f,
                0.5f + quadVertexData1[2] / 2f, 0.5f + quadVertexData1[3] / 2f,
                0.5f + quadVertexData1[4] / 2f, 0.5f + quadVertexData1[5] / 2f,
                0.5f + quadVertexData1[6] / 2f, 0.5f + quadVertexData1[7] / 2f,
                0.5f + quadVertexData1[8] / 2f, 0.5f + quadVertexData1[9] / 2f,
            };

            GL.Uniform1(Uniforms [(int)Uniform.Y], 0f);

            GL.VertexAttribPointer <float> ((int)Attrib.Vertex_Y, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1);
            GL.EnableVertexAttribArray((int)Attrib.Vertex_Y);

            GL.VertexAttribPointer <float> ((int)Attrib.TexCoord_Y, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1);
            GL.EnableVertexAttribArray((int)Attrib.TexCoord_Y);

            GL.DrawArrays(BeginMode.TriangleStrip, 0, 5);

            float[] quadVertexData2 =
            {
                (float)diagonalEnd2.X, (float)diagonalEnd2.Y,
                (float)diagonalEnd1.X, (float)diagonalEnd1.Y,
                1.0f,                                  -1.0f,
                1.0f,                                  -1.0f,
                1.0f,                                  -1.0f,
            };

            quadVertexCoordinates(ref quadVertexData2, BackgroundTrack, tween);

            float[] quadTextureData2 =
            {
                0.5f + quadVertexData2[0] / 2f, 0.5f + quadVertexData2[1] / 2f,
                0.5f + quadVertexData2[2] / 2f, 0.5f + quadVertexData2[3] / 2f,
                0.5f + quadVertexData2[4] / 2f, 0.5f + quadVertexData2[5] / 2f,
                0.5f + quadVertexData2[6] / 2f, 0.5f + quadVertexData2[7] / 2f,
                0.5f + quadVertexData2[8] / 2f, 0.5f + quadVertexData2[9] / 2f,
            };

            GL.Uniform1(Uniforms [(int)Uniform.Y], 1);

            GL.VertexAttribPointer <float> ((int)Attrib.Vertex_Y, 2, VertexAttribPointerType.Float, false, 0, quadVertexData2);
            GL.EnableVertexAttribArray((int)Attrib.Vertex_Y);

            GL.VertexAttribPointer <float> ((int)Attrib.TexCoord_Y, 2, VertexAttribPointerType.Float, false, 0, quadTextureData2);
            GL.EnableVertexAttribArray((int)Attrib.TexCoord_Y);

            // Draw the background frame
            GL.DrawArrays(BeginMode.TriangleStrip, 0, 5);

            // Perform similar operations as above for the UV plane
            GL.UseProgram(ProgramUV);

            GL.UniformMatrix4(Uniforms [(int)Uniform.Render_Transform_UV], 1, false, preferredRenderTransform);

            // UV planes of foreground and background frame are used to render the UV plane of the destination frame
            GL.ActiveTexture(TextureUnit.Texture2);
            GL.BindTexture(foregroundChromaTexture.Target, foregroundChromaTexture.Name);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);

            GL.ActiveTexture(TextureUnit.Texture3);
            GL.BindTexture(backgroundChromaTexture.Target, backgroundChromaTexture.Name);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);

            GL.Viewport(0, 0, (int)destinationPixelBuffer.GetWidthOfPlane(1), (int)destinationPixelBuffer.GetHeightOfPlane(1));

            // Attach the destination texture as a color attachment to the off screen frame buffer
            GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, destChromaTexture.Target,
                                    destChromaTexture.Name, 0);

            if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
            {
                Console.WriteLine("Failed to make complete framebuffer object: " +
                                  GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer).ToString());

                foregroundLumaTexture.Dispose();
                foregroundChromaTexture.Dispose();
                backgroundLumaTexture.Dispose();
                backgroundChromaTexture.Dispose();
                destLumaTexture.Dispose();
                destChromaTexture.Dispose();

                // Periodic texture cache flush every frame
                VideoTextureCache.Flush(CoreVideo.CVOptionFlags.None);

                EAGLContext.SetCurrentContext(null);
            }

            GL.ClearColor(0f, 0f, 0f, 1f);
            GL.Clear(ClearBufferMask.ColorBufferBit);

            GL.Uniform1(Uniforms [(int)Uniform.UV], 2);

            GL.VertexAttribPointer <float> ((int)Attrib.Vertex_UV, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1);
            GL.EnableVertexAttribArray((int)Attrib.Vertex_UV);

            GL.VertexAttribPointer <float> ((int)Attrib.TexCoord_UV, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1);
            GL.EnableVertexAttribArray((int)Attrib.TexCoord_UV);

            GL.DrawArrays(BeginMode.TriangleStrip, 0, 5);

            GL.Uniform1(Uniforms [(int)Uniform.UV], 3);

            GL.VertexAttribPointer <float> ((int)Attrib.Vertex_UV, 2, VertexAttribPointerType.Float, false, 0, quadVertexData2);
            GL.EnableVertexAttribArray((int)Attrib.Vertex_UV);

            GL.VertexAttribPointer <float> ((int)Attrib.TexCoord_UV, 2, VertexAttribPointerType.Float, false, 0, quadTextureData2);
            GL.EnableVertexAttribArray((int)Attrib.TexCoord_UV);

            GL.DrawArrays(BeginMode.TriangleStrip, 0, 5);

            GL.Flush();

            foregroundLumaTexture.Dispose();
            foregroundChromaTexture.Dispose();
            backgroundLumaTexture.Dispose();
            backgroundChromaTexture.Dispose();
            destLumaTexture.Dispose();
            destChromaTexture.Dispose();

            // Periodic texture cache flush every frame
            VideoTextureCache.Flush(CoreVideo.CVOptionFlags.None);

            EAGLContext.SetCurrentContext(null);
        }
コード例 #2
0
        public override void RenderPixelBuffer(MonoTouch.CoreVideo.CVPixelBuffer destinationPixelBuffer, MonoTouch.CoreVideo.CVPixelBuffer foregroundPixelBuffer, MonoTouch.CoreVideo.CVPixelBuffer backgroundPixelBuffer, float tween)
        {
            EAGLContext.SetCurrentContext(CurrentContext);
            if (foregroundPixelBuffer != null || backgroundPixelBuffer != null)
            {
                CVOpenGLESTexture foregroundLumaTexture   = LumaTextureForPixelBuffer(foregroundPixelBuffer);
                CVOpenGLESTexture foregroundChromaTexture = ChromaTextureForPixelBuffer(foregroundPixelBuffer);

                CVOpenGLESTexture backgroundLumaTexture   = LumaTextureForPixelBuffer(backgroundPixelBuffer);
                CVOpenGLESTexture backgroundChromaTexture = ChromaTextureForPixelBuffer(backgroundPixelBuffer);

                CVOpenGLESTexture destLumaTexture   = LumaTextureForPixelBuffer(destinationPixelBuffer);
                CVOpenGLESTexture destChromaTexture = ChromaTextureForPixelBuffer(destinationPixelBuffer);

                GL.UseProgram(ProgramY);

                // Set the render transform
                float[] preferredRenderTransform =
                {
                    RenderTransform.xx, RenderTransform.xy, RenderTransform.x0, 0.0f,
                    RenderTransform.yx, RenderTransform.yy, RenderTransform.y0, 0.0f,
                    0.0f,                             0.0f,               1.0f, 0.0f,
                    0.0f,                             0.0f,               0.0f, 1.0f,
                };


                GL.UniformMatrix4(Uniforms [(int)Uniform.Render_Transform_Y], 1, false, preferredRenderTransform);

                GL.BindFramebuffer(FramebufferTarget.Framebuffer, OffscreenBufferHandle);
                GL.Viewport(0, 0, destinationPixelBuffer.Width, destinationPixelBuffer.Height);

                GL.ActiveTexture(TextureUnit.Texture0);
                GL.BindTexture(foregroundLumaTexture.Target, foregroundLumaTexture.Name);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);

                GL.ActiveTexture(TextureUnit.Texture1);
                GL.BindTexture(backgroundLumaTexture.Target, backgroundLumaTexture.Name);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);

                // Attach the destination texture as a color attachment to the off screen frame buffer
                GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, destLumaTexture.Target, destLumaTexture.Name, 0);

                if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
                {
                    Console.Error.WriteLine("Failed to make complete framebuffer object " + GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer));
                    foregroundLumaTexture.Dispose();
                    foregroundChromaTexture.Dispose();
                    backgroundLumaTexture.Dispose();
                    backgroundChromaTexture.Dispose();
                    destLumaTexture.Dispose();
                    destChromaTexture.Dispose();
                    VideoTextureCache.Flush(0);
                    EAGLContext.SetCurrentContext(null);
                    return;
                }

                GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                GL.Clear(ClearBufferMask.ColorBufferBit);

                float[] quadVertexData1 =
                {
                    -1.0f,  1.0f,
                    1.0f,   1.0f,
                    -1.0f, -1.0f,
                    1.0f,  -1.0f,
                };
                // texture data varies from 0 -> 1, whereas vertex data varies from -1 -> 1
                float[] quadTextureData1 =
                {
                    0.5f + quadVertexData1 [0] / 2, 0.5f + quadVertexData1 [1] / 2,
                    0.5f + quadVertexData1 [2] / 2, 0.5f + quadVertexData1 [3] / 2,
                    0.5f + quadVertexData1 [4] / 2, 0.5f + quadVertexData1 [5] / 2,
                    0.5f + quadVertexData1 [6] / 2, 0.5f + quadVertexData1 [7] / 2,
                };

                GL.Uniform1(Uniforms [(int)Uniform.Y], 0);

                GL.VertexAttribPointer((int)Attrib.Vertex_Y, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1);
                GL.EnableVertexAttribArray((int)Attrib.Vertex_Y);

                GL.VertexAttribPointer((int)Attrib.TexCoord_Y, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1);
                GL.EnableVertexAttribArray((int)Attrib.TexCoord_Y);

                // Blend function to draw the foreground frame
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero);

                // Draw the foreground frame
                GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);

                GL.Uniform1(Uniforms [(int)Uniform.Y], 1);

                GL.VertexAttribPointer((int)Attrib.Vertex_Y, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1);
                GL.EnableVertexAttribArray((int)Attrib.Vertex_Y);

                GL.VertexAttribPointer((int)Attrib.TexCoord_Y, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1);
                GL.EnableVertexAttribArray((int)Attrib.TexCoord_Y);

                // Blend function to draw the background frame
                GL.BlendColor(0, 0, 0, tween);
                GL.BlendFunc(BlendingFactorSrc.ConstantAlpha, BlendingFactorDest.OneMinusConstantAlpha);

                // Draw the background frame
                GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);

                // Perform similar operations as above for the UV plane
                GL.UseProgram(ProgramUV);

                GL.UniformMatrix4(Uniforms [(int)Uniform.Render_Transform_UV], 1, false, preferredRenderTransform);

                GL.ActiveTexture(TextureUnit.Texture2);
                GL.BindTexture(foregroundChromaTexture.Target, foregroundChromaTexture.Name);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);

                GL.ActiveTexture(TextureUnit.Texture3);
                GL.BindTexture(backgroundChromaTexture.Target, backgroundChromaTexture.Name);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge);

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

                // Attach the destination texture as a color attachment to the off screen frame buffer
                GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, destChromaTexture.Target, destChromaTexture.Name, 0);

                if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
                {
                    Console.Error.WriteLine("Failed to make complete framebuffer object " + GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer));
                    foregroundLumaTexture.Dispose();
                    foregroundChromaTexture.Dispose();
                    backgroundLumaTexture.Dispose();
                    backgroundChromaTexture.Dispose();
                    destLumaTexture.Dispose();
                    destChromaTexture.Dispose();
                    this.VideoTextureCache.Flush(0);
                    EAGLContext.SetCurrentContext(null);
                    return;
                }

                GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                GL.Clear(ClearBufferMask.ColorBufferBit);

                GL.Uniform1(Uniforms [(int)Uniform.UV], 2);

                GL.VertexAttribPointer((int)Attrib.Vertex_UV, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1);
                GL.EnableVertexAttribArray((int)Attrib.Vertex_UV);

                GL.VertexAttribPointer((int)Attrib.TexCoord_UV, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1);
                GL.EnableVertexAttribArray((int)Attrib.TexCoord_UV);

                // Blend function to draw the foreground frame
                GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero);

                // Draw the foreground frame
                GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);

                GL.Uniform1(Uniforms [(int)Uniform.UV], 3);

                GL.VertexAttribPointer((int)Attrib.Vertex_UV, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1);
                GL.EnableVertexAttribArray((int)Attrib.Vertex_UV);

                GL.VertexAttribPointer((int)Attrib.TexCoord_UV, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1);
                GL.EnableVertexAttribArray((int)Attrib.TexCoord_UV);

                // Blend function to draw the background frame
                GL.BlendColor(0, 0, 0, tween);
                GL.BlendFunc(BlendingFactorSrc.ConstantAlpha, BlendingFactorDest.OneMinusConstantAlpha);

                // Draw the background frame
                GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);

                GL.Flush();

                foregroundLumaTexture.Dispose();
                foregroundChromaTexture.Dispose();
                backgroundLumaTexture.Dispose();
                backgroundChromaTexture.Dispose();
                destLumaTexture.Dispose();
                destChromaTexture.Dispose();
                this.VideoTextureCache.Flush(0);
                EAGLContext.SetCurrentContext(null);
            }
        }