1 module d2d.rendering.rectangleshape;
2 
3 import d2d;
4 
5 /**
6  * A resizable rectangle containing a texture.
7  * Examples:
8  * ---
9  * auto rect = new RectangleShape();
10  * rect.size = vec2(100, 50); // 100x50 px
11  * rect.create();
12  * window.draw(rect);
13  *
14  * // OR
15  *
16  * auto rect = RectangleShape.create(vec2(0, 0), vec2(100, 50)); // At 0,0 with size 100x50 px
17  * window.draw(rect);
18  * ---
19  */
20 class RectangleShape : Shape, IDisposable, IVerifiable
21 {
22 protected:
23 	Mesh _mesh; // TODO: Only 1 Mesh
24 	vec4 _texCoords = vec4(0, 0, 1, 1);
25 	vec2 _size = vec2(1, 1);
26 
27 public:
28 	///
29 	this()
30 	{
31 		_mesh = new Mesh();
32 		create();
33 	}
34 
35 	~this()
36 	{
37 		_mesh = null;
38 		dispose();
39 	}
40 
41 	/// Returns if the mesh is valid.
42 	override @property bool valid()
43 	{
44 		return _mesh.valid;
45 	}
46 
47 	/// Property for the size of the rectangle.
48 	@property ref vec2 size()
49 	{
50 		return _size;
51 	}
52 
53 	/// Property for begin xy and end xy using a vec4 for texture coordinates.
54 	@property ref vec4 texCoords()
55 	{
56 		return _texCoords;
57 	}
58 
59 	override void dispose()
60 	{
61 		if (_mesh && _mesh.valid)
62 		{
63 			_mesh.dispose();
64 			_mesh = null;
65 		}
66 	}
67 
68 	/// Creates a new mesh after disposing the old mesh.
69 	void create()
70 	{
71 		_mesh.dispose();
72 		_mesh = new Mesh();
73 		_mesh.addVertices([vec3(0, 0, 0), vec3(_size.x, 0, 0), vec3(_size.x, _size.y, 0), vec3(0, _size.y, 0)]);
74 		_mesh.addTexCoords([vec2(_texCoords.x, _texCoords.y), vec2(_texCoords.z, _texCoords.y), vec2(_texCoords.z, _texCoords.w), vec2(_texCoords.x, _texCoords.w)]);
75 		_mesh.addIndices([0, 1, 2, 0, 2, 3]);
76 		_mesh.create();
77 	}
78 
79 	/// Sets the current transformation matrix and draws this onto the target.
80 	override void draw(IRenderTarget target, ShaderProgram shader = null)
81 	{
82 		assert(_mesh.valid, "Mesh not valid!");
83 		matrixStack.push();
84 		matrixStack.top = matrixStack.top * transform;
85 		if (texture !is null)
86 			texture.bind(0);
87 		target.draw(_mesh, shader);
88 		matrixStack.pop();
89 	}
90 
91 	///
92 	static RectangleShape create(vec2 position, vec2 size)
93 	{
94 		auto shape = new RectangleShape();
95 		shape.position = position;
96 		shape.size = size;
97 		shape.create();
98 		return shape;
99 	}
100 
101 	///
102 	static RectangleShape create(Texture texture, vec2 position, vec2 size)
103 	{
104 		auto shape = new RectangleShape();
105 		shape.texture = texture;
106 		shape.position = position;
107 		shape.size = size;
108 		shape.create();
109 		return shape;
110 	}
111 
112 	///
113 	static RectangleShape create(Texture texture, vec2 position, vec2 size, vec4 texCoords)
114 	{
115 		auto shape = new RectangleShape();
116 		shape.texture = texture;
117 		shape.position = position;
118 		shape.size = size;
119 		shape.texCoords = texCoords;
120 		shape.create();
121 		return shape;
122 	}
123 }