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 		dispose();
38 	}
39 
40 	/// Returns if the mesh is valid.
41 	override @property bool valid()
42 	{
43 		return _mesh.valid;
44 	}
45 
46 	/// Property for the size of the rectangle.
47 	@property ref vec2 size()
48 	{
49 		return _size;
50 	}
51 
52 	/// Property for begin xy and end xy using a vec4 for texture coordinates.
53 	@property ref vec4 texCoords()
54 	{
55 		return _texCoords;
56 	}
57 
58 	override void dispose()
59 	{
60 		if (_mesh.valid)
61 		{
62 			_mesh.dispose();
63 		}
64 	}
65 
66 	/// Creates a new mesh after disposing the old mesh.
67 	void create()
68 	{
69 		_mesh.dispose();
70 		_mesh = new Mesh();
71 		_mesh.addVertices([vec3(0, 0, 0), vec3(_size.x, 0, 0), vec3(_size.x, _size.y, 0), vec3(0, _size.y, 0)]);
72 		_mesh.addTexCoords([vec2(_texCoords.x, _texCoords.y), vec2(_texCoords.z, _texCoords.y), vec2(_texCoords.z, _texCoords.w), vec2(_texCoords.x, _texCoords.w)]);
73 		_mesh.addIndices([0, 1, 2, 0, 2, 3]);
74 		_mesh.create();
75 	}
76 
77 	/// Sets the current transformation matrix and draws this onto the target.
78 	override void draw(IRenderTarget target, ShaderProgram shader = null)
79 	{
80 		if (_mesh.valid)
81 		{
82 			matrixStack.push();
83 			matrixStack.top = matrixStack.top * transform;
84 			if (texture !is null)
85 				texture.bind(0);
86 			target.draw(_mesh, shader);
87 			matrixStack.pop();
88 		}
89 		else
90 			debug std.stdio.writeln("[DEBUG] Mesh not valid!");
91 	}
92 
93 	///
94 	static RectangleShape create(vec2 position, vec2 size)
95 	{
96 		auto shape = new RectangleShape();
97 		shape.position = position;
98 		shape.size = size;
99 		shape.create();
100 		return shape;
101 	}
102 
103 	///
104 	static RectangleShape create(Texture texture, vec2 position, vec2 size)
105 	{
106 		auto shape = new RectangleShape();
107 		shape.texture = texture;
108 		shape.position = position;
109 		shape.size = size;
110 		shape.create();
111 		return shape;
112 	}
113 
114 	///
115 	static RectangleShape create(Texture texture, vec2 position, vec2 size, vec4 texCoords)
116 	{
117 		auto shape = new RectangleShape();
118 		shape.texture = texture;
119 		shape.position = position;
120 		shape.size = size;
121 		shape.texCoords = texCoords;
122 		shape.create();
123 		return shape;
124 	}
125 }