Merge: gamnit: distinguish between `create_gamnit` and `create_scene`
authorJean Privat <jean@pryen.org>
Thu, 23 Nov 2017 16:12:58 +0000 (11:12 -0500)
committerJean Privat <jean@pryen.org>
Thu, 23 Nov 2017 16:12:58 +0000 (11:12 -0500)
Intro `create_gamnit` and `create_scene` to replace the use of `on_create` in gamnit. This change keeps separate the OpenGL setup in `create_gamnit`, from the world/menu creation in `create_scene`. This will allow support for reinitializing the OpenGL context when the EGL context is lost, which may happen on Android when the game goes in the background. It may also support creating a gamnit game separately from the main application.

Current gamnit games should still work despite the API change, but they will need updating to work with the incoming Android support.

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

18 files changed:
contrib/asteronits/src/asteronits.nit
contrib/asteronits/src/touch_ui.nit
lib/gamnit/bmfont.nit
lib/gamnit/depth/cardboard.nit
lib/gamnit/depth/depth.nit
lib/gamnit/depth/depth_core.nit
lib/gamnit/depth/more_materials.nit
lib/gamnit/depth/shadow.nit
lib/gamnit/dynamic_resolution.nit
lib/gamnit/egl.nit
lib/gamnit/examples/fonts_showcase/src/fonts_showcase.nit
lib/gamnit/examples/template/src/template.nit
lib/gamnit/examples/triangle/src/portable_triangle.nit
lib/gamnit/flat/flat_core.nit
lib/gamnit/gamnit.nit
lib/gamnit/gamnit_linux.nit
lib/gamnit/textures.nit
lib/gamnit/virtual_gamepad/virtual_gamepad.nit

index d7621de..cc9f6a8 100644 (file)
@@ -64,7 +64,7 @@ redef class App
        private var fx_explosion_ship = new Sound("sounds/explosion_ship.wav")
        private var fx_explosion_asteroids = new Sound("sounds/explosion_asteroids.wav")
 
-       redef fun on_create
+       redef fun create_scene
        do
                super
 
index 5cae0d4..2264f28 100644 (file)
@@ -20,7 +20,7 @@ import gamnit::virtual_gamepad
 import asteronits
 
 redef class App
-       redef fun on_create
+       redef fun create_scene
        do
                super
 
index cdeef2d..d052922 100644 (file)
@@ -283,7 +283,7 @@ end
 #     var pos: Point3d[Float] = ui_camera.top_left.offset(128.0, -128.0, 0.0)
 #     var ui_text = new TextSprites(font, pos)
 #
-#     redef fun on_create
+#     redef fun create_scene
 #     do
 #         super
 #
index ccecf15..35c0f76 100644 (file)
@@ -80,7 +80,7 @@ redef class App
                end
        end
 
-       redef fun on_create
+       redef fun create_scene
        do
                super
                initialize_head_tracker
index 1230c4a..2e4fc82 100644 (file)
@@ -25,14 +25,19 @@ import shadow
 
 redef class App
 
-       redef fun on_create
+       redef fun create_scene
        do
-               super
-
                # Move the camera back a bit
                world_camera.reset_height(10.0)
                world_camera.near = 0.1
 
+               super
+       end
+
+       redef fun create_gamnit
+       do
+               super
+
                # Cull the invisible triangles in the back of the geometries
                glCullFace gl_BACK
 
@@ -65,6 +70,7 @@ redef class App
                for actor in actors do
                        for leaf in actor.model.leaves do
                                leaf.material.draw(actor, leaf, app.world_camera)
+                               assert glGetError == gl_NO_ERROR else print_error "Gamnit error on material {leaf.material.class_name}"
                        end
                end
                perfs["gamnit depth actors"].add frame_core_depth_clock.lapse
@@ -74,7 +80,10 @@ redef class App
 
                # Toggle writing to the depth buffer for particles effects
                glDepthMask false
