> For the complete documentation index, see [llms.txt](https://rayneo-en.gitbook.io/rayneo-devdoc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://rayneo-en.gitbook.io/rayneo-devdoc/x-series/unity-sdk/basic-capabilities-and-api/sharecamera.md).

# Sharecamera

## **Introduction**

SharedCamera is a technology in Unity that leverages Android shared textures for efficient video stream processing. It creates a shared EGL context and OpenGL texture, allowing Android native code to directly update texture data, while Unity references the texture via Texture2D.CreateExternalTexture for rendering.

This approach avoids data copying between GPU and CPU, significantly enhancing performance and rendering efficiency while reducing memory usage. It is particularly suitable for real-time video stream processing scenarios, such as AR applications.

## **API Introduction**

<table data-header-hidden><thead><tr><th width="208"></th><th></th><th></th></tr></thead><tbody><tr><td>Calling Method</td><td>Instructions for Use</td><td>Sample Code</td></tr><tr><td>Open CameraShareCamera.OpenCamera(XRCameraType cameraType, XRResolution resolution, RawImage img = null, int frameRate = 30)<br></td><td><p><strong>Details of Parameters and Return Values:</strong></p><p>/// &#x3C;param name="cameraTpye">Camera Camera Type&#x3C;/param></p><p>/// &#x3C;param name="resolution">Some camera settings (resolution), e.g., XRResolution(640, 480);&#x3C;/param></p><p>/// &#x3C;param name="img">Displayed UI&#x3C;/param></p><p>/// &#x3C;param name="frameRate">Get the frame rate of the image&#x3C;/param></p><p>/// &#x3C;returns>XRCameraHandler &#x3C;/returns></p><p><br><strong>Abnormal Scenario Description: When an abnormality occurs, check whether camera permission has been applied for</strong></p><p><br><strong>Timing suggestion for invocation: Before using the camera, it is recommended to apply for permission first</strong></p></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>Get the list of supported resolutionsShareCamera.getSupportResolutions(XRCameraType cameraTpye)</td><td><p><strong>Details of Parameters and Return Values:</strong></p><p>Get the supported resolution for the corresponding Camera type</p><p>/// &#x3C;param name="cameraTpye">Camera 类型&#x3C;/param></p><p>/// &#x3C;returns>XRResolution[] resolution array&#x3C;/returns></p><p><br><strong>Abnormal scenario description: None for now</strong></p><p><br><strong>Timing recommendation for invocation: When you are unsure about the supported camera resolution, you can obtain and view it during the running of the scenario</strong></p></td><td><pre class="language-c#"><code class="lang-c#"> XRResolution[] rlt = ShareCamera.getSupportResolutions(cameraTpye);
</code></pre></td></tr><tr><td>Turn off cameraShareCamera.CloseCamera(XRCameraHandler info)</td><td><p><strong>Details of Parameters and Return Values:</strong></p><p>/// &#x3C;param name="info">Previously opened XRCameraHandler&#x3C;/param></p><p>/// &#x3C;returns>bool Whether the closure was successful&#x3C;/returns></p><p><br><strong>Abnormal Scenario Description: Whether the parameter passed to XRCameraHandler is null</strong></p><p><br><strong>Call timing suggestion: When the camera function is not needed, please turn it off promptly</strong></p></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>Photo RotationXRImageUtils.rotate(XRImageFormat format, Texture2D src, Texture2D dst, XRRotateMode degree)<br></td><td><p><strong>Details of Parameters and Return Values:</strong></p><p>/// &#x3C;param name="format">The format of the image XRImageFormat &#x3C;/param></p><p>/// &#x3C;param name="src">源图片 Texture2D &#x3C;/param></p><p>/// &#x3C;param name="dst">Destination image Texture2D&#x3C;/param></p><p>/// &#x3C;param name="degree">Select Angle XRRotateMode &#x3C;/param></p><p>/// &#x3C;returns>int &#x3C;/returns></p><p><br><strong>Abnormal scenario description: Note that the image source data is not empty</strong></p><p><br><strong>Call timing suggestion: Rotate the image when rotation processing is needed</strong></p></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>Photo MirroringXRImageUtils.mirror(XRImageFormat format, Texture2D src, Texture2D dst)</td><td><p><strong>Details of Parameters and Return Values:</strong></p><p>/// &#x3C;param name="format">The format of the image XRImageFormat &#x3C;/param></p><p>/// &#x3C;param name="src">源图片 Texture2D &#x3C;/param></p><p>/// &#x3C;param name="dst">Destination image Texture2D&#x3C;/param></p><p>/// &#x3C;returns>int &#x3C;/returns></p><p><br><strong>Abnormal scenario description: Note that the image source data is not empty</strong></p><p><br><strong>Timing recommendation for invocation: Perform image mirroring when mirroring processing is needed</strong></p></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>

The following is an example of resolution enumeration for the X3pro camera. In actual use, it is best to obtain the latest supported resolution through the interface.

{% columns %}
{% column %}
\[Example] Resolution Supported by x3pro RGB Camera\
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 %}
\[Example] Resolution Supported by X3pro VGA Camera\
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>

