1 /* 2 * DSFML - The Simple and Fast Multimedia Library for D 3 * 4 * Copyright (c) 2013 - 2018 Jeremy DeHaan (dehaan.jeremiah@gmail.com) 5 * 6 * This software is provided 'as-is', without any express or implied warranty. 7 * In no event will the authors be held liable for any damages arising from the 8 * use of this software. 9 * 10 * Permission is granted to anyone to use this software for any purpose, 11 * including commercial applications, and to alter it and redistribute it 12 * freely, subject to the following restrictions: 13 * 14 * 1. The origin of this software must not be misrepresented; you must not claim 15 * that you wrote the original software. If you use this software in a product, 16 * an acknowledgment in the product documentation would be appreciated but is 17 * not required. 18 * 19 * 2. Altered source versions must be plainly marked as such, and must not be 20 * misrepresented as being the original software. 21 * 22 * 3. This notice may not be removed or altered from any source distribution 23 * 24 * 25 * DSFML is based on SFML (Copyright Laurent Gomila) 26 */ 27 28 /** 29 * The glsl module contains types that match their equivalents in GLSL, the 30 * OpenGL shading language. These types are exclusively used by the 31 * $(SHADER_LINK) class. 32 * 33 * Types that already exist in DSFML, such as $(VECTOR2_LINK) and 34 * $(VECTOR3_LINK), are reused as aliases, so you can use the types in this 35 * module as well as the original ones. 36 * Others are newly defined, such as `Vec4` or `Mat3`. Their actual type is an 37 * implementation detail and should not be used. 38 * 39 * All vector types support a default constructor that initializes every 40 * component to zero, in addition to a constructor with one parameter for each 41 * component. 42 * The components are stored in member variables called `x`, `y`, `z`, and `w`. 43 * 44 * All matrix types support a constructor with a `float[]` parameter of the 45 * appropriate size (that is, 9 in a 3x3 matrix, 16 in a 4x4 matrix). 46 * Furthermore, they can be converted from $(TRANSFORM_LINK) objects. 47 */ 48 module dsfml.graphics.glsl; 49 50 import dsfml.graphics.color; 51 import dsfml.graphics.transform; 52 53 import dsfml.system.vector2; 54 import dsfml.system.vector3; 55 56 import std.traits; 57 58 /// 2D float vector (vec2 in GLSL) 59 alias Vec2 = Vector2!(float); 60 /// 2D int vector (ivec2 in GLSL) 61 alias Ivec2 = Vector2!(int); 62 /// 2D bool vector (bvec2 in GLSL) 63 alias Bvec2 = Vector2!(bool); 64 /// 3D float vector (vec3 in GLSL) 65 alias Vec3 = Vector3!(float); 66 /// 3D int vector (ivec3 in GLSL) 67 alias Ivec3 = Vector3!(int); 68 /// 3D bool vector (bvec3 in GLSL) 69 alias Bvec3 = Vector3!(bool); 70 71 /** 72 * 4D float vector (vec4 in GLSL) 73 * 74 * 4D float vectors can be converted from sf::Color instances. Each color 75 * channel is normalized from integers in [0, 255] to floating point values 76 * in [0, 1]. 77 * --- 78 * Vec4 zeroVector; 79 * auto vector = Vec4(1.f, 2.f, 3.f, 4.f); 80 * auto color = Vec4(Color.Cyan); 81 * --- 82 */ 83 alias Vec4 = Vector4!(float); 84 /** 85 * 4D int vector ( ivec4 in GLSL) 86 * 87 * 4D int vectors can be converted from sf::Color instances. Each color channel 88 * remains unchanged inside the integer interval [0, 255]. 89 * $(LI test) 90 * --- 91 * Ivec4 zeroVector; 92 * auto vector = Ivec4(1, 2, 3, 4); 93 * auto color = Ivec4(Color.Cyan); 94 * --- 95 */ 96 alias Ivec4 = Vector4!(int); 97 98 /// 4D bool vector (bvec4 in GLSL) 99 alias Bvec4 = Vector4!(bool); 100 101 /** 102 * 3x3 float matrix (mat3 in GLSL) 103 * 104 * The matrix can be constructed from an array with 3x3 elements, aligned in 105 * column-major order. For example,a translation by (x, y) looks as follows: 106 * --- 107 * float[9] array = 108 * [ 109 * 1, 0, 0, 110 * 0, 1, 0, 111 * x, y, 1 112 * ]; 113 * 114 * auto matrix = Mat3(array); 115 * --- 116 * 117 * $(PARA Mat4 can also be converted from a $(TRANSFORM_LINK Transform).) 118 * --- 119 * Transform transform; 120 * auto matrix = Mat3(transform); 121 * --- 122 */ 123 alias Mat3 = Matrix!(3,3); 124 125 /** 126 * 4x4 float matrix (mat4 in GLSL) 127 * 128 * The matrix can be constructed from an array with 4x4 elements, aligned in 129 * column-major order. For example, a translation by (x, y, z) looks as follows: 130 * --- 131 * float array[16] = 132 * { 133 * 1, 0, 0, 0, 134 * 0, 1, 0, 0, 135 * 0, 0, 1, 0, 136 * x, y, z, 1 137 * }; 138 * 139 * auto matrix = Mat4(array); 140 * --- 141 * 142 * $(PARA Mat4 can also be converted from a $(TRANSFORM_LINK Transform).) 143 * --- 144 * Transform transform; 145 * auto matrix = Mat4(transform); 146 * --- 147 */ 148 alias Mat4 = Matrix!(4,4); 149 150 /** 151 * 4D vector type, used to set uniforms in GLSL. 152 */ 153 struct Vector4(T) 154 if(isNumeric!(T) || is(T == bool)) 155 { 156 /// 1st component (X) of the 4D vector 157 T x; 158 /// 2nd component (Y) of the 4D vector 159 T y; 160 /// 3rd component (Z) of the 4D vector 161 T z; 162 /// 4th component (W) of the 4D vector 163 T w; 164 165 /** 166 * Construct from 4 vector components 167 * 168 * Params: 169 * X = Component of the 4D vector 170 * Y = Component of the 4D vector 171 * Z = Component of the 4D vector 172 * W = Component of the 4D vector 173 */ 174 this(T X, T Y, T Z, T W) 175 { 176 x = X; 177 y = Y; 178 z = Z; 179 w = W; 180 } 181 182 /** 183 * Conversion constructor 184 * 185 * Params: 186 * other = 4D vector of different type 187 */ 188 this(U)(Vector!(U) other) 189 { 190 x = cast(T)other.x; 191 y = cast(T)other.y; 192 z = cast(T)other.z; 193 w = cast(T)other.w; 194 } 195 196 /** 197 * Construct vector from color. 198 * 199 * The vector values are normalized to [0, 1] for floats, and left as-is for 200 * ints. 201 * 202 * Params: 203 * source = The Color instance to create the vector from 204 */ 205 this(Color source) 206 { 207 static if(is(T == float)) 208 { 209 x = source.r / 255f; 210 y = source.g / 255f; 211 z = source.b / 255f; 212 w = source.a / 255f; 213 } 214 else static if(is(T == int)) 215 { 216 x = cast(T)source.r; 217 y = cast(T)source.g; 218 z = cast(T)source.b; 219 w = cast(T)source.a; 220 } 221 } 222 } 223 224 /** 225 * Matrix type, used to set uniforms in GLSL. 226 */ 227 struct Matrix(uint C, uint R) 228 { 229 /// Array holding matrix data. 230 float[C * R] array; 231 232 /** 233 * Construct from DSFML transform. 234 * 235 * This constructor is only supported for 3x3 and 4x4 matrices. 236 * 237 * Params: 238 * source = A DSFML Transform 239 */ 240 this(ref const(Transform) source) 241 { 242 static assert(C == R && (C == 3 || C == 4), 243 "This constructor is only supported for 3x3 and 4x4 matrices."); 244 245 const(float)[] from = source.getMatrix(); 246 247 static if(C == 3) 248 { 249 float[] to = array; // 3x3 250 // Use only left-upper 3x3 block (for a 2D transform) 251 to[0] = from[ 0]; to[1] = from[ 1]; to[2] = from[ 3]; 252 to[3] = from[ 4]; to[4] = from[ 5]; to[5] = from[ 7]; 253 to[6] = from[12]; to[7] = from[13]; to[8] = from[15]; 254 } 255 else static if(C == 4) 256 { 257 array[] = from[]; 258 } 259 } 260 261 /** 262 * Construct from raw data. 263 * 264 * The elements in source are copied to the instance. 265 * 266 * Params: 267 * source = An array that has the size of the matrix. 268 */ 269 this(const(float)[] source) 270 { 271 assert(array.length == source.length); 272 273 array[0..$] = source[0 .. $]; 274 } 275 }