1 module re.gfx.lighting.rlights;
2 
3 import raylib;
4 
5 /**********************************************************************************************
6 *
7 *   raylib.lights - Some useful functions to deal with lights data
8 *
9 *   CONFIGURATION:
10 *
11 *   enum RLIGHTS_IMPLEMENTATION
12 *       Generates the implementation of the library into the included file.
13 *       If not defined, the library is in header only mode and can be included in other headers 
14 *       or source files without problems. But only ONE file should hold the implementation.
15 *
16 *   LICENSE: zlib/libpng
17 *
18 *   Copyright (c) 2017 Victor Fisac and Ramon Santamaria
19 *
20 *   This software is provided "as-is", without any express or implied warranty. In no event
21 *   will the authors be held liable for any damages arising from the use of this software.
22 *
23 *   Permission is granted to anyone to use this software for any purpose, including commercial
24 *   applications, and to alter it and redistribute it freely, subject to the following restrictions:
25 *
26 *     1. The origin of this software must not be misrepresented; you must not claim that you
27 *     wrote the original software. If you use this software in a product, an acknowledgment
28 *     in the product documentation would be appreciated but is not required.
29 *
30 *     2. Altered source versions must be plainly marked as such, and must not be misrepresented
31 *     as being the original software.
32 *
33 *     3. This notice may not be removed or altered from any source distribution.
34 *
35 **********************************************************************************************/
36 
37 //----------------------------------------------------------------------------------
38 // Defines and Macros
39 //----------------------------------------------------------------------------------
40 enum MAX_LIGHTS = 4; // max lights supported by shader
41 
42 //----------------------------------------------------------------------------------
43 // Types and Structures Definition
44 //----------------------------------------------------------------------------------
45 enum LightType {
46     LIGHT_DIRECTIONAL,
47     LIGHT_POINT
48 }
49 
50 struct Light {
51     int type;
52     Vector3 position;
53     Vector3 target;
54     Color color;
55     bool enabled;
56 
57     // Shader locations
58     int enabledLoc;
59     int typeLoc;
60     int posLoc;
61     int targetLoc;
62     int colorLoc;
63 }
64 
65 static int light_count = 0; // Current amount of created lights
66 
67 static Light set_light(int index, LightType type, Vector3 pos, Vector3 target,
68         Color color, Shader shader, bool enabled = true) {
69     Light light;
70 
71     light.enabled = enabled;
72     light.type = type;
73     light.position = pos;
74     light.target = target;
75     light.color = color;
76 
77     char[32] enabledName = "lights[x].enabled\0";
78     char[32] typeName = "lights[x].type\0";
79     char[32] posName = "lights[x].position\0";
80     char[32] targetName = "lights[x].target\0";
81     char[32] colorName = "lights[x].color\0";
82 
83     // Set location name [x] depending on lights count
84     enabledName[7] = cast(char)('0' + index);
85     typeName[7] = cast(char)('0' + index);
86     posName[7] = cast(char)('0' + index);
87     targetName[7] = cast(char)('0' + index);
88     colorName[7] = cast(char)('0' + index);
89 
90     light.enabledLoc = GetShaderLocation(shader, cast(char*) enabledName);
91     light.typeLoc = GetShaderLocation(shader, cast(char*) typeName);
92     light.posLoc = GetShaderLocation(shader, cast(char*) posName);
93     light.targetLoc = GetShaderLocation(shader, cast(char*) targetName);
94     light.colorLoc = GetShaderLocation(shader, cast(char*) colorName);
95 
96     UpdateLightValues(shader, light);
97 
98     return light;
99 }
100 
101 static void clear_light(int index, Shader shader) {
102     // reset the light
103     set_light(index, LightType.LIGHT_POINT, Vector3Zero, Vector3Zero, Colors.BLANK, shader, false);
104 }
105 
106 // Send light properties to shader
107 // NOTE: Light shader locations should be available 
108 void UpdateLightValues(Shader shader, Light light) {
109     // Send to shader light enabled state and type
110     SetShaderValue(shader, light.enabledLoc, &light.enabled,
111             raylib.ShaderUniformDataType.UNIFORM_INT);
112     SetShaderValue(shader, light.typeLoc, &light.type, raylib.ShaderUniformDataType.UNIFORM_INT);
113 
114     // Send to shader light position values
115     float[3] position = [light.position.x, light.position.y, light.position.z];
116     SetShaderValue(shader, light.posLoc, &position, raylib.ShaderUniformDataType.UNIFORM_VEC3);
117 
118     // Send to shader light target position values
119     float[3] target = [light.target.x, light.target.y, light.target.z];
120     SetShaderValue(shader, light.targetLoc, &target, raylib.ShaderUniformDataType.UNIFORM_VEC3);
121 
122     // Send to shader light color values
123     float[4] color = [
124         cast(float) light.color.r / cast(float) 255,
125         cast(float) light.color.g / cast(float) 255,
126         cast(float) light.color.b / cast(float) 255,
127         cast(float) light.color.a / cast(float) 255
128     ];
129     SetShaderValue(shader, light.colorLoc, &color, raylib.ShaderUniformDataType.UNIFORM_VEC4);
130 }