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 * There are four global states that can be applied to the drawn objects: 30 * $(UL 31 * $(LI the blend mode: how pixels of the object are blended with the 32 * background) 33 * $(LI the transform: how the object is positioned/rotated/scaled) 34 * $(LI the texture: what image is mapped to the object) 35 * $(LI the shader: what custom effect is applied to the object)) 36 * 37 * High-level objects such as sprites or text force some of these states when 38 * they are drawn. For example, a sprite will set its own texture, so that you 39 * don't have to care about it when drawing the sprite. 40 * 41 * The transform is a special case: sprites, texts and shapes (and it's a good 42 * idea to do it with your own drawable classes too) combine their transform 43 * with the one that is passed in the RenderStates structure. So that you can 44 * use a "global" transform on top of each object's transform. 45 * 46 * Most objects, especially high-level drawables, can be drawn directly without 47 * defining render states explicitely – the default set of states is ok in most 48 * cases. 49 * --- 50 * RenderWindow window; 51 * Sprite sprite; 52 * 53 * ... 54 * 55 * window.draw(sprite); 56 * --- 57 * 58 * $(PARA If you want to use a single specific render state, for example a 59 * shader, you can construct a $(U RenderStates) object from it:) 60 * --- 61 * auto states = RenderStates(shader) 62 * window.draw(sprite, states); 63 * 64 * //or 65 * window.draw(sprite, RenderStates(shader)); 66 * --- 67 * 68 * $(PARA When you're inside the `draw` function of a drawable object (inherited 69 * from $(DRAWABLE_LINK)), you can either pass the render states unmodified, or 70 * change some of them. For example, a transformable object will combine the 71 * current transform with its own transform. A sprite will set its texture. 72 * Etc.) 73 * 74 * See_Also: 75 * $(RENDERTARGET_LINK), $(DRAWABLE_LINK) 76 */ 77 module dsfml.graphics.renderstates; 78 79 import dsfml.graphics.blendmode; 80 import dsfml.graphics.transform; 81 import dsfml.graphics.texture; 82 import dsfml.graphics.shader; 83 import std.typecons:Rebindable; 84 85 /** 86 * Define the states used for drawing to a RenderTarget. 87 */ 88 struct RenderStates 89 { 90 /// The blending mode. 91 BlendMode blendMode; 92 /// The transform. 93 Transform transform; 94 private 95 { 96 Rebindable!(const(Texture)) m_texture; 97 Rebindable!(const(Shader)) m_shader; 98 } 99 100 /** 101 * Construct a default set of render states with a custom blend mode. 102 * 103 * Params: 104 * theBlendMode = Blend mode to use 105 */ 106 this(BlendMode theBlendMode) 107 { 108 blendMode = theBlendMode; 109 transform = Transform(); 110 111 m_texture = null; 112 m_shader = null; 113 } 114 115 /** 116 * Construct a default set of render states with a custom transform. 117 * 118 * Params: 119 * theTransform = Transform to use 120 */ 121 this(Transform theTransform) 122 { 123 transform = theTransform; 124 125 blendMode = BlendMode.Alpha; 126 127 m_texture = null; 128 m_shader = null; 129 } 130 131 /** 132 * Construct a default set of render states with a custom texture 133 * 134 * Params: 135 * theTexture = Texture to use 136 */ 137 this(const(Texture) theTexture) 138 { 139 m_texture = theTexture; 140 141 blendMode = BlendMode.Alpha; 142 143 transform = Transform(); 144 m_shader = null; 145 } 146 147 /** 148 * Construct a default set of render states with a custom shader 149 * 150 * Params: 151 * theShader = Shader to use 152 */ 153 this(const(Shader) theShader) 154 { 155 m_shader = theShader; 156 } 157 158 /** 159 * Construct a set of render states with all its attributes 160 * 161 * Params: 162 * theBlendMode = Blend mode to use 163 * theTransform = Transform to use 164 * theTexture = Texture to use 165 * theShader = Shader to use 166 */ 167 this(BlendMode theBlendMode, Transform theTransform, const(Texture) theTexture, const(Shader) theShader) 168 { 169 blendMode = theBlendMode; 170 transform = theTransform; 171 m_texture = theTexture; 172 m_shader = theShader; 173 } 174 175 @property 176 { 177 /// The shader to apply while rendering. 178 const(Shader) shader(const(Shader) theShader) 179 { 180 m_shader = theShader; 181 return theShader; 182 } 183 184 /// ditto 185 const(Shader) shader() const 186 { 187 return m_shader; 188 } 189 } 190 191 @property 192 { 193 /// The texture to apply while rendering. 194 const(Texture) texture(const(Texture) theTexture) 195 { 196 m_texture = theTexture; 197 return theTexture; 198 } 199 200 /// ditto 201 const(Texture) texture() const 202 { 203 return m_texture; 204 } 205 } 206 }