/// <summary> /// Create the texture object for the native texture wrapped by the valid descriptor. /// </summary> /// <param name="descriptor">The texture descriptor wrapping a native texture object.</param> /// <returns> /// If the descriptor is valid, the <c>Texture</c> object created from the texture descriptor. Otherwise, /// <c>null</c>. /// </returns> static Texture CreateTexture(XRTextureDescriptor descriptor) { if (!descriptor.valid) { return(null); } switch (descriptor.dimension) { #if UNITY_2020_2_OR_NEWER case TextureDimension.Tex3D: return(Texture3D.CreateExternalTexture(descriptor.width, descriptor.height, descriptor.depth, descriptor.format, (descriptor.mipmapCount != 0), descriptor.nativeTexture)); #endif case TextureDimension.Tex2D: var texture = Texture2D.CreateExternalTexture(descriptor.width, descriptor.height, descriptor.format, (descriptor.mipmapCount != 0), k_TextureHasLinearColorSpace, descriptor.nativeTexture); // NB: SetWrapMode needs to be the first call here, and the value passed // needs to be kTexWrapClamp - this is due to limitations of what // wrap modes are allowed for external textures in OpenGL (which are // used for ARCore), as Texture::ApplySettings will eventually hit // an assert about an invalid enum (see calls to glTexParameteri // towards the top of ApiGLES::TextureSampler) // reference: "3.7.14 External Textures" section of // https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt // (it shouldn't ever matter what the wrap mode is set to normally, since // this is for a pass-through video texture, so we shouldn't ever need to // worry about the wrap mode as textures should never "wrap") texture.wrapMode = TextureWrapMode.Clamp; texture.filterMode = FilterMode.Bilinear; texture.hideFlags = HideFlags.HideAndDontSave; return(texture); case TextureDimension.Cube: return(Cubemap.CreateExternalTexture(descriptor.width, descriptor.format, (descriptor.mipmapCount != 0), descriptor.nativeTexture)); default: return(null); } }