← ziglang.inraylib-zigGitHub

vr simulator

★★★☆by Ramon Santamaria (@raysan5)

There is no browser build of this example yet.

Is it the same as C?

//! raylib [core] example - vr simulator
//!
//! Zig-API translation of examples/core/core_vr_simulator.c (raylib 6.2).
//! Example licensed under an unmodified zlib/libpng license.
//! Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)

const rl = @import("raylib");

const glsl_version = 330; // Desktop GLSL (PLATFORM_ANDROID, PLATFORM_WEB use 100)

pub fn main() !void {
    // Initialization
    const screen_width = 800;
    const screen_height = 450;

    // NOTE: screen_width/screen_height should match VR device aspect ratio
    rl.initWindow(screen_width, screen_height, "raylib [core] example - vr simulator");
    defer rl.closeWindow(); // Close window and OpenGL context

    // VR device parameters definition
    const device: rl.VrDeviceInfo = .{
        // Oculus Rift CV1 parameters for simulator
        .hResolution = 2160, // Horizontal resolution in pixels
        .vResolution = 1200, // Vertical resolution in pixels
        .hScreenSize = 0.133793, // Horizontal size in meters
        .vScreenSize = 0.0669, // Vertical size in meters
        .eyeToScreenDistance = 0.041, // Distance between eye and display in meters
        .lensSeparationDistance = 0.07, // Lens separation distance in meters
        .interpupillaryDistance = 0.07, // IPD (distance between pupils) in meters

        // NOTE: CV1 uses fresnel-hybrid-asymmetric lenses with specific compute shaders
        // Following parameters are just an approximation to CV1 distortion stereo rendering
        .lensDistortionValues = .{ 1.0, 0.22, 0.24, 0.0 }, // Lens distortion constant parameters
        .chromaAbCorrection = .{ 0.996, -0.004, 1.014, 0.0 }, // Chromatic aberration correction parameters
    };

    // Load VR stereo config for VR device parameteres (Oculus Rift CV1 parameters)
    const config = rl.loadVrStereoConfig(device);
    defer rl.unloadVrStereoConfig(config); // Unload stereo config

    // Distortion shader (uses device lens distortion and chroma)
    const distortion = try rl.loadShader(null, rl.textFormat("resources/shaders/glsl{d}/distortion.fs", .{glsl_version}));
    defer rl.unloadShader(distortion); // Unload distortion shader

    // Update distortion shader with lens and distortion-scale parameters
    rl.setShaderValue(distortion, rl.getShaderLocation(distortion, "leftLensCenter"), config.leftLensCenter);
    rl.setShaderValue(distortion, rl.getShaderLocation(distortion, "rightLensCenter"), config.rightLensCenter);
    rl.setShaderValue(distortion, rl.getShaderLocation(distortion, "leftScreenCenter"), config.leftScreenCenter);
    rl.setShaderValue(distortion, rl.getShaderLocation(distortion, "rightScreenCenter"), config.rightScreenCenter);

    rl.setShaderValue(distortion, rl.getShaderLocation(distortion, "scale"), config.scale);
    rl.setShaderValue(distortion, rl.getShaderLocation(distortion, "scaleIn"), config.scaleIn);
    rl.setShaderValue(distortion, rl.getShaderLocation(distortion, "deviceWarpParam"), device.lensDistortionValues);
    rl.setShaderValue(distortion, rl.getShaderLocation(distortion, "chromaAbParam"), device.chromaAbCorrection);

    // Initialize framebuffer for stereo rendering
    // NOTE: Screen size should match HMD aspect ratio
    const target = try rl.loadRenderTexture(device.hResolution, device.vResolution);
    defer rl.unloadRenderTexture(target); // Unload stereo render fbo

    // The target's height is flipped (in the source Rectangle), due to OpenGL reasons
    const source_rec: rl.Rectangle = .{
        .x = 0.0,
        .y = 0.0,
        .width = @floatFromInt(target.texture.width),
        .height = -@as(f32, @floatFromInt(target.texture.height)),
    };
    const dest_rec: rl.Rectangle = .{
        .x = 0.0,
        .y = 0.0,
        .width = @floatFromInt(rl.getScreenWidth()),
        .height = @floatFromInt(rl.getScreenHeight()),
    };

    // Define the camera to look into our 3d world
    var camera: rl.Camera = .{
        .position = .{ .x = 5.0, .y = 2.0, .z = 5.0 }, // Camera position
        .target = .{ .x = 0.0, .y = 2.0, .z = 0.0 }, // Camera looking at point
        .up = .{ .x = 0.0, .y = 1.0, .z = 0.0 }, // Camera up vector
        .fovy = 60.0, // Camera field-of-view Y
        .projection = .perspective, // Camera projection type
    };

    const cube_position: rl.Vector3 = .{ .x = 0.0, .y = 0.0, .z = 0.0 };

    rl.disableCursor(); // Limit cursor to relative movement inside the window

    rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second

    // Main game loop
    while (!rl.windowShouldClose()) { // Detect window close button or ESC key
        // Update
        rl.updateCamera(&camera, .first_person);

        // Draw
        {
            rl.beginTextureMode(target);
            defer rl.endTextureMode();

            rl.clearBackground(.ray_white);

            rl.beginVrStereoMode(config);
            defer rl.endVrStereoMode();

            rl.beginMode3D(camera);
            defer rl.endMode3D();

            rl.drawCube(cube_position, 2.0, 2.0, 2.0, .red);
            rl.drawCubeWires(cube_position, 2.0, 2.0, 2.0, .maroon);
            rl.drawGrid(40, 1.0);
        }

        rl.beginDrawing();
        defer rl.endDrawing();

        rl.clearBackground(.ray_white);
        {
            rl.beginShaderMode(distortion);
            defer rl.endShaderMode();

            rl.drawTexturePro(target.texture, source_rec, dest_rec, .{ .x = 0.0, .y = 0.0 }, 0.0, .white);
        }
        rl.drawFPS(10, 10);
    }
}
/*******************************************************************************************
*
*   raylib [core] example - vr simulator
*
*   Example complexity rating: [★★★☆] 3/4
*
*   Example originally created with raylib 2.5, last time updated with raylib 4.0
*
*   Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
*   BSD-like license that allows static linking with closed source software
*
*   Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

#include "raylib.h"

#if defined(PLATFORM_DESKTOP)
    #define GLSL_VERSION        330
#else   // PLATFORM_ANDROID, PLATFORM_WEB
    #define GLSL_VERSION        100
#endif

//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
    // Initialization
    //--------------------------------------------------------------------------------------
    const int screenWidth = 800;
    const int screenHeight = 450;

    // NOTE: screenWidth/screenHeight should match VR device aspect ratio
    InitWindow(screenWidth, screenHeight, "raylib [core] example - vr simulator");

    // VR device parameters definition
    VrDeviceInfo device = {
        // Oculus Rift CV1 parameters for simulator
        .hResolution = 2160,                 // Horizontal resolution in pixels
        .vResolution = 1200,                 // Vertical resolution in pixels
        .hScreenSize = 0.133793f,            // Horizontal size in meters
        .vScreenSize = 0.0669f,              // Vertical size in meters
        .eyeToScreenDistance = 0.041f,       // Distance between eye and display in meters
        .lensSeparationDistance = 0.07f,     // Lens separation distance in meters
        .interpupillaryDistance = 0.07f,     // IPD (distance between pupils) in meters

        // NOTE: CV1 uses fresnel-hybrid-asymmetric lenses with specific compute shaders
        // Following parameters are just an approximation to CV1 distortion stereo rendering
        .lensDistortionValues[0] = 1.0f,     // Lens distortion constant parameter 0
        .lensDistortionValues[1] = 0.22f,    // Lens distortion constant parameter 1
        .lensDistortionValues[2] = 0.24f,    // Lens distortion constant parameter 2
        .lensDistortionValues[3] = 0.0f,     // Lens distortion constant parameter 3
        .chromaAbCorrection[0] = 0.996f,     // Chromatic aberration correction parameter 0
        .chromaAbCorrection[1] = -0.004f,    // Chromatic aberration correction parameter 1
        .chromaAbCorrection[2] = 1.014f,     // Chromatic aberration correction parameter 2
        .chromaAbCorrection[3] = 0.0f,       // Chromatic aberration correction parameter 3
    };

    // Load VR stereo config for VR device parameteres (Oculus Rift CV1 parameters)
    VrStereoConfig config = LoadVrStereoConfig(device);

    // Distortion shader (uses device lens distortion and chroma)
    Shader distortion = LoadShader(0, TextFormat("resources/shaders/glsl%i/distortion.fs", GLSL_VERSION));

    // Update distortion shader with lens and distortion-scale parameters
    SetShaderValue(distortion, GetShaderLocation(distortion, "leftLensCenter"),
                   config.leftLensCenter, SHADER_UNIFORM_VEC2);
    SetShaderValue(distortion, GetShaderLocation(distortion, "rightLensCenter"),
                   config.rightLensCenter, SHADER_UNIFORM_VEC2);
    SetShaderValue(distortion, GetShaderLocation(distortion, "leftScreenCenter"),
                   config.leftScreenCenter, SHADER_UNIFORM_VEC2);
    SetShaderValue(distortion, GetShaderLocation(distortion, "rightScreenCenter"),
                   config.rightScreenCenter, SHADER_UNIFORM_VEC2);

    SetShaderValue(distortion, GetShaderLocation(distortion, "scale"),
                   config.scale, SHADER_UNIFORM_VEC2);
    SetShaderValue(distortion, GetShaderLocation(distortion, "scaleIn"),
                   config.scaleIn, SHADER_UNIFORM_VEC2);
    SetShaderValue(distortion, GetShaderLocation(distortion, "deviceWarpParam"),
                   device.lensDistortionValues, SHADER_UNIFORM_VEC4);
    SetShaderValue(distortion, GetShaderLocation(distortion, "chromaAbParam"),
                   device.chromaAbCorrection, SHADER_UNIFORM_VEC4);

    // Initialize framebuffer for stereo rendering
    // NOTE: Screen size should match HMD aspect ratio
    RenderTexture2D target = LoadRenderTexture(device.hResolution, device.vResolution);

    // The target's height is flipped (in the source Rectangle), due to OpenGL reasons
    Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };
    Rectangle destRec = { 0.0f, 0.0f, (float)GetScreenWidth(), (float)GetScreenHeight() };

    // Define the camera to look into our 3d world
    Camera camera = { 0 };
    camera.position = (Vector3){ 5.0f, 2.0f, 5.0f };    // Camera position
    camera.target = (Vector3){ 0.0f, 2.0f, 0.0f };      // Camera looking at point
    camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };          // Camera up vector
    camera.fovy = 60.0f;                                // Camera field-of-view Y
    camera.projection = CAMERA_PERSPECTIVE;             // Camera projection type

    Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };

    DisableCursor();                    // Limit cursor to relative movement inside the window

    SetTargetFPS(60);                   // Set our game to run at 60 frames-per-second
    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!WindowShouldClose())        // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        UpdateCamera(&camera, CAMERA_FIRST_PERSON);
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginTextureMode(target);
            ClearBackground(RAYWHITE);
            BeginVrStereoMode(config);
                BeginMode3D(camera);

                    DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
                    DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
                    DrawGrid(40, 1.0f);

                EndMode3D();
            EndVrStereoMode();
        EndTextureMode();

        BeginDrawing();
            ClearBackground(RAYWHITE);
            BeginShaderMode(distortion);
                DrawTexturePro(target.texture, sourceRec, destRec, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
            EndShaderMode();
            DrawFPS(10, 10);
        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    UnloadVrStereoConfig(config);   // Unload stereo config

    UnloadRenderTexture(target);    // Unload stereo render fbo
    UnloadShader(distortion);       // Unload distortion shader

    CloseWindow();                  // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}

From raylib 6.2. The original on GitHub.