Property definitions

gamnit $ ParticleSystem :: defaultinit
# Particle system using `program` and `texture` to draw each particles
#
# Each instance draws a maximum of `n_particles`.
# If full, new particles replace the oldest particles.
# Expired particle are still sent to the CPU but should be discarded by the vertex shader.
class ParticleSystem

	# Maximum number of particles
	var n_particles: Int

	private var total_particles = 0

	# Program to draw the particles
	var program: ParticleProgram

	# Texture to apply on particles, if any
	var texture: nullable Texture

	# Clock used to set `ots` and `program::t`
	#
	# TODO control this value from the game logic to allow pausing and slowing time.
	private var clock = new Clock

	# Coordinates of each particle effects
	private var centers = new Array[Float]

	# Creation time of each particles
	private var ots = new Array[Float]

	# Scale of each particles
	private var scales = new Array[Float]

	# Time-to-live of each particle
	private var ttls = new Array[Float]

	# Clear all particles
	fun clear
	do
		centers.clear
		ots.clear
		scales.clear
		ttls.clear
		total_particles = 0
	end

	# Add a particle at `center` with `scale`, living for `ttl` from `time_offset`
	#
	# `time_offset` is added to the creation time, it can be used to delay the
	# apparition of a particle using a positive value.
	#
	# See the doc of the precise class of `program`, or the general `ParticleProgram`
	# for information on the effect of these parameters.
	fun add(center: Point3d[Float], scale: Float, ttl: Float, time_offset: nullable Float)
	do
		var i = total_particles % n_particles
		total_particles += 1

		centers[i*3  ] = center.x
		centers[i*3+1] = center.y
		centers[i*3+2] = center.z

		ttls[i] = ttl
		scales[i] = scale

		time_offset = time_offset or else 0.0
		ots[i] = clock.total.to_f + time_offset
	end

	# Draw all particles of this emitter
	fun draw
	do
		if ots.is_empty then return

		var program = program
		program.use

		var texture = texture
		if texture != null then
			glActiveTexture gl_TEXTURE0
			glBindTexture(gl_TEXTURE_2D, texture.gl_texture)
			program.use_texture.uniform true
			program.texture.uniform 0
		else
			program.use_texture.uniform false
		end

		program.scale.array_enabled = true
		program.scale.array(scales, 1)

		program.center.array_enabled = true
		program.center.array(centers, 3)

		program.color.array_enabled = false
		program.color.uniform(1.0, 1.0, 1.0, 1.0)

		program.ot.array_enabled = true
		program.ot.array(ots, 1)

		program.ttl.array_enabled = true
		program.ttl.array(ttls, 1)

		program.t.uniform clock.total.to_f
		program.mvp.uniform app.world_camera.mvp_matrix

		glDrawArrays(gl_POINTS, 0, ots.length)
	end
end
lib/gamnit/depth/particles.nit:57,1--163,3