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 }