1 module nudsfml.graphics.glsl; 2 3 import nudsfml.graphics.color; 4 import nudsfml.graphics.transform; 5 6 import nudsfml.system.vector2; 7 import nudsfml.system.vector3; 8 9 import std.traits; 10 11 /// 2D float vector (vec2 in GLSL) 12 alias Vec2 = Vector2!(float); 13 /// 2D int vector (ivec2 in GLSL) 14 alias Ivec2 = Vector2!(int); 15 /// 2D bool vector (bvec2 in GLSL) 16 alias Bvec2 = Vector2!(bool); 17 /// 3D float vector (vec3 in GLSL) 18 alias Vec3 = Vector3!(float); 19 /// 3D int vector (ivec3 in GLSL) 20 alias Ivec3 = Vector3!(int); 21 /// 3D bool vector (bvec3 in GLSL) 22 alias Bvec3 = Vector3!(bool); 23 24 /** 25 * 4D float vector (vec4 in GLSL) 26 * 27 * 4D float vectors can be converted from sf::Color instances. Each color 28 * channel is normalized from integers in [0, 255] to floating point values 29 * in [0, 1]. 30 * --- 31 * Vec4 zeroVector; 32 * auto vector = Vec4(1.f, 2.f, 3.f, 4.f); 33 * auto color = Vec4(Color.Cyan); 34 * --- 35 */ 36 alias Vec4 = Vector4!(float); 37 /** 38 * 4D int vector ( ivec4 in GLSL) 39 * 40 * 4D int vectors can be converted from sf::Color instances. Each color channel 41 * remains unchanged inside the integer interval [0, 255]. 42 * $(LI test) 43 * --- 44 * Ivec4 zeroVector; 45 * auto vector = Ivec4(1, 2, 3, 4); 46 * auto color = Ivec4(Color.Cyan); 47 * --- 48 */ 49 alias Ivec4 = Vector4!(int); 50 51 /// 4D bool vector (bvec4 in GLSL) 52 alias Bvec4 = Vector4!(bool); 53 54 /** 55 * 3x3 float matrix (mat3 in GLSL) 56 * 57 * The matrix can be constructed from an array with 3x3 elements, aligned in 58 * column-major order. For example,a translation by (x, y) looks as follows: 59 * --- 60 * float[9] array = 61 * [ 62 * 1, 0, 0, 63 * 0, 1, 0, 64 * x, y, 1 65 * ]; 66 * 67 * auto matrix = Mat3(array); 68 * --- 69 * 70 * $(PARA Mat4 can also be converted from a $(TRANSFORM_LINK Transform).) 71 * --- 72 * Transform transform; 73 * auto matrix = Mat3(transform); 74 * --- 75 */ 76 alias Mat3 = Matrix!(3,3); 77 78 /** 79 * 4x4 float matrix (mat4 in GLSL) 80 * 81 * The matrix can be constructed from an array with 4x4 elements, aligned in 82 * column-major order. For example, a translation by (x, y, z) looks as follows: 83 * --- 84 * float array[16] = 85 * { 86 * 1, 0, 0, 0, 87 * 0, 1, 0, 0, 88 * 0, 0, 1, 0, 89 * x, y, z, 1 90 * }; 91 * 92 * auto matrix = Mat4(array); 93 * --- 94 * 95 * $(PARA Mat4 can also be converted from a $(TRANSFORM_LINK Transform).) 96 * --- 97 * Transform transform; 98 * auto matrix = Mat4(transform); 99 * --- 100 */ 101 alias Mat4 = Matrix!(4,4); 102 103 /** 104 * 4D vector type, used to set uniforms in GLSL. 105 */ 106 struct Vector4(T) 107 if(isNumeric!(T) || is(T == bool)) 108 { 109 /// 1st component (X) of the 4D vector 110 T x; 111 /// 2nd component (Y) of the 4D vector 112 T y; 113 /// 3rd component (Z) of the 4D vector 114 T z; 115 /// 4th component (W) of the 4D vector 116 T w; 117 118 /** 119 * Construct from 4 vector components 120 * 121 * Params: 122 * X = Component of the 4D vector 123 * Y = Component of the 4D vector 124 * Z = Component of the 4D vector 125 * W = Component of the 4D vector 126 */ 127 this(T X, T Y, T Z, T W) 128 { 129 x = X; 130 y = Y; 131 z = Z; 132 w = W; 133 } 134 135 /** 136 * Conversion constructor 137 * 138 * Params: 139 * other = 4D vector of different type 140 */ 141 this(U)(Vector!(U) other) 142 { 143 x = cast(T)other.x; 144 y = cast(T)other.y; 145 z = cast(T)other.z; 146 w = cast(T)other.w; 147 } 148 149 /** 150 * Construct vector from color. 151 * 152 * The vector values are normalized to [0, 1] for floats, and left as-is for 153 * ints. 154 * 155 * Params: 156 * source = The Color instance to create the vector from 157 */ 158 this(Color source) 159 { 160 static if(is(T == float)) 161 { 162 x = source.r / 255f; 163 y = source.g / 255f; 164 z = source.b / 255f; 165 w = source.a / 255f; 166 } 167 else static if(is(T == int)) 168 { 169 x = cast(T)source.r; 170 y = cast(T)source.g; 171 z = cast(T)source.b; 172 w = cast(T)source.a; 173 } 174 } 175 } 176 177 /** 178 * Matrix type, used to set uniforms in GLSL. 179 */ 180 struct Matrix(uint C, uint R) 181 { 182 /// Array holding matrix data. 183 float[C * R] array; 184 185 /** 186 * Construct from DSFML transform. 187 * 188 * This constructor is only supported for 3x3 and 4x4 matrices. 189 * 190 * Params: 191 * source = A DSFML Transform 192 */ 193 this(ref const(Transform) source) 194 { 195 static assert(C == R && (C == 3 || C == 4), 196 "This constructor is only supported for 3x3 and 4x4 matrices."); 197 198 const(float)[] from = source.getMatrix(); 199 200 static if(C == 3) 201 { 202 float[] to = array; // 3x3 203 // Use only left-upper 3x3 block (for a 2D transform) 204 to[0] = from[ 0]; to[1] = from[ 1]; to[2] = from[ 3]; 205 to[3] = from[ 4]; to[4] = from[ 5]; to[5] = from[ 7]; 206 to[6] = from[12]; to[7] = from[13]; to[8] = from[15]; 207 } 208 else static if(C == 4) 209 { 210 array[] = from[]; 211 } 212 } 213 214 /** 215 * Construct from raw data. 216 * 217 * The elements in source are copied to the instance. 218 * 219 * Params: 220 * source = An array that has the size of the matrix. 221 */ 222 this(const(float)[] source) 223 { 224 assert(array.length == source.length); 225 226 array[0..$] = source[0 .. $]; 227 } 228 }