Opengl es 如何将这个opengl代码从xcode移植到Monotouch?

Opengl es 如何将这个opengl代码从xcode移植到Monotouch?,opengl-es,xamarin.ios,Opengl Es,Xamarin.ios,我正在尝试将以下代码转换为Monotouch: if (videoTextureCache == NULL) { // Create a new CVOpenGLESTexture cache CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, self.context, NULL, &videoTextureCache); if (err) { NSLog

我正在尝试将以下代码转换为Monotouch:

if (videoTextureCache == NULL) {
    //  Create a new CVOpenGLESTexture cache
    CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, self.context, NULL, &videoTextureCache);
    if (err) {
        NSLog(@"Error at CVOpenGLESTextureCacheCreate %d", err);
    }
}

if (videoTextureCache) {
    CMSampleBufferRef sampleBuffer = self.videoFrameReader.sampleBuffer;
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer, 0);

    // Create a CVOpenGLESTexture from the CVImageBuffer
    size_t frameWidth = CVPixelBufferGetWidth(imageBuffer);
    size_t frameHeight = CVPixelBufferGetHeight(imageBuffer);
    CVOpenGLESTextureRef texture = NULL;
    CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
                                                                videoTextureCache,
                                                                imageBuffer,
                                                                NULL,
                                                                GL_TEXTURE_2D,
                                                                GL_RGBA,
                                                                frameWidth,
                                                                frameHeight,
                                                                GL_BGRA,
                                                                GL_UNSIGNED_BYTE,
                                                                0,
                                                                &texture);
    if (!texture || err) {
        NSLog(@"CVOpenGLESTextureCacheCreateTextureFromImage failed (error: %d)", err);
        return;
    } else {
        self.cubeTextureName = CVOpenGLESTextureGetName(texture);
    }

    // Flush the CVOpenGLESTexture cache and release the texture
    CVOpenGLESTextureCacheFlush(videoTextureCache, 0);
    CFRelease(texture);

    CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
它与快速将视频渲染成opengl纹理有关。它在xCode中工作得很好,性能非常好,但现在我需要让它在Monotouch相关的项目中工作

但是,我完全不知道如何移植这段代码,因为我找不到必要的Monotouch绑定,也找不到关于上面使用的关键方法的Monotouch相关文档,如CVOpenGLESTextureCacheCreateTextureFromImage和CVOpenGLESTextureCacheCreate。Monotouch是否缺少这些功能


有什么方法可以调用它们吗?

我对OpenGL不是很熟悉,所以我可能弄错了示例,但这里是一个起点:

using System;
using System.Collections.Generic;
using System.Linq;

using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.CoreVideo;
using MonoTouch.CoreMedia;
using System.Runtime.InteropServices;
using MonoTouch.OpenGLES;
using OpenTK.Platform.iPhoneOS;
using OpenTK.Graphics.ES20;
using OpenTK;

namespace cv1
{
    [Register ("AppDelegate")]
    public partial class AppDelegate : UIApplicationDelegate
    {
        UIWindow window;

        [DllImport (MonoTouch.Constants.CoreVideoLibrary)]
        extern static int CVOpenGLESTextureCacheCreate (IntPtr alloc, IntPtr cache, IntPtr eaglContext, IntPtr textureAttr, out IntPtr cache);

        [DllImport (MonoTouch.Constants.CoreVideoLibrary)]
        extern static int CVOpenGLESTextureCacheCreateTextureFromImage (IntPtr alloc, IntPtr textureCache, IntPtr sourceImage, IntPtr textureAttr, EnableCap target, PixelFormat internalFormat, int width, int height, int format, DataType type, int planeIndex, out IntPtr texture);
        [DllImport (MonoTouch.Constants.CoreVideoLibrary)]
        extern static int CVOpenGLESTextureCacheFlush (IntPtr texture, int v);
        [DllImport (MonoTouch.Constants.CoreVideoLibrary)]
        extern static int CVOpenGLESTextureGetName (IntPtr texture);
        [DllImport (MonoTouch.Constants.CoreFoundationLibrary, CharSet=CharSet.Unicode)]
        internal extern static IntPtr CFRelease (IntPtr obj);

        IntPtr videoTextureCache;

        void Stuff (EAGLContext context)
        {
            int err;
            if (videoTextureCache == IntPtr.Zero) {
                err = CVOpenGLESTextureCacheCreate (IntPtr.Zero, IntPtr.Zero, context.Handle, IntPtr.Zero, out videoTextureCache);
                if (err != 0){
                    Console.WriteLine ("Error at CVOpenGLESTextureCacheCreate {0}", err);
                    return;
                }
            }
            CMSampleBuffer sampleBuffer = null; //videoFrameReader.SampleBuffer;
            CVPixelBuffer imageBuffer = (CVPixelBuffer) sampleBuffer.GetImageBuffer ();
            imageBuffer.Lock (CVOptionFlags.None);
            int frameWidth = imageBuffer.Width;
            int frameHeight = imageBuffer.Height;

            IntPtr texture = IntPtr.Zero;
            err = CVOpenGLESTextureCacheCreateTextureFromImage(IntPtr.Zero,
                                                                videoTextureCache,
                                                                imageBuffer.Handle,
                                                                IntPtr.Zero,
                                                                EnableCap.Texture2D,
                                                                PixelFormat.Rgba,
                                                                frameWidth,
                                                                frameHeight,
                                                                0x10B6,
                                                                DataType.UnsignedByte,
                                                                0,
                                                                out texture);
            if (texture == IntPtr.Zero || err != 0) {
                Console.WriteLine("CVOpenGLESTextureCacheCreateTextureFromImage failed (error: {0})", err);
                return;
            } else {
                Console.WriteLine ("Texture name: {0}", CVOpenGLESTextureGetName(texture));
            }

            CVOpenGLESTextureCacheFlush(videoTextureCache, 0);
            CFRelease(texture);

            imageBuffer.Unlock (CVOptionFlags.None);
        }

