nitlanguage
/
nit.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
gamnit: don't use `sprites_to_update` after a GPU buffer resize
[nit.git]
/
lib
/
gamnit
/
flat.nit
diff --git
a/lib/gamnit/flat.nit
b/lib/gamnit/flat.nit
index
70d8c53
..
335bbd1
100644
(file)
--- a/
lib/gamnit/flat.nit
+++ b/
lib/gamnit/flat.nit
@@
-41,7
+41,8
@@
import more_collections
import performance_analysis
import gamnit
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
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
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
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
# 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
# Current context to which `self` belongs
private var sprite_set: nullable SpriteSet = null
end
@@
-293,9
+300,7
@@
redef class App
do
texture.load
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
ui_sprites.add splash
var display = display
@@
-373,6
+378,17
@@
redef class App
if display != null then display.close
end
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
redef fun frame_core(display)
do
# Check errors
@@
-582,12
+598,6
@@
private class Simple2dProgram
end
redef class Point3d[N]
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
# ---
# Associate each point to its sprites
@@
-638,6
+648,26
@@
redef class Point3d[N]
end
end
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]
# 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.sprites.add sprite
context.sprites_to_update.add sprite
+ context.last_sprite_to_update = sprite
sprite.context = context
sprite.sprite_set = self
sprite.context = context
sprite.sprite_set = self
@@
-744,11
+775,14
@@
private class SpriteContext
var usage: GLBufferUsage
# Sprites drawn by this context
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]
# 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]
# 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
# 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
# Vertices data
@@
-953,6
+990,7
@@
private class SpriteContext
glBindBuffer(gl_ELEMENT_ARRAY_BUFFER, buffer_element)
# Resize GPU buffers?
glBindBuffer(gl_ELEMENT_ARRAY_BUFFER, buffer_element)
# Resize GPU buffers?
+ var update_everything = false
if sprites.capacity > buffer_capacity then
# Try to defragment first
var moved = sprites.defragment
if sprites.capacity > buffer_capacity then
# Try to defragment first
var moved = sprites.defragment
@@
-962,6
+1000,7
@@
private class SpriteContext
resize
# We must update everything
resize
# We must update everything
+ update_everything = true
for s in sprites.items do if s != null then sprites_to_update.add s
else
# Just update the moved sprites
for s in sprites.items do if s != null then sprites_to_update.add s
else
# Just update the moved sprites
@@
-975,11
+1014,19
@@
private class SpriteContext
end
# Update GPU sprites data
end
# Update GPU sprites data
- if sprites_to_update.not_empty then
+ if sprites_to_update.not_empty or update_everything then
app.perf_clock_sprites.lapse
app.perf_clock_sprites.lapse
- for sprite in sprites_to_update do update_sprite(sprite)
+ if update_everything then
+ for sprite in sprites.items do if sprite != null then
+ update_sprite(sprite)
+ end
+ else
+ for sprite in sprites_to_update do update_sprite(sprite)
+ end
+
sprites_to_update.clear
sprites_to_update.clear
+ last_sprite_to_update = null
sys.perfs["gamnit flat gpu update"].add app.perf_clock_sprites.lapse
end
sys.perfs["gamnit flat gpu update"].add app.perf_clock_sprites.lapse
end
@@
-1145,9
+1192,6
@@
private class GroupedArray[E]
# Number of item slots in the array
fun capacity: Int do return items.length
# 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
# List of available slots
var available = new MinHeap[Int].default
@@
-1157,8
+1201,8
@@
private class GroupedArray[E]
# Index of the spots after filled chunks
var ends = new List[Int]
# 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
do
length += 1
@@
-1183,7
+1227,7
@@
private class GroupedArray[E]
# at end of first chunk
ends.first += 1
end
# at end of first chunk
ends.first += 1
end
- return
+ return i
end
items.add item
end
items.add item
@@
-1191,13
+1235,20
@@
private class GroupedArray[E]
starts.add 0
ends.add 1
else ends.last += 1
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
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
length -= 1
items[i] = null
@@
-1272,6
+1323,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]
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
remove e
add e
moved.add e
@@
-1304,6
+1356,20
@@
private class GroupedArray[E]
end
end
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
redef class GLfloatArray
private fun fill_from_matrix(matrix: Matrix, dst_offset: nullable Int)
do