Property definitions

gamnit $ SmoothMaterial :: defaultinit
# Simple material with static colors
class SmoothMaterial
	super Material

	# Ambient color, always visible
	#
	# The RGB values should be premultiplied by the alpha value.
	var ambient_color: Array[Float] is writable

	# Diffuse color when covered by a light source
	#
	# The RGB values should be premultiplied by the alpha value.
	var diffuse_color: Array[Float] is writable

	# Specular color affecting reflections
	#
	# The RGB values should be premultiplied by the alpha value.
	var specular_color: Array[Float] is writable

	redef fun draw(actor, model, camera)
	do
		var program = app.blinn_phong_program
		program.use
		program.mvp.uniform camera.mvp_matrix

		var mesh = model.mesh

		# Actor specs
		glDisableVertexAttribArray program.translation.location
		glDisableVertexAttribArray program.scale.location

		program.translation.uniform(actor.center.x, actor.center.y, actor.center.z, 0.0)
		program.scale.uniform actor.scale
		program.alpha.uniform actor.alpha
		program.rotation = new Matrix.gamnit_euler_rotation(actor.pitch, actor.yaw, actor.roll)

		# From mesh
		program.coord.array_enabled = true
		program.coord.array(mesh.vertices, 3)

		program.normal.array_enabled = true
		program.normal.array(mesh.normals, 3)

		# No textures
		program.use_map_ambient.uniform false
		program.use_map_diffuse.uniform false
		program.use_map_specular.uniform false
		program.tex_coord.array_enabled = false

		# Camera
		program.camera.uniform(camera.position.x, camera.position.y, camera.position.z)

		# Colors from the material
		program.ambient_color.uniform(ambient_color[0], ambient_color[1],
		                              ambient_color[2], ambient_color[3])
		program.diffuse_color.uniform(diffuse_color[0], diffuse_color[1],
		                              diffuse_color[2], diffuse_color[3])
		program.specular_color.uniform(specular_color[0], specular_color[1],
		                               specular_color[2], specular_color[3])

		setup_lights(camera, program)

		# Execute draw
		if mesh.indices.is_empty then
			glDrawArrays(mesh.draw_mode, 0, mesh.vertices.length/3)
		else
			glDrawElements(mesh.draw_mode, mesh.indices.length, gl_UNSIGNED_SHORT, mesh.indices_c.native_array)
		end

		assert glGetError == gl_NO_ERROR
	end

	private fun setup_lights(camera: Camera, program: BlinnPhongProgram)
	do
		# TODO use a list of lights

		# Light, for Lambert and Blinn-Phong
		var light = app.light
		if light isa ParallelLight then
			program.light_kind.uniform 1

			# Vector parallel to the light source
			program.light_center.uniform(
				-light.pitch.sin * light.yaw.sin,
				light.pitch.cos,
				-light.yaw.cos)
		else if light isa PointLight then
			program.light_kind.uniform 2

			# Position of the light source
			program.light_center.uniform(app.light.position.x, app.light.position.y, app.light.position.z)
		else
			program.light_kind.uniform 0
		end

		# Draw projected shadows?
		if not light isa LightCastingShadows or not app.shadow_depth_texture_available then
			program.use_shadows.uniform false
			return
		else program.use_shadows.uniform true

		# Light point of view
		program.light_mvp.uniform light.camera.mvp_matrix

		# Depth texture
		glActiveTexture gl_TEXTURE4
		glBindTexture(gl_TEXTURE_2D, app.shadow_context.depth_texture)
		program.depth_texture.uniform 4
		program.depth_texture_size.uniform app.shadow_resolution.to_f
		program.depth_texture_taps.uniform 2 # TODO make configurable
	end
end
lib/gamnit/depth/more_materials.nit:31,1--142,3