X-Git-Url: http://nitlanguage.org diff --git a/lib/gamnit/flat.nit b/lib/gamnit/flat.nit index 70d8c53..85c702c 100644 --- a/lib/gamnit/flat.nit +++ b/lib/gamnit/flat.nit @@ -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 @@ -234,7 +235,10 @@ class Sprite fun needs_update do var c = context - if c != null then c.sprites_to_update.add self + if c == null then return + if c.last_sprite_to_update == self then return + c.sprites_to_update.add self + c.last_sprite_to_update = self end # Request a resorting of this sprite in its sprite list @@ -252,6 +256,9 @@ class Sprite # Current context to which `self` was sorted private var context: nullable SpriteContext = null + # Index in `context` + private var context_index: Int = -1 + # Current context to which `self` belongs private var sprite_set: nullable SpriteSet = null end @@ -293,9 +300,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,6 +378,17 @@ redef class App if display != null then display.close end + redef fun on_resize(display) + do + 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 @@ -582,12 +598,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 @@ -638,6 +648,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] @@ -669,6 +699,7 @@ private class SpriteSet context.sprites.add sprite context.sprites_to_update.add sprite + context.last_sprite_to_update = sprite sprite.context = context sprite.sprite_set = self @@ -744,11 +775,14 @@ private class SpriteContext var usage: GLBufferUsage # Sprites drawn by this context - var sprites = new GroupedArray[Sprite] + var sprites = new GroupedSprites # Sprites to update since last `draw` var sprites_to_update = new Set[Sprite] + # Cache of the last `Sprite` added to `sprites_to_update` since the last call to `draw` + var last_sprite_to_update: nullable Sprite = null + # Sprites that have been update and for which `needs_update` can be set to false var updated_sprites = new Array[Sprite] @@ -854,8 +888,11 @@ private class SpriteContext # Update GPU data of `sprite` fun update_sprite(sprite: Sprite) do - var sprite_index = sprites.index_of(sprite) - if sprite_index == -1 then return + var context = sprite.context + if context != self then return + + var sprite_index = sprite.context_index + assert sprite_index != -1 # Vertices data @@ -980,6 +1017,7 @@ private class SpriteContext for sprite in sprites_to_update do update_sprite(sprite) sprites_to_update.clear + last_sprite_to_update = null sys.perfs["gamnit flat gpu update"].add app.perf_clock_sprites.lapse end @@ -1145,9 +1183,6 @@ private class GroupedArray[E] # Number of item slots in the array fun capacity: Int do return items.length - # Index of `item` - fun index_of(item: E): Int do return items.index_of(item) - # List of available slots var available = new MinHeap[Int].default @@ -1157,8 +1192,8 @@ private class GroupedArray[E] # Index of the spots after filled chunks var ends = new List[Int] - # Add `item` to the first available slot - fun add(item: E) + # Add `item` to the first available slot and return its index + fun add(item: E): Int do length += 1 @@ -1183,7 +1218,7 @@ private class GroupedArray[E] # at end of first chunk ends.first += 1 end - return + return i end items.add item @@ -1191,13 +1226,20 @@ private class GroupedArray[E] starts.add 0 ends.add 1 else ends.last += 1 + return ends.last - 1 end # Remove the first instance of `item` fun remove(item: E) do - var i = items.index_of(item) - assert i != -1 + var index = items.index_of(item) + remove_at(item, index) + end + + # Remove `item` at `index` + fun remove_at(item: E, index: Int) + do + var i = index length -= 1 items[i] = null @@ -1272,6 +1314,7 @@ private class GroupedArray[E] while max > 0 and (starts.length > 1 or starts.first != 0) do var i = ends.last - 1 var e = items[i] + assert e != null remove e add e moved.add e @@ -1304,6 +1347,20 @@ private class GroupedArray[E] end end +# Optimized `GroupedArray` to use `Sprite::context_index` and avoid using `index_of` +private class GroupedSprites + super GroupedArray[Sprite] + + redef fun add(item) + do + var index = super + item.context_index = index + return index + end + + redef fun remove(item) do remove_at(item, item.context_index) +end + redef class GLfloatArray private fun fill_from_matrix(matrix: Matrix, dst_offset: nullable Int) do