Opengl es 如何将这个opengl代码从xcode移植到Monotouch?
我正在尝试将以下代码转换为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
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;
}
}
}
由于您没有提供几个数据点,我只能将它们保留为空值,或者打印出值而不指定任何内容。非常感谢您,尽管您提供的示例不起作用,但它对我来说帮助很大。:) 这是我最终得到的代码(为了清晰起见,我对其进行了一些编辑): 不过我还是有一些奇怪的问题。当播放视频并将单个帧发送到上述方法时,帧以某种随机顺序绘制,使视频闪烁,尽管帧确实以正确的顺序进入该方法 基本上,程序流程如下所示:
另外,如果视频的分辨率不是二的幂,我会得到一个黑色纹理。。。使用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);
}