Merge: Gamnit on iOS
authorJean Privat <jean@pryen.org>
Thu, 25 Jan 2018 20:16:37 +0000 (15:16 -0500)
committerJean Privat <jean@pryen.org>
Thu, 25 Jan 2018 20:16:37 +0000 (15:16 -0500)
Support iOS as a target for Gamnit games, including:

* GC on iOS and Xcode assets folder support in the compiler.
* iOS view controller and OpenGL view using the GLKit services.
* Loading of assets: sound, texture and text (and thus 3D models and fonts).
* iOS touch event and orientation change support.
* A few bug fix and tweaks to Gamnit.
* Minimal makefile rules to target iOS.

The game `asteronits` works as expected, here it is on iPad (With controls that are way too big):

![screen shot 2018-01-14 at 10 11 17](https://user-images.githubusercontent.com/208057/34918201-187b8b4a-f91d-11e7-86a2-6b891b237316.png)

Limitations:
* By default, the compiler generates an app for the simulator. To compile for a physical device, in practice, I run `nitc -m ios --compile-dir nit_compile` to generate the iOS project and view errors in Nit or in the custom Objective-C code. And then I launch Xcode with `open -a xcode nit_compile/ios/my_project.xcodeproj` to compile and run on a device from there.

* The depth API (3D) does not work on iOS with this PR because of known bugs in the current implementation. I have a rewrite of the depth API that fixes these bugs and bring a much needed performance boost.

* A `Sound` instance can't be played more than once concurrently. This could be improved by using `AVPlayer` as kind of sound channel and an `AVPlayerItem` for each sound instance, instead of the current `AVAudioPlayer`.

* iOS does not support exactly the same format for assets than Android. Sounds in mp3 format should work on both platforms. PNG files work on both platforms but iOS is more picky on the color palette, I've had an issue with a greyscale PNG, RGBA PNG files should be safe.

  You can always use the `app_files` annotation to include platform-specific assets.

* `gamnit::selection` does not work on iOS because we can't read the screen pixels. It should be updated to use an FBO.

* We still need a portable API for locking the screen orientation.

* Compiling Gamnit games for iOS fails at a missing pkg-config package. The package is not used and in can be safely ignored by removing the "pkgconfig" line in `lib/glesv2/glesv2.nit`. I'll need to find a clean fix for this...

Pull-Request: #2605
Reviewed-by: Romain Chanoir <romain.chanoir@viacesi.fr>

1  2 
lib/gamnit/gamnit.nit
lib/glesv2/glesv2.nit
tests/Darwin.skip

diff --combined lib/gamnit/gamnit.nit
@@@ -23,6 -23,8 +23,8 @@@ import program
  
  import gamnit_android is conditional(android)
  import gamnit_linux is conditional(linux)
+ import gamnit_ios is conditional(ios)
+ import input_ios is conditional(ios)
  
  redef class App
  
        #
        # The gamnit services redefine this method to prepare optimizations and more.
        # Clients may also refine this method to prepare custom OpenGL resources.
 -      fun create_gamnit
 +      fun create_gamnit do end
 +
 +      # Hook to prepare for recreating the OpenGL context
 +      #
 +      # Some gamnit services refine this method to reset caches before the
 +      # next call to `create_gamnit`.
 +      fun recreate_gamnit do end
 +
 +      # Create and set `self.display`
 +      fun create_display
        do
                var display = new GamnitDisplay
                display.setup
        # The framework handles resizing the viewport automatically.
        fun on_resize(display: GamnitDisplay) do end
  end
+ # Portable indirection to `glBindFramebuffer(gl_FRAMEBUFFER, fbo)`
+ #
+ # This is implemented differently on iOS.
+ fun bind_screen_framebuffer(fbo: Int) do glBindFramebuffer(gl_FRAMEBUFFER, fbo)
diff --combined lib/glesv2/glesv2.nit
@@@ -17,8 -17,8 +17,8 @@@
  # OpenGL graphics rendering library for embedded systems, version 2.0
  #
  # This is a low-level wrapper, it can be useful for developers already familiar
 -# with the C API of OpenGL. Most developers will prefer to use higher level
 -# wrappers such as `mnit` and `gammit`.
 +# with the C API of OpenGL. Most developers will prefer to use the higher level
 +# graphic API `gammit`.
  #
  # Defines the annotations `glsl_vertex_shader` and `glsl_fragment_shader`
  # applicable on string literals to check shader code using `glslangValidator`.
@@@ -41,7 -41,11 +41,11 @@@ import android::awar
  intrude import c
  
  in "C Header" `{
+ #ifdef __APPLE__
+       #include <OpenGLES/ES2/gl.h>
+ #else
        #include <GLES2/gl2.h>
+ #endif
  `}
  
  # OpenGL ES program to which we attach shaders
diff --combined tests/Darwin.skip
@@@ -1,3 -1,4 +1,3 @@@
 -mnit
  android
  java
  jvm
@@@ -7,3 -8,6 +7,6 @@@ emscripte
  ui_test
  readline
  postgres
+ test_nitcorn
+ test_annot_pkgconfig
+ test_glsl_validation