← ziglang.inraylib-zigGitHub

bunnymark

★★★☆by Ramon Santamaria (@raysan5)

There is no browser build of this example yet.

Is it the same as C?

//! raylib [textures] example - bunnymark
//!
//! Zig-API translation of examples/textures/textures_bunnymark.c (raylib 6.2).
//! Example licensed under an unmodified zlib/libpng license.
//! Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)

const std = @import("std");
const rl = @import("raylib");

const max_bunnies = 80000; // 80K bunnies limit

// This is the maximum amount of elements (quads) per batch
// NOTE: This value is defined in [rlgl] module and can be changed there
const max_batch_elements = 8192;

const Bunny = struct {
    position: rl.Vector2,
    speed: rl.Vector2,
    color: rl.Color,
};

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

    rl.initWindow(screen_width, screen_height, "raylib [textures] example - bunnymark");
    defer rl.closeWindow(); // Close window and OpenGL context

    // Load bunny texture
    const tex_bunny = try rl.loadTexture("resources/raybunny.png");
    defer rl.unloadTexture(tex_bunny);

    // Bunnies storage, filled up to `bunnies_count`
    const bunnies = try std.heap.page_allocator.alloc(Bunny, max_bunnies);
    defer std.heap.page_allocator.free(bunnies);
    var bunnies_count: usize = 0;

    var paused = false;

    const half_width = @as(f32, @floatFromInt(tex_bunny.width)) / 2;
    const half_height = @as(f32, @floatFromInt(tex_bunny.height)) / 2;

    rl.setTargetFPS(0); // Set our game to run with an uncapped framerate

    // Main game loop
    while (!rl.windowShouldClose()) { // Detect window close button or ESC key
        // Update
        if (rl.isMouseButtonDown(.left)) {
            // Create more bunnies
            for (0..100) |_| {
                if (bunnies_count < max_bunnies) {
                    const position = rl.getMousePosition();
                    const speed_x: f32 = @floatFromInt(rl.getRandomValue(-250, 250));
                    const speed_y: f32 = @floatFromInt(rl.getRandomValue(-250, 250));
                    const r: u8 = @intCast(rl.getRandomValue(50, 240));
                    const g: u8 = @intCast(rl.getRandomValue(80, 240));
                    const b: u8 = @intCast(rl.getRandomValue(100, 240));
                    bunnies[bunnies_count] = .{
                        .position = position,
                        .speed = .{ .x = speed_x, .y = speed_y },
                        .color = .{ .r = r, .g = g, .b = b, .a = 255 },
                    };
                    bunnies_count += 1;
                }
            }
        }

        if (rl.isKeyPressed(.p)) paused = !paused;

        if (!paused) {
            // Update bunnies
            const screen_w: f32 = @floatFromInt(rl.getScreenWidth());
            const screen_h: f32 = @floatFromInt(rl.getScreenHeight());
            for (bunnies[0..bunnies_count]) |*bunny| {
                bunny.position.x += bunny.speed.x * rl.getFrameTime();
                bunny.position.y += bunny.speed.y * rl.getFrameTime();

                if (((bunny.position.x + half_width) > screen_w) or
                    ((bunny.position.x + half_width) < 0)) bunny.speed.x *= -1;
                if (((bunny.position.y + half_height) > screen_h) or
                    ((bunny.position.y + half_height - 40) < 0)) bunny.speed.y *= -1;
            }
        }

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

        rl.clearBackground(.ray_white);

        for (bunnies[0..bunnies_count]) |bunny| {
            // NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS),
            // a draw call is launched and buffer starts being filled again;
            // before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU...
            // Process of sending data is costly and it could happen that GPU data has not been completely
            // processed for drawing while new data is tried to be sent (updating current in-use buffers)
            // it could generates a stall and consequently a frame drop, limiting the number of drawn bunnies
            rl.drawTexture(tex_bunny, @intFromFloat(bunny.position.x), @intFromFloat(bunny.position.y), bunny.color);
        }

        rl.drawRectangle(0, 0, screen_width, 40, .black);
        rl.drawText(rl.textFormat("bunnies: {d}", .{bunnies_count}), 120, 10, 20, .green);
        rl.drawText(rl.textFormat("batched draw calls: {d}", .{1 + bunnies_count / max_batch_elements}), 320, 10, 20, .maroon);

        rl.drawFPS(10, 10);
    }
}
/*******************************************************************************************
*
*   raylib [textures] example - bunnymark
*
*   Example complexity rating: [★★★☆] 3/4
*
*   Example originally created with raylib 1.6, last time updated with raylib 2.5
*
*   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) 2014-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

#include "raylib.h"

#include <stdlib.h>                 // Required for: malloc(), free()

#define MAX_BUNNIES        80000    // 80K bunnies limit

// This is the maximum amount of elements (quads) per batch
// NOTE: This value is defined in [rlgl] module and can be changed there
#define MAX_BATCH_ELEMENTS  8192

//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct Bunny {
    Vector2 position;
    Vector2 speed;
    Color color;
} Bunny;

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

    InitWindow(screenWidth, screenHeight, "raylib [textures] example - bunnymark");

    // Load bunny texture
    Texture2D texBunny = LoadTexture("resources/raybunny.png");

    Bunny *bunnies = (Bunny *)RL_MALLOC(MAX_BUNNIES*sizeof(Bunny));    // Bunnies array

    int bunniesCount = 0;           // Bunnies counter

    bool paused = false;

    SetTargetFPS(0);               // Set our game to run with an uncapped framerate
    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!WindowShouldClose())    // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
        {
            // Create more bunnies
            for (int i = 0; i < 100; i++)
            {
                if (bunniesCount < MAX_BUNNIES)
                {
                    bunnies[bunniesCount].position = GetMousePosition();
                    bunnies[bunniesCount].speed.x = (float)GetRandomValue(-250, 250);
                    bunnies[bunniesCount].speed.y = (float)GetRandomValue(-250, 250);
                    bunnies[bunniesCount].color = (Color){ GetRandomValue(50, 240),
                                                       GetRandomValue(80, 240),
                                                       GetRandomValue(100, 240), 255 };
                    bunniesCount++;
                }
            }
        }

        if (IsKeyPressed(KEY_P)) paused = !paused;

        if (!paused)
        {
            // Update bunnies
            for (int i = 0; i < bunniesCount; i++)
            {
                bunnies[i].position.x += bunnies[i].speed.x*GetFrameTime();
                bunnies[i].position.y += bunnies[i].speed.y*GetFrameTime();

                if (((bunnies[i].position.x + (float)texBunny.width/2) > GetScreenWidth()) ||
                    ((bunnies[i].position.x + (float)texBunny.width/2) < 0)) bunnies[i].speed.x *= -1;
                if (((bunnies[i].position.y + (float)texBunny.height/2) > GetScreenHeight()) ||
                    ((bunnies[i].position.y + (float)texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1;
            }
        }
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);

            for (int i = 0; i < bunniesCount; i++)
            {
                // NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS),
                // a draw call is launched and buffer starts being filled again;
                // before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU...
                // Process of sending data is costly and it could happen that GPU data has not been completely
                // processed for drawing while new data is tried to be sent (updating current in-use buffers)
                // it could generates a stall and consequently a frame drop, limiting the number of drawn bunnies
                DrawTexture(texBunny, (int)bunnies[i].position.x, (int)bunnies[i].position.y, bunnies[i].color);
            }

            DrawRectangle(0, 0, screenWidth, 40, BLACK);
            DrawText(TextFormat("bunnies: %i", bunniesCount), 120, 10, 20, GREEN);
            DrawText(TextFormat("batched draw calls: %i", 1 + bunniesCount/MAX_BATCH_ELEMENTS), 320, 10, 20, MAROON);

            DrawFPS(10, 10);

        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    RL_FREE(bunnies);           // Unload bunnies data array

    UnloadTexture(texBunny);    // Unload bunny texture

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

    return 0;
}

From raylib 6.2. The original on GitHub.