gamnit: pass the elapsed time in the world of each sprite set to the shader
[nit.git] / lib / gamnit / flat.nit
index cbcc2e7..b70d010 100644 (file)
@@ -41,7 +41,8 @@ import more_collections
 import performance_analysis
 
 import gamnit
-import gamnit::cameras_cache
+intrude import gamnit::cameras
+intrude import gamnit::cameras_cache
 import gamnit::dynamic_resolution
 import gamnit::limit_fps
 import gamnit::camera_control
@@ -293,9 +294,7 @@ redef class App
        do
                texture.load
 
-               ui_camera.reset_height 1080.0
-
-               var splash = new Sprite(texture, ui_camera.center)
+               var splash = new Sprite(texture, ui_camera.center.offset(0.0, 0.0, 0.0))
                ui_sprites.add splash
 
                var display = display
@@ -373,11 +372,19 @@ redef class App
                if display != null then display.close
        end
 
-       redef fun frame_core(display)
+       redef fun on_resize(display)
        do
-               # Prepare to draw, clear buffers
-               glClear(gl_COLOR_BUFFER_BIT | gl_DEPTH_BUFFER_BIT)
+               super
 
+               world_camera.mvp_matrix_cache = null
+               ui_camera.mvp_matrix_cache = null
+
+               # Update all sprites in the UI
+               for sprite in ui_sprites do sprite.needs_update
+       end
+
+       redef fun frame_core(display)
+       do
                # Check errors
                var gl_error = glGetError
                assert gl_error == gl_NO_ERROR else print_error gl_error
@@ -386,6 +393,7 @@ redef class App
                perf_clock_main.lapse
                var dt = clock.lapse.to_f
                update dt
+               frame_dt = dt
                sys.perfs["gamnit flat update client"].add perf_clock_main.lapse
 
                # Draw and flip screen
@@ -397,6 +405,8 @@ redef class App
                assert gl_error == gl_NO_ERROR else print_error gl_error
        end
 
+       private var frame_dt = 0.0
+
        # Draw the whole screen, all `glDraw...` calls should be executed here
        protected fun frame_core_draw(display: GamnitDisplay)
        do
@@ -418,6 +428,9 @@ redef class App
                simple_2d_program.use
                simple_2d_program.mvp.uniform camera.mvp_matrix
 
+               sprite_set.time += frame_dt*sprite_set.time_mod
+               simple_2d_program.time.uniform sprite_set.time
+
                # draw
                sprite_set.draw
        end
@@ -500,6 +513,9 @@ private class Simple2dProgram
                // Model view projection matrix
                uniform mat4 mvp;
 
+               // Current world time, in seconds
+               uniform float time;
+
                // Rotation matrix
                attribute vec4 rotation_row0;
                attribute vec4 rotation_row1;
@@ -585,12 +601,6 @@ private class Simple2dProgram
 end
 
 redef class Point3d[N]
-       # Get a new `Point3d[Float]` with an offset of each axis of `x, y, z`
-       fun offset(x, y, z: Numeric): Point3d[Float]
-       do
-               return new Point3d[Float](self.x.to_f+x.to_f, self.y.to_f+y.to_f, self.z.to_f+z.to_f)
-       end
-
        # ---
        # Associate each point to its sprites
 
@@ -641,6 +651,26 @@ redef class Point3d[N]
        end
 end
 
+redef class OffsetPoint3d
+       redef fun x=(v)
+       do
+               if isset _x and v != x then needs_update
+               super
+       end
+
+       redef fun y=(v)
+       do
+               if isset _y and v != y then needs_update
+               super
+       end
+
+       redef fun z=(v)
+       do
+               if isset _z and v != z then needs_update
+               super
+       end
+end
+
 # Set of sprites sorting them into different `SpriteContext`
 private class SpriteSet
        super HashSet[Sprite]
@@ -654,6 +684,12 @@ private class SpriteSet
        # Sprites needing resorting in `contexts_map`
        var sprites_to_remap = new Array[Sprite]
 
+       # Animation speed multiplier (0.0 to pause, 1.0 for normal speed, etc.)
+       var time_mod = 1.0 is writable
+
+       # Seconds elapsed since the launch of the program, in world time responding to `time_mod`
+       var time = 0.0
+
        # Add a sprite to the appropriate context
        fun map_sprite(sprite: Sprite)
        do