-               for system in particle_systems do system.draw
+               for system in particle_systems do
+                       system.draw
+                       assert glGetError == gl_NO_ERROR else print_error "OpenGL error in {system}"
+               end
                glDepthMask true
                perfs["gamnit depth particles"].add frame_core_depth_clock.lapse
 
index 588b321..0e45e3d 100644 (file)
@@ -84,7 +84,7 @@ end
 
 # 3D model composed of `Mesh` and `Material`, loaded from the assets folder by default
 #
-# Instances can be created at any time and must be loaded after or at the end of `on_create`.
+# Instances can be created at any time and must be loaded after or at the end of `create_scene`.
 # If loading fails, the model is replaced by `placeholder_model`.
 #
 # ~~~
index 2546da3..8de6f9d 100644 (file)
@@ -93,6 +93,8 @@ class SmoothMaterial
                else
                        glDrawElements(mesh.draw_mode, mesh.indices.length, gl_UNSIGNED_SHORT, mesh.indices_c.native_array)
                end
+
+               assert glGetError == gl_NO_ERROR
        end
 
        private fun setup_lights(actor: Actor, model: LeafModel, camera: Camera, program: BlinnPhongProgram)
index 213b461..d65a3cb 100644 (file)
@@ -52,7 +52,7 @@ redef class App
 
        private var perf_clock_shadow = new Clock is lazy
 
-       redef fun on_create
+       redef fun create_gamnit
        do
                super
 
index fb78730..7399dd9 100644 (file)
@@ -54,7 +54,7 @@ redef class App
 
        private var perf_clock_dynamic_resolution = new Clock is lazy
 
-       redef fun on_create
+       redef fun create_scene
        do
                super
 
index 59a0aa3..b0f756f 100644 (file)
@@ -110,6 +110,10 @@ redef class GamnitDisplay
 
        redef fun flip
        do
+               assert glGetError == gl_NO_ERROR
+
+               assert egl_display.is_valid
+
                egl_display.swap_buffers(window_surface)
        end
 end
index 33a342c..10ba0b4 100644 (file)
@@ -28,7 +28,7 @@ redef class App
        # Bottom right corner
        var corner = new Texture("corner.png")
 
-       redef fun on_create
+       redef fun create_scene
        do
                super
 
index a0f37a0..8bd28fd 100644 (file)
@@ -17,7 +17,7 @@ import gamnit::flat # The 2D API, use `gamnit::depth` for 3D
 
 redef class App
 
-       # Texture, loaded automatically at `on_create`
+       # Texture, loaded in `create_scene`
        var texture = new Texture("fighter.png")
 
        # Sound effect, lazy loaded at first use
@@ -26,7 +26,7 @@ redef class App
        # Sprite, must be loaded in or after `on_create`
        var sprite = new Sprite(texture, new Point3d[Float](0.0, 0.0, 0.0)) is lazy
 
-       redef fun on_create
+       redef fun create_scene
        do
                super
 
@@ -52,7 +52,7 @@ redef class App
                # Scale the ship so it is approximately 5 world units wide.
                sprite.scale = 5.0 / texture.width
 
-               # Move the camera to show 10 world units on the Y axis at Z = 0.
+               # Move the camera to show 20 world units on the Y axis at Z = 0.
                # The `sprite` should take approximately 1/4 of the height of the screen.
                world_camera.reset_height 20.0
 
index 9dfa49c..21492ad 100644 (file)
@@ -39,7 +39,7 @@ redef class App
        # Vertex data for the triangle
        var vertex_array: VertexArray is noautoinit
 
-       redef fun on_create
+       redef fun create_scene
        do
                super
 
index dcb11f6..2ab18f6 100644 (file)
@@ -417,10 +417,15 @@ redef class App
        # Second performance clock for smaller operations
        private var perf_clock_sprites = new Clock is lazy
 
-       redef fun on_create
+       redef fun create_gamnit
        do
                super
+               create_flat
+       end
 
+       # Prepare the flat framework services
+       fun create_flat
+       do
                var display = display
                assert display != null
 
