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