1 /** 2 * Copyright: Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved 3 * Authors: $(Gabriel Gheorghe) 4 * License: $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007) 5 * Source: $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/framework/light/impl.d) 6 * Documentation: 7 * Coverage: 8 **/ 9 module liberty.framework.light.impl; 10 11 import liberty.framework.primitive.impl; 12 import liberty.framework.primitive.vertex; 13 import liberty.graphics.shader.constants; 14 import liberty.graphics.shader.impl; 15 import liberty.logger.impl; 16 import liberty.math.functions; 17 import liberty.math.transform; 18 import liberty.math.vector; 19 import liberty.scene.entity; 20 import liberty.scene.meta; 21 22 /** 23 * 24 **/ 25 final class Light : Entity { 26 mixin NodeBody; 27 28 private { 29 static uint numberOfLights; 30 31 uint index; 32 Vector3F color = Vector3F.one; 33 Vector3F attenuation = Vector3F(1.0f, 0.0f, 0.0f); 34 } 35 36 /** 37 * 38 **/ 39 this(string id) { 40 super(id); 41 register; 42 43 component!Transform 44 .setLocation(0.0f, 200.0f, 0.0f); 45 46 index = this.numberOfLights; 47 numberOfLights++; 48 49 scene.lightMap[id] = this; 50 } 51 52 ~this() { 53 this.numberOfLights--; 54 } 55 56 /** 57 * 58 * Returns reference to this so it can be used in a stream. 59 **/ 60 typeof(this) setColor(Vector3F color) { 61 this.color = color; 62 return this; 63 } 64 65 /** 66 * 67 **/ 68 Vector3F getColor() const { 69 return color; 70 } 71 72 /** 73 * 74 * Returns reference to this so it can be used in a stream. 75 **/ 76 typeof(this) setAttenuation(Vector3F attenuation) { 77 this.attenuation = attenuation; 78 return this; 79 } 80 81 /** 82 * 83 **/ 84 Vector3F getAttenuation() const { 85 return attenuation; 86 } 87 88 /** 89 * 90 **/ 91 uint getIndex() const { 92 return index; 93 } 94 95 /** 96 * Apply light to a primitive or terrain. 97 * Returns reference to this so it can be used in a stream. 98 **/ 99 typeof(this) applyTo(string shaderId) 100 in (shaderId == "Primitive" || shaderId == "Terrain", 101 "You can apply light only on primitives and terrains.") 102 do { 103 import std.conv : to; 104 105 if (index < 4) { 106 Shader 107 .getOrCreate(shaderId) 108 .getProgram 109 .loadUniform("uLightPosition[" ~ index.to!string ~ "]", component!Transform.getLocation) 110 .loadUniform("uLightColor[" ~ index.to!string ~ "]", color) 111 .loadUniform("uLightAttenuation[" ~ index.to!string ~ "]", attenuation) 112 .loadUniform("uShineDamper", 1.0f) 113 .loadUniform("uReflectivity", 0.0f); 114 } else 115 Logger.warning(shaderId ~ " shader can't render more than 4 lights.", typeof(this).stringof); 116 117 return this; 118 } 119 }