1 module Dgame.Graphic.VertexArray;
2
3 private:
4
5 import Dgame.Graphic.Drawable;
6 import Dgame.Graphic.Texture;
7 import Dgame.Graphic.Color;
8
9 import Dgame.Math.Vertex;
10 import Dgame.Math.Vector2;
11 import Dgame.Math.Rect;
12 import Dgame.Math.Geometry;
13
14 import Dgame.Window.Window;
15
16 public:
17
18 /**
19 * A VertrexArray is a simple way to handle a performant textured shape.
20 * It provides a simple API and maintains the necessary properties.
21 * It is similar to a trimmed-down version of Shape, but does not contain possible unnecessary content.
22 *
23 * See: Shape, Vertex
24 *
25 * Author: Randy Schuett (rswhite4@googlemail.com)
26 */
27 class VertexArray : Drawable {
28 private:
29 Vertex[] _vertices;
30 Texture* _texture;
31
32 protected:
33 @nogc
34 override void draw(ref const Window wnd) nothrow {
35 wnd.draw(this.geometry, _texture, _vertices);
36 }
37
38 public:
39 Geometry geometry;
40
41 final:
42 /**
43 * CTor
44 */
45 @nogc
46 this(Geometry geometry, ref Texture texture) pure nothrow {
47 this.geometry = geometry;
48 this.setTexture(texture);
49 }
50
51 /**
52 * Set or reset a Texture
53 */
54 @nogc
55 void setTexture(ref Texture texture) pure nothrow {
56 _texture = &texture;
57 }
58
59 /**
60 * Returns the current texture or null
61 */
62 @nogc
63 inout(Texture)* getTexture() inout pure nothrow {
64 return _texture;
65 }
66
67 /**
68 * Reserve (additional) space for the internal Vertex array
69 */
70 void reserve(size_t size) pure nothrow {
71 _vertices.reserve(size);
72 }
73
74 /**
75 * Clear all Vertices but preserve the storage and capacity
76 */
77 void clear() nothrow {
78 _vertices.length = 0;
79 _vertices.assumeSafeAppend();
80 }
81
82 /**
83 * Stores a Vertex
84 */
85 void append(ref const Vertex vertex) pure nothrow {
86 _vertices ~= vertex;
87 }
88
89 /**
90 * Stores a Vertex
91 */
92 void append(const Vector2f vec) pure nothrow {
93 _vertices ~= Vertex(vec);
94 }
95
96 /**
97 * Append a whole Quad.
98 * This method provides a simple way to add a quadratic texture-view.
99 * And this as easily as if you would work with a Sprite.
100 *
101 * Note: This method only works for Geometry.Quads.
102 */
103 void appendQuad(const Vector2f position, const Rect texRect) pure nothrow {
104 assert(this.geometry == Geometry.Quads, "This method supports only Geometry.Quads");
105
106 immutable float tx = float(texRect.x) / _texture.width;
107 immutable float ty = float(texRect.y) / _texture.height;
108 immutable float tw = float(texRect.width) / _texture.width;
109 immutable float th = float(texRect.height) / _texture.height;
110
111 immutable float tx_tw = tx + tw;
112 immutable float ty_th = ty + th;
113 immutable float cx_tw = position.x + texRect.width;
114 immutable float cy_th = position.y + texRect.height;
115
116 if ((_vertices.capacity - _vertices.length) < 4)
117 _vertices.reserve(4);
118
119 _vertices ~= Vertex(
120 position,
121 Vector2f(tx, ty),
122 Color4b.White
123 );
124
125 _vertices ~= Vertex(
126 Vector2f(cx_tw, position.y),
127 Vector2f(tx_tw, ty),
128 Color4b.White
129 );
130
131 _vertices ~= Vertex(
132 Vector2f(cx_tw, cy_th),
133 Vector2f(tx_tw, ty_th),
134 Color4b.White
135 );
136
137 _vertices ~= Vertex(
138 Vector2f(position.x, cy_th),
139 Vector2f(tx, ty_th),
140 Color4b.White
141 );
142 }
143
144 /**
145 * Returns all Vertices
146 */
147 @nogc
148 inout(Vertex[]) getVertices() inout pure nothrow {
149 return _vertices;
150 }
151
152 /**
153 * Returns all Vertices
154 */
155 @nogc
156 ref inout(Vertex) opIndex(size_t index) inout pure nothrow {
157 assert(index < _vertices.length);
158 return _vertices[index];
159 }
160
161 /**
162 * Returns the current amount of stored Vertices
163 */
164 @nogc
165 @property
166 size_t length() const pure nothrow {
167 return _vertices.length;
168 }
169 }