# sharecamera

## 简单介绍

SharedCamera 是一种在 Unity 中利用 Android 共享纹理实现高效视频流处理的技术。它通过创建共享的 EGL 上下文和 OpenGL 纹理，让 Android 原生代码直接更新纹理数据，Unity 则通过 `Texture2D.CreateExternalTexture` 引用该纹理进行渲染。这种方式避免了 GPU 和 CPU 之间的数据拷贝，显著提升了性能和渲染效率，同时减少了内存占用，特别适合实时处理视频流的场景，如 AR 应用等。

在使用6dof能力的同时，若还需要获取camera图像，则必须使用

## API介绍

<table data-header-hidden><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td>调用方法</td><td>使用说明</td><td>示例代码</td></tr><tr><td>打开相机ShareCamera.OpenCamera(XRCameraType cameraType, XRResolution resolution, RawImage img = null, int frameRate = 30)<br></td><td><strong>参数与返回值细节：</strong>/// &#x3C;param name="cameraTpye">Camera 相机类型&#x3C;/param>/// &#x3C;param name="resolution">Camera一些设置（分辨率）例如 XRResolution(640,480);&#x3C;/param>/// &#x3C;param name="img">显示的UI&#x3C;/param>/// &#x3C;param name="frameRate">获取图片帧率&#x3C;/param>/// &#x3C;returns>XRCameraHandler &#x3C;/returns><br><strong>异常场景说明：异常的时候，检查相机权限是否申请</strong><br><strong>调用时机建议：使用相机前，建议现申请权限</strong></td><td><pre class="language-c#"><code class="lang-c#">m_CameraHandler = ShareCamera.OpenCamera(m_CurXRCameraType, m_RI);
</code></pre><p><br></p></td></tr><tr><td>获取支持分辨率列表ShareCamera.getSupportResolutions(XRCameraType cameraTpye)</td><td><strong>参数与返回值细节：</strong>获取对应 Camera 类型支持的 分辨率/// &#x3C;param name="cameraTpye">Camera 类型&#x3C;/param>/// &#x3C;returns>XRResolution[] 分辨率 数组&#x3C;/returns><br><strong>异常场景说明：暂无</strong><br><strong>调用时机建议：不清楚所支持的相机分辨率的时候，可以在运行场景时，获取查看</strong></td><td><pre class="language-c#"><code class="lang-c#"> XRResolution[] rlt = ShareCamera.getSupportResolutions(cameraTpye);
</code></pre></td></tr><tr><td>关闭cameraShareCamera.CloseCamera(XRCameraHandler info)</td><td><strong>参数与返回值细节：</strong>/// &#x3C;param name="info">之前打开的 XRCameraHandler &#x3C;/param>/// &#x3C;returns>bool 是否关闭成功&#x3C;/returns><br><strong>异常场景说明：XRCameraHandler 传入的参数是否为空</strong><br><strong>调用时机建议：不需要获取相机功能的时候，请及时关闭</strong></td><td><pre class="language-c#"><code class="lang-c#">if(m_CameraHandler!=null) ShareCamera.CloseCamera(m_CameraHandler);
</code></pre><p><br></p></td></tr><tr><td>照片旋转XRImageUtils.rotate(XRImageFormat format, Texture2D src, Texture2D dst, XRRotateMode degree)<br></td><td><strong>参数与返回值细节：</strong>/// &#x3C;param name="format">图片的格式 XRImageFormat &#x3C;/param>/// &#x3C;param name="src">源图片 Texture2D &#x3C;/param>/// &#x3C;param name="dst">目标图片 Texture2D &#x3C;/param>/// &#x3C;param name="degree">选择角度 XRRotateMode &#x3C;/param>/// &#x3C;returns>int &#x3C;/returns><br><strong>异常场景说明：注意图片源数据不为空</strong><br><strong>调用时机建议：在需要旋转处理的时候进行图片旋转</strong></td><td><pre class="language-c#"><code class="lang-c#">Texture2D rotT2d = new Texture2D(t2d.height, t2d.width, TextureFormat.BGRA32, false);
XRImageUtils.rotate(XRImageFormat.kImageMemoryRGBA, t2d, rotT2d, XRRotateMode.kDegree270);
Debug.Log(TAG + "TextureHandle()  rotate,size:" + t2d.width + ":" + t2d.height);
</code></pre><p><br></p></td></tr><tr><td>照片镜像XRImageUtils.mirror(XRImageFormat format, Texture2D src, Texture2D dst)</td><td><strong>参数与返回值细节：</strong>/// &#x3C;param name="format">图片的格式 XRImageFormat &#x3C;/param>/// &#x3C;param name="src">源图片 Texture2D &#x3C;/param>/// &#x3C;param name="dst">目标图片 Texture2D &#x3C;/param>/// &#x3C;returns>int &#x3C;/returns><br><strong>异常场景说明：注意图片源数据不为空</strong><br><strong>调用时机建议：在需要镜像处理的时候进行图片镜像</strong></td><td><pre class="language-c#"><code class="lang-c#">Texture2D mirrorT2d = new Texture2D(rotT2d.width, rotT2d.height, TextureFormat.BGRA32, false);
XRImageUtils.mirror(XRImageFormat.kImageMemoryRGBA, rotT2d, mirrorT2d);
Debug.Log(TAG + "TextureHandle() mirror");
</code></pre><p><br></p></td></tr></tbody></table>

