# How to use

On this page, we will go through on how to use the render plugin in a simple Android app which only contains a MainActivity. The basic usage of the plugin is easy, but we have to pay attention on several tasks.

### Add dependency

The render plug-in is placed into a separate module called **apefilamentrender**. This means that when building our application, we do not just have to add the **apertusvr** module to our dependency list, but the **apefilamentrender**, as well:

{% code title="build.gradle (Module: app)" %}

```
dependencies {
    // ... 

    implementation project(":apertusvr")
    implementation project(":apefilamentrender")
}
```

{% endcode %}

### Import classes

The plug-in itself contains sever classes, but when we using this module, our only concern is about the `apeFilamentRenderPlugin`. This is the one class, which contains everything we need to render on Android:

```java
public final class apeFilamentRenderPlugin implements apePlugin {

// ...

}
```

So in our **MainActivity.java** file we import this class:

```java
import org.apertusvr.render.apefilamentrenderplugin;
```

### Init the plugin

It is not a surprise that we have to create every resource and init the plug-in, before using it. Assuming we want to use the plugin right from the application's starting, we have to do our job in the MainActivity.onCreate(/\*...\*/) funciton. So gather what resources we have to obtain there:

1. The context, which is the reference to the activity, which started the plugin,
2. the context's lifecycle,
3. a [`SurfaceView`](https://developer.android.com/reference/android/view/SurfaceView?hl=en), which we can render onto,
4. the context's resources folder
5. the context's asset folder,
6. an optional `userNode`.

The first five is pretty trivial if our `MainActivity` is derived from [`AppCompatActivity`](https://developer.android.com/reference/androidx/appcompat/app/AppCompatActivity):

```java
SurfaceView surfaceView = new SurfaceView(this);

apeFilamentRenderPlugin renderPlugin = new apeFilamentRenderPlugin(
                this, getLifecycle(), surfaceView,
                getResources(), getAssets(), /* ... */);
```

1. The context is a reference to our MainActivity.
2. AppCompatActivity implements the [LifecycleOwner interface](https://developer.android.com/reference/androidx/lifecycle/LifecycleOwner?hl=en), therefore it has getLifecycle() method.
3. We can easily get the activity's SurfaceView by `new SurfaceView(this)`.
4. The resource folder can be obtained with the getResources() method.
5. The asset folder can be obtained with the getAssets() method.

So what about the 6th parameter, the userNode? We need this in order to be able to propagate our camera's position into ApertusVR. If we do not need this feature in our application, just set the 6th parameter to `null`. Otherwise, we have to use the ApertusVR Java-API to create a userNode, possibly with some avatar geometry (e.g. a cone). Without further explanation the following code block shows an example for this:

```java
String userName = /* get userName */;
String GUID = apeCoreConfig.getNetworkGUID();
apeNode userNode = apeSceneManager.createNode(userName, true, GUID);

if (userNode != null && userNode.isValid()) {
    apeManualMaterial userMaterial = Objects.requireNonNull(
    apeSceneManager.createEntity(
        userName + "_Material",
        apeEntity.Type.MATERIAL_MANUAL,
        true, GUID))
    .cast(new apeManualMaterial.apeManualMaterialBuilder());

    if(userMaterial != null && userMaterial.isValid()) {
        apeColor color = new apeColor(255f,105f,180f);
    
        userMaterial.setDiffuseColor(color);
        userMaterial.setSpecularColor(color);
    
        apeNode userConeNode = apeSceneManager.createNode(
                userName + "_ConeNode", true, GUID);
    
        if (userConeNode != null && userConeNode.isValid()) {
            userConeNode.setParentNode(userNode);
           
            apeConeGeometry userCone = Objects.requireNonNull(
                apeSceneManager.createEntity(
                    userName + "_ConeGeometry",
                    apeEntity.Type.GEOMETRY_CONE,
                    true, GUID))
                .cast(new apeConeGeometry.apeConeBuilder());
    
            if (userCone != null && userCone.isValid()) {
                userCone.setParentNode(userConeNode);
                userCone.setMaterial(userMaterial);
            }
        }
    }
}
```

Now we have `userNode`, so just we set it as the 6th parameter.

Great! What is left? The only task remained is to  add our plugin as a lifecycle observer:

```java
getLifecycle().addObserver(renderPlugin).
```

If you did everything as discussed and also paid attention on [how to set up the ApertusVR system for applications](https://apertus.gitbook.io/vr/plugins-jni/how-to-use#writing-an-application), then the render plugin will give response for all the events occouring in ApertusVR while `MainActivity` is running.

For basic usage this is all you need to know. However to be able to custumize the plug-in for your own wish, see the next page on how to configure.


---

# 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://apertus.gitbook.io/vr/plugins-android/untitled-1/how-to-use.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.
