1 module evael.graphics.Environment; 2 3 import evael.graphics.GL; 4 5 import evael.graphics.GraphicsDevice; 6 import evael.graphics.shaders.BasicLightShader; 7 import evael.graphics.lights; 8 9 import evael.utils.Math; 10 11 import dnogc.DynamicArray; 12 13 /** 14 * Environment. 15 */ 16 class Environment 17 { 18 enum MAX_POINTS_LIGHTS = 50; 19 20 private GraphicsDevice m_graphicsDevice; 21 22 /// Ambient light 23 private AmbientLight m_ambientLight; 24 25 /// Sun 26 private DirectionalLight m_sun; 27 28 private mat4 m_sunProjection; 29 private mat4 m_sunView; 30 31 /// Lights 32 private DynamicArray!PointLight m_pointsLights; 33 34 /** 35 * Environment constructor. 36 * Params: 37 * graphics : graphics device 38 */ 39 @nogc @safe 40 public this(GraphicsDevice graphics) pure nothrow 41 { 42 this.m_graphicsDevice = graphics; 43 44 this.m_sunProjection = orthoMatrix(-300.0f, 300.0f, -300.0f, 300.0f, -300.0f, 300.0f); 45 } 46 47 /** 48 * Environment destructor. 49 */ 50 public void dispose() 51 { 52 this.m_pointsLights.dispose(); 53 } 54 55 /** 56 * Adds a point light to the scene. 57 * Params: 58 * light : point light 59 */ 60 @nogc @safe 61 public void addPointLight(PointLight light) pure nothrow 62 { 63 this.m_pointsLights ~= light; 64 } 65 66 67 /** 68 * Sets environment for the next frame. 69 */ 70 @nogc 71 public void set() nothrow 72 { 73 this.setSun(); 74 this.setPointsLights(); 75 this.setAmbientLight(); 76 } 77 78 /** 79 * Sets sun. 80 */ 81 @nogc 82 private void setSun() nothrow 83 { 84 auto lightShader = cast(BasicLightShader) this.m_graphicsDevice.currentShader; 85 86 gl.Uniform3fv(lightShader.dirLightDirectionLocation, 1, this.m_sun.direction.arrayof.ptr); 87 gl.Uniform3fv(lightShader.dirLightAmbientLocation, 1, this.m_sun.ambient.arrayof.ptr); 88 gl.Uniform3fv(lightShader.dirLightDiffuseLocation, 1, this.m_sun.diffuse.arrayof.ptr); 89 gl.Uniform3fv(lightShader.dirLightSpecularLocation, 1, this.m_sun.specular.arrayof.ptr); 90 } 91 92 /** 93 * Sets ambient light. 94 */ 95 @nogc 96 private void setAmbientLight() nothrow 97 { 98 auto lightShader = cast(BasicLightShader) this.m_graphicsDevice.currentShader; 99 100 gl.Uniform3fv(lightShader.ambientLightValueLocation, 1, this.m_ambientLight.value.arrayof.ptr); 101 } 102 103 /** 104 * Sets points lights. 105 */ 106 @nogc 107 private void setPointsLights() nothrow 108 { 109 if (this.m_pointsLights.length == 0) 110 return; 111 112 auto lightShader = cast(BasicLightShader) this.m_graphicsDevice.currentShader; 113 114 gl.Uniform1i(lightShader.pointsLightsNumberLocation, this.m_pointsLights.length); 115 116 foreach (i, light; this.m_pointsLights) 117 { 118 gl.Uniform3fv(lightShader.pointsLightsLocation + (i * 1), 1, light.position.arrayof.ptr); 119 gl.Uniform3fv(lightShader.pointsLightsLocation + MAX_POINTS_LIGHTS + (i * 1), 1, light.color.arrayof.ptr); 120 gl.Uniform1f(lightShader.pointsLightsLocation + MAX_POINTS_LIGHTS * 2 + (i * 1), light.ambient); 121 gl.Uniform1f(lightShader.pointsLightsLocation + MAX_POINTS_LIGHTS * 3 + (i * 1), light.constant); 122 gl.Uniform1f(lightShader.pointsLightsLocation + MAX_POINTS_LIGHTS * 4 + (i * 1), light.linear); 123 gl.Uniform1f(lightShader.pointsLightsLocation + MAX_POINTS_LIGHTS * 5 + (i * 1), light.quadratic); 124 gl.Uniform1i(lightShader.pointsLightsLocation + MAX_POINTS_LIGHTS * 6 + (i * 1), light.isEnabled); 125 } 126 } 127 128 @nogc @safe 129 @property pure nothrow 130 { 131 public void sun(DirectionalLight value) 132 { 133 this.m_sun = value; 134 } 135 136 public DirectionalLight sun() 137 { 138 return this.m_sun; 139 } 140 141 public void ambientLight(AmbientLight value) 142 { 143 this.m_ambientLight = value; 144 } 145 146 public AmbientLight ambientLight() 147 { 148 return this.m_ambientLight; 149 } 150 151 public void sunView()(in auto ref mat4 value) 152 { 153 this.m_sunView = value; 154 } 155 156 public mat4 sunView() 157 { 158 return this.m_sunView; 159 } 160 161 public DynamicArray!PointLight pointsLights() 162 { 163 return this.m_pointsLights; 164 } 165 } 166 }