以下是X3pro相机的分辨率枚举示例，实际使用最好根据接口获取最新的支持分辨率

{% columns %}
{% column %}
【示例】x3pro RGB相机支持的分辨率

width=4032, height=3024

width=4000, height=3000

width=3840, height=2160

width=3264, height=2448

width=3200, height=2400

width=2432, height=1824

width=1728, height=2304

width=2432, height=1368

width=2400, height=1344

width=1344, height=2400

width=2048, height=1536

width=1472, height=1920

width=1920, height=1440

width=2176, height=1224

width=1920, height=1080

width=1600, height=1200

width=1440, height=1080

width=1280, height=960

width=1280, height=720

width=720, height=1280

width=1024, height=768

width=960, height=720

width=1280, height=480

width=800, height=600

width=648, height=648

width=800, height=480

width=720, height=480

width=640, height=480

width=640, height=400

width=640, height=360

width=480, height=360

width=352, height=288

width=320, height=240

width=176, height=144
{% endcolumn %}

{% column %}
【示例】X3pro VGA相机支持的分辨率

width=640, height=480

width=640, height=400

width=640, height=360

width=480, height=360

width=352, height=288

width=320, height=240

width=176, height=144
{% endcolumn %}
{% endcolumns %}

<br>

## 构建场景

搭建好基础环境，并且根据需要导入 Sample 功能能力 Demo 。

<figure><img src="/files/AlSC94H6JAV1LhD9H54R" alt=""><figcaption></figcaption></figure>

### 1. 新建场景

新建Unity3D 工程，取名 SharedCamera

<figure><img src="/files/MAfYK2nQ7F8lYDyLhtak" alt=""><figcaption></figcaption></figure>

### 2. 替换 MainCamera 为 XR Plugin

打开场景，删除默认的MainCamera

<figure><img src="/files/3uDnDFBwCJUQ1uTOdSwe" alt=""><figcaption></figcaption></figure>

在 packages 目录下找到 RayNeo OPenXR ARDK - SDK - Runtime - Resources - Prefab 文件夹下 的 XR Plugin 预制体

<figure><img src="/files/jpxKQ2uiHd8AWtzBbQoh" alt=""><figcaption></figcaption></figure>

把 XR Plugin 预制体 拖到场景中

<figure><img src="/files/rFVRnDnvsCjYETzmaAg5" alt=""><figcaption></figcaption></figure>

### 3. 在场景中添加资源

鼠标右键，在场景中添加一个 Canvas

<figure><img src="/files/vIztS1HSTIqrR9Og6mnT" alt=""><figcaption></figcaption></figure>

