Property definitions

gamnit $ ParticleProgram :: defaultinit
# Particle drawing program using `gl_POINTS`
#
# This program should be subclassed to create custom particle effects.
# Either `vertex_shader_source` and `vertex_shader_core` can be refined.
class ParticleProgram
	super GamnitProgramFromSource

	redef var vertex_shader_source = """
		// Coordinates of particle effects
		attribute vec4 center;

		// Particles color tint
		attribute vec4 color;
		varying vec4 v_color;

		// Per particle scaling
		attribute float scale;

		// Model view projection matrix
		uniform mat4 mvp;

		// Time-to-live of each particle
		attribute float ttl;

		// Creation time of each particle
		attribute float ot;

		// Current time
		uniform float t;

		void main()
		{
			// Pass varyings to the fragment shader
			v_color = color;

			float dt = t - ot;
			float pt = dt/ttl;

			// Discard expired or not yet created particles
			if (dt > ttl || dt < 0.0) {
				gl_PointSize = 0.0;
				return;
			}

			{{{vertex_shader_core}}}
		}
		"""

	# Core GLSL code for `vertex_shader_source`
	#
	# Refine this function to easily tweak the position, size and color of particles.
	#
	# Reminder: Each execution of the vertex shader applies to a single particle.
	#
	# ## Input variables:
	# * `center`: reference coordinates of the particle effect.
	#   This if often the center of the particle itself,
	#   but it can also be reference coordinates for a moving particle.
	# * `mvp`: model-view-projection matrix.
	# * `color`: color tint of the particle.
	#
	# * `t`: global seconds counter since the creation of this particle emitter.
	# * `ot`: creation time of the particle, in seconds, in reference to `t`.
	# * `dt`: seconds since creation of the particle.
	# * `ttl`: time-to-live of the particle, in seconds.
	# * `pt`: advancement of this particle in its lifetime, in `[0.0 .. 1.0]`.
	#
	# ## Output variables:
	# * `gl_Position`: position of the particle in camera coordinates.
	# * `gl_PointSize`: size of the particle in camera coordinates.
	#   Set to `0.0` to discard the particle.
	# * `v_color`: tint applied to the particle.
	#   Assigned by default to the value of `color`.
	#
	# ## Reference implementation
	#
	# The default implementation apply the model-view-projection matrix on the position
	# and scales according to the distance from the camera.
	# Most particle effects should apply the same base logic as the default implementation.
	# Here it is for reference:
	#
	# ~~~glsl
	# gl_Position = center * mvp;
	# gl_PointSize = scale / gl_Position.z;
	# ~~~
	fun vertex_shader_core: String do return """
			gl_Position = center * mvp;
			gl_PointSize = scale / gl_Position.z;
	"""

	redef var fragment_shader_source = """
		precision mediump float;

		// Input from the vertex shader
		varying vec4 v_color;

		// Does this particle use a texture?
		uniform bool use_texture;

		// Texture to apply on this particle
		uniform sampler2D texture0;

		void main()
		{
			if (use_texture) {
				gl_FragColor = texture2D(texture0, gl_PointCoord) * v_color;
			} else {
				gl_FragColor = v_color;
			}
		}
		""" @ glsl_fragment_shader

	# Coordinates of particle effects
	var center = attributes["center"].as(AttributeVec4) is lazy

	# Should this program use the texture `texture`?
	var use_texture = uniforms["use_texture"].as(UniformBool) is lazy

	# Visible texture unit
	var texture = uniforms["texture0"].as(UniformSampler2D) is lazy

	# Color tint per vertex
	var color = attributes["color"].as(AttributeVec4) is lazy

	# Scaling per vertex
	var scale = attributes["scale"].as(AttributeFloat) is lazy

	# Model view projection matrix
	var mvp = uniforms["mvp"].as(UniformMat4) is lazy

	# Creation time of each particle
	var ot = attributes["ot"].as(AttributeFloat) is lazy

	# Current time
	var t = uniforms["t"].as(UniformFloat) is lazy

	# Time-to-live of each particle
	var ttl = attributes["ttl"].as(AttributeFloat) is lazy
end
lib/gamnit/depth/particles.nit:165,1--303,3