1. raylib bunnymark
- Posted by andreasWagner 1 day ago
- 68 views
- Last edited 3 hours ago
Hallo,
I've been experimenting with raylib for some time now, and I've learned a lot, including things I didn't even want to know.
Also a few benchmarks. Below are the results from my Computer. (AMD Ryzen 9 3900X 12-Core Processor (3.79 GHz) Nvidia GeForce GT1030 2GB).
Results from other computers are often not applicable to your own system. Therefore, here is the source code for Phix and Euphoria. (Also works with the wrapper from Icy_Viking (32and64bit)).
The program textures_bunnymark.ex runs with both languages in the 64-bit version(and a 64bit raylib.dll). The file bunnyraylib.e is the minimal wrapper for raylib that only wraps the functions for bunnymark. So that everyone can test it for themselves.
Have fun!
Edit:I'm not 100% sure, but I think that only works on Windows. Maybe somone can give it a try on Linux.
Edit:Added Nuitka Python Compiler
Edit:wrong filename in the link to rabunny.png in the soure
Language Bunnies FPS C 100000 75 the original LuaJit 100000 35 https://github.com/TSnake41/raylib-lua Python3.9 10000 45 https://github.com/electronstudio/raylib-python-cffi Python3.9 10000 56 https://github.com/Nuitka/Nuitka?tab=readme-ov-file Nuitka
--file: textures_bunnymark.ex --/******************************************************************************************* --* 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) --********************************************************************************************/ --adapted to Phix 2026 Andreas Wagner include "bunnyraylib.e" --or "raylib.e" for Icy_Vikings wrapper --/* include std\rand.e --*/ constant MAX_BUNNIES=10000 -- 50K 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 constant MAX_BATCH_ELEMENTS=8192 ------------------------------------------------------------------------------------ -- Types and Structures Definition ---------------------------------------------------------------------------------- sequence mauspos={0,0} sequence Bunny={{0,0},{0,0},{0,0,0,0}} enum x=1,y=2 enum position_=1,speed=2,color=3 enum width=2,height=3 -------------------------------------------------------------------------------------- --Program main entry point -------------------------------------------------------------------------------------- -- Initialization ---------------------------------------------------------------------------------------- constant screenWidth = 800 constant screenHeight = 450 InitWindow(screenWidth, screenHeight, "raylib [textures] example - bunnymark") -- Load bunny texture sequence texBunny= LoadTexture("resources\\raybunny.png") --https://github.com/raysan5/raylib/blob/master/examples/textures/resources/raybunny.png sequence bunnies=repeat(Bunny,MAX_BUNNIES) --// Bunnies array atom bunniesCount = 0 -- Bunnies counter SetTargetFPS(144) -- Set our game to run at 60 frames-per-second ---------------------------------------------------------------------------------------- -- Main game loop while not WindowShouldClose() -- Detect window close button or ESC key do -- Update ------------------------------------------------------------------------------------ if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) then -- Create more bunnies for i = 1 to 100 do if (bunniesCount < MAX_BUNNIES) then mauspos=GetMousePosition() bunniesCount =bunniesCount +1 bunnies[bunniesCount][position_][x]= mauspos[x] bunnies[bunniesCount][position_][y]= mauspos[y] bunnies[bunniesCount][speed][x]= rand_range(-250, 250)/60.0 bunnies[bunniesCount][speed][y]= rand_range(-250, 250)/60.0 bunnies[bunniesCount][color] = { rand_range(50, 240),rand_range(80, 240),rand_range(100, 240), 255 } end if end for end if -- Update bunnies for i= 1 to bunniesCount do bunnies[i][position_][x] = bunnies[i][position_][x]+bunnies[i][speed][x] bunnies[i][position_][y] = bunnies[i][position_][y]+bunnies[i][speed][y] if (((bunnies[i][position_][x] + texBunny[width]/2) > GetScreenWidth()) or ((bunnies[i][position_][x] + texBunny[width]/2) < 0)) then bunnies[i][speed][x] = bunnies[i][speed][x] * -1 end if if (((bunnies[i][position_][y] + texBunny[height]/2) > GetScreenHeight()) or ((bunnies[i][position_][y] + texBunny[height]/2 - 40) < 0)) then bunnies[i][speed][y] = bunnies[i][speed][y] * -1 end if end for ------------------------------------------------------------------------------------ -- Draw ------------------------------------------------------------------------------------ BeginDrawing() ClearBackground(RAYWHITE) for i = 1 to bunniesCount do -- 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, bunnies[i][position_][x], bunnies[i][position_][y], bunnies[i][color]) end for DrawRectangle(0, 0, screenWidth, 40, BLACK) DrawText(sprintf("bunnies: %d", bunniesCount), 120, 10, 20, GREEN) DrawText(sprintf("batched draw calls: %d", 1 + bunniesCount/MAX_BATCH_ELEMENTS), 320, 10, 20, MAROON) DrawFPS(10, 10) EndDrawing() ------------------------------------------------------------------------------------ end while -- De-Initialization ---------------------------------------------------------------------------------------- -- free(bunnies) -- Unload bunnies data array bunnies={} UnloadTexture(texBunny) -- Unload bunny texture CloseWindow() -- Close window and OpenGL context ----------------------------------------------------------------------------------------
--file: bunnyraylib.e only 64bitPhix/Euphoria --/* include std/dll.e include std/machine.e include std/convert.e --*/ constant Color =C_ULONG, C_TEXTURE=C_POINTER, C_HPTR=C_POINTER --A Pointer that is added (64 bit calling convention) for a struct result (not really part of the Api) -- normally silenty done by the C-Compiler atom ray=0 sequence raylib="raylib.dll" ray = open_dll(raylib) global constant MOUSE_BUTTON_LEFT = 0 -- // Mouse button left --Colors global constant WHITE = {255,255,255,255}, BLACK = {0,0,0,255}, RAYWHITE = {245,245,245,255}, GREEN = {0,228,48,255}, MAROON = {190,33,55,255} -- Converts a 64-bit Vector2 result into a sequence function RegtoV2(atom in) sequence result={0,0} sequence x=int_to_bytes(in,8) result[1]=float32_to_atom(x[1..4]) result[2]=float32_to_atom(x[5..8]) return result end function constant xInitWindow = define_c_proc(ray,"+InitWindow",{C_INT,C_INT,C_POINTER}) global procedure InitWindow(atom width,atom height,sequence title) atom ptitle = allocate_string(title) c_proc(xInitWindow,{width,height,ptitle}) free(ptitle) end procedure constant xWindowShouldClose = define_c_func(ray,"+WindowShouldClose",{},C_BOOL) global function WindowShouldClose() return c_func(xWindowShouldClose,{}) end function constant xCloseWindow = define_c_proc(ray,"+CloseWindow",{}) public procedure CloseWindow() c_proc(xCloseWindow,{}) end procedure constant xIsMouseButtonDown = define_c_func(ray,"+IsMouseButtonDown",{C_INT},C_BOOL) global function IsMouseButtonDown(atom button) return and_bits(c_func(xIsMouseButtonDown,{button}),1) end function constant xBeginDrawing = define_c_proc(ray,"+BeginDrawing",{}) global procedure BeginDrawing() c_proc(xBeginDrawing,{}) end procedure constant xEndDrawing = define_c_proc(ray,"+EndDrawing",{}) global procedure EndDrawing() c_proc(xEndDrawing,{}) end procedure constant xSetTargetFPS = define_c_proc(ray,"+SetTargetFPS",{C_INT}) global procedure SetTargetFPS(atom fps) c_proc(xSetTargetFPS,{fps}) end procedure constant xClearBackground = define_c_proc(ray,"+ClearBackground",{Color}) global procedure ClearBackground(object color) c_proc(xClearBackground,{bytes_to_int(color)}) end procedure constant xGetScreenWidth = define_c_func(ray,"+GetScreenWidth",{},C_INT) global function GetScreenWidth() return c_func(xGetScreenWidth,{}) end function constant xGetScreenHeight = define_c_func(ray,"+GetScreenHeight",{},C_INT) global function GetScreenHeight() return c_func(xGetScreenHeight,{}) end function constant xDrawFPS = define_c_proc(ray,"+DrawFPS",{C_INT,C_INT}) global procedure DrawFPS(atom x,atom y) c_proc(xDrawFPS,{x,y}) end procedure constant xDrawText = define_c_proc(ray,"+DrawText",{C_POINTER,C_INT,C_INT,C_INT,Color}) global procedure DrawText(sequence text,atom x,atom y,atom fontSize,sequence color) atom ptext =allocate_string(text) c_proc(xDrawText,{ptext,x,y,fontSize,bytes_to_int(color)}) free(ptext) end procedure constant xDrawRectangle = define_c_proc(ray,"+DrawRectangle",{C_INT,C_INT,C_INT,C_INT,Color}) global procedure DrawRectangle(atom x,atom y,atom width,atom height,sequence color) c_proc(xDrawRectangle,{x,y,width,height,bytes_to_int(color)}) end procedure constant xUnloadTexture = define_c_proc(ray,"+UnloadTexture",{C_TEXTURE}) global procedure UnloadTexture(sequence tex) atom mem=allocate(20) poke4(mem,tex[1]) poke4(mem+4,tex[2]) poke4(mem+8,tex[3]) poke4(mem+12,tex[4]) poke4(mem+16,tex[5]) c_proc(xUnloadTexture,{mem}) free(mem) end procedure constant xDrawTexture = define_c_proc(ray,"+DrawTexture",{C_TEXTURE,C_INT,C_INT,Color}) global procedure DrawTexture(sequence tex,atom x,atom y,sequence color) atom mem=allocate(20) poke4(mem,tex[1]) poke4(mem+4,tex[2]) poke4(mem+8,tex[3]) poke4(mem+12,tex[4]) poke4(mem+16,tex[5]) c_proc(xDrawTexture,{mem,x,y,bytes_to_int(color)}) free(mem) end procedure global constant xLoadTexture = define_c_func(ray,"+LoadTexture",{C_HPTR,C_POINTER},C_TEXTURE) --RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) global function LoadTexture(sequence fname) sequence tex={0,0,0,0,0} atom mem= allocate(20) atom pstr=allocate_string(fname) atom ptr ptr = c_func(xLoadTexture,{mem,pstr}) if not equal(ptr,mem) then puts(1,"Something ugly happend in: LoadTexture") end if tex[1]=peek4u(mem) tex[2]=peek4s(mem+4) tex[3]=peek4s(mem+8) tex[4]=peek4s(mem+12) tex[5]=peek4s(mem+16) free (pstr) free (mem) return tex end function --/* constant xGetMousePosition = define_c_func(ray,"+GetMousePosition",{},C_ULONGLONG) --*/ --/* */constant xGetMousePosition = define_c_func(ray,"+GetMousePosition",{},C_QWORD) public function GetMousePosition() sequence result result=RegtoV2(c_func(xGetMousePosition,{})) return result end function

