public virtual CVOpenGLESTexture LumaTextureForPixelBuffer(CVPixelBuffer pixelBuffer) { CVOpenGLESTexture lumaTexture = null; CVReturn err; if (VideoTextureCache == null) { Console.Error.WriteLine("No video texture cache"); return(lumaTexture); } // Periodic texture cache flush every frame VideoTextureCache.Flush(0); // CVOpenGLTextureCacheCreateTextureFromImage will create GL texture optimally from CVPixelBufferRef. // UV lumaTexture = VideoTextureCache.TextureFromImage(pixelBuffer, true, All.RedExt, pixelBuffer.Width, pixelBuffer.Height, All.RedExt, DataType.UnsignedByte, 0, out err); if (lumaTexture == null || err != CVReturn.Success) { Console.Error.WriteLine("Error at creating luma texture using CVOpenGLESTextureCacheCreateTextureFromImage: " + err.ToString()); } return(lumaTexture); }
public void DisplayPixelBuffer(CVImageBuffer imageBuffer) { // First check to make sure we have a FrameBuffer to write to. if (frameBuffer == 0) { var success = CreateFrameBuffer(); if (!success) { Console.WriteLine("Problem initializing OpenGL buffers."); return; } } if (videoTextureCache == null) { Console.WriteLine("Video Texture Cache not initialized"); return; } if (!(imageBuffer is CVPixelBuffer pixelBuffer)) { Console.WriteLine("Could not get Pixel Buffer from Image Buffer"); return; } // Create a CVOpenGLESTexture from the CVImageBuffer var frameWidth = (int)pixelBuffer.Width; var frameHeight = (int)pixelBuffer.Height; using (var texture = videoTextureCache.TextureFromImage(imageBuffer, true, All.Rgba, frameWidth, frameHeight, All.Bgra, DataType.UnsignedByte, 0, out CVReturn ret)) { if (texture == null || ret != CVReturn.Success) { Console.WriteLine("Could not create Texture from Texture Cache"); return; } GL.BindTexture(texture.Target, texture.Name); // Set texture parameters 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.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer); // Set the view port to the entire view GL.Viewport(0, 0, renderBufferWidth, renderBufferHeight); var squareVerticies = new float[, ] { { -1.0F, -1.0F }, { 1.0F, -1.0F }, { -1.0F, 1.0F }, { 1.0F, 1.0F } }; // The texture verticies are setup such that we flip the texture vertically. // This is so that our top left origin buffers match OpenGL's bottom left texture coordinate system. var textureSamplingRect = TextureSamplingRectForCroppingTextureWithAspectRatio(new CGSize(frameWidth, frameHeight), Bounds.Size); var textureVertices = new float[, ] { { (float)textureSamplingRect.Left, (float)textureSamplingRect.Bottom }, { (float)textureSamplingRect.Right, (float)textureSamplingRect.Bottom }, { (float)textureSamplingRect.Left, (float)textureSamplingRect.Top }, { (float)textureSamplingRect.Right, (float)textureSamplingRect.Top } }; // Draw the texture on the screen with OpenGL ES 2 RenderWithSquareVerticies(squareVerticies, textureVertices); GL.BindTexture(texture.Target, texture.Name); // Flush the CVOpenGLESTexture cache and release the texture videoTextureCache.Flush(CVOptionFlags.None); } }
public void DisplayPixelBuffer(CVPixelBuffer pixelBuffer) { DrawTextInCorner(pixelBuffer); CVReturn error; if (pixelBuffer != null) { int frameWidth = (int)pixelBuffer.Width; int frameHeight = (int)pixelBuffer.Height; if (videoTextureCache == null) { Console.WriteLine("No video texture cache"); return; } CleanUpTextures(); CVAttachmentMode attachmentMode; var colorAttachments = pixelBuffer.GetAttachment <NSString> (CVImageBuffer.YCbCrMatrixKey, out attachmentMode); if (colorAttachments == CVImageBuffer.YCbCrMatrix_ITU_R_601_4) { preferredConversion = colorConversion601; } else { preferredConversion = colorConversion709; } GL.ActiveTexture(TextureUnit.Texture0); lumaTexture = videoTextureCache.TextureFromImage(pixelBuffer, true, All.RedExt, frameWidth, frameHeight, All.RedExt, DataType.UnsignedByte, 0, out error); if (lumaTexture == null) { Console.WriteLine("Error at CVOpenGLESTextureCach.TextureFromImage"); } GL.BindTexture(lumaTexture.Target, lumaTexture.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); chromaTexture = videoTextureCache.TextureFromImage(pixelBuffer, true, All.RgExt, frameWidth / 2, frameHeight / 2, All.RgExt, DataType.UnsignedByte, 1, out error); if (chromaTexture == null) { Console.WriteLine("Error at CVOpenGLESTextureCach.TextureFromImage"); } GL.BindTexture(chromaTexture.Target, chromaTexture.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.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferHandle); GL.Viewport(0, 0, backingWidth, backingHeight); } GL.ClearColor(0f, 0f, 0f, 1f); GL.Clear(ClearBufferMask.ColorBufferBit); GL.UseProgram(Program); GL.Uniform1(uniforms [(int)UniformIndex.RotationAngle], 0f); GL.UniformMatrix3(uniforms [(int)UniformIndex.ColorConversionMatrix], 1, false, preferredConversion); CGRect vertexSamplingRect = AVUtilities.WithAspectRatio(Bounds, PresentationRect); var normalizedSamplingSize = new CGSize(0f, 0f); var cropScaleAmount = new CGSize(vertexSamplingRect.Width / Bounds.Width, vertexSamplingRect.Height / Bounds.Height); if (cropScaleAmount.Width > cropScaleAmount.Height) { normalizedSamplingSize.Width = 1f; normalizedSamplingSize.Height = cropScaleAmount.Height / cropScaleAmount.Width; } else { normalizedSamplingSize.Width = 1f; normalizedSamplingSize.Height = cropScaleAmount.Width / cropScaleAmount.Height; } float[] quadVertexData = { -1f * (float)normalizedSamplingSize.Width, -1f * (float)normalizedSamplingSize.Height, (float)normalizedSamplingSize.Width, -1f * (float)normalizedSamplingSize.Height, -1f * (float)normalizedSamplingSize.Width, (float)normalizedSamplingSize.Height, (float)normalizedSamplingSize.Width, (float)normalizedSamplingSize.Height, }; GL.VertexAttribPointer((int)AttributeIndex.Vertex, 2, VertexAttribPointerType.Float, false, 0, quadVertexData); GL.EnableVertexAttribArray((int)AttributeIndex.Vertex); var textureSamplingRect = new CGRect(0, 0, 1, 1); float[] quadTextureData = { (float)textureSamplingRect.GetMinX(), (float)textureSamplingRect.GetMaxY(), (float)textureSamplingRect.GetMaxX(), (float)textureSamplingRect.GetMaxY(), (float)textureSamplingRect.GetMinX(), (float)textureSamplingRect.GetMinY(), (float)textureSamplingRect.GetMaxX(), (float)textureSamplingRect.GetMinY() }; GL.VertexAttribPointer((int)AttributeIndex.TextureCoordinates, 2, VertexAttribPointerType.Float, false, 0, quadTextureData); GL.EnableVertexAttribArray((int)AttributeIndex.TextureCoordinates); GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, colorBufferHandle); context.PresentRenderBuffer((int)RenderbufferTarget.Renderbuffer); }