## **Scene Setup**

Set up the basic environment and import the Sample Demo for required functionalities.

![](/files/36caa37ea31262e970d017e2d6ee9ad47bfe087c)

### **1. Create a New Scene**

Create a new Unity3D project named **SharedCamera**.

![](/files/c9f4354d87ce236c9846ba0f56a8d7968a3a0647)

### **2. Replace MainCamera with XR Plugin**

Open the scene and delete the default MainCamera.

![](/files/c7f86308e81f66118f17ef14f490e671c9658446)

Locate the **XR Plugin** prefab in the path:

packages/RayNeo OPenXR ARDK - SDK - Runtime - Resources - Prefab

![](/files/b759ab9b1df95b094884f7b6ca3312a7fbff90c7)

Drag the **XR Plugin** prefab into the scene.

![](/files/7ecdff779a5fb8f8ae8c259fe52b80a9626520c5)

### **3. Add Resources to the Scene**

Right-click in the scene and add a **Canvas**.

![](/files/a76d6b18cb396f2cedecc007a8b87d025b9c1d68)

Replace the GraphicRaycaster on the Canvas with XRGraphicRaycaster:

* Remove the default GraphicRaycaster from the Canvas.

![](/files/b84ab32087253c433035041ab2449966e661c855)

* Add XRGraphicRaycaster to the Canvas.

![](/files/93959821370916296122f9a4b1da72b1f5adb673)

Add a **RawImage** under the Canvas.

![](/files/b694b03a2359805cd2a742d1cab9ddf820428692)

### **4. Configure SharedCamera Functionality**

* Set the Canvas' RenderMode to WorldSpace and EventCamera to the Camera on XRPlugin > Head.

![](/files/f67bf6e9bb27e739896b081e880ab7223e3e9eec)

* Add the ShareCameraCtrl component to the RawImage under the Canvas.

![](/files/852af079bbc20995fcd31ea8ac81e9a20325c8c5)

* Assign the current RawImage to the RI field in ShareCameraCtrl.

![](/files/6c1b2b9485bc0a5b8a1b09caf45d4892c290b42d)

### **5. Add Double-tap Exit Functionality**

Create a QuitApp script in the Scripts folder (create if not exists):

![](/files/fc8dbbe57d2afe07e32ea49ac5ee4f9641a4d839)

Edit the script with the following code:

```c#
using RayNeo;
using UnityEngine;

public class QuitApp : MonoBehaviour
{
    /// <summary>
    /// Exit the application
    /// </summary>
    public void ToQuitApp()
    {
        Application.Quit();
    }

    void Start()
    {
        // Add double-tap event
        SimpleTouch.Instance.OnDoubleTap.AddListener(ToQuitApp);
    }

    private void OnDestroy()
    {
        if (SimpleTouch.SingletonExist)
        {
            // Remove double-tap event
            SimpleTouch.Instance.OnDoubleTap.RemoveListener(ToQuitApp);
        }
    }
}
```

Attach the QuitApp script to the Canvas object.

![](/files/ecc1bbb552688e3e4f0080abe89f2354295d6f19)

## **Compile and Run the Scene**

### **1. Build the APK**

Add the **SharedCamera** scene to Scenes In Build and click **Build** to generate the APK.

![](/files/ea922ac6f851fdf09d0f409a815862fe8a3b74f5)

### **2. Connect the Device**

Connect the X3 Pro glasses to your computer via USB (ensure ADB is configured). Verify the connection with adb devices.

![](/files/283e725743fcea556a1eea434f054da8d4bc8082)

### **3. Install the Application**

Install the compiled APK using adb install xxx.apk.

![](/files/9095bb1f696bb32f96db293900f5ef9ce18aff8c)

### **4. Run the Application**

Launch the app on the glasses and tap the TouchPad to see the demo in action.

| ![](/files/4d3cc5081e72297031944ab99a16babde10c4cb5) | ![](/files/b62515a494b6b1753df45b99796e352e48c5d954) |
| ---------------------------------------------------- | ---------------------------------------------------- |

\[Note]Add dynamic camera permission request.

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://rayneo-en.gitbook.io/rayneo-devdoc/x-series/unity-sdk/basic-capabilities-and-api/sharecamera.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
