Convierta uintptr_t a id <MTLTexture>

Quería crear un complemento de iOS simple que pueda dibujar la textura en la unidad Texture2D. Lo he hecho por CreateExternalTexture () y UpdateExternalTexture (), está funcionando bien, pero tengo curiosidad si puedo llenar la textura Unity directamente desde el lado iOS. Aquí está mi código de complemento de iOS:

// // testTexturePlugin.m // Unity-iPhone // // Created by user on 18/01/16. // // #import <OpenGLES/ES2/gl.h> #import <OpenGLES/ES2/glext.h> #import <UIKit/UIKit.h> #include "UnityMetalSupport.h" #include <stdlib.h> #include <stdint.h> static UIImage* LoadImage() { NSString* imageName = @"logo"; //[NSString stringWithUTF8String: filename]; NSString* imagePath = [[NSBundle mainBundle] pathForResource: imageName ofType: @"png"]; return [UIImage imageWithContentsOfFile: imagePath]; } // you need to free this pointer static void* LoadDataFromImage(UIImage* image) { CGImageRef imageData = image.CGImage; unsigned imageW = CGImageGetWidth(imageData); unsigned imageH = CGImageGetHeight(imageData); // for the sake of the sample we enforce 128x128 textures //assert(imageW == 128 && imageH == 128); void* textureData = ::malloc(imageW * imageH * 4); ::memset(textureData, 0x00, imageW * imageH * 4); CGContextRef textureContext = CGBitmapContextCreate(textureData, imageW, imageH, 8, imageW * 4, CGImageGetColorSpace(imageData), kCGImageAlphaPremultipliedLast); CGContextSetBlendMode(textureContext, kCGBlendModeCopy); CGContextDrawImage(textureContext, CGRectMake(0, 0, imageW, imageH), imageData); CGContextRelease(textureContext); return textureData; } static void CreateMetalTexture(uintptr_t texRef, void* data, unsigned w, unsigned h) { #if defined(__IPHONE_8_0) && !TARGET_IPHONE_SIMULATOR NSLog(@"texRef iOS = %lu", texRef); id<MTLTexture> tex = (id<MTLTexture>)(size_t)texRef; MTLRegion r = MTLRegionMake3D(0, 0, 0, w, h, 1); [tex replaceRegion: r mipmapLevel: 0 withBytes: data bytesPerRow: w * 4]; #else #endif } extern "C" void FillUnityTexture(uintptr_t texRef) { UIImage* image = LoadImage(); void* textureData = LoadDataFromImage(image); if (UnitySelectedRenderingAPI() == apiMetal) CreateMetalTexture(texRef, textureData, image.size.width, image.size.height); ::free(textureData); } 

Y aquí está el código de Unidad:

 using UnityEngine; using System; using System.Collections; using System.Runtime.InteropServices; public class TextureHandler : MonoBehaviour { [SerializeField] private Renderer _mesh; private Texture2D _meshTexture; [DllImport("__Internal")] private static extern void FillUnityTexture(IntPtr texRef); void Start () { _meshTexture = new Texture2D(200, 200, TextureFormat.ARGB32, false); _mesh.material.SetTextureScale ("_MainTex", new Vector2 (-1, -1)); _mesh.material.mainTexture = _meshTexture; IntPtr texPtr = _meshTexture.GetNativeTexturePtr(); Debug.Log("texPtr Unity = " + texPtr); FillUnityTexture(texPtr); } } 

El puntero en la textura Unity está pasando correctamente al complemento iOS, lo comprobé. Pero tengo el locking en esta línea en el complemento de iOS:

 [tex replaceRegion: r mipmapLevel: 0 withBytes: data bytesPerRow: w * 4]; 

y estoy bastante seguro de que tengo este problema debido a la conversión incorrecta del puntero en la textura Unity (uintptr_t) a la textura metálica (id).

Entonces, mi pregunta es: ¿cómo puedo convertir correctamente el puntero a la textura de MTLTexture?

Supongo que deberías leer sobre ARC.

Puede usar __bridge_retained para transferir la propiedad del object id<MTLTexture> recién creado al código uintptr_t . Cuando desee convertir uintptr_t nuevo a id<MTLTexture> use __bridge si no desea transferir la propiedad de nuevo o usar __bridge_transfer cuando lo haga.