        public override bool FinishedLaunching (UIApplication app, NSDictionary options)
        {
            window = new UIWindow (UIScreen.MainScreen.Bounds);
            window.MakeKeyAndVisible ();


            return true;
        }
    }
}

由于您没有提供几个数据点,我只能将它们保留为空值,或者打印出值而不指定任何内容。

非常感谢您,尽管您提供的示例不起作用,但它对我来说帮助很大。:)

这是我最终得到的代码(为了清晰起见,我对其进行了一些编辑):

不过我还是有一些奇怪的问题。当播放视频并将单个帧发送到上述方法时,帧以某种随机顺序绘制,使视频闪烁,尽管帧确实以正确的顺序进入该方法

基本上,程序流程如下所示:

  • 提取视频帧(我知道它们的顺序确实正确)
  • 将帧馈送到上述方法,并创建纹理
  • 绘制纹理(实际绘制当前帧的+/-5帧)
  • 非常简单,但Monotouch似乎没有很好地发挥作用

    这是很奇怪的,因为上面的代码是xCode版本的精确副本,可以正常工作。不确定发生了什么,但我怀疑这与Monotouch中的自动内存管理有关


    另外,如果视频的分辨率不是二的幂,我会得到一个黑色纹理。。。使用Objective C时没有问题。同样,不确定Monotouch在这里发生了什么…:(

    这回答了一个不相关的问题,即如何绑定size\u t(如我所怀疑的,为int),因此,谢谢!)
        [DllImport (MonoTouch.Constants.CoreVideoLibrary)]
        extern static int CVOpenGLESTextureCacheCreateTextureFromImage (
            IntPtr allocator,
            IntPtr textureCache,
            IntPtr sourceImage,
            IntPtr textureAttributes,
            int target,
            int internalFormat,
            int width,
            int height,
            int format,
            int type,
            int planeIndex,
            ref IntPtr textureOut);
    
    [DllImport (MonoTouch.Constants.CoreVideoLibrary)]
    extern static int CVOpenGLESTextureCacheFlush (IntPtr texture, int v);
    
    [DllImport (MonoTouch.Constants.CoreVideoLibrary)]
    extern static int CVOpenGLESTextureGetName (IntPtr texture);
    
    [DllImport (MonoTouch.Constants.CoreFoundationLibrary, CharSet=CharSet.Unicode)]
    internal extern static IntPtr CFRelease (IntPtr obj);
    
        private IntPtr videoTextureCache;
        unsafe public void setTexture(CVImageBuffer sampleBuffer)
        {
            int err;
        if (videoTextureCache == IntPtr.Zero) {
                EAGLContext eaglContext=Global.localScreen.view.Context;
            err = CVOpenGLESTextureCacheCreate (IntPtr.Zero, IntPtr.Zero, eaglContext.Handle, IntPtr.Zero, out videoTextureCache);
            if (err != 0){
                Console.WriteLine ("Error at CVOpenGLESTextureCacheCreate {0}", err);
                return;
            }
        }
    
            CVPixelBuffer pixelBuffer = (CVPixelBuffer) sampleBuffer;
        pixelBuffer.Lock (CVOptionFlags.None);
        int frameWidth = pixelBuffer.Width;
        int frameHeight = pixelBuffer.Height;
    
            IntPtr texture = IntPtr.Zero;
            err = CVOpenGLESTextureCacheCreateTextureFromImage(IntPtr.Zero,
                                                            videoTextureCache,
                                                            pixelBuffer.Handle,
                                                            IntPtr.Zero,
                                                            (int)All.Texture2D,
                                                            (int)All.Rgba,
                                                            frameWidth,
                                                            frameHeight,
                                                            (int)All.Bgra,
                                                            (int)All.UnsignedByte,
                                                            0,
                                                            ref texture);
    
        if (texture == IntPtr.Zero || err != 0) {
            Console.WriteLine("CVOpenGLESTextureCacheCreateTextureFromImage failed (error: {0})", err);
            return;
        } else {
            Console.WriteLine ("Texture name: {0}", CVOpenGLESTextureGetName(texture));
        }
    
        CVOpenGLESTextureCacheFlush(videoTextureCache, 0);
            CFRelease(texture);
    
            pixelBuffer.Unlock (CVOptionFlags.None);            
    
        }