raylib
raylib copied to clipboard
[rcore] Porting raylib to iOS and implement `rcore_ios.c`
I would like to take the initial step to add iOS support for raylib.
I am going to add rcore_ios.c
and implement an iOS's platform layer.
I will update this pr on my progress.
Current Demo (iPhone 8)
https://github.com/raysan5/raylib/assets/28104173/2f890d7e-bf00-44da-9285-2c73bb5c2e1e
Steps
- [x] Create an empty iOS game project in XCode
- [x] Compile ANGLE and get
libEGL.xcframework
andlibGLESv2.xcframework
- [x] Fill
rcore_ios.c
and compile raylib - [x] Link all of the above with an example source file
Functions
- [x]
void PollInputEvents(void)
- [x]
int InitPlatform(void)
- [x]
void ClosePlatform(void)
Prebuilt ANGLE libraries for iOS
Users need to add the following ANGLE libraries into Xcode. libEGL.xcframework.zip libGLESv2.xcframework.zip
References
- https://github.com/raysan5/raylib/discussions/2681
- https://github.com/raysan5/raylib/discussions/2998
- https://medium.com/@grplyler/building-and-linking-googles-angle-with-raylib-on-macos-67b07cd380a3
- https://github.com/raysan5/raylib/issues/330
- https://github.com/levinli303/ANGLESwiftUI/tree/main
I found a repository https://github.com/levinli303/ANGLESwiftUI/tree/main which made ANGLE working on iOS.
Now I grab the prebuilt libEGL.xcframework
and libGLESv2.xcframework
from the repo directly. I will figure out how to compile ANGLE from scratch later.
Hi @raysan5 . I need your help. iOS always use a UIApplicationMain
function to start the game. UIApplicationMain
is an extern function which is hidden for me. It runs forever.
int main(int argc, char * argv[]) {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
It seems does not expose detailed control to allow us to achieve the following:
int main() {
library_init();
// game init code here
while(we_have_not_quit_the_game) {
library_message_loop();
library_init_render();
// render stuff
library_end_render();
// update game state
}
library_shutdown();
}
See https://stackoverflow.com/questions/2187684/how-can-i-remove-uiapplicationmain-from-an-iphone-application.
What we can do is registering render callbacks via CADisplayLink. I cannot find a way to give users full control of the game loop.
I can try a callback-based api like this. However, this requires a minor change of existing raylib projects if they want to run on iOS.
extern void ios_ready();
extern void ios_update();
extern void ios_destroy();
Old project should adapt their main function into this in order to be cross-platform between iOS and other platforms:
#ifndef PLATFORM_IOS
int main(int argc, char** argv){
// store as global variables if you need
ios_ready();
while(!WindowShouldClose()) ios_update();
ios_destroy();
return 0;
}
#endif
Default shader seems does not compile on iOS [OpenGL ES GLSL ES 3.00 (ANGLE 2.1.22473 git hash: 07e41ef0e070)].
Click to see logs
INFO: Initializing raylib 5.1-dev
INFO: Platform backend: CUSTOM
INFO: Supported raylib modules:
INFO: > rcore:..... loaded (mandatory)
INFO: > rlgl:...... loaded (mandatory)
INFO: > rshapes:... loaded (optional)
INFO: > rtextures:. loaded (optional)
INFO: > rtext:..... loaded (optional)
INFO: > rmodels:... loaded (optional)
INFO: > raudio:.... loaded (optional)
INFO: DISPLAY: Device initialized successfully
INFO: > Display size: 0 x 0
INFO: > Screen size: 800 x 450
INFO: > Render size: 800 x 450
INFO: > Viewport offsets: 0, 0
INFO: DISPLAY: Device initialized successfully
INFO: > Display size: 0 x 0
INFO: > Screen size: 800 x 450
INFO: > Render size: 800 x 450
INFO: > Viewport offsets: 0, 0
INFO: GLAD: OpenGL extensions loaded successfully
INFO: GL: Supported extensions count: 99
INFO: GL: OpenGL device information:
INFO: > Vendor: Google Inc. (Apple)
INFO: > Renderer: ANGLE (Apple, ANGLE Metal Renderer: Apple iOS simulator GPU, Version 17.2 (Build 21C62))
INFO: > Version: OpenGL ES 3.0.0 (ANGLE 2.1.22473 git hash: 07e41ef0e070)
INFO: > GLSL: OpenGL ES GLSL ES 3.00 (ANGLE 2.1.22473 git hash: 07e41ef0e070)
INFO: GL: VAO extension detected, VAO functions loaded successfully
INFO: GL: NPOT textures extension detected, full NPOT textures supported
INFO: PLATFORM: CUSTOM: Initialized successfully
INFO: TEXTURE: [ID 1] Texture loaded successfully (1x1 | R8G8B8A8 | 1 mipmaps)
INFO: TEXTURE: [ID 1] Default texture loaded successfully
WARNING: SHADER: [ID 1] Failed to compile vertex shader code
WARNING: SHADER: [ID 1] Compile error: ERROR: 0:1: '
' : invalid version directive
ERROR: 0:2: 'in' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:3: 'in' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:4: 'in' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:5: 'out' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:6: 'out' : storage qualifier supported in GLSL ES 3.00 and above only
WARNING: SHADER: [ID 2] Failed to compile fragment shader code
WARNING: SHADER: [ID 2] Compile error: ERROR: 0:1: '
' : invalid version directive
ERROR: 0:2: 'in' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:2: '' : No precision specified for (float)
ERROR: 0:3: 'in' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:3: '' : No precision specified for (float)
ERROR: 0:4: 'out' : storage qualifier supported in GLSL ES 3.00 and above only
ERROR: 0:4: '' : No precision specified for (float)
ERROR: 0:6: '' : No precision specified for (float)
ERROR: 0:9: '' : No precision specified for (float)
ERROR: 0:9: 'texture' : no matching overloaded function found
ERROR: 0:9: '=' : dimension mismatch
ERROR: 0:9: '=' : cannot convert from 'const mediump float' to '4-component vector of float'
WARNING: SHADER: [ID 3] Failed to link shader program
WARNING: SHADER: [ID 3] Link error: Vertex shader is not compiled.
WARNING: SHADER: [ID 0] Failed to load default shader
INFO: RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)
INFO: RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)
INFO: RLGL: Default OpenGL state initialized successfully
The initial rcore_ios.c
is starting to work!! (with simple touch support)
https://github.com/raysan5/raylib/assets/28104173/ad64965e-d587-47aa-b08b-96762c9809c2
Question: I see there is a feature: InitWindow(0, 0, "title")
will set as full screen. How is it achieved?
Should I override CORE.Window.screen.width
and CORE.Window.screen.height
in InitPlatform
with device width and height?
Now rcore_ios.c
has basic functionalities including graphics, audio and touch input. I've marked this PR as ready for review. I will continue to work for more details and wait for raysan5's comment.
I request a change in CoreData
structure. On iOS, I need to use a void*
as "Point identifiers" (which is the UITouch object's address). However, current int pointId[MAX_TOUCH_POINTS];
uses int
, which cannot be used to safely store a void*
.
struct {
int pointCount;
int pointId[MAX_TOUCH_POINTS]; // Point identifiers
Vector2 position[MAX_TOUCH_POINTS];
char currentTouchState[MAX_TOUCH_POINTS];
char previousTouchState[MAX_TOUCH_POINTS];
} Touch;
Can we change it to long long pointId[MAX_TOUCH_POINTS];
?
Update: I have used a custom void*
to int
mapping to avoid the change of CoreData
Added iOS build workflow to CI.
@blueloveTH Excuse my late response and thank you very much for working on this great improvement. iOS platform has been missing from raylib for +10 years and I'm happy to see that some user implemented it.
My main concern is the iOS application approach that completely differs from all the other platforms. All raylib examples work exactly as they are on all the supported platforms and requiring a complete re-design for iOS is not the ideal situation.
Is it possible to use a similar approach to Android one? Embedding the App management inside raylib?
Also note that the provided rcore_ios.c
implementation does not follow raylib code conventions. It would be nice to follow them when possible.
Thanks for your review. I am going to resolve them soon.
Interesting.. will colaborate soon
Any new progress?
also interested :D?
I am a bit busy recently :/
It works on my branch. I may sync it with the latest raylib if I have time.
@blueloveTH do you have local changes on your branch?
I have this running on my mac/iphone now and planning on allocating some free time on this as I also need raylib ios for a project I'm working on.
Anything you need for collaboration?
Do you have your Makefile/CMake changes to compile Raylib to ios local?
To use raylib with Emscripten it's already necessary to give up the main loop control(unless one's willing to add ASYNCIFY
which has a nonnegligible overhead).
So I like the idea of a callback based design. Maybe something along the lines of SDL3 main callback functions.
Here's how they handle the quirks of each platform, including iOS.
Definitely interested in this. This is the dream, being able to make cross platform mobile apps and games with raylib would be amazing.
@leftbones Unfortunately the code structure required for this iOS implementation is hardly compatible with raylib structure, not sure if it's possible to use another structure, more similar to Android one.
There may be internal functions that Apple does not expose allowing us to take full control of the main loop.
Perhaps the newly merged SDL_GPU as a backend would be a better approach for targeting iOS, and consoles!!!