替换 Canvas 上的 GraphicRaycaster 为 XRGraphicRaycaster，移除 Canvas 上的 GraphicRaycaster

<figure><img src="/files/FhfcnTKrdPVEP7jlFb1l" alt=""><figcaption></figcaption></figure>

在 Canvas 上，添加 XRGraphicRaycaster

<figure><img src="/files/FH6qhRqsMokgdMNAoLSh" alt=""><figcaption></figcaption></figure>

在 Canvas 下添加 RawImage

<figure><img src="/files/vATKl0p2g0AqY8HZRXq6" alt=""><figcaption></figcaption></figure>

### 4. 实现 SharedCamera 功能的设置

设置 Canvas 的 RenderMode 为 WorldSpace, EventCamera 设置为 XRPlugin下的 Head 上的 Camera

<figure><img src="/files/UrBV8ahbETw1uqdjAeoz" alt=""><figcaption></figcaption></figure>

在 Canvas 下的 RawImage 下添加组件 ShareCameraCtrl

<figure><img src="/files/ffVtho3LFdzUgjBSQhkh" alt=""><figcaption></figcaption></figure>

ShareCameraCtrl 脚本 RI 赋值 当前的RawImage

<figure><img src="/files/Z6PA5dhWcfOtimz1ZDmo" alt=""><figcaption></figcaption></figure>

### 5. 添加双击 TP 操控板退出应用功能

在 Scripts 文件夹（没有自行创建即可）下，创建一个 QuitApp 脚本

<figure><img src="/files/b5wkN0rUOO59DanbVDEX" alt=""><figcaption></figcaption></figure>

双击脚本，打开编辑器，编写双击 TP 退出代码

```c#
using RayNeo;
using UnityEngine;

public class QuitApp : MonoBehaviour
{
    /// <summary>
    /// 退出应用
    /// </summary>
    public void ToQuitApp()
    {
        Application.Quit();
    }

    void Start()
    {
        // 添加双击事件
        SimpleTouchForLite.Instance.OnDoubleTap.AddListener(ToQuitApp);
    }

    private void OnDestroy()
    {
        if (SimpleTouchForLite.SingletonExist)
        {
            // 移除双击事件
            SimpleTouchForLite.Instance.OnDoubleTap.RemoveListener(ToQuitApp);
        }

    }
}
```

\
把 QuitApp 挂载到 Canvas 物体上

<figure><img src="/files/BYQfE6xCgAPNMu7rdC03" alt=""><figcaption></figcaption></figure>

## 编译运行场景

### 1. 编译打包 APK

把 SharedCamera 场景 添加到 Scene In Build 中，点击 Build 进行 打包 APK

<figure><img src="/files/VeSaZlRA4NzYmDDENZ96" alt=""><figcaption></figcaption></figure>

### 2. 连接设备

X3pro 眼镜通过设备线，连接电脑，（其中，电脑 ADB 环境参见手机已经配置好环境），使用 adb devices ，查看连接的设备

<figure><img src="/files/pskmWqE2pJTj4AB9KKTp" alt=""><figcaption></figcaption></figure>

### 3. 安装应用

之前编译打包好的应用，使用 adb install xxx.apk 进行安装

<figure><img src="/files/XnAyeVah8D6GkYm0309W" alt=""><figcaption></figcaption></figure>

### 4. 查看运行应用

可以在眼镜上看到刚刚安装的应用

<figure><img src="/files/iAB6B9Pw7yUwwADZoEdF" alt=""><figcaption></figcaption></figure>

单击 TP 操作板，运行应用，简单效果如下

<figure><img src="/files/BPKn9sjW1A9vVG3uCuUt" alt=""><figcaption></figcaption></figure>

注意，添加动态相机权限申请

<figure><img src="/files/1CCm3D7Heq6WPjeX9ejY" alt=""><figcaption></figcaption></figure>

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://rayneo.gitbook.io/rayneo-devdoc/x-xi-lie/unity-kai-fa/ji-chu-neng-li-api/sharecamera.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
