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