@@ -459,10 +464,15 @@ redef class App
                        glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR)
                        glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR)
                end
+
+               sprites.reset
+               ui_sprites.reset
        end
 
        redef fun on_stop
        do
+               super
+
                # Clean up
                simple_2d_program.delete
 
@@ -532,6 +542,8 @@ redef class App
 
                # draw
                sprite_set.draw
+
+               assert glGetError == gl_NO_ERROR
        end
 
        # Draw world sprites from `sprites`
@@ -963,7 +975,7 @@ class SpriteSet
                for sprite in sprites_to_remap do
 
                        # Skip if it was removed from this set after being modified
-                       if sprite.context != self then continue
+                       if sprite.sprite_set != self then continue
 
                        unmap_sprite sprite
                        map_sprite sprite
@@ -1003,6 +1015,23 @@ class SpriteSet
                for c in contexts_items do c.destroy
                contexts_map.clear
                contexts_items.clear
+               sprites_to_remap.clear
+       end
+
+       private fun reset
+       do
+               for sprite in self do
+                       sprite.context = null
+               end
+
+               for c in contexts_items do c.destroy
+               contexts_map.clear
+               contexts_items.clear
+               sprites_to_remap.clear
+
+               for sprite in self do
+                       map_sprite sprite
+               end
        end
 end
 
index bd26cbd..3051553 100644 (file)
@@ -26,13 +26,15 @@ import gamnit_linux is conditional(linux)
 
 redef class App
 
-       # Main `GamnitDisplay` initialized by `on_create`
+       # Main `GamnitDisplay` initialized by `create_gamnit`
        var display: nullable GamnitDisplay = null
 
-       redef fun on_create
+       # Hook to setup the OpenGL context: compiling shaders, creating VBO, reloading textures, etc.
+       #
+       # 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
        do
-               super
-
                var display = new GamnitDisplay
                display.setup
                self.display = display
@@ -45,6 +47,15 @@ redef class App
                print "GL extensions: {glGetString(gl_EXTENSIONS)}"
        end
 
+       # Hook for client programs to setup the scene
+       #
+       # Refine this method to build the game world or the main menu,
+       # creating instances of `Sprite` and `Actor` as needed.
+       #
+       # This method is called only once per execution of the program and it should
+       # be considered as the entry point of most game logic.
+       fun create_scene do end
+
        # Core of the frame logic, executed only when the display is visible
        #
        # This method should be redefined by user modules to customize the behavior of the game.
index b86f8e5..3818878 100644 (file)
@@ -46,6 +46,13 @@ redef class App
                        accept_event gamnit_event
                end
        end
+
+       redef fun on_create
+       do
+               super
+               create_gamnit
+               create_scene
+       end
 end
 
 redef class GamnitDisplay
index 2aa405d..60cec5a 100644 (file)
@@ -20,7 +20,7 @@ import display
 # Texture composed of pixels, loaded from the assets folder by default
 #
 # Most textures should be created with `App` (as attributes)
-# for the method `on_create` to load them.
+# for the method `create_scene` to load them.
 #
 # ~~~
 # import gamnit::flat
@@ -29,9 +29,9 @@ import display
 #     # Create the texture object, it will be loaded automatically
 #     var texture = new Texture("path/in/assets.png")
 #
-#     redef fun on_create()
+#     redef fun create_scene()
 #     do
-#         # Let `on_create` load the texture
+#         # Let `create_scene` load the texture
 #         super
 #
 #         # Use the texture
@@ -41,7 +41,7 @@ import display
 # end
 # ~~~
 #
-# Otherwise, they can be loaded and error checked explicitly after `on_create`.
+# Otherwise, they can be loaded and error checked explicitly after `create_scene`.
 #
 # ~~~nitish
 # var texture = new Texture("path/in/assets.png")
index f5b6bec..fb1920d 100644 (file)
@@ -25,7 +25,7 @@
 #
 # ~~~
 # redef class App
-#     redef fun on_create
+#     redef fun create_scene
 #     do
 #         super
 #