1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.Graphic.Sprite; 25 26 private: 27 28 import Dgame.Math.Rect; 29 import Dgame.Math.Vector2; 30 import Dgame.Math.Vertex; 31 import Dgame.Math.Geometry; 32 33 import Dgame.Graphic.Drawable; 34 import Dgame.Graphic.Transformable; 35 import Dgame.Graphic.Texture; 36 import Dgame.Graphic.Color; 37 38 public: 39 40 /** 41 * Sprite represents a drawable object and maintains a Texture 42 * 43 * Author: Randy Schuett (rswhite4@googlemail.com) 44 */ 45 class Sprite : Transformable, Drawable { 46 protected: 47 Texture* _texture; 48 Rect _texRect; 49 Vertex[4] _vertices; 50 51 @nogc 52 override void draw(ref const Window wnd) nothrow { 53 wnd.draw(Geometry.TriangleStrip, super.getMatrix(), _texture, _vertices[]); 54 } 55 56 @nogc 57 final void _updateVertices() pure nothrow { 58 immutable float tx = float(_texRect.x) / _texture.width; 59 immutable float ty = float(_texRect.y) / _texture.height; 60 immutable float tw = float(_texRect.width) / _texture.width; 61 immutable float th = float(_texRect.height) / _texture.height; 62 63 immutable float tx_tw = tx + tw; 64 immutable float ty_th = ty + th; 65 66 _vertices[0].position = Vector2f(0, 0); 67 _vertices[0].texCoord = Vector2f(tx, ty); 68 69 _vertices[1].position = Vector2f(_texRect.width, 0); 70 _vertices[1].texCoord = Vector2f(tx_tw, ty); 71 72 _vertices[2].position = Vector2f(0, _texRect.height); 73 _vertices[2].texCoord = Vector2f(tx, ty_th); 74 75 _vertices[3].position = Vector2f(_texRect.width, _texRect.height); 76 _vertices[3].texCoord = Vector2f(tx_tw, ty_th); 77 } 78 79 @nogc 80 final void _adjustTextureRect() pure nothrow { 81 _texRect.x = 0; 82 _texRect.y = 0; 83 _texRect.width = _texture.width; 84 _texRect.height = _texture.height; 85 } 86 87 public: 88 final: 89 /** 90 * CTor 91 */ 92 @nogc 93 this(ref Texture tex) pure nothrow { 94 _texture = &tex; 95 96 _adjustTextureRect(); 97 _updateVertices(); 98 99 this.setColor(Color4b.White); 100 } 101 102 /** 103 * CTor 104 */ 105 @nogc 106 this(ref Texture tex, const Vector2f pos) pure nothrow { 107 this(tex); 108 109 super.setPosition(pos); 110 } 111 112 /** 113 * Reset the Texture 114 */ 115 @nogc 116 void setTexture(ref Texture tex) pure nothrow { 117 _texture = &tex; 118 119 this.setColor(Color4b.White); 120 121 _adjustTextureRect(); 122 _updateVertices(); 123 } 124 125 /** 126 * Returns a pointer to the current Texture 127 */ 128 @nogc 129 inout(Texture*) getTexture() inout pure nothrow { 130 return _texture; 131 } 132 133 /** 134 * Set a Color for the Sprite which is painted over the displayed Texture. 135 */ 136 @nogc 137 void setColor(const Color4b col) pure nothrow { 138 foreach (ref Vertex v; _vertices) { 139 v.color = Color4f(col); 140 } 141 } 142 143 /** 144 * Set the Texture Rect. With this you can define a specific view of the Texture, 145 * so that only this specific view will be drawn. 146 */ 147 @nogc 148 void setTextureRect(const Rect texRect) pure nothrow { 149 _texRect = texRect; 150 _updateVertices(); 151 } 152 153 /** 154 * Returns the current Texture Rect 155 */ 156 @nogc 157 ref const(Rect) getTextureRect() const pure nothrow { 158 return _texRect; 159 } 160 161 /** 162 * Returns the Clip Rect. 163 * The Sprite will notice if a Texture Rect is used or not and will therefore adapt the size of the view automatically 164 */ 165 @nogc 166 Rect getClipRect() const pure nothrow { 167 uint w = 0, h = 0; 168 if (_texRect.isEmpty()) { 169 w = _texture.width; 170 h = _texture.height; 171 } else { 172 w = _texRect.width; 173 h = _texRect.height; 174 } 175 176 return Rect(cast(int) super.x, cast(int) super.y, w, h); 177 } 178 }