Skip to content

Rendering Basics

Phoenix-Ra edited this page Jan 21, 2026 · 8 revisions

This page covers the essentials of setting up VR rendering with AtumVR.

Contents

  1. Setting Up the Renderer
  2. Creating a VR Scene
  3. Eye Cameras
  4. Textures

Setting Up the Renderer

To render VR content, create a class that extends XRRenderer.

Create Your Renderer

public class ExampleVRRenderer extends XRRenderer {
    private VRScene vrScene;
    
    public ExampleVRRenderer(XRProvider provider) {
        super(provider);
    }

    @Override
    public void onInit() throws Throwable {
        vrScene = new ExampleScene(this);
        vrScene.init();
    }

    @Override
    protected XRTexture createTexture(int width, int height, int textureId, int index) {
        return new XRTexture(width, height, textureId, index);
    }

    @Override
    public VRScene getCurrentScene() {
        return vrScene;
    }
}

Register in Your VRProvider

@Override
public @NotNull XRRenderer createRenderer() {
    ExampleVRRenderer renderer = new ExampleVRRenderer(this);
    renderer.setupGLContext(); // Creates OpenGL context if you don't have one
    return renderer;
}

The base XRRenderer handles frame timing, swapchain management, and view tracking automatically.


Creating a VR Scene

The scene renders your actual VR content. Extend XRScene and implement the required methods.

public class ExampleScene extends XRScene {
    private VRShaderProgram shaderProgram;
    
    public ExampleScene(XRRenderer vrRenderer) {
        super(vrRenderer);
    }

    @Override
    public void onInit() {
        // Initialize shaders and resources
        shaderProgram = new VRShaderProgram(getVrRenderer().getVrProvider());
        shaderProgram.bindVertexShader("shaders/vertex. vsh");
        shaderProgram.bindFragmentShader("shaders/fragment.fsh");
        shaderProgram.finishShader();
    }

    @Override
    public void updateEyeTexture(@NotNull EyeType eyeType) {
        // Called twice per frame - once for each eye
        shaderProgram.useShader();
        
        XREyeCamera camera = (eyeType == EyeType. LEFT) 
            ? getLeftEyeCamera() 
            : getRightEyeCamera();
        
        // Use camera matrices for rendering
        shaderProgram.setUniform("projection", camera.getProjectionMatrix());
        shaderProgram.setUniform("view", camera.getViewMatrix());
        
        // Render your objects here
        
        GL30.glUseProgram(0);
    }
    
    @Override
    public void destroy() {
        if (shaderProgram != null) {
            shaderProgram. destroy();
        }
    }
}

The built-in render() method handles framebuffer binding and clearing for each eye.


Eye Cameras

XRScene provides leftEyeCamera and rightEyeCamera that update automatically each frame.

Using Eye Cameras

XREyeCamera camera = (eyeType == EyeType.LEFT) 
    ? getLeftEyeCamera() 
    : getRightEyeCamera();

Matrix4f view = camera.getViewMatrix();        // Based on HMD position/rotation
Matrix4f projection = camera. getProjectionMatrix(); // Based on HMD field of view

Custom Clip Distances

Override setupCamera() to change the default near/far clip distances (0.02 to 100):

@Override
protected void setupCamera() {
    float near = 0.1f;
    float far = 500.0f;
    
    getLeftEyeCamera().updateProjectionMatrix(EyeType. LEFT, near, far);
    getLeftEyeCamera().updateViewMatrix(EyeType.LEFT);
    
    getRightEyeCamera().updateProjectionMatrix(EyeType.RIGHT, near, far);
    getRightEyeCamera().updateViewMatrix(EyeType.RIGHT);
}

Textures

AtumVR uses XRTexture for VR framebuffers. The renderer creates textures for both eyes automatically.

Accessing Eye Textures

XRTexture leftEye = vrRenderer.getTextureLeftEye();
XRTexture rightEye = vrRenderer.getTextureRightEye();

// Each texture provides: 
int fbo = leftEye.getFrameBufferId();  // Framebuffer to bind for rendering
int tex = leftEye.getTextureId();      // OpenGL texture ID

Note: The built-in XRScene. render() already handles framebuffer binding. You only need direct access for custom rendering pipelines.

Clone this wiki locally